mirror of
https://github.com/directus/directus.git
synced 2026-04-03 03:00:39 -04:00
Update bookmark editing flow
This commit is contained in:
@@ -9,26 +9,40 @@ export function usePreset(collection: Ref<string>, bookmark: Ref<number | null>
|
||||
const presetsStore = usePresetsStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const saving = ref(false);
|
||||
|
||||
const { info: collectionInfo } = useCollection(collection);
|
||||
|
||||
const bookmarkExists = computed(() => {
|
||||
if (!bookmark.value) return false;
|
||||
|
||||
return !!presetsStore.state.collectionPresets.find((preset) => preset.id === bookmark.value);
|
||||
});
|
||||
|
||||
const localPreset = ref<Partial<Preset>>({});
|
||||
initLocalPreset();
|
||||
|
||||
const bookmarkSaved = computed(() => localPreset.value.$saved !== false);
|
||||
const bookmarkIsMine = computed(() => localPreset.value.user === userStore.state.currentUser!.id);
|
||||
|
||||
const savePreset = async (preset?: Partial<Preset>) => {
|
||||
saving.value = true;
|
||||
const updatedValues = await presetsStore.savePreset(preset ? preset : localPreset.value);
|
||||
initLocalPreset();
|
||||
localPreset.value.id = updatedValues.id;
|
||||
saving.value = false;
|
||||
return updatedValues;
|
||||
};
|
||||
|
||||
const saveLocal = async () => {
|
||||
presetsStore.saveLocal(localPreset.value);
|
||||
initLocalPreset();
|
||||
};
|
||||
|
||||
const autoSave = debounce(async () => {
|
||||
if (!bookmark || bookmark.value === null) {
|
||||
savePreset();
|
||||
} else {
|
||||
saveLocal();
|
||||
}
|
||||
}, 450);
|
||||
|
||||
@@ -143,6 +157,9 @@ export function usePreset(collection: Ref<string>, bookmark: Ref<number | null>
|
||||
saveCurrentAsBookmark,
|
||||
title,
|
||||
resetPreset,
|
||||
bookmarkSaved,
|
||||
bookmarkIsMine,
|
||||
saving,
|
||||
};
|
||||
|
||||
async function resetPreset() {
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import { computed, Ref } from '@vue/composition-api';
|
||||
import { clone } from 'lodash';
|
||||
|
||||
export default function useSync<T, K extends keyof T>(
|
||||
props: T,
|
||||
key: K,
|
||||
|
||||
emit: (event: string, ...args: any[]) => void
|
||||
): Ref<Readonly<T[K]>> {
|
||||
return computed<T[K]>({
|
||||
get() {
|
||||
return clone(props[key]);
|
||||
return props[key];
|
||||
},
|
||||
set(newVal) {
|
||||
emit(`update:${key}`, newVal);
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent, PropType, ref, computed, inject, toRefs, Ref } from '@vue/composition-api';
|
||||
import { defineComponent, PropType, ref, computed, inject, toRefs, Ref, watch } from '@vue/composition-api';
|
||||
|
||||
import { HeaderRaw, Item } from '@/components/v-table/types';
|
||||
import { Field, Filter } from '@/types';
|
||||
@@ -389,6 +389,13 @@ export default defineComponent({
|
||||
|
||||
const localWidths = ref<{ [field: string]: number }>({});
|
||||
|
||||
watch(
|
||||
() => _viewOptions.value,
|
||||
() => {
|
||||
localWidths.value = {};
|
||||
}
|
||||
);
|
||||
|
||||
const saveWidthsToViewOptions = debounce(() => {
|
||||
_viewOptions.value = {
|
||||
...(_viewOptions.value || {}),
|
||||
|
||||
@@ -13,30 +13,38 @@
|
||||
</template>
|
||||
|
||||
<template #title-outer:append>
|
||||
<bookmark-add
|
||||
v-if="!bookmark"
|
||||
class="bookmark-add"
|
||||
v-model="bookmarkDialogActive"
|
||||
@save="createBookmark"
|
||||
:saving="creatingBookmark"
|
||||
>
|
||||
<template #activator="{ on }">
|
||||
<v-icon class="toggle" name="bookmark_outline" @click="on" />
|
||||
</template>
|
||||
</bookmark-add>
|
||||
<div class="bookmark-controls">
|
||||
<bookmark-add
|
||||
v-if="!bookmark"
|
||||
class="add"
|
||||
v-model="bookmarkDialogActive"
|
||||
@save="createBookmark"
|
||||
:saving="creatingBookmark"
|
||||
>
|
||||
<template #activator="{ on }">
|
||||
<v-icon class="toggle" name="bookmark_outline" @click="on" />
|
||||
</template>
|
||||
</bookmark-add>
|
||||
|
||||
<bookmark-edit
|
||||
v-else
|
||||
class="bookmark-edit"
|
||||
v-model="bookmarkDialogActive"
|
||||
:saving="editingBookmark"
|
||||
:name="bookmarkName"
|
||||
@save="editBookmark"
|
||||
>
|
||||
<template #activator="{ on }">
|
||||
<v-icon class="toggle" name="bookmark" @click="on" />
|
||||
<v-icon class="saved" name="bookmark" v-else-if="bookmarkSaved" />
|
||||
|
||||
<template v-else-if="bookmarkIsMine">
|
||||
<v-progress-circular indeterminate small v-if="bookmarkSaving" />
|
||||
<v-icon class="save" v-else @click="savePreset()" name="save" />
|
||||
</template>
|
||||
</bookmark-edit>
|
||||
|
||||
<bookmark-add
|
||||
v-else
|
||||
class="add"
|
||||
v-model="bookmarkDialogActive"
|
||||
@save="createBookmark"
|
||||
:saving="creatingBookmark"
|
||||
>
|
||||
<template #activator="{ on }">
|
||||
<v-icon class="toggle" name="bookmark_outline" @click="on" />
|
||||
</template>
|
||||
</bookmark-add>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #actions:prepend>
|
||||
@@ -277,6 +285,9 @@ export default defineComponent({
|
||||
saveCurrentAsBookmark,
|
||||
title: bookmarkName,
|
||||
resetPreset,
|
||||
bookmarkSaved,
|
||||
bookmarkIsMine,
|
||||
saving: bookmarkSaving,
|
||||
} = usePreset(collection, bookmarkID);
|
||||
|
||||
const {
|
||||
@@ -345,6 +356,9 @@ export default defineComponent({
|
||||
deleteError,
|
||||
createAllowed,
|
||||
resetPreset,
|
||||
bookmarkSaved,
|
||||
bookmarkIsMine,
|
||||
bookmarkSaving,
|
||||
};
|
||||
|
||||
function useBreadcrumb() {
|
||||
@@ -559,25 +573,31 @@ export default defineComponent({
|
||||
--layout-offset-top: 64px;
|
||||
}
|
||||
|
||||
.bookmark-add .toggle,
|
||||
.bookmark-edit .toggle {
|
||||
margin-left: 8px;
|
||||
transition: color var(--fast) var(--transition);
|
||||
}
|
||||
|
||||
.bookmark-add {
|
||||
color: var(--foreground-subdued);
|
||||
|
||||
&:hover {
|
||||
color: var(--foreground-normal);
|
||||
}
|
||||
}
|
||||
|
||||
.bookmark-edit {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
--v-button-color-disabled: var(--foreground-normal);
|
||||
}
|
||||
|
||||
.bookmark-controls {
|
||||
.add,
|
||||
.save,
|
||||
.saved,
|
||||
.v-progress-circular {
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.add,
|
||||
.save {
|
||||
color: var(--foreground-subdued);
|
||||
transition: color var(--fast) var(--transition);
|
||||
|
||||
&:hover {
|
||||
color: var(--foreground-normal);
|
||||
}
|
||||
}
|
||||
|
||||
.saved {
|
||||
color: var(--primary);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -22,7 +22,6 @@ export const usePresetsStore = createStore({
|
||||
actions: {
|
||||
async hydrate() {
|
||||
// Hydrate is only called for logged in users, therefore, currentUser exists
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const { id, role } = useUserStore().state.currentUser!;
|
||||
|
||||
const values = await Promise.all([
|
||||
@@ -65,6 +64,7 @@ export const usePresetsStore = createStore({
|
||||
|
||||
this.state.collectionPresets = this.state.collectionPresets.map((preset) => {
|
||||
const updatedPreset = response.data.data;
|
||||
|
||||
if (preset.id === updatedPreset.id) {
|
||||
return updatedPreset;
|
||||
}
|
||||
@@ -167,5 +167,18 @@ export const usePresetsStore = createStore({
|
||||
return await this.update(id, preset);
|
||||
}
|
||||
},
|
||||
|
||||
async saveLocal(updatedPreset: Preset) {
|
||||
this.state.collectionPresets = this.state.collectionPresets.map((preset) => {
|
||||
if (preset.id === updatedPreset.id) {
|
||||
return {
|
||||
...updatedPreset,
|
||||
$saved: false,
|
||||
};
|
||||
}
|
||||
|
||||
return preset;
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -37,8 +37,9 @@ export type Preset = {
|
||||
search_query: string | null;
|
||||
filters: readonly Filter[] | null;
|
||||
view_type: string | null;
|
||||
|
||||
view_query: { [view_type: string]: any } | null;
|
||||
|
||||
view_options: { [view_type: string]: any } | null;
|
||||
|
||||
// App flag to indicate that the local copy hasn't been saved to the API yet
|
||||
$saved?: false;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user