@object-ui/fields 17.6.0 → 18.0.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/CHANGELOG.md +6228 -0
- package/README.md +251 -9
- package/dist/FieldEditWidget.d.ts +54 -6
- package/dist/coerceToSafeValue.d.ts +54 -0
- package/dist/currency.d.ts +1 -1
- package/dist/fieldHelpText.d.ts +41 -0
- package/dist/index.cjs +5 -5
- package/dist/index.css +68 -5
- package/dist/index.d.ts +446 -69
- package/dist/index.js +5326 -3443
- package/dist/resolveActionParams.d.ts +259 -0
- package/dist/widgets/AvatarField.d.ts +19 -3
- package/dist/widgets/BooleanField.d.ts +1 -1
- package/dist/widgets/DateField.d.ts +1 -1
- package/dist/widgets/DateTimeField.d.ts +1 -1
- package/dist/widgets/FilterConditionField.d.ts +21 -7
- package/dist/widgets/FormulaField.d.ts +41 -0
- package/dist/widgets/GeolocationField.d.ts +9 -3
- package/dist/widgets/GridField.d.ts +73 -101
- package/dist/widgets/LocationField.d.ts +30 -3
- package/dist/widgets/LookupField.d.ts +8 -0
- package/dist/widgets/NumberField.d.ts +1 -1
- package/dist/widgets/ObjectField.d.ts +9 -2
- package/dist/widgets/OptionsEmptyState.d.ts +29 -5
- package/dist/widgets/PasswordField.d.ts +14 -0
- package/dist/widgets/PeoplePicker.d.ts +17 -2
- package/dist/widgets/PercentField.d.ts +2 -1
- package/dist/widgets/PersonRow.d.ts +13 -2
- package/dist/widgets/RecipientPickerField.d.ts +75 -0
- package/dist/widgets/RecordPickerDialog.d.ts +31 -12
- package/dist/widgets/RegistryRefField.d.ts +77 -0
- package/dist/widgets/RichTextField.d.ts +1 -1
- package/dist/widgets/SelectionTray.d.ts +13 -2
- package/dist/widgets/SummaryField.d.ts +30 -0
- package/dist/widgets/TextField.d.ts +1 -1
- package/dist/widgets/TimeField.d.ts +1 -1
- package/dist/widgets/booleanValueLabel.d.ts +18 -0
- package/dist/widgets/date-picker/DatePickerField.d.ts +40 -0
- package/dist/widgets/date-picker/localeDateText.d.ts +39 -0
- package/dist/widgets/deriveLookupColumns.d.ts +1 -1
- package/dist/widgets/file-affordance.d.ts +63 -0
- package/dist/widgets/file-refused.d.ts +17 -0
- package/dist/widgets/file-size-guard.d.ts +5 -23
- package/dist/widgets/file-value.d.ts +49 -9
- package/dist/widgets/longTextCarrierHandoff.d.ts +35 -0
- package/dist/widgets/lookupColumnDisplay.d.ts +26 -9
- package/dist/widgets/nativeDateValue.d.ts +9 -27
- package/dist/widgets/number-format.d.ts +137 -0
- package/dist/widgets/numberBadInput.d.ts +135 -0
- package/dist/widgets/objectRefLabel.d.ts +16 -0
- package/dist/widgets/personDisplay.d.ts +22 -4
- package/dist/widgets/recipientKinds.d.ts +85 -0
- package/dist/widgets/richTextDisplay.d.ts +32 -13
- package/dist/widgets/searchOffer.d.ts +8 -0
- package/dist/widgets/toDomProps.d.ts +26 -4
- package/dist/widgets/toHostGroupProps.d.ts +53 -0
- package/dist/widgets/toHostProps.d.ts +105 -0
- package/dist/widgets/types.d.ts +11 -3
- package/dist/widgets/upload-error-message.d.ts +6 -0
- package/dist/widgets/uploadingScope.d.ts +142 -0
- package/dist/widgets/useCascadingOptions.d.ts +3 -2
- package/dist/widgets/useRecordQuery.d.ts +17 -2
- package/dist/widgets/useUploadingSignal.d.ts +8 -0
- package/package.json +11 -12
|
@@ -1,7 +1,34 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
+
import { LocationValue } from '@objectstack/spec/data';
|
|
2
3
|
import { FieldWidgetComponentProps } from './types.js';
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
5
|
+
* The stored shape of a `type: 'location'` value — RE-EXPORTED from
|
|
6
|
+
* `@objectstack/spec/data`, never re-declared here (objectui#6272).
|
|
7
|
+
*
|
|
8
|
+
* `LocationValue` is `z.input` of the spec's `LocationValueSchema`
|
|
9
|
+
* (`{ lat, lng, altitude?, accuracy? }`), which is what `valueSchemaFor({ type:
|
|
10
|
+
* 'location' })` validates a stored location against. A second local
|
|
11
|
+
* declaration under the spec's own name is objectstack#4115's failure class and
|
|
12
|
+
* is refused by `scripts/check-spec-symbol-derivation.mjs` — it was refused on
|
|
13
|
+
* the closed PR #6418, which is why this is a bare re-export.
|
|
6
14
|
*/
|
|
7
|
-
export
|
|
15
|
+
export type { LocationValue } from '@objectstack/spec/data';
|
|
16
|
+
/**
|
|
17
|
+
* LocationField - Geographic coordinate input for a `type: 'location'` value.
|
|
18
|
+
*
|
|
19
|
+
* Reads and writes `@objectstack/spec`'s `LocationValue` (`{ lat, lng }`) and
|
|
20
|
+
* displays it as the comma-separated pair a user types. The coordinates are
|
|
21
|
+
* still called latitude and longitude to a human — only the STORED key names
|
|
22
|
+
* are the spec's (objectui#6272), which is why the placeholder names the two
|
|
23
|
+
* coordinates rather than the `lat`/`lng` keys. That is a statement about KEY
|
|
24
|
+
* NAMES, not about language: the placeholder's words are the reader's, from
|
|
25
|
+
* the locale packs (objectui#8149, {@link placeholderPair}).
|
|
26
|
+
*
|
|
27
|
+
* ⚠️ BREAKING (objectui#6272): a record stored in the deprecated
|
|
28
|
+
* `{ latitude, longitude }` spelling — including one this widget itself wrote
|
|
29
|
+
* before the flip — now renders EMPTY here until it is re-saved or fixed at the
|
|
30
|
+
* data layer. It keeps rendering correctly in detail views and on the map,
|
|
31
|
+
* which read the spec spelling first. That cost was presented and accepted as
|
|
32
|
+
* part of the A1 ruling; it is not an oversight to route around with a shim.
|
|
33
|
+
*/
|
|
34
|
+
export declare function LocationField({ value, onChange, field, readonly, error, ...props }: FieldWidgetComponentProps<LocationValue | null>): React.JSX.Element;
|
|
@@ -3,6 +3,14 @@ import { FieldWidgetComponentProps } from './types.js';
|
|
|
3
3
|
export interface LookupOption {
|
|
4
4
|
value: string | number;
|
|
5
5
|
label: string;
|
|
6
|
+
/**
|
|
7
|
+
* Secondary text: searched by the popover typeahead alongside the label, and
|
|
8
|
+
* rendered as supporting text. For AUTHORED static options this is the
|
|
9
|
+
* declared `SelectOptionMetadata.description` (objectui#6153 — declared
|
|
10
|
+
* there, and on `@objectstack/spec`'s `SelectOptionSchema`, precisely
|
|
11
|
+
* because this widget consumes it); for fetched records `recordToOption`
|
|
12
|
+
* derives it from `descriptionField`.
|
|
13
|
+
*/
|
|
6
14
|
description?: string;
|
|
7
15
|
[key: string]: any;
|
|
8
16
|
}
|
|
@@ -4,4 +4,4 @@ import { FieldWidgetComponentProps } from './types.js';
|
|
|
4
4
|
* NumberField - Numeric input with optional decimal precision
|
|
5
5
|
* Supports min/max/step constraints and configurable decimal precision
|
|
6
6
|
*/
|
|
7
|
-
export declare function NumberField({ value, onChange, field, readonly, ...props }: FieldWidgetComponentProps<number>): React.JSX.Element;
|
|
7
|
+
export declare function NumberField({ value, onChange, field, readonly, error, ...props }: FieldWidgetComponentProps<number>): React.JSX.Element;
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { FieldWidgetComponentProps } from './types.js';
|
|
3
3
|
/**
|
|
4
|
-
* ObjectField - JSON
|
|
5
|
-
*
|
|
4
|
+
* ObjectField - JSON editor for a structured value.
|
|
5
|
+
*
|
|
6
|
+
* The form face of the free-form JSON types: `object`, `composite`, `record`, and
|
|
7
|
+
* since objectui#11448 `json`, which used to alias the raw-text code editor and
|
|
8
|
+
* so showed a stored object as `[object Object]` and saved an edit as a string.
|
|
9
|
+
* A json value need not be an object — an array, a number, a string, a boolean
|
|
10
|
+
* and `null` are all JSON — and this editor shows and parses each of them as
|
|
11
|
+
* itself: the box holds `JSON.stringify(value, null, 2)` and an edit emits
|
|
12
|
+
* `JSON.parse(text)`.
|
|
6
13
|
*/
|
|
7
14
|
export declare function ObjectField({ value, onChange, field, readonly, error, ...props }: FieldWidgetComponentProps<any>): React.JSX.Element;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
import { HostGroupProps } from './toHostGroupProps.js';
|
|
2
|
+
import { HostControlProps, HostGroupProps } from './toHostGroupProps.js';
|
|
3
3
|
/**
|
|
4
4
|
* The "this option list cannot be filled" state shared by every fixed-option
|
|
5
5
|
* widget (`SelectField` single, `MultiSelectField`, `RadioField`,
|
|
@@ -56,10 +56,34 @@ export interface OptionsEmptyStateProps {
|
|
|
56
56
|
* `aria-describedby` and the `role` that makes them meaningful may reach this
|
|
57
57
|
* element, and reopening a spread is what objectui#3291 exists to prevent —
|
|
58
58
|
* `aria-invalid` / `aria-required` are control-channel state and stay off this
|
|
59
|
-
* surface. Absent for the single `SelectField
|
|
60
|
-
*
|
|
61
|
-
* attributes.
|
|
59
|
+
* surface. Absent for the single `SelectField`, which is not group-labelled
|
|
60
|
+
* and fills {@link OptionsEmptyStateProps.hostControlProps} instead.
|
|
62
61
|
*/
|
|
63
62
|
hostGroupProps?: HostGroupProps;
|
|
63
|
+
/**
|
|
64
|
+
* The host label's PLAIN-`for` plumbing, for the one caller that is NOT
|
|
65
|
+
* group-labelled — the single `SelectField` (objectui#8803).
|
|
66
|
+
*
|
|
67
|
+
* Supplying this switches the rendered element from a `div` to an `<output>`,
|
|
68
|
+
* and that is the entire repair. `select` declares `labelling: 'control'`,
|
|
69
|
+
* which the registry defines as "the component's outermost rendered element
|
|
70
|
+
* is a LABELABLE HTML element" — true of the Radix
|
|
71
|
+
* `button[role="combobox"]` it renders with options, and FALSE of the `div`
|
|
72
|
+
* this box used to be. So the host's `for` pointed at an id no element
|
|
73
|
+
* carried, and `HTMLLabelElement.control` was null. Landing the id on the
|
|
74
|
+
* `div` instead was measured and rejected: `for` may only reference a
|
|
75
|
+
* labelable element, so it stayed null and the label stayed unusable.
|
|
76
|
+
*
|
|
77
|
+
* `<output>` is labelable, and its implicit `status` role claims no
|
|
78
|
+
* interactivity — it is the result of a computation, which is what this box
|
|
79
|
+
* reports. Declaring `select` as `'group'` was the alternative and it
|
|
80
|
+
* measurably moved the LIVE path: a select WITH options lost the working
|
|
81
|
+
* `<label for>` to its combobox (objectui#3306).
|
|
82
|
+
*
|
|
83
|
+
* Mutually exclusive with `hostGroupProps` — one host, one naming channel
|
|
84
|
+
* (objectui#3978). A caller that supplies neither renders the box with no
|
|
85
|
+
* host plumbing at all, which is what standalone rendering has always done.
|
|
86
|
+
*/
|
|
87
|
+
hostControlProps?: HostControlProps;
|
|
64
88
|
}
|
|
65
|
-
export declare function OptionsEmptyState({ emptyHint, gated, dependsOnFields, testId, className, hostGroupProps, }: OptionsEmptyStateProps): React.JSX.Element;
|
|
89
|
+
export declare function OptionsEmptyState({ emptyHint, gated, dependsOnFields, testId, className, hostGroupProps, hostControlProps, }: OptionsEmptyStateProps): React.JSX.Element;
|
|
@@ -3,5 +3,19 @@ import { FieldWidgetComponentProps } from './types.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* PasswordField - Secure password input with visibility toggle
|
|
5
5
|
* Includes show/hide toggle button and masks value in readonly mode
|
|
6
|
+
*
|
|
7
|
+
* Readonly draws the mask for a credential that is SET, and the shared
|
|
8
|
+
* `EmptyValue` affordance for one that is NOT (objectui#10639). The platform's
|
|
9
|
+
* read contract is presence-preserving: `@objectstack/spec`'s `SECRET_MASK`
|
|
10
|
+
* docblock says an unset credential "reads back `null` instead, never this
|
|
11
|
+
* mask", which is what lets a reader tell "configured" from "not configured".
|
|
12
|
+
*
|
|
13
|
+
* "Empty" is the password CELL's predicate (`MaskedCellRenderer` in this
|
|
14
|
+
* package's barrel, objectui#8678), called on the same two helpers, so `{}`
|
|
15
|
+
* and a whitespace-only string stay values and keep the mask. The helpers are
|
|
16
|
+
* imported from their own modules, never from the barrel, which lazy-loads
|
|
17
|
+
* this widget. ⛔ The value is never printed, and a set value keeps exactly
|
|
18
|
+
* the mask it drew before. `__tests__/PasswordField.readonlyEmpty-10639`
|
|
19
|
+
* pins the widget's "empty" to the cell's.
|
|
6
20
|
*/
|
|
7
21
|
export declare function PasswordField({ value, onChange, field, readonly, className, ...props }: FieldWidgetComponentProps<string>): React.JSX.Element;
|
|
@@ -27,12 +27,27 @@ export interface PeoplePickerProps {
|
|
|
27
27
|
dataSource: DataSource;
|
|
28
28
|
/** Object to query — `sys_user` for user fields. */
|
|
29
29
|
objectName: string;
|
|
30
|
+
/**
|
|
31
|
+
* The person's name field (default `name`), read first of the name ladder
|
|
32
|
+
* (then `name`, `username`, `label`). Once the permission policy has loaded,
|
|
33
|
+
* a rung the user may not read on `objectName` is skipped.
|
|
34
|
+
*/
|
|
30
35
|
displayField?: string;
|
|
31
36
|
idField?: string;
|
|
32
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* Dotted field paths for the row subtitle, e.g. `['primary_business_unit_id.name','email']`.
|
|
39
|
+
* Once the permission policy has loaded, a path whose field on `objectName`
|
|
40
|
+
* the user may not read is not drawn.
|
|
41
|
+
*/
|
|
33
42
|
subtitleFields?: string[];
|
|
43
|
+
/** Avatar image field; not drawn once the loaded policy denies it on `objectName`. */
|
|
34
44
|
avatarField?: string;
|
|
35
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* Related entities to expand (e.g. `['primary_business_unit_id']` for the
|
|
47
|
+
* department name). Once the permission policy has loaded, a relation the
|
|
48
|
+
* user may not read on `objectName` is left out, as it is from the list
|
|
49
|
+
* derived from `subtitleFields` when this is not passed.
|
|
50
|
+
*/
|
|
36
51
|
expand?: string[];
|
|
37
52
|
/** Narrow the server searchable set (ADR-0061). */
|
|
38
53
|
searchFields?: string[];
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { FieldWidgetComponentProps } from './types.js';
|
|
3
3
|
/**
|
|
4
|
-
* PercentField - Percentage input
|
|
4
|
+
* PercentField - Percentage input whose decimal places follow the field's
|
|
5
|
+
* `scale` as the protocol resolves it (see the read below)
|
|
5
6
|
* Stores values as decimals (0-1) and displays as percentages (0-100%)
|
|
6
7
|
* Includes a slider for interactive control.
|
|
7
8
|
*/
|
|
@@ -10,8 +10,19 @@ import { default as React } from 'react';
|
|
|
10
10
|
export interface PersonRowProps {
|
|
11
11
|
record: any;
|
|
12
12
|
displayField?: string;
|
|
13
|
+
/**
|
|
14
|
+
* The fields the name is read from, in order; defaults to the ladder of
|
|
15
|
+
* `displayField` (`getPersonNameFields`). PeoplePicker passes the fields of
|
|
16
|
+
* that ladder the loaded policy lets the viewer read (objectui#10535).
|
|
17
|
+
*/
|
|
18
|
+
nameFields?: string[];
|
|
13
19
|
subtitleFields?: string[];
|
|
14
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Avatar image field (default `image`). `null` draws no image, only the
|
|
22
|
+
* initials: what PeoplePicker passes when field-level security withholds the
|
|
23
|
+
* field (objectui#10433).
|
|
24
|
+
*/
|
|
25
|
+
avatarField?: string | null;
|
|
15
26
|
selected?: boolean;
|
|
16
27
|
/** Keyboard cursor is on this row — highlight + scroll into view. */
|
|
17
28
|
active?: boolean;
|
|
@@ -20,4 +31,4 @@ export interface PersonRowProps {
|
|
|
20
31
|
onSelect?: (record: any) => void;
|
|
21
32
|
className?: string;
|
|
22
33
|
}
|
|
23
|
-
export declare function PersonRow({ record, displayField, subtitleFields, avatarField, selected, active, highlightQuery, onSelect, className, }: PersonRowProps): React.JSX.Element;
|
|
34
|
+
export declare function PersonRow({ record, displayField, nameFields, subtitleFields, avatarField, selected, active, highlightQuery, onSelect, className, }: PersonRowProps): React.JSX.Element;
|
|
@@ -1,4 +1,79 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { FieldWidgetComponentProps } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* RecipientPickerField — dependent record picker for a polymorphic recipient
|
|
5
|
+
* reference (e.g. `sys_sharing_rule.recipient_id`), whose target object is
|
|
6
|
+
* decided by a sibling `recipient_type` select.
|
|
7
|
+
*
|
|
8
|
+
* Reached via the field `widget: 'recipient-picker'` hint (resolves as
|
|
9
|
+
* `field:recipient-picker`). Reads the live `recipient_type` from
|
|
10
|
+
* `dependentValues` (the form record), loads candidate records of the mapped
|
|
11
|
+
* object via `dataSource.find(...)`, and stores the value the sharing evaluator
|
|
12
|
+
* expects for that type:
|
|
13
|
+
*
|
|
14
|
+
* user → sys_user, store `id`
|
|
15
|
+
* team → sys_team, store `id`
|
|
16
|
+
* business_unit → sys_business_unit, store `id`
|
|
17
|
+
* unit_and_subordinates → sys_business_unit, store `id`
|
|
18
|
+
*
|
|
19
|
+
* One kind lists CATALOG ITEMS instead of records (objectui#7611, ADR-0131
|
|
20
|
+
* D3/D7): its candidates are the `position` items of the environment registry,
|
|
21
|
+
* read through the console's metadata store, and the picker stores the item's
|
|
22
|
+
* `name` (matched against `sys_user_position.position` at evaluation time):
|
|
23
|
+
*
|
|
24
|
+
* position → the `position` registry, store `name`
|
|
25
|
+
*
|
|
26
|
+
* One kind is NOT a record picker and therefore has no row above:
|
|
27
|
+
*
|
|
28
|
+
* field → a user-valued COLUMN of the shared object, store
|
|
29
|
+
* the column's `name` (see FIELD_RECIPIENT_TYPE)
|
|
30
|
+
*
|
|
31
|
+
* When `recipient_type` changes after mount the stored id is reset (an id valid
|
|
32
|
+
* for one type is meaningless for another). Unknown types degrade to a plain
|
|
33
|
+
* text input so nothing breaks.
|
|
34
|
+
*/
|
|
35
|
+
/** A user-valued column offered by the `field` recipient mode. */
|
|
36
|
+
interface UserFieldDef {
|
|
37
|
+
/** The machine name — this is what gets stored in `recipient_id`. */
|
|
38
|
+
name: string;
|
|
39
|
+
label: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Does this declared field hold USERS?
|
|
43
|
+
*
|
|
44
|
+
* ⭐ This predicate is the picker's half of a two-sided agreement with the
|
|
45
|
+
* sharing evaluator, which asks the same question of the same two spellings:
|
|
46
|
+
* the `user` type (whose target is fixed to `sys_user` by the type itself —
|
|
47
|
+
* `Field.user()` takes no target), and a `lookup` / `master_detail` whose
|
|
48
|
+
* `reference` is `sys_user`.
|
|
49
|
+
*
|
|
50
|
+
* ⛔ The two must not drift apart. The evaluator treats a column that is not
|
|
51
|
+
* user-typed as "grants nobody" and warns once per rule, so a picker that
|
|
52
|
+
* OFFERED a wider set would let an admin save a rule that looks configured and
|
|
53
|
+
* authorises nobody — worse than the hand-typed name this mode replaces,
|
|
54
|
+
* because it has a credible appearance.
|
|
55
|
+
*
|
|
56
|
+
* `reference` is the only spelling the protocol declares (objectui#6837):
|
|
57
|
+
* `FieldSchema` refuses `reference_to` by name, and the evaluator reads
|
|
58
|
+
* `reference` as well.
|
|
59
|
+
*
|
|
60
|
+
* @internal exported for tests
|
|
61
|
+
*/
|
|
62
|
+
export declare function fieldHoldsUsers(def: unknown): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* The user-valued columns of an object schema, in declaration order.
|
|
65
|
+
*
|
|
66
|
+
* Accepts both shapes an object schema spells `fields` in — a name-keyed map
|
|
67
|
+
* and an array of definitions carrying their own `name`.
|
|
68
|
+
*
|
|
69
|
+
* ⛔ `hidden` is deliberately NOT filtered here, unlike the filter builder's
|
|
70
|
+
* own field derivation: the evaluator honours a hidden user column exactly
|
|
71
|
+
* like a visible one, and withholding it would break the agreement above in
|
|
72
|
+
* the other direction — an authorable, working configuration the picker
|
|
73
|
+
* refuses to offer.
|
|
74
|
+
*
|
|
75
|
+
* @internal exported for tests
|
|
76
|
+
*/
|
|
77
|
+
export declare function deriveUserFields(schema: any): UserFieldDef[];
|
|
3
78
|
export declare function RecipientPickerField({ value, onChange, readonly, className, error, ...props }: FieldWidgetComponentProps<string>): React.JSX.Element;
|
|
4
79
|
export default RecipientPickerField;
|
|
@@ -41,7 +41,12 @@ export interface RecordPickerFilterBarProps {
|
|
|
41
41
|
* Allows plugging in ObjectGrid or any compatible table component.
|
|
42
42
|
*/
|
|
43
43
|
export interface RecordPickerGridSlotProps {
|
|
44
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* Resolved column definitions, less the ones field-level security denies
|
|
46
|
+
* once the permission policy has loaded, the display column included — the
|
|
47
|
+
* columns the built-in table draws (objectui#10373). When none survives,
|
|
48
|
+
* this is the id column alone.
|
|
49
|
+
*/
|
|
45
50
|
columns: LookupColumnDef[];
|
|
46
51
|
/** Current page of records */
|
|
47
52
|
records: any[];
|
|
@@ -93,16 +98,30 @@ export interface RecordPickerDialogProps {
|
|
|
93
98
|
objectName: string;
|
|
94
99
|
/** Columns to display. Defaults to [displayField, descriptionField]. */
|
|
95
100
|
columns?: Array<string | LookupColumnDef>;
|
|
96
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* The display field as the lookup DECLARES it. The display column is keyed on
|
|
103
|
+
* it, or on `'name'` when it is omitted. With `objectSchema` given, a declared
|
|
104
|
+
* value is also the first rung of the column's title (the resolver's
|
|
105
|
+
* `titleField`); the `'name'` default never is, because it is a guess and a
|
|
106
|
+
* guess never outranks the referenced object's own declarations. So pass
|
|
107
|
+
* `undefined` when the field declares none, never a pre-filled `'name'`.
|
|
108
|
+
*/
|
|
97
109
|
displayField?: string;
|
|
98
110
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
111
|
+
* The referenced object's schema (objectui#10486). When given, the display
|
|
112
|
+
* column renders each record's title through `@object-ui/core`'s
|
|
113
|
+
* `getRecordDisplayName`, the call LookupField's dropdown option label and
|
|
114
|
+
* the read cell make: the declared `displayField`, then the object's
|
|
115
|
+
* `nameField`, then its deprecated `titleFormat` template, then type-aware
|
|
116
|
+
* derivation (ADR-0079). The title reads the row with its relations
|
|
117
|
+
* collapsed to ids and the fields the loaded policy denies removed, exactly
|
|
118
|
+
* as the dropdown's option label does.
|
|
119
|
+
*
|
|
120
|
+
* Replaces the retired `titleFormat` prop: a bare template cut out of the
|
|
121
|
+
* schema ranked above the `nameField` beside it, so the picker and the
|
|
122
|
+
* dropdown labelled one record two ways.
|
|
104
123
|
*/
|
|
105
|
-
|
|
124
|
+
objectSchema?: Record<string, unknown> | null;
|
|
106
125
|
/** Record id field (default: 'id') */
|
|
107
126
|
idField?: string;
|
|
108
127
|
/** Page size (default: 10) */
|
|
@@ -119,7 +138,7 @@ export interface RecordPickerDialogProps {
|
|
|
119
138
|
onSelectRecords?: (records: any[]) => void;
|
|
120
139
|
/**
|
|
121
140
|
* Base filters applied to every query.
|
|
122
|
-
* Converted from LookupFieldMetadata.
|
|
141
|
+
* Converted from LookupFieldMetadata.lookupFilters.
|
|
123
142
|
* Restricts which records are selectable (e.g. only active records).
|
|
124
143
|
*/
|
|
125
144
|
lookupFilters?: LookupFilterDef[];
|
|
@@ -145,7 +164,7 @@ export interface RecordPickerDialogProps {
|
|
|
145
164
|
* (`before`, `after`, `is_empty`, `is_not_empty`) the record form has no
|
|
146
165
|
* `$op` for. No second operator vocabulary is introduced here: two already
|
|
147
166
|
* exist (the spec's `AST_OPERATOR_MAP`, data-objectstack's
|
|
148
|
-
* `FILTER_OPERATOR_ALIASES`) and #3948 is what a third costs.
|
|
167
|
+
* `FILTER_OPERATOR_ALIASES`) and objectstack-ai/objectstack#3948 is what a third costs.
|
|
149
168
|
*
|
|
150
169
|
* The discriminator is exact rather than heuristic — every AST node is an
|
|
151
170
|
* ARRAY and a rule is a plain OBJECT, the same predicate `toFilterNode` uses.
|
|
@@ -168,7 +187,7 @@ export interface RecordPickerDialogProps {
|
|
|
168
187
|
* The referenced object's schema `fields` map (field name → field
|
|
169
188
|
* definition). When provided, cell renderers receive the FULL field
|
|
170
189
|
* metadata — `options`, `currency`, `scale`, `precision`, `format`,
|
|
171
|
-
* `
|
|
190
|
+
* `reference`, … — exactly like the list view enriches its columns from
|
|
172
191
|
* the object schema. Without it a `select` column falls back to
|
|
173
192
|
* title-casing the raw stored value instead of resolving the option label
|
|
174
193
|
* (#3333: `manufacturing` rendered as "Manufacturing" instead of the
|
|
@@ -225,4 +244,4 @@ export interface RecordPickerDialogProps {
|
|
|
225
244
|
* states, and single/multi-select. Responsive: mobile-friendly width
|
|
226
245
|
* via Tailwind breakpoints.
|
|
227
246
|
*/
|
|
228
|
-
export declare function RecordPickerDialog({ open, onOpenChange, title, multiple, dataSource, objectName, columns: columnsProp, displayField,
|
|
247
|
+
export declare function RecordPickerDialog({ open, onOpenChange, title, multiple, dataSource, objectName, columns: columnsProp, displayField: declaredDisplayField, objectSchema, idField, pageSize, value, onSelect, onSelectRecords, lookupFilters, baseFilter, cellRenderer, fieldsMeta, filterColumns, renderFilterBar, renderGrid, }: RecordPickerDialogProps): React.JSX.Element;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { FieldWidgetComponentProps } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* RegistryRefField — a record-form field that names ONE item of ONE metadata
|
|
5
|
+
* registry type by its machine name (objectui#7611, ruling B2 on
|
|
6
|
+
* objectstack#22865).
|
|
7
|
+
*
|
|
8
|
+
* The record-form face of the mechanism the metadata forms already have
|
|
9
|
+
* (`ref-multi:permission`, objectui#12126): the registry's items are listed by
|
|
10
|
+
* name, with the author's label beside the name, and the value written is the
|
|
11
|
+
* NAME — one string, never an id, never a row. A grant names its position or
|
|
12
|
+
* its permission set that way (ADR-0131 D4), and the server refuses a name the
|
|
13
|
+
* registry does not hold, so this widget only has to make the right name easy
|
|
14
|
+
* to pick.
|
|
15
|
+
*
|
|
16
|
+
* Reached through a field's `widget:` hint, which the form renderer looks up as
|
|
17
|
+
* `field:<widget>` (the spec's `FieldSchema.widget`). One registration per
|
|
18
|
+
* registry type, with the type in the key, as `object-ref` carries `object`:
|
|
19
|
+
*
|
|
20
|
+
* position-ref → `GET /api/v1/meta/position`
|
|
21
|
+
* permission-ref → `GET /api/v1/meta/permission`
|
|
22
|
+
*
|
|
23
|
+
* The catalog comes from `DataSource.listMetadataItems`, which rejects on a
|
|
24
|
+
* failure rather than answering `[]`, so its four arms are told apart the way
|
|
25
|
+
* the metadata forms' `ref:dataset` / `ref-multi:<type>` pickers tell them
|
|
26
|
+
* apart:
|
|
27
|
+
*
|
|
28
|
+
* - IDLE — no data source, or one that cannot enumerate a registry: a text
|
|
29
|
+
* box that writes the typed name;
|
|
30
|
+
* - LOADING — the stored name in a disabled box;
|
|
31
|
+
* - FAILED — a notice naming the failure and its cause, beside a text box that
|
|
32
|
+
* stays enabled, so a failed catalog does not also block the edit;
|
|
33
|
+
* - LOADED — nothing a grant can name: the same text box as IDLE; otherwise
|
|
34
|
+
* a searchable picker. A stored name the catalog does not list stays
|
|
35
|
+
* selectable as its own option, flagged "not found", so it is neither
|
|
36
|
+
* dropped nor read as a listed item. The flag is a claim about the
|
|
37
|
+
* registry's answer, so it is made only once the catalog has answered.
|
|
38
|
+
*
|
|
39
|
+
* The picker OFFERS only what a grant can name (objectui#12200). A position
|
|
40
|
+
* grant cannot name an audience anchor — `everyone` or `guest` (ADR-0090
|
|
41
|
+
* D5/D9), held implicitly by every authenticated or anonymous principal — and
|
|
42
|
+
* the server refuses a `sys_user_position` row that does. So `position-ref`
|
|
43
|
+
* leaves the anchors out of its options ({@link nonGrantableNames}). A stored
|
|
44
|
+
* anchor is still the row's value: it stays on screen as its own option, by its
|
|
45
|
+
* label beside its name, and it is not flagged "not found", because the
|
|
46
|
+
* registry does list it.
|
|
47
|
+
*
|
|
48
|
+
* ⛔ No arm writes anything but a name the person picked or typed: no label,
|
|
49
|
+
* no id, no first-item default.
|
|
50
|
+
*/
|
|
51
|
+
/** One listed item of a registry: the name stored, the label shown beside it. */
|
|
52
|
+
export interface RegistryItemHeader {
|
|
53
|
+
name: string;
|
|
54
|
+
label?: string;
|
|
55
|
+
}
|
|
56
|
+
/** The catalog, in whichever of its four states the load is actually in. */
|
|
57
|
+
export type RegistryCatalogState = {
|
|
58
|
+
status: 'idle';
|
|
59
|
+
} | {
|
|
60
|
+
status: 'loading';
|
|
61
|
+
} | {
|
|
62
|
+
status: 'error';
|
|
63
|
+
message: string;
|
|
64
|
+
} | {
|
|
65
|
+
status: 'loaded';
|
|
66
|
+
items: RegistryItemHeader[];
|
|
67
|
+
};
|
|
68
|
+
export interface RegistryRefFieldProps extends FieldWidgetComponentProps<string> {
|
|
69
|
+
/** The registry type whose items this field names (`position`, `permission`). */
|
|
70
|
+
registryType: string;
|
|
71
|
+
}
|
|
72
|
+
export declare function RegistryRefField({ registryType, value, onChange, readonly, className, error, ...props }: RegistryRefFieldProps): React.JSX.Element;
|
|
73
|
+
/** `position-ref`: names one position of the position registry. */
|
|
74
|
+
export declare function PositionRefField(props: FieldWidgetComponentProps<string>): React.JSX.Element;
|
|
75
|
+
/** `permission-ref`: names one permission set of the `permission` registry. */
|
|
76
|
+
export declare function PermissionRefField(props: FieldWidgetComponentProps<string>): React.JSX.Element;
|
|
77
|
+
export default RegistryRefField;
|
|
@@ -23,7 +23,7 @@ import { FieldWidgetComponentProps } from './types.js';
|
|
|
23
23
|
* from the shared `FullscreenFieldEditor`, so one form-level setting keeps
|
|
24
24
|
* producing one behaviour across both widgets.
|
|
25
25
|
*
|
|
26
|
-
* ## Readonly display (
|
|
26
|
+
* ## Readonly display (`4bb940b6e`)
|
|
27
27
|
*
|
|
28
28
|
* The readonly early return used to render `{value}` as a React TEXT CHILD,
|
|
29
29
|
* so a readonly field of any of the three types showed the user the markup
|
|
@@ -12,7 +12,18 @@ export interface SelectionTrayProps {
|
|
|
12
12
|
/** Remove a selected record by its id. */
|
|
13
13
|
onRemove: (id: any) => void;
|
|
14
14
|
displayField?: string;
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* The fields each chip's name is read from, in order; defaults to the ladder
|
|
17
|
+
* of `displayField` (`getPersonNameFields`). PeoplePicker passes the fields
|
|
18
|
+
* of that ladder the loaded policy lets the viewer read (objectui#10535).
|
|
19
|
+
*/
|
|
20
|
+
nameFields?: string[];
|
|
21
|
+
/**
|
|
22
|
+
* Avatar image field (default `image`). `null` draws no image, only the
|
|
23
|
+
* initials: what PeoplePicker passes when field-level security withholds the
|
|
24
|
+
* field (objectui#10433).
|
|
25
|
+
*/
|
|
26
|
+
avatarField?: string | null;
|
|
16
27
|
idField?: string;
|
|
17
28
|
/** Header label, e.g. "Selected (3)" — omit to hide the header. */
|
|
18
29
|
label?: string;
|
|
@@ -24,4 +35,4 @@ export interface SelectionTrayProps {
|
|
|
24
35
|
emptyText?: string;
|
|
25
36
|
className?: string;
|
|
26
37
|
}
|
|
27
|
-
export declare function SelectionTray({ records, onRemove, displayField, avatarField, idField, label, onClear, clearLabel, emptyText, className, }: SelectionTrayProps): React.JSX.Element;
|
|
38
|
+
export declare function SelectionTray({ records, onRemove, displayField, nameFields, avatarField, idField, label, onClear, clearLabel, emptyText, className, }: SelectionTrayProps): React.JSX.Element;
|
|
@@ -3,5 +3,35 @@ import { FieldWidgetComponentProps } from './types.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* SummaryField - Read-only aggregation field
|
|
5
5
|
* Values are aggregated from related records and cannot be edited
|
|
6
|
+
*
|
|
7
|
+
* ## One value, one reading (objectui#11752)
|
|
8
|
+
*
|
|
9
|
+
* This is the read-only FORM face of a roll-up; its TABLE face is the formula
|
|
10
|
+
* cell, `FormulaCellRenderer` in this package's barrel, which `summary` is
|
|
11
|
+
* registered to. The two used to format the value each by itself, so one
|
|
12
|
+
* stored value read two ways: this face picked a format by the roll-up's
|
|
13
|
+
* aggregation `function` (`count` as it arrived, the other four at two fixed
|
|
14
|
+
* decimals), so a `sum` over `15750.5` read `15750.50`, ungrouped and in every
|
|
15
|
+
* locale, beside the cell's `15,750.5`.
|
|
16
|
+
*
|
|
17
|
+
* This face now reads the value the way the cell reads a summary's value,
|
|
18
|
+
* whatever the function:
|
|
19
|
+
*
|
|
20
|
+
* - the emptiness FLOOR (`isEmptyValue`) on the coerced value, as the cell
|
|
21
|
+
* takes it, so `''` and `[]` read the shared affordance in both faces;
|
|
22
|
+
* - a JS number: `formatNumberFieldValue`, the one call every number face
|
|
23
|
+
* makes (the display locale's grouping, the width `resolveFieldScale`
|
|
24
|
+
* answers for a declared `scale`, the value's natural precision when none
|
|
25
|
+
* is declared). A `count` is a whole number, so it reads whole; an author
|
|
26
|
+
* who wants a fixed width on a `sum` or an `avg` declares `scale`, and both
|
|
27
|
+
* faces honour it.
|
|
28
|
+
* - anything else: the coerced value as text, as the cell prints it. A
|
|
29
|
+
* summary declares no `returnType`, so a string of digits is not a number.
|
|
30
|
+
*
|
|
31
|
+
* The rule is spelled here and in the cell, because the barrel and this lazily
|
|
32
|
+
* loaded widget may not import each other (the reason `number-format.ts`
|
|
33
|
+
* gives). `__tests__/summaryFaces.numberFace-11752.test.tsx` draws every
|
|
34
|
+
* aggregation function in both faces and compares the two texts, so neither
|
|
35
|
+
* can move alone.
|
|
6
36
|
*/
|
|
7
37
|
export declare function SummaryField({ value, field, ...props }: FieldWidgetComponentProps<any>): React.JSX.Element;
|
|
@@ -4,4 +4,4 @@ import { FieldWidgetComponentProps } from './types.js';
|
|
|
4
4
|
* TextField - Standard single-line or multi-line text input
|
|
5
5
|
* Automatically renders as a textarea when rows are configured in field metadata
|
|
6
6
|
*/
|
|
7
|
-
export declare function TextField({ value, onChange, field, readonly, ...props }: FieldWidgetComponentProps<string>): React.JSX.Element;
|
|
7
|
+
export declare function TextField({ value, onChange, field, readonly, error, ...props }: FieldWidgetComponentProps<string>): React.JSX.Element;
|
|
@@ -4,4 +4,4 @@ import { FieldWidgetComponentProps } from './types.js';
|
|
|
4
4
|
* TimeField - Time picker input widget
|
|
5
5
|
* Uses native time input for hour and minute selection
|
|
6
6
|
*/
|
|
7
|
-
export declare function TimeField({ value, onChange, field, readonly, ...props }: FieldWidgetComponentProps<string>): React.JSX.Element;
|
|
7
|
+
export declare function TimeField({ value, onChange, field, readonly, error, ...props }: FieldWidgetComponentProps<string>): React.JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
/** Draws a boolean value as the current locale's word for it. */
|
|
3
|
+
export type BooleanValueLabel = (value: boolean) => string;
|
|
4
|
+
/**
|
|
5
|
+
* The current locale's word for a boolean value: `common.yes` for `true`,
|
|
6
|
+
* `common.no` for `false`.
|
|
7
|
+
*
|
|
8
|
+
* The caller decides WHICH values are booleans; this only names them. Call it
|
|
9
|
+
* once at the top of a component and use the returned function in the render.
|
|
10
|
+
*/
|
|
11
|
+
export declare function useBooleanValueLabel(): BooleanValueLabel;
|
|
12
|
+
/**
|
|
13
|
+
* The same word as a node, for a caller that is a plain function and cannot
|
|
14
|
+
* call a hook itself (`renderLookupColumnValue`).
|
|
15
|
+
*/
|
|
16
|
+
export declare function BooleanValueText({ value }: {
|
|
17
|
+
value: boolean;
|
|
18
|
+
}): React.ReactElement;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { FieldWidgetComponentProps } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The `date` and date-time controls of the form field widgets
|
|
5
|
+
* (objectui#12622, objectui#12642).
|
|
6
|
+
*
|
|
7
|
+
* `fieldWidgetMap`'s `date` / `datetime` widgets — what a record form resolves
|
|
8
|
+
* `field:date` / `field:datetime` to, and what `getLazyFieldWidget` hands the
|
|
9
|
+
* action-param and bulk-action dialogs — draw the platform picker instead of
|
|
10
|
+
* the browser's native input: a text box in the display locale's format (keyboard
|
|
11
|
+
* entry), a calendar popover (the same `Calendar` the calendar view's date
|
|
12
|
+
* popover opens, localized by the same resolver), a clear button, and
|
|
13
|
+
* today / tomorrow shortcuts.
|
|
14
|
+
*
|
|
15
|
+
* ## The value written is unchanged
|
|
16
|
+
*
|
|
17
|
+
* Both faces go through the native adapters `DateField` / `DateTimeField` use
|
|
18
|
+
* (`toDateInputValue`, `toDateTimeInputValue`, `fromDateTimeInputValue`), so a
|
|
19
|
+
* `date` field writes `YYYY-MM-DD` and a `datetime` field writes an ISO
|
|
20
|
+
* instant, exactly as the native inputs did; clearing writes `''` as the
|
|
21
|
+
* native inputs did.
|
|
22
|
+
*
|
|
23
|
+
* ## Where the native input stays
|
|
24
|
+
*
|
|
25
|
+
* - The read-only face is `DateField` / `DateTimeField`'s own, rendered as is.
|
|
26
|
+
* - `FieldEditWidget` (the grid's inline cell editor and the kanban
|
|
27
|
+
* required-fields dialog) draws THIS picker since objectui#12664, loaded
|
|
28
|
+
* lazily so it stays in its own chunk; the grid's cell seam blurs the
|
|
29
|
+
* control before Enter or a click outside commits, and that blur is where
|
|
30
|
+
* the typed text is read. plugin-detail's `InlineFieldInput` (the record
|
|
31
|
+
* page's details and highlights) delegates `date` and `datetime` to
|
|
32
|
+
* `FieldEditWidget` too since objectui#12759. The list filter rows are
|
|
33
|
+
* objectui#12743.
|
|
34
|
+
* - A form whose `field:date` widget is not registered (no
|
|
35
|
+
* `@object-ui/fields` loaded) falls back to the form renderer's own
|
|
36
|
+
* `<input type={inputType}>`, with the `inputType` `ObjectForm` maps.
|
|
37
|
+
*/
|
|
38
|
+
export declare function DatePickerField(props: FieldWidgetComponentProps<string>): React.JSX.Element;
|
|
39
|
+
/** The `datetime` face of {@link DatePickerField}. */
|
|
40
|
+
export declare function DateTimePickerField(props: FieldWidgetComponentProps<string>): React.JSX.Element;
|