Merge branch 'main' into insights

This commit is contained in:
rijkvanzanten
2021-09-17 21:41:53 -04:00
188 changed files with 2049 additions and 2139 deletions

1
.github/CODEOWNERS vendored
View File

@@ -2,6 +2,7 @@
/docs/*.md @benhaynes
/packages/sdk @joselcvarela
/packages/shared @nickrum
/packages/extensions-sdk @nickrum
/packages/create-directus-extension @nickrum

View File

@@ -1,6 +1,6 @@
{
"name": "directus",
"version": "9.0.0-rc.92",
"version": "9.0.0-rc.93",
"license": "GPL-3.0-only",
"homepage": "https://github.com/directus/directus#readme",
"description": "Directus is a real-time API and App dashboard for managing SQL database content.",
@@ -70,16 +70,16 @@
"example.env"
],
"dependencies": {
"@directus/app": "9.0.0-rc.92",
"@directus/drive": "9.0.0-rc.92",
"@directus/drive-azure": "9.0.0-rc.92",
"@directus/drive-gcs": "9.0.0-rc.92",
"@directus/drive-s3": "9.0.0-rc.92",
"@directus/extensions-sdk": "9.0.0-rc.92",
"@directus/format-title": "9.0.0-rc.92",
"@directus/schema": "9.0.0-rc.92",
"@directus/shared": "9.0.0-rc.92",
"@directus/specs": "9.0.0-rc.92",
"@directus/app": "9.0.0-rc.93",
"@directus/drive": "9.0.0-rc.93",
"@directus/drive-azure": "9.0.0-rc.93",
"@directus/drive-gcs": "9.0.0-rc.93",
"@directus/drive-s3": "9.0.0-rc.93",
"@directus/extensions-sdk": "9.0.0-rc.93",
"@directus/format-title": "9.0.0-rc.93",
"@directus/schema": "9.0.0-rc.93",
"@directus/shared": "9.0.0-rc.93",
"@directus/specs": "9.0.0-rc.93",
"@godaddy/terminus": "^4.9.0",
"@rollup/plugin-alias": "^3.1.2",
"@rollup/plugin-virtual": "^2.0.3",
@@ -183,7 +183,7 @@
"@types/json2csv": "5.0.3",
"@types/jsonwebtoken": "8.5.5",
"@types/keyv": "3.1.3",
"@types/lodash": "4.14.172",
"@types/lodash": "4.14.173",
"@types/mime-types": "2.1.1",
"@types/ms": "0.7.31",
"@types/node": "15.12.2",

View File

@@ -16,7 +16,7 @@ export function getCache(): { cache: Keyv | null; schemaCache: Keyv | null } {
}
if (env.CACHE_SCHEMA !== false && schemaCache === null) {
schemaCache = getKeyvInstance(typeof env.CACHE_SCHEMA === 'string' ? ms(env.CACHE_SCHEMA) : undefined);
schemaCache = getKeyvInstance(typeof env.CACHE_SCHEMA === 'string' ? ms(env.CACHE_SCHEMA) : undefined, '_schema');
schemaCache.on('error', (err) => logger.warn(err, `[cache] ${err}`));
}
@@ -29,21 +29,25 @@ export async function flushCaches(): Promise<void> {
await cache?.clear();
}
function getKeyvInstance(ttl: number | undefined): Keyv {
function getKeyvInstance(ttl: number | undefined, namespaceSuffix?: string): Keyv {
switch (env.CACHE_STORE) {
case 'redis':
return new Keyv(getConfig('redis', ttl));
return new Keyv(getConfig('redis', ttl, namespaceSuffix));
case 'memcache':
return new Keyv(getConfig('memcache', ttl));
return new Keyv(getConfig('memcache', ttl, namespaceSuffix));
case 'memory':
default:
return new Keyv(getConfig('memory', ttl));
return new Keyv(getConfig('memory', ttl, namespaceSuffix));
}
}
function getConfig(store: 'memory' | 'redis' | 'memcache' = 'memory', ttl: number | undefined): Options<any> {
function getConfig(
store: 'memory' | 'redis' | 'memcache' = 'memory',
ttl: number | undefined,
namespaceSuffix = ''
): Options<any> {
const config: Options<any> = {
namespace: env.CACHE_NAMESPACE,
namespace: `${env.CACHE_NAMESPACE}${namespaceSuffix}`,
ttl,
};

View File

@@ -6,41 +6,7 @@ export async function up(knex: Knex): Promise<void> {
});
await knex.schema.alterTable('directus_settings', (table) => {
table.json('module_bar').defaultTo(
JSON.stringify([
{
type: 'module',
id: 'collections',
enabled: true,
},
{
type: 'module',
id: 'users',
enabled: true,
},
{
type: 'module',
id: 'files',
enabled: true,
},
{
type: 'module',
id: 'insights',
enabled: false,
},
{
type: 'module',
id: 'docs',
enabled: true,
},
{
type: 'module',
id: 'settings',
enabled: true,
locked: true,
},
])
);
table.json('module_bar');
});
}

View File

@@ -160,10 +160,25 @@ export class AuthenticationService {
}
}
const payload = {
let payload = {
id: user.id,
};
const customClaims = await emitter.emitAsync('auth.jwt.before', payload, {
event: 'auth.jwt.before',
action: 'jwt',
schema: this.schema,
payload: payload,
accountability: this.accountability,
status: 'pending',
user: user?.id,
database: this.knex,
});
if (customClaims) {
payload = customClaims.length > 0 ? customClaims.reduce((acc, val) => merge(acc, val), payload) : payload;
}
/**
* @TODO
* Sign token with combination of server secret + user password hash

View File

@@ -19,7 +19,7 @@ export class Url {
!isProtocolRelative && !isRootRelative && !isPathRelative
? parsedUrl.protocol.substring(0, parsedUrl.protocol.length - 1)
: null;
this.host = !isRootRelative && !isPathRelative ? parsedUrl.host : null;
this.host = !isRootRelative && !isPathRelative ? parsedUrl.hostname : null;
this.port = parsedUrl.port !== '' ? parsedUrl.port : null;
this.path = parsedUrl.pathname.split('/').filter((p) => p !== '');
this.query = Object.fromEntries(parsedUrl.searchParams.entries());

View File

@@ -1,6 +1,6 @@
{
"name": "@directus/app",
"version": "9.0.0-rc.92",
"version": "9.0.0-rc.93",
"private": false,
"description": "Directus is an Open-Source Headless CMS & API for Managing Custom Databases",
"author": "Rijk van Zanten <rijkvanzanten@me.com>",
@@ -27,10 +27,10 @@
},
"gitHead": "24621f3934dc77eb23441331040ed13c676ceffd",
"devDependencies": {
"@directus/docs": "9.0.0-rc.92",
"@directus/extensions-sdk": "9.0.0-rc.92",
"@directus/format-title": "9.0.0-rc.92",
"@directus/shared": "9.0.0-rc.92",
"@directus/docs": "9.0.0-rc.93",
"@directus/extensions-sdk": "9.0.0-rc.93",
"@directus/format-title": "9.0.0-rc.93",
"@directus/shared": "9.0.0-rc.93",
"@fullcalendar/core": "5.9.0",
"@fullcalendar/daygrid": "5.9.0",
"@fullcalendar/interaction": "5.9.0",
@@ -38,7 +38,7 @@
"@fullcalendar/timegrid": "5.9.0",
"@mapbox/mapbox-gl-draw": "1.3.0",
"@mapbox/mapbox-gl-draw-static-mode": "1.0.1",
"@mapbox/mapbox-gl-geocoder": "4.7.3",
"@mapbox/mapbox-gl-geocoder": "4.7.4",
"@popperjs/core": "2.9.3",
"@rollup/plugin-yaml": "3.1.0",
"@sindresorhus/slugify": "2.1.0",
@@ -52,7 +52,7 @@
"@types/diff": "5.0.1",
"@types/dompurify": "2.2.3",
"@types/geojson": "7946.0.8",
"@types/lodash": "4.14.172",
"@types/lodash": "4.14.173",
"@types/mapbox__mapbox-gl-draw": "1.2.3",
"@types/mapbox__mapbox-gl-geocoder": "4.7.1",
"@types/markdown-it": "12.2.1",
@@ -67,14 +67,14 @@
"@vue/cli-plugin-typescript": "4.5.13",
"@vue/cli-plugin-vuex": "4.5.13",
"@vue/cli-service": "4.5.13",
"@vue/compiler-sfc": "3.2.11",
"@vue/compiler-sfc": "3.2.12",
"apexcharts": "3.26.3",
"axios": "0.21.4",
"base-64": "1.0.0",
"codemirror": "5.62.3",
"copyfiles": "2.4.1",
"cropperjs": "1.5.12",
"date-fns": "2.23.0",
"date-fns": "2.24.0",
"diacritics": "1.3.0",
"dompurify": "2.3.2",
"escape-string-regexp": "5.0.0",
@@ -89,15 +89,15 @@
"nanoid": "3.1.25",
"p-queue": "7.1.0",
"pinia": "2.0.0-rc.9",
"prettier": "2.4.0",
"prettier": "2.4.1",
"pretty-ms": "7.0.1",
"qrcode": "1.4.4",
"rimraf": "3.0.2",
"sass": "1.41.0",
"sass": "1.41.1",
"tinymce": "5.9.2",
"typescript": "4.4.3",
"vite": "2.5.7",
"vue": "3.2.11",
"vite": "2.5.8",
"vue": "3.2.12",
"vue-i18n": "9.1.7",
"vue-router": "4.0.11",
"vuedraggable": "4.1.0",

View File

@@ -20,6 +20,7 @@
tile,
'full-width': fullWidth,
},
kind,
]"
:type="type"
:disabled="disabled"
@@ -55,6 +56,10 @@ export default defineComponent({
type: Boolean,
default: false,
},
kind: {
type: String as PropType<'normal' | 'info' | 'success' | 'warning' | 'danger'>,
default: 'normal',
},
fullWidth: {
type: Boolean,
default: false,
@@ -172,7 +177,6 @@ export default defineComponent({
return false;
});
return { sizeClass, onClick, component, isActiveRoute, toggle };
function onClick(event: MouseEvent) {
@@ -203,9 +207,36 @@ export default defineComponent({
--v-button-min-width: 140px;
}
.v-button {
display: inline-flex;
align-items: center;
.info {
--v-button-color: var(--white);
--v-button-color-hover: var(--white);
--v-button-background-color: var(--blue);
--v-button-background-color-hover: var(--blue-125);
--v-button-background-color-active: var(--blue);
}
.success {
--v-button-color: var(--white);
--v-button-color-hover: var(--white);
--v-button-background-color: var(--success);
--v-button-background-color-hover: var(--success-125);
--v-button-background-color-active: var(--success);
}
.warning {
--v-button-color: var(--white);
--v-button-color-hover: var(--white);
--v-button-background-color: var(--warning);
--v-button-background-color-hover: var(--warning-125);
--v-button-background-color-active: var(--warning);
}
.danger {
--v-button-color: var(--white);
--v-button-color-hover: var(--white);
--v-button-background-color: var(--danger);
--v-button-background-color-hover: var(--danger-125);
--v-button-background-color-active: var(--danger);
}
.secondary {
@@ -224,11 +255,6 @@ export default defineComponent({
--v-button-color-disabled: var(--foreground-normal);
}
.warning {
--v-button-background-color: var(--warning);
--v-button-background-color-hover: var(--warning-125);
}
.warning.rounded {
--v-button-background-color: var(--warning-10);
--v-button-color: var(--warning);
@@ -236,11 +262,6 @@ export default defineComponent({
--v-button-color-hover: var(--warning);
}
.danger {
--v-button-background-color: var(--danger);
--v-button-background-color-hover: var(--danger-125);
}
.danger.rounded {
--v-button-background-color: var(--danger-10);
--v-button-color: var(--danger);

View File

@@ -21,7 +21,7 @@
<script lang="ts">
import { defineComponent, computed } from 'vue';
import useSync from '@/composables/use-sync';
import { useSync } from '@directus/shared/composables';
export default defineComponent({
props: {

View File

@@ -45,11 +45,10 @@
import { useI18n } from 'vue-i18n';
import { defineComponent, toRefs, ref, PropType, computed } from 'vue';
import FieldListItem from '../v-field-template/field-list-item.vue';
import { Collection, Relation } from '@/types';
import { Field } from '@directus/shared/types';
import { Field, Collection, Relation } from '@directus/shared/types';
import Draggable from 'vuedraggable';
import useFieldTree from '@/composables/use-field-tree';
import useCollection from '@/composables/use-collection';
import { useCollection } from '@directus/shared/composables';
import { FieldTree } from '../v-field-template/types';
import hideDragImage from '@/utils/hide-drag-image';

View File

@@ -33,8 +33,7 @@ import { defineComponent, toRefs, ref, watch, onMounted, onUnmounted, PropType }
import FieldListItem from './field-list-item.vue';
import useFieldTree from '@/composables/use-field-tree';
import { FieldTree } from './types';
import { Relation } from '@/types';
import { Field } from '@directus/shared/types';
import { Field, Relation } from '@directus/shared/types';
export default defineComponent({
components: { FieldListItem },

View File

@@ -1,4 +0,0 @@
import { useCollection } from './use-collection';
export { useCollection };
export default useCollection;

View File

@@ -1,7 +1,6 @@
import { useCollectionsStore, useFieldsStore, useRelationsStore } from '@/stores/';
import { Relation } from '@/types';
import { Field } from '@directus/shared/types';
import { getRelationType } from '@/utils/get-relation-type';
import { Field, Relation } from '@directus/shared/types';
import { getRelationType } from '@directus/shared/utils';
import { cloneDeep, orderBy } from 'lodash';
import { Ref, ref, watch } from 'vue';

View File

@@ -1,5 +1,5 @@
import api from '@/api';
import useCollection from '@/composables/use-collection';
import { useCollection } from '@directus/shared/composables';
import { VALIDATION_TYPES } from '@/constants';
import { i18n } from '@/lang';
import { APIError } from '@/types';
@@ -322,6 +322,7 @@ export function useItem(collection: Ref<string>, primaryKey: Ref<string | number
const conditions = [...field.meta.conditions].reverse();
const matchingCondition = conditions.find((condition) => {
if (!condition.rule || Object.keys(condition.rule).length !== 1) return;
const errors = validatePayload(condition.rule, item, { requireAll: true });
return errors.length === 0;
});

View File

@@ -1,4 +0,0 @@
import { useItems } from './use-items';
export { useItems };
export default useItems;

View File

@@ -3,7 +3,7 @@ import { Field } from '@directus/shared/types';
import { computed, ComputedRef, Ref } from 'vue';
import { cloneDeep } from 'lodash';
import { isAllowed } from '../utils/is-allowed';
import { useCollection } from './use-collection';
import { useCollection } from '@directus/shared/composables';
type UsablePermissions = {
deleteAllowed: ComputedRef<boolean>;

View File

@@ -1,4 +1,4 @@
import { useCollection } from '@/composables/use-collection';
import { useCollection } from '@directus/shared/composables';
import { usePresetsStore, useUserStore } from '@/stores';
import { Filter, Preset } from '@directus/shared/types';
import { debounce, isEqual } from 'lodash';

View File

@@ -1,4 +0,0 @@
import useSync from './use-sync';
export { useSync };
export default useSync;

View File

@@ -1,31 +0,0 @@
# Use Sync
```ts
function useSync<T, K extends keyof T>(
props: T,
key: K,
emit: (event: string, ...args: any[]) => void
): Ref<Readonly<T[K]>>;
```
Small utility composition that allows you to easily setup the two-way binding with the prop:
```ts
// Before
const internalOptions = computed({
get() {
return props.options;
},
set(val) {
emit('update:options', val);
},
});
```
```ts
// after
const internalOptions = useSync(props, 'options', emit);
```

View File

@@ -1,6 +1,6 @@
import api from '@/api';
import { Collection } from '@/types';
import { getFieldsFromTemplate } from '@/utils/get-fields-from-template';
import { Collection } from '@directus/shared/types';
import { getFieldsFromTemplate } from '@directus/shared/utils';
import { computed, Ref, ref, watch } from 'vue';
type UsableTemplateData = {

View File

@@ -35,3 +35,37 @@ export const COLLECTIONS_DENY_LIST = [
'directus_sessions',
'directus_settings',
];
export const MODULE_BAR_DEFAULT = [
{
type: 'module',
id: 'collections',
enabled: true,
},
{
type: 'module',
id: 'users',
enabled: true,
},
{
type: 'module',
id: 'files',
enabled: true,
},
{
type: 'module',
id: 'insights',
enabled: false,
},
{
type: 'module',
id: 'docs',
enabled: true,
},
{
type: 'module',
id: 'settings',
enabled: true,
locked: true,
},
];

View File

@@ -8,7 +8,7 @@
<script lang="ts">
import { defineComponent, toRefs } from 'vue';
import useCollection from '@/composables/use-collection';
import { useCollection } from '@directus/shared/composables';
export default defineComponent({
props: {

View File

@@ -1,6 +1,13 @@
<template>
<v-icon v-if="imgError" name="" />
<img v-else-if="src" :src="src" role="presentation" :alt="value && value.title" :class="{ circle }" />
<v-icon v-if="imageError" name="image" />
<img
v-else-if="src"
:src="src"
role="presentation"
:alt="value && value.title"
:class="{ circle }"
@error="imageError = true"
/>
<value-null v-else />
</template>
@@ -29,7 +36,7 @@ export default defineComponent({
},
},
setup(props) {
const imgError = ref(false);
const imageError = ref(false);
const src = computed(() => {
if (props.value === null) return null;
@@ -37,7 +44,7 @@ export default defineComponent({
return addTokenToURL(url);
});
return { src, imgError };
return { src, imageError };
},
});
</script>

View File

@@ -1,11 +1,10 @@
import useCollection from '@/composables/use-collection';
import { defineDisplay } from '@directus/shared/utils';
import adjustFieldsForDisplays from '@/utils/adjust-fields-for-displays';
import { getFieldsFromTemplate } from '@/utils/get-fields-from-template';
import { getFieldsFromTemplate } from '@directus/shared/utils';
import getRelatedCollection from '@/utils/get-related-collection';
import { ref } from 'vue';
import options from './options.vue';
import DisplayRelatedValues from './related-values.vue';
import { useFieldsStore } from '@/stores';
type Options = {
template: string;
@@ -22,7 +21,8 @@ export default defineDisplay({
groups: ['m2m', 'm2o', 'o2m'],
fields: (options: Options | null, { field, collection }) => {
const relatedCollection = getRelatedCollection(collection, field);
const { primaryKeyField } = useCollection(ref(relatedCollection as unknown as string));
const fieldsStore = useFieldsStore();
const primaryKeyField = fieldsStore.getPrimaryKeyFieldForCollection(relatedCollection);
if (!relatedCollection) return [];
@@ -30,8 +30,8 @@ export default defineDisplay({
? adjustFieldsForDisplays(getFieldsFromTemplate(options.template), relatedCollection as unknown as string)
: [];
if (primaryKeyField.value && !fields.includes(primaryKeyField.value.field)) {
fields.push(primaryKeyField.value.field);
if (primaryKeyField && !fields.includes(primaryKeyField.field)) {
fields.push(primaryKeyField.field);
}
return fields;

View File

@@ -12,8 +12,7 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { Relation } from '@/types';
import { Field } from '@directus/shared/types';
import { Field, Relation } from '@directus/shared/types';
import { defineComponent, PropType, computed } from 'vue';
export default defineComponent({

View File

@@ -31,9 +31,9 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { defineComponent, computed, PropType, Ref } from 'vue';
import { defineComponent, computed, PropType } from 'vue';
import getRelatedCollection from '@/utils/get-related-collection';
import useCollection from '@/composables/use-collection';
import { useCollection } from '@directus/shared/composables';
import ValueNull from '@/views/private/components/value-null';
export default defineComponent({
@@ -67,12 +67,7 @@ export default defineComponent({
return getRelatedCollection(props.collection, props.field);
});
const primaryKeyField = computed(() => {
if (relatedCollection.value !== null) {
return useCollection(relatedCollection as unknown as Ref<string>).primaryKeyField.value;
}
return null;
});
const { primaryKeyField } = useCollection(relatedCollection);
const internalTemplate = computed(() => {
return props.template || `{{ ${primaryKeyField.value!.field} }}`;

View File

@@ -58,7 +58,7 @@
<v-error v-if="error" :error="error" />
</v-card-text>
<v-card-actions>
<v-button type="submit" class="disable" :loading="loading" :disabled="otp.length !== 6">
<v-button type="submit" kind="warning" :loading="loading" :disabled="otp.length !== 6">
{{ t('disable_tfa') }}
</v-button>
</v-card-actions>
@@ -237,11 +237,6 @@ export default defineComponent({
text-align: center;
}
.disable {
--v-button-background-color: var(--warning);
--v-button-background-color-hover: var(--warning-125);
}
.v-error {
margin-top: 24px;
}

View File

@@ -68,6 +68,7 @@ import { assign } from 'lodash';
import { useI18n } from 'vue-i18n';
import { nanoid } from 'nanoid';
import { Field, DeepPartial } from '@directus/shared/types';
import { MODULE_BAR_DEFAULT } from '@/constants';
type PreviewExtra = {
to: string;
@@ -118,7 +119,7 @@ export default defineComponent({
props: {
value: {
type: Array as PropType<Settings['module_bar']>,
default: () => [],
default: () => MODULE_BAR_DEFAULT,
},
},
emits: ['input'],
@@ -145,12 +146,12 @@ export default defineComponent({
const valuesWithData = computed<PreviewValue[]>({
get() {
const savedModules = (props.value.filter((value) => value.type === 'module') as SettingsModuleBarModule[]).map(
(value) => value.id
);
const savedModules = (
(props.value ?? MODULE_BAR_DEFAULT).filter((value) => value.type === 'module') as SettingsModuleBarModule[]
).map((value) => value.id);
return valueToPreview([
...props.value,
...(props.value ?? MODULE_BAR_DEFAULT),
...availableModulesAsBarModule.value.filter(
(availableModuleAsBarModule) => savedModules.includes(availableModuleAsBarModule.id) === false
),
@@ -230,7 +231,7 @@ export default defineComponent({
let value: SettingsModuleBarLink;
if (id !== '+') {
value = props.value.find((val) => val.id === id) as SettingsModuleBarLink;
value = (props.value ?? MODULE_BAR_DEFAULT).find((val) => val.id === id) as SettingsModuleBarLink;
} else {
value = {
id: nanoid(),
@@ -248,11 +249,11 @@ export default defineComponent({
function save() {
if (editing.value === '+') {
emit('input', [...props.value, values.value]);
emit('input', [...(props.value ?? MODULE_BAR_DEFAULT), values.value]);
} else {
emit(
'input',
props.value.map((val) => (val.id === editing.value ? values.value : val))
(props.value ?? MODULE_BAR_DEFAULT).map((val) => (val.id === editing.value ? values.value : val))
);
}
@@ -263,7 +264,7 @@ export default defineComponent({
function remove(id: string) {
emit(
'input',
props.value.filter((val) => val.id !== id)
(props.value ?? MODULE_BAR_DEFAULT).filter((val) => val.id !== id)
);
}
},

View File

@@ -7,7 +7,14 @@
</v-notice>
<div v-else-if="image" class="image-preview" :class="{ 'is-svg': image.type && image.type.includes('svg') }">
<img :src="src" alt="" role="presentation" />
<div v-if="imageError" class="image-error">
<v-icon large :name="imageError === 'UNKNOWN' ? 'error_outline' : 'info_outline'" />
<span class="message">
{{ t(`errors.${imageError}`) }}
</span>
</div>
<img v-else :src="src" alt="" role="presentation" @error="imageErrorHandler" />
<div class="shadow" />
@@ -85,12 +92,13 @@ export default defineComponent({
},
emits: ['input'],
setup(props, { emit }) {
const { t, n } = useI18n();
const { t, n, te } = useI18n();
const loading = ref(false);
const image = ref<Image | null>(null);
const lightboxActive = ref(false);
const editDrawerActive = ref(false);
const imageError = ref<string | null>(null);
const cacheBuster = ref(nanoid());
@@ -147,6 +155,8 @@ export default defineComponent({
loading,
image,
src,
imageError,
imageErrorHandler,
meta,
lightboxActive,
editDrawerActive,
@@ -185,6 +195,19 @@ export default defineComponent({
}
}
async function imageErrorHandler() {
if (!src.value) return;
try {
await api.get(src.value);
} catch (err: any) {
imageError.value = err.response?.data?.errors[0]?.extensions?.code;
if (!imageError.value || !te('errors.' + imageError.value)) {
imageError.value = 'UNKNOWN';
}
}
}
function changeCacheBuster() {
cacheBuster.value = nanoid();
}
@@ -255,6 +278,27 @@ img {
}
}
.image-error {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
// width: 100%;
height: 100%;
color: var(--foreground-subdued);
background-color: var(--background-normal);
.v-icon {
margin-bottom: 6px;
}
.message {
max-width: 300px;
padding: 0 16px;
text-align: center;
}
}
.shadow {
position: absolute;
bottom: 0;

View File

@@ -140,12 +140,12 @@
import { useI18n } from 'vue-i18n';
import { defineComponent, computed, PropType, ref, watch } from 'vue';
import { useRelationsStore, useCollectionsStore, useFieldsStore } from '@/stores';
import { Relation, Collection } from '@/types';
import { Collection, Relation } from '@directus/shared/types';
import DrawerCollection from '@/views/private/components/drawer-collection/';
import DrawerItem from '@/views/private/components/drawer-item/';
import api from '@/api';
import { unexpectedError } from '@/utils/unexpected-error';
import { getFieldsFromTemplate } from '@/utils/get-fields-from-template';
import { getFieldsFromTemplate } from '@directus/shared/utils';
import { isPlainObject, cloneDeep } from 'lodash';
import { getEndpoint } from '@/utils/get-endpoint';
import { hideDragImage } from '@/utils/hide-drag-image';

View File

@@ -101,7 +101,7 @@ import usePreview from './use-preview';
import useEdit from './use-edit';
import useSelection from './use-selection';
import useSort from './use-sort';
import { getFieldsFromTemplate } from '@/utils/get-fields-from-template';
import { getFieldsFromTemplate } from '@directus/shared/utils';
import adjustFieldsForDisplays from '@/utils/adjust-fields-for-displays';
import { usePermissionsStore, useUserStore } from '@/stores';

View File

@@ -30,8 +30,7 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { Relation, Collection } from '@/types';
import { Field } from '@directus/shared/types';
import { Field, Collection, Relation } from '@directus/shared/types';
import { defineComponent, PropType, computed } from 'vue';
import { useCollectionsStore } from '@/stores';
export default defineComponent({

View File

@@ -1,7 +1,6 @@
import useCollection from '@/composables/use-collection';
import { useCollection } from '@directus/shared/composables';
import { useCollectionsStore, useRelationsStore } from '@/stores/';
import { Collection, Relation } from '@/types';
import { Field } from '@directus/shared/types';
import { Field, Collection, Relation } from '@directus/shared/types';
import { computed, ComputedRef, Ref } from 'vue';
export type RelationInfo = {

View File

@@ -50,14 +50,13 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { defineComponent, ref, computed, PropType, onMounted, watch } from 'vue';
import { useCollection } from '@/composables/use-collection';
import { useCollection } from '@directus/shared/composables';
import { useRelationsStore } from '@/stores';
import api from '@/api';
import { getFieldsFromTemplate } from '@/utils/get-fields-from-template';
import { getFieldsFromTemplate } from '@directus/shared/utils';
import hideDragImage from '@/utils/hide-drag-image';
import NestedDraggable from './nested-draggable.vue';
import { Filter } from '@directus/shared/types';
import { Relation } from '@/types';
import { Filter, Relation } from '@directus/shared/types';
import DrawerCollection from '@/views/private/components/drawer-collection';
import DrawerItem from '@/views/private/components/drawer-item';

View File

@@ -22,8 +22,7 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { Relation } from '@/types';
import { Field } from '@directus/shared/types';
import { Field, Relation } from '@directus/shared/types';
import { defineComponent, PropType, computed } from 'vue';
export default defineComponent({
props: {

View File

@@ -82,16 +82,15 @@
import { useI18n } from 'vue-i18n';
import { defineComponent, ref, computed, watch, PropType } from 'vue';
import api from '@/api';
import useCollection from '@/composables/use-collection';
import { useCollection } from '@directus/shared/composables';
import { useCollectionsStore, useRelationsStore, useFieldsStore, usePermissionsStore, useUserStore } from '@/stores/';
import DrawerItem from '@/views/private/components/drawer-item';
import DrawerCollection from '@/views/private/components/drawer-collection';
import { Relation } from '@/types';
import { Filter, Field } from '@directus/shared/types';
import { Filter, Field, Relation } from '@directus/shared/types';
import { isEqual, sortBy } from 'lodash';
import { get } from 'lodash';
import { unexpectedError } from '@/utils/unexpected-error';
import { getFieldsFromTemplate } from '@/utils/get-fields-from-template';
import { getFieldsFromTemplate } from '@directus/shared/utils';
import { addRelatedPrimaryKeyToFields } from '@/utils/add-related-primary-key-to-fields';
import Draggable from 'vuedraggable';
import adjustFieldsForDisplays from '@/utils/adjust-fields-for-displays';

View File

@@ -30,8 +30,7 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { Relation, Collection } from '@/types';
import { Field } from '@directus/shared/types';
import { Field, Collection, Relation } from '@directus/shared/types';
import { defineComponent, PropType, computed } from 'vue';
import { useCollectionsStore } from '@/stores/';

View File

@@ -31,8 +31,8 @@
</v-notice>
<template #append>
<v-card-actions>
<v-button small class="soft-reset" secondary @click="resetValue(false)">{{ t('continue') }}</v-button>
<v-button small class="hard-reset" @click="resetValue(true)">{{ t('reset') }}</v-button>
<v-button small secondary @click="resetValue(false)">{{ t('continue') }}</v-button>
<v-button small kind="danger" @click="resetValue(true)">{{ t('reset') }}</v-button>
</v-card-actions>
</template>
</v-info>
@@ -456,11 +456,4 @@ export default defineComponent({
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.v-button.hard-reset {
--v-button-background-color: var(--danger-10);
--v-button-color: var(--danger);
--v-button-background-color-hover: var(--danger-25);
--v-button-color-hover: var(--danger);
}
</style>

View File

@@ -12,8 +12,7 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { Relation } from '@/types';
import { Field } from '@directus/shared/types';
import { Field, Relation } from '@directus/shared/types';
import { defineComponent, PropType, computed } from 'vue';
export default defineComponent({

View File

@@ -89,8 +89,8 @@
import { useI18n } from 'vue-i18n';
import { defineComponent, computed, ref, toRefs, watch, PropType } from 'vue';
import { useCollectionsStore, useRelationsStore } from '@/stores/';
import useCollection from '@/composables/use-collection';
import { getFieldsFromTemplate } from '@/utils/get-fields-from-template';
import { useCollection } from '@directus/shared/composables';
import { getFieldsFromTemplate } from '@directus/shared/utils';
import api from '@/api';
import DrawerItem from '@/views/private/components/drawer-item';
import DrawerCollection from '@/views/private/components/drawer-collection';
@@ -336,11 +336,9 @@ export default defineComponent({
return collectionsStore.getCollection(relation.value.related_collection)!;
});
const relatedPrimaryKeyField = computed(() => {
if (!relatedCollection.value?.collection) return null;
const { primaryKeyField } = useCollection(relatedCollection.value?.collection);
return primaryKeyField.value;
});
const relatedCollectionName = computed(() => relatedCollection.value?.collection ?? null);
const { primaryKeyField: relatedPrimaryKeyField } = useCollection(relatedCollectionName);
return { relation, relatedCollection, relatedPrimaryKeyField };
}

View File

@@ -12,8 +12,7 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { Relation } from '@/types';
import { Field } from '@directus/shared/types';
import { Field, Relation } from '@directus/shared/types';
import { defineComponent, PropType, computed } from 'vue';
import { useFieldsStore } from '@/stores/';

View File

@@ -49,11 +49,11 @@
<script lang="ts">
import LanguageSelect from './language-select.vue';
import { computed, defineComponent, PropType, Ref, ref, toRefs, watch, unref } from 'vue';
import useCollection from '@/composables/use-collection';
import { useFieldsStore, useRelationsStore } from '@/stores/';
import { useI18n } from 'vue-i18n';
import api from '@/api';
import { Relation } from '@/types';
import { Relation } from '@directus/shared/types';
import { useCollection } from '@directus/shared/composables';
import { unexpectedError } from '@/utils/unexpected-error';
import { cloneDeep, isEqual, assign } from 'lodash';
import { notEmpty } from '@/utils/is-empty';
@@ -367,9 +367,7 @@ export default defineComponent({
}
async function loadItems() {
const pkField = translationsPrimaryKeyField.value;
if (pkField === null || !props.value || props.value.length === 0) return;
if (!translationsRelation.value?.field) return;
loading.value = true;
@@ -379,8 +377,8 @@ export default defineComponent({
fields: '*',
limit: -1,
filter: {
[pkField]: {
_in: props.value,
[translationsRelation.value.field]: {
_eq: props.primaryKey,
},
},
},

View File

@@ -25,6 +25,7 @@ ko-KR: Korean (Korea)
lt-LT: Lithuanian (Lithuania)
ms-MY: Malay (Malaysia)
no-NO: Norwegian (Norway)
fa-IR: Farci (Iran)
pl-PL: Polish (Poland)
pt-BR: Portuguese (Brazil)
pt-PT: Portuguese (Portugal)

View File

@@ -419,9 +419,9 @@ errors:
RECORD_NOT_UNIQUE: تم اكتشاف تكرار القيمة
USER_SUSPENDED: المستخدم موقوف
CONTAINS_NULL_VALUES: الحقل يحتوي على قيم فارغة
UNKNOWN: خطأ غير متوقع
INTERNAL_SERVER_ERROR: خطأ غير متوقع
NOT_NULL_VIOLATION: لا يمكن أن تكون القيمة فارغة
UNKNOWN: خطأ غير متوقع
security: الأمان
value_hashed: تم تجزئة القيمة بشكل آمن
bookmark_name: اسم الإشارة المرجعية...

View File

@@ -424,10 +424,10 @@ errors:
RECORD_NOT_UNIQUE: Вече съществува такава стойност
USER_SUSPENDED: Потребителя е деактивиран
CONTAINS_NULL_VALUES: Полето съдържа null стойност
UNKNOWN: Неочаквана грешка
UNPROCESSABLE_ENTITY: Необработен обект
INTERNAL_SERVER_ERROR: Неочаквана грешка
NOT_NULL_VIOLATION: Стойността не трябва да е null
UNKNOWN: Неочаквана грешка
security: Сигурност
value_hashed: Хеширана стойност
bookmark_name: Име на отметка...

View File

@@ -423,10 +423,10 @@ errors:
RECORD_NOT_UNIQUE: Valor duplicat detectat
USER_SUSPENDED: Usuari suspès
CONTAINS_NULL_VALUES: El camp conté valors nuls
UNKNOWN: Error inesperat
UNPROCESSABLE_ENTITY: Entitat no processable
INTERNAL_SERVER_ERROR: Error inesperat
NOT_NULL_VIOLATION: El valor no pot ser null
UNKNOWN: Error inesperat
security: Seguretat
value_hashed: Aplicat hash segur al valor
bookmark_name: Nom del marcador...

View File

@@ -1,11 +1,35 @@
---
## Be aware:
#Due to the way this is imported, JavaScript reserved words, including "delete", "private",
#"void", etc are stripped out. See
#https://github.com/rollup/plugins/blob/8748b8cd3bbab3c5ac6190556930219f19060e63/packages/pluginutils/src/makeLegalIdentifier.ts#L4
#and
#https://github.com/rollup/plugins/blob/8748b8cd3bbab3c5ac6190556930219f19060e63/packages/yaml/src/index.js#L45
#Illegal words:
#'break', 'case', 'class', 'catch', 'const', 'continue', 'debugger', 'default', 'delete', 'do',
#'else', 'export', 'extends', 'finally', 'for', 'function', 'if', 'import', 'in', 'instanceof',
#'let', 'new', 'return', 'super', 'switch', 'this', 'throw', 'try', 'typeof', 'var', 'void',
#'while', 'with', 'yield', 'enum', 'await', 'implements', 'package', 'protected', 'static',
#'interface', 'private', 'public', 'arguments', 'Infinity', 'NaN', 'undefined', 'null', 'true',
#'false', 'eval', 'uneval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'decodeURI',
#'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape', 'unescape', 'Object',
#'Function', 'Boolean', 'Symbol', 'Error', 'EvalError', 'InternalError', 'RangeError',
#'ReferenceError', 'SyntaxError', 'TypeError', 'URIError', 'Number', 'Math', 'Date', 'String',
#'RegExp', 'Array', 'Int8Array', 'Uint8Array', 'Uint8ClampedArray', 'Int16Array', 'Uint16Array',
#'Int32Array', 'Uint32Array', 'Float32Array', 'Float64Array', 'Map', 'Set', 'WeakMap', 'WeakSet',
#'SIMD', 'ArrayBuffer', 'DataView', 'JSON', 'Promise', 'Generator', 'GeneratorFunction', 'Reflect',
#'Proxy', 'Intl'
published: Zveřejněno
tile_size: Velikost dlaždice
edit_field: Upravit pole
conditions: Podmínky
maps: Mapy
item_revision: Revize položky
enter_a_name: Zadejte název...
duplicate_field: Duplikovat pole
half_width: Poloviční šířka
full_width: Plná šířka
limit: Limit
group: Skupina
and: A
or: Nebo
@@ -18,6 +42,7 @@ branch: Větev
leaf: List
indeterminate: Neurčitý
edit_collection: Upravit kolekci
exclusive: Exkluzivní
children: Potomci
db_only_click_to_configure: 'Pouze databáze: Klikněte pro nastavení '
show_archived_items: Zobrazit archivované položky
@@ -30,6 +55,8 @@ create_role: Vytvořit roli
create_user: Vytvořit uživatele
create_webhook: Vytvořit webhook
invite_users: Pozvat uživatele
email_examples: "admin{'@'}stranka.cz, user{'@'}stranka.cz..."
url_example: "https://stranka.cz"
invite: Pozvat
email_already_invited: E-mail "{email}" již byl pozván
emails: E-mail

View File

@@ -22,10 +22,13 @@
published: Veröffentlicht
draft: Entwurf
archived: Archiviert
module_bar: Modulleiste
tile_size: Kachelgröße
edit_field: Feld bearbeiten
conditions: Bedingungen
maps: Karten
item_revision: Element Revision
enter_a_name: Namen eingeben...
duplicate_field: Feld duplizieren
half_width: Halbe Breite
full_width: Volle Breite
@@ -56,6 +59,7 @@ create_user: Benutzer erstellen
create_webhook: Webhook erstellen
invite_users: Benutzer einladen
email_examples: "admin{'@'}beispiel.de, benutzer{'@'}beispiel.de..."
url_example: "https://example.com"
invite: Einladen
email_already_invited: E-Mail "{email}" wurde bereits eingeladen
emails: E-Mails
@@ -145,6 +149,9 @@ fields_for_role: 'Felder die von der {role} Rolle {action} werden können.'
validation_for_role: 'Feld {action} Regeln welche durch die {role} Rolle befolgt werden muss.'
presets_for_role: 'Feld Voreinstellungen für die {role} Rolle.'
presentation_and_aliases: Darstellung & Aliasse
revision_post_update: So sieht dieses Element nach dem Update aus.
changes_made: Dies sind die spezifischen Änderungen, die in dieser Revision vorgenommen wurden.
no_relational_data: Beachten Sie, dass relationale Daten hier nicht enthalten sind.
hide_field_on_detail: In Detailansicht ausblenden
show_field_on_detail: In Detailansicht einblenden
delete_field: Feld löschen
@@ -211,6 +218,8 @@ add_m2m_to_collection: 'n:m zu "{collection}" hinzufügen'
choose_a_type: Wähle einen Typ...
determined_by_relationship: Bestimmt durch Beziehung
add_note: Füge eine hilfreiche Beschreibung für die Benutzer hinzu...
add_link: Verknüpfung hinzufügen
custom_link: Benutzerdefinierte Verknüpfung
default_value: Standardwert
standard_field: Standardfeld
single_file: Eine Datei
@@ -382,6 +391,7 @@ no_files_copy: Keine Dateien vorhanden.
user_count: 'Keine Benutzer | Ein Benutzer | {count} Benutzer'
no_users_copy: Es gibt noch keine Benutzer in dieser Rolle.
webhooks_count: 'Keine Webhooks | Ein Webhook | {count} Webhooks'
no_webhooks_copy: Es wurden noch keine Webhooks erstellt. Beginnen Sie.
all_items: Alle Elemente
any: Irgendein
csv: CSV
@@ -445,10 +455,10 @@ errors:
RECORD_NOT_UNIQUE: Doppelter Wert erkannt
USER_SUSPENDED: Benutzer gesperrt
CONTAINS_NULL_VALUES: Feld enthält NULL-Werte
UNKNOWN: Unerwarteter Fehler
UNPROCESSABLE_ENTITY: Unverarbeitbares Objekt
INTERNAL_SERVER_ERROR: Unerwarteter Fehler
NOT_NULL_VIOLATION: Der Wert darf nicht leer sein
UNKNOWN: Unerwarteter Fehler
security: Sicherheit
value_hashed: Wert sicher gehashed
bookmark_name: Name des Lesezeichens...
@@ -729,6 +739,22 @@ collections: Sammlungen
singleton: Einzelnes Element
singleton_label: Als einzelnes Objekt behandeln
system_fields_locked: Systemfelder sind gesperrt und können nicht bearbeitet werden
directus_collection:
directus_activity: Verantwortungsprotokoll für alle Ereignisse
directus_collections: Weitere Konfiguration und Metadaten
directus_fields: Weitere Felder und Metadaten
directus_files: Metadaten für alle verwalteten Anlagen
directus_folders: Stellt virtuelle Verzeichnisse für Dateien bereit
directus_migrations: Welche Version der Datenbank verwenden Sie
directus_permissions: Zugriffsrechte für jede Rolle
directus_presets: Voreinstellungen für Sammlung und Lesezeichen
directus_relations: Relationen und Metadaten
directus_revisions: Speicherabzug für alle Aktivitäten
directus_roles: Berechtigungsgruppen für Systembenutzer
directus_sessions: Sitzungsinformation
directus_settings: Projektkonfiguration
directus_users: Systembenutzer für die Plattform
directus_webhooks: Konfiguration für ereignisbasierte HTTP-Anfragen
fields:
directus_activity:
item: Item-Primärschlüssel
@@ -959,6 +985,7 @@ field_options:
actions_delete: Löschen
actions_login: Login
no_fields_in_collection: 'Es gibt noch keine Felder in "{collection}"'
no_value: Kein Wert
do_nothing: Keine Aktion
generate_and_save_uuid: UUID generieren und speichern
save_current_user_id: Aktuelle Benutzer-ID speichern
@@ -1247,6 +1274,8 @@ interfaces:
translations:
display_template: Anzeigevorlage
no_collection: Keine Sammlung
toggle_split_view: Teil-Ansicht umschalten
language_field: Sprachfeld
list-o2m-tree-view:
description: Baumansicht für verschachtelte rekursive 1:n-Elemente
recursive_only: Die Baumansicht funktioniert nur für rekursive Beziehungen.
@@ -1402,3 +1431,5 @@ layouts:
invalid_geometry: Ungültige Geometrie
auto_location_filter: Daten immer filtern, um Grenzen anzuzeigen
search_this_area: Diesen Bereich durchsuchen
clear_data_filter: Datenfilter löschen
clear_location_filter: Standortfilter löschen

View File

@@ -488,10 +488,11 @@ errors:
RECORD_NOT_UNIQUE: Duplicate value detected
USER_SUSPENDED: User Suspended
CONTAINS_NULL_VALUES: Field contains null values
UNKNOWN: Unexpected Error
UNPROCESSABLE_ENTITY: Unprocessable entity
INTERNAL_SERVER_ERROR: Unexpected Error
NOT_NULL_VIOLATION: Value can't be null
ILLEGAL_ASSET_TRANSFORMATION: Image source too large to preview
UNKNOWN: Unexpected Error
security: Security
value_hashed: Value Securely Hashed
bookmark_name: Bookmark name...

View File

@@ -413,10 +413,10 @@ errors:
RECORD_NOT_UNIQUE: Se ha detectado un valor duplicado
USER_SUSPENDED: Usuario Suspendido
CONTAINS_NULL_VALUES: El campo contiene valores nulos
UNKNOWN: Error Inesperado
UNPROCESSABLE_ENTITY: Entidad no procesable
INTERNAL_SERVER_ERROR: Error Inesperado
NOT_NULL_VIOLATION: El valor no puede ser nulo
UNKNOWN: Error Inesperado
value_hashed: Valor Hasheado de Manera Segura
bookmark_name: Nombre del Marcador...
create_bookmark: Crear Marcador

View File

@@ -413,10 +413,10 @@ errors:
RECORD_NOT_UNIQUE: Se ha detectado un valor duplicado
USER_SUSPENDED: Usuario Suspendido
CONTAINS_NULL_VALUES: El campo contiene valores nulos
UNKNOWN: Error Inesperado
UNPROCESSABLE_ENTITY: Entidad no procesable
INTERNAL_SERVER_ERROR: Error Inesperado
NOT_NULL_VIOLATION: El valor no puede ser nulo
UNKNOWN: Error Inesperado
value_hashed: Valor Hasheado de Manera Segura
bookmark_name: Nombre del Marcador...
create_bookmark: Crear Marcador

View File

@@ -412,10 +412,10 @@ errors:
RECORD_NOT_UNIQUE: Se ha detectado un valor duplicado
USER_SUSPENDED: Usuario Suspendido
CONTAINS_NULL_VALUES: El campo contiene valores nulos
UNKNOWN: Error Inesperado
UNPROCESSABLE_ENTITY: Entidad no procesable
INTERNAL_SERVER_ERROR: Error Inesperado
NOT_NULL_VIOLATION: El valor no puede ser nulo
UNKNOWN: Error Inesperado
value_hashed: Valor Hasheado de Manera Segura
bookmark_name: Nombre del Marcador...
create_bookmark: Crear Marcador

View File

@@ -401,9 +401,9 @@ errors:
RECORD_NOT_UNIQUE: Kirje pole unikaalne
USER_SUSPENDED: Kasutajakonto on suletud
CONTAINS_NULL_VALUES: Väli sisaldab tühje väärtusi
UNKNOWN: Ootamatu viga
INTERNAL_SERVER_ERROR: Ootamatu viga
NOT_NULL_VIOLATION: Väärtus ei saa olla null
UNKNOWN: Ootamatu viga
value_hashed: Väärtus salastati
bookmark_name: Järjehoidja nimi...
create_bookmark: Loo järjehoidja

View File

@@ -0,0 +1,3 @@
---
module_bar: ماژول
edit_field: ویرایش فیلد

View File

@@ -400,9 +400,9 @@ errors:
RECORD_NOT_UNIQUE: Duplikaattiarvo havaittu
USER_SUSPENDED: Käyttäjä jäädytetty
CONTAINS_NULL_VALUES: Kenttä sisältää null-arvoja
UNKNOWN: Odottamaton virhe
INTERNAL_SERVER_ERROR: Odottamaton virhe
NOT_NULL_VIOLATION: Arvo ei voi olla null
UNKNOWN: Odottamaton virhe
value_hashed: Arvo tiivistetty turvallisesti
bookmark_name: Kirjanmerkin nimi...
create_bookmark: Luo kirjanmerkki

View File

@@ -449,10 +449,10 @@ errors:
RECORD_NOT_UNIQUE: Valeur dupliquée détecté
USER_SUSPENDED: Utilisateur suspendu
CONTAINS_NULL_VALUES: Le champ contient des valeurs nulles
UNKNOWN: Erreur inconnue
UNPROCESSABLE_ENTITY: Cette entité ne peut être traitée
INTERNAL_SERVER_ERROR: Erreur inconnue
NOT_NULL_VIOLATION: La valeur ne peut pas être nulle
UNKNOWN: Erreur inconnue
security: Sécurité
value_hashed: Valeur hashée de manière sûre
bookmark_name: Nom du favori...

View File

@@ -423,10 +423,10 @@ errors:
RECORD_NOT_UNIQUE: Ismétlődő értéket észleltem
USER_SUSPENDED: Felhasználó felfüggesztve
CONTAINS_NULL_VALUES: A mező null értékeket tartalmaz
UNKNOWN: Váratlan hiba történt
UNPROCESSABLE_ENTITY: Feldolgozhatatlan entitás
INTERNAL_SERVER_ERROR: Váratlan hiba történt
NOT_NULL_VIOLATION: Az érték nem lehet null
UNKNOWN: Váratlan hiba történt
security: Biztonság
value_hashed: Biztonságosan hashelt érték
bookmark_name: Könyvjelző neve...

View File

@@ -398,9 +398,9 @@ errors:
ITEM_NOT_FOUND: Item tidak ditemukan
ROUTE_NOT_FOUND: Tidak ditemukan
RECORD_NOT_UNIQUE: Nilai duplikat terdeteksi
UNKNOWN: Kesalahan Tidak Terduga
INTERNAL_SERVER_ERROR: Kesalahan Tidak Terduga
NOT_NULL_VIOLATION: Nilai tidak boleh kosong
UNKNOWN: Kesalahan Tidak Terduga
value_hashed: Nilai telah Di-hash secara Aman
bookmark_name: Nama bookmark...
create_bookmark: Buat Bookmark

View File

@@ -146,7 +146,7 @@ field_validation: Convalida di Campo
field_presets: Preset di Campo
permissions_for_role: 'Campi che il ruolo {role} può {action}.'
fields_for_role: 'Campi che il ruolo {role} può {action}.'
validation_for_role: 'Regole per il campo {action} che il ruolo {role} deve rispettare.'
validation_for_role: 'Regole per il campo che il ruolo {role} deve rispettare alla {action}.'
presets_for_role: 'Valore predefinito del campo per il ruolo {role}.'
presentation_and_aliases: Presentazione e Alias
revision_post_update: Ecco come appariva questo elemento dopo l'aggiornamento.
@@ -378,7 +378,7 @@ search_items: Ricerca elementi...
disabled: Disabilitato
information: Informazioni
report_bug: Segnala un Bug
request_feature: Richiesta caratteristica
request_feature: Richiesta funzionalità
interface_not_found: 'Interfaccia "{interface}" non trovata.'
reset_interface: '"Reimposta interfaccia"'
display_not_found: 'Display "{display}" non trovato.'
@@ -398,7 +398,7 @@ csv: CSV
no_collections: Nessuna Raccolta
create_collection: Crea Raccolta
no_collections_copy_admin: Non hai ancora nessuna Raccolta. Clicca sul pulsante qui sotto per iniziare.
no_collections_copy: Non hai ancora nessuna Raccolta. Contatta il tuo l'amministratore di sistema.
no_collections_copy: Non hai ancora nessuna Raccolta. Contatta il tuo amministratore di sistema.
relationship_not_setup: La relazione non è stata configurata correttamente
display_template_not_setup: L'opzione del modello di visualizzazione non è configurata correttamente
collection_field_not_setup: L'opzione del campo della raccolta non è configurato correttamente
@@ -455,10 +455,10 @@ errors:
RECORD_NOT_UNIQUE: Rilevato valore duplicato
USER_SUSPENDED: Utente sospeso
CONTAINS_NULL_VALUES: Il campo contiene valori nulli
UNKNOWN: Errore Imprevisto
UNPROCESSABLE_ENTITY: Entità non elaborabile
INTERNAL_SERVER_ERROR: Errore Imprevisto
NOT_NULL_VIOLATION: Il valore non può essere nullo
UNKNOWN: Errore Imprevisto
security: Sicurezza
value_hashed: Valore cifrato in sicurezza
bookmark_name: Nome segnalibro...
@@ -564,7 +564,7 @@ value_unique: Il valore deve essere unico
all_activity: Tutte le Attività
create_item: Crea Elemento
display_template: Display Template
language_display_template: Modello Visualizzazione Lingua
language_display_template: Modello di visualizzazione della lingua
translations_display_template: Modello Visualizzazione Traduzioni
n_items_selected: 'Nessun Elemento Selezionato | 1 Elemento Selezionato | {n} Elementi Selezionati'
per_page: Per Pagina
@@ -586,11 +586,11 @@ no_presets: Nessuna Preset
no_presets_copy: Nessun preset o segnalibro sono stati ancora salvati.
no_presets_cta: Aggiungi Preset
presets_only: Solo Preset
create: Creare
on_create: Alla Creazione
on_update: In aggiornamento
read: Leggere
update: Aggiornare
create: Creazione
on_create: Alla creazione
on_update: Alla modifica
read: Lettura
update: Modifica
select_fields: Seleziona campi
format_text: Formato testo
bold: Grassetto
@@ -677,7 +677,7 @@ editing_in_batch: 'Modifica batch {count} Articoli'
no_options_available: Nessuna opzione disponibile
settings_data_model: Modello dei dati
settings_permissions: Ruoli e permessi
settings_project: Impostazioni del progetto
settings_project: Impostazioni progetto
settings_webhooks: Webhooks
settings_presets: Preset & Segnalibri
one_or_more_options_are_missing: Mancano una o più opzioni
@@ -784,7 +784,7 @@ fields:
title: Titolo
description: Descrizione
tags: Tag
location: Percorso
location: Posizione
storage: Archiviazione
filename_disk: Nome File (Disco)
filename_download: Nome File (Download)
@@ -809,7 +809,7 @@ fields:
email: E-mail
password: Password
avatar: Avatar
location: Percorso
location: Posizione
title: Titolo
description: Descrizione
tags: Tag
@@ -852,7 +852,7 @@ fields:
public_foreground: Primo Piano Pubblico
public_background: Sfondo Pubblico
public_note: Nota Pubblica
auth_password_policy: Criteri Password di accesso
auth_password_policy: Sicurezza della password
auth_login_attempts: Tentativi di accesso
files_and_thumbnails: File e miniature
storage_default_folder: Cartella predefinita di archiviazione
@@ -914,9 +914,9 @@ field_options:
overrides_divider_title: Personalizzazioni App
directus_activity:
login: Accedi
create: Creare
update: Aggiornare
delete: Elimina
create: Creazione
update: Modifica
delete: Cancellazione
directus_collections:
track_activity_revisions: Traccia Attività e Revisioni
only_track_activity: Traccia solo Attività
@@ -980,9 +980,9 @@ field_options:
status_options_inactive: Disattivato
data_label: Invia dati evento
triggers_divider: Trigger
actions_create: Creare
actions_update: Aggiornare
actions_delete: Elimina
actions_create: Creazione
actions_update: Modifica
actions_delete: Cancellazione
actions_login: Accedi
no_fields_in_collection: 'Non ci sono ancora campi in "{collection}"'
no_value: Nessun valore
@@ -1008,7 +1008,7 @@ continue_as: >-
editing_role: '{role} Ruolo'
creating_webhook: Creazione Webhook
default_label: Predefinito
delete_label: Elimina
delete_label: Cancellazione
delete_are_you_sure: >-
Questa azione è permanente e non può essere annullata. Sei sicuro di voler procedere?
delete_field_are_you_sure: >-
@@ -1274,6 +1274,8 @@ interfaces:
translations:
display_template: Display Template
no_collection: Nessuna Raccolta
toggle_split_view: Attiva/disattiva la Split View
language_field: Campo lingua
list-o2m-tree-view:
description: Vista ad albero per oggetti ricorsivi annidati one-to-many
recursive_only: L'interfaccia di visualizzazione ad albero funziona solo per le relazioni ricorsive.

View File

@@ -201,8 +201,8 @@ errors:
ITEM_NOT_FOUND: アイテムが見つかりませんでした。
ROUTE_NOT_FOUND: 見つかりません
RECORD_NOT_UNIQUE: 重複値が検出されました
UNKNOWN: 予期しないエラーが発生しました
INTERNAL_SERVER_ERROR: 予期しないエラーが発生しました
UNKNOWN: 予期しないエラーが発生しました
bookmark_name: ブックマーク名
create_bookmark: ブックマークを作成
edit_bookmark: ブックマークを編集

View File

@@ -391,9 +391,9 @@ errors:
ITEM_LIMIT_REACHED: Pasiektas elementų limitas
ITEM_NOT_FOUND: Elementas nerastas
ROUTE_NOT_FOUND: Nerasta
UNKNOWN: Nenumatyta klaida
INTERNAL_SERVER_ERROR: Nenumatyta klaida
NOT_NULL_VIOLATION: Reikšmė negali būti null
UNKNOWN: Nenumatyta klaida
value_hashed: Reikšmė saugiai išsaugota
bookmark_name: Žymės pavadinimas...
create_bookmark: Kurti žymę

View File

@@ -413,10 +413,10 @@ errors:
RECORD_NOT_UNIQUE: Verdubbelde waarde gedetecteerd
USER_SUSPENDED: Gebruiker geschorst
CONTAINS_NULL_VALUES: Veld bevat NULL waarden
UNKNOWN: Onverwachte fout
UNPROCESSABLE_ENTITY: Onverwerkbare entiteit
INTERNAL_SERVER_ERROR: Onverwachte fout
NOT_NULL_VIOLATION: Waarde kan niet "null" zijn
UNKNOWN: Onverwachte fout
value_hashed: Waarde veilig opgeslagen
bookmark_name: Bladwijzer naam...
create_bookmark: Bladwijzer aanmaken

View File

@@ -420,9 +420,9 @@ errors:
RECORD_NOT_UNIQUE: Wykryto zduplikowaną wartość
USER_SUSPENDED: Użytkownik zawieszony
CONTAINS_NULL_VALUES: Pole zawiera pustą wartość (Null)
UNKNOWN: Nieoczekiwany błąd
INTERNAL_SERVER_ERROR: Nieoczekiwany błąd
NOT_NULL_VIOLATION: Wartość nie może być pusta
UNKNOWN: Nieoczekiwany błąd
value_hashed: Wartość bezpiecznie zakodowana
bookmark_name: Nazwa zakładki...
create_bookmark: Utwórz zakładkę

View File

@@ -424,10 +424,10 @@ errors:
RECORD_NOT_UNIQUE: Valor duplicado detectado
USER_SUSPENDED: Usuário suspenso
CONTAINS_NULL_VALUES: O campo contém valores nulos
UNKNOWN: Erro inesperado
UNPROCESSABLE_ENTITY: Entidade não processável
INTERNAL_SERVER_ERROR: Erro inesperado
NOT_NULL_VIOLATION: Valor não pode ser nulo
UNKNOWN: Erro inesperado
security: Segurança
value_hashed: Valor secretamente salvo em hash
bookmark_name: Nome do marcador...

View File

@@ -455,10 +455,10 @@ errors:
RECORD_NOT_UNIQUE: Обнаружен дубликат значения
USER_SUSPENDED: Пользователь заблокирован
CONTAINS_NULL_VALUES: Поле содержит значения null
UNKNOWN: Неожиданная Ошибка
UNPROCESSABLE_ENTITY: Необрабатываемый объект
INTERNAL_SERVER_ERROR: Неожиданная Ошибка
NOT_NULL_VIOLATION: Значение не может быть null
UNKNOWN: Неожиданная Ошибка
security: Безопасность
value_hashed: Значение Безопасно Хэшировано
bookmark_name: Название закладки...

View File

@@ -424,10 +424,10 @@ errors:
RECORD_NOT_UNIQUE: Vrednost ni edinstvena (že obstaja)
USER_SUSPENDED: Uporabnik suspendiran
CONTAINS_NULL_VALUES: Polje vsebuje nične vrednosti
UNKNOWN: Nepričakovana napaka
UNPROCESSABLE_ENTITY: Obdelava nemogoča
INTERNAL_SERVER_ERROR: Nepričakovana napaka
NOT_NULL_VIOLATION: Vrednost ne sme biti nična
UNKNOWN: Nepričakovana napaka
security: Varnost
value_hashed: Vrednost varno zgoščena
bookmark_name: Ime zaznamka ...

View File

@@ -401,9 +401,9 @@ errors:
RECORD_NOT_UNIQUE: Detektovana je dupla vrijednost
USER_SUSPENDED: Suspendovan Korisnik
CONTAINS_NULL_VALUES: Polje sadrži null vrijednosti
UNKNOWN: Neočekivana greška
INTERNAL_SERVER_ERROR: Neočekivana greška
NOT_NULL_VIOLATION: Vrijednost ne može biti null
UNKNOWN: Neočekivana greška
value_hashed: Vrijednost je Sigurno Skladištena
bookmark_name: Naziv oznake...
create_bookmark: Napravi Oznaku

View File

@@ -388,9 +388,9 @@ errors:
ROUTE_NOT_FOUND: Hittades inte
RECORD_NOT_UNIQUE: Duplicerat värde upptäckt
USER_SUSPENDED: Användare avstängd
UNKNOWN: Oväntat fel
INTERNAL_SERVER_ERROR: Oväntat fel
NOT_NULL_VIOLATION: Värdet kan inte vara null
UNKNOWN: Oväntat fel
value_hashed: Värde säkert hashat
bookmark_name: Bokmärkesnamn...
create_bookmark: Skapa bokmärke

View File

@@ -447,10 +447,10 @@ errors:
RECORD_NOT_UNIQUE: พบค่าที่ซ้ำกัน
USER_SUSPENDED: ผู้ใช้ถูกระงับ
CONTAINS_NULL_VALUES: ฟิลด์มีค่าว่าง
UNKNOWN: พบข้อผิดพลาดบางอย่างที่ไม่คาดคิด
UNPROCESSABLE_ENTITY: เอ็นติตี้ที่ประมวลผลไม่ได้
INTERNAL_SERVER_ERROR: พบข้อผิดพลาดบางอย่างที่ไม่คาดคิด
NOT_NULL_VIOLATION: ต้องไม่เป็นค่า null
UNKNOWN: พบข้อผิดพลาดบางอย่างที่ไม่คาดคิด
security: ความปลอดภัย
value_hashed: ข้อมูลถูกเข้ารหัสไว้อย่างปลอดภัย
bookmark_name: ชื่อบุ๊กมาร์ก...

View File

@@ -377,9 +377,9 @@ errors:
RECORD_NOT_UNIQUE: Kopya değer tespit edildi
USER_SUSPENDED: Kullanıcı Askıya Alındı
CONTAINS_NULL_VALUES: Alan null değer içeriyor
UNKNOWN: Beklenmeyen hata
INTERNAL_SERVER_ERROR: Beklenmeyen hata
NOT_NULL_VIOLATION: Değer null olamaz
UNKNOWN: Beklenmeyen hata
value_hashed: Değer Güvenli Şekilde Hashlendi
bookmark_name: Yer imi adı...
create_bookmark: Yer imi oluştur

View File

@@ -327,9 +327,9 @@ errors:
ITEM_LIMIT_REACHED: Đạt mức giới hạn của bản ghi
ITEM_NOT_FOUND: Bản ghi không tồn tại
ROUTE_NOT_FOUND: Không tìm thấy
UNKNOWN: Lỗi Bất Thường
INTERNAL_SERVER_ERROR: Lỗi Bất Thường
NOT_NULL_VIOLATION: Dữ liệu không thể là null
UNKNOWN: Lỗi Bất Thường
value_hashed: Dữ Liệu Mã Hóa An Toàn
bookmark_name: Tên Dấu trang...
create_bookmark: Tạo Dấu trang

View File

@@ -445,10 +445,10 @@ errors:
RECORD_NOT_UNIQUE: 检测到重复的值
USER_SUSPENDED: 用户已禁用
CONTAINS_NULL_VALUES: 字段包含空值
UNKNOWN: 未知错误
UNPROCESSABLE_ENTITY: 不可处理的实体
INTERNAL_SERVER_ERROR: 未知错误
NOT_NULL_VIOLATION: 值不能为null
UNKNOWN: 未知错误
security: 安全
value_hashed: 哈希值
bookmark_name: 书签名称

View File

@@ -303,9 +303,9 @@ errors:
INVALID_QUERY: 無效的查詢
ITEM_NOT_FOUND: 找不到項目
ROUTE_NOT_FOUND: 找不到
UNKNOWN: 未預期的錯誤
INTERNAL_SERVER_ERROR: 未預期的錯誤
NOT_NULL_VIOLATION: 值不能為null
UNKNOWN: 未預期的錯誤
bookmark_name: 書籤名稱...
create_bookmark: 建立書籤
edit_bookmark: 編輯書籤

View File

@@ -1,10 +1,10 @@
import api from '@/api';
import useCollection from '@/composables/use-collection';
import { useCollection } from '@directus/shared/composables';
import { formatISO, parse, format } from 'date-fns';
import useItems from '@/composables/use-items';
import { useItems } from '@directus/shared/composables';
import { router } from '@/router';
import { useAppStore } from '@/stores/app';
import { getFieldsFromTemplate } from '@/utils/get-fields-from-template';
import { getFieldsFromTemplate } from '@directus/shared/utils';
import getFullcalendarLocale from '@/utils/get-fullcalendar-locale';
import { renderPlainStringTemplate } from '@/utils/render-string-template';
import { unexpectedError } from '@/utils/unexpected-error';
@@ -21,7 +21,7 @@ import CalendarActions from './actions.vue';
import CalendarLayout from './calendar.vue';
import CalendarOptions from './options.vue';
import CalendarSidebar from './sidebar.vue';
import useSync from '@/composables/use-sync';
import { useSync } from '@directus/shared/composables';
import { LayoutOptions } from './types';
export default defineLayout<LayoutOptions>({

View File

@@ -19,7 +19,7 @@
import { useI18n } from 'vue-i18n';
import { defineComponent, PropType } from 'vue';
import { Field } from '@directus/shared/types';
import useSync from '@/composables/use-sync';
import { useSync } from '@directus/shared/composables';
export default defineComponent({
inheritAttrs: false,

View File

@@ -7,7 +7,7 @@
import { defineComponent, PropType } from 'vue';
import { AppFilter } from '@directus/shared/types';
import useSync from '@/composables/use-sync';
import { useSync } from '@directus/shared/composables';
export default defineComponent({
inheritAttrs: false,

View File

@@ -86,8 +86,8 @@ import Card from './components/card.vue';
import CardsHeader from './components/header.vue';
import useElementSize from '@/composables/use-element-size';
import { Field, Item } from '@directus/shared/types';
import useSync from '@/composables/use-sync';
import { Collection } from '@/types';
import { useSync } from '@directus/shared/composables';
import { Collection } from '@directus/shared/types';
export default defineComponent({
components: { Card, CardsHeader },

View File

@@ -55,7 +55,7 @@
import { useI18n } from 'vue-i18n';
import { defineComponent, PropType, computed } from 'vue';
import { Field } from '@directus/shared/types';
import useSync from '@/composables/use-sync';
import { useSync } from '@directus/shared/composables';
export default defineComponent({
props: {

View File

@@ -6,14 +6,14 @@ import CardsActions from './actions.vue';
import { useI18n } from 'vue-i18n';
import { toRefs, inject, computed, ref } from 'vue';
import useCollection from '@/composables/use-collection/';
import useItems from '@/composables/use-items';
import { getFieldsFromTemplate } from '@/utils/get-fields-from-template';
import { useCollection } from '@directus/shared/composables';
import { useItems } from '@directus/shared/composables';
import { getFieldsFromTemplate } from '@directus/shared/utils';
import { useRelationsStore } from '@/stores/';
import adjustFieldsForDisplays from '@/utils/adjust-fields-for-displays';
import { clone } from 'lodash';
import useSync from '@/composables/use-sync';
import { useSync } from '@directus/shared/composables';
import { LayoutOptions, LayoutQuery } from './types';
export default defineLayout<LayoutOptions, LayoutQuery>({

View File

@@ -49,7 +49,7 @@ import { useI18n } from 'vue-i18n';
import { defineComponent, PropType } from 'vue';
import { Field } from '@directus/shared/types';
import useSync from '@/composables/use-sync';
import { useSync } from '@directus/shared/composables';
export default defineComponent({
inheritAttrs: false,

View File

@@ -13,7 +13,7 @@ import { defineComponent, PropType } from 'vue';
import { LayoutQuery } from './types';
import { AppFilter } from '@directus/shared/types';
import useSync from '@/composables/use-sync';
import { useSync } from '@directus/shared/composables';
export default defineComponent({
inheritAttrs: false,

View File

@@ -10,12 +10,12 @@ import { toRefs, computed, ref, watch, Ref } from 'vue';
import { toGeoJSON } from '@/utils/geometry';
import { layers } from './style';
import { useRouter } from 'vue-router';
import useSync from '@/composables/use-sync';
import { useSync } from '@directus/shared/composables';
import { LayoutOptions, LayoutQuery } from './types';
import { Filter } from '@directus/shared/types';
import useCollection from '@/composables/use-collection/';
import useItems from '@/composables/use-items';
import { getFieldsFromTemplate } from '@/utils/get-fields-from-template';
import { useCollection } from '@directus/shared/composables';
import { useItems } from '@directus/shared/composables';
import { getFieldsFromTemplate } from '@directus/shared/utils';
import { Field, GeometryFormat, GeometryOptions } from '@directus/shared/types';
import { cloneDeep, merge } from 'lodash';

View File

@@ -116,7 +116,7 @@ import { useI18n } from 'vue-i18n';
import { defineComponent, PropType } from 'vue';
import MapComponent from './components/map.vue';
import useSync from '@/composables/use-sync';
import { useSync } from '@directus/shared/composables';
import { GeometryOptions, Item } from '@directus/shared/types';
import { Filter } from '@directus/shared/types';

View File

@@ -34,30 +34,6 @@
:disabled="geometryOptions && geometryOptions.geometryType !== 'Point'"
/>
</div>
<!-- <div class="field">
<v-drawer
v-model="customLayerDrawerOpenWritable"
:title="t('layouts.map.custom_layers')"
@cancel="customLayerDrawerOpenWritable = false"
>
<template #activator="{ on }">
<v-button @click="on">{{ t('layouts.map.edit_custom_layers') }}</v-button>
</template>
<template #actions>
<v-button v-tooltip.bottom="t('reset')" icon rounded class="delete-action" @click="resetLayers">
<v-icon name="replay" />
</v-button>
<v-button v-tooltip.bottom="t('save')" icon rounded @click="updateLayers">
<v-icon name="check" />
</v-button>
</template>
<div class="custom-layers">
<interface-input-code v-model="customLayersWritable" language="json" type="json" :line-number="false" />
</div>
</v-drawer>
</div> -->
</template>
<script lang="ts">
@@ -67,7 +43,7 @@ import { defineComponent, PropType, toRefs } from 'vue';
import { useAppStore } from '@/stores';
import { getBasemapSources } from '@/utils/geometry/basemap';
import { GeometryOptions, Item } from '@directus/shared/types';
import useSync from '@/composables/use-sync';
import { useSync } from '@directus/shared/composables';
export default defineComponent({
inheritAttrs: false,

View File

@@ -13,7 +13,7 @@ import { defineComponent, PropType } from 'vue';
import { LayoutQuery } from './types';
import { AppFilter } from '@directus/shared/types';
import useSync from '@/composables/use-sync';
import { useSync } from '@directus/shared/composables';
export default defineComponent({
inheritAttrs: false,

View File

@@ -11,12 +11,12 @@ import { HeaderRaw, Item } from '@/components/v-table/types';
import { Field } from '@directus/shared/types';
import { useRouter } from 'vue-router';
import { debounce, clone } from 'lodash';
import useCollection from '@/composables/use-collection';
import useItems from '@/composables/use-items';
import { useCollection } from '@directus/shared/composables';
import { useItems } from '@directus/shared/composables';
import adjustFieldsForDisplays from '@/utils/adjust-fields-for-displays';
import hideDragImage from '@/utils/hide-drag-image';
import { getDefaultDisplayForType } from '@/utils/get-default-display-for-type';
import useSync from '@/composables/use-sync';
import { useSync } from '@directus/shared/composables';
import { LayoutOptions, LayoutQuery } from './types';
export default defineLayout<LayoutOptions, LayoutQuery>({

View File

@@ -54,7 +54,7 @@ import { useI18n } from 'vue-i18n';
import { defineComponent, PropType } from 'vue';
import Draggable from 'vuedraggable';
import useSync from '@/composables/use-sync';
import { useSync } from '@directus/shared/composables';
import { Field } from '@directus/shared/types';
export default defineComponent({

View File

@@ -11,7 +11,7 @@
<script lang="ts">
import { defineComponent, PropType } from 'vue';
import useSync from '@/composables/use-sync';
import { useSync } from '@directus/shared/composables';
import { AppFilter } from '@directus/shared/types';
import { LayoutQuery } from './types';

View File

@@ -82,11 +82,10 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { ComponentPublicInstance, defineComponent, PropType, ref } from 'vue';
import useSync from '@/composables/use-sync';
import { useSync } from '@directus/shared/composables';
import useShortcut from '@/composables/use-shortcut';
import { Field, Item } from '@directus/shared/types';
import { Field, Item, Collection } from '@directus/shared/types';
import { HeaderRaw } from '@/components/v-table/types';
import { Collection } from '@/types';
export default defineComponent({
inheritAttrs: false,

View File

@@ -49,7 +49,7 @@
<v-card-title>{{ t('delete_bookmark_copy', { bookmark: bookmark.bookmark }) }}</v-card-title>
<v-card-actions>
<v-button secondary @click="deleteActive = false">{{ t('cancel') }}</v-button>
<v-button :loading="deleteSaving" class="action-delete" @click="deleteSave">
<v-button :loading="deleteSaving" kind="danger" @click="deleteSave">
{{ t('delete_label') }}
</v-button>
</v-card-actions>
@@ -182,11 +182,4 @@ export default defineComponent({
--v-list-item-color: var(--danger);
--v-list-item-icon-color: var(--danger);
}
.action-delete {
--v-button-background-color: var(--danger-25);
--v-button-color: var(--danger);
--v-button-background-color-hover: var(--danger-50);
--v-button-color-hover: var(--danger);
}
</style>

View File

@@ -1,5 +1,5 @@
import { useCollectionsStore, useUserStore } from '@/stores/';
import { Collection } from '@/types';
import { Collection } from '@directus/shared/types';
import { computed, ComputedRef, Ref, ref } from 'vue';
export type NavItem = {

View File

@@ -111,7 +111,7 @@
<v-button secondary @click="confirmDelete = false">
{{ t('cancel') }}
</v-button>
<v-button class="action-delete" :loading="deleting" @click="batchDelete">
<v-button kind="danger" :loading="deleting" @click="batchDelete">
{{ t('delete_label') }}
</v-button>
</v-card-actions>
@@ -143,7 +143,7 @@
<v-button secondary @click="confirmArchive = false">
{{ t('cancel') }}
</v-button>
<v-button class="action-archive" :loading="archiving" @click="archive">
<v-button kind="warning" :loading="archiving" @click="archive">
{{ t('archive') }}
</v-button>
</v-card-actions>
@@ -259,7 +259,7 @@ import CollectionsNavigation from '../components/navigation.vue';
import CollectionsNavigationSearch from '../components/navigation-search.vue';
import api from '@/api';
import CollectionsNotFound from './not-found.vue';
import useCollection from '@/composables/use-collection';
import { useCollection } from '@directus/shared/composables';
import { useLayout } from '@/composables/use-layout';
import usePreset from '@/composables/use-preset';
import LayoutSidebarDetail from '@/views/private/components/layout-sidebar-detail';

View File

@@ -79,7 +79,7 @@
<v-button secondary @click="confirmDelete = false">
{{ t('cancel') }}
</v-button>
<v-button class="action-delete" :loading="deleting" @click="deleteAndQuit">
<v-button kind="danger" :loading="deleting" @click="deleteAndQuit">
{{ t('delete_label') }}
</v-button>
</v-card-actions>
@@ -113,7 +113,7 @@
<v-button secondary @click="confirmArchive = false">
{{ t('cancel') }}
</v-button>
<v-button class="action-archive" :loading="archiving" @click="toggleArchive">
<v-button kind="warning" :loading="archiving" @click="toggleArchive">
{{ isArchived ? t('unarchive') : t('archive') }}
</v-button>
</v-card-actions>
@@ -198,7 +198,7 @@ import { defineComponent, computed, toRefs, ref, ComponentPublicInstance } from
import CollectionsNavigationSearch from '../components/navigation-search.vue';
import CollectionsNavigation from '../components/navigation.vue';
import CollectionsNotFound from './not-found.vue';
import useCollection from '@/composables/use-collection';
import { useCollection } from '@directus/shared/composables';
import RevisionsDrawerDetail from '@/views/private/components/revisions-drawer-detail';
import CommentsSidebarDetail from '@/views/private/components/comments-sidebar-detail';
import useItem from '@/composables/use-item';

View File

@@ -106,7 +106,7 @@
</v-card-text>
<v-card-actions>
<v-button secondary @click="deleteActive = false">{{ t('cancel') }}</v-button>
<v-button :loading="deleteSaving" @click="deleteSave">{{ t('delete_label') }}</v-button>
<v-button kind="danger" :loading="deleteSaving" @click="deleteSave">{{ t('delete_label') }}</v-button>
</v-card-actions>
</v-card>
</v-dialog>

View File

@@ -77,7 +77,7 @@
<v-button secondary @click="confirmDelete = false">
{{ t('cancel') }}
</v-button>
<v-button class="action-delete" :loading="deleting" @click="batchDelete">
<v-button kind="danger" :loading="deleting" @click="batchDelete">
{{ t('delete_label') }}
</v-button>
</v-card-actions>

View File

@@ -33,7 +33,7 @@
<v-button secondary @click="confirmDelete = false">
{{ t('cancel') }}
</v-button>
<v-button class="action-delete" :loading="deleting" @click="deleteAndQuit">
<v-button kind="danger" :loading="deleting" @click="deleteAndQuit">
{{ t('delete_label') }}
</v-button>
</v-card-actions>

View File

@@ -1,9 +1,7 @@
import api from '@/api';
import { useCollection } from '@/composables/use-collection';
import { defineModule } from '@directus/shared/utils';
import { useCollectionsStore, useFieldsStore } from '@/stores';
import RouterPass from '@/utils/router-passthrough';
import { ref } from 'vue';
import Collections from './routes/data-model/collections/collections.vue';
import FieldDetail from './routes/data-model/field-detail/field-detail.vue';
import Fields from './routes/data-model/fields/fields.vue';
@@ -62,10 +60,11 @@ export default defineModule({
path: ':collection',
component: Fields,
async beforeEnter(to) {
const { info } = useCollection(ref(to.params.collection as string));
const collectionsStore = useCollectionsStore();
const info = collectionsStore.getCollection(to.params.collection as string);
const fieldsStore = useFieldsStore();
if (!info.value?.meta) {
if (!info?.meta) {
await api.patch(`/collections/${to.params.collection}`, { meta: {} });
}

View File

@@ -100,7 +100,7 @@ import { defineComponent, ref, computed } from 'vue';
import SettingsNavigation from '../../../components/navigation.vue';
import { HeaderRaw } from '@/components/v-table/types';
import { useCollectionsStore } from '@/stores/';
import { Collection } from '@/types';
import { Collection } from '@directus/shared/types';
import { useRouter } from 'vue-router';
import { sortBy } from 'lodash';
import CollectionOptions from './components/collection-options.vue';

View File

@@ -22,7 +22,7 @@
<v-button :disabled="deleting" secondary @click="deleteActive = null">
{{ t('cancel') }}
</v-button>
<v-button :loading="deleting" class="delete" @click="deleteCollection">
<v-button :loading="deleting" kind="danger" @click="deleteCollection">
{{ t('delete_collection') }}
</v-button>
</v-card-actions>
@@ -34,7 +34,7 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { defineComponent, PropType, ref } from 'vue';
import { Collection } from '@/types';
import { Collection } from '@directus/shared/types';
import { useCollectionsStore } from '@/stores/';
export default defineComponent({
@@ -74,11 +74,6 @@ export default defineComponent({
</script>
<style lang="scss" scoped>
.v-button.delete {
--v-button-background-color: var(--danger);
--v-button-background-color-hover: var(--danger-125);
}
.ctx-toggle {
--v-icon-color: var(--foreground-subdued);

Some files were not shown because too many files have changed in this diff Show More