web/satellite/vuetify-poc: allow for sharing files and folders
This change allows linksharing URLs to be generated for files and folders within the Vuetify project's file browser. Resolves #6111 Change-Id: I8cbe81b33cb5e35de0c34bba8ccc9175c727bd94
This commit is contained in:
parent
8f1682941e
commit
ec8f3b4528
@ -59,7 +59,7 @@
|
||||
</v-list-item>
|
||||
</template>
|
||||
|
||||
<v-list-item density="comfortable" link rounded="lg">
|
||||
<v-list-item density="comfortable" link rounded="lg" @click="() => emit('shareClick')">
|
||||
<template #prepend>
|
||||
<icon-share bold />
|
||||
</template>
|
||||
@ -134,6 +134,7 @@ const props = defineProps<{
|
||||
|
||||
const emit = defineEmits<{
|
||||
deleteFolderClick: [];
|
||||
shareClick: [];
|
||||
}>();
|
||||
|
||||
const isDownloading = ref<boolean>(false);
|
||||
|
@ -67,6 +67,7 @@
|
||||
<browser-row-actions
|
||||
:file="item.raw.browserObject"
|
||||
@delete-folder-click="() => onDeleteFolderClick(item.raw.browserObject)"
|
||||
@share-click="() => onShareClick(item.raw.browserObject)"
|
||||
/>
|
||||
</template>
|
||||
</v-data-table-row>
|
||||
@ -76,7 +77,18 @@
|
||||
<file-preview-dialog v-model="previewDialog" />
|
||||
</v-card>
|
||||
|
||||
<delete-folder-dialog v-if="folderToDelete" v-model="isDeleteFolderDialogShown" :folder="folderToDelete" />
|
||||
<delete-folder-dialog
|
||||
v-if="folderToDelete"
|
||||
v-model="isDeleteFolderDialogShown"
|
||||
:folder="folderToDelete"
|
||||
@content-removed="folderToDelete = null"
|
||||
/>
|
||||
<share-dialog
|
||||
v-model="isShareDialogShown"
|
||||
:bucket-name="bucketName"
|
||||
:file="fileToShare || undefined"
|
||||
@content-removed="fileToShare = null"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -107,6 +119,7 @@ import { tableSizeOptions } from '@/types/common';
|
||||
import BrowserRowActions from '@poc/components/BrowserRowActions.vue';
|
||||
import FilePreviewDialog from '@poc/components/dialogs/FilePreviewDialog.vue';
|
||||
import DeleteFolderDialog from '@poc/components/dialogs/DeleteFolderDialog.vue';
|
||||
import ShareDialog from '@poc/components/dialogs/ShareDialog.vue';
|
||||
|
||||
import folderIcon from '@poc/assets/icon-folder-tonal.svg';
|
||||
import pdfIcon from '@poc/assets/icon-pdf-tonal.svg';
|
||||
@ -164,8 +177,10 @@ const search = ref<string>('');
|
||||
const selected = ref([]);
|
||||
const previewDialog = ref<boolean>(false);
|
||||
const options = ref<TableOptions>();
|
||||
const folderToDelete = ref<BrowserObject>();
|
||||
const folderToDelete = ref<BrowserObject | null>(null);
|
||||
const isDeleteFolderDialogShown = ref<boolean>(false);
|
||||
const fileToShare = ref<BrowserObject | null>(null);
|
||||
const isShareDialogShown = ref<boolean>(false);
|
||||
|
||||
const sortBy = [{ key: 'name', order: 'asc' }];
|
||||
const headers = [
|
||||
@ -405,6 +420,14 @@ function onDeleteFolderClick(folder: BrowserObject): void {
|
||||
isDeleteFolderDialogShown.value = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles Share button click event.
|
||||
*/
|
||||
function onShareClick(file: BrowserObject): void {
|
||||
fileToShare.value = file;
|
||||
isShareDialogShown.value = true;
|
||||
}
|
||||
|
||||
watch(filePath, fetchFiles, { immediate: true });
|
||||
watch(() => props.forceEmpty, v => !v && fetchFiles());
|
||||
</script>
|
||||
|
@ -8,7 +8,7 @@
|
||||
transition="fade-transition"
|
||||
:persistent="isLoading"
|
||||
>
|
||||
<v-card rounded="xlg">
|
||||
<v-card rounded="xlg" ref="innerContent">
|
||||
<v-card-item class="pl-7 py-4">
|
||||
<template #prepend>
|
||||
<v-sheet
|
||||
@ -62,7 +62,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { computed, ref, Component, watch } from 'vue';
|
||||
import {
|
||||
VDialog,
|
||||
VCard,
|
||||
@ -91,6 +91,7 @@ const props = defineProps<{
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: boolean],
|
||||
'contentRemoved': [],
|
||||
}>();
|
||||
|
||||
const model = computed<boolean>({
|
||||
@ -104,6 +105,8 @@ const bucketsStore = useBucketsStore();
|
||||
const { isLoading, withLoading } = useLoading();
|
||||
const notify = useNotify();
|
||||
|
||||
const innerContent = ref<Component | null>(null);
|
||||
|
||||
const filePath = computed<string>(() => bucketsStore.state.fileComponentPath);
|
||||
|
||||
async function onDeleteClick(): Promise<void> {
|
||||
@ -120,4 +123,6 @@ async function onDeleteClick(): Promise<void> {
|
||||
model.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
watch(innerContent, comp => !comp && emit('contentRemoved'));
|
||||
</script>
|
||||
|
@ -42,7 +42,7 @@
|
||||
Download
|
||||
</v-tooltip>
|
||||
</v-btn>
|
||||
<v-btn icon size="small" color="white">
|
||||
<v-btn icon size="small" color="white" @click="isShareDialogShown = true">
|
||||
<icon-share size="22" />
|
||||
<v-tooltip
|
||||
activator="parent"
|
||||
@ -90,6 +90,8 @@
|
||||
</v-carousel>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<share-dialog v-model="isShareDialogShown" :bucket-name="bucketName" :file="currentFile" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -105,9 +107,7 @@ import {
|
||||
VToolbarTitle,
|
||||
VTooltip,
|
||||
} from 'vuetify/components';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import { useAppStore } from '@/store/modules/appStore';
|
||||
import { BrowserObject, useObjectBrowserStore } from '@/store/modules/objectBrowserStore';
|
||||
import { useBucketsStore } from '@/store/modules/bucketsStore';
|
||||
import { useNotify } from '@/utils/hooks';
|
||||
@ -115,15 +115,14 @@ import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames
|
||||
|
||||
import IconShare from '@poc/components/icons/IconShare.vue';
|
||||
import FilePreviewItem from '@poc/components/dialogs/filePreviewComponents/FilePreviewItem.vue';
|
||||
import ShareDialog from '@poc/components/dialogs/ShareDialog.vue';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const obStore = useObjectBrowserStore();
|
||||
const bucketsStore = useBucketsStore();
|
||||
const notify = useNotify();
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const isDownloading = ref<boolean>(false);
|
||||
const isShareDialogShown = ref<boolean>(false);
|
||||
|
||||
const folderType = 'folder';
|
||||
|
||||
@ -182,6 +181,13 @@ const currentPath = computed((): string => {
|
||||
return obStore.state.path;
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns the name of the current bucket from the store.
|
||||
*/
|
||||
const bucketName = computed((): string => {
|
||||
return bucketsStore.state.fileComponentBucketName;
|
||||
});
|
||||
|
||||
/**
|
||||
* Download the current opened file.
|
||||
*/
|
||||
|
@ -21,7 +21,7 @@
|
||||
</v-sheet>
|
||||
</template>
|
||||
<v-card-title class="font-weight-bold">
|
||||
Share {{ !filePath ? 'Bucket' : isFolder ? 'Folder' : 'File' }}
|
||||
Share {{ !file ? 'Bucket' : file.type == 'folder' ? 'Folder' : 'File' }}
|
||||
</v-card-title>
|
||||
<template #append>
|
||||
<v-btn
|
||||
@ -118,18 +118,20 @@ import { useAnalyticsStore } from '@/store/modules/analyticsStore';
|
||||
import { useNotify } from '@/utils/hooks';
|
||||
import { useLinksharing } from '@/composables/useLinksharing';
|
||||
import { SHARE_BUTTON_CONFIGS, ShareOptions } from '@/types/browser';
|
||||
import { BrowserObject } from '@/store/modules/objectBrowserStore';
|
||||
import { useBucketsStore } from '@/store/modules/bucketsStore';
|
||||
|
||||
import IconShare from '@poc/components/icons/IconShare.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean,
|
||||
bucketName: string;
|
||||
filePath?: string;
|
||||
isFolder?: boolean;
|
||||
bucketName: string,
|
||||
file?: BrowserObject,
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: boolean],
|
||||
'update:modelValue': [value: boolean];
|
||||
'contentRemoved': [];
|
||||
}>();
|
||||
|
||||
const model = computed<boolean>({
|
||||
@ -138,6 +140,7 @@ const model = computed<boolean>({
|
||||
});
|
||||
|
||||
const analyticsStore = useAnalyticsStore();
|
||||
const bucketsStore = useBucketsStore();
|
||||
|
||||
const notify = useNotify();
|
||||
const { generateBucketShareURL, generateFileOrFolderShareURL } = useLinksharing();
|
||||
@ -149,6 +152,8 @@ const link = ref<string>('');
|
||||
const copiedTimeout = ref<ReturnType<typeof setTimeout> | null>(null);
|
||||
const justCopied = computed<boolean>(() => copiedTimeout.value !== null);
|
||||
|
||||
const filePath = computed<string>(() => bucketsStore.state.fileComponentPath);
|
||||
|
||||
/**
|
||||
* Saves link to clipboard.
|
||||
*/
|
||||
@ -166,20 +171,23 @@ function onCopy(): void {
|
||||
* Generates linksharing URL when the dialog is opened.
|
||||
*/
|
||||
watch(() => innerContent.value, async (comp: Component | null): Promise<void> => {
|
||||
if (!comp) return;
|
||||
if (!comp) {
|
||||
emit('contentRemoved');
|
||||
return;
|
||||
}
|
||||
|
||||
isLoading.value = true;
|
||||
link.value = '';
|
||||
analyticsStore.eventTriggered(AnalyticsEvent.LINK_SHARED);
|
||||
|
||||
try {
|
||||
if (!props.filePath) {
|
||||
if (!props.file) {
|
||||
link.value = await generateBucketShareURL(props.bucketName);
|
||||
} else {
|
||||
link.value = await generateFileOrFolderShareURL(
|
||||
props.bucketName,
|
||||
props.filePath,
|
||||
props.isFolder,
|
||||
`${filePath.value ? filePath.value + '/' : ''}${props.file.Key}`,
|
||||
props.file.type === 'folder',
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
|
Loading…
Reference in New Issue
Block a user