@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.
- package/README.md +51 -0
- package/index.d.ts +74 -0
- package/index.js +148 -0
- package/license.pdf +0 -0
- package/licenses.md +310 -0
- package/package.json +22 -0
- package/src/BryntumAIFilterField.vue +382 -0
- package/src/BryntumButton.vue +342 -0
- package/src/BryntumButtonGroup.vue +354 -0
- package/src/BryntumChatPanel.vue +406 -0
- package/src/BryntumCheckbox.vue +384 -0
- package/src/BryntumCheckboxGroup.vue +414 -0
- package/src/BryntumChecklistFilterCombo.vue +457 -0
- package/src/BryntumChipView.vue +350 -0
- package/src/BryntumCodeEditor.vue +400 -0
- package/src/BryntumColorField.vue +384 -0
- package/src/BryntumCombo.vue +451 -0
- package/src/BryntumContainer.vue +339 -0
- package/src/BryntumDateField.vue +402 -0
- package/src/BryntumDatePicker.vue +480 -0
- package/src/BryntumDateRangeField.vue +404 -0
- package/src/BryntumDateTimeField.vue +362 -0
- package/src/BryntumDemoCodeEditor.vue +406 -0
- package/src/BryntumDemoHeader.vue +145 -0
- package/src/BryntumDisplayField.vue +372 -0
- package/src/BryntumDurationField.vue +396 -0
- package/src/BryntumEditor.vue +385 -0
- package/src/BryntumEventColorField.vue +384 -0
- package/src/BryntumFieldFilterPicker.vue +366 -0
- package/src/BryntumFieldFilterPickerGroup.vue +373 -0
- package/src/BryntumFieldSet.vue +396 -0
- package/src/BryntumFileField.vue +374 -0
- package/src/BryntumFilePicker.vue +351 -0
- package/src/BryntumFilterField.vue +388 -0
- package/src/BryntumFullscreenButton.vue +41 -0
- package/src/BryntumGrid.vue +819 -0
- package/src/BryntumGridBase.vue +816 -0
- package/src/BryntumGridChartDesigner.vue +295 -0
- package/src/BryntumGridFieldFilterPicker.vue +368 -0
- package/src/BryntumGridFieldFilterPickerGroup.vue +371 -0
- package/src/BryntumGroupBar.vue +350 -0
- package/src/BryntumHint.vue +417 -0
- package/src/BryntumLabel.vue +293 -0
- package/src/BryntumList.vue +344 -0
- package/src/BryntumMenu.vue +425 -0
- package/src/BryntumMonthPicker.vue +396 -0
- package/src/BryntumNumberField.vue +386 -0
- package/src/BryntumPagingToolbar.vue +358 -0
- package/src/BryntumPanel.vue +388 -0
- package/src/BryntumPasswordField.vue +370 -0
- package/src/BryntumProjectCombo.vue +453 -0
- package/src/BryntumRadio.vue +384 -0
- package/src/BryntumRadioGroup.vue +404 -0
- package/src/BryntumResourceCombo.vue +453 -0
- package/src/BryntumResourceFilter.vue +355 -0
- package/src/BryntumScheduler.vue +1563 -0
- package/src/BryntumSchedulerBase.vue +1561 -0
- package/src/BryntumSchedulerDatePicker.vue +486 -0
- package/src/BryntumSchedulerProjectModel.vue +211 -0
- package/src/BryntumSlideToggle.vue +384 -0
- package/src/BryntumSlider.vue +327 -0
- package/src/BryntumSplitter.vue +304 -0
- package/src/BryntumTabPanel.vue +406 -0
- package/src/BryntumTextAreaField.vue +374 -0
- package/src/BryntumTextAreaPickerField.vue +386 -0
- package/src/BryntumTextField.vue +378 -0
- package/src/BryntumTimeField.vue +396 -0
- package/src/BryntumTimePicker.vue +352 -0
- package/src/BryntumTimelineHistogram.vue +1083 -0
- package/src/BryntumToolbar.vue +356 -0
- package/src/BryntumTreeCombo.vue +451 -0
- package/src/BryntumTreeGrid.vue +818 -0
- package/src/BryntumUndoRedo.vue +347 -0
- package/src/BryntumViewPresetCombo.vue +362 -0
- package/src/BryntumWidget.vue +294 -0
- package/src/BryntumYearPicker.vue +403 -0
- 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
|
+
};
|