neuronetio / gantt-schedule-timeline-calendar

Gantt Gantt Gantt Timeline Schedule Calendar [ javascript gantt, js gantt, projects gantt, timeline, scheduler, gantt timeline, reservation timeline, react gantt, angular gantt, vue gantt, svelte gantt, booking manager ]
https://gantt-schedule-timeline-calendar.neuronet.io
Other
3.07k stars 358 forks source link

Time bookmarks are not rendered correctly when mounting multiple components #393

Closed FabianDaniel00 closed 2 months ago

FabianDaniel00 commented 3 months ago

Describe the bug When mounting multiple GSTC components, the time bookmarks are only rendered for the last GSTC component that was mounted, using the TimeBookmarks plugin.

Code How to reproduce this error? I'm using GSTC in Svelte and the same issue is happening there. This is just an example.

import GSTC from 'gantt-schedule-timeline-calendar';
import { Plugin as TimeBookmarks } from 'gantt-schedule-timeline-calendar/dist/plugins/time-bookmarks.esm.min.js';

const rowsFromDB1 = [
  {
    id: '1',
    label: '(1) Row 1'
  },
  {
    id: '2',
    label: '(1) Row 2'
  }
];

const itemsFromDB1 = [
  {
    id: '1',
    label: '(1) Item 1',
    rowId: '1',
    time: {
      start: GSTC.api
        .date('2020-01-01')
        .startOf('day')
        .add(12, 'hour')
        .valueOf(),
      end: GSTC.api.date('2020-01-02').endOf('day').add(12, 'hour').valueOf()
    }
  },
  {
    id: '2',
    label: '(1) Item 2',
    rowId: '1',
    time: {
      start: GSTC.api
        .date('2020-02-01')
        .startOf('day')
        .add(12, 'hour')
        .valueOf(),
      end: GSTC.api.date('2020-02-02').endOf('day').add(12, 'hour').valueOf()
    }
  },
  {
    id: '3',
    label: '(1) Item 3',
    rowId: '2',
    time: {
      start: GSTC.api
        .date('2020-01-15')
        .startOf('day')
        .add(12, 'hour')
        .valueOf(),
      end: GSTC.api.date('2020-01-20').endOf('day').add(12, 'hour').valueOf()
    }
  }
];

const columnsFromDB1 = [
  {
    id: 'id',
    label: '(1) ID',
    data: ({ row }) => GSTC.api.sourceID(row.id), // show original id (not internal GSTCID)
    sortable: ({ row }) => Number(GSTC.api.sourceID(row.id)), // sort by id converted to number
    width: 80,
    header: {
      content: '(1) ID'
    }
  },
  {
    id: 'label',
    data: 'label',
    sortable: 'label',
    isHTML: false,
    width: 230,
    header: {
      content: '(1) Label'
    }
  }
];

// Configuration object
const config1 = {
  // for free key for your domain please visit https://gstc.neuronet.io/free-key
  // if you need commercial license please visit https://gantt-schedule-timeline-calendar.neuronet.io/pricing

  licenseKey:
    '====BEGIN LICENSE KEY====\n...\n====END LICENSE KEY====',

  innerHeight: 200,
  list: {
    columns: {
      data: GSTC.api.fromArray(columnsFromDB1)
    },
    rows: GSTC.api.fromArray(rowsFromDB1)
  },
  chart: {
    items: GSTC.api.fromArray(itemsFromDB1)
  },
  plugins: [
    TimeBookmarks({
      bookmarks: {
        '1-bookmark1': {
          time: GSTC.api.date('2020-01-03').valueOf(),
          label: '(1) Bookmark 1'
        },
        '1-bookmark2': {
          time: GSTC.api.date('2020-01-05').valueOf(),
          label: '(1) Bookmark 2'
        }
      }
    })
  ]
};

// Generate GSTC state from configuration object
const state1 = GSTC.api.stateFromConfig(config1);

// for testing
globalThis.state1 = state1;

// Mount the component
const app1 = GSTC({
  element: document.getElementById('gstc1'),
  state: state1
});

//for testing
globalThis.gstc1 = app1;

// ------------ SECOND ONE ----------------

const rowsFromDB2 = [
  {
    id: '1',
    label: '(2) Row 1'
  },
  {
    id: '2',
    label: '(2) Row 2'
  }
];

const itemsFromDB2 = [
  {
    id: '1',
    label: '(2) Item 1',
    rowId: '1',
    time: {
      start: GSTC.api
        .date('2020-01-01')
        .startOf('day')
        .add(12, 'hour')
        .valueOf(),
      end: GSTC.api.date('2020-01-02').endOf('day').add(12, 'hour').valueOf()
    }
  },
  {
    id: '2',
    label: '(2) Item 2',
    rowId: '1',
    time: {
      start: GSTC.api
        .date('2020-02-01')
        .startOf('day')
        .add(12, 'hour')
        .valueOf(),
      end: GSTC.api.date('2020-02-02').endOf('day').add(12, 'hour').valueOf()
    }
  },
  {
    id: '3',
    label: '(2) Item 3',
    rowId: '2',
    time: {
      start: GSTC.api
        .date('2020-01-15')
        .startOf('day')
        .add(12, 'hour')
        .valueOf(),
      end: GSTC.api.date('2020-01-20').endOf('day').add(12, 'hour').valueOf()
    }
  }
];

const columnsFromDB2 = [
  {
    id: 'id',
    label: '(2) ID',
    data: ({ row }) => GSTC.api.sourceID(row.id), // show original id (not internal GSTCID)
    sortable: ({ row }) => Number(GSTC.api.sourceID(row.id)), // sort by id converted to number
    width: 80,
    header: {
      content: '(2) ID'
    }
  },
  {
    id: 'label',
    data: 'label',
    sortable: 'label',
    isHTML: false,
    width: 230,
    header: {
      content: '(2) Label'
    }
  }
];

// Configuration object
const config2 = {
  // for free key for your domain please visit https://gstc.neuronet.io/free-key
  // if you need commercial license please visit https://gantt-schedule-timeline-calendar.neuronet.io/pricing

  licenseKey:
    '====BEGIN LICENSE KEY====\n...\n====END LICENSE KEY====',

  innerHeight: 200,
  list: {
    columns: {
      data: GSTC.api.fromArray(columnsFromDB2)
    },
    rows: GSTC.api.fromArray(rowsFromDB2)
  },
  chart: {
    items: GSTC.api.fromArray(itemsFromDB2)
  },
  plugins: [
    TimeBookmarks({
      bookmarks: {
        '2-bookmark1': {
          time: GSTC.api.date('2020-01-04').valueOf(),
          label: '(2) Bookmark 1'
        },
        '2-bookmark2': {
          time: GSTC.api.date('2020-01-06').valueOf(),
          label: '(2) Bookmark 2'
        }
      }
    })
  ]
};

// Generate GSTC state from configuration object
const state2 = GSTC.api.stateFromConfig(config2);

// for testing
globalThis.state2 = state2;

// Mount the component
const app2 = GSTC({
  element: document.getElementById('gstc2'),
  state: state2
});

//for testing
globalThis.gstc2 = app2;

gantt-schedule-timeline-calendar version 3.35.4

Screenshots or movies image

However if I comment out the second component mount, you can see the time bookmarks are rendered for the first component:

// Mount the component
// const app2 = GSTC({
//   element: document.getElementById('gstc2'),
//   state: state2
// });

//for testing
// globalThis.gstc2 = app2;

image

neuronetio commented 2 months ago

fixed in 3.35.5

FabianDaniel00 commented 2 months ago

fixed in 3.35.5

Nice! Thanks, it's working as expected. 🚀