Refactor bookmark query navigation (#6170)

* Revert back to using query params for bookmarks

Aka "this hurts so much"

* Fix collection navigation active state

* Add active and query props to v-button

Also unify active and activated state.

* Remove not needed exact prop from collections navigation
This commit is contained in:
Nicola Krumschmidt
2021-06-10 21:11:01 +02:00
committed by GitHub
parent 976baa7206
commit f55a2072e1
19 changed files with 142 additions and 103 deletions

View File

@@ -89,7 +89,7 @@ export default defineComponent({
const openItemLink = computed(() => {
if (!item.value) return;
return `/collections/${item.value.collection}/-/${encodeURIComponent(item.value.item)}`;
return `/collections/${item.value.collection}/${encodeURIComponent(item.value.item)}`;
});
watch(() => props.primaryKey, loadActivity, { immediate: true });

View File

@@ -1,5 +1,5 @@
<template>
<v-list-item :to="bookmark.to" class="bookmark" @contextmenu.prevent.stop="activateContextMenu">
<v-list-item :to="bookmark.to" query class="bookmark" @contextmenu.prevent.stop="activateContextMenu">
<v-list-item-icon><v-icon name="bookmark" /></v-list-item-icon>
<v-list-item-content>
<v-text-overflow :text="bookmark.bookmark" />
@@ -142,7 +142,7 @@ export default defineComponent({
let navigateTo: string | null = null;
if (+route.query?.bookmark === props.bookmark.id) {
navigateTo = `/collections/${props.bookmark.collection}/-`;
navigateTo = `/collections/${props.bookmark.collection}`;
}
await presetsStore.delete(props.bookmark.id);

View File

@@ -11,7 +11,7 @@
<template
v-if="(group.name === undefined || group.name === null) && group.accordion === 'always_open' && index === 0"
>
<v-list-item :exact="exact" v-for="navItem in group.items" :key="navItem.to" :to="navItem.to">
<v-list-item v-for="navItem in group.items" :key="navItem.to" :to="navItem.to" query>
<v-list-item-icon><v-icon :name="navItem.icon" :color="navItem.color" /></v-list-item-icon>
<v-list-item-content>
<v-text-overflow :text="navItem.name" />
@@ -26,7 +26,7 @@
:label="group.name || null"
@update:model-value="toggleActive(group.name)"
>
<v-list-item :exact="exact" v-for="navItem in group.items" :key="navItem.to" :to="navItem.to">
<v-list-item v-for="navItem in group.items" :key="navItem.to" :to="navItem.to" query>
<v-list-item-icon><v-icon :name="navItem.icon" :color="navItem.color" /></v-list-item-icon>
<v-list-item-content>
<v-text-overflow :text="navItem.name" />
@@ -37,7 +37,7 @@
</template>
</template>
<v-list-item v-else :exact="exact" v-for="navItem in navItems" :key="navItem.to" :to="navItem.to">
<v-list-item v-else v-for="navItem in navItems" :key="navItem.to" :to="navItem.to" query>
<v-list-item-icon><v-icon :name="navItem.icon" :color="navItem.color" /></v-list-item-icon>
<v-list-item-content>
<v-text-overflow :text="navItem.name" />
@@ -65,13 +65,7 @@
<template v-if="hiddenShown">
<v-divider />
<v-list-item
class="hidden-collection"
:exact="exact"
v-for="navItem in hiddenNavItems"
:key="navItem.to"
:to="navItem.to"
>
<v-list-item class="hidden-collection" v-for="navItem in hiddenNavItems" :key="navItem.to" :to="navItem.to" query>
<v-list-item-icon><v-icon :name="navItem.icon" :color="navItem.color" /></v-list-item-icon>
<v-list-item-content>
<v-text-overflow :text="navItem.name" />
@@ -105,12 +99,6 @@ import { useSearch } from '../composables/use-search';
export default defineComponent({
components: { NavigationBookmark },
props: {
exact: {
type: Boolean,
default: false,
},
},
setup() {
const { t } = useI18n();
@@ -142,7 +130,7 @@ export default defineComponent({
return {
...preset,
to: `/collections/${preset.collection}/${preset.id}`,
to: `/collections/${preset.collection}?bookmark=${preset.id}`,
scope,
};
}),

View File

@@ -27,7 +27,7 @@ function collectionToNavItem(collection: Collection): NavItem {
icon: collection.meta?.icon || 'label',
color: collection.meta?.color,
note: collection.meta?.note || null,
to: `/collections/${collection.collection}/-`,
to: `/collections/${collection.collection}`,
};
}

View File

@@ -1,4 +1,5 @@
import { defineModule } from '@/modules/define';
import { addQueryToPath } from '@/utils/add-query-to-path';
import RouterPass from '@/utils/router-passthrough';
import { NavigationGuard } from 'vue-router';
import CollectionOrItem from './routes/collection-or-item.vue';
@@ -6,7 +7,7 @@ import Item from './routes/item.vue';
import ItemNotFound from './routes/not-found.vue';
import Overview from './routes/overview.vue';
const checkForSystem: NavigationGuard = (to) => {
const checkForSystem: NavigationGuard = (to, from) => {
if (!to.params?.collection) return;
if (to.params.collection === 'directus_users') {
@@ -40,6 +41,15 @@ const checkForSystem: NavigationGuard = (to) => {
return '/settings/webhooks';
}
}
if (
'bookmark' in from.query &&
typeof from.query.bookmark === 'string' &&
'bookmark' in to.query === false &&
to.params.collection === from.params.collection
) {
return addQueryToPath(to.fullPath, { bookmark: from.query.bookmark });
}
};
export default defineModule({
@@ -54,23 +64,16 @@ export default defineModule({
},
{
path: ':collection',
redirect: (to) => ({
name: 'collections-collection',
params: {
collection: to.params.collection,
bookmark: '-',
},
}),
},
{
path: ':collection/:bookmark',
component: RouterPass,
children: [
{
name: 'collections-collection',
path: '',
component: CollectionOrItem,
props: true,
props: (route) => ({
collection: route.params.collection,
bookmark: route.query.bookmark,
}),
beforeEnter: checkForSystem,
},
{

View File

@@ -1,6 +1,6 @@
<template>
<collections-not-found v-if="!currentCollection || collection.startsWith('directus_')" />
<private-view v-else :title="bookmark !== '-' ? bookmarkTitle : currentCollection.name">
<private-view v-else :title="bookmark ? bookmarkTitle : currentCollection.name">
<template #title-outer:prepend>
<v-button class="header-icon" rounded icon secondary disabled>
<v-icon :name="currentCollection.icon" :color="currentCollection.color" />
@@ -8,14 +8,14 @@
</template>
<template #headline>
<v-breadcrumb v-if="bookmark !== '-'" :items="breadcrumb" />
<v-breadcrumb v-if="bookmark" :items="breadcrumb" />
<v-breadcrumb v-else :items="[{ name: t('collections'), to: '/collections' }]" />
</template>
<template #title-outer:append>
<div class="bookmark-controls">
<bookmark-add
v-if="bookmark === '-'"
v-if="!bookmark"
class="add"
v-model="bookmarkDialogActive"
@save="createBookmark"
@@ -57,7 +57,7 @@
</bookmark-add>
<v-icon
v-if="bookmark !== '-' && !bookmarkSaving && bookmarkSaved === false"
v-if="bookmark && !bookmarkSaving && bookmarkSaved === false"
name="settings_backup_restore"
clickable
@click="clearLocalSave"
@@ -164,7 +164,7 @@
<v-info
type="warning"
v-if="bookmark !== '-' && bookmarkExists === false"
v-if="bookmark && bookmarkExists === false"
:title="t('bookmark_doesnt_exist')"
icon="bookmark"
center
@@ -194,7 +194,7 @@
{{ t('no_items_copy') }}
<template #append v-if="createAllowed">
<v-button :to="`/collections/${collection}/-/+`">{{ t('create_item') }}</v-button>
<v-button :to="`/collections/${collection}/+`">{{ t('create_item') }}</v-button>
</template>
</v-info>
</template>
@@ -296,7 +296,7 @@ export default defineComponent({
const permissionsStore = usePermissionsStore();
const { collection } = toRefs(props);
const bookmarkID = computed(() => (props.bookmark !== '-' ? +props.bookmark : null));
const bookmarkID = computed(() => (props.bookmark ? +props.bookmark : null));
const { selection } = useSelection();
const { info: currentCollection } = useCollection(collection);
@@ -413,7 +413,7 @@ export default defineComponent({
const breadcrumb = computed(() => [
{
name: currentCollection.value?.name,
to: `/collections/${props.collection}/-`,
to: `/collections/${props.collection}`,
},
]);
@@ -493,11 +493,11 @@ export default defineComponent({
function useLinks() {
const addNewLink = computed<string>(() => {
return `/collections/${props.collection}/-/+`;
return `/collections/${props.collection}/+`;
});
const currentCollectionLink = computed<string>(() => {
return `/collections/${props.collection}/-`;
return `/collections/${props.collection}`;
});
return { addNewLink, currentCollectionLink };
@@ -521,7 +521,7 @@ export default defineComponent({
try {
const newBookmark = await saveCurrentAsBookmark({ bookmark: name });
router.push(`/collections/${newBookmark.collection}/${newBookmark.id}`);
router.push(`/collections/${newBookmark.collection}?bookmark=${newBookmark.id}`);
bookmarkDialogActive.value = false;
} catch (err) {
@@ -617,7 +617,7 @@ export default defineComponent({
.header-icon.secondary {
--v-button-background-color: var(--background-normal);
--v-button-background-color-activated: var(--background-normal);
--v-button-background-color-active: var(--background-normal);
--v-button-background-color-hover: var(--background-normal-alt);
}

View File

@@ -419,7 +419,7 @@ export default defineComponent({
const breadcrumb = computed(() => [
{
name: collectionInfo.value?.name,
to: `/collections/${props.collection}/-`,
to: `/collections/${props.collection}`,
},
]);
@@ -431,7 +431,7 @@ export default defineComponent({
try {
await save();
if (props.singleton === false) router.push(`/collections/${props.collection}/-`);
if (props.singleton === false) router.push(`/collections/${props.collection}`);
} catch {
// Save shows unexpected error dialog
}
@@ -448,7 +448,7 @@ export default defineComponent({
if (props.primaryKey === '+') {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const newPrimaryKey = savedItem[primaryKeyField.value!.field];
router.replace(`/collections/${props.collection}/-/${encodeURIComponent(newPrimaryKey)}`);
router.replace(`/collections/${props.collection}/${encodeURIComponent(newPrimaryKey)}`);
}
} catch {
// Save shows unexpected error dialog
@@ -464,7 +464,7 @@ export default defineComponent({
if (isNew.value === true) {
refresh();
} else {
router.push(`/collections/${props.collection}/-/+`);
router.push(`/collections/${props.collection}/+`);
}
} catch {
// Save shows unexpected error dialog
@@ -474,7 +474,7 @@ export default defineComponent({
async function saveAsCopyAndNavigate() {
try {
const newPrimaryKey = await saveAsCopy();
if (newPrimaryKey) router.push(`/collections/${props.collection}/-/${encodeURIComponent(newPrimaryKey)}`);
if (newPrimaryKey) router.push(`/collections/${props.collection}/${encodeURIComponent(newPrimaryKey)}`);
} catch {
// Save shows unexpected error dialog
}
@@ -483,7 +483,7 @@ export default defineComponent({
async function deleteAndQuit() {
try {
await remove();
router.push(`/collections/${props.collection}/-`);
router.push(`/collections/${props.collection}`);
} catch {
// `remove` will show the unexpected error dialog
}
@@ -494,7 +494,7 @@ export default defineComponent({
await archive();
if (isArchived.value === true) {
router.push(`/collections/${props.collection}/-`);
router.push(`/collections/${props.collection}`);
} else {
confirmArchive.value = false;
}
@@ -538,7 +538,7 @@ export default defineComponent({
.header-icon.secondary {
--v-button-background-color: var(--background-normal);
--v-button-color-disabled: var(--foreground-normal);
--v-button-color-activated: var(--foreground-normal);
--v-button-color-active: var(--foreground-normal);
}
.v-form {