@rakun-kit/manager-react 1.4.4 → 1.4.6
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/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/DynamicDataControl.js +369 -106
- package/dist/cjs/router/dashboard/[contentType]/[edit]/_fields/DynamicDataControl.js.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/DynamicDataControl.d.ts +21 -0
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/DynamicDataControl.d.ts.map +1 -1
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/DynamicDataControl.js +361 -98
- package/dist/esm/router/dashboard/[contentType]/[edit]/_fields/DynamicDataControl.js.map +1 -1
- package/dist/styles.css +11 -7
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
'use client';
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.DynamicDataControl = exports.isDynamicFieldEnabled = void 0;
|
|
4
|
+
exports.DynamicDataControl = exports.buildFilter = exports.readFilterState = exports.sourceFieldOptions = exports.isDynamicFieldEnabled = void 0;
|
|
5
5
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
6
|
const client_1 = require("@rakun-kit/core/client");
|
|
7
7
|
const lucide_react_1 = require("lucide-react");
|
|
@@ -73,10 +73,7 @@ const isCompatibleSourceKind = (sourceKind, targetField) => {
|
|
|
73
73
|
return sourceKind !== 'object' && sourceKind !== 'array';
|
|
74
74
|
return sourceKind === getFieldKind(targetField);
|
|
75
75
|
};
|
|
76
|
-
const
|
|
77
|
-
field.isMultiple
|
|
78
|
-
? field
|
|
79
|
-
: undefined;
|
|
76
|
+
const getFileField = (field) => field.config.type === 'File' ? field : undefined;
|
|
80
77
|
const areFieldKindsCompatible = (sourceField, targetField) => {
|
|
81
78
|
const sourceKind = getFieldKind(sourceField);
|
|
82
79
|
if (!targetField)
|
|
@@ -84,23 +81,19 @@ const areFieldKindsCompatible = (sourceField, targetField) => {
|
|
|
84
81
|
const targetKind = getFieldKind(targetField);
|
|
85
82
|
if (sourceKind !== targetKind)
|
|
86
83
|
return false;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const sourceFile = getMultipleFileField(sourceField);
|
|
90
|
-
const targetFile = getMultipleFileField(targetField);
|
|
84
|
+
const sourceFile = getFileField(sourceField);
|
|
85
|
+
const targetFile = getFileField(targetField);
|
|
91
86
|
if (!sourceFile && !targetFile)
|
|
92
87
|
return true;
|
|
93
88
|
if (!sourceFile || !targetFile)
|
|
94
89
|
return false;
|
|
95
|
-
return (sourceFile.
|
|
96
|
-
|
|
97
|
-
|
|
90
|
+
return (sourceFile.isMultiple === targetFile.isMultiple &&
|
|
91
|
+
(sourceFile.mediaType === 'Any' ||
|
|
92
|
+
targetFile.mediaType === 'Any' ||
|
|
93
|
+
sourceFile.mediaType === targetFile.mediaType));
|
|
98
94
|
};
|
|
99
95
|
const fieldLabel = (path) => path.startsWith('_seo.') ? `seo.${path.slice('_seo.'.length)}` : path;
|
|
100
|
-
const isSeoPath = (path) => path === '_seo' ||
|
|
101
|
-
path === 'seo' ||
|
|
102
|
-
path.startsWith('_seo.') ||
|
|
103
|
-
path.startsWith('seo.');
|
|
96
|
+
const isSeoPath = (path) => path.split('.').some((segment) => segment === '_seo' || segment === 'seo');
|
|
104
97
|
const fileFieldOptions = (path, targetField) => {
|
|
105
98
|
const options = [
|
|
106
99
|
{ label: fieldLabel(`${path}.url`), value: `${path}.url`, kind: 'string' },
|
|
@@ -141,27 +134,38 @@ const nestedSourceFieldOptions = ({ contentType, prefix = '', targetField, depth
|
|
|
141
134
|
return [];
|
|
142
135
|
if (field.config.type === 'Relation' && depth < 3) {
|
|
143
136
|
const relationContentType = field.contentType;
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if (!areFieldKindsCompatible(field, targetField))
|
|
154
|
-
return [];
|
|
137
|
+
const idOption = isCompatibleSourceKind('string', targetField)
|
|
138
|
+
? [
|
|
139
|
+
{
|
|
140
|
+
label: fieldLabel(`${path}._id`),
|
|
141
|
+
value: `${path}._id`,
|
|
142
|
+
kind: 'string',
|
|
143
|
+
},
|
|
144
|
+
]
|
|
145
|
+
: [];
|
|
155
146
|
return [
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
147
|
+
...idOption,
|
|
148
|
+
...nestedSourceFieldOptions({
|
|
149
|
+
contentType: relationContentType,
|
|
150
|
+
prefix: path,
|
|
151
|
+
targetField,
|
|
152
|
+
depth: depth + 1,
|
|
153
|
+
}),
|
|
161
154
|
];
|
|
162
155
|
}
|
|
163
156
|
if (field.config.type === 'File') {
|
|
164
|
-
|
|
157
|
+
const fieldOption = areFieldKindsCompatible(field, targetField)
|
|
158
|
+
? [
|
|
159
|
+
{
|
|
160
|
+
label: fieldLabel(path),
|
|
161
|
+
value: path,
|
|
162
|
+
kind,
|
|
163
|
+
},
|
|
164
|
+
]
|
|
165
|
+
: [];
|
|
166
|
+
if (field.isMultiple)
|
|
167
|
+
return fieldOption;
|
|
168
|
+
return [...fieldOption, ...fileFieldOptions(path, targetField)];
|
|
165
169
|
}
|
|
166
170
|
if (!areFieldKindsCompatible(field, targetField))
|
|
167
171
|
return [];
|
|
@@ -183,6 +187,7 @@ const sourceFieldOptions = (contentType, targetField) => {
|
|
|
183
187
|
? [{ label: 'href', value: '$href', kind: 'string' }, ...fields]
|
|
184
188
|
: fields;
|
|
185
189
|
};
|
|
190
|
+
exports.sourceFieldOptions = sourceFieldOptions;
|
|
186
191
|
const createSource = (contentType, value, id) => value === '$href'
|
|
187
192
|
? { contentType, id, virtual: 'href' }
|
|
188
193
|
: { contentType, id, path: value };
|
|
@@ -212,17 +217,55 @@ const sourceContentTypeLabel = (source, documentContentTypeName) => source.conte
|
|
|
212
217
|
? 'Current document'
|
|
213
218
|
: source.contentType;
|
|
214
219
|
const getSourceContentTypes = (contentTypes) => contentTypes.filter((sourceContentType) => (0, client_1.isDynamicDataSourceContentTypeAllowed)(sourceContentType));
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
+
const operatorByMongoOperator = {
|
|
221
|
+
$eq: 'equals',
|
|
222
|
+
$ne: 'notEquals',
|
|
223
|
+
$contains: 'contains',
|
|
224
|
+
$in: 'in',
|
|
225
|
+
$nin: 'notIn',
|
|
226
|
+
$gt: 'greaterThan',
|
|
227
|
+
$gte: 'greaterThanOrEqual',
|
|
228
|
+
$lt: 'lessThan',
|
|
229
|
+
$lte: 'lessThanOrEqual',
|
|
230
|
+
};
|
|
231
|
+
const readFilterOperand = (value) => {
|
|
232
|
+
if (isRecord(value) &&
|
|
233
|
+
typeof value[client_1.DYNAMIC_QUERY_CURRENT_VALUE_KEY] === 'string') {
|
|
234
|
+
return {
|
|
235
|
+
value: value[client_1.DYNAMIC_QUERY_CURRENT_VALUE_KEY],
|
|
236
|
+
valueSource: 'current',
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
value: Array.isArray(value) ? value.join(', ') : String(value ?? ''),
|
|
241
|
+
};
|
|
242
|
+
};
|
|
243
|
+
const filterConditionFromEntry = (field, value) => {
|
|
220
244
|
if (value === true)
|
|
221
245
|
return { field, operator: 'true', value: '' };
|
|
222
246
|
if (value === false)
|
|
223
247
|
return { field, operator: 'false', value: '' };
|
|
224
|
-
|
|
225
|
-
|
|
248
|
+
const directOperand = readFilterOperand(value);
|
|
249
|
+
if (directOperand.valueSource === 'current') {
|
|
250
|
+
return { field, operator: 'equals', ...directOperand };
|
|
251
|
+
}
|
|
252
|
+
if (isRecord(value)) {
|
|
253
|
+
if (typeof value.$exists === 'boolean') {
|
|
254
|
+
return {
|
|
255
|
+
field,
|
|
256
|
+
operator: value.$exists ? 'exists' : 'notExists',
|
|
257
|
+
value: '',
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
const operatorEntry = Object.entries(value).find(([operator]) => operator in operatorByMongoOperator);
|
|
261
|
+
if (operatorEntry) {
|
|
262
|
+
const [operator, operatorValue] = operatorEntry;
|
|
263
|
+
return {
|
|
264
|
+
field,
|
|
265
|
+
operator: operatorByMongoOperator[operator],
|
|
266
|
+
...readFilterOperand(operatorValue),
|
|
267
|
+
};
|
|
268
|
+
}
|
|
226
269
|
}
|
|
227
270
|
return {
|
|
228
271
|
field,
|
|
@@ -230,31 +273,124 @@ const readFilterState = (filter) => {
|
|
|
230
273
|
value: typeof value === 'string' ? value : String(value ?? ''),
|
|
231
274
|
};
|
|
232
275
|
};
|
|
233
|
-
const
|
|
234
|
-
if (!
|
|
235
|
-
return
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
276
|
+
const readFilterState = (filter) => {
|
|
277
|
+
if (!filter)
|
|
278
|
+
return { combinator: 'and', conditions: [] };
|
|
279
|
+
const logicalEntry = ['$and', '$or'].find((key) => Array.isArray(filter[key]));
|
|
280
|
+
if (logicalEntry) {
|
|
281
|
+
const conditions = filter[logicalEntry].flatMap((item) => isRecord(item)
|
|
282
|
+
? Object.entries(item)
|
|
283
|
+
.filter(([field]) => !field.startsWith('$'))
|
|
284
|
+
.map(([field, value]) => filterConditionFromEntry(field, value))
|
|
285
|
+
: []);
|
|
286
|
+
return {
|
|
287
|
+
combinator: logicalEntry === '$or' ? 'or' : 'and',
|
|
288
|
+
conditions,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
return {
|
|
292
|
+
combinator: 'and',
|
|
293
|
+
conditions: Object.entries(filter)
|
|
294
|
+
.filter(([field]) => !field.startsWith('$'))
|
|
295
|
+
.map(([field, value]) => filterConditionFromEntry(field, value)),
|
|
296
|
+
};
|
|
297
|
+
};
|
|
298
|
+
exports.readFilterState = readFilterState;
|
|
299
|
+
const operatorNeedsValue = (operator) => !['true', 'false', 'exists', 'notExists'].includes(operator);
|
|
300
|
+
const parseFilterValue = (condition, fieldOptions) => {
|
|
301
|
+
const kind = fieldOptions.find((option) => option.value === condition.field)?.kind;
|
|
302
|
+
const parseValue = (value) => kind === 'number' && value.trim() !== '' && Number.isFinite(Number(value))
|
|
303
|
+
? Number(value)
|
|
304
|
+
: value.trim();
|
|
305
|
+
if (condition.operator === 'in' || condition.operator === 'notIn') {
|
|
306
|
+
return condition.value
|
|
307
|
+
.split(',')
|
|
308
|
+
.map((value) => value.trim())
|
|
309
|
+
.filter(Boolean)
|
|
310
|
+
.map(parseValue);
|
|
311
|
+
}
|
|
312
|
+
return parseValue(condition.value);
|
|
313
|
+
};
|
|
314
|
+
const buildFilterCondition = (condition, fieldOptions) => {
|
|
315
|
+
if (!condition.field)
|
|
241
316
|
return undefined;
|
|
242
|
-
if (
|
|
243
|
-
return { [
|
|
317
|
+
if (condition.operator === 'true')
|
|
318
|
+
return { [condition.field]: true };
|
|
319
|
+
if (condition.operator === 'false')
|
|
320
|
+
return { [condition.field]: false };
|
|
321
|
+
if (condition.operator === 'exists') {
|
|
322
|
+
return { [condition.field]: { $exists: true } };
|
|
323
|
+
}
|
|
324
|
+
if (condition.operator === 'notExists') {
|
|
325
|
+
return { [condition.field]: { $exists: false } };
|
|
244
326
|
}
|
|
245
|
-
|
|
327
|
+
if (!condition.value.trim())
|
|
328
|
+
return undefined;
|
|
329
|
+
const value = condition.valueSource === 'current'
|
|
330
|
+
? { [client_1.DYNAMIC_QUERY_CURRENT_VALUE_KEY]: condition.value }
|
|
331
|
+
: parseFilterValue(condition, fieldOptions);
|
|
332
|
+
const mongoOperator = {
|
|
333
|
+
notEquals: '$ne',
|
|
334
|
+
contains: '$contains',
|
|
335
|
+
in: '$in',
|
|
336
|
+
notIn: '$nin',
|
|
337
|
+
greaterThan: '$gt',
|
|
338
|
+
greaterThanOrEqual: '$gte',
|
|
339
|
+
lessThan: '$lt',
|
|
340
|
+
lessThanOrEqual: '$lte',
|
|
341
|
+
};
|
|
342
|
+
const operator = mongoOperator[condition.operator];
|
|
343
|
+
return operator
|
|
344
|
+
? { [condition.field]: { [operator]: value } }
|
|
345
|
+
: { [condition.field]: value };
|
|
346
|
+
};
|
|
347
|
+
const buildFilter = (state, fieldOptions = []) => {
|
|
348
|
+
const conditions = state.conditions.flatMap((condition) => {
|
|
349
|
+
const builtCondition = buildFilterCondition(condition, fieldOptions);
|
|
350
|
+
return builtCondition ? [builtCondition] : [];
|
|
351
|
+
});
|
|
352
|
+
if (conditions.length === 0)
|
|
353
|
+
return undefined;
|
|
354
|
+
if (conditions.length === 1)
|
|
355
|
+
return conditions[0];
|
|
356
|
+
return { [state.combinator === 'or' ? '$or' : '$and']: conditions };
|
|
246
357
|
};
|
|
358
|
+
exports.buildFilter = buildFilter;
|
|
247
359
|
const filterSummary = (filter) => {
|
|
248
|
-
const state = readFilterState(filter);
|
|
249
|
-
if (
|
|
360
|
+
const state = (0, exports.readFilterState)(filter);
|
|
361
|
+
if (state.conditions.length === 0)
|
|
250
362
|
return '';
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
363
|
+
const first = state.conditions[0];
|
|
364
|
+
const operatorLabels = {
|
|
365
|
+
equals: '=',
|
|
366
|
+
notEquals: '!=',
|
|
367
|
+
contains: 'contains',
|
|
368
|
+
in: 'in',
|
|
369
|
+
notIn: 'not in',
|
|
370
|
+
greaterThan: '>',
|
|
371
|
+
greaterThanOrEqual: '>=',
|
|
372
|
+
lessThan: '<',
|
|
373
|
+
lessThanOrEqual: '<=',
|
|
374
|
+
true: '= true',
|
|
375
|
+
false: '= false',
|
|
376
|
+
exists: 'is set',
|
|
377
|
+
notExists: 'is not set',
|
|
378
|
+
};
|
|
379
|
+
const firstSummary = [
|
|
380
|
+
first.field,
|
|
381
|
+
operatorLabels[first.operator],
|
|
382
|
+
operatorNeedsValue(first.operator)
|
|
383
|
+
? first.valueSource === 'current'
|
|
384
|
+
? `Current document.${first.value}`
|
|
385
|
+
: first.value
|
|
386
|
+
: '',
|
|
387
|
+
]
|
|
388
|
+
.filter(Boolean)
|
|
389
|
+
.join(' ');
|
|
390
|
+
const remaining = state.conditions.length - 1;
|
|
391
|
+
return remaining > 0
|
|
392
|
+
? `${firstSummary} + ${remaining} ${remaining === 1 ? 'condition' : 'conditions'}`
|
|
393
|
+
: firstSummary;
|
|
258
394
|
};
|
|
259
395
|
const bindingSummary = ({ list, fieldBinding, listBinding, documentContentTypeName, }) => {
|
|
260
396
|
if (list) {
|
|
@@ -307,7 +443,7 @@ const FieldBindingEditor = ({ contentTypes, documentContentType, currentDocument
|
|
|
307
443
|
const items = (sourceItemsQuery.data?.items ?? []);
|
|
308
444
|
const hasCurrentDocumentItem = currentDocumentSourceEnabled && sourceType === documentContentType.name;
|
|
309
445
|
const hasItemOptions = hasCurrentDocumentItem || items.length > 0;
|
|
310
|
-
const fieldOptions = sourceFieldOptions(selectedContentType, targetField);
|
|
446
|
+
const fieldOptions = (0, exports.sourceFieldOptions)(selectedContentType, targetField);
|
|
311
447
|
const emit = (nextType = sourceType, nextId = sourceId, nextPath = fieldPath) => {
|
|
312
448
|
const usesCurrentDocument = currentDocumentSourceEnabled &&
|
|
313
449
|
nextType === documentContentType.name &&
|
|
@@ -371,7 +507,7 @@ const getRelatedRelationOptions = (contentType, currentSource) => Object.entries
|
|
|
371
507
|
const relationContentType = getRelationContentType(field);
|
|
372
508
|
return relationContentType?.name === currentSource.name ? [name] : [];
|
|
373
509
|
});
|
|
374
|
-
const getRelatedPathOptions = (contentType, targetField) => sourceFieldOptions(contentType, targetField).filter((option) => option.kind === 'array' && option.value !== '$href');
|
|
510
|
+
const getRelatedPathOptions = (contentType, targetField) => (0, exports.sourceFieldOptions)(contentType, targetField).filter((option) => option.kind === 'array' && option.value !== '$href');
|
|
375
511
|
const getSortFieldOptions = (contentType) => Object.entries(contentType.fields).flatMap(([name, field]) => {
|
|
376
512
|
if (!isDynamicVisibleField(field) ||
|
|
377
513
|
field.isTranslatable ||
|
|
@@ -389,6 +525,57 @@ const getSortFieldOptions = (contentType) => Object.entries(contentType.fields).
|
|
|
389
525
|
isSingleSelect;
|
|
390
526
|
return isSortable ? [{ label: fieldLabel(name), value: name, kind }] : [];
|
|
391
527
|
});
|
|
528
|
+
const filterOperatorOptions = {
|
|
529
|
+
equals: { label: 'Equals', value: 'equals' },
|
|
530
|
+
notEquals: { label: 'Does not equal', value: 'notEquals' },
|
|
531
|
+
contains: { label: 'Contains', value: 'contains' },
|
|
532
|
+
in: { label: 'Is one of', value: 'in' },
|
|
533
|
+
notIn: { label: 'Is not one of', value: 'notIn' },
|
|
534
|
+
greaterThan: { label: 'Greater than', value: 'greaterThan' },
|
|
535
|
+
greaterThanOrEqual: {
|
|
536
|
+
label: 'Greater than or equal',
|
|
537
|
+
value: 'greaterThanOrEqual',
|
|
538
|
+
},
|
|
539
|
+
lessThan: { label: 'Less than', value: 'lessThan' },
|
|
540
|
+
lessThanOrEqual: {
|
|
541
|
+
label: 'Less than or equal',
|
|
542
|
+
value: 'lessThanOrEqual',
|
|
543
|
+
},
|
|
544
|
+
true: { label: 'Is true', value: 'true' },
|
|
545
|
+
false: { label: 'Is false', value: 'false' },
|
|
546
|
+
exists: { label: 'Is set', value: 'exists' },
|
|
547
|
+
notExists: { label: 'Is not set', value: 'notExists' },
|
|
548
|
+
};
|
|
549
|
+
const getFilterOperatorOptions = (kind) => {
|
|
550
|
+
const operators = kind === 'boolean'
|
|
551
|
+
? ['true', 'false', 'exists', 'notExists']
|
|
552
|
+
: kind === 'number' || kind === 'date'
|
|
553
|
+
? [
|
|
554
|
+
'equals',
|
|
555
|
+
'notEquals',
|
|
556
|
+
'greaterThan',
|
|
557
|
+
'greaterThanOrEqual',
|
|
558
|
+
'lessThan',
|
|
559
|
+
'lessThanOrEqual',
|
|
560
|
+
'in',
|
|
561
|
+
'notIn',
|
|
562
|
+
'exists',
|
|
563
|
+
'notExists',
|
|
564
|
+
]
|
|
565
|
+
: kind === 'string' || kind === 'richText'
|
|
566
|
+
? [
|
|
567
|
+
'equals',
|
|
568
|
+
'notEquals',
|
|
569
|
+
'contains',
|
|
570
|
+
'in',
|
|
571
|
+
'notIn',
|
|
572
|
+
'exists',
|
|
573
|
+
'notExists',
|
|
574
|
+
]
|
|
575
|
+
: ['equals', 'notEquals', 'exists', 'notExists'];
|
|
576
|
+
return operators.map((operator) => filterOperatorOptions[operator]);
|
|
577
|
+
};
|
|
578
|
+
const defaultFilterOperator = (kind) => (kind === 'boolean' ? 'true' : 'equals');
|
|
392
579
|
const createRelatedCollectionSource = ({ contentType, currentSource, targetField, }) => {
|
|
393
580
|
const relation = getRelatedRelationOptions(contentType, currentSource)[0];
|
|
394
581
|
const path = getRelatedPathOptions(contentType, targetField)[0]?.value;
|
|
@@ -405,7 +592,7 @@ const createRelatedCollectionSource = ({ contentType, currentSource, targetField
|
|
|
405
592
|
const MappingSourceEditor = ({ contentTypes, currentSource, targetField, source, onChange, }) => {
|
|
406
593
|
const relatedSource = isRelatedCollectionSource(source) ? source : undefined;
|
|
407
594
|
const directSource = source && !isRelatedCollectionSource(source) ? source : undefined;
|
|
408
|
-
const directFieldOptions = sourceFieldOptions(currentSource, targetField);
|
|
595
|
+
const directFieldOptions = (0, exports.sourceFieldOptions)(currentSource, targetField);
|
|
409
596
|
const relatedContentTypes = contentTypes.filter((contentType) => getRelatedRelationOptions(contentType, currentSource).length > 0 &&
|
|
410
597
|
getRelatedPathOptions(contentType, targetField).length > 0);
|
|
411
598
|
const selectedRelatedContentType = relatedSource
|
|
@@ -469,10 +656,10 @@ const MappingSourceEditor = ({ contentTypes, currentSource, targetField, source,
|
|
|
469
656
|
})
|
|
470
657
|
: undefined, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'asc', children: "Ascending" }), (0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'desc', children: "Descending" })] })] })] })] })] }));
|
|
471
658
|
};
|
|
472
|
-
const ListBindingEditor = ({ contentTypes, field, binding, onChange, }) => {
|
|
659
|
+
const ListBindingEditor = ({ contentTypes, documentContentType, field, binding, onChange, }) => {
|
|
473
660
|
const [sourceType, setSourceType] = (0, react_1.useState)(binding?.contentType || '');
|
|
474
661
|
const [itemName, setItemName] = (0, react_1.useState)(binding?.itemName || field.fields[0]?.name || '');
|
|
475
|
-
const [filterState, setFilterState] = (0, react_1.useState)(readFilterState(binding?.query?.filter));
|
|
662
|
+
const [filterState, setFilterState] = (0, react_1.useState)((0, exports.readFilterState)(binding?.query?.filter));
|
|
476
663
|
const [openMappingField, setOpenMappingField] = (0, react_1.useState)(null);
|
|
477
664
|
const selectedSource = contentTypes.find((ct) => ct.name === sourceType);
|
|
478
665
|
const targetContentType = getListTargetContentType(field, itemName);
|
|
@@ -483,8 +670,17 @@ const ListBindingEditor = ({ contentTypes, field, binding, onChange, }) => {
|
|
|
483
670
|
? getSortFieldOptions(selectedSource)
|
|
484
671
|
: [];
|
|
485
672
|
const filterFieldOptions = selectedSource
|
|
486
|
-
? sourceFieldOptions(selectedSource).filter((item) => item.value !== '$href')
|
|
673
|
+
? (0, exports.sourceFieldOptions)(selectedSource).filter((item) => item.value !== '$href')
|
|
487
674
|
: [];
|
|
675
|
+
const currentDocumentFieldOptions = [
|
|
676
|
+
{ label: '_id', value: '_id', kind: 'string' },
|
|
677
|
+
...(0, exports.sourceFieldOptions)(documentContentType).filter((item) => item.value !== '$href' &&
|
|
678
|
+
item.kind !== 'object' &&
|
|
679
|
+
item.kind !== 'array'),
|
|
680
|
+
];
|
|
681
|
+
const sortEntry = Object.entries(binding?.query?.options?.sort ?? {})[0];
|
|
682
|
+
const sortField = sortEntry?.[0] ?? '';
|
|
683
|
+
const sortDirection = sortEntry?.[1] ?? 'desc';
|
|
488
684
|
const emit = (patch) => {
|
|
489
685
|
const next = {
|
|
490
686
|
contentType: sourceType,
|
|
@@ -504,57 +700,124 @@ const ListBindingEditor = ({ contentTypes, field, binding, onChange, }) => {
|
|
|
504
700
|
emit({
|
|
505
701
|
query: {
|
|
506
702
|
...binding?.query,
|
|
507
|
-
filter: buildFilter(nextFilterState),
|
|
703
|
+
filter: (0, exports.buildFilter)(nextFilterState, filterFieldOptions),
|
|
508
704
|
},
|
|
509
705
|
});
|
|
510
706
|
};
|
|
707
|
+
const updateFilterCondition = (index, nextCondition) => {
|
|
708
|
+
const conditions = [...filterState.conditions];
|
|
709
|
+
conditions[index] = nextCondition;
|
|
710
|
+
updateFilter({ ...filterState, conditions });
|
|
711
|
+
};
|
|
511
712
|
return ((0, jsx_runtime_1.jsxs)("div", { className: 'grid gap-3', children: [(0, jsx_runtime_1.jsx)(PanelSection, { title: 'Collection', children: (0, jsx_runtime_1.jsxs)("div", { className: 'grid gap-3 md:grid-cols-2', children: [(0, jsx_runtime_1.jsxs)(label_1.Label, { className: 'grid gap-1.5', children: ["Source", (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: contentTypes.length === 0, value: sourceType, onValueChange: (value) => {
|
|
512
713
|
setSourceType(value);
|
|
513
|
-
|
|
714
|
+
const nextFilterState = {
|
|
715
|
+
combinator: 'and',
|
|
716
|
+
conditions: [],
|
|
717
|
+
};
|
|
718
|
+
setFilterState(nextFilterState);
|
|
719
|
+
emit({
|
|
720
|
+
contentType: value,
|
|
721
|
+
map: {},
|
|
722
|
+
query: {
|
|
723
|
+
options: {
|
|
724
|
+
limit: binding?.query?.options?.limit ?? 10,
|
|
725
|
+
},
|
|
726
|
+
},
|
|
727
|
+
});
|
|
514
728
|
}, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: contentTypes.length > 0 ? 'Content type' : 'No content types' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: contentTypes.map((ct) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: ct.name, children: ct.name }, ct.name))) }) })] })] }), (0, jsx_runtime_1.jsxs)(label_1.Label, { className: 'grid gap-1.5', children: ["Item", (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !sourceType || field.fields.length === 0, value: itemName, onValueChange: (value) => {
|
|
515
729
|
setItemName(value);
|
|
516
730
|
emit({ itemName: value, map: {} });
|
|
517
|
-
}, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: field.fields.length > 0 ? 'Item type' : 'No item types' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: field.fields.map((item) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: item.name, children: item.name }, item.name))) }) })] })] })] }) }), (0, jsx_runtime_1.
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
731
|
+
}, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: field.fields.length > 0 ? 'Item type' : 'No item types' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: field.fields.map((item) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: item.name, children: item.name }, item.name))) }) })] })] })] }) }), (0, jsx_runtime_1.jsxs)(PanelSection, { title: 'Query', children: [(0, jsx_runtime_1.jsxs)("div", { className: 'grid grid-cols-[minmax(5rem,0.4fr)_minmax(0,1.2fr)_minmax(8rem,0.6fr)] items-end gap-3', children: [(0, jsx_runtime_1.jsxs)(label_1.Label, { className: 'grid gap-1.5', children: ["Limit", (0, jsx_runtime_1.jsx)(input_1.Input, { type: 'number', min: 1, max: 100, value: String(binding?.query?.options?.limit ?? 10), onChange: (event) => emit({
|
|
732
|
+
query: {
|
|
733
|
+
...binding?.query,
|
|
734
|
+
options: {
|
|
735
|
+
...binding?.query?.options,
|
|
736
|
+
limit: Math.min(100, Math.max(1, Number(event.target.value || 10))),
|
|
737
|
+
},
|
|
523
738
|
},
|
|
524
|
-
},
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
739
|
+
}) })] }), (0, jsx_runtime_1.jsxs)(label_1.Label, { className: 'grid min-w-0 gap-1.5', children: ["Sort by", (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: sortFieldOptions.length === 0, value: sortField || '__none__', onValueChange: (value) => emit({
|
|
740
|
+
query: {
|
|
741
|
+
...binding?.query,
|
|
742
|
+
options: {
|
|
743
|
+
...binding?.query?.options,
|
|
744
|
+
sort: value === '__none__'
|
|
745
|
+
? undefined
|
|
746
|
+
: { [value]: sortDirection },
|
|
747
|
+
},
|
|
531
748
|
},
|
|
532
|
-
},
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
749
|
+
}), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: sortFieldOptions.length > 0
|
|
750
|
+
? 'Sort by field'
|
|
751
|
+
: 'No sortable fields' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsxs)(select_1.SelectGroup, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: '__none__', children: "No sort" }), sortFieldOptions.map((item) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: item.value, children: item.label }, item.value)))] }) })] })] }), (0, jsx_runtime_1.jsxs)(label_1.Label, { className: 'grid gap-1.5', children: ["Direction", (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !sortField, value: sortDirection, onValueChange: (direction) => sortField
|
|
752
|
+
? emit({
|
|
753
|
+
query: {
|
|
754
|
+
...binding?.query,
|
|
755
|
+
options: {
|
|
756
|
+
...binding?.query?.options,
|
|
757
|
+
sort: {
|
|
758
|
+
[sortField]: direction,
|
|
759
|
+
},
|
|
760
|
+
},
|
|
761
|
+
},
|
|
762
|
+
})
|
|
763
|
+
: undefined, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'asc', children: "Ascending" }), (0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'desc', children: "Descending" })] })] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'grid gap-3 rounded-md border border-border bg-background/60 p-3', children: [(0, jsx_runtime_1.jsxs)("div", { className: 'flex flex-wrap items-center justify-between gap-2', children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: 'text-sm font-medium', children: "Conditions" }), (0, jsx_runtime_1.jsx)("div", { className: 'text-xs text-muted-foreground', children: "Filter the records used to build this list." })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'flex items-center gap-2', children: [filterState.conditions.length > 1 ? ((0, jsx_runtime_1.jsxs)(select_1.Select, { value: filterState.combinator, onValueChange: (combinator) => updateFilter({
|
|
764
|
+
...filterState,
|
|
765
|
+
combinator: combinator,
|
|
766
|
+
}), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'h-8 w-36', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'and', children: "Match all" }), (0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'or', children: "Match any" })] })] })) : null, (0, jsx_runtime_1.jsxs)(button_1.Button, { type: 'button', size: 'sm', variant: 'outline', disabled: filterFieldOptions.length === 0 ||
|
|
767
|
+
filterState.conditions.length >= 25, onClick: () => updateFilter({
|
|
545
768
|
...filterState,
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
})
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
769
|
+
conditions: [
|
|
770
|
+
...filterState.conditions,
|
|
771
|
+
{ field: '', operator: 'equals', value: '' },
|
|
772
|
+
],
|
|
773
|
+
}), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Plus, { className: 'h-4 w-4' }), "Add condition"] })] })] }), filterState.conditions.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: 'rounded-md border border-dashed border-border px-3 py-5 text-center text-sm text-muted-foreground', children: "No conditions. All records from this collection will match." })) : ((0, jsx_runtime_1.jsx)("div", { className: 'grid gap-2', children: filterState.conditions.map((condition, index) => {
|
|
774
|
+
const fieldOption = filterFieldOptions.find((option) => option.value === condition.field);
|
|
775
|
+
const operatorOptions = getFilterOperatorOptions(fieldOption?.kind);
|
|
776
|
+
const needsValue = operatorNeedsValue(condition.operator);
|
|
777
|
+
const currentValueOptions = currentDocumentFieldOptions.filter((option) => !fieldOption || option.kind === fieldOption.kind);
|
|
778
|
+
const allowsCurrentValue = condition.operator !== 'in' &&
|
|
779
|
+
condition.operator !== 'notIn' &&
|
|
780
|
+
currentValueOptions.length > 0;
|
|
781
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: 'grid items-center gap-2 rounded-md border border-border bg-background p-2 sm:grid-cols-[1.2fr_1fr_1.8fr_auto]', children: [(0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: filterFieldOptions.length === 0, value: condition.field, onValueChange: (value) => {
|
|
782
|
+
const kind = filterFieldOptions.find((option) => option.value === value)?.kind;
|
|
783
|
+
updateFilterCondition(index, {
|
|
784
|
+
field: value,
|
|
785
|
+
operator: defaultFilterOperator(kind),
|
|
786
|
+
value: '',
|
|
787
|
+
});
|
|
788
|
+
}, children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: 'Field' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: filterFieldOptions.map((item) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: item.value, children: item.label }, item.value))) }) })] }), (0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !condition.field, value: condition.operator, onValueChange: (operator) => updateFilterCondition(index, {
|
|
789
|
+
...condition,
|
|
790
|
+
operator: operator,
|
|
791
|
+
valueSource: operator === 'in' || operator === 'notIn'
|
|
792
|
+
? 'literal'
|
|
793
|
+
: condition.valueSource,
|
|
794
|
+
value: operatorNeedsValue(operator)
|
|
795
|
+
? operator === 'in' || operator === 'notIn'
|
|
796
|
+
? ''
|
|
797
|
+
: condition.value
|
|
798
|
+
: '',
|
|
799
|
+
}), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: 'Operator' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: operatorOptions.map((option) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: option.value, children: option.label }, option.value))) }) })] }), needsValue ? ((0, jsx_runtime_1.jsxs)("div", { className: 'grid grid-cols-[minmax(7rem,0.7fr)_minmax(0,1fr)] gap-2', children: [(0, jsx_runtime_1.jsxs)(select_1.Select, { value: condition.valueSource ?? 'literal', onValueChange: (valueSource) => updateFilterCondition(index, {
|
|
800
|
+
...condition,
|
|
801
|
+
valueSource: valueSource,
|
|
802
|
+
value: '',
|
|
803
|
+
}), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', "aria-label": 'Value source', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, {}) }), (0, jsx_runtime_1.jsxs)(select_1.SelectContent, { children: [(0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'literal', children: "Fixed value" }), allowsCurrentValue ? ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: 'current', children: "Current document" })) : null] })] }), condition.valueSource === 'current' ? ((0, jsx_runtime_1.jsxs)(select_1.Select, { disabled: !condition.field, value: condition.value, onValueChange: (value) => updateFilterCondition(index, {
|
|
804
|
+
...condition,
|
|
805
|
+
value,
|
|
806
|
+
}), children: [(0, jsx_runtime_1.jsx)(select_1.SelectTrigger, { className: 'w-full', children: (0, jsx_runtime_1.jsx)(select_1.SelectValue, { placeholder: 'Current field' }) }), (0, jsx_runtime_1.jsx)(select_1.SelectContent, { children: (0, jsx_runtime_1.jsx)(select_1.SelectGroup, { children: currentValueOptions.map((option) => ((0, jsx_runtime_1.jsx)(select_1.SelectItem, { value: option.value, children: option.label }, option.value))) }) })] })) : ((0, jsx_runtime_1.jsx)(input_1.Input, { type: fieldOption?.kind === 'number' &&
|
|
807
|
+
condition.operator !== 'in' &&
|
|
808
|
+
condition.operator !== 'notIn'
|
|
809
|
+
? 'number'
|
|
810
|
+
: 'text', value: condition.value, disabled: !condition.field, placeholder: condition.operator === 'in' ||
|
|
811
|
+
condition.operator === 'notIn'
|
|
812
|
+
? 'Comma-separated values'
|
|
813
|
+
: 'Value', onChange: (event) => updateFilterCondition(index, {
|
|
814
|
+
...condition,
|
|
815
|
+
value: event.target.value,
|
|
816
|
+
}) }))] })) : ((0, jsx_runtime_1.jsx)("div", { className: 'h-9 rounded-md border border-dashed border-border bg-muted/30' })), (0, jsx_runtime_1.jsxs)(button_1.Button, { type: 'button', size: 'icon', variant: 'ghost', className: 'size-9 text-muted-foreground hover:text-destructive', onClick: () => updateFilter({
|
|
554
817
|
...filterState,
|
|
555
|
-
|
|
556
|
-
})
|
|
557
|
-
|
|
818
|
+
conditions: filterState.conditions.filter((_, conditionIndex) => conditionIndex !== index),
|
|
819
|
+
}), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Trash2, { className: 'h-4 w-4' }), (0, jsx_runtime_1.jsx)("span", { className: 'sr-only', children: "Remove condition" })] })] }, `${index}-${condition.field}`));
|
|
820
|
+
}) }))] })] }), (0, jsx_runtime_1.jsx)(PanelSection, { title: 'Mapping', children: (0, jsx_runtime_1.jsx)("div", { className: 'grid gap-2', children: targetFields.map(([targetField, targetFieldConfig]) => {
|
|
558
821
|
const source = binding?.map?.[targetField];
|
|
559
822
|
const summary = mappingSourceSummary(source, selectedSource?.name ?? 'Source');
|
|
560
823
|
const isOpen = openMappingField === targetField;
|
|
@@ -653,7 +916,7 @@ const DynamicDataControl = ({ contentType, documentContentType, fieldName, field
|
|
|
653
916
|
setOpen(false);
|
|
654
917
|
};
|
|
655
918
|
const trigger = ((0, jsx_runtime_1.jsxs)("div", { className: 'flex min-w-0 items-center gap-1.5', children: [(0, jsx_runtime_1.jsxs)(tooltip_1.Tooltip, { children: [(0, jsx_runtime_1.jsx)(tooltip_1.TooltipTrigger, { asChild: true, children: (0, jsx_runtime_1.jsx)("button", { type: 'button', className: 'min-w-0 cursor-pointer rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring', onClick: () => setOpen((value) => !value), children: bound && summary ? ((0, jsx_runtime_1.jsxs)(badge_1.Badge, { variant: 'secondary', className: 'max-w-80 min-w-0 gap-1.5 rounded-md px-2 py-1 hover:bg-secondary/80', children: [list ? ((0, jsx_runtime_1.jsx)(lucide_react_1.ListFilter, { className: 'h-3.5 w-3.5 shrink-0' })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.Link2, { className: 'h-3.5 w-3.5 shrink-0' })), (0, jsx_runtime_1.jsx)("span", { className: 'truncate', children: summary })] })) : ((0, jsx_runtime_1.jsxs)(badge_1.Badge, { variant: 'outline', className: 'gap-1.5 rounded-md px-2 py-1 text-muted-foreground', children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Cable, { className: 'h-3.5 w-3.5' }), "Not linked"] })) }) }), (0, jsx_runtime_1.jsx)(tooltip_1.TooltipContent, { side: 'top', sideOffset: 6, children: triggerLabel })] }), bound ? ((0, jsx_runtime_1.jsxs)(tooltip_1.Tooltip, { children: [(0, jsx_runtime_1.jsx)(tooltip_1.TooltipTrigger, { asChild: true, children: (0, jsx_runtime_1.jsxs)(button_1.Button, { type: 'button', size: 'icon', variant: 'ghost', className: 'size-6', onClick: clearBinding, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: 'h-4 w-4' }), (0, jsx_runtime_1.jsx)("span", { className: 'sr-only', children: "Clear dynamic data" })] }) }), (0, jsx_runtime_1.jsx)(tooltip_1.TooltipContent, { side: 'top', sideOffset: 6, children: "Clear dynamic data link" })] })) : null] }));
|
|
656
|
-
const editor = list ? ((0, jsx_runtime_1.jsx)(ListBindingEditor, { contentTypes: sourceContentTypes, field: field, binding: listBinding, onChange: updateListBinding })) : ((0, jsx_runtime_1.jsx)(FieldBindingEditor, { contentTypes: fieldSourceContentTypes, documentContentType: currentDocumentContentType, currentDocumentSourceEnabled: currentDocumentSourceEnabled, targetField: field, binding: fieldBinding, onChange: updateFieldBinding }));
|
|
919
|
+
const editor = list ? ((0, jsx_runtime_1.jsx)(ListBindingEditor, { contentTypes: sourceContentTypes, documentContentType: currentDocumentContentType, field: field, binding: listBinding, onChange: updateListBinding })) : ((0, jsx_runtime_1.jsx)(FieldBindingEditor, { contentTypes: fieldSourceContentTypes, documentContentType: currentDocumentContentType, currentDocumentSourceEnabled: currentDocumentSourceEnabled, targetField: field, binding: fieldBinding, onChange: updateFieldBinding }));
|
|
657
920
|
const panel = isOpen ? ((0, jsx_runtime_1.jsx)("div", { className: 'rounded-md border border-border bg-background p-4 shadow-sm', children: editor })) : null;
|
|
658
921
|
const dialog = ((0, jsx_runtime_1.jsx)(dialog_1.Dialog, { open: isOpen, onOpenChange: (value) => {
|
|
659
922
|
if (value) {
|