-
Notifications
You must be signed in to change notification settings - Fork 12
Add isLoading checking for the Example field in Create Listing Modal #4250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -47,8 +47,12 @@ export default class CreateListingModal extends Component<Signature> { | |||||
|
|
||||||
| @tracked private selectedExamples: PickerOption[] = []; | ||||||
|
|
||||||
| private instancesSearch = getSearch<CardDef>(this, getOwner(this)!, () => | ||||||
| this.codeRef ? { filter: { type: this.codeRef } } : undefined, | ||||||
| private instancesSearch = getSearch<CardDef>( | ||||||
| this, | ||||||
| getOwner(this)!, | ||||||
| () => (this.codeRef ? { filter: { type: this.codeRef } } : undefined), | ||||||
| () => (this.payload?.targetRealm ? [this.payload.targetRealm] : undefined), | ||||||
| { isLive: true }, | ||||||
|
||||||
| { isLive: true }, | |
| { isLive: false }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still need to remove this right
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The .length part
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add loading checking and also the instance length check else the fieldcontainer will still display if the search result is empty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{{#if this.instanceOptions.length}} =. showExampleRow
Copilot
AI
Mar 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Examples picker is now hidden while instancesSearch.isLoading, but the modal’s Create button remains enabled. If the user clicks Create before the search finishes, selectedExampleURLs can resolve to an empty list (because instances/instanceOptions haven’t populated yet), resulting in a listing created without the user’s intended examples. Consider disabling Create while instancesSearch.isLoading and/or having selectedExampleURLs fall back to payload.openCardIds when options haven’t loaded yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make sense ,agree with this
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -591,6 +591,135 @@ module(`Integration | search resource`, function (hooks) { | |
| ); | ||
| }); | ||
|
|
||
| test(`setting query to undefined clears cached state and re-runs search on next query`, async function (assert) { | ||
| let query: Query | undefined = { | ||
| filter: { | ||
| on: { | ||
| module: `${testRealmURL}book`, | ||
| name: 'Book', | ||
| }, | ||
| eq: { | ||
| 'author.lastName': 'Abdel-Rahman', | ||
| }, | ||
| }, | ||
| }; | ||
| let args = { | ||
| query, | ||
| realms: [testRealmURL], | ||
| isLive: false, | ||
| isAutoSaved: false, | ||
| storeService, | ||
| owner: this.owner, | ||
| } satisfies SearchResourceArgs['named']; | ||
|
|
||
| let search = getSearchResourceForTest(loaderService, () => ({ | ||
| named: args, | ||
| })); | ||
| await search.loaded; | ||
| assert.strictEqual( | ||
| search.instances.length, | ||
| 2, | ||
| 'initial search returns 2 books', | ||
| ); | ||
|
|
||
| // Simulate modal close: set query to undefined | ||
| args = { ...args, query: undefined }; | ||
| search.modify([], args); | ||
|
Comment on lines
+625
to
+627
|
||
| await settled(); | ||
|
|
||
| // Simulate modal reopen with same query | ||
| args = { ...args, query }; | ||
| search.modify([], args); | ||
| await search.loaded; | ||
|
|
||
| assert.strictEqual( | ||
| search.instances.length, | ||
| 2, | ||
| 'search re-runs after query was set to undefined and back', | ||
| ); | ||
| }); | ||
|
lucaslyl marked this conversation as resolved.
|
||
|
|
||
| test(`setting query to undefined tears down live subscriptions`, async function (assert) { | ||
| let query: Query | undefined = { | ||
| filter: { | ||
| on: { | ||
| module: `${testRealmURL}book`, | ||
| name: 'Book', | ||
| }, | ||
| eq: { | ||
| 'author.lastName': 'Abdel-Rahman', | ||
| }, | ||
| }, | ||
| }; | ||
| let args = { | ||
| query, | ||
| realms: [testRealmURL], | ||
| isLive: true, | ||
| isAutoSaved: false, | ||
| storeService, | ||
| owner: this.owner, | ||
| } satisfies SearchResourceArgs['named']; | ||
|
|
||
| let search = getSearchResourceForTest(loaderService, () => ({ | ||
| named: args, | ||
| })); | ||
| await search.loaded; | ||
| assert.strictEqual( | ||
| search.instances.length, | ||
| 2, | ||
| 'initial live search returns 2 books', | ||
| ); | ||
|
|
||
| // Simulate modal close: set query to undefined | ||
| args = { ...args, query: undefined }; | ||
| search.modify([], args); | ||
| await settled(); | ||
|
|
||
| // Write a new matching card while "modal is closed" | ||
| await realm.write( | ||
| 'books/4.json', | ||
| JSON.stringify({ | ||
| data: { | ||
| type: 'card', | ||
| attributes: { | ||
| author: { | ||
| firstName: 'New', | ||
| lastName: 'Abdel-Rahman', | ||
| }, | ||
| editions: 0, | ||
| pubDate: '2024-01-01', | ||
| }, | ||
| meta: { | ||
| adoptsFrom: { | ||
| module: `${testRealmURL}book`, | ||
| name: 'Book', | ||
| }, | ||
| }, | ||
| }, | ||
| } as LooseSingleCardDocument), | ||
| ); | ||
|
|
||
| await settled(); | ||
|
|
||
| // Instances should NOT have updated since subscriptions were torn down | ||
| assert.strictEqual( | ||
| search.instances.length, | ||
| 2, | ||
| 'live subscription was torn down — no update while query is undefined', | ||
| ); | ||
|
|
||
| // Simulate modal reopen: restore query | ||
| args = { ...args, query }; | ||
| search.modify([], args); | ||
| await search.loaded; | ||
|
|
||
| assert.strictEqual( | ||
| search.instances.length, | ||
| 3, | ||
| 'fresh search on reopen picks up the new card', | ||
| ); | ||
| }); | ||
|
|
||
| test(`can search for file-meta instances using SearchResource`, async function (assert) { | ||
| let query: Query = { | ||
| filter: { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting
isLive: truehere introduces a persistent background subscription after the modal is dismissed.CreateListingModalis always mounted (operator-mode/container.gtsrenders it unconditionally), and when the payload is clearedcodeRefbecomes undefined; inSearchResource.modify()(packages/host/app/resources/search.ts) that path returns early onquery === undefinedwithout unsubscribing existing live subscriptions or clearing#previousQuery. As a result, later realm index events can continue triggeringsearch.perform(...)for the stale query even while the modal is closed, causing unnecessary live refresh traffic/work until the whole component is destroyed.Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good comment for leaking abstraction
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so one observastion Ed noted way back when we did the card resources refactor is that "isLive" is kind of a lie. when you have a store that is driving your state, everything is always live. in fact you actually have to go thru weird acrobatics to make things not live. perhaps this is the same.