list options
Gitea Actions / Deploy (push) Successful in 39s

This commit is contained in:
vadim committed 2026-10-14 11:19:21 +03:00
1 parent 66a6400cda
commit a0c557f9b2
3 files changed
+36 -12

No files matched your search

+8 -8
View File
@@ -1,24 +1,23 @@
<script setup lang="ts">
const options = [
{ id: 1, title: 'Title' },
{ id: 2, title: 'Content' },
{ id: 3, title: 'Status' },
]
const select = (value: unknown) => {}
import { ISSUE_LIST_FIELDS, useIssueListOptions } from '@/composables/useIssueListOptions.ts'
const visible = useIssueListOptions()
</script>
<template>
<div>
<v-menu width="15rem" :close-on-content-click="false">
<template v-slot:activator="{ props }">
<v-btn density="compact" icon="mdi-dots-horizontal" v-bind="props" />
</template>
<v-list border select-strategy="single-leaf" density="compact" @update:selected="select">
<v-list-item rounded="0" class="py-0" slim v-for="el in options" :key="el.id">
<v-list border density="compact">
<v-list-item rounded="0" class="py-0" slim v-for="el in ISSUE_LIST_FIELDS" :key="el.alias">
<v-list-item-title>
<div class="menu-grid px-1">
<div>{{ el.title }}</div>
<v-switch
v-model="visible[el.alias]"
inset="material"
size="x-small"
color="success"
@@ -31,6 +30,7 @@ const select = (value: unknown) => {}
</v-list-item>
</v-list>
</v-menu>
</div>
</template>
<style scoped lang="scss">
+7 -4
View File
@@ -4,6 +4,7 @@ import StatusMenu from '@/components/StatusMenu.vue'
import { useIssueStore } from '@/stores/issue.ts'
import type { Issue } from '@/api/issue.api.ts'
import AssigneeMenu from '@/components/AssigneeMenu.vue'
import { useIssueListOptions } from '@/composables/useIssueListOptions.ts'
interface Props {
issue: Issue
@@ -19,6 +20,7 @@ const emit = defineEmits<{
}>()
const issueStore = useIssueStore()
const visible = useIssueListOptions()
const onStatusChanged = async (status: Issue['status']) => {
const updated = await issueStore.update(issue.id, { status })
@@ -47,10 +49,11 @@ const onAssigneeChanged = async (assignee: string) => {
icon="mdi-alert-box"
color="error"
/>
<div class="flex-shrink-0" :class="{ 'text-decoration-line-through': issue.status === 'DONE' }">
<div v-if="visible.title" class="flex-shrink-0" :class="{ 'text-decoration-line-through': issue.status === 'DONE' }">
{{ issue.title }}
</div>
<div
v-if="visible.content"
:class="{ 'text-decoration-line-through': issue.status === 'DONE' }"
class="text-body-medium text-truncate min-w-0"
:title="issue.content"
@@ -74,9 +77,9 @@ const onAssigneeChanged = async (assignee: string) => {
<template #append>
<div class="d-flex ga-4 align-center">
<status-menu :value="issue.status" @changed="onStatusChanged" />
<priority-menu :value="issue.priority" @changed="onPriorityChanged" />
<assignee-menu :value="issue.assignee" @changed="onAssigneeChanged" />
<status-menu v-if="visible.status" :value="issue.status" @changed="onStatusChanged" />
<priority-menu v-if="visible.priority" :value="issue.priority" @changed="onPriorityChanged" />
<assignee-menu v-if="visible.assignee" :value="issue.assignee" @changed="onAssigneeChanged" />
</div>
</template>
</v-list-item>
+21
View File
@@ -0,0 +1,21 @@
import { createGlobalState, useLocalStorage } from '@vueuse/core'
export const ISSUE_LIST_FIELDS = [
{ title: 'Title', alias: 'title' },
{ title: 'Content', alias: 'content' },
{ title: 'Status', alias: 'status' },
{ title: 'Priority', alias: 'priority' },
{ title: 'Assignee', alias: 'assignee' },
] as const
export type IssueListField = (typeof ISSUE_LIST_FIELDS)[number]['alias']
/** Persisted visibility of the issue list element fields, shared by every list element. */
export const useIssueListOptions = createGlobalState(() =>
useLocalStorage<Record<IssueListField, boolean>>(
'issue-list:visible-fields',
{ title: true, content: true, status: true, priority: true, assignee: true },
// Fields added later stay visible for users who already have saved options
{ mergeDefaults: true },
),
)