Fix incorrect endpoints for system collections (#18657)

* Fix endpoints for system collections in kanban layout

* Fix other occurrences

* Fix item route for system collections in kanban layout

* Add changeset

* Remove redundant string interpolation

Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com>

* Extract getItemRoute as an app util

* Remove empty line

Co-authored-by: Pascal Jufer <pascal-jufer@bluewin.ch>

---------

Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com>
Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
Co-authored-by: Pascal Jufer <pascal-jufer@bluewin.ch>
This commit is contained in:
ian
2023-05-20 00:01:11 +08:00
committed by GitHub
parent 2e647d80e6
commit ea857563ad
8 changed files with 63 additions and 17 deletions

View File

@@ -0,0 +1,5 @@
---
"@directus/app": patch
---
Fixed incorrect endpoints for system collections

View File

@@ -82,6 +82,7 @@ import { cloneDeep, isNil } from 'lodash';
import { computed, ref, toRefs, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import LanguageSelect from './language-select.vue';
import { getEndpoint } from '@directus/utils';
const props = withDefaults(
defineProps<{
@@ -291,7 +292,7 @@ function useLanguages() {
try {
languages.value = await fetchAll<Record<string, any>[]>(
`/items/${relationInfo.value.relatedCollection.collection}`,
getEndpoint(relationInfo.value.relatedCollection.collection),
{
params: {
fields: Array.from(fields),

View File

@@ -3,6 +3,7 @@ import { router } from '@/router';
import { useAppStore } from '@/stores/app';
import { useServerStore } from '@/stores/server';
import { getFullcalendarLocale } from '@/utils/get-fullcalendar-locale';
import { getItemRoute } from '@/utils/get-item-route';
import { renderDisplayStringTemplate } from '@/utils/render-string-template';
import { saveAsCSV } from '@/utils/save-as-csv';
import { syncRefProperty } from '@/utils/sync-ref-property';
@@ -176,11 +177,7 @@ export default defineLayout<LayoutOptions>({
} else {
const primaryKey = info.event.id;
const route = collection.value.startsWith('directus_')
? collection.value.substring(9)
: `content/${collection.value}`;
router.push(`/${route}/${primaryKey}`);
router.push(getItemRoute(collection.value, primaryKey));
}
},
async eventChange(info) {

View File

@@ -6,7 +6,7 @@ import { getRootPath } from '@/utils/get-root-path';
import { translate } from '@/utils/translate-literal';
import { useCollection, useFilterFields, useItems, useSync } from '@directus/composables';
import { User } from '@directus/types';
import { defineLayout, getRelationType, moveInArray } from '@directus/utils';
import { defineLayout, getEndpoint, getRelationType, moveInArray } from '@directus/utils';
import { computed, ref, toRefs, watch } from 'vue';
import KanbanActions from './actions.vue';
import KanbanLayout from './kanban.vue';
@@ -255,7 +255,7 @@ export default defineLayout<LayoutOptions, LayoutQuery>({
const gField = groupField.value;
const pkField = primaryKeyField.value?.field;
if (gField === null || pkField === undefined || event.removed) return;
if (gField === null || pkField === undefined || event.removed || !collection.value) return;
if (event.moved) {
const item = group.items[event.moved.oldIndex]?.id;
@@ -288,7 +288,7 @@ export default defineLayout<LayoutOptions, LayoutQuery>({
}
}
await api.patch(`/items/${collection.value}/${event.added.element.id}`, {
await api.patch(`${getEndpoint(collection.value)}/${event.added.element.id}`, {
[gField]: group.id,
});
}
@@ -459,19 +459,19 @@ export default defineLayout<LayoutOptions, LayoutQuery>({
async function deleteGroup(id: string | number) {
const pkField = primaryKeyField.value?.field;
if (pkField === undefined) return;
if (pkField === undefined || !groupsCollection.value) return;
items.value = items.value.filter((item) => item[pkField] !== id);
await api.delete(`/items/${groupsCollection.value}/${id}`);
await api.delete(`${getEndpoint(groupsCollection.value)}/${id}`);
await getGroups();
}
async function addGroup(title: string) {
if (groupTitle.value === null) return;
if (groupTitle.value === null || !groupsCollection.value) return;
await api.post(`/items/${groupsCollection.value}`, {
await api.post(getEndpoint(groupsCollection.value), {
[groupTitle.value]: title,
});
@@ -480,9 +480,9 @@ export default defineLayout<LayoutOptions, LayoutQuery>({
async function editGroup(id: string | number, title: string) {
if (isRelational.value) {
if (groupTitle.value === null) return;
if (groupTitle.value === null || !groupsCollection.value) return;
await api.patch(`/items/${groupsCollection.value}/${id}`, {
await api.patch(`${getEndpoint(groupsCollection.value)}/${id}`, {
[groupTitle.value]: title,
});
} else {

View File

@@ -50,7 +50,7 @@
@change="change(group, $event)"
>
<template #item="{ element }">
<router-link :to="`${collection}/${element.id}`" class="item">
<router-link :to="getItemRoute(collection, element.id)" class="item">
<div v-if="element.title" class="title">{{ element.title }}</div>
<img v-if="element.image" class="image" :src="element.image" />
<div v-if="element.text" class="text">{{ element.text }}</div>
@@ -110,6 +110,7 @@ export default {
<script setup lang="ts">
import { addTokenToURL } from '@/api';
import { getRootPath } from '@/utils/get-root-path';
import { getItemRoute } from '@/utils/get-item-route';
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import Draggable from 'vuedraggable';

View File

@@ -13,6 +13,7 @@ import * as alterations from './alterations';
import { getLocalTypeForField } from '@/utils/get-local-type';
import api from '@/api';
import { useExtensions } from '@/extensions';
import { getEndpoint } from '@directus/utils';
export function syncFieldDetailStoreProperty(path: string, defaultValue?: any) {
const fieldDetailStore = useFieldDetailStore();
@@ -223,7 +224,7 @@ export const useFieldDetailStore = defineStore({
}
for (const collection of Object.keys(this.items)) {
await api.post(`/items/${collection}`, this.items[collection]);
await api.post(getEndpoint(collection), this.items[collection]);
}
await fieldsStore.hydrate();

View File

@@ -0,0 +1,27 @@
import { describe, expect, it } from 'vitest';
import { getItemRoute } from '@/utils/get-item-route';
const collection = 'some_collection';
const systemCollection = 'directus_users';
const primaryKeys = [123, 'abc'];
describe('getItemRoute', () => {
it('Returns an empty string when collection is null', () => {
for (const primaryKey of primaryKeys) {
expect(getItemRoute(null, primaryKey)).toBe('');
}
});
it('Returns the expected route for collection', () => {
for (const primaryKey of primaryKeys) {
expect(getItemRoute(collection, primaryKey)).toBe(`/content/${collection}/${primaryKey}`);
}
});
it('Returns the expected route for system collection', () => {
for (const primaryKey of primaryKeys) {
expect(getItemRoute(systemCollection, primaryKey)).toBe(`/${systemCollection.substring(9)}/${primaryKey}`);
}
});
});

View File

@@ -0,0 +1,14 @@
/**
* Get the route of an item in the admin app for a given collection and primary key
*
* @param collection - Collection name
* @param primaryKey - Primary key of item
* @returns - URL route for the item
*/
export function getItemRoute(collection: string | null, primaryKey: string | number) {
if (collection === null) return '';
const route = collection.startsWith('directus_') ? collection.substring(9) : `content/${collection}`;
return `/${route}/${primaryKey}`;
}