Skip to content

Commit

Permalink
Rearange declined shares (#7356)
Browse files Browse the repository at this point in the history
Rearange declined shares
  • Loading branch information
Jan authored Jul 28, 2022
1 parent 9100cc0 commit 7747d83
Show file tree
Hide file tree
Showing 5 changed files with 424 additions and 382 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Enhancement: Declined shares are now easily accessible

We've redesigned the 'Shared with me' page,
so the 'Declined shares' section is now displayed under the 'Accepted shares' section.
There is no need to click the toggle button anymore which makes the 'Declined shares' easily accessible.

https://github.com/owncloud/web/pull/7356
https://github.com/owncloud/web/issues/7342


286 changes: 286 additions & 0 deletions packages/web-app-files/src/components/Shares/SharedWithMeSection.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
<template>
<div>
<h2 class="oc-px-m oc-py-s">
{{ title }}
<span class="oc-text-initial">({{ items.length }})</span>
</h2>

<no-content-message v-if="!items.length" class="files-empty oc-flex-stretch" icon="group">
<template #message>
<span>{{ emptyMessage }}</span>
</template>
</no-content-message>
<resource-table
v-else
v-model="itemsSelected"
:data-test-share-status="shareStatus"
class="files-table"
:class="{ 'files-table-squashed': !sidebarClosed }"
:fields-displayed="displayedFields"
sidebar-closed
:are-thumbnails-displayed="displayThumbnails"
:resources="resourceItems"
:are-resources-clickable="resourceClickable"
:target-route="resourceTargetLocation"
:target-route-param-mapping="resourceTargetParamMapping"
:target-route-query-mapping="resourceTargetQueryMapping"
:header-position="fileListHeaderY"
:sort-by="sortBy"
:sort-dir="sortDir"
@fileClick="$_fileActions_triggerDefaultAction"
@rowMounted="rowMounted"
@sort="sortHandler"
>
<template #status="{ resource }">
<div
:key="resource.getDomSelector() + resource.status"
class="oc-text-nowrap oc-flex oc-flex-middle oc-flex-right"
>
<oc-button
v-if="getShowAcceptButton(resource)"
size="small"
variation="success"
class="file-row-share-status-accept"
@click.stop="$_acceptShare_trigger({ resources: [resource] })"
>
<oc-icon size="small" name="check" />
<translate>Accept</translate>
</oc-button>
<oc-button
v-if="getShowDeclineButton(resource)"
size="small"
class="file-row-share-decline oc-ml-s"
@click.stop="$_declineShare_trigger({ resources: [resource] })"
>
<oc-icon size="small" name="close" />
<translate>Decline</translate>
</oc-button>
</div>
</template>
<template #contextMenu>
<context-actions :items="itemsSelected" />
</template>
<template #footer>
<div v-if="showMoreToggle && hasMore" class="oc-width-1-1 oc-text-center oc-mt">
<oc-button
id="files-shared-with-me-show-all"
appearance="raw"
gap-size="xsmall"
size="small"
:data-test-expand="(!showMore).toString()"
@click="toggleShowMore"
>
{{ toggleMoreLabel }}
<oc-icon :name="'arrow-' + (showMore ? 'up' : 'down') + '-s'" fill-type="line" />
</oc-button>
</div>
<list-info
v-else
class="oc-width-1-1 oc-my-s"
:files="countFiles"
:folders="countFolders"
/>
</template>
</resource-table>
</div>
</template>

<script lang="ts">
import ResourceTable from '../FilesList/ResourceTable.vue'
import { computed, defineComponent, unref } from '@vue/composition-api'
import debounce from 'lodash-es/debounce'
import { ImageDimension, ImageType } from '../../constants'
import { VisibilityObserver } from 'web-pkg/src/observer'
import { mapActions, mapGetters, mapMutations, mapState } from 'vuex'
import FileActions from '../../mixins/fileActions'
import MixinAcceptShare from '../../mixins/actions/acceptShare'
import MixinDeclineShare from '../../mixins/actions/declineShare'
import MixinFilesListFilter from '../../mixins/filesListFilter'
import MixinMountSideBar from '../../mixins/sidebar/mountSideBar'
import { useResourcesViewDefaults } from '../../composables'
import { Resource } from '../../helpers/resource'
import { useCapabilityShareJailEnabled, useStore } from 'web-pkg/src/composables'
import { createLocationSpaces } from '../../router'
import ListInfo from '../../components/FilesList/ListInfo.vue'
import { ShareStatus } from '../../helpers/share'
import ContextActions from '../../components/FilesList/ContextActions.vue'
import NoContentMessage from 'web-pkg/src/components/NoContentMessage.vue'
const visibilityObserver = new VisibilityObserver()
export default defineComponent({
components: {
ResourceTable,
ContextActions,
ListInfo,
NoContentMessage
},
mixins: [
FileActions,
MixinAcceptShare,
MixinDeclineShare,
MixinMountSideBar,
MixinFilesListFilter
],
props: {
title: {
type: String,
required: true
},
emptyMessage: {
type: String,
required: false,
default: ''
},
items: {
type: Array,
required: true
},
shareStatus: {
type: Number,
required: true
},
sortBy: {
type: String,
required: true
},
sortDir: {
type: String,
required: true
},
sortHandler: {
type: Function,
required: true
},
showMoreToggle: {
type: Boolean,
default: false
},
showMoreToggleCount: {
type: Number,
default: 3
},
resourceClickable: {
type: Boolean,
default: true
},
displayThumbnails: {
type: Boolean,
default: true
}
},
setup() {
const { fileListHeaderY } = useResourcesViewDefaults<Resource, any, any[]>()
const store = useStore()
const hasShareJail = useCapabilityShareJailEnabled()
const resourceTargetLocation = computed(() =>
unref(hasShareJail)
? createLocationSpaces('files-spaces-share')
: createLocationSpaces('files-spaces-personal', {
params: { storageId: store.getters.user.id }
})
)
const resourceTargetParamMapping = computed(() =>
unref(hasShareJail) ? { name: 'shareName', path: 'item' } : undefined
)
const resourceTargetQueryMapping = computed(() =>
unref(hasShareJail) ? { id: 'shareId' } : undefined
)
return {
resourceTargetLocation,
resourceTargetParamMapping,
resourceTargetQueryMapping,
fileListHeaderY
}
},
data: () => ({
ShareStatus,
showMore: false
}),
computed: {
...mapGetters('Files', ['selectedFiles']),
...mapGetters(['configuration']),
...mapState('Files/sidebar', { sidebarClosed: 'closed' }),
displayedFields() {
return ['name', 'status', 'owner', 'sdate', 'sharedWith']
},
countFiles() {
return this.items.filter((s) => s.type !== 'folder').length
},
countFolders() {
return this.items.filter((s) => s.type === 'folder').length
},
itemsSelected: {
get() {
return this.selectedFiles
},
set(resources) {
this.SET_FILE_SELECTION(resources.filter((r) => r.status === this.shareStatus))
}
},
toggleMoreLabel() {
return this.showMore ? this.$gettext('Show less') : this.$gettext('Show more')
},
hasMore() {
return this.items.length > this.showMoreToggleCount
},
resourceItems() {
if (!this.showMoreToggle || this.showMore) {
return this.items
}
return this.items.slice(0, this.showMoreToggleCount)
}
},
beforeDestroy() {
visibilityObserver.disconnect()
},
methods: {
...mapActions('Files', ['loadIndicators', 'loadPreview', 'loadAvatars']),
...mapMutations('Files', ['LOAD_FILES', 'SET_FILE_SELECTION', 'CLEAR_CURRENT_FILES_LIST']),
rowMounted(resource, component) {
const debounced = debounce(({ unobserve }) => {
unobserve()
this.loadAvatars({ resource })
if (!this.displayThumbnails) {
return
}
this.loadPreview({
resource,
isPublic: false,
dimensions: ImageDimension.Thumbnail,
type: ImageType.Thumbnail
})
}, 250)
visibilityObserver.observe(component.$el, {
onEnter: debounced,
onExit: debounced.cancel
})
},
getShowAcceptButton(resource) {
return resource.status === ShareStatus.declined || resource.status === ShareStatus.pending
},
getShowDeclineButton(resource) {
return resource.status === ShareStatus.accepted || resource.status === ShareStatus.pending
},
toggleShowMore() {
this.showMore = !this.showMore
}
}
})
</script>

<style lang="scss" scoped>
.files-empty {
height: auto;
}
</style>
Loading

0 comments on commit 7747d83

Please sign in to comment.