@dxos/react-ui-form 0.8.4-main.f9ba587 → 0.8.4-main.fffef41
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/lib/browser/index.mjs +884 -637
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +884 -637
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/ControlSection/ControlSection.d.ts +2 -2
- package/dist/types/src/components/ControlSection/ControlSection.d.ts.map +1 -1
- package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts +80 -5
- package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +4 -5
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +77 -7
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/ArrayField.d.ts +2 -2
- package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -1
- package/dist/types/src/components/Form/Defaults.d.ts +5 -5
- package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +8 -6
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +128 -32
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormActions.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContent.d.ts +17 -11
- package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContext.d.ts +3 -3
- package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
- package/dist/types/src/components/Form/Input.d.ts +5 -2
- package/dist/types/src/components/Form/Input.d.ts.map +1 -1
- package/dist/types/src/components/Form/RefField.d.ts +15 -5
- package/dist/types/src/components/Form/RefField.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +1 -1
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +1 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +75 -4
- package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/TupleInput.d.ts +1 -1
- package/dist/types/src/components/Form/factory.d.ts +1 -1
- package/dist/types/src/components/Form/factory.d.ts.map +1 -1
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +41 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +81 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -0
- package/dist/types/src/components/ObjectPicker/index.d.ts +2 -0
- package/dist/types/src/components/ObjectPicker/index.d.ts.map +1 -0
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +20 -6
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +80 -9
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +6 -3
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/useForm.d.ts +3 -3
- package/dist/types/src/hooks/useForm.d.ts.map +1 -1
- package/dist/types/src/hooks/useQueryRefOptions.d.ts +9 -3
- package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +1 -1
- package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +13 -8
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/util/field.d.ts +1 -1
- package/dist/types/src/util/field.d.ts.map +1 -1
- package/dist/types/src/util/formatting.d.ts +1 -1
- package/dist/types/src/util/formatting.d.ts.map +1 -1
- package/dist/types/src/util/refs.d.ts +1 -1
- package/dist/types/src/util/refs.d.ts.map +1 -1
- package/dist/types/src/util/schema.d.ts +1 -1
- package/dist/types/src/util/schema.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +42 -36
- package/src/components/ControlSection/ControlSection.stories.tsx +11 -14
- package/src/components/ControlSection/ControlSection.tsx +26 -12
- package/src/components/FieldEditor/FieldEditor.stories.tsx +26 -24
- package/src/components/FieldEditor/FieldEditor.test.tsx +14 -13
- package/src/components/FieldEditor/FieldEditor.tsx +21 -23
- package/src/components/Form/ArrayField.tsx +13 -12
- package/src/components/Form/Defaults.tsx +23 -21
- package/src/components/Form/Form.stories.tsx +135 -99
- package/src/components/Form/Form.tsx +30 -16
- package/src/components/Form/FormActions.tsx +4 -3
- package/src/components/Form/FormContent.tsx +171 -49
- package/src/components/Form/FormContext.tsx +8 -8
- package/src/components/Form/Input.tsx +5 -2
- package/src/components/Form/RefField.tsx +111 -41
- package/src/components/Form/custom/GeoPointInput.tsx +29 -21
- package/src/components/Form/custom/SelectOptionsInput.stories.tsx +11 -11
- package/src/components/Form/custom/SelectOptionsInput.tsx +31 -32
- package/src/components/Form/custom/TupleInput.tsx +2 -2
- package/src/components/Form/factory.tsx +2 -2
- package/src/components/ObjectPicker/ObjectPicker.stories.tsx +207 -0
- package/src/components/ObjectPicker/ObjectPicker.tsx +161 -0
- package/src/components/ObjectPicker/index.ts +5 -0
- package/src/components/ViewEditor/ViewEditor.stories.tsx +130 -49
- package/src/components/ViewEditor/ViewEditor.test.tsx +19 -19
- package/src/components/ViewEditor/ViewEditor.tsx +281 -233
- package/src/components/index.ts +1 -2
- package/src/components/testing.tsx +15 -9
- package/src/hooks/useForm.ts +11 -6
- package/src/hooks/useQueryRefOptions.ts +15 -6
- package/src/hooks/useRefQueryLookupHandler.ts +3 -3
- package/src/translations.ts +15 -9
- package/src/util/field.ts +9 -19
- package/src/util/formatting.ts +1 -1
- package/src/util/refs.ts +7 -7
- package/src/util/schema.ts +2 -4
- package/dist/types/src/components/deprecated/Form.d.ts +0 -15
- package/dist/types/src/components/deprecated/Form.d.ts.map +0 -1
- package/dist/types/src/components/deprecated/Form.stories.d.ts +0 -13
- package/dist/types/src/components/deprecated/Form.stories.d.ts.map +0 -1
- package/dist/types/src/components/deprecated/FormInput.d.ts +0 -16
- package/dist/types/src/components/deprecated/FormInput.d.ts.map +0 -1
- package/dist/types/src/components/deprecated/index.d.ts +0 -2
- package/dist/types/src/components/deprecated/index.d.ts.map +0 -1
- package/src/components/deprecated/Form.stories.tsx +0 -62
- package/src/components/deprecated/Form.tsx +0 -119
- package/src/components/deprecated/FormInput.tsx +0 -71
- package/src/components/deprecated/index.ts +0 -5
|
@@ -2,87 +2,142 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
|
-
import
|
|
9
|
-
import React, { useCallback, useMemo,
|
|
6
|
+
import * as Schema from 'effect/Schema';
|
|
7
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
10
8
|
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
9
|
+
import { DXN, Filter, Obj, Query, type QueryAST, Tag, Type } from '@dxos/echo';
|
|
10
|
+
import { type EchoSchema, Format } from '@dxos/echo/internal';
|
|
11
|
+
import { useQuery } from '@dxos/react-client/echo';
|
|
12
|
+
import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
|
|
14
13
|
import { useAsyncEffect } from '@dxos/react-ui';
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
14
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
15
|
+
import { type ProjectionModel, View, getTypenameFromQuery } from '@dxos/schema';
|
|
16
|
+
import { Employer, Organization, Person, Project } from '@dxos/types';
|
|
17
17
|
|
|
18
|
-
import { ViewEditor, type ViewEditorProps } from './ViewEditor';
|
|
19
18
|
import { translations } from '../../translations';
|
|
20
19
|
import { TestLayout, TestPanel, VIEW_EDITOR_DEBUG_SYMBOL } from '../testing';
|
|
21
20
|
|
|
21
|
+
import { ViewEditor, type ViewEditorProps } from './ViewEditor';
|
|
22
|
+
|
|
23
|
+
const types = [
|
|
24
|
+
// TODO(burdon): Get label from annotation.
|
|
25
|
+
{ value: Organization.Organization.typename, label: 'Organization' },
|
|
26
|
+
{ value: Person.Person.typename, label: 'Person' },
|
|
27
|
+
{ value: Type.getTypename(Project.Project), label: 'Project' },
|
|
28
|
+
{ value: Employer.Employer.typename, label: 'Employer' },
|
|
29
|
+
];
|
|
30
|
+
|
|
22
31
|
// Type definition for debug objects exposed to tests.
|
|
23
32
|
export type ViewEditorDebugObjects = {
|
|
24
33
|
schema: EchoSchema;
|
|
25
|
-
view:
|
|
26
|
-
projection:
|
|
34
|
+
view: View.View;
|
|
35
|
+
projection: ProjectionModel;
|
|
27
36
|
};
|
|
28
37
|
|
|
29
|
-
type StoryProps = Pick<ViewEditorProps, 'readonly'>;
|
|
38
|
+
type StoryProps = Pick<ViewEditorProps, 'readonly' | 'mode'>;
|
|
30
39
|
|
|
31
40
|
const DefaultStory = (props: StoryProps) => {
|
|
32
|
-
const space =
|
|
41
|
+
const { space } = useClientProvider();
|
|
33
42
|
const [schema, setSchema] = useState<EchoSchema>();
|
|
34
|
-
const [view, setView] = useState<
|
|
35
|
-
const
|
|
43
|
+
const [view, setView] = useState<View.View>();
|
|
44
|
+
const projectionRef = useRef<ProjectionModel>(null);
|
|
45
|
+
|
|
46
|
+
const tags = useQuery(space, Filter.type(Tag.Tag));
|
|
47
|
+
|
|
36
48
|
useAsyncEffect(async () => {
|
|
37
49
|
if (space) {
|
|
38
|
-
|
|
50
|
+
const TestSchema = Schema.Struct({
|
|
39
51
|
name: Schema.String,
|
|
40
52
|
email: Format.Email,
|
|
41
53
|
salary: Format.Currency(),
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
54
|
+
}).pipe(
|
|
55
|
+
Type.Obj({
|
|
56
|
+
typename: 'example.com/type/Test',
|
|
57
|
+
version: '0.1.0',
|
|
58
|
+
}),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const AlternateSchema = Schema.Struct({
|
|
62
|
+
title: Schema.String,
|
|
63
|
+
description: Schema.String,
|
|
64
|
+
completed: Schema.Boolean,
|
|
65
|
+
}).pipe(
|
|
66
|
+
Type.Obj({
|
|
67
|
+
typename: 'example.com/type/Alternate',
|
|
68
|
+
version: '0.1.0',
|
|
69
|
+
}),
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const [testSchema] = await space.db.schemaRegistry.register([TestSchema, AlternateSchema]);
|
|
73
|
+
const view = View.make({
|
|
74
|
+
name: 'Test',
|
|
75
|
+
query: Query.select(Filter.type(TestSchema)),
|
|
76
|
+
jsonSchema: Type.toJsonSchema(TestSchema),
|
|
77
|
+
presentation: Obj.make(Type.Expando, {}),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
setSchema(testSchema);
|
|
49
81
|
setView(view);
|
|
50
|
-
setProjection(projection);
|
|
51
82
|
}
|
|
52
83
|
}, [space]);
|
|
53
84
|
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
(newTypename: string) => {
|
|
58
|
-
if (!schema) {
|
|
85
|
+
const updateViewQuery = useCallback(
|
|
86
|
+
async (newQuery: QueryAST.Query, target?: string) => {
|
|
87
|
+
if (!schema || !view || !space) {
|
|
59
88
|
return;
|
|
60
89
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
90
|
+
|
|
91
|
+
if (props.mode === 'query') {
|
|
92
|
+
const queue = target && DXN.tryParse(target) ? target : undefined;
|
|
93
|
+
const query = queue ? Query.fromAst(newQuery).options({ queues: [queue] }) : Query.fromAst(newQuery);
|
|
94
|
+
view.query.ast = query.ast;
|
|
95
|
+
|
|
96
|
+
const typename = getTypenameFromQuery(query.ast);
|
|
97
|
+
const [newSchema] = await space.db.schemaRegistry.query({ typename }).run();
|
|
98
|
+
if (!newSchema) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const newView = View.make({
|
|
103
|
+
query,
|
|
104
|
+
jsonSchema: newSchema.jsonSchema,
|
|
105
|
+
presentation: Obj.make(Type.Expando, {}),
|
|
106
|
+
});
|
|
107
|
+
view.projection = Obj.getSnapshot(newView).projection;
|
|
108
|
+
setSchema(() => newSchema);
|
|
109
|
+
} else {
|
|
110
|
+
console.log('updateViewQuery', { newQuery });
|
|
111
|
+
view.query.ast = newQuery;
|
|
112
|
+
schema.updateTypename(getTypenameFromQuery(newQuery));
|
|
64
113
|
}
|
|
65
|
-
schema.updateTypename(newTypename);
|
|
66
114
|
},
|
|
67
|
-
[
|
|
115
|
+
[view, schema],
|
|
68
116
|
);
|
|
69
117
|
|
|
70
|
-
const handleDelete = useCallback(
|
|
118
|
+
const handleDelete = useCallback(
|
|
119
|
+
(property: string) => projectionRef.current?.deleteFieldProjection(property),
|
|
120
|
+
[projectionRef],
|
|
121
|
+
);
|
|
71
122
|
|
|
72
123
|
// Expose objects on window for test access.
|
|
73
124
|
useEffect(() => {
|
|
74
|
-
if (typeof window !== 'undefined' && schema && view &&
|
|
75
|
-
(window as any)[VIEW_EDITOR_DEBUG_SYMBOL] = {
|
|
125
|
+
if (typeof window !== 'undefined' && schema && view && projectionRef.current) {
|
|
126
|
+
(window as any)[VIEW_EDITOR_DEBUG_SYMBOL] = {
|
|
127
|
+
schema,
|
|
128
|
+
view,
|
|
129
|
+
projection: projectionRef.current,
|
|
130
|
+
} satisfies ViewEditorDebugObjects;
|
|
76
131
|
}
|
|
77
|
-
}, [schema, view
|
|
132
|
+
}, [schema, view]);
|
|
78
133
|
|
|
79
134
|
// NOTE(ZaymonFC): This looks awkward but it resolves an infinite parsing issue with sb.
|
|
80
135
|
const json = useMemo(
|
|
81
|
-
() => JSON.parse(JSON.stringify({ schema, view, projection })),
|
|
82
|
-
[JSON.stringify(schema), JSON.stringify(view)
|
|
136
|
+
() => JSON.parse(JSON.stringify({ schema, view, projection: projectionRef.current })),
|
|
137
|
+
[JSON.stringify(schema), JSON.stringify(view)],
|
|
83
138
|
);
|
|
84
139
|
|
|
85
|
-
if (!schema || !view
|
|
140
|
+
if (!schema || !view) {
|
|
86
141
|
return <div />;
|
|
87
142
|
}
|
|
88
143
|
|
|
@@ -90,11 +145,15 @@ const DefaultStory = (props: StoryProps) => {
|
|
|
90
145
|
<TestLayout json={json}>
|
|
91
146
|
<TestPanel>
|
|
92
147
|
<ViewEditor
|
|
148
|
+
ref={projectionRef}
|
|
93
149
|
schema={schema}
|
|
94
150
|
view={view}
|
|
95
151
|
registry={space?.db.schemaRegistry}
|
|
152
|
+
mode={props.mode}
|
|
96
153
|
readonly={props.readonly}
|
|
97
|
-
|
|
154
|
+
types={types}
|
|
155
|
+
tags={tags}
|
|
156
|
+
onQueryChanged={updateViewQuery}
|
|
98
157
|
onDelete={handleDelete}
|
|
99
158
|
/>
|
|
100
159
|
</TestPanel>
|
|
@@ -102,19 +161,41 @@ const DefaultStory = (props: StoryProps) => {
|
|
|
102
161
|
);
|
|
103
162
|
};
|
|
104
163
|
|
|
105
|
-
const meta
|
|
164
|
+
const meta = {
|
|
106
165
|
title: 'ui/react-ui-form/ViewEditor',
|
|
107
166
|
render: DefaultStory,
|
|
108
|
-
decorators: [
|
|
109
|
-
|
|
110
|
-
|
|
167
|
+
decorators: [
|
|
168
|
+
withClientProvider({
|
|
169
|
+
createSpace: true,
|
|
170
|
+
types: [Tag.Tag],
|
|
171
|
+
onCreateSpace: ({ space }) => {
|
|
172
|
+
space.db.add(Tag.make({ label: 'Important' }));
|
|
173
|
+
space.db.add(Tag.make({ label: 'Investor' }));
|
|
174
|
+
space.db.add(Tag.make({ label: 'New' }));
|
|
175
|
+
},
|
|
176
|
+
}),
|
|
177
|
+
withTheme,
|
|
178
|
+
],
|
|
179
|
+
parameters: {
|
|
180
|
+
layout: 'fullscreen',
|
|
181
|
+
translations,
|
|
182
|
+
},
|
|
183
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
111
184
|
|
|
112
185
|
export default meta;
|
|
113
186
|
|
|
114
|
-
type Story = StoryObj<
|
|
187
|
+
type Story = StoryObj<typeof meta>;
|
|
115
188
|
|
|
116
189
|
export const Default: Story = {};
|
|
117
190
|
|
|
118
191
|
export const Readonly: Story = {
|
|
119
|
-
args: {
|
|
192
|
+
args: {
|
|
193
|
+
readonly: true,
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
export const QueryMode: Story = {
|
|
198
|
+
args: {
|
|
199
|
+
mode: 'query',
|
|
200
|
+
},
|
|
120
201
|
};
|
|
@@ -3,15 +3,16 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { composeStories } from '@storybook/react';
|
|
6
|
-
import {
|
|
6
|
+
import { cleanup, fireEvent, screen, waitFor } from '@testing-library/react';
|
|
7
7
|
import { afterEach, describe, expect, test } from 'vitest';
|
|
8
8
|
|
|
9
|
-
import { EchoSchema } from '@dxos/echo
|
|
10
|
-
import {
|
|
9
|
+
import { EchoSchema, isInstanceOf } from '@dxos/echo/internal';
|
|
10
|
+
import { ProjectionModel, View } from '@dxos/schema';
|
|
11
|
+
|
|
12
|
+
import { VIEW_EDITOR_DEBUG_SYMBOL } from '../testing';
|
|
11
13
|
|
|
12
14
|
import * as stories from './ViewEditor.stories';
|
|
13
15
|
import { type ViewEditorDebugObjects } from './ViewEditor.stories';
|
|
14
|
-
import { VIEW_EDITOR_DEBUG_SYMBOL } from '../testing';
|
|
15
16
|
|
|
16
17
|
const { Default } = composeStories(stories);
|
|
17
18
|
|
|
@@ -19,8 +20,8 @@ const getViewEditorDebugObjects = (): ViewEditorDebugObjects => {
|
|
|
19
20
|
const debugObjects = (window as any)[VIEW_EDITOR_DEBUG_SYMBOL] as ViewEditorDebugObjects;
|
|
20
21
|
expect(debugObjects).toBeDefined();
|
|
21
22
|
expect(debugObjects.schema).toBeInstanceOf(EchoSchema);
|
|
22
|
-
expect(debugObjects.view).
|
|
23
|
-
expect(debugObjects.projection).toBeInstanceOf(
|
|
23
|
+
expect(isInstanceOf(View.View, debugObjects.view)).toBeTruthy();
|
|
24
|
+
expect(debugObjects.projection).toBeInstanceOf(ProjectionModel);
|
|
24
25
|
return debugObjects;
|
|
25
26
|
};
|
|
26
27
|
|
|
@@ -41,7 +42,7 @@ describe('ViewEditor', () => {
|
|
|
41
42
|
test('renders view editor', async () => {
|
|
42
43
|
await Default.run();
|
|
43
44
|
await waitForViewEditor();
|
|
44
|
-
expect(screen.getByText('
|
|
45
|
+
expect(screen.getByText('Record type')).toBeInTheDocument();
|
|
45
46
|
});
|
|
46
47
|
|
|
47
48
|
test('change property name', async () => {
|
|
@@ -73,7 +74,7 @@ describe('ViewEditor', () => {
|
|
|
73
74
|
expect(schemaProperties!.name).toBeUndefined();
|
|
74
75
|
|
|
75
76
|
// Check view contains new_property field.
|
|
76
|
-
const newPropertyField = debugObjects.view.fields.find((field: any) => field.path === 'new_property');
|
|
77
|
+
const newPropertyField = debugObjects.view.projection.fields.find((field: any) => field.path === 'new_property');
|
|
77
78
|
expect(newPropertyField).toBeDefined();
|
|
78
79
|
expect(newPropertyField!.path).toBe('new_property');
|
|
79
80
|
|
|
@@ -120,7 +121,9 @@ describe('ViewEditor', () => {
|
|
|
120
121
|
expect(schemaProperties!.added_property).toBeDefined();
|
|
121
122
|
|
|
122
123
|
// Check view contains added_property field.
|
|
123
|
-
const addedPropertyField = debugObjects.view.fields.find(
|
|
124
|
+
const addedPropertyField = debugObjects.view.projection.fields.find(
|
|
125
|
+
(field: any) => field.path === 'added_property',
|
|
126
|
+
);
|
|
124
127
|
expect(addedPropertyField).toBeDefined();
|
|
125
128
|
expect(addedPropertyField!.path).toBe('added_property');
|
|
126
129
|
|
|
@@ -131,14 +134,15 @@ describe('ViewEditor', () => {
|
|
|
131
134
|
expect(addedPropertyProjection!.props.property).toBe('added_property');
|
|
132
135
|
});
|
|
133
136
|
|
|
134
|
-
|
|
137
|
+
// TODO(mykola): Fix flaky test.
|
|
138
|
+
test('delete property', { retry: 2 }, async () => {
|
|
135
139
|
await Default.run();
|
|
136
140
|
await waitForViewEditor();
|
|
137
141
|
|
|
138
142
|
// Find the delete button for the 'name' property.
|
|
139
143
|
const nameProperty = screen.getByText('name');
|
|
140
144
|
const propertyRow = nameProperty.closest('[role="listitem"]');
|
|
141
|
-
const deleteButton = propertyRow?.querySelector('
|
|
145
|
+
const deleteButton = propertyRow?.querySelector('[data-testid="field.delete"]');
|
|
142
146
|
|
|
143
147
|
if (!deleteButton) {
|
|
144
148
|
throw new Error('Delete button not found');
|
|
@@ -161,7 +165,7 @@ describe('ViewEditor', () => {
|
|
|
161
165
|
expect(schemaProperties!.name).toBeUndefined();
|
|
162
166
|
|
|
163
167
|
// Check view no longer contains the name field.
|
|
164
|
-
const nameField = debugObjects.view.fields.find((field: any) => field.path === 'name');
|
|
168
|
+
const nameField = debugObjects.view.projection.fields.find((field: any) => field.path === 'name');
|
|
165
169
|
expect(nameField).toBeUndefined();
|
|
166
170
|
|
|
167
171
|
// Check projection no longer contains the name property.
|
|
@@ -186,19 +190,15 @@ describe('ViewEditor', () => {
|
|
|
186
190
|
// Access the live objects directly from window using symbol.
|
|
187
191
|
const debugObjects = getViewEditorDebugObjects();
|
|
188
192
|
|
|
189
|
-
// Check that hiddenFields is non-empty.
|
|
190
|
-
expect(debugObjects.view.hiddenFields).toBeDefined();
|
|
191
|
-
expect(debugObjects.view.hiddenFields!.length).toBeGreaterThan(0);
|
|
192
|
-
|
|
193
193
|
// Click the show button
|
|
194
194
|
fireEvent.click(screen.getByTestId('show-field-button'));
|
|
195
195
|
|
|
196
196
|
// Wait for the data to update and check that hiddenFields is empty.
|
|
197
197
|
await waitFor(() => {
|
|
198
|
-
expect(debugObjects.view.
|
|
198
|
+
expect(debugObjects.view.projection.fields.filter(({ visible }) => visible === false)!.length).toBe(0);
|
|
199
199
|
});
|
|
200
200
|
|
|
201
201
|
// Also verify that the field is back in the visible fields list.
|
|
202
|
-
expect(debugObjects.view.fields.length).toBeGreaterThan(0);
|
|
202
|
+
expect(debugObjects.view.projection.fields.filter(({ visible }) => visible !== false).length).toBeGreaterThan(0);
|
|
203
203
|
});
|
|
204
|
-
});
|
|
204
|
+
}, 30_000);
|