@cratis/components 4.25.1 → 4.26.0
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/compat-manifest.json +11 -11
- package/dist/esm/Canvas/canvasZoomListeners.d.ts +30 -0
- package/dist/esm/Canvas/canvasZoomListeners.d.ts.map +1 -0
- package/dist/esm/Canvas/canvasZoomListeners.js +121 -0
- package/dist/esm/Canvas/canvasZoomListeners.js.map +1 -0
- package/dist/esm/Canvas/useCanvasWheelZoom.d.ts +2 -1
- package/dist/esm/Canvas/useCanvasWheelZoom.d.ts.map +1 -1
- package/dist/esm/Canvas/useCanvasWheelZoom.js +24 -132
- package/dist/esm/Canvas/useCanvasWheelZoom.js.map +1 -1
- package/dist/esm/SchemaEditor/NameCell.d.ts +5 -1
- package/dist/esm/SchemaEditor/NameCell.d.ts.map +1 -1
- package/dist/esm/SchemaEditor/NameCell.js +2 -2
- package/dist/esm/SchemaEditor/NameCell.js.map +1 -1
- package/dist/esm/SchemaEditor/SchemaEditor.d.ts +63 -48
- package/dist/esm/SchemaEditor/SchemaEditor.d.ts.map +1 -1
- package/dist/esm/SchemaEditor/SchemaEditor.js +83 -25
- package/dist/esm/SchemaEditor/SchemaEditor.js.map +1 -1
- package/dist/esm/SchemaEditor/SchemaEditorLabels.d.ts +98 -0
- package/dist/esm/SchemaEditor/SchemaEditorLabels.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/SchemaEditorLabels.js +4 -0
- package/dist/esm/SchemaEditor/SchemaEditorLabels.js.map +1 -0
- package/dist/esm/SchemaEditor/SchemaEditorLayout.d.ts +6 -0
- package/dist/esm/SchemaEditor/SchemaEditorLayout.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/SchemaEditorLayout.js +4 -0
- package/dist/esm/SchemaEditor/SchemaEditorLayout.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/Property.d.ts +30 -0
- package/dist/esm/SchemaEditor/Tree/Property.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/Property.js +4 -0
- package/dist/esm/SchemaEditor/Tree/Property.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyConcept.d.ts +15 -0
- package/dist/esm/SchemaEditor/Tree/PropertyConcept.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyConcept.js +4 -0
- package/dist/esm/SchemaEditor/Tree/PropertyConcept.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyConceptsContext.d.ts +22 -0
- package/dist/esm/SchemaEditor/Tree/PropertyConceptsContext.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyConceptsContext.js +10 -0
- package/dist/esm/SchemaEditor/Tree/PropertyConceptsContext.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyType.d.ts +22 -0
- package/dist/esm/SchemaEditor/Tree/PropertyType.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyType.js +15 -0
- package/dist/esm/SchemaEditor/Tree/PropertyType.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeBadge.d.ts +20 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeBadge.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeBadge.js +11 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeBadge.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeMenu.d.ts +28 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeMenu.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeMenu.js +37 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeMenu.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaEditorContext.d.ts +42 -0
- package/dist/esm/SchemaEditor/Tree/SchemaEditorContext.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaEditorContext.js +12 -0
- package/dist/esm/SchemaEditor/Tree/SchemaEditorContext.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaEditorParts.d.ts +60 -0
- package/dist/esm/SchemaEditor/Tree/SchemaEditorParts.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaEditorParts.js +4 -0
- package/dist/esm/SchemaEditor/Tree/SchemaEditorParts.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyContext.d.ts +13 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyContext.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyContext.js +4 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyContext.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyRow.d.ts +13 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyRow.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyRow.js +107 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyRow.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyRowState.d.ts +16 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyRowState.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyRowState.js +4 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyRowState.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/TreeSchemaEditor.d.ts +116 -0
- package/dist/esm/SchemaEditor/Tree/TreeSchemaEditor.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/TreeSchemaEditor.js +96 -0
- package/dist/esm/SchemaEditor/Tree/TreeSchemaEditor.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/propertyNaming.d.ts +35 -0
- package/dist/esm/SchemaEditor/Tree/propertyNaming.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/propertyNaming.js +34 -0
- package/dist/esm/SchemaEditor/Tree/propertyNaming.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/propertyTree.d.ts +30 -0
- package/dist/esm/SchemaEditor/Tree/propertyTree.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/propertyTree.js +36 -0
- package/dist/esm/SchemaEditor/Tree/propertyTree.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/propertyTypeDisplay.d.ts +22 -0
- package/dist/esm/SchemaEditor/Tree/propertyTypeDisplay.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/propertyTypeDisplay.js +45 -0
- package/dist/esm/SchemaEditor/Tree/propertyTypeDisplay.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/schemaConversion.d.ts +95 -0
- package/dist/esm/SchemaEditor/Tree/schemaConversion.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/schemaConversion.js +171 -0
- package/dist/esm/SchemaEditor/Tree/schemaConversion.js.map +1 -0
- package/dist/esm/SchemaEditor/TypeCell.d.ts +3 -1
- package/dist/esm/SchemaEditor/TypeCell.d.ts.map +1 -1
- package/dist/esm/SchemaEditor/TypeCell.js +2 -2
- package/dist/esm/SchemaEditor/TypeCell.js.map +1 -1
- package/dist/esm/SchemaEditor/defaultSchemaEditorLabels.d.ts +9 -0
- package/dist/esm/SchemaEditor/defaultSchemaEditorLabels.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/defaultSchemaEditorLabels.js +51 -0
- package/dist/esm/SchemaEditor/defaultSchemaEditorLabels.js.map +1 -0
- package/dist/esm/SchemaEditor/index.d.ts +12 -0
- package/dist/esm/SchemaEditor/index.d.ts.map +1 -1
- package/dist/esm/SchemaEditor/index.js +7 -1
- package/dist/esm/SchemaEditor/index.js.map +1 -1
- package/dist/esm/SchemaEditor/resolveSchemaEditorLabels.d.ts +4 -0
- package/dist/esm/SchemaEditor/resolveSchemaEditorLabels.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/resolveSchemaEditorLabels.js +13 -0
- package/dist/esm/SchemaEditor/resolveSchemaEditorLabels.js.map +1 -0
- package/dist/esm/styles.SchemaEditor.css +346 -0
- package/dist/esm/styles.css +346 -0
- package/dist/esm/types/parts.d.ts +25 -0
- package/dist/esm/types/parts.d.ts.map +1 -1
- package/dist/esm/types/parts.js +25 -0
- package/dist/esm/types/parts.js.map +1 -1
- package/package.json +2 -1
|
@@ -1,49 +1,31 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
1
2
|
import type { ChangeHandler } from '../types/ChangeHandler.js';
|
|
2
3
|
import type { JsonSchema } from '../types/JsonSchema.js';
|
|
3
4
|
import { type TypeFormat } from '../types/TypeFormat.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
save: string;
|
|
14
|
-
/** Menu action that cancels editing. */
|
|
15
|
-
cancel: string;
|
|
16
|
-
/** Menu action that adds a property. */
|
|
17
|
-
addProperty: string;
|
|
18
|
-
/** Accessible name for the action menubar. */
|
|
19
|
-
actions: string;
|
|
20
|
-
/** Accessible name and tooltip for the back button. */
|
|
21
|
-
navigateBack: string;
|
|
22
|
-
/** Shown when the schema has no properties. */
|
|
23
|
-
emptyMessage: string;
|
|
24
|
-
/** Accessible name for the "drill into array item definition" button. */
|
|
25
|
-
navigateToItemDefinition: string;
|
|
26
|
-
/** Accessible name for the "drill into object properties" button. */
|
|
27
|
-
navigateToProperties: string;
|
|
28
|
-
/** Accessible name for a property-name input. */
|
|
29
|
-
propertyName: string;
|
|
30
|
-
/** Accessible name for a property-type selector. */
|
|
31
|
-
propertyType: string;
|
|
32
|
-
/** Accessible name for an array item-type selector. */
|
|
33
|
-
arrayItemType: string;
|
|
34
|
-
/** Accessible name for the "remove property" button. */
|
|
35
|
-
deleteProperty: string;
|
|
36
|
-
/** Validation message shown when the schema cannot be represented as valid JSON. */
|
|
37
|
-
invalidJson: string;
|
|
38
|
-
}
|
|
39
|
-
/** English defaults for {@link SchemaEditorLabels}. */
|
|
40
|
-
export declare const defaultSchemaEditorLabels: SchemaEditorLabels;
|
|
5
|
+
import { defaultSchemaEditorLabels } from './defaultSchemaEditorLabels.js';
|
|
6
|
+
import type { SchemaEditorLabels } from './SchemaEditorLabels.js';
|
|
7
|
+
import type { SchemaEditorLayout } from './SchemaEditorLayout.js';
|
|
8
|
+
import type { Property } from './Tree/Property.js';
|
|
9
|
+
import { type TreeSchemaEditorProps } from './Tree/TreeSchemaEditor.js';
|
|
10
|
+
export { defaultSchemaEditorLabels };
|
|
11
|
+
export type { SchemaEditorLabels };
|
|
12
|
+
/** Properties of the tree layout the table layout has no counterpart for. They are ignored when `layout` is `'table'`. */
|
|
13
|
+
type TreeOnlyProps = Omit<TreeSchemaEditorProps, 'schema' | 'onChange' | 'labels' | 'className' | 'allowKeyProperty' | 'allowRequired' | 'readOnly' | 'isPropertyProtected' | 'validatePropertyName' | 'onPropertyRemoved' | 'onPropertyRenamed' | 'header' | 'footer'>;
|
|
41
14
|
/**
|
|
42
15
|
* Props for {@link SchemaEditor}.
|
|
43
16
|
*/
|
|
44
|
-
export interface SchemaEditorProps {
|
|
45
|
-
/**
|
|
46
|
-
|
|
17
|
+
export interface SchemaEditorProps extends TreeOnlyProps {
|
|
18
|
+
/**
|
|
19
|
+
* Which editor to render. `'table'` (the default) is the breadcrumb-navigated table with an Edit, Save and
|
|
20
|
+
* Cancel workflow; `'tree'` is the inline tree editor that applies every edit live. See the layout notes in
|
|
21
|
+
* the documentation for the props each layout honors.
|
|
22
|
+
*/
|
|
23
|
+
layout?: SchemaEditorLayout;
|
|
24
|
+
/**
|
|
25
|
+
* The JSON Schema being viewed or edited. Required unless the tree layout is controlled through
|
|
26
|
+
* `properties`.
|
|
27
|
+
*/
|
|
28
|
+
schema?: JsonSchema;
|
|
47
29
|
/** Optional event-type label displayed in the editor header. */
|
|
48
30
|
eventTypeName?: string;
|
|
49
31
|
/** When false, the Edit action remains visible but cannot enter edit mode; defaults to `true`. */
|
|
@@ -79,18 +61,51 @@ export interface SchemaEditorProps {
|
|
|
79
61
|
className?: string;
|
|
80
62
|
/** Override any user-facing string (for localization). See {@link SchemaEditorLabels}. */
|
|
81
63
|
labels?: Partial<SchemaEditorLabels>;
|
|
64
|
+
/**
|
|
65
|
+
* Offers the key toggle (`x-key`, at most one property per object). In the table layout this adds a Key
|
|
66
|
+
* column, editable in edit mode; a function enables the column for every row. In the tree layout it is
|
|
67
|
+
* offered on every property, or per property when a function is given.
|
|
68
|
+
*/
|
|
69
|
+
allowKeyProperty?: TreeSchemaEditorProps['allowKeyProperty'];
|
|
70
|
+
/**
|
|
71
|
+
* Offers the toggle for whether a property must be present (the `required` list). In the table layout this
|
|
72
|
+
* adds a Required column, editable in edit mode.
|
|
73
|
+
*/
|
|
74
|
+
allowRequired?: boolean;
|
|
75
|
+
/** Offers no edits at all. Tree layout only: the table layout is read-only until Edit is chosen, controlled by `canEdit`. */
|
|
76
|
+
readOnly?: boolean;
|
|
77
|
+
/** Decides which properties can be neither renamed nor removed. By default none. Both layouts. */
|
|
78
|
+
isPropertyProtected?: (property: Property) => boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Extra check of a new name, after the editor has rejected blank, reserved and duplicate names. Return the
|
|
81
|
+
* message to show, or `undefined` to accept the name. Both layouts.
|
|
82
|
+
*/
|
|
83
|
+
validatePropertyName?: (name: string, property: Property, siblings: Property[]) => string | undefined;
|
|
84
|
+
/** Called after a property was removed, with the property and everything nested under it. Both layouts. */
|
|
85
|
+
onPropertyRemoved?: (property: Property) => void;
|
|
86
|
+
/** Called after a property was renamed, with the renamed property and the name it had. Both layouts. */
|
|
87
|
+
onPropertyRenamed?: (property: Property, previousName: string) => void;
|
|
88
|
+
/** Content above the editor, for example the title of the schema. Both layouts. */
|
|
89
|
+
header?: ReactNode;
|
|
90
|
+
/** Content below the properties, for example further actions. Both layouts. */
|
|
91
|
+
footer?: ReactNode;
|
|
82
92
|
}
|
|
83
93
|
/**
|
|
84
|
-
*
|
|
85
|
-
* `object` and `array` property definitions, add or remove properties, change
|
|
86
|
-
*
|
|
87
|
-
*
|
|
94
|
+
* Edits the properties of a JSON Schema. By default (`layout='table'`) it is a breadcrumb-navigated table: it
|
|
95
|
+
* lets users browse nested `object` and `array` property definitions, add or remove properties, change types and
|
|
96
|
+
* formats, and validate naming rules in place, behind an Edit, Save and Cancel workflow. With `layout='tree'` it
|
|
97
|
+
* is an inline tree that shows nested properties in place and applies every edit live. Designed to drive UIs
|
|
98
|
+
* around event payload schemas and similar structural documents.
|
|
99
|
+
*
|
|
100
|
+
* Both layouts accept `allowRequired`, `allowKeyProperty`, `isPropertyProtected`, `validatePropertyName`,
|
|
101
|
+
* `onPropertyRenamed`, `onPropertyRemoved`, `header` and `footer`. The tree layout also takes concepts, controlled
|
|
102
|
+
* mode, per-row slots and selection; see the documentation for the exact split.
|
|
88
103
|
*
|
|
89
|
-
* The
|
|
90
|
-
*
|
|
91
|
-
*
|
|
104
|
+
* The table layout composes a Cratis data table, action toolbar, and form widgets internally. Restyle it through
|
|
105
|
+
* semantic tokens, the editor root `className`, and documented `data-cratis-part` values rather than a provider
|
|
106
|
+
* preset.
|
|
92
107
|
*
|
|
93
108
|
* @param props - {@link SchemaEditorProps}.
|
|
94
109
|
*/
|
|
95
|
-
export declare const SchemaEditor: (
|
|
110
|
+
export declare const SchemaEditor: (props: SchemaEditorProps) => import("react").JSX.Element;
|
|
96
111
|
//# sourceMappingURL=SchemaEditor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SchemaEditor.d.ts","sourceRoot":"","sources":["../../../SchemaEditor/SchemaEditor.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SchemaEditor.d.ts","sourceRoot":"","sources":["../../../SchemaEditor/SchemaEditor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { useMemo, useState, useEffect, useCallback } from 'react';
|
|
3
3
|
import { Button } from '../Common/Button.js';
|
|
4
|
+
import { Checkbox } from '../Common/Checkbox.js';
|
|
4
5
|
import { DataTableCore } from '../DataTables/DataTableCore.js';
|
|
5
6
|
import { Column } from '../DataTables/Column.js';
|
|
6
7
|
import { ActionMenubar } from '../Common/ActionMenubar.js';
|
|
@@ -11,23 +12,11 @@ import { NameCell } from './NameCell.js';
|
|
|
11
12
|
import { TypeCell } from './TypeCell.js';
|
|
12
13
|
import { DEFAULT_TYPE_FORMATS } from '../types/TypeFormat.js';
|
|
13
14
|
import { validatePropertyName, buildBreadcrumbItems } from './schemaHelpers.js';
|
|
15
|
+
import { defaultSchemaEditorLabels } from './defaultSchemaEditorLabels.js';
|
|
16
|
+
import { jsonSchemaToProperties, KEY_KEYWORD } from './Tree/schemaConversion.js';
|
|
17
|
+
import { TreeSchemaEditor } from './Tree/TreeSchemaEditor.js';
|
|
14
18
|
|
|
15
|
-
const
|
|
16
|
-
edit: 'Edit',
|
|
17
|
-
save: 'Save',
|
|
18
|
-
cancel: 'Cancel',
|
|
19
|
-
addProperty: 'Add Property',
|
|
20
|
-
actions: 'Actions',
|
|
21
|
-
navigateBack: 'Navigate back',
|
|
22
|
-
emptyMessage: 'No properties defined',
|
|
23
|
-
navigateToItemDefinition: 'Navigate to item definition',
|
|
24
|
-
navigateToProperties: 'Navigate to object properties',
|
|
25
|
-
propertyName: 'Property name',
|
|
26
|
-
propertyType: 'Property type',
|
|
27
|
-
arrayItemType: 'Array item type',
|
|
28
|
-
deleteProperty: 'Delete property',
|
|
29
|
-
invalidJson: 'The schema must contain valid JSON before it can be edited.',
|
|
30
|
-
};
|
|
19
|
+
const emptySchema = {};
|
|
31
20
|
const isPlainObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
32
21
|
const isValidSchemaNode = (node) => {
|
|
33
22
|
if (!isPlainObject(node)) {
|
|
@@ -68,14 +57,32 @@ const cloneSchema = (schema) => {
|
|
|
68
57
|
return undefined;
|
|
69
58
|
}
|
|
70
59
|
};
|
|
60
|
+
const findSchemaAtPath = (root, path) => {
|
|
61
|
+
let target = root;
|
|
62
|
+
for (const segment of path) {
|
|
63
|
+
if (target.type === 'array' && segment === '$items') {
|
|
64
|
+
target = target.items || {};
|
|
65
|
+
}
|
|
66
|
+
else if (target.properties && target.properties[segment]) {
|
|
67
|
+
target = target.properties[segment];
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return target;
|
|
74
|
+
};
|
|
71
75
|
const asJsonSchema = (property) => {
|
|
72
76
|
return property;
|
|
73
77
|
};
|
|
74
78
|
const asJsonSchemaProperty = (schema) => {
|
|
75
79
|
return schema;
|
|
76
80
|
};
|
|
77
|
-
const
|
|
81
|
+
const TableSchemaEditor = ({ schema: suppliedSchema, eventTypeName = '', canEdit = true, canNotEditReason, onChange, onSave, onCancel, editMode, saveDisabled = false, cancelDisabled = false, typeFormats = DEFAULT_TYPE_FORMATS, className, labels, allowKeyProperty, allowRequired, isPropertyProtected, validatePropertyName: validateCustomPropertyName, onPropertyRemoved, onPropertyRenamed, header, footer, }) => {
|
|
82
|
+
const schema = suppliedSchema ?? emptySchema;
|
|
78
83
|
const l = useMemo(() => ({ ...defaultSchemaEditorLabels, ...labels }), [labels]);
|
|
84
|
+
const showKey = allowKeyProperty !== undefined && allowKeyProperty !== false;
|
|
85
|
+
const showRequired = allowRequired === true;
|
|
79
86
|
const [currentPath, setCurrentPath] = useState([]);
|
|
80
87
|
const [properties, setProperties] = useState([]);
|
|
81
88
|
const [initialParsedSchema] = useState(() => cloneSchema(schema));
|
|
@@ -89,17 +96,23 @@ const SchemaEditor = ({ schema, eventTypeName = '', canEdit = true, canNotEditRe
|
|
|
89
96
|
setCurrentPath([]);
|
|
90
97
|
}
|
|
91
98
|
}, [isEditMode]);
|
|
92
|
-
const validateAllProperties = useCallback((properties) => {
|
|
99
|
+
const validateAllProperties = useCallback((properties, level = []) => {
|
|
93
100
|
const errors = {};
|
|
94
101
|
properties.forEach((prop) => {
|
|
95
|
-
|
|
102
|
+
let error = validatePropertyName(prop.name ?? '', prop.id, properties);
|
|
103
|
+
if (!error && validateCustomPropertyName) {
|
|
104
|
+
const property = level.find((candidate) => candidate.name === prop.name);
|
|
105
|
+
if (property) {
|
|
106
|
+
error = validateCustomPropertyName(property.name, property, level);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
96
109
|
if (error) {
|
|
97
110
|
errors[prop.id] = error;
|
|
98
111
|
}
|
|
99
112
|
});
|
|
100
113
|
setValidationErrors(errors);
|
|
101
114
|
return Object.keys(errors).length === 0;
|
|
102
|
-
}, [validatePropertyName]);
|
|
115
|
+
}, [validatePropertyName, validateCustomPropertyName]);
|
|
103
116
|
useEffect(() => {
|
|
104
117
|
const parsedSchema = cloneSchema(schema);
|
|
105
118
|
if (!parsedSchema) {
|
|
@@ -144,7 +157,7 @@ const SchemaEditor = ({ schema, eventTypeName = '', canEdit = true, canNotEditRe
|
|
|
144
157
|
}
|
|
145
158
|
setProperties(schemaProps);
|
|
146
159
|
if (isEditMode) {
|
|
147
|
-
validateAllProperties(schemaProps);
|
|
160
|
+
validateAllProperties(schemaProps, jsonSchemaToProperties(targetSchema));
|
|
148
161
|
}
|
|
149
162
|
};
|
|
150
163
|
const updateSchemaAtPath = useCallback((path, updater) => {
|
|
@@ -198,7 +211,17 @@ const SchemaEditor = ({ schema, eventTypeName = '', canEdit = true, canNotEditRe
|
|
|
198
211
|
return { ...schema, properties: newProps };
|
|
199
212
|
});
|
|
200
213
|
}, [currentPath, updateSchemaAtPath]);
|
|
214
|
+
const getLevelProperties = useCallback(() => jsonSchemaToProperties(findSchemaAtPath(currentSchema, currentPath)), [currentSchema, currentPath]);
|
|
215
|
+
const isProtected = useCallback((propertyName) => {
|
|
216
|
+
if (!isPropertyProtected)
|
|
217
|
+
return false;
|
|
218
|
+
const property = getLevelProperties().find((candidate) => candidate.name === propertyName);
|
|
219
|
+
return property !== undefined && isPropertyProtected(property);
|
|
220
|
+
}, [isPropertyProtected, getLevelProperties]);
|
|
201
221
|
const removeProperty = useCallback((propertyName) => {
|
|
222
|
+
const removed = getLevelProperties().find((candidate) => candidate.name === propertyName);
|
|
223
|
+
if (removed && isPropertyProtected?.(removed))
|
|
224
|
+
return;
|
|
202
225
|
updateSchemaAtPath(currentPath, (schema) => {
|
|
203
226
|
const newProps = { ...(schema.properties || {}) };
|
|
204
227
|
delete newProps[propertyName];
|
|
@@ -208,15 +231,44 @@ const SchemaEditor = ({ schema, eventTypeName = '', canEdit = true, canNotEditRe
|
|
|
208
231
|
}
|
|
209
232
|
return updated;
|
|
210
233
|
});
|
|
234
|
+
if (removed)
|
|
235
|
+
onPropertyRemoved?.(removed);
|
|
236
|
+
}, [currentPath, updateSchemaAtPath, getLevelProperties, isPropertyProtected, onPropertyRemoved]);
|
|
237
|
+
const setRequired = useCallback((propertyName, isRequired) => {
|
|
238
|
+
updateSchemaAtPath(currentPath, (schema) => {
|
|
239
|
+
const others = (schema.required ?? []).filter((name) => name !== propertyName);
|
|
240
|
+
const required = isRequired ? [...others, propertyName] : others;
|
|
241
|
+
const updated = { ...schema };
|
|
242
|
+
if (required.length > 0) {
|
|
243
|
+
updated.required = required;
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
delete updated.required;
|
|
247
|
+
}
|
|
248
|
+
return updated;
|
|
249
|
+
});
|
|
250
|
+
}, [currentPath, updateSchemaAtPath]);
|
|
251
|
+
const setKey = useCallback((propertyName) => {
|
|
252
|
+
updateSchemaAtPath(currentPath, (schema) => {
|
|
253
|
+
const newProps = {};
|
|
254
|
+
for (const [name, property] of Object.entries(schema.properties || {})) {
|
|
255
|
+
const { [KEY_KEYWORD]: previousKey, ...rest } = property;
|
|
256
|
+
const makeKey = name === propertyName && previousKey !== true;
|
|
257
|
+
newProps[name] = (makeKey ? { ...rest, [KEY_KEYWORD]: true } : rest);
|
|
258
|
+
}
|
|
259
|
+
return { ...schema, properties: newProps };
|
|
260
|
+
});
|
|
211
261
|
}, [currentPath, updateSchemaAtPath]);
|
|
212
262
|
const updateProperty = useCallback((oldName, field, value, additionalUpdates) => {
|
|
263
|
+
let renamed;
|
|
213
264
|
updateSchemaAtPath(currentPath, (schema) => {
|
|
214
265
|
const newProps = { ...(schema.properties || {}) };
|
|
215
266
|
const prop = { ...(newProps[oldName] || {}) };
|
|
216
267
|
let newRequired = schema.required;
|
|
217
268
|
if (field === 'name') {
|
|
218
269
|
const newName = value;
|
|
219
|
-
if (newName !== oldName && !newProps[newName]) {
|
|
270
|
+
if (newName !== oldName && !newProps[newName] && !isProtected(oldName)) {
|
|
271
|
+
renamed = jsonSchemaToProperties({ properties: { [newName]: prop } })[0];
|
|
220
272
|
newProps[newName] = prop;
|
|
221
273
|
delete newProps[oldName];
|
|
222
274
|
if (schema.required?.includes(oldName)) {
|
|
@@ -226,6 +278,7 @@ const SchemaEditor = ({ schema, eventTypeName = '', canEdit = true, canNotEditRe
|
|
|
226
278
|
}
|
|
227
279
|
else if (field === 'type') {
|
|
228
280
|
prop.type = value;
|
|
281
|
+
delete prop['x-concept'];
|
|
229
282
|
if (value === 'array') {
|
|
230
283
|
prop.items = { type: 'string' };
|
|
231
284
|
delete prop.format;
|
|
@@ -265,7 +318,9 @@ const SchemaEditor = ({ schema, eventTypeName = '', canEdit = true, canNotEditRe
|
|
|
265
318
|
}
|
|
266
319
|
return { ...schema, properties: newProps, required: newRequired };
|
|
267
320
|
});
|
|
268
|
-
|
|
321
|
+
if (renamed)
|
|
322
|
+
onPropertyRenamed?.(renamed, oldName);
|
|
323
|
+
}, [currentPath, updateSchemaAtPath, isProtected, onPropertyRenamed]);
|
|
269
324
|
const updateArrayItemType = useCallback((propertyName, itemType) => {
|
|
270
325
|
updateSchemaAtPath(currentPath, (schema) => {
|
|
271
326
|
const newProps = { ...(schema.properties || {}) };
|
|
@@ -417,7 +472,8 @@ const SchemaEditor = ({ schema, eventTypeName = '', canEdit = true, canNotEditRe
|
|
|
417
472
|
const breadcrumbItems = getBreadcrumbItems();
|
|
418
473
|
const isAtRoot = currentPath.length === 0;
|
|
419
474
|
const currentDescription = getCurrentDescription();
|
|
420
|
-
|
|
475
|
+
const currentLevel = findSchemaAtPath(currentSchema, currentPath);
|
|
476
|
+
return (jsxs("div", { className: className ? `schema-editor ${className}` : 'schema-editor', style: { display: 'flex', flexDirection: 'column', height: '100%' }, children: [header, jsxs("div", { className: 'cratis:px-4 cratis:py-4', children: [jsx("div", { className: 'schema-editor-menubar', children: jsx(ActionMenubar, { "aria-label": l.actions, model: menuItems }) }), schemaJsonIsInvalid && (jsx(Message, { severity: 'error', text: l.invalidJson, className: 'cratis:mt-3' }))] }), jsxs("div", { className: 'cratis:px-4 cratis:py-2 cratis-schema-editor-bottom-border', children: [jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '0.5rem' }, children: [jsx(Tooltip, { content: l.navigateBack, position: 'top', children: jsx(Button, { variant: 'ghost', size: 'small', icon: jsx(faIcons.FaArrowLeft, {}), onClick: navigateBack, disabled: isAtRoot, "aria-label": l.navigateBack }) }), jsx("div", { style: {
|
|
421
477
|
fontSize: '0.9rem',
|
|
422
478
|
color: 'var(--cratis-text-color-secondary)',
|
|
423
479
|
cursor: 'pointer',
|
|
@@ -470,8 +526,10 @@ const SchemaEditor = ({ schema, eventTypeName = '', canEdit = true, canNotEditRe
|
|
|
470
526
|
borderTop: '1px solid var(--cratis-surface-border)',
|
|
471
527
|
},
|
|
472
528
|
},
|
|
473
|
-
}, children: [jsx(Column, { field: 'name', header: 'Property', body: (rowData) => (jsx(NameCell, { rowData: rowData, isEditMode: isEditMode, onUpdate: updateProperty, validationError: validationErrors[rowData.id], propertyNameLabel: l.propertyName })), style: { width: '30%' } }), jsx(Column, { header: 'Type', body: (rowData) => (jsx(TypeCell, { rowData: rowData, isEditMode: isEditMode, typeFormats: typeFormats, onUpdateProperty: updateProperty, onUpdateArrayItemType: updateArrayItemType, onNavigateToProperty: navigateToProperty, onNavigateToArrayItems: navigateToArrayItems, onRemoveProperty: removeProperty, labels: l })), style: { width: '70%' } })] }, `${isEditMode}-${currentPath.join('/')}`) })] }));
|
|
529
|
+
}, children: [jsx(Column, { field: 'name', header: 'Property', body: (rowData) => (jsx(NameCell, { rowData: rowData, isEditMode: isEditMode, onUpdate: updateProperty, validationError: validationErrors[rowData.id], propertyNameLabel: l.propertyName, isLocked: isProtected(rowData.name ?? ''), lockedReason: l.protectedProperty })), style: { width: '30%' } }), showRequired && (jsx(Column, { header: l.requiredColumn, body: (rowData) => (jsx(Checkbox, { "aria-label": l.requiredProperty(rowData.name ?? ''), checked: Boolean(currentLevel?.required?.includes(rowData.name ?? '')), readOnly: !isEditMode, onChange: (checked) => setRequired(rowData.name ?? '', checked) })), style: { width: '6rem' } })), showKey && (jsx(Column, { header: l.keyColumn, body: (rowData) => (jsx(Checkbox, { "aria-label": l.keyProperty(rowData.name ?? ''), checked: isKeyProperty(currentLevel, rowData.name ?? ''), readOnly: !isEditMode, onChange: () => setKey(rowData.name ?? '') })), style: { width: '6rem' } })), jsx(Column, { header: 'Type', body: (rowData) => (jsx(TypeCell, { rowData: rowData, isEditMode: isEditMode, typeFormats: typeFormats, onUpdateProperty: updateProperty, onUpdateArrayItemType: updateArrayItemType, onNavigateToProperty: navigateToProperty, onNavigateToArrayItems: navigateToArrayItems, onRemoveProperty: removeProperty, canRemove: !isProtected(rowData.name ?? ''), labels: l })), style: { width: '70%' } })] }, `${isEditMode}-${currentPath.join('/')}`) }), footer] }));
|
|
474
530
|
};
|
|
531
|
+
const isKeyProperty = (level, propertyName) => level?.properties?.[propertyName]?.[KEY_KEYWORD] === true;
|
|
532
|
+
const SchemaEditor = (props) => props.layout === 'tree' ? jsx(TreeSchemaEditor, { ...props }) : jsx(TableSchemaEditor, { ...props });
|
|
475
533
|
|
|
476
534
|
export { SchemaEditor, defaultSchemaEditorLabels };
|
|
477
535
|
//# sourceMappingURL=SchemaEditor.js.map
|