Skip to content
42 changes: 41 additions & 1 deletion apps/journeys-admin/src/components/JourneyList/JourneyList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,46 @@ export function JourneyList({
})
const { navbar, sidePanel } = usePageWrapperStyles()

useEffect(() => {
if (!router.isReady) return
const sortByFromQuery = router.query.sortBy as string
const sortByFromStorage =
typeof window !== 'undefined'
? localStorage.getItem('journeyListSortBy')
: null
const sortBy = sortByFromQuery || sortByFromStorage
if (sortBy && Object.values(SortOrder).includes(sortBy as SortOrder)) {
setSortOrder((prev) => (prev !== sortBy ? (sortBy as SortOrder) : prev))
if (sortByFromQuery && typeof window !== 'undefined') {
localStorage.setItem('journeyListSortBy', sortByFromQuery)
} else if (sortByFromStorage && !sortByFromQuery) {
void router.replace(
{ query: { ...router.query, sortBy: sortByFromStorage } },
undefined,
{ shallow: true }
)
}
}
}, [router.isReady, router.query.sortBy, router])
Comment on lines +45 to +65
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Validate the query param before it overrides stored sort.

sortByFromQuery can be a string[] or an invalid value. Because it’s used with ||, an invalid query string (or array) blocks a valid localStorage fallback, leaving sortOrder unset. Consider validating the query first, and only falling back to storage when the query is absent/invalid.

🛠️ Suggested fix
-    const sortByFromQuery = router.query.sortBy as string
+    const rawSortBy = router.query.sortBy
+    const sortByFromQuery = Array.isArray(rawSortBy) ? rawSortBy[0] : rawSortBy
     const sortByFromStorage =
       typeof window !== 'undefined'
         ? localStorage.getItem('journeyListSortBy')
         : null
-    const sortBy = sortByFromQuery || sortByFromStorage
-    if (sortBy && Object.values(SortOrder).includes(sortBy as SortOrder)) {
-      setSortOrder((prev) => (prev !== sortBy ? (sortBy as SortOrder) : prev))
+    const isValidSort = (value?: string | null): value is SortOrder =>
+      !!value && Object.values(SortOrder).includes(value as SortOrder)
+    const sortBy = isValidSort(sortByFromQuery)
+      ? sortByFromQuery
+      : isValidSort(sortByFromStorage)
+        ? sortByFromStorage
+        : undefined
+    if (sortBy) {
+      setSortOrder((prev) => (prev !== sortBy ? sortBy : prev))
       if (sortByFromQuery && typeof window !== 'undefined') {
         localStorage.setItem('journeyListSortBy', sortByFromQuery)
       } else if (sortByFromStorage && !sortByFromQuery) {
🤖 Prompt for AI Agents
In `@apps/journeys-admin/src/components/JourneyList/JourneyList.tsx` around lines
45 - 65, The current useEffect uses router.query.sortBy with "||" which allows
an invalid value or string[] to override localStorage; change the logic in the
useEffect to first validate router.query.sortBy is a single string and a member
of SortOrder before using it, otherwise fall back to the localStorage value from
localStorage.getItem('journeyListSortBy'); then call setSortOrder only with a
validated SortOrder value, and only write to localStorage or call router.replace
when the validated source (query or storage) is used; reference
router.query.sortBy, SortOrder, setSortOrder,
localStorage.getItem('journeyListSortBy'), and router.replace to locate and
update the logic.


const handleSetSortOrder = (
order: SortOrder | ((prev: SortOrder | undefined) => SortOrder | undefined)
) => {
const newOrder = typeof order === 'function' ? order(sortOrder) : order
if (newOrder) {
setSortOrder(newOrder)
if (router.isReady) {
void router.push(
{ query: { ...router.query, sortBy: newOrder } },
undefined,
{ shallow: true }
)
}
if (typeof window !== 'undefined')
localStorage.setItem('journeyListSortBy', newOrder)
}
}

useEffect(() => {
const handleRouteChange = (url: string) => {
// for updating journey list cache for shallow loading
Expand Down Expand Up @@ -112,7 +152,7 @@ export function JourneyList({
<JourneyListView
renderList={renderList}
setActiveEvent={handleClick}
setSortOrder={setSortOrder}
setSortOrder={handleSetSortOrder}
sortOrder={sortOrder}
/>
</Box>
Expand Down
Loading