From ce2d381ada52871f2d599d2c7deff9008e95600c Mon Sep 17 00:00:00 2001 From: Nitwel Date: Mon, 19 Oct 2020 12:44:18 +0200 Subject: [PATCH 1/6] add ability to replace file --- app/src/lang/en-US/index.json | 3 + .../components/file-info-sidebar-detail.vue | 9 +++ .../modules/files/components/replace-file.vue | 81 +++++++++++++++++++ app/src/modules/files/routes/item.vue | 12 ++- 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 app/src/modules/files/components/replace-file.vue diff --git a/app/src/lang/en-US/index.json b/app/src/lang/en-US/index.json index fad743f221..61f3a55d90 100644 --- a/app/src/lang/en-US/index.json +++ b/app/src/lang/en-US/index.json @@ -442,6 +442,8 @@ "zoom": "Zoom", "download": "Download", "open": "Open", + "or": "or", + "replace": "Replace", "foreground_color": "Foreground Color", "background_color": "Background Color", @@ -786,6 +788,7 @@ "create_folder": "Create Folder", "folder_name": "Folder Name...", "add_file": "Add File", + "replace_file": "Replace File", "no_results": "No Results", "no_results_copy": "Adjust or clear search filters to see results.", 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 18081a21b1..e58b13f934 100644 --- a/app/src/modules/files/components/file-info-sidebar-detail.vue +++ b/app/src/modules/files/components/file-info-sidebar-detail.vue @@ -64,6 +64,15 @@ +
+
{{ $t('file') }}
+
+ + {{ $t('or') }} + +
+
+
{{ $t('folder') }}
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..bdbf5be2f6 --- /dev/null +++ b/app/src/modules/files/components/replace-file.vue @@ -0,0 +1,81 @@ + + + + + diff --git a/app/src/modules/files/routes/item.vue b/app/src/modules/files/routes/item.vue index 61288d4a08..94de8d95ed 100644 --- a/app/src/modules/files/routes/item.vue +++ b/app/src/modules/files/routes/item.vue @@ -156,7 +156,11 @@ + + @@ -194,6 +200,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; @@ -224,6 +231,7 @@ export default defineComponent({ FileInfoSidebarDetail, FolderPicker, FilesNotFound, + ReplaceFile, }, props: { primaryKey: { @@ -236,6 +244,7 @@ export default defineComponent({ const { primaryKey } = toRefs(props); const { breadcrumb } = useBreadcrumb(); const fieldsStore = useFieldsStore(); + const replaceFileDialogActive = ref(false); const revisionsDrawerDetail = ref(null); @@ -335,6 +344,7 @@ export default defineComponent({ fileSrc, form, to, + replaceFileDialogActive, }; function changeCacheBuster() { From 80f7ad775548cc887907151bf57ad74add1fda29 Mon Sep 17 00:00:00 2001 From: Nitwel Date: Mon, 19 Oct 2020 19:46:24 +0200 Subject: [PATCH 2/6] redo replacing of image --- app/src/components/v-upload/v-upload.vue | 5 +++ app/src/composables/use-item/use-item.ts | 4 +- app/src/lang/en-US/index.json | 2 - .../components/file-info-sidebar-detail.vue | 33 +++++++++++---- .../modules/files/components/replace-file.vue | 38 ++++-------------- app/src/modules/files/routes/item.vue | 40 +++++++------------ app/src/utils/upload-file/upload-file.ts | 15 +++++-- app/src/utils/upload-files/upload-files.ts | 2 + .../components/file-preview/file-preview.vue | 13 ++++-- 9 files changed, 76 insertions(+), 76 deletions(-) diff --git a/app/src/components/v-upload/v-upload.vue b/app/src/components/v-upload/v-upload.vue index 0b0d3b69e8..a41167d576 100644 --- a/app/src/components/v-upload/v-upload.vue +++ b/app/src/components/v-upload/v-upload.vue @@ -103,6 +103,10 @@ export default defineComponent({ type: Object, default: () => ({}), }, + replaceWithId: { + type: String, + default: null, + }, fromUrl: { type: Boolean, default: false, @@ -160,6 +164,7 @@ export default defineComponent({ progress.value = Math.round(percentage.reduce((acc, cur) => (acc += cur)) / files.length); done.value = percentage.filter((p) => p === 100).length; }, + replaceWithId: props.replaceWithId, preset: props.preset, }); diff --git a/app/src/composables/use-item/use-item.ts b/app/src/composables/use-item/use-item.ts index ebe5e61b61..a1f0466456 100644 --- a/app/src/composables/use-item/use-item.ts +++ b/app/src/composables/use-item/use-item.ts @@ -9,7 +9,7 @@ import { APIError } from '@/types'; export function useItem(collection: Ref, primaryKey: Ref) { const { info: collectionInfo, primaryKeyField } = useCollection(collection); - const item = ref(null); + const item = ref | null>(null); const error = ref(null); const validationErrors = ref([]); const loading = ref(false); @@ -203,7 +203,7 @@ export function useItem(collection: Ref, primaryKey: Ref
{{ $t('file') }}
- - {{ $t('or') }} - + {{ $t('open') }}
{{ $t('folder') }}
- + {{ folder ? folder.name : $t('file_library') }}
@@ -124,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'; export default defineComponent({ inheritAttrs: false, @@ -148,9 +147,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); @@ -238,16 +248,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 index bdbf5be2f6..d69b917304 100644 --- a/app/src/modules/files/components/replace-file.vue +++ b/app/src/modules/files/components/replace-file.vue @@ -1,9 +1,9 @@ @@ -190,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'; @@ -227,7 +220,6 @@ export default defineComponent({ SaveOptions, FilePreview, ImageEditor, - FileLightbox, FileInfoSidebarDetail, FolderPicker, FilesNotFound, @@ -265,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 @@ -327,10 +321,7 @@ export default defineComponent({ saveAndStay, saveAsCopyAndNavigate, isBatch, - changeCacheBuster, - cacheBuster, editActive, - previewActive, revisionsDrawerDetail, formFields, confirmLeave, @@ -345,12 +336,9 @@ export default defineComponent({ form, to, replaceFileDialogActive, + refresh, }; - function changeCacheBuster() { - cacheBuster.value = nanoid(); - } - function useBreadcrumb() { const breadcrumb = computed(() => { if (!item?.value?.folder) { @@ -405,7 +393,7 @@ export default defineComponent({ } function downloadFile() { - const filePath = getRootPath() + `assets/${props.primaryKey}`; + const filePath = getRootPath() + `assets/${props.primaryKey}?download=true`; window.open(filePath, '_blank'); } @@ -415,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/utils/upload-file/upload-file.ts b/app/src/utils/upload-file/upload-file.ts index 138b4e8e3b..7be2f5420f 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; + replaceWithId?: 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?.replaceWithId !== undefined) { + response = await api.patch(`/files/${options.replaceWithId}`, formData, { + onUploadProgress, + }); + } else { + response = await api.post(`/files`, formData, { + onUploadProgress, + }); + } if (options?.notifications) { notify({ diff --git a/app/src/utils/upload-files/upload-files.ts b/app/src/utils/upload-files/upload-files.ts index 018554e184..a8816b3122 100644 --- a/app/src/utils/upload-files/upload-files.ts +++ b/app/src/utils/upload-files/upload-files.ts @@ -8,6 +8,7 @@ export default async function uploadFiles( onProgressChange?: (percentages: number[]) => void; notifications?: boolean; preset?: Record; + replaceWithId?: string; } ) { const progressHandler = options?.onProgressChange || (() => undefined); @@ -22,6 +23,7 @@ export default async function uploadFiles( progressForFiles[index] = percentage; progressHandler(progressForFiles); }, + replaceWithId: index === 0 ? options?.replaceWithId : undefined, }) ) ); 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 @@