Youtrack Workflow to set issue due date based on issue start date + estimate - youtrack

I am trying to set up a workflow on youtrack where it sets automatically the end date based on the start date + estimates.
For example, my issue start date is 2022/10/01 and it has an estimate of 10d (10 days, for example). I want that the end date to be set of 2022/10/10.
I couldn't figure out how to set this rule as I couldn't user the workflow constructor for it.
Thanks

Here is an example of a similar workflow that automatically adds the Planned time value to Start date field and writes the result in the Due date field:
const entities = require('#jetbrains/youtrack-scripting-api/entities');
exports.rule = entities.Issue.onChange({
title: 'End date',
guard: (ctx) => {
return (ctx.issue.fields.isChanged(ctx.Plan) || ctx.issue.fields.isChanged(ctx.StartDate)) && ctx.issue.fields.Plan != null && ctx.issue.fields.StartDate != null;
},
action: (ctx) => {
const issue = ctx.issue;
var periodestimate = issue.fields.Plan;
var minutesestimate = !periodestimate ? 0 : (periodestimate.getMinutes() + 60 * (periodestimate.getHours() + 24 * (periodestimate.getDays() + 7 * periodestimate.getWeeks())));
ctx.issue.fields.EndDate = issue.fields.StartDate + (minutesestimate * 60000);
},
requirements: {
Plan: {
name: "Planned time",
type: entities.Field.periodType
},
EndDate: {
name: "Due Date",
type: entities.Field.dateType
},
StartDate: {
name: "Start Date",
type: entities.Field.dateType
}
}
});

Related

Getting "INVALID DATE" if device or emulator not in "debug remotely" mode

I'm building chat fonctionality in an app and i'm using FaridSafi/react-native-gifted-chat. When i debug on chrome the messages dates are good.
if i'm not debugging remotely all dates of messages become "INVALID DATE".
I have same result on real device and emulator
I format date i get from the API to the format the library is in using this function:
formatOneMessage(message) {
const receiver = this.props.navigation.getParam("receiver");
const receiverName = receiver.Name;
const receiverLastName = receiver.lastName;
const formatedDate = Util.formatDate(message.creation_date)
const FormatedMessage = {
_id: message.id,
text: message.content,
createdAt: new Date(formatedDate),
user: {
_id: message.sender_id,
name: receiverName + " " + receiverLastName,
avatar: "https://placeimg.com/140/140/any"
}
};
return FormatedMessage;
}
formatDate(date){
let dateAndTimeArray = date.split(" ");
let dateArray = dateAndTimeArray[0].split("-");
let newDate = dateArray[1] + "-" + dateArray[0] + "-" + dateArray[2];
let newDateAndTime = newDate + " " + dateAndTimeArray[1]
return newDateAndTime;
}
Thanks!
I used Moment.JS to fix this issue myself, using the
moment().format()
Be aware, that your Parameter for "new Date()" has ISO_8601 Format.
More information about this see here: https://stackoverflow.com/a/58353084/1256697
Here is how i used moment.js to resolve this issue:
formatOneMessage(message) {
const receiverName = this.props.navigation.getParam("receiverName");
const modifiedDate = Util.formatDate(message.creation_date);
const formatedDate = moment(modifiedDate, "MM-DD-YYYY HH:mm:ss");
const FormatedMessage = {
_id: message.id,
text: message.content,
createdAt: formatedDate,
user: {
_id: message.sender_id,
name: receiverName,
avatar: "https://placeimg.com/140/140/any"
}
};
return FormatedMessage;
}
if you are curious what Util.formatDate is doing:
formatDate(date) {
let dateAndTimeArray = date.split(" ");
let dateArray = dateAndTimeArray[0].split("-");
let newDate = dateArray[1] + "-" + dateArray[0] + "-" + dateArray[2];
let newDateAndTime = newDate + " " + dateAndTimeArray[1];
return newDateAndTime;
},

Validating a date before today with VeeValidate

I'm trying to validate a date of birth field on Vue.js to only allow dates before today, but I am unsure of how to implement Javascript to the before attributes or the date_between attributes
I'm trying to do something along the lines of
v-validate="'date_format:DD-MM-YYYY|before:changeDateFormat(new Date(Date.now()))'"
where changeDateFormat() is
changeDateFormat(dateStr) {
if (dateStr != null) {
var date = new Date(dateStr)
var newDate = ("00"+(date.getDate())).slice(-2)+'-'+("00"+(date.getMonth()+1)).slice(-2)+'-'+date.getFullYear()
return newDate
}
return ''
I'm quite new to Vue.js so I apologise if this is a simple question.
Try to use rules expression like object.
VeeValidate syntax:
https://baianat.github.io/vee-validate/guide/syntax.html
For example:
data: {
validators: {
BirthDate: {
required: true,
date_format: 'dd-MM-yyyy',
before: this.changeDateFormat(new Date(Date.now()))
}
}
},
methods: {
changeDateFormat(dateStr) {
if (dateStr != null) {
var date = new Date(dateStr)
var newDate = ("00" + (date.getDate())).slice(-2) + '-' + ("00" + (date.getMonth() + 1)).slice(-2) + '-' +date.getFullYear()
return newDate
}
return ''
}
},
And your directive:
v-validate="validators.BirthDate"

Sequelize Getter Method Date Format

I'm trying to use the getter method in my model to change the date format for my field to a mm/dd/yyy readable format, but it doesn't appear that my method is working or it might be that I'm not understanding how the method works. Below is my model and I try to expose the annotationDateRead field for use in a route, but I get an endless loop, which indicates that I can't find this field. Is there a better way to achieve what I am looking for?
model:
module.exports = function(sequelize, DataTypes) {
var Annotation = sequelize.define('annotation', {
annotation_id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
annotationDate: {
type: DataTypes.DATE,
field: 'annotation_date'
},
userId: {
type: DataTypes.STRING,
field: 'user_id'
}
},
{
freezeTableName: true,
getterMethods: {
annotationDateRead: function(){
var date = new Date(this.getDataValue('annotationDate'));
var month = date.getMonth();
var day = date.getDate();
var year = date.getFullYear();
return month + '/' + day + '/' + year;
}
},
classMethods: {
associate: function(db) {
Annotation.belongsTo(db.User)
}
}
});
return Annotation;
}
this should work (version 5+):
getterMethods: {
annotationDateRead() {
var date = new Date(this.annotationDate);
var month = date.getMonth();
var day = date.getDate();
var year = date.getFullYear();
return month + '/' + day + '/' + year;
}
}

Displaying count down timer in Sencha Touch 2

I need to display a countdown timer, implemented it using delayed task.
code as below:
var task = Ext.create('Ext.util.DelayedTask', function() {
if (sec < 1 && min > 0) {
min--;
sec = 60;
}
if (min == 0 && sec == 1) {
task.cancel();
}
sec--;
Ext.getCmp('minute').setHtml(min);
Ext.getCmp('second').setHtml(sec);
console.log('minute is' + min + 'second is' + sec);
task.delay(1000);
}, this);
task.delay(1000);
With the above implementation, function gets called only once.
Looking at the discussion at this thread
Auto Refresh the List in Sencha Touch Application the above code should work. But, it is not working. What could be wrong in my code? Thanks.
As far as I know, Ext.util.DelayedTask is meant for delaying a task without executing it.
This can be useful for delaying an Ajax-call on a form, as you can see in the docs:
This method is especially useful for things like detecting whether a user has finished typing in a text field. [..] You can use this class to buffer the keypress events for a certain number of milliseconds, and perform only if they stop for that amount of time.
Why don't you just use a regular setTimeout? Something like http://jsfiddle.net/EreaP/ works perfectly.
Late response:
Ext.define('MyApp.view.TimerClock', {
extend: 'Ext.Container',
xtype: 'timerClock',
duration: 3 * 60 * 60, //default to 3 hour
paused: false,
clockIntervalHook: undefined,
config: {
listeners: {
initialize: function () {
this.start();
}
}
},
start: function () {
var me = this,
duration = me.duration,
updateClock = function () {
if (me.isPaused()) {
return;
}
me.setHtml(me.formatTime(duration--));
if (duration <= 0) {
me.stop();
}
};
me.clockIntervalHook = setInterval(updateClock, 1000);
return me;
},
pause: function () {
this.paused = true;
return this;
},
isPaused: function () {
return this.paused == true
},
resume: function () {
this.paused = false;
},
restart: function () {
this.stop();
this.start();
},
stop: function () {
clearInterval(this.clockIntervalHook);
return this;
},
//format the given seconds into "HH:MM:SS" format
//override this if you need custom behavior
formatTime: function (seconds) {
var hours = Math.floor(seconds / 3600);
hours = hours <= 9 ? "0" + hours : hours;
seconds %= 3600;
var minutes = Math.floor(seconds / 60);
minutes = minutes <= 9 ? "0" + minutes : minutes;
seconds %= 60;
seconds = seconds <= 9 ? "0" + seconds : seconds;
return hours + ":" + minutes + ":" + seconds
}
});
Any other view, add the timer simply using
{ xtype : 'timerClock' }

Dojo's dijit.calendar and isDisabledDate

I'd like to use the dijit.calendar widget, but be able to set disabled dates from an array of dates. All the examples point out how to disable weekends, but I need to disable special dates too.
Can anyone point me in the right direction to utilize a custom function in the isDisabledDate, rather than just whats in dojo.date.locale?
I've tried writing a function, and putting it inside the isDisabledDate attribute, but all I get is errors.
I'm making a huge assumption here, that you're populating your array for each month displayed via an XHR request. This XHR request returns an array of strings in Y-m-d format (i.e. ['2011-11-29','2011-11-30']). Another slight assumption is that the XHR request returns an array of dates that should be enabled, but this can be reversed by swapping the disable = true; and disable = false; lines
I don't know how much detail to go into without being patronizing, so if anything is unclear I'll try to clarify afterwards.
dojo.provide("custom.Calendar");
dojo.declare("custom.Calendar", dijit.Calendar, {
_xhr: null,
// Month/Year navigation buttons clicked
_adjustDisplay: function(){
// Ensure all dates are initially enabled (prevents seepage)
this.isDisabledDate = function(date) {
return false;
};
this.inherited(arguments);
this._disableAndPopulate();
},
constructor: function(){
this.inherited(arguments);
this._disableAndPopulate();
},
// Month drop down box
_onMonthSelect: function(){
// Ensure all dates are initially enabled (prevents seepage)
this.isDisabledDate = function(date) {
return false;
};
this.inherited(arguments);
this._disableAndPopulate();
},
// Set disabled dates and re-render calendar
_disableAndPopulate: function(){
var currDate = this.currentFocus;
// Get Lower bound date
var startDate = new Date();
startDate.setFullYear(currDate.getFullYear(), currDate.getMonth(), -5);
// Create ymd dates manually (10x faster than dojo.date.locale.format)
var startMonth = (startDate.getMonth()<9 ? '0' + (startDate.getMonth()+1) : startDate.getMonth()+1);
var startDay = (startDate.getDate()<10 ? '0' + startDate.getDate() : startDate.getDate());
var ymdStartDate = startDate.getFullYear() + '-' + startMonth + '-' + startDay;
// Get Upper bound date
var endDate = new Date();
endDate.setFullYear(currDate.getFullYear(), currDate.getMonth() + 1, 14);
// Create ymd dates manually (10x faster than dojo.date.locale.format)
var endMonth = (endDate.getMonth()<9 ? '0' + (endDate.getMonth()+1) : endDate.getMonth()+1);
var endDay = (endDate.getDate()<10 ? '0' + endDate.getDate() : endDate.getDate());
var ymdEndDate = endDate.getFullYear() + '-' + endMonth + '-' + endDay;
var calendar = this;
// Get IssueDates
var issueDates;
// If an existing xhr request is still running, cancel it before starting a new one
if (this._xhr) {
this._xhr.cancel();
}
this._xhr = dojo.xhrGet({
url: "http://.....", // url of server-side script
content: {
startDate: ymdStartDate, // Earliest possible date displayed on current month
endDate: ymdEndDate, // Last possible date displayed on current month
filters: {} // Any additional criteria which your server-side script uses to determine which dates to return
},
failOk: true, // Prevent error being logged to console when previous XHR calls are cancelled
load: function(data){
issueDates = dojo.fromJson(data);
if (issueDates === undefined) {
// Error with xhr
} else {
calendar.isDisabledDate = function(date) {
var disable = true;
// Create ymdDate manually (10x faster than dojo.date.locale.format)
var month = (date.getMonth()<9 ? '0' + (date.getMonth()+1) : date.getMonth()+1);
var day = (date.getDate()<10 ? '0' + date.getDate() : date.getDate());
var ymdDate = date.getFullYear() + '-' + month + '-' + day;
// Loop through array returned from XHR request, if it contains current date then
// current date should not be disabled
for (key in issueDates) {
if (issueDates[key] == ymdDate) {
disable = false;
break;
}
}
return disable;
};
calendar._populateGrid(); // Refresh calendar display
}
},
// Log any errors to console (except when XHR request is cancelled)
error: function(args) {
if (args.dojoType == 'cancel') {
// Request cancelled
} else {
console.error(args);
}
}
});
},
onClose: function() {
// If an existing xhr request is still running, cancel it before starting a new one
if (this._xhr) {
this._xhr.cancel();
}
}
});
AMD style:
CalendarLite.js.uncompressed.js in dojo 1.7.1 contains the isDisabledDate function:
isDisabledDate: function(/*===== dateObject, locale =====*/){
// summary:
// May be overridden to disable certain dates in the calendar e.g. `isDisabledDate=dojo.date.locale.isWeekend`
// dateObject: Date
// locale: String?
// tags:
// extension
/*=====
return false; // Boolean
=====*/
},
...
You could re-implement the function using this example:
var myCalendar = declare(Calendar, {
datesToDisable : [],
constructor: function(args) {
this.inherited("constructor", arguments);
this.datesToDisable = args.datesToDisable;
},
isDisabledDate: function(/*Date*/date, /*String?*/locale){
return array.some(this.datesToDisable, function(item) {
return dojo.compare(item, date, "date") === 0;
});
}
});
Then you can use the following constructor and datesToDisable parameter to specify your array.
var someCalendar = new myCalendar({datesToDisable: [new Date(...),....,new Date(....)]},...);
or try this for a fast and dirty solution:
var someCalendar = new Calendar(...);
someCalendar.datesToDisable = [new Date(...),....,new Date(....)];
someCalendar.isDisabledDate = function(/*Date*/date, /*String?*/locale){
return array.some(this.datesToDisable, function(item) {
return date.compare(item, date, "date") === 0;
});
}
But I would recommend the first approach. The assumption is that you know AMD style in order to "import" dijit/Calendar, dojo/_base/array and dojo/date (for "date.compare()" to work).
Cheers!
You can add list of holidays in an array with its timestamp and use indexOf method to find matching dates while populating the calendar in the overriding function of isDisabledDate
var holidays = new Array();
var holidDt = new Date("October 2, 2012");
holidays.push(holidDt.getTime());
Now access the holiday array and check its presence. If present disable, else enable by overriding the isDisabledDate function
isDisabledDate: function(d) {
var dt = new Date(d);
var dayN = dt.getDay();
dt.setHours(0, 0, 0, 0);
/**
* Condition for
* 1. Weekends
* 2. Holidays (holiday array needs to be updated with holiday times)
*/
return ((!((dayN > 0) && (dayN < 6))) || (arrayUtil.indexOf(holidays, dt.getTime()) >= 0));
}