Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/DIMOC-216/drag-and-drop #6

Merged
merged 2 commits into from
Aug 13, 2024
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
31 changes: 31 additions & 0 deletions css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,34 @@
color: var(--color-error);
}


/* File drag and drop */

.filesListDragDropNotice{
display: flex;
align-items: center;
justify-content: center;
width: 100%;
min-height: 113px;
margin: 0;
user-select: none;
color: var(--color-text-maxcontrast);
background-color: var(--color-main-background);
border-color: #000;
}

.filesListDragDropNoticeWrapper{
display: flex;
align-items: center;
justify-content: center;
height: 15vh;
max-height: 70%;
padding: 0 5vw;
border: 2px var(--color-border-dark) dashed;
border-radius: var(--border-radius-large);
}

.filesListDragDropNoticeTitle{
margin-left: 16px;
color: inherit;
}
95 changes: 95 additions & 0 deletions src/composables/UseFileSelection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { useDropZone, useFileDialog } from '@vueuse/core'
import { ref, computed } from 'vue'
import { publicationStore } from './../store/store.js'

/**
* File selection composable
* @param options
*
* Special thanks to Github user adamreisnz for creating most of this file
* https://github.com/adamreisnz
* https://github.com/vueuse/vueuse/issues/4085
*
*/
export function useFileSelection(options) {

// Extract options
const {
dropzone,
allowMultiple,
allowedFileTypes,
onFileDrop,
} = options

// Data types computed ref
const dataTypes = computed(() => {
if (allowedFileTypes?.value) {
if (!Array.isArray(allowedFileTypes.value)) {
return [allowedFileTypes.value]

Check failure on line 28 in src/composables/UseFileSelection.js

View workflow job for this annotation

GitHub Actions / build

Multi-line function call not indented correctly; expected 8 spaces but found 12

Check failure on line 28 in src/composables/UseFileSelection.js

View workflow job for this annotation

GitHub Actions / build

Multi-line function call not indented correctly; expected 8 spaces but found 12
}
return allowedFileTypes.value
}
return null
})

Check failure on line 34 in src/composables/UseFileSelection.js

View workflow job for this annotation

GitHub Actions / build

Multi-line function call not indented correctly; expected 8 spaces but found 12

Check failure on line 34 in src/composables/UseFileSelection.js

View workflow job for this annotation

GitHub Actions / build

Multi-line function call not indented correctly; expected 8 spaces but found 12
// Accept string computed ref
const accept = computed(() => {
if (Array.isArray(dataTypes.value)) {
return dataTypes.value.join(',')
}
return '*'
})

Check failure on line 41 in src/composables/UseFileSelection.js

View workflow job for this annotation

GitHub Actions / build

Multi-line function call not indented correctly; expected 8 spaces but found 12

Check failure on line 41 in src/composables/UseFileSelection.js

View workflow job for this annotation

GitHub Actions / build

Multi-line function call not indented correctly; expected 8 spaces but found 12

// Handling of files drop
const onDrop = files => {

Check failure on line 44 in src/composables/UseFileSelection.js

View workflow job for this annotation

GitHub Actions / build

Multi-line function call not indented correctly; expected 8 spaces but found 12

Check failure on line 44 in src/composables/UseFileSelection.js

View workflow job for this annotation

GitHub Actions / build

Multi-line function call not indented correctly; expected 8 spaces but found 12
if (!files || files.length === 0) {
return
}
if (files instanceof FileList) {
files = Array.from(files)
}
if (files.length > 1 && !allowMultiple.value) {
files = [files[0]]
}
filesList.value = files
onFileDrop && onFileDrop()
}

const reset = () => {
filesList.value = null
}

// const onLeave = () => {
// let timer
// document.addEventListener('mousemove', () => {
// clearTimeout(timer)
// timer = setTimeout(isOverDropZone.value = false, 300)
// })
// }

const setFiles = (files) => {
filesList.value = files
publicationStore.setAttachmentFile(null)
}

// Setup dropzone and file dialog composables
const { isOverDropZone } = useDropZone(dropzone, { dataTypes, onDrop })
const { onChange, open } = useFileDialog({
accept: accept.value,
multiple: allowMultiple?.value,
})

const filesList = ref(null)

// Use onChange handler
onChange(fileList => onDrop(fileList))

// Expose interface
return {
isOverDropZone,
openFileUpload: open,
files: filesList,
reset,
setFiles,
}
}
6 changes: 5 additions & 1 deletion src/modals/Modals.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
<script setup>
import { publicationStore } from './../store/store.js'
</script>

<template>
<!-- Placeholder Div -->
<div>
<AddAttachmentModal />
<AddAttachmentModal :drop-files="publicationStore.attachmentFile" />
<EditAttachmentModal />
<AddPublicationModal />
<EditPublicationModal />
Expand Down
159 changes: 94 additions & 65 deletions src/modals/attachment/AddAttachmentModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,87 +7,103 @@ import { navigationStore, publicationStore } from '../../store/store.js'
ref="modalRef"
label-id="AddAttachmentModal"
@close="navigationStore.setModal(false)">
<div class="modal__content">
<div ref="dropZoneRef" class="modal__content">
<h2>Bijlage toevoegen</h2>
<div v-if="success !== null || error">
<NcNoteCard v-if="success" type="success">
<p>Bijlage succesvol toegevoegd</p>
</NcNoteCard>
<NcNoteCard v-if="!success" type="error">
<p>Er is iets fout gegaan bij het toevoegen van bijlage</p>
</NcNoteCard>
<NcNoteCard v-if="error" type="error">
<p>{{ error }}</p>
</NcNoteCard>
</div>
<div v-if="success === null" class="form-group">
<NcTextField :disabled="(files && true) || loading"
label="Titel"
maxlength="255"
:value.sync="publicationStore.attachmentItem.title"
required />
<NcTextField :disabled="loading"
label="Samenvatting"
maxlength="255"
:value.sync="publicationStore.attachmentItem.summary" />
<NcTextArea :disabled="loading"
label="Beschrijving"
maxlength="255"
:value.sync="publicationStore.attachmentItem.description" />
<NcTextField :disabled="loading"
label="Toegangs URL"
maxlength="255"
:value.sync="publicationStore.attachmentItem.accessUrl" />
<NcTextField :disabled="(files && true) || loading"
label="Download URL"
maxlength="255"
:value.sync="publicationStore.attachmentItem.downloadUrl" />
<div class="addFileButtonGroup">
<NcButton v-if="success === null && !files"
:disabled="checkIfDisabled() || loading"
type="primary"
@click="openFileUpload()">
<template #icon>
<Plus :size="20" />
</template>
Bestand toevoegen
</NcButton>

<NcButton v-if="success === null && files"
:disabled="checkIfDisabled() || loading"
<div v-if="!isOverDropZone">
<div v-if="success !== null || error">
<NcNoteCard v-if="success" type="success">
<p>Bijlage succesvol toegevoegd</p>
</NcNoteCard>
<NcNoteCard v-if="!success" type="error">
<p>Er is iets fout gegaan bij het toevoegen van bijlage</p>
</NcNoteCard>
<NcNoteCard v-if="error" type="error">
<p>{{ error }}</p>
</NcNoteCard>
</div>
<div v-if="success === null" class="form-group">
<NcTextField :disabled="(files && true) || loading"
label="Titel"
maxlength="255"
:value.sync="publicationStore.attachmentItem.title"
required />
<NcTextField :disabled="loading"
label="Samenvatting"
maxlength="255"
:value.sync="publicationStore.attachmentItem.summary" />
<NcTextArea :disabled="loading"
label="Beschrijving"
maxlength="255"
:value.sync="publicationStore.attachmentItem.description" />
<NcTextField :disabled="loading"
label="Toegangs URL"
maxlength="255"
:value.sync="publicationStore.attachmentItem.accessUrl" />
<NcTextField :disabled="(files && true) || loading"
label="Download URL"
maxlength="255"
:value.sync="publicationStore.attachmentItem.downloadUrl" />
<div class="addFileButtonGroup">
<NcButton v-if="success === null && !files"
:disabled="checkIfDisabled() || loading"
type="primary"
@click="openFileUpload()">
<template #icon>
<Plus :size="20" />
</template>
Bestand toevoegen
</NcButton>

<NcButton v-if="success === null && files"
:disabled="checkIfDisabled() || loading"
type="primary"
@click="reset()">
<template #icon>
<Minus :size="20" />
</template>
<span v-for="file of files" :key="file.name">{{ file.name }}</span>
</NcButton>
</div>
<NcButton v-if="success === null"
:disabled="loading"
type="primary"
@click="reset()">
@click="addAttachment()">
<template #icon>
<Minus :size="20" />
<NcLoadingIcon v-if="loading" :size="20" />
<Plus v-if="!loading" :size="20" />
</template>
<span v-for="file of files" :key="file.name">{{ file.name }}</span>
Toevoegen
</NcButton>
</div>
<NcButton v-if="success === null"
:disabled="loading"
type="primary"
@click="addAttachment()">
<template #icon>
<NcLoadingIcon v-if="loading" :size="20" />
<Plus v-if="!loading" :size="20" />
</template>
Toevoegen
</NcButton>
</div>
<div v-if="isOverDropZone">
<div class="filesListDragDropNotice">
<div class="filesListDragDropNoticeWrapper">
<TrayArrowDown :size="48" />
<h3 class="filesListDragDropNoticeTitle">
Drag and drop files here to upload
</h3>
</div>
</div>
</div>
</div>
</NcModal>
</template>

<script>
import { NcButton, NcLoadingIcon, NcModal, NcNoteCard, NcTextArea, NcTextField } from '@nextcloud/vue'
import { useFileDialog } from '@vueuse/core'
import { useFileSelection } from './../../composables/UseFileSelection.js'

import { ref } from 'vue'

import Minus from 'vue-material-design-icons/Minus.vue'
import Plus from 'vue-material-design-icons/Plus.vue'
import TrayArrowDown from 'vue-material-design-icons/TrayArrowDown.vue'

import axios from 'axios'

const { files, open: openFileUpload, reset } = useFileDialog({ multiple: false })
const dropZoneRef = ref()
const { isOverDropZone, openFileUpload, files, reset, setFiles } = useFileSelection({ allowMultiple: false, dropzone: dropZoneRef })

export default {
name: 'AddAttachmentModal',
Expand All @@ -98,8 +114,13 @@ export default {
NcButton,
NcLoadingIcon,
NcNoteCard,
// Icons
Plus,
},
props: {
dropFiles: {
type: Array,
required: false,
default: null,
},
},
data() {
return {
Expand All @@ -108,14 +129,22 @@ export default {
error: false,
}
},
watch: {
dropFiles: {
handler(addedFiles) {
publicationStore.attachmentFile && setFiles(addedFiles)
},
deep: true,
},
},
mounted() {
publicationStore.setAttachmentItem([])
},
methods: {

closeModal() {
navigationStore.modal = false
},

checkIfDisabled() {
if (publicationStore.attachmentItem.downloadUrl || publicationStore.attachmentItem.title) return true
return false
Expand Down
8 changes: 8 additions & 0 deletions src/store/modules/publication.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const usePublicationStore = defineStore(
publicationList: [],
publicationDataKey: false,
attachmentItem: false,
attachmentFile: null,
publicationAttachments: false,
conceptPublications: [],
conceptAttachments: [],
Expand Down Expand Up @@ -157,6 +158,10 @@ export const usePublicationStore = defineStore(
this.attachmentItem = attachmentItem && new Attachment(attachmentItem)
console.log('Active attachment item set to ' + attachmentItem)
},
setAttachmentFile(files) {
this.attachmentFile = files
console.log('Active attachment files set to ' + files)
},
},
setPublicationList(publicationList) {
this.publicationList = publicationList.map((publicationItem) => new Publication(publicationItem))
Expand Down Expand Up @@ -254,5 +259,8 @@ export const usePublicationStore = defineStore(
this.attachmentItem = attachmentItem && new Attachment(attachmentItem)
console.log('Active attachment item set to ' + attachmentItem)
},
setAttachmentFile(files) {
this.attachmentFile = files
},
},
)
Loading
Loading