-
Notifications
You must be signed in to change notification settings - Fork 2
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
Austenem/CAT-754 Refactor "My Lists" #3671
base: main
Are you sure you want to change the base?
Conversation
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.
I'm a little confused why we are continuing to use a store for the saved lists/entities. Maybe it would be helpful to have a chat between the three of us?
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.
Wow, a lot of changes here! I still need to check this out locally.
...s/components/detailPage/entityHeader/EntityHeaderActionButtons/EntityHeaderActionButtons.tsx
Outdated
Show resolved
Hide resolved
...s/components/detailPage/entityHeader/EntityHeaderActionButtons/EntityHeaderActionButtons.tsx
Outdated
Show resolved
Hide resolved
description: propDescription, | ||
creationLabel: propCreationLabel, | ||
creationDate: propCreationDate, |
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.
Why rename the variables with prop*?
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.
This was to avoid naming the final description/creation info variables in the function body like checkedDescription
- this way they get to keep their intended names (description
, etc) and there's a clear distinction between these and the optional prop variables.
.../static/js/components/detailPage/summary/SummarySaveEntityButton/SummarySaveEntityButton.tsx
Outdated
Show resolved
Hide resolved
context/app/static/js/components/savedLists/CreateListDialog/CreateListDialog.tsx
Outdated
Show resolved
Hide resolved
function useSavedEntityData(savedEntities: SavedEntities, source: string[]) { | ||
const query = useMemo( | ||
() => ({ | ||
query: getIDsQuery(Object.keys(savedEntities)), | ||
_source: source, | ||
size: Object.keys(savedEntities).length, |
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.
I would either bump this to 10000 when we are returning a source or set it to 0 for purely aggregations queries.
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.
Got it - is this just a performance concern?
context/app/static/js/components/savedLists/SavedListPanel/hooks.ts
Outdated
Show resolved
Hide resolved
context/app/static/js/components/savedLists/SavedListsContent/style.ts
Outdated
Show resolved
Hide resolved
404: listUUID ? `No list with UUID ${listUUID} found.` : 'No lists for the current user were found.', | ||
}, | ||
}), | ||
{ revalidateOnFocus: hasAccess, refreshInterval: 1000 * 60 }, |
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.
Do we need to refresh this on an interval or only once the user has performed some action which might affect what's returned?
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 refresh interval isn't needed - just removed. This was based on the workspaces fetcher function.
function sortEntities(searchHits: Required<SearchHit<Entity>>[], savedEntities: SavedEntities) { | ||
if (!searchHits) return []; | ||
|
||
return [...searchHits].sort((a, b) => { | ||
const entityA: SavedEntity = savedEntities[a._id] ?? { dateSaved: 0 }; | ||
const entityB: SavedEntity = savedEntities[b._id] ?? { dateSaved: 0 }; | ||
|
||
const dateA = entityA.dateSaved ?? 0; | ||
const dateB = entityB.dateSaved ?? 0; | ||
|
||
return dateB - dateA; | ||
}); | ||
} | ||
|
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.
Can we apply sort to the ES query?
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.
I don't know of a good way to do this in the query (apart from maybe passing in a custom comparator function for the sort) - the dateSaved property is only accessible by looking up the UUID in the savedEntities object, and not from any info returned by ES. What would you recommend?
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.
Great improvements! I will also need to test this locally 😄
context/app/static/js/components/detailPage/summary/SummarySaveEntityButton/index.ts
Outdated
Show resolved
Hide resolved
context/app/static/js/components/savedLists/SaveEntitiesButton/SaveEntitiesButton.tsx
Outdated
Show resolved
Hide resolved
handleSaveEntities({ entityUUIDs: uuids }).catch((error) => { | ||
console.error(error); | ||
}); |
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.
Would it be helpful to track errored attempts to save as well? @tsliaw
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.
I've put together a list of lists-related events to track that Tiffany and I will go over together - that will be a separate PR (CAT-1113). I don't believe based on the event tracking doc that we are currently tracking errors for most events, but that's definitely an option to consider.
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.
We don't typically track error states, so I don't see the need to track this one unless we expect this error to occur often.
context/app/static/js/components/savedLists/SavedListsDescription/SavedListsDescription.tsx
Outdated
Show resolved
Hide resolved
context/app/static/js/components/savedLists/SavedListsContent/style.ts
Outdated
Show resolved
Hide resolved
let tooltip = ''; | ||
|
||
if (disabled) { | ||
tooltip = allInSavedEntities ? `All ${entityLabel} are already saved.` : `Select ${entityTypes} to save.`; | ||
} else { | ||
tooltip = `Save ${entityLabel}.`; | ||
} |
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.
Maybe we can pull this out into a helper function instead to keep things more readable? e.g.
// Outside of the component
function createTooltip(entityLabel: string, allInSavedEntities: boolean, disabled: boolean) {
if (disabled) {
return `Save ${entityLabel}.`
}
if (allInSavedEntities) {
return `All ${entityLabel} are already saved.`
}
return `Select ${entityLabel}s to save.`
}
...
// Back inside the component
const tooltip = createTooltip(entityLabel, allInSavedEntities, disabled)
That would also let us add some unit tests if need be.
onClick={() => { | ||
trackSave({ action: 'Save To List', label: generateCommaList(Array.from(uuids)) }); | ||
handleSaveEntities({ entityUUIDs: uuids }).catch((error) => { | ||
console.error(error); | ||
}); | ||
}} |
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.
In my experience, useCallback
is necessary whenever passing event handler functions down, since it breaks memoization otherwise.
We could also use useEventCallback
from MUI (https://usehooks-ts.com/react-hook/use-event-callback - same hook, different library) which was designed to be easier to use than useCallback
and address issues like facebook/react#14099.
context/app/static/js/components/savedLists/SavedListPanel/hooks.ts
Outdated
Show resolved
Hide resolved
context/app/static/js/components/savedLists/SavedListPanel/hooks.ts
Outdated
Show resolved
Hide resolved
@austenem can you merge main into this branch so the virtualenvs are aligned between the branches? |
Summary
Broad update to the "My Lists" feature across the portal that leverages the new UKV API.
Major updates include:
Design Documentation/Original Tickets
CAT-754 Jira ticket
Testing
Tested using the following checklist:
Screenshots/Video
Updated Search page
![Screenshot 2025-01-21 at 6 11 22 PM](https://private-user-images.githubusercontent.com/84676120/405729936-c66bb9e4-aaf0-4ebe-bcd9-e63ca6a73e8f.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkyMzg5NzUsIm5iZiI6MTczOTIzODY3NSwicGF0aCI6Ii84NDY3NjEyMC80MDU3Mjk5MzYtYzY2YmI5ZTQtYWFmMC00ZWJlLWJjZDktZTYzY2E2YTczZThmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjExVDAxNTExNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWJiMjQ3MWRjYTBkYWNlODY5N2VlODZiYzg1M2VlMzU1OWU1ODNlZjY2MmZlOGU0ZjZjNjIxMmZiNDNmMzk1ZmEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.BHbpyY7UlkV4OmaljnBJXVNmx5dsh6eBklIkVNWcVLc)
Updated Collections dataset table
![Screenshot 2025-01-22 at 12 41 41 PM](https://private-user-images.githubusercontent.com/84676120/405729976-21b6e6b6-eb5b-4a26-be6f-4e25fd015187.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkyMzg5NzUsIm5iZiI6MTczOTIzODY3NSwicGF0aCI6Ii84NDY3NjEyMC80MDU3Mjk5NzYtMjFiNmU2YjYtZWI1Yi00YTI2LWJlNmYtNGUyNWZkMDE1MTg3LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjExVDAxNTExNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTBhZjVhYmIzMTYwNjYyOTdkNzNkNDQ5MGY3YzIxN2M2MTI5Njk5ZjI4OTQ3NzNlNTkwYzhhMGJjM2U5MDIwZTImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.6w2Q3ZgQ3rqh1Whw6JZvWL0VgqLrxoXHI3O5lzIHzbE)
Updated "My Lists" page for logged-out users
![Screenshot 2025-01-28 at 5 23 52 PM](https://private-user-images.githubusercontent.com/84676120/407524630-694b53d2-1826-44e3-9006-aa4c78b935e8.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkyMzg5NzUsIm5iZiI6MTczOTIzODY3NSwicGF0aCI6Ii84NDY3NjEyMC80MDc1MjQ2MzAtNjk0YjUzZDItMTgyNi00NGUzLTkwMDYtYWE0Yzc4YjkzNWU4LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjExVDAxNTExNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTBmMWE0NWQ0YzBmYzBjNTg1ODI5NjYyYjFiNWY3ZGZhNDQ3ZjllOTUzMWViYzViM2ZkMDQ3ZTI5MjEzNDZmODYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.F6DXXfHU56DGPxrC_jzEzCxex0n7KpdkceQ6U-iOI7I)
Example of banner shown after transfer of local lists to a user's profile
![Screenshot 2025-01-28 at 12 40 19 PM](https://private-user-images.githubusercontent.com/84676120/407525034-98a9e700-00a9-4f04-969c-9a066007243c.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkyMzg5NzUsIm5iZiI6MTczOTIzODY3NSwicGF0aCI6Ii84NDY3NjEyMC80MDc1MjUwMzQtOThhOWU3MDAtMDBhOS00ZjA0LTk2OWMtOWEwNjYwMDcyNDNjLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjExVDAxNTExNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTY0Y2I0NTY5YzA4YjQyMWI0MDVmODU0MzJiNTQyOWE3NWFkZTgzYzFhYzM3MGI0ZDM3ZjVjYWIxZWYxNGRlMjUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.nPn59kiGIutEEZ7JuwW4enNe_UwICM1C9l6YgDNhn64)
Checklist
CHANGELOG-your-feature-name-here.md
is present in the root directory, describing the change(s) in full sentences.