mirror of
https://github.com/directus/directus.git
synced 2026-01-24 03:17:56 -05:00
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:
5
.changeset/wet-beds-fold.md
Normal file
5
.changeset/wet-beds-fold.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@directus/app": patch
|
||||
---
|
||||
|
||||
Fixed incorrect endpoints for system collections
|
||||
@@ -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),
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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();
|
||||
|
||||
27
app/src/utils/get-item-route.test.ts
Normal file
27
app/src/utils/get-item-route.test.ts
Normal 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}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
14
app/src/utils/get-item-route.ts
Normal file
14
app/src/utils/get-item-route.ts
Normal 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}`;
|
||||
}
|
||||
Reference in New Issue
Block a user