OpenFn / OpenFn/lightning

Template browser wipes your search when the channel arrives

Open
#5,030 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Elixir
Stars
296
Forks
86
Avg merge
1d 13h
Merged PRs (30d)
50

Description

Depends on #4848

User story

As someone browsing templates on a new workflow, I don't want what I've typed
into the search box to disappear on its own.

Details

One effect in TemplateBrowserModalWrapper.tsx:40-84 does two jobs. Its body
clears search, templates and loading before it checks whether it can fetch:

useEffect(() => {
  if (!isOpen) return;
  setTemplateSearchQuery('');
  setTemplates(BASE_TEMPLATES);
  setTemplatesLoading(false);
  if (!channel) return;
  // ...fetch
}, [isOpen, channel, setTemplateSearchQuery, setTemplatesLoading, setTemplates]);

channel is provider?.channel (:30), undefined until the collaboration
provider attaches. It's also in the dependency array. So the effect runs twice —
once on open with no channel, again when the channel arrives — and the second run
clears what you typed in between.

The window is real: LandingScreenWrapper renders as a sibling after
</LoadingBoundary> (CollaborativeEditor.tsx:299-308), so the landing cards
are clickable from first paint, before the session connects.

The reset itself is needed. Panel state lives in the global UI store and no
longer resets on unmount, so each open has to start clean — the comment at
:42-45 says so. The bug is that one effect owns both the reset and the fetch,
so the reset inherits the fetch's dependency.

One correction to the review. It blames a socket reconnect. A Phoenix rejoin
reuses the same Channel object, so its identity is stable and the effect
doesn't re-run. The trigger is the initial undefined → Channel transition.

How to see it

The natural window is short, so widen it:

  1. In CollaborativeEditor.tsx, temporarily delay the provider — or throttle to
    Slow 3G in devtools before loading.
  2. Load /w/new.
  3. Click Browse templates as soon as the card paints.
  4. Type into the search box.
  5. When the connection lands, the box empties and the list resets to
    BASE_TEMPLATES.
Implementation notes

Split the effect. isOpen drives the reset, channel drives the fetch.

// Reset on open only
useEffect(() => {
  if (!isOpen) return;
  setTemplateSearchQuery('');
  setTemplates(BASE_TEMPLATES);
  setTemplatesLoading(false);
}, [isOpen, setTemplateSearchQuery, setTemplates, setTemplatesLoading]);

// Fetch once a channel exists
useEffect(() => {
  if (!isOpen || !channel) return;
  let cancelled = false;
  // ...existing load(), unchanged
  return () => { cancelled = true; };
}, [isOpen, channel, setTemplates, setTemplatesLoading]);

Keep the cancelled guard as-is; it protects a different race
(close-before-resolve, then reopen).

Consider doing this inside the wider template-state cleanup rather than
alone.
The state was moved into createUIStore for a single consumer, and the
manual reset only exists because of that move. Three separate reviews have landed
on the same conclusion. In the same slice: an unmemoized base/user split and
search filter, a per-keystroke write to a global store with ~13 subscribers where
the deleted TemplateSearchInput debounced at 300ms, and cols derived from the
unfiltered length.

Blocking question for that larger version, not for this fix: list_templates
(workflow_channel.ex:591) is unscoped and instance-wide. Publishing is gated to
user.support_user, so a global curated library may well be the intent — but the
query enforces no boundary and nothing says so.

Release notes

Fixed a bug where the template browser could clear your search while it was still
connecting.

User acceptance criteria
  • With the delay above in place: open Browse templates, type a search, wait for
    the connection — the text and the filtered results survive.
  • Closing and reopening still starts clean: empty search, base templates, no
    stranded spinner.
  • A failed fetch still shows the alert and clears loading.
  • A test simulates the undefined → Channel transition with a non-empty search
    and fails against current code.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in TemplateBrowserModalWrapper.tsx:40-84 and inspect how channel is obtained at :30; review CollaborativeEditor.tsx:299-308 to understand the connection timing. Reproduce the undefined-to-Channel transition with a delayed provider, then add a test covering a non-empty search. Done means the search and filtered results survive connection, while closing and reopening still resets state and failed fetches clear loading.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend, testing-qa
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
84/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.