fix(views): edit views with filters
This change fixes a bug where filter values of views would be transformed in the wrong order, not transformed at all or at the wrong time. Transforming the filters now happens transparently in the background without anything funky happening visible to the user.
This commit is contained in:
parent
244ca262df
commit
68d233684f
@ -35,6 +35,11 @@ const {
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'blur'])
|
||||
|
||||
const userService = new UserService()
|
||||
const projectUserService = new ProjectUserService()
|
||||
const labelStore = useLabelStore()
|
||||
const projectStore = useProjectStore()
|
||||
|
||||
const filterQuery = ref<string>('')
|
||||
const {
|
||||
textarea: filterInput,
|
||||
@ -60,9 +65,6 @@ watch(
|
||||
},
|
||||
)
|
||||
|
||||
const userService = new UserService()
|
||||
const projectUserService = new ProjectUserService()
|
||||
|
||||
function escapeHtml(unsafe: string): string {
|
||||
return unsafe
|
||||
.replace(/&/g, '&')
|
||||
@ -196,8 +198,6 @@ const autocompleteMatchText = ref('')
|
||||
const autocompleteResultType = ref<'labels' | 'assignees' | 'projects' | null>(null)
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const autocompleteResults = ref<any[]>([])
|
||||
const labelStore = useLabelStore()
|
||||
const projectStore = useProjectStore()
|
||||
|
||||
function handleFieldInput() {
|
||||
const cursorPosition = filterInput.value.selectionStart
|
||||
|
@ -2,28 +2,29 @@
|
||||
import type {IProjectView} from '@/modelTypes/IProjectView'
|
||||
import XButton from '@/components/input/button.vue'
|
||||
import FilterInput from '@/components/project/partials/FilterInput.vue'
|
||||
import {ref, watch} from 'vue'
|
||||
import {ref, onBeforeMount} from 'vue'
|
||||
import {transformFilterStringForApi, transformFilterStringFromApi} from '@/helpers/filters'
|
||||
import {useLabelStore} from '@/stores/labels'
|
||||
import {useProjectStore} from '@/stores/projects'
|
||||
|
||||
const {
|
||||
modelValue,
|
||||
loading = false,
|
||||
showSaveButtons = false,
|
||||
} = defineProps<{
|
||||
modelValue: IProjectView,
|
||||
loading?: bool,
|
||||
showSaveButtons?: bool,
|
||||
}>()
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const emit = defineEmits(['update:modelValue', 'cancel'])
|
||||
|
||||
const view = ref<IProjectView>()
|
||||
|
||||
const labelStore = useLabelStore()
|
||||
const projectStore = useProjectStore()
|
||||
|
||||
watch(
|
||||
() => modelValue,
|
||||
newValue => {
|
||||
|
||||
onBeforeMount(() => {
|
||||
const transform = filterString => transformFilterStringFromApi(
|
||||
filterString,
|
||||
labelId => labelStore.getLabelById(labelId)?.title,
|
||||
@ -31,9 +32,9 @@ watch(
|
||||
)
|
||||
|
||||
const transformed = {
|
||||
...newValue,
|
||||
filter: transform(newValue.filter),
|
||||
bucketConfiguration: newValue.bucketConfiguration.map(bc => ({
|
||||
...modelValue,
|
||||
filter: transform(modelValue.filter),
|
||||
bucketConfiguration: modelValue.bucketConfiguration.map(bc => ({
|
||||
title: bc.title,
|
||||
filter: transform(bc.filter),
|
||||
})),
|
||||
@ -42,37 +43,45 @@ watch(
|
||||
if (JSON.stringify(view.value) !== JSON.stringify(transformed)) {
|
||||
view.value = transformed
|
||||
}
|
||||
},
|
||||
{immediate: true, deep: true},
|
||||
)
|
||||
})
|
||||
|
||||
watch(
|
||||
() => view.value,
|
||||
newView => {
|
||||
emit('update:modelValue', {
|
||||
...newView,
|
||||
filter: transformFilterStringForApi(
|
||||
newView.filter,
|
||||
function save() {
|
||||
const transformFilter = filterQuery => transformFilterStringForApi(
|
||||
filterQuery,
|
||||
labelTitle => labelStore.filterLabelsByQuery([], labelTitle)[0]?.id || null,
|
||||
projectTitle => {
|
||||
const found = projectStore.findProjectByExactname(projectTitle)
|
||||
return found?.id || null
|
||||
},
|
||||
),
|
||||
})
|
||||
},
|
||||
{deep: true},
|
||||
)
|
||||
|
||||
emit('update:modelValue', {
|
||||
...view.value,
|
||||
filter: transformFilter(view.value?.filter),
|
||||
bucketConfiguration: view.value?.bucketConfiguration.map(bc => ({
|
||||
title: bc.title,
|
||||
filter: transformFilter(bc.filter),
|
||||
})),
|
||||
})
|
||||
}
|
||||
|
||||
const titleValid = ref(true)
|
||||
|
||||
function validateTitle() {
|
||||
titleValid.value = view.value?.title !== ''
|
||||
}
|
||||
|
||||
function handleBubbleSave() {
|
||||
if (showSaveButtons) {
|
||||
return
|
||||
}
|
||||
|
||||
save()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<form>
|
||||
<form @focusout="handleBubbleSave">
|
||||
<div class="field">
|
||||
<label
|
||||
class="label"
|
||||
@ -130,6 +139,7 @@ function validateTitle() {
|
||||
|
||||
<FilterInput
|
||||
v-model="view.filter"
|
||||
:project-id="view.projectId"
|
||||
:input-label="$t('project.views.filter')"
|
||||
/>
|
||||
|
||||
@ -199,6 +209,7 @@ function validateTitle() {
|
||||
|
||||
<FilterInput
|
||||
v-model="view.bucketConfiguration[index].filter"
|
||||
:project-id="view.projectId"
|
||||
:input-label="$t('project.views.filter')"
|
||||
/>
|
||||
</div>
|
||||
@ -214,6 +225,24 @@ function validateTitle() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="showSaveButtons"
|
||||
class="is-flex is-justify-content-end"
|
||||
>
|
||||
<XButton
|
||||
variant="tertiary"
|
||||
class="mr-2"
|
||||
@click="emit('cancel')"
|
||||
>
|
||||
{{ $t('misc.cancel') }}
|
||||
</XButton>
|
||||
<XButton
|
||||
:loading="loading"
|
||||
@click="save"
|
||||
>
|
||||
{{ $t('misc.save') }}
|
||||
</XButton>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
|
@ -111,6 +111,7 @@ async function saveView() {
|
||||
>
|
||||
<XButton
|
||||
:loading="projectViewService.loading"
|
||||
:disabled="showCreateForm && newView.title === ''"
|
||||
@click="createView"
|
||||
>
|
||||
{{ $t('project.views.create') }}
|
||||
@ -144,22 +145,11 @@ async function saveView() {
|
||||
<ViewEditForm
|
||||
v-model="viewToEdit"
|
||||
class="mb-4"
|
||||
/>
|
||||
<div class="is-flex is-justify-content-end">
|
||||
<XButton
|
||||
variant="tertiary"
|
||||
class="mr-2"
|
||||
@click="viewToEdit = null"
|
||||
>
|
||||
{{ $t('misc.cancel') }}
|
||||
</XButton>
|
||||
<XButton
|
||||
:loading="projectViewService.loading"
|
||||
@click="saveView"
|
||||
>
|
||||
{{ $t('misc.save') }}
|
||||
</XButton>
|
||||
</div>
|
||||
:show-save-buttons="true"
|
||||
@cancel="viewToEdit = null"
|
||||
@update:modelValue="saveView"
|
||||
/>
|
||||
</td>
|
||||
</template>
|
||||
<template v-else>
|
||||
|
Loading…
x
Reference in New Issue
Block a user