-
Notifications
You must be signed in to change notification settings - Fork 168
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rearange declined shares
- Loading branch information
Jan
authored
Jul 28, 2022
1 parent
9100cc0
commit 7747d83
Showing
5 changed files
with
424 additions
and
382 deletions.
There are no files selected for viewing
10 changes: 10 additions & 0 deletions
10
changelog/unreleased/enhancement-declined-shares-now-easily-accessible
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
286
packages/web-app-files/src/components/Shares/SharedWithMeSection.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
Oops, something went wrong.