-
Notifications
You must be signed in to change notification settings - Fork 0
feat: epic pages and cards #102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,11 @@ | ||||||||||||||||||||||||||||||||||||
| <template> | ||||||||||||||||||||||||||||||||||||
| <div class="relative active:scale-90 duration-200 motion-preset-slide-left" @click="vibrate()"> | ||||||||||||||||||||||||||||||||||||
| <Section> | ||||||||||||||||||||||||||||||||||||
| <slot /> | ||||||||||||||||||||||||||||||||||||
| </Section> | ||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+2
to
+6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Make the clickable wrapper accessible (keyboard + ARIA). The root div is clickable but not keyboard-accessible. Add role/tabindex and handle Enter/Space. - <div class="relative active:scale-90 duration-200 motion-preset-slide-left" @click="vibrate()">
+ <div
+ role="button"
+ tabindex="0"
+ class="relative active:scale-90 duration-200 motion-preset-slide-left"
+ @click="vibrate()"
+ @keydown.enter.prevent="vibrate()"
+ @keydown.space.prevent="vibrate()"
+ >
<Section>
<slot />
</Section>
</div>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
| </template> | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| <script setup lang="ts"> | ||||||||||||||||||||||||||||||||||||
| const { vibrate } = useFeedback() | ||||||||||||||||||||||||||||||||||||
| </script> | ||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,38 @@ | ||||||||||||||||||||||||||||||
| <template> | ||||||||||||||||||||||||||||||
| <ActiveCard class="w-full flex flex-col gap-3.5"> | ||||||||||||||||||||||||||||||
| <UIcon name="i-lucide-crown" class="size-8 text-primary" /> | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| <h3 class="text-lg/5 font-bold"> | ||||||||||||||||||||||||||||||
| {{ epic.title }} | ||||||||||||||||||||||||||||||
| </h3> | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| <div class="w-full text-base/5 text-muted/50 whitespace-pre-wrap break-words line-clamp-3"> | ||||||||||||||||||||||||||||||
| {{ epic.description }} | ||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| <div class="flex justify-between items-center"> | ||||||||||||||||||||||||||||||
| <div class="flex flex-row gap-4"> | ||||||||||||||||||||||||||||||
| <div class="flex flex-row gap-1.5 items-center text-muted"> | ||||||||||||||||||||||||||||||
| <UIcon name="i-lucide-message-circle" class="size-5" /> | ||||||||||||||||||||||||||||||
| <p>{{ epic?.comments.length }}</p> | ||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| <time | ||||||||||||||||||||||||||||||
| :datetime="epic.createdAt" | ||||||||||||||||||||||||||||||
| class="text-sm text-muted" | ||||||||||||||||||||||||||||||
| v-text="format(new Date(epic.createdAt), 'от d MMMM yyyy', { locale: ru })" | ||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||
|
Comment on lines
+21
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Escape literal text in date-fns format string. 'o' is a token; without quotes you'll get incorrect output. Wrap "от" in quotes. - v-text="format(new Date(epic.createdAt), 'от d MMMM yyyy', { locale: ru })"
+ v-text="format(new Date(epic.createdAt), `'от' d MMMM yyyy`, { locale: ru })"📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||
| </ActiveCard> | ||||||||||||||||||||||||||||||
| </template> | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| <script setup lang="ts"> | ||||||||||||||||||||||||||||||
| import type { EpicWithData } from '~/stores/epic' | ||||||||||||||||||||||||||||||
| import { format } from 'date-fns' | ||||||||||||||||||||||||||||||
| import { ru } from 'date-fns/locale/ru' | ||||||||||||||||||||||||||||||
|
Comment on lines
+32
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix date-fns locale import (named import from locale/ru is invalid). Use the default export from 'date-fns/locale/ru' to avoid runtime undefined. -import { format } from 'date-fns'
-import { ru } from 'date-fns/locale/ru'
+import { format } from 'date-fns'
+import ru from 'date-fns/locale/ru'📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| defineProps<{ | ||||||||||||||||||||||||||||||
| epic: EpicWithData | ||||||||||||||||||||||||||||||
| }>() | ||||||||||||||||||||||||||||||
| </script> | ||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,106 @@ | ||||||||||
| <template> | ||||||||||
| <UDropdownMenu | ||||||||||
| :items="items" | ||||||||||
| :ui="{ | ||||||||||
| content: 'w-48', | ||||||||||
| }" | ||||||||||
| :content="{ | ||||||||||
| sideOffset: -12, | ||||||||||
| }" | ||||||||||
| > | ||||||||||
| <UButton | ||||||||||
| color="neutral" | ||||||||||
| variant="link" | ||||||||||
| active | ||||||||||
| :ui="{ | ||||||||||
| base: 'p-0', | ||||||||||
| }" | ||||||||||
| class="group/message relative text-left scroll-mt-4 motion-preset-slide-down-right" | ||||||||||
| > | ||||||||||
| <div class="min-w-[60%] relative flex items-start gap-2 pb-2 rtl:justify-end"> | ||||||||||
| <div class="inline-flex items-center justify-center min-h-6 mt-1.5"> | ||||||||||
| <UAvatar :src="user?.avatarUrl ?? undefined" /> | ||||||||||
| </div> | ||||||||||
|
|
||||||||||
| <div class="min-h-12 w-full bg-elevated/25 px-3.5 py-2 flex flex-col gap-2.5 rounded-lg ring ring-default"> | ||||||||||
| <div class="flex flex-col gap-1"> | ||||||||||
| <div v-if="comment?.createdAt" class="mt-1 flex justify-start text-xs text-dimmed"> | ||||||||||
| {{ format(new Date(comment.createdAt), 'dd MMMM в HH:mm', { locale: ru }) }} | ||||||||||
| </div> | ||||||||||
|
|
||||||||||
| <div class="text-sm/4 whitespace-break-spaces text-default text-pretty font-medium"> | ||||||||||
| {{ comment?.text }} | ||||||||||
| </div> | ||||||||||
| </div> | ||||||||||
|
|
||||||||||
| <div v-if="comment?.notifications?.length" class="flex flex-row flex-wrap gap-1"> | ||||||||||
| <UserBeacon | ||||||||||
| v-for="notification in comment.notifications" | ||||||||||
| :key="notification.id" | ||||||||||
| :notification="notification" | ||||||||||
| /> | ||||||||||
| </div> | ||||||||||
| </div> | ||||||||||
| </div> | ||||||||||
| </UButton> | ||||||||||
| </UDropdownMenu> | ||||||||||
| </template> | ||||||||||
|
|
||||||||||
| <script setup lang="ts"> | ||||||||||
| import type { DropdownMenuItem } from '@nuxt/ui' | ||||||||||
| import { ModalCreateEpicCommentBeacon } from '#components' | ||||||||||
| import { format } from 'date-fns' | ||||||||||
| import { ru } from 'date-fns/locale/ru' | ||||||||||
|
|
||||||||||
|
Comment on lines
+52
to
+54
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix date-fns locale import (named import from locale/ru is invalid). Same issue as in EpicCard.vue. -import { format } from 'date-fns'
-import { ru } from 'date-fns/locale/ru'
+import { format } from 'date-fns'
+import ru from 'date-fns/locale/ru'📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
| const { epicId, commentId } = defineProps<{ | ||||||||||
| epicId: string | ||||||||||
| commentId: string | ||||||||||
| }>() | ||||||||||
|
|
||||||||||
| const overlay = useOverlay() | ||||||||||
| const modalCreateEpicCommentBeacon = overlay.create(ModalCreateEpicCommentBeacon) | ||||||||||
|
|
||||||||||
| const epicStore = useEpicStore() | ||||||||||
| const userStore = useUserStore() | ||||||||||
|
|
||||||||||
| const epic = computed(() => epicStore.epics.find((epic) => epic.id === epicId)) | ||||||||||
| const comment = computed(() => epic.value?.comments.find((comment) => comment.id === commentId)) | ||||||||||
| const user = computed(() => userStore.find(comment.value?.userId ?? '')) | ||||||||||
|
|
||||||||||
| const items = computed<DropdownMenuItem[]>(() => { | ||||||||||
| const menuItems: DropdownMenuItem[] = [ | ||||||||||
| { | ||||||||||
| label: 'Маякнуть', | ||||||||||
| icon: 'i-lucide-users-round', | ||||||||||
| color: 'neutral', | ||||||||||
| disabled: false, | ||||||||||
| onSelect: () => modalCreateEpicCommentBeacon.open({ commentId }), | ||||||||||
| condition: true, | ||||||||||
| }, | ||||||||||
| { | ||||||||||
| label: 'Поставить лайк', | ||||||||||
| icon: 'i-lucide-thumbs-up', | ||||||||||
| color: 'neutral', | ||||||||||
| disabled: true, | ||||||||||
| onSelect: () => {}, | ||||||||||
| condition: user.value?.id !== userStore.id, | ||||||||||
| }, | ||||||||||
| { | ||||||||||
| label: 'Редактировать', | ||||||||||
| icon: 'i-lucide-edit', | ||||||||||
| disabled: true, | ||||||||||
| onSelect: () => {}, | ||||||||||
| condition: user.value?.id === userStore.id, | ||||||||||
| }, | ||||||||||
| { | ||||||||||
| label: 'Удалить', | ||||||||||
| icon: 'i-lucide-trash-2', | ||||||||||
| disabled: true, | ||||||||||
| onSelect: () => {}, | ||||||||||
| condition: user.value?.id === userStore.id, | ||||||||||
| }, | ||||||||||
| ] | ||||||||||
|
|
||||||||||
| return menuItems.filter((item) => item.condition) | ||||||||||
| }) | ||||||||||
| </script> | ||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,15 +11,15 @@ | |
| <div | ||
| class="relative py-1 w-full rounded-2xl flex flex-row items-center justify-center" | ||
| :class="[ | ||
| router.currentRoute.value.path === route.path && 'tg-bg-button tg-text-button motion-translate-y-in', | ||
| (route.exact ? router.currentRoute.value.path === route.path : router.currentRoute.value.path.startsWith(route.path)) && 'tg-bg-button tg-text-button motion-translate-y-in', | ||
| ]" | ||
|
Comment on lines
+14
to
15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Avoid over-highlighting routes when using startsWith.
- (route.exact ? router.currentRoute.value.path === route.path : router.currentRoute.value.path.startsWith(route.path)) && 'tg-bg-button tg-text-button motion-translate-y-in',
+ isActive(route) && 'tg-bg-button tg-text-button motion-translate-y-in',Add once in <script setup>: const isActive = (route: { path: string; exact?: boolean }) => {
const path = router.currentRoute.value.path
return route.exact ? path === route.path : (path === route.path || path.startsWith(route.path + '/'))
}🤖 Prompt for AI Agents |
||
| > | ||
| <UIcon :name="route.icon" class="size-6" /> | ||
| </div> | ||
| <p | ||
| class="text-xs font-medium" | ||
| :class="[ | ||
| router.currentRoute.value.path === route.path && 'tg-text', | ||
| (route.exact ? router.currentRoute.value.path === route.path : router.currentRoute.value.path.startsWith(route.path)) && 'tg-text', | ||
| ]" | ||
| > | ||
| {{ route.title }} | ||
|
|
@@ -41,6 +41,7 @@ const mainRoutes = computed(() => [ | |
| name: 'home', | ||
| title: t('app.home'), | ||
| icon: 'i-lucide-layout-dashboard', | ||
| exact: true, | ||
| }, | ||
| { | ||
| path: '/epic', | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| <template> | ||
| <div class="p-4 tg-bg-section group/section space-y-3.5 rounded-lg"> | ||
| <slot /> | ||
| </div> | ||
| </template> |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,71 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <template> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <UCard | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| variant="subtle" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| class="mt-auto bg-elevated/25" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <form | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| class="flex flex-col gap-4" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @submit.prevent="onCommentSubmit" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <UTextarea | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| v-model="text" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| color="neutral" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| variant="none" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| size="xl" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| autoresize | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| placeholder="Напишите свою мысль..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| :rows="3" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| :disabled="loading" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| class="w-full" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| :ui="{ base: 'p-1' }" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="flex items-center justify-end gap-2"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <UButton | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type="submit" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| color="secondary" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| size="md" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| :loading="loading" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| :disabled="!text" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| label="Добавить комментарий" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| icon="i-lucide-send" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| :ui="{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| base: 'px-3 rounded-full', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| label: 'font-medium', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+25
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Prevent whitespace-only submits and disable while loading; localize button label. Disabling on trimmed text avoids empty comments. <div class="flex items-center justify-end gap-2">
<UButton
type="submit"
color="secondary"
size="md"
:loading="loading"
- :disabled="!text"
- label="Добавить комментарий"
+ :disabled="!text?.trim() || loading"
+ :label="$t('epic.comment.add')"
icon="i-lucide-send"
:ui="{
base: 'px-3 rounded-full',
label: 'font-medium',
}"
/>
</div>📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </form> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </UCard> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </template> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <script setup lang="ts"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { epicId } = defineProps<{ epicId: string }>() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { vibrate } = useFeedback() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const epicStore = useEpicStore() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const text = ref('') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const loading = ref(false) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async function onCommentSubmit() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const trimmed = text.value.trim() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!trimmed) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| loading.value = true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await epicStore.addComment(epicId, trimmed) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| text.value = '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vibrate('success') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.error(e) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vibrate('error') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } finally { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| loading.value = false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </script> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| <template> | ||
| <UModal :title="$t('app.create.epic.title')"> | ||
| <template #body> | ||
| <FormCreateEpic @submitted="overlay.closeAll" @success="overlay.closeAll" /> | ||
| </template> | ||
| </UModal> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| const overlay = useOverlay() | ||
| </script> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| <template> | ||
| <UModal :title="$t('app.create.beacon.title')"> | ||
| <template #body> | ||
| <FormCreateEpicCommentBeacon | ||
| :comment-id="commentId" | ||
| @submitted="overlay.closeAll" | ||
| @success="overlay.closeAll" | ||
| /> | ||
| </template> | ||
| </UModal> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| defineProps<{ | ||
| commentId: string | ||
| }>() | ||
|
|
||
| const overlay = useOverlay() | ||
| </script> |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,19 @@ | ||||||||||||||||||||||||
| <template> | ||||||||||||||||||||||||
| <UModal :title="$t('app.update.epic.title')"> | ||||||||||||||||||||||||
| <template #body> | ||||||||||||||||||||||||
| <FormUpdateEpic | ||||||||||||||||||||||||
| :epic-id="epicId" | ||||||||||||||||||||||||
| @submitted="overlay.closeAll" | ||||||||||||||||||||||||
| @success="overlay.closeAll" | ||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||
| </template> | ||||||||||||||||||||||||
|
Comment on lines
+4
to
+9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Don’t close the modal on “submitted”; close only on success. Closing on submitted can hide failures and lose user input. <FormUpdateEpic
:epic-id="epicId"
- @submitted="overlay.closeAll"
- @success="overlay.closeAll"
+ @success="overlay.closeAll"
/>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
| </UModal> | ||||||||||||||||||||||||
| </template> | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| <script setup lang="ts"> | ||||||||||||||||||||||||
| defineProps<{ | ||||||||||||||||||||||||
| epicId: string | ||||||||||||||||||||||||
| }>() | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| const overlay = useOverlay() | ||||||||||||||||||||||||
| </script> | ||||||||||||||||||||||||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Harden periodic updates and avoid type pitfall for interval handle.
Apply:
Additionally (outside this hunk), change the declaration:
🏁 Script executed:
Length of output: 181
Harden periodic updates and use correct interval type
Replace
Promise.allwithPromise.allSettledin the interval callback so one failed update doesn’t cancel the others, and change the interval’s declaration fromNodeJS.Timeoutto the browser-compatibleReturnType<typeof setInterval>.And at line 69:
📝 Committable suggestion
🤖 Prompt for AI Agents