1
0

feat: improve label store

(cherry picked from commit 2a6ba7e7f0162bb050575908e7ca80f4b0292398)
This commit is contained in:
Dominik Pschenitschni 2024-07-17 19:08:47 +02:00 committed by kolaente
parent d707e1576a
commit a0e3efe2d1
No known key found for this signature in database
GPG Key ID: F40E70337AB24C9B
2 changed files with 40 additions and 34 deletions

View File

@ -1,4 +1,4 @@
import {computed, ref} from 'vue' import {computed, readonly, ref} from 'vue'
import {acceptHMRUpdate, defineStore} from 'pinia' import {acceptHMRUpdate, defineStore} from 'pinia'
import LabelService from '@/services/label' import LabelService from '@/services/label'
@ -21,23 +21,28 @@ async function getAllLabels(page = 1): Promise<ILabel[]> {
} }
} }
export interface LabelState {
[id: ILabel['id']]: ILabel
}
export const useLabelStore = defineStore('label', () => { export const useLabelStore = defineStore('label', () => {
// The labels are stored as an object which has the label ids as keys. const labels = ref<{ [id: ILabel['id']]: ILabel }>({})
const labels = ref<LabelState>({})
const isLoading = ref(false)
const getLabelsByIds = computed(() => { // Alphabetically sort the labels
return (ids: ILabel['id'][]) => Object.values(labels.value).filter(({id}) => ids.includes(id)) const labelsArray = computed(() => Object.values(labels.value)
}) .sort((a, b) => a.title.localeCompare(
b.title, i18n.global.locale.value,
{ ignorePunctuation: true },
)),
)
const isLoading = ref(false)
const getLabelById = computed(() => { const getLabelById = computed(() => {
return (labelId: ILabel['id']) => Object.values(labels.value).find(({id}) => id === labelId) return (labelId: ILabel['id']) => labels.value[labelId]
}) })
const getLabelsByIds = computed(() => (ids: ILabel['id'][]) =>
ids.map(id => labels.value[id]).filter(Boolean),
)
// ** // **
// * Checks if a project of labels is available in the store and filters them then query // * Checks if a project of labels is available in the store and filters them then query
// ** // **
@ -53,14 +58,12 @@ export const useLabelStore = defineStore('label', () => {
}) })
const getLabelsByExactTitles = computed(() => { const getLabelsByExactTitles = computed(() => {
return (labelTitles: string[]) => Object return (labelTitles: string[]) => labelsArray.value
.values(labels.value)
.filter(({title}) => labelTitles.some(l => l.toLowerCase() === title.toLowerCase())) .filter(({title}) => labelTitles.some(l => l.toLowerCase() === title.toLowerCase()))
}) })
const getLabelByExactTitle = computed(() => { const getLabelByExactTitle = computed(() => {
return (labelTitle: string) => Object return (labelTitle: string) => labelsArray.value
.values(labels.value)
.find(l => l.title.toLowerCase() === labelTitle.toLowerCase()) .find(l => l.title.toLowerCase() === labelTitle.toLowerCase())
}) })
@ -144,11 +147,12 @@ export const useLabelStore = defineStore('label', () => {
} }
return { return {
labels, labels: readonly(labels),
labelsArray: readonly(labelsArray),
isLoading, isLoading,
getLabelsByIds,
getLabelById, getLabelById,
getLabelsByIds,
filterLabelsByQuery, filterLabelsByQuery,
getLabelsByExactTitles, getLabelsByExactTitles,
getLabelByExactTitle, getLabelByExactTitle,

View File

@ -13,7 +13,7 @@
<div class="content"> <div class="content">
<h1>{{ $t('label.manage') }}</h1> <h1>{{ $t('label.manage') }}</h1>
<p v-if="Object.entries(labels).length > 0"> <p v-if="labelStore.labelsArray.length > 0">
{{ $t('label.description') }} {{ $t('label.description') }}
</p> </p>
<p <p
@ -30,29 +30,29 @@
<div class="columns"> <div class="columns">
<div class="labels-list column"> <div class="labels-list column">
<span <span
v-for="l in labels" v-for="label in labelStore.labelsArray"
:key="l.id" :key="label.id"
:class="{'disabled': userInfo.id !== l.createdBy.id}" :class="{'disabled': userInfo.id !== label.createdBy.id}"
:style="{'background': l.hexColor, 'color': l.textColor}" :style="{'background': label.hexColor, 'color': label.textColor}"
class="tag" class="tag"
> >
<span <span
v-if="userInfo.id !== l.createdBy.id" v-if="userInfo.id !== label.createdBy.id"
v-tooltip.bottom="$t('label.edit.forbidden')" v-tooltip.bottom="$t('label.edit.forbidden')"
> >
{{ l.title }} {{ label.title }}
</span> </span>
<BaseButton <BaseButton
v-else v-else
:style="{'color': l.textColor}" :style="{'color': label.textColor}"
@click="editLabel(l)" @click="editLabel(label)"
> >
{{ l.title }} {{ label.title }}
</BaseButton> </BaseButton>
<BaseButton <BaseButton
v-if="userInfo.id === l.createdBy.id" v-if="userInfo.id === label.createdBy.id"
class="delete is-small" class="delete is-small"
@click="showDeleteDialoge(l)" @click="showDeleteDialoge(label)"
/> />
</span> </span>
</div> </div>
@ -155,7 +155,7 @@ const labelEditLabel = ref<ILabel>(new LabelModel())
const isLabelEdit = ref(false) const isLabelEdit = ref(false)
const editorActive = ref(false) const editorActive = ref(false)
const showDeleteModal = ref(false) const showDeleteModal = ref(false)
const labelToDelete = ref<ILabel>(null) const labelToDelete = ref<ILabel | undefined>(undefined)
useTitle(() => t('label.title')) useTitle(() => t('label.title'))
@ -165,11 +165,13 @@ const userInfo = computed(() => authStore.info)
const labelStore = useLabelStore() const labelStore = useLabelStore()
labelStore.loadAllLabels() labelStore.loadAllLabels()
// Alphabetically sort the labels
const labels = computed(() => Object.values(labelStore.labels).sort((f, s) => f.title > s.title ? 1 : -1))
const loading = computed(() => labelStore.isLoading) const loading = computed(() => labelStore.isLoading)
function deleteLabel(label: ILabel) { function deleteLabel(label?: ILabel) {
if (!label) {
return
}
showDeleteModal.value = false showDeleteModal.value = false
isLabelEdit.value = false isLabelEdit.value = false
return labelStore.deleteLabel(label) return labelStore.deleteLabel(label)