Skip to content

Commit 3fa4b4f

Browse files
committed
fix(url-state): review fixes — resolve custom-block deep links before opening detail, per-surface time-range fallback
- custom-blocks: gate the detail view on the resolved block (matching mcp/ access-control), so a dead or still-loading ?custom-block-id no longer flashes a bogus create screen - parseAsTimeRange: unknown tokens now parse to null so each surface's .withDefault applies (logs keeps 'All time'; audit-logs keeps 'Past 30 days' instead of silently widening to all time on a malformed link) - audit-logs: date-picker cancel target can never be 'Custom range' itself on a dateless custom deep link - refresh shared ?search= consumer lists in TSDoc
1 parent 26be826 commit 3fa4b4f

5 files changed

Lines changed: 19 additions & 10 deletions

File tree

apps/sim/app/workspace/[workspaceId]/logs/search-params.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ const TOKEN_TO_TIME_RANGE: Record<string, TimeRange> = Object.fromEntries(
4141
) as Record<string, TimeRange>
4242

4343
/**
44-
* Parser for the `timeRange` param. Serializes labels to kebab tokens and
45-
* tolerantly maps unknown tokens back to the default ("All time").
44+
* Parser for the `timeRange` param. Serializes labels to kebab tokens. Unknown
45+
* tokens parse to `null` so each consuming surface's `.withDefault(...)` decides
46+
* the fallback (logs: "All time"; audit-logs: "Past 30 days").
4647
*/
4748
export const parseAsTimeRange = createParser<TimeRange>({
4849
parse(value) {
49-
return TOKEN_TO_TIME_RANGE[value] ?? DEFAULT_TIME_RANGE
50+
return TOKEN_TO_TIME_RANGE[value] ?? null
5051
},
5152
serialize(value) {
5253
return TIME_RANGE_TO_TOKEN[value] ?? 'all-time'

apps/sim/app/workspace/[workspaceId]/settings/components/search-params.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import { parseAsString } from 'nuqs/server'
33
/**
44
* Shared URL query-param definition for the settings list search boxes
55
* (teammates, api-keys, copilot, custom-tools, mcp, secrets,
6-
* workflow-mcp-servers). Settings sections never co-render, so they all share
7-
* the `search` key without collisions.
6+
* workflow-mcp-servers, and the ee sections: audit-logs, access-control,
7+
* custom-blocks, data-drains, forks). Settings sections never co-render, so
8+
* they all share the `search` key without collisions.
89
*
910
* Consume via `useSettingsSearch` (`settings/components/use-settings-search`),
1011
* which owns the debounced-write wiring — the input is controlled directly by

apps/sim/app/workspace/[workspaceId]/settings/components/use-settings-search.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import { useDebouncedSearchSetter } from '@/hooks/use-debounced-search-setter'
99

1010
/**
1111
* The shared `?search=` binding for settings list search boxes (teammates,
12-
* api-keys, copilot, custom-tools, mcp, secrets, workflow-mcp-servers).
12+
* api-keys, copilot, custom-tools, mcp, secrets, workflow-mcp-servers, and the
13+
* ee sections: audit-logs, access-control, custom-blocks, data-drains, forks).
1314
* Composes `useDebouncedSearchSetter`, so it carries the canonical semantics:
1415
* the value updates instantly (drives the controlled input and the in-memory
1516
* filter), non-empty URL writes are debounced, and clearing (or a

apps/sim/ee/audit-logs/components/audit-logs.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,10 @@ export function AuditLogs({ organizationId }: AuditLogsProps) {
238238
const customStartDate = urlFilters.startDate ?? ''
239239
const customEndDate = urlFilters.endDate ?? ''
240240
const [datePickerOpen, setDatePickerOpen] = useState(false)
241-
const previousTimeRangeRef = useRef<TimeRange>(timeRange)
241+
/** Cancel target for the date picker — never 'Custom range' itself, so a deep link straight to an empty custom range still cancels back to a preset. */
242+
const previousTimeRangeRef = useRef<TimeRange>(
243+
timeRange === 'Custom range' ? 'Past 30 days' : timeRange
244+
)
242245
const dateRangeAppliedRef = useRef(false)
243246
const [searchTerm, setSearchTerm] = useSettingsSearch()
244247
const debouncedSearch = useDebounce(searchTerm, SEARCH_DEBOUNCE_MS).trim()

apps/sim/ee/custom-blocks/components/custom-blocks.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ export function CustomBlocks() {
6060
return blocks.filter((b) => b.name.toLowerCase().includes(q))
6161
}, [blocks, searchTerm])
6262

63+
/** Open the detail only once the deep-linked id resolves to a loaded block. */
64+
const selectedBlock = selectedBlockId ? blocks.find((b) => b.id === selectedBlockId) : undefined
65+
6366
if (isLoading) return null
6467

6568
if (!canManage) {
@@ -70,11 +73,11 @@ export function CustomBlocks() {
7073
)
7174
}
7275

73-
if ((isCreating || (selectedBlockId && canAdmin)) && workspaceId) {
76+
if ((isCreating || (selectedBlock && canAdmin)) && workspaceId) {
7477
return (
7578
<CustomBlockDetail
76-
key={isCreating ? 'new' : selectedBlockId}
77-
blockId={isCreating ? null : selectedBlockId}
79+
key={isCreating ? 'new' : selectedBlock?.id}
80+
blockId={isCreating ? null : (selectedBlock?.id ?? null)}
7881
workspaceId={workspaceId}
7982
onBack={() => {
8083
setIsCreating(false)

0 commit comments

Comments
 (0)