@bryntum/scheduler-vue 7.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +51 -0
  2. package/index.d.ts +74 -0
  3. package/index.js +148 -0
  4. package/license.pdf +0 -0
  5. package/licenses.md +310 -0
  6. package/package.json +22 -0
  7. package/src/BryntumAIFilterField.vue +382 -0
  8. package/src/BryntumButton.vue +342 -0
  9. package/src/BryntumButtonGroup.vue +354 -0
  10. package/src/BryntumChatPanel.vue +406 -0
  11. package/src/BryntumCheckbox.vue +384 -0
  12. package/src/BryntumCheckboxGroup.vue +414 -0
  13. package/src/BryntumChecklistFilterCombo.vue +457 -0
  14. package/src/BryntumChipView.vue +350 -0
  15. package/src/BryntumCodeEditor.vue +400 -0
  16. package/src/BryntumColorField.vue +384 -0
  17. package/src/BryntumCombo.vue +451 -0
  18. package/src/BryntumContainer.vue +339 -0
  19. package/src/BryntumDateField.vue +402 -0
  20. package/src/BryntumDatePicker.vue +480 -0
  21. package/src/BryntumDateRangeField.vue +404 -0
  22. package/src/BryntumDateTimeField.vue +362 -0
  23. package/src/BryntumDemoCodeEditor.vue +406 -0
  24. package/src/BryntumDemoHeader.vue +145 -0
  25. package/src/BryntumDisplayField.vue +372 -0
  26. package/src/BryntumDurationField.vue +396 -0
  27. package/src/BryntumEditor.vue +385 -0
  28. package/src/BryntumEventColorField.vue +384 -0
  29. package/src/BryntumFieldFilterPicker.vue +366 -0
  30. package/src/BryntumFieldFilterPickerGroup.vue +373 -0
  31. package/src/BryntumFieldSet.vue +396 -0
  32. package/src/BryntumFileField.vue +374 -0
  33. package/src/BryntumFilePicker.vue +351 -0
  34. package/src/BryntumFilterField.vue +388 -0
  35. package/src/BryntumFullscreenButton.vue +41 -0
  36. package/src/BryntumGrid.vue +819 -0
  37. package/src/BryntumGridBase.vue +816 -0
  38. package/src/BryntumGridChartDesigner.vue +295 -0
  39. package/src/BryntumGridFieldFilterPicker.vue +368 -0
  40. package/src/BryntumGridFieldFilterPickerGroup.vue +371 -0
  41. package/src/BryntumGroupBar.vue +350 -0
  42. package/src/BryntumHint.vue +417 -0
  43. package/src/BryntumLabel.vue +293 -0
  44. package/src/BryntumList.vue +344 -0
  45. package/src/BryntumMenu.vue +425 -0
  46. package/src/BryntumMonthPicker.vue +396 -0
  47. package/src/BryntumNumberField.vue +386 -0
  48. package/src/BryntumPagingToolbar.vue +358 -0
  49. package/src/BryntumPanel.vue +388 -0
  50. package/src/BryntumPasswordField.vue +370 -0
  51. package/src/BryntumProjectCombo.vue +453 -0
  52. package/src/BryntumRadio.vue +384 -0
  53. package/src/BryntumRadioGroup.vue +404 -0
  54. package/src/BryntumResourceCombo.vue +453 -0
  55. package/src/BryntumResourceFilter.vue +355 -0
  56. package/src/BryntumScheduler.vue +1563 -0
  57. package/src/BryntumSchedulerBase.vue +1561 -0
  58. package/src/BryntumSchedulerDatePicker.vue +486 -0
  59. package/src/BryntumSchedulerProjectModel.vue +211 -0
  60. package/src/BryntumSlideToggle.vue +384 -0
  61. package/src/BryntumSlider.vue +327 -0
  62. package/src/BryntumSplitter.vue +304 -0
  63. package/src/BryntumTabPanel.vue +406 -0
  64. package/src/BryntumTextAreaField.vue +374 -0
  65. package/src/BryntumTextAreaPickerField.vue +386 -0
  66. package/src/BryntumTextField.vue +378 -0
  67. package/src/BryntumTimeField.vue +396 -0
  68. package/src/BryntumTimePicker.vue +352 -0
  69. package/src/BryntumTimelineHistogram.vue +1083 -0
  70. package/src/BryntumToolbar.vue +356 -0
  71. package/src/BryntumTreeCombo.vue +451 -0
  72. package/src/BryntumTreeGrid.vue +818 -0
  73. package/src/BryntumUndoRedo.vue +347 -0
  74. package/src/BryntumViewPresetCombo.vue +362 -0
  75. package/src/BryntumWidget.vue +294 -0
  76. package/src/BryntumYearPicker.vue +403 -0
  77. package/src/WrapperHelper.js +487 -0
@@ -0,0 +1,487 @@
1
+ /**
2
+ * Vue 2 widget helper
3
+ */
4
+
5
+ import { StringHelper, Widget } from '@bryntum/scheduler';
6
+
7
+ export default function WrapperHelper() {
8
+
9
+ /**
10
+ * Development warning. Showed when environment is set to 'development'
11
+ * @param {String} clsName vue component instance
12
+ * @param {String} msg console message
13
+ */
14
+ function devWarning(clsName, msg) {
15
+ if (window.bryntum && window.bryntum.isTestEnv || process.env.NODE_ENV === 'development') {
16
+ console.warn(`Bryntum${clsName}Component development warning!\n${msg}\n` +
17
+ 'Please check Vue integration guide: https://bryntum.com/products/scheduler/docs/guide/Scheduler/integration/vue/guide'
18
+ );
19
+ }
20
+ }
21
+
22
+ function devWarningContainer(clsName, containerParam) {
23
+ devWarning(clsName,
24
+ `Using "${containerParam}" parameter for configuration is not recommended.\n` +
25
+ 'Widget is placed automatically inside it\'s container element.\n' +
26
+ `Solution: remove "${containerParam}" parameter from configuration.`
27
+ );
28
+ }
29
+
30
+ function devWarningConfigProp(clsName, prop) {
31
+ devWarning(clsName,
32
+ `Using "${prop}" parameter for configuration is not recommended.\n` +
33
+ `Solution: Use separate parameter for each "${prop}" value to enable reactive updates of the API instance`
34
+ );
35
+ }
36
+
37
+ function devWarningUpdateProp(clsName, prop) {
38
+ devWarning(clsName,
39
+ `"${prop}" is a static config option for component constructor only. No runtime changes are supported!`
40
+ );
41
+ }
42
+
43
+ /**
44
+ * Creates bryntum component config from vue component
45
+ * @param {Object} context
46
+ * @param {Object} context.me vue component instance
47
+ * @param {Object} context.props reference to props
48
+ * @param {Object} context.data reference to data
49
+ * @param {Function} context.emit reference to emit
50
+ * @param {Object} context.element HTML element
51
+ * @param {Function} context.processCellContent cell renderer method
52
+ * @param {Function} context.processEventContent event renderer method
53
+ * @param {Function} context.hasFrameworkRenderer checks presence of vue renderer
54
+ * @param {Function} context.toRaw Vue fn to unwrap reactive object
55
+ * @returns {Object} config object
56
+ */
57
+ function createConfig({ me, props, listeners, data, emit, element, processCellContent, processEventContent, hasFrameworkRenderer, toRaw }) {
58
+ const
59
+ {
60
+ instanceClass,
61
+ instanceName
62
+ } = data,
63
+ filter = arr => arr.filter(prop => props[prop] !== undefined),
64
+ configNames = filter(data.configNames || []),
65
+ propertyConfigNames = filter(data.propertyConfigNames || []),
66
+ propertyNames = filter(data.propertyNames || []),
67
+ featureNames = filter(data.featureNames || []),
68
+ eventNames = data.eventNames.filter(event => listeners[event] !== undefined || listeners[event.toLowerCase()] !== undefined),
69
+ bryntumConfig = {
70
+ vueComponent : instanceClass.isModel ? undefined : me,
71
+ listeners : {},
72
+ features : {},
73
+ processCellContent,
74
+ processEventContent,
75
+ hasFrameworkRenderer
76
+ };
77
+
78
+ // Setup events listeners
79
+ eventNames.forEach(eventName => {
80
+ const onFunctionName = `on${StringHelper.capitalize(eventName)}`;
81
+
82
+ // Vue prefixes DOM events with on, for example click becomes onClick which
83
+ // is same as our on-Function. Therefore the DOM events' handlers are called twice.
84
+ // This prevents firing the event if we already have on-Function created by Vue.
85
+ if (!props[onFunctionName]) {
86
+ bryntumConfig.listeners[eventName] = event => emit(eventName.toLowerCase(), event);
87
+ }
88
+ });
89
+
90
+ // Assign configs. Skip properties
91
+ configNames
92
+ .concat(propertyConfigNames)
93
+ .concat(featureNames)
94
+ .forEach(prop => {
95
+ applyPropValue(bryntumConfig, prop, props[prop], true, toRaw);
96
+ if (['features', 'config'].includes(prop)) {
97
+ devWarningConfigProp(instanceClass.$name, prop);
98
+ }
99
+ });
100
+
101
+ // Add vue wrapper class name
102
+ bryntumConfig.cls = (bryntumConfig.cls || '') + ` b-vue-${instanceClass.$name.toLowerCase()}-container`;
103
+
104
+ // Prepare watch arrays
105
+ data.configNames = configNames;
106
+ data.propertyNames = configNames.concat(propertyNames).concat(propertyConfigNames).concat(featureNames);
107
+
108
+ // Cleanup unused instance arrays
109
+ data.eventNames && delete data.eventNames;
110
+ data.propertyConfigNames && delete data.propertyConfigNames;
111
+ data.featureNames && delete data.featureNames;
112
+
113
+ // If component has no container specified in config then use adopt to Wrapper's element
114
+ const
115
+ containerParam = [
116
+ 'adopt',
117
+ 'appendTo',
118
+ 'insertAfter',
119
+ 'insertBefore'
120
+ ].find(prop => bryntumConfig[prop]);
121
+ if (!containerParam) {
122
+ if (instanceName === 'Button') {
123
+ // Button should always be <a> or <button> inside owner element
124
+ bryntumConfig.appendTo = element;
125
+ }
126
+ else {
127
+ bryntumConfig.adopt = element;
128
+ }
129
+ }
130
+ else {
131
+ devWarningContainer(instanceClass.$name, containerParam);
132
+ }
133
+
134
+ return bryntumConfig;
135
+ }
136
+
137
+ /**
138
+ * Setup store events relay
139
+ * @param {Object} data reference to data
140
+ * @param {Object} instance bryntum widget instance
141
+ */
142
+ function relayStores(data, instance) {
143
+ const { dataStores, projectStores } = data;
144
+
145
+ if (dataStores) {
146
+ Object.keys(dataStores).forEach(storeName => {
147
+ const store = projectStores ? instance.project[storeName] : instance[storeName];
148
+ if (store) {
149
+ if (store.syncDataOnLoad == null && !store.readUrl && !store.lazyLoad && (!store.crudManager || !store.crudManager.loadUrl)) {
150
+ // Default syncDataOnLoad to true if store is not configured with a readUrl (AjaxStore)
151
+ // and it doesn't belong to a project that has a loadUrl configured
152
+ store.syncDataOnLoad = true;
153
+ }
154
+
155
+ // Makes relaying store events configurable but off by default
156
+ if (instance && instance.relayStoreEvents) {
157
+ store.relayAll(instance, dataStores[storeName]);
158
+ }
159
+ }
160
+ });
161
+ delete data.dataStores;
162
+ }
163
+ }
164
+
165
+ /**
166
+ * Creates bryntum Widget from vue component
167
+ * @param {Object} context
168
+ * @param {Object} context.me vue component instance
169
+ * @param {Object} context.props reference to props
170
+ * @param {Object} context.data reference to data
171
+ * @param {Function} context.emit reference to emit
172
+ * @param {Object} context.element HTML element
173
+ * @param {Function} context.processCellContent cell renderer method
174
+ * @param {Function} context.hasFrameworkRenderer check the presence of vue renderer
175
+ * @param {Function} context.toRaw Vue fn to unwrap reactive object
176
+ * @returns {Object} widget object
177
+ */
178
+ function createWidget(context) {
179
+ const
180
+ { instanceClass } = context.data,
181
+ config = createConfig(context);
182
+ return instanceClass.$name === 'Widget' ? Widget.create(config) : new instanceClass(config);
183
+ }
184
+
185
+ /**
186
+ * Applies property value to Bryntum config or instance.
187
+ * @param {Object} configOrInstance target object
188
+ * @param {String} prop property name
189
+ * @param {Object} value value
190
+ * @param {Boolean} isConfig config setting mode
191
+ * @param {Function} toRaw Vue fn to unwrap reactive object
192
+ */
193
+ function applyPropValue(configOrInstance, prop, value, isConfig = true, toRaw) {
194
+
195
+ if (prop === 'project') {
196
+ // Allow use ProjectModel component as project
197
+ if (value && typeof value === 'object') {
198
+ configOrInstance[prop] = value.instance ? value.instance.value || value.instance : value;
199
+ }
200
+ }
201
+ else if (prop === 'features' && typeof value === 'object') {
202
+ Object.keys(value).forEach(key => applyPropValue(configOrInstance, `${key}Feature`, value[key], isConfig, toRaw));
203
+ }
204
+ else if (prop === 'config' && typeof value === 'object') {
205
+ Object.keys(value).forEach(key => applyPropValue(configOrInstance, key, value[key], isConfig, toRaw));
206
+ }
207
+ else if (prop === 'columns' && !isConfig) {
208
+ configOrInstance['columns'].data = value;
209
+ }
210
+ else if (prop.endsWith('Feature')) {
211
+ const
212
+ features = configOrInstance['features'],
213
+ featureName = prop.replace('Feature', '');
214
+ if (isConfig) {
215
+ features[featureName] = value;
216
+ }
217
+ else {
218
+ const feature = features[featureName];
219
+ if (feature) {
220
+ feature.setConfig(value);
221
+ }
222
+ }
223
+ }
224
+ else {
225
+ configOrInstance[prop] = toRaw ? toRaw(value) : value;
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Creates watches for vue component properties
231
+ * @param {Object} me vue component instance
232
+ * @param {Object} instance bryntum widget instance
233
+ * @param {Object} props reference to props
234
+ * @param {Object} data reference to data
235
+ * @param {Function} watcher watch method reference (Accepts: prop and newValue)
236
+ */
237
+ function watchProps(me, instance, props, data, watcher) {
238
+ const
239
+ {
240
+ configNames,
241
+ propertyNames,
242
+ instanceClass
243
+ } = data;
244
+
245
+ propertyNames.forEach(prop => watcher(prop, newValue => {
246
+ const value = Array.isArray(newValue) ? newValue.slice() : newValue;
247
+ applyPropValue(instance, prop, value, false);
248
+
249
+ // Check if property is a config and notify
250
+ if (configNames.includes(prop)) {
251
+ devWarningUpdateProp(instanceClass.$name, prop);
252
+ }
253
+ }));
254
+
255
+ // Cleanup unused instance arrays
256
+ delete data.configNames;
257
+ delete data.propertyNames;
258
+ }
259
+
260
+ /**
261
+ * Returns `true` if the provided configuration object is valid for Vue processing.
262
+ * @param {*} config
263
+ * @returns {Boolean}
264
+ */
265
+ function isVueConfig(config) {
266
+ return Boolean(config && config.vue);
267
+ }
268
+
269
+ /**
270
+ *
271
+ * @param { Object } context
272
+ * @param { * } context.cellContent Content to be rendered in cell (set by renderer)
273
+ * @param { Column } context.column Column being rendered
274
+ * @returns { Boolean } `true` if there is a Vue Renderer in this cell, `false` otherwise
275
+ */
276
+ function hasFrameworkRenderer({ cellContent, column }) {
277
+ return (
278
+ cellContent &&
279
+ typeof cellContent === 'object' &&
280
+ column.data.vue
281
+ );
282
+ }
283
+
284
+ /**
285
+ * https://github.com/bryntum/support/issues/10416
286
+ *
287
+ * @param { Object} context }
288
+ * @param { String } context.action The requested action
289
+ * @param { Object } context.domConfig
290
+ * @param { Boolean } context.isRelease This is a "release" call
291
+ * @param { Object } context.jsx That what is returned by the user's eventRenderer function
292
+ * @param { Boolean } context.scrolling `true` if this a "scrolling" call
293
+ * @param { HTMLElement } context.targetElement Element to render to
294
+ * @returns { Boolean } `true` if the function set the content, `false` otherwise
295
+ */
296
+ function processEventContent({
297
+ action,
298
+ domConfig,
299
+ isRelease,
300
+ // Core passes it as jsx for React wrappers.
301
+ // Let's rename it to a more appropriate name.
302
+ jsx : rendererConfig,
303
+ scrolling,
304
+ targetElement
305
+ }) {
306
+ const
307
+ me = this,
308
+ { instance : scheduler, $refs } = me,
309
+ { eventResize } = scheduler && scheduler.features ? scheduler.features : {};
310
+
311
+ // Early return if no action or resizing or we haven't got a proper instance (can happen for calendar)
312
+ // if (['none', 'removeElement'].includes(action) || (eventResize?.isResizing && !eventResize.dragging.completed && !scrolling)) {
313
+ if (!eventResize || ['none', 'removeElement'].includes(action) || (eventResize.isResizing && !eventResize.dragging.completed && !scrolling)) {
314
+ return false;
315
+ }
316
+
317
+ const
318
+ { vueInstance } = targetElement,
319
+ // domConfigData = scheduler.isVertical ? domConfig?.elementData?.renderData : domConfig?.elementData,
320
+ domConfigData = scheduler.isVertical ? (domConfig.elementData ? domConfig.elementData.renderData : false) : domConfig.elementData,
321
+ // Get wrap that contains the important data
322
+ // wrap = domConfig?.dataset?.isMilestone
323
+ wrap = (domConfig.dataset ? domConfig.dataset.isMilestone : false)
324
+ ? targetElement.parentElement.parentElement.parentElement
325
+ : targetElement.parentElement.parentElement,
326
+ // Get data
327
+ wrapData = scheduler.isVertical ? wrap.elementData.renderData : wrap.elementData,
328
+ // Get records
329
+ { assignmentRecord, eventRecord } = isRelease ? domConfigData || {} : wrapData || {},
330
+ // Calculate key
331
+ key = assignmentRecord ? `assignment-${assignmentRecord.id}` : null;
332
+
333
+ let [existing] = $refs[key] || [];
334
+
335
+ // If the targetElement has vueInstance, move its element out of way
336
+ if (vueInstance) {
337
+ $refs.cellInstancesHolder.appendChild(vueInstance.$el);
338
+ delete targetElement.vueInstance;
339
+ }
340
+
341
+ // If we have an existing vueInstance make it visible
342
+ if (!isRelease && existing) {
343
+ targetElement.appendChild(existing.$el);
344
+ targetElement.vueInstance = existing;
345
+ }
346
+
347
+ // Create or re-create the vueInstance as needed
348
+ if (isVueConfig(rendererConfig) && (rendererConfig ? rendererConfig.is : false)) {
349
+ const { cellInstances } = me;
350
+
351
+ // Remove the existing vueInstance if the eventRecord has been updated
352
+ if (existing && existing.generation !== eventRecord.generation) {
353
+ const eventIndex = cellInstances.findIndex(item => item.key === key);
354
+ if (eventIndex !== -1) {
355
+ cellInstances.splice(eventIndex, 1);
356
+ }
357
+ // removeEventComponent.call(me, key);
358
+ existing = null;
359
+ }
360
+ // No existing instance, create a new one and pull its element in on next Vue tick
361
+ if (!existing) {
362
+
363
+ // Data from the renderer that will be turned into a vue instance by the v-for in App.vue
364
+ cellInstances.push({ ...rendererConfig, key });
365
+
366
+ // Wait until the vue component is mounted
367
+ me.$nextTick(() => {
368
+ // Get the newly rendered Vue component (refs in v-for are arrays)
369
+ const [instance] = $refs[key];
370
+
371
+ if (instance) {
372
+ instance.$el.retainElement = true;
373
+ targetElement.appendChild(instance.$el);
374
+
375
+ instance.generation = eventRecord.generation;
376
+ targetElement.vueInstance = instance;
377
+ }
378
+ });
379
+ }
380
+ domConfig.retainChildren = true;
381
+ return true;
382
+ }
383
+
384
+ return false;
385
+ }
386
+
387
+ /**
388
+ * Hook called by instance when rendering cells within
389
+ * Row::renderCell(), creates portals for JSX supplied by renderers
390
+ * @param {Object} context
391
+ * @param {Object} context.rendererData Data passed from renderCell
392
+ * @param {Object} context.rendererHtml Data passed from renderCell
393
+ */
394
+ function processCellContent({
395
+ rendererData,
396
+ rendererData : { record },
397
+ rendererData : { cellElement },
398
+ rendererHtml : cellContent
399
+ }) {
400
+ if (!isVueConfig(rendererData.column.data) || record.isSpecialRow || typeof cellContent !== 'object') {
401
+ return true;
402
+ }
403
+
404
+ const // Bound array of cell components + refs from the Grid Vue component
405
+ me = this,
406
+ { cellInstances, $refs } = me,
407
+ // Vue component currently displayed in the cell
408
+ { vueInstance } = cellElement,
409
+ // Key, used as both key and ref
410
+ key = `${rendererData.column.id}-${record.id}`,
411
+ // Reuse already existing component for this cell (refs in v-for are arrays)
412
+ [existing] = $refs[key] || [];
413
+
414
+ // Cell has a vue instance associated with it, move its element back to the cell instance container before
415
+ // adding a new instance. It will be pulled in again if another cell renders the same record later
416
+ if (vueInstance) {
417
+ $refs.cellInstancesHolder.appendChild(vueInstance.$el);
418
+
419
+ // If we're removing vue element from the cell, we need to remove references to it and from it, so
420
+ // current cell doesn't know about vueInstance and vueInstance doesn't know about cell it was rendered to
421
+ if (vueInstance.cellElement) {
422
+ delete vueInstance.cellElement.vueInstance;
423
+ }
424
+ delete vueInstance.cellElement;
425
+ }
426
+
427
+ // There is an existing instance previously rendered, pull its element in from the cell instance container
428
+ if (existing) {
429
+ // `existing` is a VueComponent.
430
+ // `existing.$props.record` is the record which holds the data to render into the component.
431
+ // Note, if store.syncDataOnLoad is falsy and you load the data with the same ID,
432
+ // the record and existing.$props.record will be different objects, and existing.$props.record
433
+ // will hold the old value. Make sure `syncDataOnLoad` is true.
434
+
435
+ // Move its element to the cell
436
+ cellElement.appendChild(existing.$el);
437
+
438
+ // Remember that cell is displaying it
439
+ cellElement.vueInstance = existing;
440
+
441
+ // When reassigning cell remove reference to the vueInstance from the previous cellElement
442
+ if (existing.cellElement) {
443
+ delete existing.cellElement.vueInstance;
444
+ }
445
+
446
+ existing.cellElement = cellElement;
447
+ }
448
+ // No existing instance, create a new one and pull its element in on next Vue tick
449
+ else {
450
+ // Data from the renderer that will be turned into a vue instance by the v-for in App.vue
451
+ cellInstances.push({ ...cellContent, key });
452
+
453
+ // Wait until the vue component is mounted
454
+ me.$nextTick(() => {
455
+ // Get the newly rendered Vue component (refs in v-for are arrays)
456
+ const [instance] = $refs[key];
457
+
458
+ // Move its element to the cell
459
+ cellElement.appendChild(instance.$el);
460
+ // Remember that cell is displaying it
461
+ cellElement.vueInstance = instance;
462
+
463
+ // Let vue instance to know about the cell it is rendered to, so when it gets moved to cache it can
464
+ // clear itself from the cellElement
465
+ instance.cellElement = cellElement;
466
+ });
467
+ }
468
+ return false;
469
+ }
470
+
471
+ return {
472
+ createWidget,
473
+ hasFrameworkRenderer,
474
+ isVueConfig,
475
+ processCellContent,
476
+ processEventContent,
477
+ relayStores,
478
+ watchProps
479
+ };
480
+
481
+ }
482
+
483
+ // Expose wrapper methods on window.bryntum
484
+ window.bryntum = window.bryntum || {};
485
+ window.bryntum.vue = {
486
+ isVueConfig : WrapperHelper().isVueConfig
487
+ };