fix(tables): rework lock settings as Table Security and gate locked actions - #7853
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
|
…s as Table Security
…d tables - Update-locked tables open cell editors read-only; the expanded editor disables Save with the reason on hover, and empty cells that can't be edited open nothing - New row opens the Add Row form when only updates are locked - Row form reads and writes values by column id and uses one date-and-time picker - ChipDatePicker follows InsideModalContext so its calendar is clickable in modals, and gains showTime/timeLabel in single mode
j15z
force-pushed
the
fix/row-locking-columns-bug
branch
from
September 15, 2026 19:14
57f0d4d to
1dbc256
Compare
… on required fields - New row, Shift+Enter, and Insert row open the Add Row form at their position when updates are locked or any column is required - Add Row and Update Row stay disabled until every required field has a value - Add mode accepts an insert position; Shift+Enter anchors to the neighbor row id
Clicking a column header opened the full column editor on a schema-locked table: every field was editable and Save only failed once the server refused it. The header click is the primary way into that panel, so it now opens read-only — values stay readable and selectable, a disabled `<fieldset>` makes the controls inert, and Save carries the lock reason. Clicking a checkbox cell on an update-locked table did nothing at all, while the keyboard paths explained themselves; it now raises the same notice. The column menu disabled only "Edit column" while "Insert column left/right" and "Delete column" stayed live and explained the lock after the click. All four are disabled now, each with a tooltip. A disabled `DropdownMenuItem` sets `pointer-events: none`, so the tooltip wraps the row rather than the item. "Hide column" is untouched: hiding a workflow output is a metadata change no lock covers. Notices now speak the modal's Allow/Deny vocabulary and name the row that denies the action, and the tooltip strings live in `lock-copy` instead of being written out at each call site. Drops the "This table is append-only" copy, which no path could reach once New row and Shift+Enter started opening the add-row form. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…s once The add/edit row form sent every column on every save. An untouched empty column was written as `null`, so a no-op edit still bumped the row, and an insert filled in nulls for columns the user never opened. It now sends only the fields the user touched, and in edit mode only those whose value actually differs — a save with nothing changed closes without a write. Checkboxes stay the exception on insert: they always carry a concrete boolean, so a required one the user never clicked still reaches the server as `false`. A rejected write also arrived twice: the modal rendered the message inline and the mutation toasted the same sentence. Row mutations take an opt-in `suppressErrorToast` so the form owns its own failure; the cache self-heal on a 423 still runs, only its toast is dropped. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… store "Enable Table Security" had no server representation: enabled-with-everything- allowed and never-configured both save four `false` flags, so the difference lived only in the browser that set it. Anyone else — another device, another admin — saw the table as unconfigured, and the per-action choices behind the switch were remembered per device too. The modal now always shows the four Allow/Deny rows, mapped one-to-one onto the server flags, so an unconfigured table opens on four `Allow`s and every viewer sees the same state. That removes the reason for the preference store, which is deleted along with its helpers and test. Stale `table-security-preferences` keys are left where they are; nothing reads them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The modal reset its draft only when it opened, so a lock another admin changed while it sat open went stale behind it: the controls kept rendering the old values and Save submitted all four flags, overwriting the newer state. Only the rows this admin moves are staged now. Every other row keeps rendering the authoritative value, so a concurrent change shows up in the open modal instead of hiding behind it, and Save sends just that patch — the route already takes a partial — so an untouched row can't carry a stale flag over someone else's change. A row both admins moved is the one real conflict, and there the explicit choice wins. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Collaborator
Author
Collaborator
Author
|
@cursor review |
|
Skipping Bugbot: Bugbot is disabled for this repository. Visit the Bugbot dashboard to update your settings. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces Lock settings with a Table Security modal, and makes a denied action explain itself where the user meets it instead of failing on save or doing nothing at all.
Denyis a set lock — so an unconfigured table opens on fourAllows and every viewer sees the same state. No backend or migration change.aria-disabled, and explains itself in a tooltip. Edit column, Insert column left/right, and Delete column are all disabled with tooltips. Clicking a column header opens the config panel read-only — values stay readable and selectable, the controls are inert, and Save carries the reason.Hide columnis untouched: hiding a workflow output is a metadata change no lock covers.↵ save.nulland a no-op save closes without a write. Checkboxes are the exception on insert: they always carry a concrete boolean.suppressErrorToast; the cache self-heal on a 423 still runs.lock-copyrather than at each call site.ChipDatePicker: followsInsideModalContextlikeChipDropdown(fix(ui): keep modal popovers interactive #7435 missed it), so its calendar is clickable inside modals, including the document tags modal. Single mode gainsshowTimeandtimeLabel.Reviewer notes:
*.-00:00offset whiledatecolumns use the viewer's local offset. Existing behavior, left as is.Type of Change
Testing
Allow, mirrors server locks withDenyas a set lock, saves denied actions as locks, and keeps the modal open with the draft intact when the save fails.↵ savewhile blocked, and saves normally when allowed.type-checkandlintpass; 607 tests acrosstables/[tableId]andhooks/queriespass.Checklist
Screenshots/Videos
Before:


After:


🤖 Generated with Claude Code