diff --git a/api/package-lock.json b/api/package-lock.json index 969522898e..21b348ee9a 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -1,6 +1,6 @@ { "name": "directus", - "version": "9.0.0-rc.1", + "version": "9.0.0-rc.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/api/package.json b/api/package.json index 908e97169c..1e030e12c2 100644 --- a/api/package.json +++ b/api/package.json @@ -1,6 +1,6 @@ { "name": "directus", - "version": "9.0.0-rc.1", + "version": "9.0.0-rc.2", "license": "GPL-3.0-only", "homepage": "https://github.com/directus/next#readme", "description": "Directus is a real-time API and App dashboard for managing SQL database content.", diff --git a/api/src/database/seeds/03-fields/09-settings.yaml b/api/src/database/seeds/03-fields/09-settings.yaml index 3cdc8df1fa..f7604aa374 100644 --- a/api/src/database/seeds/03-fields/09-settings.yaml +++ b/api/src/database/seeds/03-fields/09-settings.yaml @@ -135,15 +135,18 @@ fields: - field: key name: Key type: string + schema: + is_nullable: false meta: interface: slug options: onlyOnCreate: false - required: true width: half - field: fit name: Fit type: string + schema: + is_nullable: false meta: interface: dropdown options: @@ -152,34 +155,35 @@ fields: text: Contain (preserve aspect ratio) - value: cover text: Cover (forces exact size) - required: true width: half - field: width name: Width type: integer + schema: + is_nullable: false meta: interface: numeric - required: true width: half - field: height name: Height type: integer + schema: + is_nullable: false meta: interface: numeric - required: true width: half - field: quality type: integer name: Quality schema: default_value: 80 + is_nullable: false meta: interface: slider options: max: 100 min: 0 step: 1 - required: true width: full template: '{{key}}' special: json diff --git a/api/src/types/field.ts b/api/src/types/field.ts index f46d105f68..636afee7e5 100644 --- a/api/src/types/field.ts +++ b/api/src/types/field.ts @@ -26,7 +26,6 @@ export type FieldMeta = { interface: string | null; options: Record | null; locked: boolean; - required: boolean; readonly: boolean; hidden: boolean; sort: number | null; diff --git a/app/package-lock.json b/app/package-lock.json index 045f0e04c4..8720d18275 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -1,6 +1,6 @@ { "name": "@directus/app", - "version": "9.0.0-rc.1", + "version": "9.0.0-rc.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -6601,51 +6601,6 @@ "tslint": "^5.20.1", "webpack": "^4.0.0", "yorkie": "^2.0.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "optional": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "fork-ts-checker-webpack-plugin-v5": { - "version": "npm:fork-ts-checker-webpack-plugin@5.2.0", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.0.tgz", - "integrity": "sha512-NEKcI0+osT5bBFZ1SFGzJMQETjQWZrSvMO1g0nAR/w0t328Z41eN8BJEIZyFCl2HsuiJpa9AN474Nh2qLVwGLQ==", - "dev": true, - "optional": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - } - }, - "schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "dev": true, - "optional": true, - "requires": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - } - } } }, "@vue/cli-plugin-unit-jest": { @@ -6785,17 +6740,6 @@ "unique-filename": "^1.1.1" } }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "optional": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -6879,18 +6823,6 @@ "graceful-fs": "^4.1.6" } }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "optional": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -7004,18 +6936,6 @@ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, - "vue-loader-v16": { - "version": "npm:vue-loader@16.0.0-beta.8", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.0.0-beta.8.tgz", - "integrity": "sha512-oouKUQWWHbSihqSD7mhymGPX1OQ4hedzAHyvm8RdyHh6m3oIvoRF+NM45i/bhNOlo8jCnuJhaSUf/6oDjv978g==", - "dev": true, - "optional": true, - "requires": { - "chalk": "^4.1.0", - "hash-sum": "^2.0.0", - "loader-utils": "^2.0.0" - } - }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -11744,6 +11664,51 @@ } } }, + "fork-ts-checker-webpack-plugin-v5": { + "version": "npm:fork-ts-checker-webpack-plugin@5.2.0", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.0.tgz", + "integrity": "sha512-NEKcI0+osT5bBFZ1SFGzJMQETjQWZrSvMO1g0nAR/w0t328Z41eN8BJEIZyFCl2HsuiJpa9AN474Nh2qLVwGLQ==", + "dev": true, + "optional": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "optional": true, + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + } + } + }, "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", @@ -20377,6 +20342,43 @@ } } }, + "vue-loader-v16": { + "version": "npm:vue-loader@16.0.0-beta.8", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.0.0-beta.8.tgz", + "integrity": "sha512-oouKUQWWHbSihqSD7mhymGPX1OQ4hedzAHyvm8RdyHh6m3oIvoRF+NM45i/bhNOlo8jCnuJhaSUf/6oDjv978g==", + "dev": true, + "optional": true, + "requires": { + "chalk": "^4.1.0", + "hash-sum": "^2.0.0", + "loader-utils": "^2.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "optional": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + } + } + }, "vue-router": { "version": "3.4.6", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.6.tgz", diff --git a/app/package.json b/app/package.json index 833b8b595b..b7996a9ef7 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "@directus/app", - "version": "9.0.0-rc.1", + "version": "9.0.0-rc.2", "private": false, "description": "Directus is an Open-Source Headless CMS & API for Managing Custom Databases", "author": "Rijk van Zanten ", diff --git a/app/src/components/v-field-template/v-field-template.vue b/app/src/components/v-field-template/v-field-template.vue index bb16483191..8caec10346 100644 --- a/app/src/components/v-field-template/v-field-template.vue +++ b/app/src/components/v-field-template/v-field-template.vue @@ -263,7 +263,7 @@ export default defineComponent({ if (part.startsWith('{{') === false) { return `${part}`; } - const fieldKey = part.replaceAll(/({|})/g, '').trim(); + const fieldKey = part.replace(/({|})/g, '').trim(); const field = findTree(tree.value, fieldKey.split('.')); if (!field) return ''; diff --git a/app/src/components/v-upload/v-upload.vue b/app/src/components/v-upload/v-upload.vue index 0b0d3b69e8..0fad1a6123 100644 --- a/app/src/components/v-upload/v-upload.vue +++ b/app/src/components/v-upload/v-upload.vue @@ -88,6 +88,7 @@ diff --git a/app/src/modules/docs/components/markdown.vue b/app/src/modules/docs/components/markdown.vue index 6e10a3025e..2a5b6bcc03 100644 --- a/app/src/modules/docs/components/markdown.vue +++ b/app/src/modules/docs/components/markdown.vue @@ -54,12 +54,9 @@ export default defineComponent({ }, }); - htmlString = htmlString.replaceAll( - hintRegex, - (match: string, type: string, title: string, body: string) => { - return `

${title}

${body}

`; - } - ); + htmlString = htmlString.replace(hintRegex, (match: string, type: string, title: string, body: string) => { + return `

${title}

${body}

`; + }); html.value = htmlString; } diff --git a/app/src/modules/docs/index.ts b/app/src/modules/docs/index.ts index 400ce4415d..2978c3e5b4 100644 --- a/app/src/modules/docs/index.ts +++ b/app/src/modules/docs/index.ts @@ -31,14 +31,14 @@ export default defineModule(({ i18n }) => { for (const doc of directory.children) { if (doc.type === 'file') { routes.push({ - path: '/' + doc.path.replace('.md', '').replaceAll('\\', '/'), + path: '/' + doc.path.replace('.md', '').replace(/\\/g, '/'), component: StaticDocs, }); } else if (doc.type === 'directory') { if (doc.path && doc.children && doc.children.length > 0) routes.push({ - path: '/' + doc.path.replaceAll('\\', '/'), - redirect: '/' + doc.children![0].path.replace('.md', '').replaceAll('\\', '/'), + path: '/' + doc.path.replace(/\\/g, '/'), + redirect: '/' + doc.children![0].path.replace('.md', '').replace(/\\/g, '/'), }); routes.push(...parseRoutes(doc)); diff --git a/app/src/modules/files/components/file-info-sidebar-detail.vue b/app/src/modules/files/components/file-info-sidebar-detail.vue index 31e9d24930..b1cc415469 100644 --- a/app/src/modules/files/components/file-info-sidebar-detail.vue +++ b/app/src/modules/files/components/file-info-sidebar-detail.vue @@ -64,10 +64,17 @@ +
+
{{ $t('file') }}
+
+ {{ $t('open') }} +
+
+
{{ $t('folder') }}
- + {{ folder ? folder.name : $t('file_library') }}
@@ -115,6 +122,7 @@ import i18n from '@/lang'; import marked from 'marked'; import localizedFormat from '@/utils/localized-format'; import api from '@/api'; +import getRootPath from '@/utils/get-root-path'; import { userName } from '@/utils/user-name'; export default defineComponent({ @@ -140,9 +148,20 @@ export default defineComponent({ const { creationDate, modificationDate } = useDates(); const { userCreated, userModified } = useUser(); - const { folder } = useFolder(); + const { folder, folderLink } = useFolder(); - return { readableMimeType, size, creationDate, modificationDate, userCreated, userModified, folder, marked }; + return { + readableMimeType, + size, + creationDate, + modificationDate, + userCreated, + userModified, + folder, + marked, + folderLink, + getRootPath, + }; function useDates() { const creationDate = ref(null); @@ -230,16 +249,23 @@ export default defineComponent({ function useFolder() { type Folder = { - id: number; + id: string; name: string; }; const loading = ref(false); const folder = ref(null); + const folderLink = computed(() => { + if (folder.value === null) { + return `/files`; + } + return `/files/?folder=${folder.value.id}`; + }); + watch(() => props.file, fetchFolder, { immediate: true }); - return { folder }; + return { folder, folderLink }; async function fetchFolder() { if (!props.file) return null; diff --git a/app/src/modules/files/components/replace-file.vue b/app/src/modules/files/components/replace-file.vue new file mode 100644 index 0000000000..ff9ed0713b --- /dev/null +++ b/app/src/modules/files/components/replace-file.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/app/src/modules/files/routes/item.vue b/app/src/modules/files/routes/item.vue index 35a624ae57..67fb6bd885 100644 --- a/app/src/modules/files/routes/item.vue +++ b/app/src/modules/files/routes/item.vue @@ -119,15 +119,13 @@ :width="item.width" :height="item.height" :title="item.title" - @click="previewActive = true" + @click="replaceFileDialogActive = true" /> - - @@ -156,7 +154,7 @@ + + @@ -184,7 +184,6 @@ import SaveOptions from '@/views/private/components/save-options'; import FilePreview from '@/views/private/components/file-preview'; import ImageEditor from '@/views/private/components/image-editor'; import { nanoid } from 'nanoid'; -import FileLightbox from '@/views/private/components/file-lightbox'; import { useFieldsStore } from '@/stores/'; import { Field } from '@/types'; import FileInfoSidebarDetail from '../components/file-info-sidebar-detail.vue'; @@ -194,6 +193,7 @@ import api from '@/api'; import getRootPath from '@/utils/get-root-path'; import FilesNotFound from './not-found.vue'; import useShortcut from '@/composables/use-shortcut'; +import ReplaceFile from '../components/replace-file.vue'; type Values = { [field: string]: any; @@ -220,10 +220,10 @@ export default defineComponent({ SaveOptions, FilePreview, ImageEditor, - FileLightbox, FileInfoSidebarDetail, FolderPicker, FilesNotFound, + ReplaceFile, }, props: { primaryKey: { @@ -236,6 +236,7 @@ export default defineComponent({ const { primaryKey } = toRefs(props); const { breadcrumb } = useBreadcrumb(); const fieldsStore = useFieldsStore(); + const replaceFileDialogActive = ref(false); const revisionsDrawerDetail = ref(null); @@ -256,13 +257,15 @@ export default defineComponent({ const hasEdits = computed(() => Object.keys(edits.value).length > 0); const confirmDelete = ref(false); - const cacheBuster = ref(nanoid()); const editActive = ref(false); - const previewActive = ref(false); const fileSrc = computed(() => { - return ( - getRootPath() + `assets/${props.primaryKey}?cache-buster=${cacheBuster.value}&key=system-large-contain` - ); + if (item.value && item.value.modified_on) { + return ( + getRootPath() + + `assets/${props.primaryKey}?cache-buster=${item.value.modified_on}&key=system-large-contain` + ); + } + return getRootPath() + `assets/${props.primaryKey}?key=system-large-contain`; }); // These are the fields that will be prevented from showing up in the form because they'll be shown in the sidebar @@ -318,10 +321,7 @@ export default defineComponent({ saveAndStay, saveAsCopyAndNavigate, isBatch, - changeCacheBuster, - cacheBuster, editActive, - previewActive, revisionsDrawerDetail, formFields, confirmLeave, @@ -335,12 +335,10 @@ export default defineComponent({ fileSrc, form, to, + replaceFileDialogActive, + refresh, }; - function changeCacheBuster() { - cacheBuster.value = nanoid(); - } - function useBreadcrumb() { const breadcrumb = computed(() => { if (!item?.value?.folder) { @@ -405,7 +403,7 @@ export default defineComponent({ const selectedFolder = ref(); watch(item, () => { - selectedFolder.value = item.value.folder; + selectedFolder.value = item.value?.folder || null; }); return { moveToDialogActive, moving, moveToFolder, selectedFolder }; diff --git a/app/src/modules/settings/routes/data-model/field-detail/store.ts b/app/src/modules/settings/routes/data-model/field-detail/store.ts index 33e0a73a6a..49cc2e55a0 100644 --- a/app/src/modules/settings/routes/data-model/field-detail/store.ts +++ b/app/src/modules/settings/routes/data-model/field-detail/store.ts @@ -67,6 +67,7 @@ function initLocalStore(collection: string, field: string, type: typeof localTyp if (inter.system === true) return false; const matchesType = inter.types.includes(state.fieldData?.type || 'alias'); + const matchesLocalType = inter.localTypes?.includes(type); let matchesRelation = false; if (type === 'standard' || type === 'presentation') { @@ -81,7 +82,7 @@ function initLocalStore(collection: string, field: string, type: typeof localTyp matchesRelation = inter.relationship === type; } - return matchesType && matchesRelation; + return matchesType && matchesRelation && (matchesLocalType === undefined || matchesLocalType); }) .sort((a, b) => (a.name > b.name ? 1 : -1)); }); diff --git a/app/src/modules/settings/routes/data-model/new-collection.vue b/app/src/modules/settings/routes/data-model/new-collection.vue index ea82121add..c864445722 100644 --- a/app/src/modules/settings/routes/data-model/new-collection.vue +++ b/app/src/modules/settings/routes/data-model/new-collection.vue @@ -304,7 +304,6 @@ export default defineComponent({ type: 'string', meta: { width: 'full', - required: true, options: { choices: [ { @@ -342,6 +341,7 @@ export default defineComponent({ }, schema: { default_value: 'draft', + is_nullable: false, }, }); diff --git a/app/src/modules/settings/routes/roles/item/item.vue b/app/src/modules/settings/routes/roles/item/item.vue index fd7161f136..3cbacd5f55 100644 --- a/app/src/modules/settings/routes/roles/item/item.vue +++ b/app/src/modules/settings/routes/roles/item/item.vue @@ -133,7 +133,7 @@ export default defineComponent({ const values = { ...item.value, ...edits.value, - }; + } as Record; return !!values.admin_access; }); diff --git a/app/src/modules/settings/routes/webhooks/item.vue b/app/src/modules/settings/routes/webhooks/item.vue index bbcb6bd156..5744bb66c0 100644 --- a/app/src/modules/settings/routes/webhooks/item.vue +++ b/app/src/modules/settings/routes/webhooks/item.vue @@ -115,7 +115,7 @@ export default defineComponent({ const title = computed(() => { if (loading.value) return i18n.t('loading'); if (isNew.value) return i18n.t('creating_webhook'); - return item.value.name; + return item.value?.name; }); return { diff --git a/app/src/modules/users/routes/item.vue b/app/src/modules/users/routes/item.vue index 9c44f53655..24c42cd262 100644 --- a/app/src/modules/users/routes/item.vue +++ b/app/src/modules/users/routes/item.vue @@ -384,7 +384,7 @@ export default defineComponent({ } async function refreshCurrentUser() { - if (userStore.state.currentUser!.id === item.value.id) { + if (userStore.state.currentUser!.id === item.value?.id) { await userStore.hydrate(); } } diff --git a/app/src/stores/fields.ts b/app/src/stores/fields.ts index 413f08cc42..452dc125ce 100644 --- a/app/src/stores/fields.ts +++ b/app/src/stores/fields.ts @@ -27,7 +27,6 @@ const fakeFilesField: Field = { display_options: null, hidden: false, locked: true, - required: false, translations: null, readonly: true, width: 'full', diff --git a/app/src/types/fields.ts b/app/src/types/fields.ts index 95488c7bc6..79e83e8ef0 100644 --- a/app/src/types/fields.ts +++ b/app/src/types/fields.ts @@ -60,7 +60,6 @@ export type FieldMeta = { options: null | Record; display_options: null | Record; readonly: boolean; - required: boolean; sort: number | null; special: string[] | null; translations: null | Translations[]; diff --git a/app/src/utils/is-allowed.ts b/app/src/utils/is-allowed.ts index 904b10c379..6555154264 100644 --- a/app/src/utils/is-allowed.ts +++ b/app/src/utils/is-allowed.ts @@ -2,7 +2,7 @@ import { usePermissionsStore, useUserStore } from '@/stores'; import { Permission } from '@/types'; import generateJoi from '@/utils/generate-joi'; -export function isAllowed(collection: string, action: Permission['action'], value: Record) { +export function isAllowed(collection: string, action: Permission['action'], value: Record | null) { const permissionsStore = usePermissionsStore(); const userStore = useUserStore(); diff --git a/app/src/utils/upload-file/upload-file.ts b/app/src/utils/upload-file/upload-file.ts index 138b4e8e3b..45f6a9d3ed 100644 --- a/app/src/utils/upload-file/upload-file.ts +++ b/app/src/utils/upload-file/upload-file.ts @@ -11,6 +11,7 @@ export default async function uploadFile( onProgressChange?: (percentage: number) => void; notifications?: boolean; preset?: Record; + fileId?: string; } ) { const progressHandler = options?.onProgressChange || (() => undefined); @@ -25,9 +26,17 @@ export default async function uploadFile( formData.append('file', file); try { - const response = await api.post(`/files`, formData, { - onUploadProgress, - }); + let response = null; + + if (options?.fileId) { + response = await api.patch(`/files/${options.fileId}`, formData, { + onUploadProgress, + }); + } else { + response = await api.post(`/files`, formData, { + onUploadProgress, + }); + } if (options?.notifications) { notify({ diff --git a/app/src/views/private/components/file-preview/file-preview.vue b/app/src/views/private/components/file-preview/file-preview.vue index 4ccc07b16d..e6c3b9cd23 100644 --- a/app/src/views/private/components/file-preview/file-preview.vue +++ b/app/src/views/private/components/file-preview/file-preview.vue @@ -1,16 +1,21 @@