Skip to content

Commit 127719f

Browse files
committed
fix ag-grid renderer
1 parent ff2cc3b commit 127719f

File tree

1 file changed

+79
-17
lines changed

1 file changed

+79
-17
lines changed

packages/jsonforms-vuetify-renderers/src/renderers/AgGridArrayControlRenderer.vue

Lines changed: 79 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ import { useIcons } from '@/icons';
114114
import {
115115
composePaths,
116116
createDefaultValue,
117+
mapStateToArrayControlProps,
117118
type ControlElement,
118119
} from '@jsonforms/core';
119120
import {
@@ -128,6 +129,7 @@ import type {
128129
ColDef,
129130
ColGroupDef,
130131
FilterChangedEvent,
132+
GetRowIdFunc,
131133
GridApi,
132134
GridOptions,
133135
GridReadyEvent,
@@ -139,6 +141,7 @@ import type {
139141
Theme,
140142
} from 'ag-grid-community';
141143
import startCase from 'lodash/startCase';
144+
import uniqueId from 'lodash/uniqueId';
142145
import {
143146
computed,
144147
defineAsyncComponent,
@@ -181,6 +184,7 @@ const AgGridVue = defineAsyncComponent(() =>
181184
RowSelectionModule,
182185
TextEditorModule,
183186
TextFilterModule,
187+
TooltipModule,
184188
ValidationModule,
185189
ModuleRegistry,
186190
themeQuartz,
@@ -199,6 +203,7 @@ const AgGridVue = defineAsyncComponent(() =>
199203
RowSelectionModule,
200204
TextEditorModule,
201205
TextFilterModule,
206+
TooltipModule,
202207
ValidationModule,
203208
]);
204209
@@ -213,6 +218,13 @@ function isColDef(col: ColDef | ColGroupDef): col is ColDef {
213218
return !('children' in col);
214219
}
215220
221+
const rowIdSymbol = Symbol('rowId');
222+
function ensureRowId(row: object) {
223+
if (!(row as any)[rowIdSymbol]) {
224+
(row as any)[rowIdSymbol] = uniqueId();
225+
}
226+
}
227+
216228
const components = {
217229
DispatchRendererCell: defineComponent({
218230
name: 'DispatchRendererCell',
@@ -222,38 +234,45 @@ const components = {
222234
type: Object as PropType<
223235
ICellRendererParams & {
224236
propertyName: string;
225-
input: ReturnType<typeof useVuetifyArrayControl> &
226-
ReturnType<typeof useJsonFormsArrayControl>;
237+
control: ReturnType<typeof mapStateToArrayControlProps>;
227238
}
228239
>,
229240
required: true,
230241
},
231242
},
232243
setup({ params }) {
233244
return () => {
234-
const { propertyName, node, input } = params;
235-
236-
const control = input.control;
245+
const { propertyName, node, control } = params;
237246
const controlWithoutLabel = (scope: string): ControlElement => {
238247
return { type: 'Control', scope: scope, label: false };
239248
};
240249
241250
function resolveUiSchema(propName: string) {
242-
return control.value.schema.properties && propName
251+
return control.schema.properties && propName
243252
? controlWithoutLabel(`#/properties/${propName}`)
244253
: controlWithoutLabel('#');
245254
}
246255
247256
return h(DispatchRenderer, {
248-
schema: control.value.schema,
257+
schema: control.schema,
249258
uischema: resolveUiSchema(propertyName),
250-
path: composePaths(control.value.path, `${node.rowIndex}`),
251-
enabled: control.value.enabled,
252-
renderers: control.value.renderers,
253-
cells: control.value.cells,
259+
path: composePaths(control.path, `${node.sourceRowIndex}`),
260+
enabled: control.enabled,
261+
renderers: control.renderers,
262+
cells: control.cells,
254263
});
255264
};
256265
},
266+
methods: {
267+
// ag grid will check if we have a refresh function that will return true then it will reuse the renderer instead of recreating it
268+
refresh(
269+
_params: ICellRendererParams<any, any, any> & {
270+
propertyName: string;
271+
},
272+
) {
273+
return true;
274+
},
275+
},
257276
}),
258277
};
259278
@@ -297,14 +316,38 @@ const AgGridArrayControlRenderer = defineComponent({
297316
298317
const suppressRowDrag = ref(!input.control.value.enabled);
299318
319+
const schema = ref(input.control.value.schema);
320+
watch(
321+
() => input.control.value.schema,
322+
(newSchema) => {
323+
schema.value = newSchema;
324+
},
325+
);
326+
const showSortButtons = ref(input.appliedOptions.value.showSortButtons);
327+
watch(
328+
() => input.appliedOptions.value.showSortButtons,
329+
(newValue) => {
330+
showSortButtons.value = newValue;
331+
},
332+
);
333+
const enabled = ref(input.control.value.enabled);
334+
watch(
335+
() => input.control.value.enabled,
336+
(newValue) => {
337+
enabled.value = newValue;
338+
},
339+
);
340+
300341
const gridOptions = computed<GridOptions>(() => {
301342
const baseOptions: GridOptions =
302343
props.uischema?.options?.agGridOptions || {};
303344
304-
const showSortButtons = ref(input.appliedOptions.value.showSortButtons);
345+
let haveRowDragColumn = false;
305346
// Generate columnDefs from schema
306347
const schemaColumnDefs: ColDef[] = Object.entries(
307-
input.control.value.schema.properties || {},
348+
schema.value.type === 'object'
349+
? schema.value.properties || {}
350+
: { '': { title: '' } }, // primitive
308351
).map(([propertyName, propertySchema]: [string, any]) => {
309352
const baseDef: ColDef = {
310353
headerName: propertySchema.title ?? startCase(propertyName),
@@ -320,7 +363,7 @@ const AgGridArrayControlRenderer = defineComponent({
320363
321364
if (isColDef(extraDef) && extraDef.rowDrag) {
322365
// another column is designated as reordering column
323-
showSortButtons.value = false;
366+
haveRowDragColumn = true;
324367
}
325368
326369
const cellDef = isColDef(extraDef)
@@ -335,10 +378,13 @@ const AgGridArrayControlRenderer = defineComponent({
335378
component: 'DispatchRendererCell',
336379
params: {
337380
propertyName,
338-
input: input,
381+
control: input.control.value,
339382
},
340383
};
341384
},
385+
cellRendererParams: {
386+
deferRender: true,
387+
},
342388
}
343389
: {};
344390
@@ -351,7 +397,7 @@ const AgGridArrayControlRenderer = defineComponent({
351397
352398
const schemaColumnDefsControls: ColDef[] = [];
353399
354-
if (input.control.value.enabled && showSortButtons.value) {
400+
if (enabled.value && showSortButtons.value && !haveRowDragColumn) {
355401
schemaColumnDefsControls.push({
356402
headerName: '',
357403
rowDrag: true,
@@ -364,6 +410,21 @@ const AgGridArrayControlRenderer = defineComponent({
364410
}
365411
366412
delete baseOptions.rowData;
413+
414+
let getRowId: GetRowIdFunc | undefined = undefined;
415+
if (schema.value.type === 'object' || schema.value.type === 'array') {
416+
getRowId = (params) => {
417+
const data = params.data;
418+
if (typeof data === 'object' && data !== null) {
419+
ensureRowId(data);
420+
return (data as any)[rowIdSymbol];
421+
} else {
422+
// fallback
423+
return String(data);
424+
}
425+
};
426+
}
427+
367428
return {
368429
...baseOptions,
369430
columnDefs: [...schemaColumnDefsControls, ...schemaColumnDefs],
@@ -375,6 +436,7 @@ const AgGridArrayControlRenderer = defineComponent({
375436
},
376437
components,
377438
suppressRowDrag: baseOptions.suppressRowDrag || suppressRowDrag.value,
439+
getRowId: getRowId,
378440
};
379441
});
380442
@@ -406,7 +468,7 @@ const AgGridArrayControlRenderer = defineComponent({
406468
};
407469
408470
const onRowDragEnd = (event: RowDragEndEvent) => {
409-
const fromIndex = event.node.rowIndex ?? -1;
471+
const fromIndex = event.node.sourceRowIndex ?? -1;
410472
const toIndex = event.overIndex;
411473
if (fromIndex === -1 || event.overIndex === -1 || fromIndex === toIndex) {
412474
return;

0 commit comments

Comments
 (0)