74 lines
2.2 KiB
Vue
74 lines
2.2 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
import { useIssueTypeStore } from '@/stores/issue-type.ts'
|
|
import type { Issue } from '@/api/issue.api.ts'
|
|
|
|
interface Props {
|
|
value?: string
|
|
compact?: boolean
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), { compact: true })
|
|
const emit = defineEmits<{ changed: [value: Issue['type']] }>()
|
|
|
|
const issueTypeStore = useIssueTypeStore()
|
|
|
|
const icons: Record<string, string> = {
|
|
BUG: 'mdi-bug-outline',
|
|
TASK: 'mdi-checkbox-outline',
|
|
FEATURE: 'mdi-bookmark-outline',
|
|
}
|
|
const defaultIcon = 'mdi-star-outline'
|
|
|
|
const iconOf = (alias?: string) => (alias && icons[alias]) || defaultIcon
|
|
|
|
const current = computed(() => issueTypeStore.issueTypes?.find((el) => el.alias === props.value))
|
|
const currentIcon = computed(() => iconOf(props.value))
|
|
const currentColor = computed(() => current.value?.color ?? 'primary')
|
|
const currentName = computed(() => current.value?.name ?? props.value ?? '')
|
|
|
|
const availableTypes = computed(() => issueTypeStore.issueTypes?.filter((el) => el.alias !== props.value))
|
|
|
|
const select = (value: unknown) => {
|
|
if (Array.isArray(value)) {
|
|
emit('changed', value[0])
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<v-menu>
|
|
<template v-slot:activator="{ props: activatorProps }">
|
|
<v-btn
|
|
v-if="props.compact"
|
|
density="compact"
|
|
:icon="currentIcon"
|
|
:color="currentColor"
|
|
:title="currentName"
|
|
variant="text"
|
|
v-bind="activatorProps"
|
|
/>
|
|
|
|
<v-btn v-else density="comfortable" slim v-bind="activatorProps">
|
|
<div class="d-flex align-center ga-2">
|
|
<v-icon :color="currentColor" :icon="currentIcon" />
|
|
<span>{{ currentName }}</span>
|
|
</div>
|
|
</v-btn>
|
|
</template>
|
|
|
|
<v-list border class="mt-1" select-strategy="single-leaf" density="compact" @update:selected="select">
|
|
<v-list-item v-for="el in availableTypes" :key="el.alias" :value="el.alias">
|
|
<div class="d-flex justify-start align-center ga-1">
|
|
<v-icon size="small" :icon="iconOf(el.alias)" :color="el.color" />
|
|
<div>{{ el.name }}</div>
|
|
</div>
|
|
</v-list-item>
|
|
</v-list>
|
|
</v-menu>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped lang="scss"></style>
|