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

Date range picker for trashbin #9637

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
147 changes: 147 additions & 0 deletions packages/web-app-files/src/components/FilesList/TrashbinDatePicker.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<template>
<div class="oc-flex oc-flex-row trashbin-datepicker">
<oc-datepicker
v-model="rangeSelected"
:min-date="dateMin"
:max-date="dateMax"
:locale="language.current"
:is-range="true"
class="trashbin-datepicker oc-width-1-1"
data-testid="trashbin-datepicker"
>
<template #default="{ togglePopover }">
<oc-button
class="oc-p-m action-menu-item"
data-testid="trashbin-datepicker-btn"
appearance="raw"
:aria-label="
rangeSelected ? $gettext('Edit time interval') : $gettext('Set time interval')
"
@click="togglePopover"
>
<oc-icon name="calendar-event" fill-type="line" size="medium" variation="passive" />
<span
v-if="!rangeSelected"
key="no-selected-date-label"
v-text="$gettext('Set time interval')"
/>
<span v-else key="set-selected-date-label" v-text="formatRange(rangeSelected)" />
</oc-button>
</template>
</oc-datepicker>
<oc-button
v-if="rangeSelected"
class="recipient-edit-expiration-btn-remove"
appearance="raw"
:aria-label="$gettext('Remove time interval')"
@click="rangeSelected = null"
>
<oc-icon name="close" />
</oc-button>
</div>
</template>

<script lang="ts">
import { DateTime } from 'luxon'
import { ref, computed, watch, defineComponent } from 'vue'
import { useStore } from 'web-pkg/src/composables'
import { getLocaleFromLanguage } from 'web-pkg/src/helpers'
import { useGettext } from 'vue3-gettext'
import { useRouter } from 'vue-router'

export default defineComponent({
name: 'TrashbinDatePicker',
props: {},
emits: ['rangeChanged'],
setup(props, { emit }) {
const language = useGettext()
const store = useStore()
const router = useRouter()

const dateMin = DateTime.now().setLocale(language.current).minus({ months: 6 }).toJSDate()

const dateNow = computed(() =>
DateTime.now().setLocale(getLocaleFromLanguage(language.current)).toJSDate()
)

function formatDate(date: Date) {
const day = date.getDate().toString().padStart(2, '0')
const month = (date.getMonth() + 1).toString().padStart(2, '0')
const year = date.getFullYear().toString().slice(-2)

return `${day}-${month}-${year}`
}

// const dateSelected = customRef<Date>((track, trigger) => {
// let date = dateNow.value
// return {
// get() {
// track()
// return date
// },
// set(val) {
// date = val
// trigger()
// }
// }
// })

const rangeSelected =
router.currentRoute.value.query.from && router.currentRoute.value.query.to
? ref({
start: new Date(router.currentRoute.value.query.from),
end: new Date(router.currentRoute.value.query.to)
})
: ref(null)

function formatRange(range) {
return `${formatDate(new Date(range.start))} - ${formatDate(new Date(range.end))}`
}
const dateMax = computed(() => dateNow.value)

// watch(dateSelected, (val) => {
// const dateSelected = DateTime.fromJSDate(val)
// .setLocale(getLocaleFromLanguage(language.current))
// .endOf('day')
// emit('dateChanged', {
// expirationDate: dateSelected.isValid
// ? dateSelected.toFormat("yyyy-MM-dd'T'HH:mm:ssZZZ")
// : null
// })
// })

watch(rangeSelected, (newRange, oldRange) => {
const query = { ...router.currentRoute.value.query }

if (!newRange) {
delete query.from
delete query.to
router.replace({ query })
emit('rangeChanged', { range: null })
}
if (newRange?.start && newRange.end) {
query.from = newRange.start.toISOString().slice(0, 10)
query.to = newRange.end.toISOString().slice(0, 10)

router.push({ query })
emit('rangeChanged', { range: { from: query.from, to: query.to } })
}
})

return {
language,
rangeSelected,
dateMin,
dateMax,
formatDate,
formatRange
}
}
})
</script>

<style lang="scss" scoped>
.trashbin-datepicker {
width: fit-content;
}
</style>
10 changes: 8 additions & 2 deletions packages/web-app-files/src/services/folder/loaderTrashbin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,20 @@ export class FolderLoaderTrashbin implements FolderLoader {
} = context
const hasShareJail = useCapabilityShareJailEnabled(store)

return useTask(function* (signal1, signal2, space: Resource) {
return useTask(function* (signal1, signal2, space: Resource, query) {
store.commit('Files/CLEAR_CURRENT_FILES_LIST')
store.commit('Files/SET_ANCESTOR_META_DATA', {})

const path = unref(hasShareJail)
? buildWebDavSpacesTrashPath(space.id)
: buildWebDavFilesTrashPath(space.id)
const resources = yield client.fileTrash.list(path, '1', DavProperties.Trashbin)

let resources
if (query.value) {
resources = yield client.fileTrash.list(path, '1', DavProperties.Trashbin, unref(query))
} else {
resources = yield client.fileTrash.list(path, '1', DavProperties.Trashbin)
}

store.commit('Files/LOAD_FILES', {
currentFolder: buildResource(resources[0]),
Expand Down
29 changes: 25 additions & 4 deletions packages/web-app-files/src/views/spaces/GenericTrash.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
:side-bar-open="sideBarOpen"
:space="space"
/>

<trashbin-date-picker @range-changed="rangeChanged" />
<app-loading-spinner v-if="areResourcesLoading" />
<template v-else>
<no-content-message
Expand Down Expand Up @@ -68,20 +70,22 @@ import ContextActions from '../../components/FilesList/ContextActions.vue'
import FilesViewWrapper from '../../components/FilesViewWrapper.vue'
import ListInfo from '../../components/FilesList/ListInfo.vue'
import ResourceTable from '../../components/FilesList/ResourceTable.vue'
import TrashbinDatePicker from '../../components/FilesList/TrashbinDatePicker.vue'
import SideBar from '../../components/SideBar/SideBar.vue'
import AppLoadingSpinner from 'web-pkg/src/components/AppLoadingSpinner.vue'
import NoContentMessage from 'web-pkg/src/components/NoContentMessage.vue'
import Pagination from 'web-pkg/src/components/Pagination.vue'

import { eventBus } from 'web-pkg/src/services/eventBus'
import { useResourcesViewDefaults } from '../../composables'
import { computed, defineComponent, PropType, onMounted, onBeforeUnmount, unref } from 'vue'
import { computed, defineComponent, PropType, onMounted, onBeforeUnmount, unref, ref } from 'vue'
import { Resource } from 'web-client'
import { useCapabilityShareJailEnabled, useCapabilitySpacesEnabled } from 'web-pkg/src/composables'
import { createLocationTrash } from '../../router'
import { isProjectSpaceResource, SpaceResource } from 'web-client/src/helpers'
import { useDocumentTitle } from 'web-pkg/src/composables/appDefaults/useDocumentTitle'
import { useGettext } from 'vue3-gettext'
import { useRouter } from 'vue-router'

export default defineComponent({
name: 'GenericTrash',
Expand All @@ -95,7 +99,8 @@ export default defineComponent({
NoContentMessage,
Pagination,
ResourceTable,
SideBar
SideBar,
TrashbinDatePicker
},

props: {
Expand All @@ -113,6 +118,7 @@ export default defineComponent({

setup(props) {
const { $gettext } = useGettext()
const router = useRouter()
let loadResourcesEventToken
const noContentMessage = computed(() => {
return props.space.driveType === 'personal'
Expand All @@ -130,9 +136,17 @@ export default defineComponent({
})
useDocumentTitle({ titleSegments })

const query =
router.currentRoute.value.query.from && router.currentRoute.value.query.to
? ref({
from: router.currentRoute.value.query.from,
to: router.currentRoute.value.query.to
})
: ref(null)

const resourcesViewDefaults = useResourcesViewDefaults<Resource, any, any[]>()
const performLoaderTask = async () => {
await resourcesViewDefaults.loadResourcesTask.perform(props.space)
await resourcesViewDefaults.loadResourcesTask.perform(props.space, query)
resourcesViewDefaults.refreshFileListHeaderPosition()
resourcesViewDefaults.scrollToResourceFromRoute(
unref(resourcesViewDefaults.paginatedResources)
Expand All @@ -146,14 +160,21 @@ export default defineComponent({
})
})

function rangeChanged(data) {
query.value =
data.range?.from && data.range?.to ? { from: data.range.from, to: data.range.to } : null
performLoaderTask()
}

onBeforeUnmount(() => {
eventBus.unsubscribe('app.files.list.load', loadResourcesEventToken)
})

return {
...resourcesViewDefaults,
hasShareJail: useCapabilityShareJailEnabled(),
noContentMessage
noContentMessage,
rangeChanged
}
},

Expand Down