Fix: states not updated#2698
Conversation
Console (appwrite/console)Project ID: Tip Git integration provides automatic deployments with optional PR comments |
WalkthroughThis PR refactors disabled state management across four row editing components. The changes replace imperative function-based disable checks (isDisabled(), disableSubmit()) with a declarative reactive prop-and-effect pattern. The main layout component introduces three disabled state flags (editRowDisabled, editRelatedRowDisabled, editRowPermissionsDisabled) that are bound to child components as props. Child components now receive these disabled states and use reactive effects to synchronize them with internal validation conditions. Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editRelated.svelte (1)
309-317: Remove redundant disabled state update.The
disabledStateis updated in two places:
- Line 314: Manually in
handleFormUpdate- Line 342: Reactively in
$effectThis creates duplicate work and potential timing issues. The reactive
$effectalready tracks all necessary dependencies (viaworkDatareactivity when stores are updated), making the manual update redundant.Remove the manual update from
handleFormUpdate:function handleFormUpdate(rowId: string) { return (updatedFormValues: object) => { const workStore = workData.get(rowId); if (workStore) { workStore.set(updatedFormValues as Models.Row); - disabledState = calculateAndCompareDisabledState(); } }; }The
$effectat line 341-343 will automatically recalculate whenworkDatastores change, sincecalculateAndCompareDisabledState()reads from those stores viaget(work).Also applies to: 341-343
🧹 Nitpick comments (4)
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editRelated.svelte (1)
38-41: Remove the onMount anti-pattern.Using
onMountsolely to reference a variable to silence compiler warnings is an anti-pattern. If the prop is truly unused, the warning is legitimate. However,disabledStateis actually consumed by the parent via$bindable, so the warning is incorrect.In Svelte 5, bindable props that are only written (not read) by the component can trigger false "not read" warnings. The proper solution is to either:
- Add
// @ts-expect-error - bindable prop written by reactive effectabove the prop declaration, or- Use
$inspect(disabledState)in development modeThe current approach adds unnecessary lifecycle overhead.
Remove the onMount block entirely and add a suppression comment:
- onMount(() => { - /* silences the not read error warning */ - disabledState; - }); - function isSingleStore() {Then add a comment on line 24:
let { rows, tableId, + // Bindable prop - written by reactive effects, consumed by parent disabledState = $bindable(true) }: {src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editPermissions.svelte (1)
26-29: Remove the onMount anti-pattern.Same issue as in
editRelated.svelte: usingonMountsolely to silence a compiler warning is an anti-pattern. ThearePermsDisabledprop is bindable and consumed by the parent via two-way binding, so it's not actually unused.Remove the onMount block and add a clarifying comment instead:
- onMount(() => { - /* silences the not read error warning */ - arePermsDisabled; - }); - export async function updatePermissions() {Add a comment on the prop declaration (line 17):
let { row = $bindable(null), + // Bindable prop - written by reactive effect, consumed by parent arePermsDisabled = $bindable(true) }: {src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/edit.svelte (1)
44-47: Remove the onMount anti-pattern.Same issue as the other components: using
onMountsolely to reference a bindable prop to silence warnings is an anti-pattern. Thedisabledprop is written by the reactive effect and consumed by the parent.Remove the onMount block:
- onMount(() => { - /* silences the not read error warning */ - disabled; - }); - function initWork() {Add a clarifying comment on the prop declaration (line 31):
let { row = $bindable(), rowId = $bindable(null), autoFocus = true, + // Bindable prop - written by reactive effect, consumed by parent disabled = $bindable(true) }: {src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte (1)
443-444: Verify consistent disabled state bindings across all editors.The bindings look correct, but ensure all child components properly implement the bindable prop contract:
EditRowexpectsbind:disabledEditRelatedRowexpectsbind:disabledStateEditRowPermissionsexpectsbind:arePermsDisabledNote the naming inconsistency:
disabledvsdisabledStatevsarePermsDisabled. While this works, it would be more maintainable if all three used the same prop name (e.g.,disabled).Consider standardizing the prop name across all three components for consistency:
// Instead of: bind:disabled={editRowDisabled} bind:disabledState={editRelatedRowDisabled} bind:arePermsDisabled={editRowPermissionsDisabled} // Use: bind:disabled={editRowDisabled} bind:disabled={editRelatedRowDisabled} bind:disabled={editRowPermissionsDisabled}This would require renaming
disabledState→disabledineditRelated.svelteandarePermsDisabled→disabledineditPermissions.svelte.Also applies to: 508-509, 519-520, 525-526, 551-552, 554-557
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte(5 hunks)src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/edit.svelte(2 hunks)src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editPermissions.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editRelated.svelte(2 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx,js,jsx,svelte}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx,svelte}: Import reusable modules from the src/lib directory using the $lib alias
Use minimal comments in code; reserve comments for TODOs or complex logic explanations
Use $lib, $routes, and $themes aliases instead of relative paths for module imports
Files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editRelated.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/edit.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editPermissions.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte
src/routes/**/*.svelte
📄 CodeRabbit inference engine (AGENTS.md)
Use SvelteKit file conventions: +page.svelte for components, +page.ts for data loaders, +layout.svelte for wrappers, +error.svelte for error handling, and dynamic route params in square brackets like [param]
Files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editRelated.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/edit.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editPermissions.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte
**/*.{ts,tsx,js,jsx,svelte,json}
📄 CodeRabbit inference engine (AGENTS.md)
Use 4 spaces for indentation, single quotes, 100 character line width, and no trailing commas per Prettier configuration
Files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editRelated.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/edit.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editPermissions.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte
**/*.svelte
📄 CodeRabbit inference engine (AGENTS.md)
Use Svelte 5 + SvelteKit 2 syntax with TypeScript for component development
Files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editRelated.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/edit.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editPermissions.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte
src/routes/**
📄 CodeRabbit inference engine (AGENTS.md)
Configure dynamic routes using SvelteKit convention with [param] syntax in route directory names
Files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editRelated.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/edit.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editPermissions.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte
🧠 Learnings (6)
📚 Learning: 2025-10-13T05:16:07.656Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2413
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/header.svelte:54-58
Timestamp: 2025-10-13T05:16:07.656Z
Learning: In SvelteKit apps, shared layout components (like headers) that use `$derived(page.data.*)` should use optional chaining when accessing properties that may not be present on all routes. During page transitions, reactive statements can briefly evaluate with different page.data structures, so optional chaining prevents runtime errors when navigating between routes with different data shapes (e.g., between `/databases` and `/databases/database-[database]`).
Applied to files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editRelated.svelte
📚 Learning: 2025-09-25T04:33:19.632Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2373
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/createTable.svelte:28-33
Timestamp: 2025-09-25T04:33:19.632Z
Learning: In the Appwrite console createTable component, manual submit state management (like setting creatingTable = true) is not needed because: 1) The Modal component handles submit state internally via submissionLoader, preventing double submissions, and 2) After successful table creation, the entire view is destroyed and replaced with the populated table view, ending the component lifecycle.
Applied to files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editRelated.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/edit.svelte
📚 Learning: 2025-09-25T04:21:57.071Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2373
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte:536-552
Timestamp: 2025-09-25T04:21:57.071Z
Learning: In the Appwrite console database suggestions flow, after successfully creating columns via `createColumns()`, the `await invalidate(Dependencies.TABLE)` call causes the view to be destroyed and another view (populated table view) to be rendered, automatically cleaning up component state without needing manual reset.
Applied to files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editRelated.svelte
📚 Learning: 2025-09-08T13:20:47.308Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2316
File: src/routes/(console)/project-[region]-[project]/functions/create-function/deploy/+page.svelte:29-29
Timestamp: 2025-09-08T13:20:47.308Z
Learning: The Form.svelte component in the Appwrite console creates a FormContext with isSubmitting as writable(false) and expects consumers to work with Svelte writable stores, not plain booleans.
Applied to files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editRelated.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/edit.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/editPermissions.svelte
📚 Learning: 2025-09-30T07:41:06.679Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2425
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte:454-468
Timestamp: 2025-09-30T07:41:06.679Z
Learning: In `src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte`, the column suggestions API (console.suggestColumns) has a maximum limit of 7 columns returned, which aligns with the initial placeholder count of 7 in customColumns.
Applied to files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte
📚 Learning: 2025-11-25T03:15:27.539Z
Learnt from: CR
Repo: appwrite/console PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T03:15:27.539Z
Learning: Applies to src/routes/**/*.svelte : Use SvelteKit file conventions: +page.svelte for components, +page.ts for data loaders, +layout.svelte for wrappers, +error.svelte for error handling, and dynamic route params in square brackets like [param]
Applied to files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: e2e
- GitHub Check: build
🔇 Additional comments (2)
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/edit.svelte (1)
168-175: LGTM - proper reactive disabled state management.The reactive effect correctly:
- Guards against missing data (work, row, table columns)
- Defaults to disabled when data is unavailable
- Compares all columns to determine if changes exist
This is the correct pattern for managing derived disabled state.
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte (1)
85-87: LGTM - proper disabled state coordination.The three disabled state flags correctly:
- Initialize to
true(safe default - buttons disabled until validation completes)- Are bound to child components via
$bindabletwo-way bindings- Control the corresponding submit button states
This establishes proper parent-child state coordination for the disabled state refactoring.

What does this PR do?
(Provide a description of what this PR does.)
Test Plan
(Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work.)
Related PRs and Issues
(If this PR is related to any other PR or resolves any issue or related to any issue link all related PR and issues here.)
Have you read the Contributing Guidelines on issues?
(Write your answer here.)
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.