fix(newsfeed): load saved content when reopening the edit modal

Sync modal editor state from the updated feed on open, clear editFeed
on reset, and remount TextEditor so a second edit shows the latest HTML
instead of stale content.
This commit is contained in:
Rotimi Best
2026-06-11 20:32:39 +01:00
parent bbd243d214
commit 89e44d4fab
6 changed files with 116 additions and 31 deletions
@@ -51,12 +51,9 @@
let isDeleteFeedModal = $state(false); let isDeleteFeedModal = $state(false);
const openEditFeed = () => { const openEditFeed = () => {
newsfeedApi.openNewFeedModal();
edit = true;
if (edit === true) {
editFeed = feed; editFeed = feed;
} edit = true;
newsfeedApi.openNewFeedModal();
}; };
const handleReact = (reactionType: string) => addNewReaction(reactionType, feed.id, author.id); const handleReact = (reactionType: string) => addNewReaction(reactionType, feed.id, author.id);
@@ -21,7 +21,18 @@
newPost: '' newPost: ''
}); });
let newPost = $state(edit === true ? editFeed?.content : ''); let newPost = $state('');
$effect(() => {
if (!newsfeedApi.isNewFeedModalOpen) {
newPost = '';
return;
}
if (edit && editFeed) {
newPost = editFeed.content || '';
}
});
const onPost = async () => { const onPost = async () => {
isLoading = true; isLoading = true;
@@ -31,9 +42,7 @@
await newsfeedApi.update(courseId, editFeed.id, { content: newPost ?? '' }); await newsfeedApi.update(courseId, editFeed.id, { content: newPost ?? '' });
if (newsfeedApi.success) { if (newsfeedApi.success) {
edit = false; resetEditor();
newPost = '';
newsfeedApi.closeNewFeedModal();
} }
} else { } else {
await newsfeedApi.create(courseId, { await newsfeedApi.create(courseId, {
@@ -59,6 +68,7 @@
const resetEditor = () => { const resetEditor = () => {
newPost = ''; newPost = '';
edit = false; edit = false;
editFeed = null;
newsfeedApi.closeNewFeedModal(); newsfeedApi.closeNewFeedModal();
}; };
</script> </script>
@@ -81,14 +91,16 @@
</Dialog.Title> </Dialog.Title>
</Dialog.Header> </Dialog.Header>
<section class="max-w-lg"> <section class="max-w-lg">
{#key edit ? editFeed?.id : 'new'}
<TextEditor <TextEditor
content={newPost || editFeed?.content || ''} content={newPost}
onChange={(text) => { onChange={(text) => {
newPost = text; newPost = text;
}} }}
editorClass="max-h-[400px]" editorClass="max-h-[400px]"
placeholder={$t('course.navItem.news_feed.heading_button.placeholder')} placeholder={$t('course.navItem.news_feed.heading_button.placeholder')}
/> />
{/key}
{#if errors.newPost} {#if errors.newPost}
<p class="text-sm text-red-500">{errors.newPost}</p> <p class="text-sm text-red-500">{errors.newPost}</p>
{/if} {/if}
@@ -20,13 +20,13 @@
let newPost = $state(''); let newPost = $state('');
$effect(() => { $effect(() => {
if (edit && editFeed) { if (!programNewsfeedApi.isNewFeedModalOpen) {
newPost = editFeed.content || ''; newPost = '';
return; return;
} }
if (!programNewsfeedApi.isNewFeedModalOpen) { if (edit && editFeed) {
newPost = ''; newPost = editFeed.content || '';
} }
}); });
@@ -84,14 +84,16 @@
</Dialog.Title> </Dialog.Title>
</Dialog.Header> </Dialog.Header>
<section class="max-w-lg"> <section class="max-w-lg">
{#key edit ? editFeed?.id : 'new'}
<TextEditor <TextEditor
content={newPost || editFeed?.content || ''} content={newPost}
onChange={(text) => { onChange={(text) => {
newPost = text; newPost = text;
}} }}
editorClass="max-h-[400px]" editorClass="max-h-[400px]"
placeholder={$t('programs.newsfeed.editor_placeholder')} placeholder={$t('programs.newsfeed.editor_placeholder')}
/> />
{/key}
</section> </section>
<Dialog.Footer> <Dialog.Footer>
<Button variant="outline" onclick={resetEditor}> <Button variant="outline" onclick={resetEditor}>
+1 -1
View File
@@ -8,4 +8,4 @@ pre-commit:
run: pnpm format:check run: pnpm format:check
fail_text: | fail_text: |
❌ Prettier formatting check failed! ❌ Prettier formatting check failed!
Please run 'pnpm format' to fix formatting issues and try again. Please run 'pnpm format:changed' or 'pnpm format' to fix formatting issues and try again.
+2 -1
View File
@@ -9,7 +9,8 @@
"clean": "turbo clean && find . -name 'node_modules' -type d -prune -exec rm -rf '{}' +", "clean": "turbo clean && find . -name 'node_modules' -type d -prune -exec rm -rf '{}' +",
"clean:pnpm": "pnpm clean && pnpm store prune", "clean:pnpm": "pnpm clean && pnpm store prune",
"format": "turbo run format", "format": "turbo run format",
"format:check": "git diff --name-only -z --diff-filter=d HEAD~1 | xargs -0 -I{} sh -c '[ ! -L \"{}\" ] && printf \"%s\\0\" \"{}\"' | xargs -0 prettier --check --ignore-unknown", "format:changed": "node scripts/format-changed.mjs --write",
"format:check": "node scripts/format-changed.mjs --staged --check",
"postinstall": "test -d .git && lefthook install || true", "postinstall": "test -d .git && lefthook install || true",
"release": "standard-version", "release": "standard-version",
"db:reset": "pnpm --filter @cio/db db:reset", "db:reset": "pnpm --filter @cio/db db:reset",
+73
View File
@@ -0,0 +1,73 @@
import { lstatSync } from 'node:fs';
import { spawnSync } from 'node:child_process';
const prettierMode = process.argv.includes('--check') ? '--check' : '--write';
const stagedOnly = process.argv.includes('--staged');
function runGitCommand(args) {
const result = spawnSync('git', args, {
cwd: process.cwd(),
encoding: 'utf8'
});
if (result.status !== 0) {
const errorOutput = result.stderr || result.stdout || `git ${args.join(' ')} failed`;
throw new Error(errorOutput.trim());
}
return result.stdout;
}
function getChangedFiles() {
const commands = stagedOnly
? [['diff', '--name-only', '-z', '--cached', '--diff-filter=ACMR']]
: [
['diff', '--name-only', '-z', '--diff-filter=d'],
['diff', '--name-only', '-z', '--cached', '--diff-filter=d'],
['ls-files', '--others', '--exclude-standard', '-z']
];
const filePaths = new Set();
for (const args of commands) {
const output = runGitCommand(args);
const paths = output.split('\0').filter(Boolean);
for (const filePath of paths) {
filePaths.add(filePath);
}
}
return [...filePaths].filter((filePath) => {
try {
return !lstatSync(filePath).isSymbolicLink();
} catch {
return false;
}
});
}
function runPrettier(filePaths) {
const chunkSize = 200;
for (let index = 0; index < filePaths.length; index += chunkSize) {
const chunk = filePaths.slice(index, index + chunkSize);
const result = spawnSync('prettier', [prettierMode, '--ignore-unknown', ...chunk], {
cwd: process.cwd(),
stdio: 'inherit'
});
if (result.status !== 0) {
process.exit(result.status ?? 1);
}
}
}
const changedFiles = getChangedFiles();
if (changedFiles.length === 0) {
console.log('No changed files to format.');
process.exit(0);
}
runPrettier(changedFiles);