Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 83 additions & 107 deletions packages/web-app-files/src/components/AppBar/Upload/ResourceUpload.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
v-oc-tooltip="
isRemoteUploadInProgress ? $gettext('Please wait until all imports have finished') : null
"
class="relative overflow-hidden"
>
<oc-button
:class="btnClass"
Expand All @@ -27,129 +28,104 @@
</div>
</template>

<script lang="ts">
import {
computed,
defineComponent,
onMounted,
onBeforeUnmount,
ref,
unref,
useTemplateRef
} from 'vue'
<script setup lang="ts">
import { computed, onMounted, onBeforeUnmount, ref, unref, useTemplateRef } from 'vue'
import { Resource } from '@opencloud-eu/web-client'
import { useService, ResourceIcon, convertToMinimalUppyFile } from '@opencloud-eu/web-pkg'
import type { UppyService } from '@opencloud-eu/web-pkg'
import { getItemsViaDirectoryPicker } from '../../../helpers/directoryPicker'
import { useGettext } from 'vue3-gettext'
export default defineComponent({
components: { ResourceIcon },
props: {
btnLabel: {
type: String,
required: false,
default: ''
},
btnClass: {
type: String,
required: false,
default: ''
},
isFolder: {
type: Boolean,
required: false,
default: false
}
},
setup(props) {
const uppyService = useService<UppyService>('$uppyService')
const input = useTemplateRef<HTMLInputElement>('input')
const {
btnLabel = '',
btnClass = '',
isFolder = false
} = defineProps<{
btnLabel?: string
btnClass?: string
isFolder?: boolean
}>()
const { $gettext } = useGettext()
const uppyService = useService<UppyService>('$uppyService')
const input = useTemplateRef<HTMLInputElement>('input')
const isRemoteUploadInProgress = ref(uppyService.isRemoteUploadInProgress())
const isRemoteUploadInProgress = ref(uppyService.isRemoteUploadInProgress())
let uploadStartedSub: string
let uploadCompletedSub: string
let uploadStartedSub: string
let uploadCompletedSub: string
const resource = computed(() => {
return { extension: '', isFolder: props.isFolder } as Resource
})
const resource = computed(() => {
return { extension: '', isFolder } as Resource
})
const onUploadStarted = () =>
(isRemoteUploadInProgress.value = uppyService.isRemoteUploadInProgress())
const onUploadCompleted = () => (isRemoteUploadInProgress.value = false)
const onUploadStarted = () =>
(isRemoteUploadInProgress.value = uppyService.isRemoteUploadInProgress())
const onUploadCompleted = () => (isRemoteUploadInProgress.value = false)
const triggerUpload = async () => {
if (!props.isFolder || typeof (window as any).showDirectoryPicker !== 'function') {
// use native file picker for file uploads or if browser does not support the Directory API
unref(input).click()
return
}
const triggerUpload = async () => {
if (!isFolder || typeof (window as any).showDirectoryPicker !== 'function') {
// use native file picker for file uploads or if browser does not support the Directory API
unref(input).click()
return
}
try {
// use the Directory API so we can retrieve empty folders
const items = await getItemsViaDirectoryPicker((error) => uppyService.log(error))
const uppyFiles = convertToMinimalUppyFile('FolderUpload', items)
uppyService.addFiles(uppyFiles)
} catch (error) {
if (error.name !== 'AbortError') {
// AbortError means the user closed the picker. in any other case
// we assume something went wrong and we fall back to the native picker.
console.error('Error using DirectoryPicker, falling back to the native one:', error)
unref(input).click()
}
}
try {
// use the Directory API so we can retrieve empty folders
const items = await getItemsViaDirectoryPicker((error) => uppyService.log(error))
const uppyFiles = convertToMinimalUppyFile('FolderUpload', items)
uppyService.addFiles(uppyFiles)
} catch (error) {
if (error.name !== 'AbortError') {
// AbortError means the user closed the picker. in any other case
// we assume something went wrong and we fall back to the native picker.
console.error('Error using DirectoryPicker, falling back to the native one:', error)
unref(input).click()
}
}
}
onMounted(() => {
uploadStartedSub = uppyService.subscribe('uploadStarted', onUploadStarted)
uploadCompletedSub = uppyService.subscribe('uploadCompleted', onUploadCompleted)
uppyService.registerUploadInput(unref(input))
})
onMounted(() => {
uploadStartedSub = uppyService.subscribe('uploadStarted', onUploadStarted)
uploadCompletedSub = uppyService.subscribe('uploadCompleted', onUploadCompleted)
uppyService.registerUploadInput(unref(input))
})
onBeforeUnmount(() => {
uppyService.unsubscribe('uploadStarted', uploadStartedSub)
uppyService.unsubscribe('uploadCompleted', uploadCompletedSub)
uppyService.removeUploadInput(unref(input))
})
onBeforeUnmount(() => {
uppyService.unsubscribe('uploadStarted', uploadStartedSub)
uppyService.unsubscribe('uploadCompleted', uploadCompletedSub)
uppyService.removeUploadInput(unref(input))
})
const inputId = computed(() => {
if (isFolder) {
return 'files-folder-upload-input'
}
return 'files-file-upload-input'
})
const uploadLabelId = computed(() => {
if (isFolder) {
return 'files-folder-upload-button'
}
return 'files-file-upload-button'
})
const buttonLabel = computed(() => {
if (btnLabel) {
return btnLabel
}
if (isFolder) {
return $gettext('Folder')
}
return $gettext('Files')
})
const inputAttrs = computed(() => {
if (isFolder) {
return {
isRemoteUploadInProgress,
resource,
input,
triggerUpload
}
},
computed: {
inputId() {
if (this.isFolder) {
return 'files-folder-upload-input'
}
return 'files-file-upload-input'
},
uploadLabelId() {
if (this.isFolder) {
return 'files-folder-upload-button'
}
return 'files-file-upload-button'
},
buttonLabel() {
if (this.btnLabel) {
return this.btnLabel
}
if (this.isFolder) {
return this.$gettext('Folder')
}
return this.$gettext('Files')
},
inputAttrs() {
if (this.isFolder) {
return {
webkitdirectory: true,
mozdirectory: true,
allowdirs: true
}
}
return { multiple: true }
webkitdirectory: true,
mozdirectory: true,
allowdirs: true
}
}
return { multiple: true }
})
</script>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Resource Upload Component > file upload > should render component 1`] = `
"<div><button type="button" class="oc-button-secondary oc-button-raw oc-button-secondary-raw gap-2 justify-start text-base min-h-4 oc-button cursor-pointer disabled:opacity-60 disabled:cursor-default">
"<div class="relative overflow-hidden"><button type="button" class="oc-button-secondary oc-button-raw oc-button-secondary-raw gap-2 justify-start text-base min-h-4 oc-button cursor-pointer disabled:opacity-60 disabled:cursor-default">
<!--v-if-->
<!-- @slot Content of the button --> <span class="oc-icon box-content inline-block align-baseline [&amp;_svg]:block size-5.5 oc-resource-icon inline-flex items-center [&amp;_svg]:h-[70%] [&amp;_svg]:h-5.5! sm:[&amp;_svg]:h-full"><svg data-testid="inline-svg-stub" src="icons/resource-type-file-fill.svg" transform-source="(svg) => {
if (__props.accessibleLabel !== &quot;&quot;) {
Expand All @@ -16,7 +16,7 @@ exports[`Resource Upload Component > file upload > should render component 1`] =
`;

exports[`Resource Upload Component > folder upload > should render component 1`] = `
"<div><button type="button" class="oc-button-secondary oc-button-raw oc-button-secondary-raw gap-2 justify-start text-base min-h-4 oc-button cursor-pointer disabled:opacity-60 disabled:cursor-default">
"<div class="relative overflow-hidden"><button type="button" class="oc-button-secondary oc-button-raw oc-button-secondary-raw gap-2 justify-start text-base min-h-4 oc-button cursor-pointer disabled:opacity-60 disabled:cursor-default">
<!--v-if-->
<!-- @slot Content of the button --> <span class="oc-icon box-content inline-block align-baseline [&amp;_svg]:block size-5.5 oc-resource-icon inline-flex items-center [&amp;_svg]:h-5.5! sm:[&amp;_svg]:h-full"><svg data-testid="inline-svg-stub" src="icons/resource-type-folder-fill.svg" transform-source="(svg) => {
if (__props.accessibleLabel !== &quot;&quot;) {
Expand Down