Skip to content

Fix stale draft#591

Draft
okt-limonikas wants to merge 4 commits into
ts-factory:mainfrom
okt-limonikas:fix-stale-draft
Draft

Fix stale draft#591
okt-limonikas wants to merge 4 commits into
ts-factory:mainfrom
okt-limonikas:fix-stale-draft

Conversation

@okt-limonikas

Copy link
Copy Markdown
Collaborator

No description provided.

@okt-limonikas okt-limonikas self-assigned this Jun 19, 2026
The sidebar sometimes showed no configs even though configs existed.

`getListOfConfigs` forwarded only `project: projectIds?.[0]` to the
backend, so whenever a project filter was present in the URL the server
returned just that project's configs and dropped the global ones
(`per_conf`, `references`). The sidebar's `ConfigList` is already built
to group globals into the always-visible "No Project (Default)" group
and to filter project groups client-side, so the backend pre-filter was
starving that grouping and leaving the list empty.

Fetch the full list (the query already used `cache: 'no-cache'` +
`refetchOnMountOrArgChange`, so freshness is unaffected) and let
`ConfigList` group/filter by project on the client. The query arg is
dropped to `void` since project filtering no longer happens server-side.

Signed-off-by: Danil Kostromin <danil.kostromin@icloud.com>
The editor frequently displayed the MODIFIED badge on a config the user
had just opened or created without changing anything.

`isModified` was computed as
`JSON.stringify(formValues) !== JSON.stringify(defaultValues)`, which is
sensitive to object key order. The form's seeded values and the
server-derived `defaultValues` are constructed with different key orders
(`{name, description, is_active, content}` vs `{name, content,
description, is_active}`), so the two serialized differently even when
every value matched.

Replace the brittle stringify with a new `isConfigModified` helper that
compares the relevant fields individually (treating an undefined and an
empty description as equal). The badge now reflects only real
differences from the server config.

Signed-off-by: Danil Kostromin <danil.kostromin@icloud.com>
Editing a config, leaving the page and returning showed the old edited
content instead of the saved server data, and configs lingered in a
"modified" state.

The editor persists the form to sessionStorage so unsaved edits survive
navigation. That draft mechanism had three problems:

- The persist effect ran on every render, including mount, so simply
  opening a config planted a draft that shadowed fresh server data on
the
  next visit. It is now gated on the semantic "modified" check: a draft
is
  written only while the form differs from the server config and is
  removed again as soon as it matches.
- The draft was never cleared after a successful save/create, so it
  outlived the server update. The update form now clears the draft once
  the mutation succeeds (handleSubmit returns a success flag from the
  container), and the create form clears it on a successful create.
  clearSavedValue also removes the key synchronously, because callers
  clear right before the component unmounts (navigating to the new
  version) where react-use's write-on-render effect would never flush.
- Activating/deactivating a config keeps the same id (no remount) and
  flips is_active outside the form, which left the form out of sync and
  flagged it as modified. The form now syncs is_active when it changes
on
  the server, skipping the initial render so a saved draft is preserved.

Also drops the redundant beforeunload/unmount raw-editor writer from
useSavedState (the per-change effect already persists the latest value)
and removes two unused imports.

Signed-off-by: Danil Kostromin <danil.kostromin@icloud.com>
Quality cleanup of the draft-persistence fix, no behavior change:

- Key the persist effect on the serialized form string instead of the
  `form.watch()` object. The watched object has a new identity every
  render, so the effect (and its `sessionStorage` write/remove) ran on
  every render even while just viewing an unmodified config; it now runs
  only when the form actually changes.
- Replace the hand-rolled `prevIsActive` ref with the shared
  `usePrevious` hook from `@/shared/hooks`, which also removes the
  eslint-disable and the extra `useRef` import.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant