Refining the speech-to-text conversion structure

This commit is contained in:
2026-09-22 11:02:08 +03:30
parent 17fb33b3e7
commit 4b335aa7ff
16 changed files with 634 additions and 333 deletions
+38 -49
View File
@@ -12,6 +12,7 @@ import {
} from '@/lib/jalali';
import {
UiButton,
UiDropdownMenu,
UiModal,
UiPageHeader,
UiPagination,
@@ -129,11 +130,6 @@ const filterLabel = computed(() => TABS.find((t) => t.key === filter.value)?.lab
const trulyEmpty = computed(() => !loading.value && counts.value.all === 0 && !q.value.trim());
const listEmpty = computed(() => !loading.value && !items.value.length);
function isLastItem(id: string) {
const rows = items.value;
return rows.length > 0 && rows[rows.length - 1]?.id === id;
}
function isOverdue(item: ActivityDto) {
if (item.status !== 'open' || !item.dueAt) return false;
return startOfLocalDay(new Date(item.dueAt)).getTime() < startOfLocalDay().getTime();
@@ -480,7 +476,6 @@ onMounted(() => {
v-for="item in items"
:key="item.id"
class="trow"
:class="{ 'menu-open': menuId === item.id }"
role="row"
>
<div class="title-cell">
@@ -516,29 +511,31 @@ onMounted(() => {
</span>
</div>
<div class="row-more" @click.stop>
<button
class="icon-more"
type="button"
aria-label="عملیات"
@click="menuId = menuId === item.id ? null : item.id"
<UiDropdownMenu
:open="menuId === item.id"
align="end"
@update:open="(v) => (menuId = v ? item.id : null)"
>
<UiIcon name="dots-v" :size="16" />
</button>
<div
v-if="menuId === item.id"
class="popover"
:class="{ 'drop-up': isLastItem(item.id) }"
>
<RouterLink :to="{ name: 'activity-detail', params: { id: item.id } }" @click="menuId = null">
<template #trigger="{ toggle }">
<button
class="icon-more"
type="button"
aria-label="عملیات"
@click.stop="toggle"
>
<UiIcon name="dots-v" :size="16" />
</button>
</template>
<RouterLink :to="{ name: 'activity-detail', params: { id: item.id } }">
مشاهده
</RouterLink>
<RouterLink :to="{ name: 'activity-edit', params: { id: item.id } }" @click="menuId = null">
<RouterLink :to="{ name: 'activity-edit', params: { id: item.id } }">
ویرایش
</RouterLink>
<button v-if="item.status === 'open'" type="button" @click="complete(item.id)">
انجام شد
</button>
</div>
</UiDropdownMenu>
</div>
</article>
</div>
@@ -565,31 +562,32 @@ onMounted(() => {
</p>
</div>
<div class="card-side">
<button
class="icon-more"
type="button"
aria-label="عملیات"
@click.stop="menuId = menuId === item.id ? null : item.id"
<UiDropdownMenu
:open="menuId === item.id"
align="end"
@update:open="(v) => (menuId = v ? item.id : null)"
>
<UiIcon name="dots-v" :size="16" />
</button>
<span class="type-ico" :class="item.type">
<UiIcon :name="typeIcon[item.type]" :size="18" />
</span>
<span class="type-pill" :class="item.type">{{ typeLabel[item.type] }}</span>
<div
v-if="menuId === item.id"
class="popover"
:class="{ 'drop-up': isLastItem(item.id) }"
@click.stop
>
<RouterLink :to="{ name: 'activity-detail', params: { id: item.id } }" @click="menuId = null">
<template #trigger="{ toggle }">
<button
class="icon-more"
type="button"
aria-label="عملیات"
@click.stop="toggle"
>
<UiIcon name="dots-v" :size="16" />
</button>
</template>
<RouterLink :to="{ name: 'activity-detail', params: { id: item.id } }">
مشاهده
</RouterLink>
<button v-if="item.status === 'open'" type="button" @click="complete(item.id)">
انجام شد
</button>
</div>
</UiDropdownMenu>
<span class="type-ico" :class="item.type">
<UiIcon :name="typeIcon[item.type]" :size="18" />
</span>
<span class="type-pill" :class="item.type">{{ typeLabel[item.type] }}</span>
</div>
</div>
<footer class="card-foot">
@@ -849,11 +847,6 @@ h1 {
z-index: 20;
}
.popover.drop-up {
top: auto;
bottom: calc(100% + 6px);
}
.popover a,
.popover button {
display: block;
@@ -968,10 +961,6 @@ h1 {
border-radius: 0 0 var(--radius) var(--radius);
}
.trow.menu-open {
z-index: 12;
}
.title-cell {
display: flex;
gap: 0.55rem;