@dxos/react-ui-form 0.8.3 → 0.8.4-main.28f8d3d
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 +222 -209
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +222 -209
- 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.stories.d.ts +1 -1
- package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +4 -4
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +3 -3
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -1
- package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +2 -2
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +1 -1
- 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 +1 -1
- package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContext.d.ts +1 -1
- package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
- package/dist/types/src/components/Form/RefField.d.ts +1 -1
- package/dist/types/src/components/Form/RefField.d.ts.map +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 +1 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/factory.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +2 -2
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +4 -4
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/Form.d.ts +3 -3
- package/dist/types/src/components/deprecated/Form.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/Form.stories.d.ts +1 -1
- package/dist/types/src/components/deprecated/Form.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/useForm.d.ts +1 -1
- package/dist/types/src/hooks/useForm.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +57 -57
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +31 -32
- package/src/components/ControlSection/ControlSection.stories.tsx +3 -2
- package/src/components/FieldEditor/FieldEditor.stories.tsx +17 -14
- package/src/components/FieldEditor/FieldEditor.test.tsx +14 -13
- package/src/components/FieldEditor/FieldEditor.tsx +11 -11
- package/src/components/Form/ArrayField.tsx +8 -7
- package/src/components/Form/Defaults.tsx +2 -1
- package/src/components/Form/Form.stories.tsx +5 -4
- package/src/components/Form/Form.tsx +4 -3
- package/src/components/Form/FormActions.tsx +2 -1
- package/src/components/Form/FormContent.tsx +6 -5
- package/src/components/Form/FormContext.tsx +5 -5
- package/src/components/Form/RefField.tsx +7 -6
- package/src/components/Form/custom/GeoPointInput.tsx +2 -2
- package/src/components/Form/custom/SelectOptionsInput.stories.tsx +5 -4
- package/src/components/Form/custom/SelectOptionsInput.tsx +28 -29
- package/src/components/Form/factory.tsx +1 -1
- package/src/components/ViewEditor/ViewEditor.stories.tsx +21 -14
- package/src/components/ViewEditor/ViewEditor.test.tsx +41 -38
- package/src/components/ViewEditor/ViewEditor.tsx +81 -81
- package/src/components/deprecated/Form.stories.tsx +8 -7
- package/src/components/deprecated/Form.tsx +6 -6
- package/src/components/testing.tsx +1 -1
- package/src/hooks/useForm.ts +5 -3
- package/src/hooks/useRefQueryLookupHandler.ts +1 -1
- package/src/index.ts +1 -1
- package/src/translations.ts +7 -4
- package/dist/lib/node/index.cjs +0 -2416
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/types/src/components/ViewEditor/Test.stories.d.ts +0 -10
- package/dist/types/src/components/ViewEditor/Test.stories.d.ts.map +0 -1
- package/src/components/ViewEditor/Test.stories.tsx +0 -45
|
@@ -2,19 +2,18 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, { type ChangeEvent, type KeyboardEvent, useCallback, useEffect,
|
|
5
|
+
import React, { type ChangeEvent, type KeyboardEvent, useCallback, useEffect, useRef, useState } from 'react';
|
|
6
6
|
|
|
7
7
|
import { type SelectOption } from '@dxos/echo-schema';
|
|
8
8
|
import { PublicKey } from '@dxos/keys';
|
|
9
|
-
import { type ChromaticPalette,
|
|
9
|
+
import { type ChromaticPalette, IconButton, Input, Tag, useTranslation } from '@dxos/react-ui';
|
|
10
10
|
import { List } from '@dxos/react-ui-list';
|
|
11
11
|
import { HuePicker } from '@dxos/react-ui-pickers';
|
|
12
|
-
import { hues,
|
|
12
|
+
import { hues, subtleHover } from '@dxos/react-ui-theme';
|
|
13
13
|
|
|
14
14
|
import { translationKey } from '../../../translations';
|
|
15
15
|
import { InputHeader, type InputProps } from '../Input';
|
|
16
16
|
|
|
17
|
-
// TODO(ZaymonFC): Handle disabled.
|
|
18
17
|
export const SelectOptionInput = ({ type, label, disabled, getStatus, getValue, onValueChange }: InputProps) => {
|
|
19
18
|
const [selected, setSelectedId] = useState<string | null>(null);
|
|
20
19
|
const [isNewOption, setIsNewOption] = useState(false);
|
|
@@ -115,7 +114,12 @@ export const SelectOptionInput = ({ type, label, disabled, getStatus, getValue,
|
|
|
115
114
|
<InputHeader error={error} label={label} />
|
|
116
115
|
<div role='none'>
|
|
117
116
|
{options && (
|
|
118
|
-
<List.Root
|
|
117
|
+
<List.Root
|
|
118
|
+
items={options}
|
|
119
|
+
isItem={(item) => true}
|
|
120
|
+
onMove={disabled ? undefined : handleMove}
|
|
121
|
+
readonly={disabled}
|
|
122
|
+
>
|
|
119
123
|
{({ items }) => (
|
|
120
124
|
<div role='list' className='w-full overflow-auto'>
|
|
121
125
|
{items?.map((item) => (
|
|
@@ -123,26 +127,30 @@ export const SelectOptionInput = ({ type, label, disabled, getStatus, getValue,
|
|
|
123
127
|
<List.Item
|
|
124
128
|
role='button'
|
|
125
129
|
item={item}
|
|
126
|
-
classNames={
|
|
130
|
+
classNames={[subtleHover, 'flex flex-col cursor-pointer rounded-sm']}
|
|
127
131
|
aria-expanded={selected === item.id}
|
|
128
132
|
>
|
|
129
133
|
<div className='flex items-center'>
|
|
130
|
-
<List.ItemDragHandle />
|
|
134
|
+
<List.ItemDragHandle disabled={disabled} />
|
|
131
135
|
<List.ItemTitle onClick={() => handleClick(item.id)} classNames='flex-1'>
|
|
132
136
|
{/* TODO(ZaymonFC): Move spacer into Tag component. */}
|
|
133
137
|
<Tag palette={item.color as ChromaticPalette}>{item.title || '\u200b'}</Tag>
|
|
134
138
|
</List.ItemTitle>
|
|
135
|
-
<
|
|
139
|
+
<IconButton
|
|
140
|
+
iconOnly
|
|
141
|
+
variant='ghost'
|
|
142
|
+
label={t(selected === item.id ? 'collapse label' : 'expand label', { ns: 'os' })}
|
|
136
143
|
icon={selected === item.id ? 'ph--caret-down--regular' : 'ph--caret-right--regular'}
|
|
137
144
|
onClick={() => handleClick(item.id)}
|
|
138
145
|
/>
|
|
139
146
|
</div>
|
|
140
147
|
{selected === item.id && (
|
|
141
|
-
<div className='
|
|
148
|
+
<div className='pli-cardSpacingInline plb-cardSpacingBlock flex flex-col gap-1 density-fine'>
|
|
142
149
|
{/* 16px to match drag handle width. */}
|
|
143
150
|
<Input.Label classNames='text-xs'>{t('select option label')}</Input.Label>
|
|
144
|
-
<div className='
|
|
151
|
+
<div className='grid grid-cols-[1fr_min-content_min-content] gap-1'>
|
|
145
152
|
<Input.TextInput
|
|
153
|
+
disabled={disabled}
|
|
146
154
|
placeholder={t('select option label placeholder')}
|
|
147
155
|
ref={selected === item.id ? inputRef : undefined}
|
|
148
156
|
value={item.title}
|
|
@@ -151,14 +159,9 @@ export const SelectOptionInput = ({ type, label, disabled, getStatus, getValue,
|
|
|
151
159
|
classNames='flex-1'
|
|
152
160
|
data-no-submit
|
|
153
161
|
/>
|
|
154
|
-
<
|
|
155
|
-
<HuePicker
|
|
156
|
-
value={item.color}
|
|
157
|
-
onChange={handleColorChange(item.id)}
|
|
158
|
-
rootVariant='toolbar-button'
|
|
159
|
-
/>
|
|
160
|
-
</Toolbar.Root>
|
|
162
|
+
<HuePicker disabled={disabled} value={item.color} onChange={handleColorChange(item.id)} />
|
|
161
163
|
<IconButton
|
|
164
|
+
disabled={disabled}
|
|
162
165
|
icon='ph--trash--fill'
|
|
163
166
|
iconOnly
|
|
164
167
|
label={t('select option delete')}
|
|
@@ -170,18 +173,14 @@ export const SelectOptionInput = ({ type, label, disabled, getStatus, getValue,
|
|
|
170
173
|
</List.Item>
|
|
171
174
|
</div>
|
|
172
175
|
))}
|
|
173
|
-
<
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
<span className='text-sm'>{t('select option add')}</span>
|
|
182
|
-
</div>
|
|
183
|
-
</div>
|
|
184
|
-
</div>
|
|
176
|
+
<IconButton
|
|
177
|
+
variant='ghost'
|
|
178
|
+
icon='ph--plus--regular'
|
|
179
|
+
label={t('select option add')}
|
|
180
|
+
onClick={handleAdd}
|
|
181
|
+
disabled={disabled}
|
|
182
|
+
classNames='is-full'
|
|
183
|
+
/>
|
|
185
184
|
</div>
|
|
186
185
|
)}
|
|
187
186
|
</List.Root>
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
import { FormatEnum } from '@dxos/echo-schema';
|
|
6
6
|
import { type SimpleType } from '@dxos/effect';
|
|
7
7
|
|
|
8
|
+
import { GeoPointInput } from './custom';
|
|
8
9
|
import { BooleanInput, MarkdownInput, NumberInput, TextInput } from './Defaults';
|
|
9
10
|
import { type InputComponent } from './Input';
|
|
10
|
-
import { GeoPointInput } from './custom';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Get property input component.
|
|
@@ -4,26 +4,28 @@
|
|
|
4
4
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
|
-
import { type Meta, type StoryObj } from '@storybook/react';
|
|
7
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
8
|
import { Schema } from 'effect';
|
|
9
|
-
import React, { useCallback, useMemo, useState
|
|
9
|
+
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { Obj, Type } from '@dxos/echo';
|
|
12
|
+
import { type EchoSchema, Format, TypedObject, toJsonSchema } from '@dxos/echo-schema';
|
|
12
13
|
import { Filter, useQuery, useSpace } from '@dxos/react-client/echo';
|
|
13
14
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
14
15
|
import { useAsyncEffect } from '@dxos/react-ui';
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
16
|
+
import { DataType, ProjectionModel, createView } from '@dxos/schema';
|
|
17
|
+
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
17
18
|
|
|
18
|
-
import {
|
|
19
|
-
import translations from '../../translations';
|
|
19
|
+
import { translations } from '../../translations';
|
|
20
20
|
import { TestLayout, TestPanel, VIEW_EDITOR_DEBUG_SYMBOL } from '../testing';
|
|
21
21
|
|
|
22
|
+
import { ViewEditor, type ViewEditorProps } from './ViewEditor';
|
|
23
|
+
|
|
22
24
|
// Type definition for debug objects exposed to tests.
|
|
23
25
|
export type ViewEditorDebugObjects = {
|
|
24
26
|
schema: EchoSchema;
|
|
25
|
-
view:
|
|
26
|
-
projection:
|
|
27
|
+
view: DataType.View;
|
|
28
|
+
projection: ProjectionModel;
|
|
27
29
|
};
|
|
28
30
|
|
|
29
31
|
type StoryProps = Pick<ViewEditorProps, 'readonly'>;
|
|
@@ -31,8 +33,8 @@ type StoryProps = Pick<ViewEditorProps, 'readonly'>;
|
|
|
31
33
|
const DefaultStory = (props: StoryProps) => {
|
|
32
34
|
const space = useSpace();
|
|
33
35
|
const [schema, setSchema] = useState<EchoSchema>();
|
|
34
|
-
const [view, setView] = useState<
|
|
35
|
-
const [projection, setProjection] = useState<
|
|
36
|
+
const [view, setView] = useState<DataType.View>();
|
|
37
|
+
const [projection, setProjection] = useState<ProjectionModel>();
|
|
36
38
|
useAsyncEffect(async () => {
|
|
37
39
|
if (space) {
|
|
38
40
|
class TestSchema extends TypedObject({ typename: 'example.com/type/Test', version: '0.1.0' })({
|
|
@@ -42,8 +44,13 @@ const DefaultStory = (props: StoryProps) => {
|
|
|
42
44
|
}) {}
|
|
43
45
|
|
|
44
46
|
const [schema] = await space.db.schemaRegistry.register([TestSchema]);
|
|
45
|
-
const view = createView({
|
|
46
|
-
|
|
47
|
+
const view = createView({
|
|
48
|
+
name: 'Test',
|
|
49
|
+
typename: schema.typename,
|
|
50
|
+
jsonSchema: toJsonSchema(TestSchema),
|
|
51
|
+
presentation: Obj.make(Type.Expando, {}),
|
|
52
|
+
});
|
|
53
|
+
const projection = new ProjectionModel(schema.jsonSchema, view.projection);
|
|
47
54
|
|
|
48
55
|
setSchema(schema);
|
|
49
56
|
setView(view);
|
|
@@ -51,7 +58,7 @@ const DefaultStory = (props: StoryProps) => {
|
|
|
51
58
|
}
|
|
52
59
|
}, [space]);
|
|
53
60
|
|
|
54
|
-
const views = useQuery(space, Filter.type(
|
|
61
|
+
const views = useQuery(space, Filter.type(DataType.View));
|
|
55
62
|
const currentTypename = useMemo(() => view?.query?.typename, [view]);
|
|
56
63
|
const updateViewTypename = useCallback(
|
|
57
64
|
(newTypename: string) => {
|
|
@@ -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-schema';
|
|
10
|
-
import {
|
|
9
|
+
import { EchoSchema, isInstanceOf } from '@dxos/echo-schema';
|
|
10
|
+
import { DataType, ProjectionModel } 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(DataType.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 () => {
|
|
@@ -58,7 +59,7 @@ describe('ViewEditor', () => {
|
|
|
58
59
|
|
|
59
60
|
fireEvent.click(screen.getByTestId('save-button'));
|
|
60
61
|
|
|
61
|
-
// Wait for the changes to propagate to both UI and schema
|
|
62
|
+
// Wait for the changes to propagate to both UI and schema.
|
|
62
63
|
await waitFor(() => {
|
|
63
64
|
expect(screen.getByText('new_property')).toBeInTheDocument();
|
|
64
65
|
});
|
|
@@ -66,18 +67,18 @@ describe('ViewEditor', () => {
|
|
|
66
67
|
// Access the live objects directly from window using symbol.
|
|
67
68
|
const debugObjects = getViewEditorDebugObjects();
|
|
68
69
|
|
|
69
|
-
// Check schema contains new_property
|
|
70
|
+
// Check schema contains new_property.
|
|
70
71
|
const schemaProperties = debugObjects.schema.jsonSchema.properties;
|
|
71
72
|
expect(schemaProperties).toBeDefined();
|
|
72
73
|
expect(schemaProperties!.new_property).toBeDefined();
|
|
73
74
|
expect(schemaProperties!.name).toBeUndefined();
|
|
74
75
|
|
|
75
|
-
// Check view contains new_property field
|
|
76
|
-
const newPropertyField = debugObjects.view.fields.find((field: any) => field.path === 'new_property');
|
|
76
|
+
// Check view contains new_property field.
|
|
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
|
|
|
80
|
-
// Check projection contains new_property
|
|
81
|
+
// Check projection contains new_property.
|
|
81
82
|
const fieldProjections = debugObjects.projection.getFieldProjections();
|
|
82
83
|
const newPropertyProjection = fieldProjections.find((proj: any) => proj.field.path === 'new_property');
|
|
83
84
|
expect(newPropertyProjection).toBeDefined();
|
|
@@ -88,25 +89,25 @@ describe('ViewEditor', () => {
|
|
|
88
89
|
await Default.run();
|
|
89
90
|
await waitForViewEditor();
|
|
90
91
|
|
|
91
|
-
// Click the add property button
|
|
92
|
+
// Click the add property button.
|
|
92
93
|
const addButton = screen.getByText('Add property');
|
|
93
94
|
fireEvent.click(addButton);
|
|
94
95
|
|
|
95
|
-
// Fill out the property field
|
|
96
|
+
// Fill out the property field.
|
|
96
97
|
const fieldInput = screen.getByPlaceholderText('Field name.');
|
|
97
98
|
fireEvent.change(fieldInput, { target: { value: 'added_property' } });
|
|
98
99
|
|
|
99
|
-
// Click the format combo box and select the first option
|
|
100
|
+
// Click the format combo box and select the first option.
|
|
100
101
|
const formatCombo = screen.getByRole('combobox');
|
|
101
102
|
fireEvent.click(formatCombo);
|
|
102
103
|
|
|
103
104
|
const firstOption = screen.getAllByRole('option')[0];
|
|
104
105
|
fireEvent.click(firstOption);
|
|
105
106
|
|
|
106
|
-
// Save the changes
|
|
107
|
+
// Save the changes.
|
|
107
108
|
fireEvent.click(screen.getByTestId('save-button'));
|
|
108
109
|
|
|
109
|
-
// Wait for the changes to propagate
|
|
110
|
+
// Wait for the changes to propagate.
|
|
110
111
|
await waitFor(() => {
|
|
111
112
|
expect(screen.getByText('added_property')).toBeInTheDocument();
|
|
112
113
|
});
|
|
@@ -114,17 +115,19 @@ describe('ViewEditor', () => {
|
|
|
114
115
|
// Access the live objects directly from window using symbol.
|
|
115
116
|
const debugObjects = getViewEditorDebugObjects();
|
|
116
117
|
|
|
117
|
-
// Check schema contains added_property
|
|
118
|
+
// Check schema contains added_property.
|
|
118
119
|
const schemaProperties = debugObjects.schema.jsonSchema.properties;
|
|
119
120
|
expect(schemaProperties).toBeDefined();
|
|
120
121
|
expect(schemaProperties!.added_property).toBeDefined();
|
|
121
122
|
|
|
122
|
-
// Check view contains added_property field
|
|
123
|
-
const addedPropertyField = debugObjects.view.fields.find(
|
|
123
|
+
// Check view contains added_property field.
|
|
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
|
|
|
127
|
-
// Check projection contains added_property
|
|
130
|
+
// Check projection contains added_property.
|
|
128
131
|
const fieldProjections = debugObjects.projection.getFieldProjections();
|
|
129
132
|
const addedPropertyProjection = fieldProjections.find((proj: any) => proj.field.path === 'added_property');
|
|
130
133
|
expect(addedPropertyProjection).toBeDefined();
|
|
@@ -135,19 +138,19 @@ describe('ViewEditor', () => {
|
|
|
135
138
|
await Default.run();
|
|
136
139
|
await waitForViewEditor();
|
|
137
140
|
|
|
138
|
-
// Find the delete button for the 'name' property
|
|
141
|
+
// Find the delete button for the 'name' property.
|
|
139
142
|
const nameProperty = screen.getByText('name');
|
|
140
143
|
const propertyRow = nameProperty.closest('[role="listitem"]');
|
|
141
|
-
const deleteButton = propertyRow?.querySelector('
|
|
144
|
+
const deleteButton = propertyRow?.querySelector('[data-testid="field.delete"]');
|
|
142
145
|
|
|
143
146
|
if (!deleteButton) {
|
|
144
147
|
throw new Error('Delete button not found');
|
|
145
148
|
}
|
|
146
149
|
|
|
147
|
-
// Click the delete button
|
|
150
|
+
// Click the delete button.
|
|
148
151
|
fireEvent.click(deleteButton);
|
|
149
152
|
|
|
150
|
-
// Wait for the changes to propagate
|
|
153
|
+
// Wait for the changes to propagate.
|
|
151
154
|
await waitFor(() => {
|
|
152
155
|
expect(screen.queryByText('name')).not.toBeInTheDocument();
|
|
153
156
|
});
|
|
@@ -155,16 +158,16 @@ describe('ViewEditor', () => {
|
|
|
155
158
|
// Access the live objects directly from window using symbol.
|
|
156
159
|
const debugObjects = getViewEditorDebugObjects();
|
|
157
160
|
|
|
158
|
-
// Check schema no longer contains the name property
|
|
161
|
+
// Check schema no longer contains the name property.
|
|
159
162
|
const schemaProperties = debugObjects.schema.jsonSchema.properties;
|
|
160
163
|
expect(schemaProperties).toBeDefined();
|
|
161
164
|
expect(schemaProperties!.name).toBeUndefined();
|
|
162
165
|
|
|
163
|
-
// Check view no longer contains the name field
|
|
164
|
-
const nameField = debugObjects.view.fields.find((field: any) => field.path === 'name');
|
|
166
|
+
// Check view no longer contains the name field.
|
|
167
|
+
const nameField = debugObjects.view.projection.fields.find((field: any) => field.path === 'name');
|
|
165
168
|
expect(nameField).toBeUndefined();
|
|
166
169
|
|
|
167
|
-
// Check projection no longer contains the name property
|
|
170
|
+
// Check projection no longer contains the name property.
|
|
168
171
|
const fieldProjections = debugObjects.projection.getFieldProjections();
|
|
169
172
|
const nameProjection = fieldProjections.find((proj: any) => proj.field.path === 'name');
|
|
170
173
|
expect(nameProjection).toBeUndefined();
|
|
@@ -174,11 +177,11 @@ describe('ViewEditor', () => {
|
|
|
174
177
|
await Default.run();
|
|
175
178
|
await waitForViewEditor();
|
|
176
179
|
|
|
177
|
-
// Click the first hide button
|
|
180
|
+
// Click the first hide button.
|
|
178
181
|
const hideButtons = screen.getAllByTestId('hide-field-button');
|
|
179
182
|
fireEvent.click(hideButtons[0]);
|
|
180
183
|
|
|
181
|
-
// Check that hiddenFields is non-empty
|
|
184
|
+
// Check that hiddenFields is non-empty.
|
|
182
185
|
await waitFor(() => {
|
|
183
186
|
expect(screen.getByTestId('show-field-button')).toBeInTheDocument();
|
|
184
187
|
});
|
|
@@ -186,19 +189,19 @@ describe('ViewEditor', () => {
|
|
|
186
189
|
// Access the live objects directly from window using symbol.
|
|
187
190
|
const debugObjects = getViewEditorDebugObjects();
|
|
188
191
|
|
|
189
|
-
// Check that hiddenFields is non-empty
|
|
190
|
-
expect(debugObjects.view.hiddenFields).toBeDefined();
|
|
191
|
-
expect(debugObjects.view.hiddenFields!.length).toBeGreaterThan(0);
|
|
192
|
+
// Check that hiddenFields is non-empty.
|
|
193
|
+
expect(debugObjects.view.projection.hiddenFields).toBeDefined();
|
|
194
|
+
expect(debugObjects.view.projection.hiddenFields!.length).toBeGreaterThan(0);
|
|
192
195
|
|
|
193
196
|
// Click the show button
|
|
194
197
|
fireEvent.click(screen.getByTestId('show-field-button'));
|
|
195
198
|
|
|
196
|
-
// Wait for the data to update and check that hiddenFields is empty
|
|
199
|
+
// Wait for the data to update and check that hiddenFields is empty.
|
|
197
200
|
await waitFor(() => {
|
|
198
|
-
expect(debugObjects.view.hiddenFields!.length).toBe(0);
|
|
201
|
+
expect(debugObjects.view.projection.hiddenFields!.length).toBe(0);
|
|
199
202
|
});
|
|
200
203
|
|
|
201
|
-
// Also verify that the field is back in the visible fields list
|
|
202
|
-
expect(debugObjects.view.fields.length).toBeGreaterThan(0);
|
|
204
|
+
// Also verify that the field is back in the visible fields list.
|
|
205
|
+
expect(debugObjects.view.projection.fields.length).toBeGreaterThan(0);
|
|
203
206
|
});
|
|
204
207
|
});
|