Skip to content

Commit 57f7f2d

Browse files
fix(changelog): keep notes open on a failed save, reject out-of-range cursors
1 parent f185e8a commit 57f7f2d

3 files changed

Lines changed: 18 additions & 6 deletions

File tree

‎apps/sim/app/workspace/[workspaceId]/changelog/changelog.tsx‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,13 @@ function ChangelogContent({ workspaceId }: ChangelogProps) {
5454
) : (
5555
<div
5656
ref={setScrollElement}
57-
className={cn('@container/changelog min-h-0 flex-1 overflow-y-auto', scrollFadeClass)}
57+
className={cn(
58+
'@container/changelog min-h-0 flex-1 overflow-y-auto py-10',
59+
scrollFadeClass
60+
)}
5861
{...scrollFadeAttributes(edges)}
5962
>
60-
<div className='mx-auto flex max-w-[960px] flex-col gap-12 px-8 py-10'>
63+
<div className='mx-auto flex max-w-[960px] flex-col gap-12 px-8'>
6164
{releases.map((release) => (
6265
<ReleaseEntry
6366
key={release.id}

‎apps/sim/app/workspace/[workspaceId]/changelog/components/release-entry/release-entry.tsx‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const DATE_FORMAT = new Intl.DateTimeFormat('en-US', { month: 'short', day: 'num
3131
/** One shipped release: the date and version rail, then its title, body, and change lines. */
3232
export function ReleaseEntry({ workspaceId, release, canEdit, onEditDetails }: ReleaseEntryProps) {
3333
const saveRef = useRef<(() => Promise<void>) | null>(null)
34+
const saveFailedRef = useRef(false)
3435
const [editingBody, setEditingBody] = useState(false)
3536
const [savingBody, setSavingBody] = useState(false)
3637
const file = useAddressedWorkspaceFileRecord(workspaceId, release.fileId)
@@ -60,14 +61,17 @@ export function ReleaseEntry({ workspaceId, release, canEdit, onEditDetails }: R
6061
disabled={savingBody}
6162
onClick={async () => {
6263
setSavingBody(true)
64+
saveFailedRef.current = false
6365
try {
6466
await saveRef.current?.()
65-
setEditingBody(false)
6667
} catch (error) {
67-
toast.error(getErrorMessage(error, 'Failed to save notes'))
68+
if (!saveFailedRef.current)
69+
toast.error(getErrorMessage(error, 'Failed to save notes'))
70+
saveFailedRef.current = true
6871
} finally {
6972
setSavingBody(false)
7073
}
74+
if (!saveFailedRef.current) setEditingBody(false)
7175
}}
7276
>
7377
{savingBody ? 'Saving...' : 'Done'}
@@ -106,6 +110,10 @@ export function ReleaseEntry({ workspaceId, release, canEdit, onEditDetails }: R
106110
canEdit={editingBody}
107111
readOnly={!editingBody}
108112
saveRef={saveRef}
113+
onSaveError={(error) => {
114+
saveFailedRef.current = true
115+
toast.error(getErrorMessage(error, 'Failed to save notes'))
116+
}}
109117
/>
110118
</div>
111119
) : null}

‎apps/sim/lib/changelog/application/changelog.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,10 @@ function decodeCursor(cursor: string): ReleaseCursor {
119119
const separator = cursor.indexOf(':')
120120
const millis = Number(cursor.slice(0, separator))
121121
const id = cursor.slice(separator + 1)
122-
if (separator < 1 || !Number.isSafeInteger(millis) || id.length === 0)
122+
const publishedAt = new Date(millis)
123+
if (separator < 1 || Number.isNaN(publishedAt.getTime()) || id.length === 0)
123124
throw new OrchestrationError('validation', 'cursor must be the nextCursor from a list')
124-
return { publishedAt: new Date(millis), id }
125+
return { publishedAt, id }
125126
}
126127

127128
async function assertChangesInWorkspace(

0 commit comments

Comments
 (0)