Skip to content
This repository was archived by the owner on Oct 26, 2026. It is now read-only.

Commit 2dcc28a

Browse files
committed
docs(components,plugin-grid,types): the schema window can be permanent; scope the text-over-secret union
Round 5 (wording only, no behaviour change): - "until it settles" becomes "until it arrives, and for good if that read fails": the grid swallows a failed schema read and keeps its heuristic column types (objectui#10706). - The object-declared half of the narrow-only union applies once the object schema has loaded; say so wherever the text-over-secret case is stated. Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN Co-authored-by: Claude <noreply@anthropic.com>
1 parent fe124b7 commit 2dcc28a

5 files changed

Lines changed: 26 additions & 21 deletions

File tree

‎.changeset/10583-masked-cell-copy.md‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ This is the grid face of the disclosure the detail page closed in objectui#8440.
3636

3737
Columns without the flag copy, show, export and edit exactly as before.
3838
- **`@object-ui/plugin-grid`: `ObjectGrid` sets the flag** at its column emit seam, from
39-
`isMaskedFieldType()` (objectui#8686). It reads the column's type and the
40-
object-declared type as a narrow-only union, the same shape as the detail page's
41-
`isMaskedDetailFieldType`. So a view that authors `type: 'text'` over a `secret` field
42-
keeps the refusal, and a view that authors `type: 'password'` masks a field the object
43-
declares as text. Once the object schema has loaded, the same rule leaves every masked
39+
`isMaskedFieldType()` (objectui#8686). It reads the column's type and, once the object
40+
schema has loaded, the object-declared type as a narrow-only union, the same shape as
41+
the detail page's `isMaskedDetailFieldType`. So a view that authors `type: 'password'`
42+
masks a field the object declares as text from first paint, and a view that authors
43+
`type: 'text'` over a `secret` field keeps the refusal once the schema has loaded. Once the object schema has loaded, the same rule leaves every masked
4444
field of the grid's object out of the grid's client export (CSV and JSON, used when the
4545
data source has no server export) and draws a masked field through its cell on the
4646
mobile card. Once the object schema has loaded, it also refuses a masked field as a
@@ -59,8 +59,9 @@ This is the grid face of the disclosure the detail page closed in objectui#8440.
5959
which folded objectui#10658).
6060
- On the host-fetched path (rows handed down as `data`, as `ListView` and `ObjectView`
6161
do), the grid's guards and the cell's own mask depend on the object schema, which the
62-
grid fetches after first paint. Until it settles, an untyped view column over a
63-
`password` / `secret` field draws and hands out the raw value (objectui#10706).
62+
grid fetches after first paint. Until it arrives, and for good if that read fails (the
63+
grid swallows the failure and keeps its heuristic column types), an untyped view column
64+
over a `password` / `secret` field draws and hands out the raw value (objectui#10706).
6465
- The server-streamed export (`exportDownload`) sends the masked columns as before and
6566
relies on the server's masking.
6667
- The client JSON export writes an expanded lookup record whole, so a credential field

‎content/docs/components/complex/data-table.mdx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,16 +161,16 @@ producer's `cell` renderer, and the table draws a column with no `cell` as its v
161161
You rarely set the flag by hand: `object-grid` sets it for every column whose field
162162
type is drawn as a mask (`password`, `secret`, or a type registered with the mask),
163163
from `isMaskedFieldType()` in `@object-ui/fields`. It reads both the view's column
164-
`type` and the object's field type, so a view that shows a `secret` field as `text`
165-
keeps the flag. Once the object schema has loaded, the same rule leaves every masked
164+
`type` and, once the object schema has loaded, the object's field type, so a view that
165+
shows a `secret` field as `text` keeps the flag once that schema has loaded. Once the object schema has loaded, the same rule leaves every masked
166166
field of the grid's object out of `object-grid`'s own client export (CSV and JSON),
167167
draws those fields through their `cell` on its mobile card, and refuses them as
168168
grouping keys (the entry is ignored with a console warning). What `object-grid` does
169169
not cover: on the host-fetched path (rows handed down as `data`, as `ListView` and
170170
`ObjectView` do), the grid's guards and the cell's own mask depend on the object
171-
schema, which the grid fetches after first paint, so until it settles an untyped
172-
view column over a `password` / `secret` field draws and hands out the raw value
173-
(objectui#10706). The server-streamed export (`exportDownload`) sends the masked
171+
schema, which the grid fetches after first paint, so until it arrives, and for good
172+
if that read fails, an untyped view column over a `password` / `secret` field draws
173+
and hands out the raw value (objectui#10706). The server-streamed export (`exportDownload`) sends the masked
174174
columns as before and relies on the server's masking, and the client JSON export
175175
writes an expanded lookup record whole, so a credential field of the related object
176176
is not pruned. Other producers of

‎packages/plugin-grid/README.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,10 @@ Not covered:
396396
which folded objectui#10658).
397397
- On the host-fetched path (rows handed down as `data`, as `ListView` and `ObjectView`
398398
do), the grid's guards and the cell's own mask depend on the object schema, which
399-
the grid fetches after first paint. Until it settles, an untyped view column over a
400-
`password` / `secret` field draws and hands out the raw value (objectui#10706).
399+
the grid fetches after first paint. Until it arrives, and for good if that read fails
400+
(the grid swallows the failure and keeps its heuristic column types), an untyped view
401+
column over a `password` / `secret` field draws and hands out the raw value
402+
(objectui#10706).
401403
- The server-streamed export (`exportDownload`) sends the masked columns as before
402404
and relies on the server's masking.
403405
- The client JSON export writes an expanded lookup record whole, so a credential

‎packages/plugin-grid/src/maskedColumn.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import { isMaskedFieldType } from '@object-ui/fields';
2525
* ⚠️ Every one of those paths asks with the object-declared type, which the grid
2626
* reads from the object schema it fetches after first paint. On the host-fetched
2727
* path (rows handed down as `data`) an untyped view column is therefore
28-
* unmasked until that schema settles (objectui#10706).
28+
* unmasked until that schema arrives, and for good if the read fails
29+
* (objectui#10706).
2930
*
3031
* The rule itself is NOT restated here — it is `isMaskedFieldType()` from
3132
* `@object-ui/fields`, the one authority for "is this field type's cell drawn

‎packages/types/src/data-display.ts‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -724,19 +724,20 @@ export interface TableColumn {
724724
* ⭐ The producer decides, and the rule is not restated here: `ObjectGrid`
725725
* stamps this flag from `isMaskedFieldType()` in `@object-ui/fields`
726726
* (objectui#8686), the one authority for "is this field type's cell drawn as
727-
* a mask", reading the view-authored type and the object-declared type as a
728-
* narrow-only UNION — a view authoring `type: 'text'` over a `secret`
729-
* column keeps the flag. Once the grid's object schema has loaded, the same
727+
* a mask", reading the view-authored type and, once the grid's object schema
728+
* has loaded, the object-declared type as a narrow-only UNION — a view
729+
* authoring `type: 'text'` over a `secret` column keeps the flag once that
730+
* schema has loaded. Once the grid's object schema has loaded, the same
730731
* rule also leaves every masked field of the grid's object out of the grid's
731732
* own client export, draws those fields through `cell` on its mobile card,
732733
* and refuses them as grouping keys. `@object-ui/components` cannot import
733734
* `@object-ui/fields`, so the table obeys the flag instead of asking the
734735
* question itself. Not covered there: on the host-fetched path (rows handed
735736
* down as `data`, as `ListView` and `ObjectView` do), the grid's guards and
736737
* the cell's own mask depend on the object schema, which the grid fetches
737-
* after first paint, so until it settles an untyped view column over a
738-
* `password` / `secret` field draws and hands out the raw value
739-
* (objectui#10706); the server-streamed export (`exportDownload`) sends the masked columns as
738+
* after first paint, so until it arrives, and for good if that read fails,
739+
* an untyped view column over a `password` / `secret` field draws and hands
740+
* out the raw value (objectui#10706); the server-streamed export (`exportDownload`) sends the masked columns as
740741
* before and relies on the server's masking; the client JSON export, and
741742
* this table's CSV export of a lookup column, write an expanded lookup
742743
* record whole, so a credential field of the related object is not pruned;

0 commit comments

Comments
 (0)