search envelope-o feed check
Home Unanswered Active Tags New Question
user comment-o

Scheduler - onTimeRangeRightClick not fired on frozen rows

Asked by Anonymous
2 years ago.

For some reason the event onTimeRangeRightClick doesn't get fired for frozen rows. I assume, this should be possible?

This is my configuration:

  schedulerConfig: any = {
    rowHeaderColumns: [
      { text: '', display: "name" },
      { text: '' }
    ],

    durationBarVisible: false,
    heightSpec: 'Parent100Pct',
    hideBorderFor100PctHeight: true,
    locale: this.localeService.localeId,
    cellWidthSpec: 'Auto',
    crosshairType: 'Full',
    timeHeaders: [
      { 'groupBy': "Month", 'format': "MMMM yyyy" },
      { 'groupBy': 'Week' },
      { 'groupBy': 'Day', 'format': 'd' }
    ],
    scale: 'CellDuration',
    cellDuration: 720,
    // https://forums.daypilot.org/question/5571/how-to-change-the-displayed-end-date-of-selected-range
    //eventEndSpec: 'Date',
    showNonBusiness: true,
    businessWeekends: false,
    floatingEvents: true,
    eventHeight: 20,
    headerHeight: 20,
    rowMinHeight: 20,
    eventStackingLineHeight: 100,
    rowMarginTop: 1,
    rowMarginBottom: 4,
    eventMarginBottom: 1,
    eventMarginLeft: 1,
    eventMarginRight: 2,
    eventMovingStartEndEnabled: true,
    eventResizingStartEndEnabled: true,
    timeRangeSelectingStartEndEnabled: true,
    groupConcurrentEvents: false,
    allowEventOverlap: true,
    allowMultiRange: false,
    multiSelectRectangle: 'Free',
    rowHeaderHideIconEnabled: false,
    multiMoveVerticalMode: 'All',
    allowMultiMove: false,
    treeEnabled: false,
    //useEventBoxes: 'Never',

    contextMenuResource: new DayPilot.Menu({
      items: [
        {
          text: this.dialogTextService.getTranslation('TitJumpToTimesheet'),
          onClick: (args) => { this.navigateToTimeSheet(args.source.data.id); },
          hidden: false
        },
      ],
      onShow: (args) => {
        const personResource = args.source.data as PersonResource;
        args.menu.items[0].hidden = !this.isActiveAndSubordinatedPerson(personResource);

        if (args.menu.items.all(i => i.hidden)) {
          args.preventDefault();
        }
      }
    }),

    contextMenuSelection: new DayPilot.Menu({
      onShow: (args) => {
        const personId = +args.source.resource;
        const from = new Date(args.source.start.value);
        const to = new Date(args.source.end.value);

        const personResource = this.personResources.find(p => p.id == personId.toString());

        let hasEditPermission = this.globalVariableService.LoggedInUser.hasPermission(PermissionKeys.MODULE_ATTENDANCE)
        let menuItems = new Array<DayPilot.MenuItemData>();

        if (personResource.frozen === undefined) {
          if (personResource && personResource.tags.personRole == PersonRole.OtherEmployee) {
            args.preventDefault();
          }

          this.focusedPersonId = personResource.id;

          if (hasEditPermission) {
            // Hinzufügen
            menuItems.push({
              text: this.dialogTextService.getTranslation('TitAdd'),
              items: this.addCommandSubMenuItems(personResource)
            });

            // Einfügen
            if (this.clipboard[0]) {
              // Separator
              if (menuItems.any()) {
                menuItems.push({ text: '-' });
              }

              menuItems.push({
                text: this.dialogTextService.getTranslation('TitPaste'),
                onClick: (args) => { this.pasteItem(args); }
              });
            }
          }

          // Separator
          if (menuItems.any()) {
            menuItems.push({ text: '-' });
          }

          // Zeitausweis öffnen
          menuItems.push({
            text: this.dialogTextService.getTranslation('TitJumpToTimesheet'),
            onClick: (args) => { this.navigateToTimeSheet(args.source.resource); }
          });
        }
        else {
          // Plankommentar hinzufügen
          menuItems.push({
            text: this.dialogTextService.getTranslation('TitPlanComment'),
            onClick: (args) => { this.addPlanningComment(args.source.resource); }
          });
        }

        args.menu.items = menuItems;

        if (!args.menu.items.any()) {
          args.preventDefault();
        }
      }
    }),

    bubble: new DayPilot.Bubble({
      onLoad: (args) => {
        this.showTooltip(args);
      }
    }),

    /**
     * Events handling settings
     */
    timeRangeSelectedHandling: 'Hold',
    eventMoveHandling: 'Update',
    eventResizeHandling: 'Update',
    eventDeleteHandling: 'Disabled',
    eventClickHandling: 'Select',
    eventHoverHandling: 'Bubble',
    eventDoubleClickHandling: 'Enabled',
    timeRangeRightClickHandling: "ContextMenu",

    /**
     * Events handler
     */

    onAfterRender: (args) => {
      this.busyIndicatorService.hide();
    },

    onBeforeTimeHeaderRender: (args) => {
      if (args.header.level === 1) {
        args.header.html = `${this.dialogTextService.getTranslation('TitWeek')} ${args.header.start.weekNumberISO().padStart(2, '0')}`;
      }

      let start = new Date(args.header.start.value);
      if (args.header.level === 2 && start.isSame(Date.today())) {
        args.header.areas = [
          { start: args.header.start, end: args.header.end, bottom: 0, height: 2, backColor: 'blue' }
        ];
      }
    },

    onBeforeRowHeaderRender: (args) => {
      const personResource = args.row.data as PersonResource;

      if (personResource.frozen !== undefined) {
        return;
      }

      // Status icons
      args.row.columns[1].areas = [];

      const leftOffset = 20
      let left = 60;
      // Same position for top and bottom
      // see https://forums.daypilot.org/question/5577/how-to-center-vertically-active-areas
      const topBottom = 5;

      if (personResource.tags.ignoreWorkProfileChangesToolTipText) {
        args.row.columns[1].areas.push(
          {
            left: left,
            top: topBottom,
            bottom: topBottom,
            style: "display: flex; align-items: center;",
            width: 16,
            html: '<img src="assets/icons/favorites.png" height="16" width="16">',
            toolTip: personResource.tags.ignoreWorkProfileChangesToolTipText
          });

        left = left - leftOffset;
      }

      if (personResource.tags.isIndirectlySubordinatedToolTipText) {
        args.row.columns[1].areas.push(
          {
            left: left,
            top: topBottom,
            bottom: topBottom,
            style: "display: flex; align-items: center;",
            width: 16,
            html: '<img src="assets/icons/subordinate.png" height="16" width="16">',
            toolTip: personResource.tags.isIndirectlySubordinatedToolTipText
          });

        left = left - leftOffset;
      }

      if (personResource.tags.personWillEnterToolTipText) {
        args.row.columns[1].areas.push(
          {
            left: left,
            top: topBottom,
            bottom: topBottom,
            style: "display: flex; align-items: center;",
            width: 16,
            html: '<img src="assets/icons/Enter.png" height="16" width="16">',
            toolTip: personResource.tags.personWillEnterToolTipText
          });

        left = left - leftOffset;
      }

      if (personResource.tags.personLeftCompanyToolTipText) {
        args.row.columns[1].areas.push(
          {
            left: left,
            top: topBottom,
            bottom: topBottom,
            style: "display: flex; align-items: center;",
            width: 16,
            html: '<img src="assets/icons/leave.png" height="16" width="16">',
            toolTip: personResource.tags.personLeftCompanyToolTipText
          });

        left = left - leftOffset;
      }

      if (personResource.tags.calculationStatusToolTipText) {
        args.row.columns[1].areas.push(
          {
            left: left,
            top: topBottom,
            bottom: topBottom,
            style: "display: flex; align-items: center;",
            width: 16,
            html: '<img src="assets/icons/Error.png" height="16" width="16">',
            toolTip: personResource.tags.calculationStatusToolTipText
          });

        left = left - leftOffset;
      }
    },

    onBeforeCellRender: (args) => {
      this.setDayColor(args);
    },

    onBeforeEventRender: (args) => {
      const menuItems = new Array<DayPilot.MenuItemData>();
      const personId = args.data.resource;
      const from = new Date(args.data.start);

      const personResource = this.personResources.find(p => p.id == args.data.resource);

      if (args.data.tags.type == 'Comment' && !this.dlgCommentCommand.canExecute()) {
        return;
      }

      let hasEditPermission = this.globalVariableService.LoggedInUser.hasPermission(PermissionKeys.MODULE_ATTENDANCE)

      if (!args.data.isReadonly && hasEditPermission) {
        // Bearbeiten
        if (args.data.tags.type != 'Error' && args.data.tags.type != 'Absence') {
          menuItems.push({
            text: this.dialogTextService.getTranslation('TitEdit'),
            onClick: (args) => {
              let event: DayPilot.Event = args.source;
              let item = event.data as AttendancePlanningEvent;
              this.editItem(item);
            }
          });
        }

        if (args.data.tags.type == 'AdditionalService' || args.data.tags.type == 'Service'
          || args.data.tags.type == 'PlanningBreak') {
          // Kopieren
          menuItems.push({
            text: this.dialogTextService.getTranslation('BtnCopy'),
            onClick: (args) => {
              let event: DayPilot.Event = args.source;
              let item = event.data as AttendancePlanningEvent;
              this.copyItem(args);
            }
          });
        }

        // Löschen
        if (args.data.tags.type != 'Error' && args.data.tags.type != 'Absence') {
          menuItems.push({
            text: this.dialogTextService.getTranslation('BtnDelete'),
            onClick: (args) => {
              let event: DayPilot.Event = args.source;
              let item = event.data as AttendancePlanningEvent;
              this.deleteItem(item);
            }
          });
        }
      }

      // Zeitausweis öffnen
      if (this.isActiveAndSubordinatedPerson(personResource)) {
        // Separator
        if (menuItems.any()) {
          menuItems.push({ text: '-' });
        }

        menuItems.push({
          text: this.dialogTextService.getTranslation('TitJumpToTimesheet'),
          onClick: (args) => { this.navigateToTimeSheet(args.source.resource); }
        });
      }

      if (menuItems.any()) {
        args.data.contextMenu = new DayPilot.Menu({
          items: menuItems
        });
      }
    },

    onEventDoubleClick: (args) => {
      let event = args.e.data as AttendancePlanningEvent;
      if (event.tags.type == 'Absence' || event.tags.type == 'Error') {
        args.preventDefault();
      }
    },

    onEventDoubleClicked: (args) => {
      let event = args.e.data as AttendancePlanningEvent;
      this.editItem(event);
    },

    onTimeRangeRightClick: (args) => {
      const from = new Date(args.start.value);
      if (from.isSameOrBefore(this.clientConfigurationService.blockedDate.toDate())) {
        args.preventDefault();
      }
    },

    onTimeRangeSelecting: (args) => {
      let day = new Date(args.anchor.value).date();
      this.globalVariableService.date = moment(day);

      let personResource = this.personResources.find(p => p.id == args.resource);

      if (personResource.frozen === undefined) {
        let person = this.personService.getById(args.resource) as Person;
        this.globalVariableService.personId = person.personId;          

        if ((this.currentPerson && this.currentPerson.personId != person.personId) || !day.isSame(this.selectedDay)) {
          this.currentPerson = person;
          this.selectedDay = day;
          this.updateBalanceChart();
        }
      }
    }
  };
Answer posted by Dan Letecky [DayPilot]
2 years ago.

This should be fixed now in the latest sandbox build (2022.4.5471):

https://release.daypilot.org/changes/js/

Comment posted by Anonymous
2 years ago.

It works fine. Thanks

Comment posted by Anonymous
2 years ago.

Something else seems to be wrong. I have a top frozen row. When I right click on it, I got the resource of the first unfrozen row instead of the frozen row. This happens in the events onTimeRangeRightClick and in the event onShow of contextMenuSelection

onTimeRangeRightClick: (args) => {     
      // args.resource is wrong
}
contextMenuSelection: new DayPilot.Menu({
      onShow: (args) => {
        // args.source.resource is wrong
      }
    })
Comment posted by Dan Letecky [DayPilot]
2 years ago.

Thanks for reporting the issue. This should be fixed now as well (2022.4.5472).

This question is more than 1 months old and has been closed. Please create a new question if you have anything to add.