fix: multiple fixes all accross the SPA, missing buttons actions, styling etc.
This commit is contained in:
1 parent
ad55137883
commit
d4fcfb2bba
11 files changed
+262
-43
No files matched your search
@@ -34,6 +34,7 @@ const showSkeleton = ref(false)
|
||||
const article = ref<Article | null>(null)
|
||||
const previewOn = ref(false)
|
||||
const detailsOpen = ref(false)
|
||||
const publishPending = ref<string | undefined>(undefined)
|
||||
let skeletonTimer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
function clearSkeletonTimer() {
|
||||
@@ -111,6 +112,99 @@ function goBack() {
|
||||
router.push('/article')
|
||||
}
|
||||
|
||||
async function setOnline(makeOnline: boolean) {
|
||||
if (!article.value) {
|
||||
return
|
||||
}
|
||||
publishPending.value = makeOnline ? 'Publishing…' : 'Unpublishing…'
|
||||
try {
|
||||
const updated = await request<Article>(
|
||||
`/v1/article/${articleId}/${makeOnline ? 'publish' : 'unpublish'}`,
|
||||
{ method: 'PATCH' },
|
||||
)
|
||||
article.value = updated
|
||||
toast.add({
|
||||
id: `article-${makeOnline ? 'published' : 'unpublished'}-${articleId}`,
|
||||
color: 'success',
|
||||
icon: 'i-lucide-circle-check',
|
||||
title: makeOnline ? 'Article published' : 'Article unpublished',
|
||||
description: makeOnline
|
||||
? `"${updated.title}" is now online.`
|
||||
: `"${updated.title}" is now offline.`,
|
||||
})
|
||||
} catch (err) {
|
||||
if (err instanceof ApiError && err.status === 404) {
|
||||
loadState.value = 'notFound'
|
||||
return
|
||||
}
|
||||
toast.add({
|
||||
id: `article-${makeOnline ? 'publish' : 'unpublish'}-failed-${articleId}`,
|
||||
color: 'error',
|
||||
icon: 'i-lucide-circle-x',
|
||||
title: makeOnline ? "Couldn't publish" : "Couldn't unpublish",
|
||||
description: "The server didn't respond. Nothing changed.",
|
||||
duration: 0,
|
||||
actions: [{ label: 'Retry', onClick: () => setOnline(makeOnline) }],
|
||||
})
|
||||
} finally {
|
||||
publishPending.value = undefined
|
||||
}
|
||||
}
|
||||
|
||||
function handlePublish() {
|
||||
setOnline(true)
|
||||
}
|
||||
|
||||
function handleUnpublish() {
|
||||
setOnline(false)
|
||||
}
|
||||
|
||||
function deleteDescription() {
|
||||
const count = article.value?.images.length ?? 0
|
||||
const imagesPhrase =
|
||||
count === 0 ? '' : count === 1 ? ' and its image' : ` and its ${count} images`
|
||||
return `"${article.value?.title ?? ''}"${imagesPhrase} will be deleted. This can't be undone.`
|
||||
}
|
||||
|
||||
async function performDelete() {
|
||||
try {
|
||||
await request(`/v1/article/${articleId}`, { method: 'DELETE' })
|
||||
toast.add({
|
||||
id: `article-deleted-${articleId}`,
|
||||
color: 'success',
|
||||
icon: 'i-lucide-circle-check',
|
||||
title: 'Article deleted',
|
||||
description: `"${article.value?.title ?? ''}" and its images are gone.`,
|
||||
})
|
||||
router.push('/article')
|
||||
} catch (err) {
|
||||
if (err instanceof ApiError && err.status === 404) {
|
||||
loadState.value = 'notFound'
|
||||
return
|
||||
}
|
||||
throw new Error("Couldn't delete the article, so it's still there. Try again in a moment.")
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDelete() {
|
||||
if (!article.value) {
|
||||
return
|
||||
}
|
||||
await overlay
|
||||
.create(ConfirmDialog, {
|
||||
props: {
|
||||
title: 'Delete this article?',
|
||||
description: deleteDescription(),
|
||||
confirmLabel: 'Delete article',
|
||||
cancelLabel: 'Cancel',
|
||||
pendingLabel: 'Deleting…',
|
||||
tone: 'danger',
|
||||
action: performDelete,
|
||||
},
|
||||
})
|
||||
.open()
|
||||
}
|
||||
|
||||
function onKeydown(event: KeyboardEvent) {
|
||||
if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 's') {
|
||||
event.preventDefault()
|
||||
@@ -254,7 +348,7 @@ onBeforeRouteLeave(async () => {
|
||||
root: 'items-center gap-2',
|
||||
container: 'h-auto',
|
||||
base: 'h-4.5 w-8 p-0.5',
|
||||
thumb: 'size-3.5 bg-default data-[state=checked]:translate-x-3.5',
|
||||
thumb: 'size-3.5 bg-default data-[state=checked]:translate-x-2.5',
|
||||
wrapper: 'ms-0',
|
||||
label: 'text-sm font-normal text-toned',
|
||||
}"
|
||||
@@ -274,15 +368,20 @@ onBeforeRouteLeave(async () => {
|
||||
class="h-8 gap-1.5 px-3"
|
||||
:online="article.is_online"
|
||||
:dirty="draft.state.value === 'dirty'"
|
||||
:pending="publishPending"
|
||||
:disabled="publishDisabled"
|
||||
@publish="handlePublish"
|
||||
@unpublish="handleUnpublish"
|
||||
/>
|
||||
<UButton
|
||||
icon="i-lucide-ellipsis"
|
||||
color="neutral"
|
||||
icon="i-lucide-trash-2"
|
||||
color="error"
|
||||
variant="ghost"
|
||||
class="size-8 justify-center text-toned"
|
||||
aria-label="More actions"
|
||||
/>
|
||||
class="h-8 gap-1.5 px-3"
|
||||
@click="handleDelete"
|
||||
>
|
||||
Delete
|
||||
</UButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -357,7 +456,10 @@ onBeforeRouteLeave(async () => {
|
||||
hide-icon
|
||||
:online="article.is_online"
|
||||
:dirty="draft.state.value === 'dirty'"
|
||||
:pending="publishPending"
|
||||
:disabled="publishDisabled"
|
||||
@publish="handlePublish"
|
||||
@unpublish="handleUnpublish"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user