mirror of
https://github.com/directus/directus.git
synced 2026-02-11 04:15:08 -05:00
Fix type errors
This commit is contained in:
@@ -160,7 +160,7 @@ const redirectIfNeeded: NavigationGuard = async (to, from, next) => {
|
||||
|
||||
const primaryKeyField = fieldsStore.getPrimaryKeyFieldForCollection(to.params.collection);
|
||||
|
||||
const item = await api.get(`/${to.params.project}/items/${to.params.collection}`, {
|
||||
const item = await api.get(`/items/${to.params.collection}`, {
|
||||
params: {
|
||||
limit: 1,
|
||||
fields: primaryKeyField.field,
|
||||
@@ -170,7 +170,7 @@ const redirectIfNeeded: NavigationGuard = async (to, from, next) => {
|
||||
|
||||
const primaryKey = item.data.data[primaryKeyField.field];
|
||||
|
||||
return next(`/${to.params.project}/collections/${to.params.collection}/${primaryKey}`);
|
||||
return next(`/collections/${to.params.collection}/${primaryKey}`);
|
||||
}
|
||||
|
||||
return next();
|
||||
|
||||
@@ -217,17 +217,19 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
function getPrimaryKeyField() {
|
||||
const field: Partial<Field> = {
|
||||
auto_increment: true,
|
||||
const field: DeepPartial<Field> = {
|
||||
field: primaryKeyFieldName.value,
|
||||
hidden_browse: false,
|
||||
hidden_detail: false,
|
||||
interface: 'numeric',
|
||||
length: 15,
|
||||
primary_key: true,
|
||||
type: 'integer',
|
||||
datatype: 'INT',
|
||||
readonly: true,
|
||||
system: {
|
||||
hidden_browse: false,
|
||||
hidden_detail: false,
|
||||
interface: 'numeric',
|
||||
readonly: true,
|
||||
},
|
||||
database: {
|
||||
has_auto_increment: true,
|
||||
is_primary_key: true,
|
||||
type: 'INT',
|
||||
},
|
||||
};
|
||||
|
||||
if (primaryKeyFieldType.value === 'uuid') {
|
||||
@@ -256,127 +258,150 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
function getSystemFields() {
|
||||
const fields: Partial<Field>[] = [];
|
||||
const fields: DeepPartial<Field>[] = [];
|
||||
|
||||
if (systemFields[0].enabled === true) {
|
||||
fields.push({
|
||||
type: 'status',
|
||||
datatype: 'VARCHAR',
|
||||
length: 20,
|
||||
field: systemFields[0].name,
|
||||
interface: 'status',
|
||||
default_value: 'draft',
|
||||
width: 'full',
|
||||
required: true,
|
||||
options: {
|
||||
status_mapping: {
|
||||
published: {
|
||||
name: 'Published',
|
||||
value: 'published',
|
||||
text_color: 'white',
|
||||
background_color: 'accent',
|
||||
browse_subdued: false,
|
||||
browse_badge: true,
|
||||
soft_delete: false,
|
||||
published: true,
|
||||
required_fields: true,
|
||||
},
|
||||
draft: {
|
||||
name: 'Draft',
|
||||
value: 'draft',
|
||||
text_color: 'white',
|
||||
background_color: 'blue-grey-100',
|
||||
browse_subdued: true,
|
||||
browse_badge: true,
|
||||
soft_delete: false,
|
||||
published: false,
|
||||
required_fields: false,
|
||||
},
|
||||
deleted: {
|
||||
name: 'Deleted',
|
||||
value: 'deleted',
|
||||
text_color: 'white',
|
||||
background_color: 'red',
|
||||
browse_subdued: true,
|
||||
browse_badge: true,
|
||||
soft_delete: true,
|
||||
published: false,
|
||||
required_fields: false,
|
||||
system: {
|
||||
width: 'full',
|
||||
required: true,
|
||||
options: {
|
||||
status_mapping: {
|
||||
published: {
|
||||
name: 'Published',
|
||||
value: 'published',
|
||||
text_color: 'white',
|
||||
background_color: 'accent',
|
||||
browse_subdued: false,
|
||||
browse_badge: true,
|
||||
soft_delete: false,
|
||||
published: true,
|
||||
required_fields: true,
|
||||
},
|
||||
draft: {
|
||||
name: 'Draft',
|
||||
value: 'draft',
|
||||
text_color: 'white',
|
||||
background_color: 'blue-grey-100',
|
||||
browse_subdued: true,
|
||||
browse_badge: true,
|
||||
soft_delete: false,
|
||||
published: false,
|
||||
required_fields: false,
|
||||
},
|
||||
deleted: {
|
||||
name: 'Deleted',
|
||||
value: 'deleted',
|
||||
text_color: 'white',
|
||||
background_color: 'red',
|
||||
browse_subdued: true,
|
||||
browse_badge: true,
|
||||
soft_delete: true,
|
||||
published: false,
|
||||
required_fields: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
special: 'status',
|
||||
interface: 'status',
|
||||
},
|
||||
database: {
|
||||
type: 'VARCHAR',
|
||||
default_value: 'draft',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (systemFields[1].enabled === true) {
|
||||
fields.push({
|
||||
type: 'sort',
|
||||
datatype: 'INT',
|
||||
field: systemFields[1].name,
|
||||
interface: 'sort',
|
||||
hidden_detail: true,
|
||||
hidden_browse: true,
|
||||
width: 'full',
|
||||
system: {
|
||||
interface: 'sort',
|
||||
hidden_detail: true,
|
||||
hidden_browse: true,
|
||||
width: 'full',
|
||||
special: 'sort',
|
||||
},
|
||||
database: {
|
||||
type: 'INT',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (systemFields[2].enabled === true) {
|
||||
fields.push({
|
||||
type: 'user_created',
|
||||
datatype: 'INT',
|
||||
field: systemFields[2].name,
|
||||
interface: 'owner',
|
||||
options: {
|
||||
template: '{{first_name}} {{last_name}}',
|
||||
display: 'both',
|
||||
system: {
|
||||
special: 'user_created',
|
||||
interface: 'owner',
|
||||
options: {
|
||||
template: '{{first_name}} {{last_name}}',
|
||||
display: 'both',
|
||||
},
|
||||
readonly: true,
|
||||
hidden_detail: true,
|
||||
hidden_browse: true,
|
||||
width: 'full',
|
||||
},
|
||||
database: {
|
||||
type: 'INT' /** @todo make these vendor based */,
|
||||
},
|
||||
readonly: true,
|
||||
hidden_detail: true,
|
||||
hidden_browse: true,
|
||||
width: 'full',
|
||||
});
|
||||
}
|
||||
|
||||
if (systemFields[3].enabled === true) {
|
||||
fields.push({
|
||||
type: 'datetime_created',
|
||||
datatype: 'DATETIME',
|
||||
field: systemFields[3].name,
|
||||
interface: 'datetime-created',
|
||||
readonly: true,
|
||||
hidden_detail: true,
|
||||
hidden_browse: true,
|
||||
width: 'full',
|
||||
system: {
|
||||
special: 'datetime_created',
|
||||
interface: 'datetime-created',
|
||||
readonly: true,
|
||||
hidden_detail: true,
|
||||
hidden_browse: true,
|
||||
width: 'full',
|
||||
},
|
||||
database: {
|
||||
type: 'DATETIME',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (systemFields[4].enabled === true) {
|
||||
fields.push({
|
||||
type: 'user_updated',
|
||||
datatype: 'INT',
|
||||
field: systemFields[4].name,
|
||||
interface: 'user-updated',
|
||||
options: {
|
||||
template: '{{first_name}} {{last_name}}',
|
||||
display: 'both',
|
||||
system: {
|
||||
special: 'user_updated',
|
||||
interface: 'user-updated',
|
||||
options: {
|
||||
template: '{{first_name}} {{last_name}}',
|
||||
display: 'both',
|
||||
},
|
||||
readonly: true,
|
||||
hidden_detail: true,
|
||||
hidden_browse: true,
|
||||
width: 'full',
|
||||
},
|
||||
database: {
|
||||
type: 'INT',
|
||||
},
|
||||
readonly: true,
|
||||
hidden_detail: true,
|
||||
hidden_browse: true,
|
||||
width: 'full',
|
||||
});
|
||||
}
|
||||
|
||||
if (systemFields[5].enabled === true) {
|
||||
fields.push({
|
||||
type: 'datetime_updated',
|
||||
datatype: 'DATETIME',
|
||||
field: systemFields[5].name,
|
||||
interface: 'datetime-updated',
|
||||
readonly: true,
|
||||
hidden_detail: true,
|
||||
hidden_browse: true,
|
||||
width: 'full',
|
||||
system: {
|
||||
special: 'datetime_updated',
|
||||
interface: 'datetime-updated',
|
||||
readonly: true,
|
||||
hidden_detail: true,
|
||||
hidden_browse: true,
|
||||
width: 'full',
|
||||
},
|
||||
database: {
|
||||
type: 'DATETIME',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ export default defineComponent({
|
||||
const { duplicateActive, duplicateName, collections, duplicateTo, saveDuplicate, duplicating } = useDuplicate();
|
||||
|
||||
const interfaceName = computed(() => {
|
||||
return interfaces.find((inter) => inter.id === props.field.interface)?.name;
|
||||
return interfaces.find((inter) => inter.id === props.field.system.interface)?.name;
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -194,8 +194,8 @@ export default defineComponent({
|
||||
collection: duplicateTo.value,
|
||||
};
|
||||
|
||||
delete newField.id;
|
||||
delete newField.sort;
|
||||
delete newField.system.id;
|
||||
delete newField.system.sort;
|
||||
delete newField.name;
|
||||
|
||||
duplicating.value = true;
|
||||
|
||||
@@ -69,7 +69,7 @@ export default defineComponent({
|
||||
});
|
||||
|
||||
const selectedDisplay = computed(() => {
|
||||
return displays.find((inter) => inter.id === props.value.display) || null;
|
||||
return displays.find((inter) => inter.id === props.value.system.display) || null;
|
||||
});
|
||||
|
||||
return { emitValue, items, selectedDisplay };
|
||||
|
||||
@@ -71,7 +71,7 @@ export default defineComponent({
|
||||
});
|
||||
|
||||
const selectedInterface = computed(() => {
|
||||
return interfaces.find((inter) => inter.id === props.value.interface) || null;
|
||||
return interfaces.find((inter) => inter.id === props.value.system.interface) || null;
|
||||
});
|
||||
|
||||
return { emitValue, items, selectedInterface, setInterface };
|
||||
|
||||
@@ -25,7 +25,7 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const selectedInterface = computed(() => interfaces.find((inter) => inter.id === props.value.interface));
|
||||
const selectedInterface = computed(() => interfaces.find((inter) => inter.id === props.value.system.interface));
|
||||
|
||||
const typeChoices = computed(() => {
|
||||
let availableTypes = types;
|
||||
@@ -45,115 +45,145 @@ export default defineComponent({
|
||||
{
|
||||
field: 'field',
|
||||
name: i18n.t('database_column_name'),
|
||||
interface: 'slug',
|
||||
width: 'half',
|
||||
options: null,
|
||||
readonly: props.isNew === false,
|
||||
system: {
|
||||
interface: 'slug',
|
||||
width: 'half',
|
||||
options: null,
|
||||
readonly: props.isNew === false,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'note',
|
||||
name: i18n.t('note'),
|
||||
interface: 'text-input',
|
||||
width: 'full',
|
||||
options: {
|
||||
placeholder: i18n.t('add_helpful_note'),
|
||||
system: {
|
||||
interface: 'text-input',
|
||||
width: 'full',
|
||||
options: {
|
||||
placeholder: i18n.t('add_helpful_note'),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'translation',
|
||||
name: i18n.t('translations'),
|
||||
interface: 'key-value',
|
||||
width: 'full',
|
||||
options: null,
|
||||
system: {
|
||||
interface: 'key-value',
|
||||
width: 'full',
|
||||
options: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'default_value',
|
||||
name: i18n.t('default_value'),
|
||||
interface: 'text-input' /** @TODO base on selected datatype */,
|
||||
width: 'half',
|
||||
options: {
|
||||
placeholder: i18n.t('enter_value'),
|
||||
system: {
|
||||
interface: 'text-input' /** @TODO base on selected datatype */,
|
||||
width: 'half',
|
||||
options: {
|
||||
placeholder: i18n.t('enter_value'),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'length',
|
||||
name: i18n.t('length'),
|
||||
interface: 'numeric',
|
||||
width: 'half',
|
||||
options: null,
|
||||
system: {
|
||||
interface: 'numeric',
|
||||
width: 'half',
|
||||
options: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'required',
|
||||
name: i18n.t('required'),
|
||||
interface: 'toggle',
|
||||
width: 'half',
|
||||
options: null,
|
||||
system: {
|
||||
interface: 'toggle',
|
||||
width: 'half',
|
||||
options: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'readonly',
|
||||
name: i18n.t('readonly'),
|
||||
interface: 'toggle',
|
||||
width: 'half',
|
||||
options: null,
|
||||
system: {
|
||||
interface: 'toggle',
|
||||
width: 'half',
|
||||
options: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'hidden_detail',
|
||||
name: i18n.t('hide_on_detail'),
|
||||
interface: 'toggle',
|
||||
width: 'half',
|
||||
options: null,
|
||||
system: {
|
||||
interface: 'toggle',
|
||||
width: 'half',
|
||||
options: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'hidden_browse',
|
||||
name: i18n.t('hide_on_browse'),
|
||||
interface: 'toggle',
|
||||
width: 'half',
|
||||
options: null,
|
||||
system: {
|
||||
interface: 'toggle',
|
||||
width: 'half',
|
||||
options: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'unique',
|
||||
name: i18n.t('unique'),
|
||||
interface: 'toggle',
|
||||
width: 'half',
|
||||
options: null,
|
||||
system: {
|
||||
interface: 'toggle',
|
||||
width: 'half',
|
||||
options: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'primary_key',
|
||||
name: i18n.t('primary_key'),
|
||||
interface: 'toggle',
|
||||
width: 'half',
|
||||
options: null,
|
||||
system: {
|
||||
interface: 'toggle',
|
||||
width: 'half',
|
||||
options: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'validation',
|
||||
name: i18n.t('validation_regex'),
|
||||
interface: 'text-input',
|
||||
width: 'half',
|
||||
options: {
|
||||
font: 'monospace',
|
||||
placeholder: 'eg: /^[A-Z]+$/',
|
||||
system: {
|
||||
interface: 'text-input',
|
||||
width: 'half',
|
||||
options: {
|
||||
font: 'monospace',
|
||||
placeholder: 'eg: /^[A-Z]+$/',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'validation_message',
|
||||
name: i18n.t('validation_message'),
|
||||
interface: 'text-input',
|
||||
width: 'half',
|
||||
system: {
|
||||
interface: 'text-input',
|
||||
width: 'half',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'type',
|
||||
name: i18n.t('directus_type'),
|
||||
interface: 'dropdown',
|
||||
width: 'half',
|
||||
options: {
|
||||
choices: typeChoices.value,
|
||||
system: {
|
||||
interface: 'dropdown',
|
||||
width: 'half',
|
||||
options: {
|
||||
choices: typeChoices.value,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'datatype',
|
||||
name: i18n.t('database_type'),
|
||||
interface: 'text-input',
|
||||
width: 'half',
|
||||
system: {
|
||||
interface: 'text-input',
|
||||
width: 'half',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -2,7 +2,10 @@ import FieldSetup from './field-setup.vue';
|
||||
import { types, Type } from '@/stores/fields/types';
|
||||
import { LocalType } from './types';
|
||||
|
||||
const localTypeGroups: Record<LocalType, Type[]> = {
|
||||
/**
|
||||
* @todo fix local type groups in settings
|
||||
*/
|
||||
const localTypeGroups: Record<LocalType, string[]> = {
|
||||
relational: ['m2o', 'o2m', 'm2m', 'translation'],
|
||||
file: ['file'],
|
||||
files: ['files'],
|
||||
|
||||
@@ -13,11 +13,11 @@ export default function useValidation(field: Ref<Field>, localType: Ref<LocalTyp
|
||||
});
|
||||
|
||||
const interfaceComplete = computed<boolean>(() => {
|
||||
return notEmpty(field.value.interface);
|
||||
return notEmpty(field.value.system.interface);
|
||||
});
|
||||
|
||||
const displayComplete = computed<boolean>(() => {
|
||||
return notEmpty(field.value.display);
|
||||
return notEmpty(field.value.system.display);
|
||||
});
|
||||
|
||||
const schemaComplete = computed<boolean>(() => {
|
||||
|
||||
@@ -105,15 +105,15 @@ export default defineComponent({
|
||||
|
||||
const sortedVisibleFields = computed(() =>
|
||||
sortBy(
|
||||
[...fields.value].filter(({ hidden_detail }) => hidden_detail === false),
|
||||
(field) => field.sort || Infinity
|
||||
[...fields.value].filter((field) => field.system.hidden_detail === false),
|
||||
(field) => field.system.sort || Infinity
|
||||
)
|
||||
);
|
||||
|
||||
const sortedHiddenFields = computed(() =>
|
||||
sortBy(
|
||||
[...fields.value].filter(({ hidden_detail }) => hidden_detail === true),
|
||||
(field) => field.sort || Infinity
|
||||
[...fields.value].filter((field) => field.system.hidden_detail === true),
|
||||
(field) => field.system.sort || Infinity
|
||||
)
|
||||
);
|
||||
|
||||
@@ -157,9 +157,10 @@ export default defineComponent({
|
||||
|
||||
const fieldsInGroup = location === 'visible' ? sortedVisibleFields.value : sortedHiddenFields.value;
|
||||
|
||||
const updates: Partial<Field>[] = fieldsInGroup.slice(newIndex).map((field) => {
|
||||
const updates: DeepPartial<Field>[] = fieldsInGroup.slice(newIndex).map((field) => {
|
||||
const sortValue =
|
||||
field.sort || fieldsInGroup.findIndex((existingField) => existingField.field === field.field);
|
||||
field.system.sort ||
|
||||
fieldsInGroup.findIndex((existingField) => existingField.field === field.field);
|
||||
|
||||
return {
|
||||
field: field.field,
|
||||
@@ -169,11 +170,11 @@ export default defineComponent({
|
||||
|
||||
const addedToEnd = newIndex === fieldsInGroup.length;
|
||||
|
||||
let newSortValue = fieldsInGroup[newIndex]?.sort;
|
||||
let newSortValue = fieldsInGroup[newIndex]?.system.sort;
|
||||
|
||||
if (!newSortValue && addedToEnd) {
|
||||
const previousItem = fieldsInGroup[newIndex - 1];
|
||||
if (previousItem && previousItem.sort) newSortValue = previousItem.sort + 1;
|
||||
if (previousItem && previousItem.system.sort) newSortValue = previousItem.system.sort + 1;
|
||||
}
|
||||
|
||||
if (!newSortValue) {
|
||||
@@ -182,8 +183,10 @@ export default defineComponent({
|
||||
|
||||
updates.push({
|
||||
field: element.field,
|
||||
sort: newSortValue,
|
||||
hidden_detail: location === 'hidden',
|
||||
system: {
|
||||
hidden_detail: location === 'hidden',
|
||||
sort: newSortValue,
|
||||
},
|
||||
});
|
||||
|
||||
fieldsStore.updateFields(element.collection, updates);
|
||||
@@ -197,11 +200,11 @@ export default defineComponent({
|
||||
|
||||
const fields = location === 'visible' ? sortedVisibleFields.value : sortedHiddenFields.value;
|
||||
|
||||
const updates: Partial<Field>[] = fields.slice(...selectionRange).map((field) => {
|
||||
const updates: DeepPartial<Field>[] = fields.slice(...selectionRange).map((field) => {
|
||||
// If field.sort isn't set yet, base it on the index of the array. That way, the
|
||||
// new sort value will match what's visible on the screen
|
||||
const sortValue =
|
||||
field.sort || fields.findIndex((existingField) => existingField.field === field.field);
|
||||
field.system.sort || fields.findIndex((existingField) => existingField.field === field.field);
|
||||
|
||||
return {
|
||||
field: field.field,
|
||||
@@ -209,10 +212,12 @@ export default defineComponent({
|
||||
};
|
||||
});
|
||||
|
||||
const sortOfItemOnNewIndex = fields[newIndex].sort || newIndex;
|
||||
const sortOfItemOnNewIndex = fields[newIndex].system.sort || newIndex;
|
||||
updates.push({
|
||||
field: element.field,
|
||||
sort: sortOfItemOnNewIndex,
|
||||
system: {
|
||||
sort: sortOfItemOnNewIndex,
|
||||
},
|
||||
});
|
||||
|
||||
fieldsStore.updateFields(element.collection, updates);
|
||||
|
||||
@@ -251,9 +251,9 @@ export default defineComponent({
|
||||
};
|
||||
|
||||
const statuses = computed<Status[] | null>(() => {
|
||||
if (statusField.value && statusField.value.options) {
|
||||
return Object.keys(statusField.value.options.status_mapping).map((key: string) => ({
|
||||
...statusField.value?.options?.status_mapping[key],
|
||||
if (statusField.value && statusField.value.system.options) {
|
||||
return Object.keys(statusField.value.system.options.status_mapping).map((key: string) => ({
|
||||
...statusField.value?.system.options?.status_mapping[key],
|
||||
value: key,
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<v-list nav>
|
||||
<v-list-item :to="`/${project}/users/all`">
|
||||
<v-list-item to="/users/all">
|
||||
<v-list-item-icon><v-icon name="people" /></v-list-item-icon>
|
||||
<v-list-item-content>{{ $t('all_users') }}</v-list-item-content>
|
||||
</v-list-item>
|
||||
@@ -13,7 +13,7 @@
|
||||
</v-list-item>
|
||||
</template>
|
||||
|
||||
<v-list-item v-for="{ name, id } in roles" :key="id" :to="`/${project}/users/${id}`">
|
||||
<v-list-item v-for="{ name, id } in roles" :key="id" :to="`/users/${id}`">
|
||||
<v-list-item-icon><v-icon name="people" /></v-list-item-icon>
|
||||
<v-list-item-content>{{ name }}</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
Reference in New Issue
Block a user