Skip to content

Commit

Permalink
Introduce Shares overview page
Browse files Browse the repository at this point in the history
Introduce `active` property for navItems in shares navigation

The `active` property that's being used in the template was simply
missing in the navItems. Added it and used the chance to switch over to
composition API for the new SharesNavigation component.

Use $gettext in template directly

Not needed to define it in setup function

Finalize SharesNavigation component && adjust tests
  • Loading branch information
pascalwengerter committed Mar 8, 2022
1 parent c67c1ac commit 2854ebf
Show file tree
Hide file tree
Showing 22 changed files with 310 additions and 106 deletions.
7 changes: 7 additions & 0 deletions changelog/unreleased/enhancement-shares-overview
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Enhancement: Shares overview

We've merged the three shares navigation items into one central "Shares" item,
with a toggle to switch between the three different kinds of shares (incoming, outgoing, links).

https://github.com/owncloud/web/issues/6440
https://github.com/owncloud/web/pull/6512
36 changes: 23 additions & 13 deletions packages/web-app-files/src/components/AppBar/AppBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,22 @@
@progress="onFileProgress"
/>
<div class="files-topbar oc-py-s">
<oc-breadcrumb
v-if="breadcrumbs.length"
id="files-breadcrumb"
data-testid="files-breadcrumbs"
class="oc-py-s"
:items="breadcrumbs"
>
<template #contextMenu>
<context-actions v-if="showContextActions" :items="[currentFolder]" />
</template>
</oc-breadcrumb>
<h1 class="oc-invisible-sr" v-text="pageTitle" />
<div class="oc-flex oc-flex-between">
<oc-breadcrumb
v-if="breadcrumbs.length"
id="files-breadcrumb"
data-testid="files-breadcrumbs"
class="oc-py-s"
:items="breadcrumbs"
>
<template #contextMenu>
<context-actions v-if="showContextActions" :items="[currentFolder]" />
</template>
</oc-breadcrumb>
<shares-navigation v-if="isSharesLocation" />
<view-options v-if="!hideViewOptions" />
</div>
<div class="files-app-bar-actions">
<div
v-if="showActions || selectedFiles.length > 0 || hasBulkActions"
Expand All @@ -42,7 +46,6 @@
<size-info v-if="hasBulkActions && selectedFiles.length > 0" class="oc-mr oc-visible@l" />
<batch-actions v-if="hasBulkActions" />
</div>
<view-options v-if="!hideViewOptions" />
</div>
</div>
</div>
Expand All @@ -57,13 +60,18 @@ import MixinFileActions from '../../mixins/fileActions'
import { buildResource, buildWebDavFilesPath, buildWebDavSpacesPath } from '../../helpers/resources'
import { bus } from 'web-pkg/src/instance'
import { DavProperties } from 'web-pkg/src/constants'
import { isLocationPublicActive, isLocationSpacesActive } from '../../router'
import {
isLocationPublicActive,
isLocationSharesActive,
isLocationSpacesActive
} from '../../router'
import { useActiveLocation } from '../../composables'
import BatchActions from './SelectedResources/BatchActions.vue'
import ContextActions from '../FilesList/ContextActions.vue'
import CreateAndUpload from './CreateAndUpload.vue'
import FileDrop from './Upload/FileDrop.vue'
import SharesNavigation from './SharesNavigation.vue'
import SizeInfo from './SelectedResources/SizeInfo.vue'
import ViewOptions from './ViewOptions.vue'
Expand All @@ -73,12 +81,14 @@ export default {
ContextActions,
CreateAndUpload,
FileDrop,
SharesNavigation,
SizeInfo,
ViewOptions
},
mixins: [Mixins, MixinFileActions],
setup() {
return {
isSharesLocation: useActiveLocation(isLocationSharesActive),
isPersonalLocation: useActiveLocation(isLocationSpacesActive, 'files-spaces-personal-home'),
isPublicLocation: useActiveLocation(isLocationPublicActive, 'files-public-files'),
isSpacesProjectsLocation: useActiveLocation(isLocationSpacesActive, 'files-spaces-projects'),
Expand Down
85 changes: 85 additions & 0 deletions packages/web-app-files/src/components/AppBar/SharesNavigation.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<template>
<nav id="shares-navigation" class="oc-py-s" :aria-label="$gettext('Shares pages navigation')">
<oc-list class="oc-flex oc-visible@s">
<li v-for="navItem in navItems" :key="`shares-navigation-desktop-${navItem.to}`">
<oc-button
type="router-link"
class="oc-mr-s"
appearance="raw"
:variation="navItem.active ? 'primary' : 'passive'"
:to="navItem.to"
>
<span v-text="navItem.text" />
</oc-button>
</li>
</oc-list>
<div class="oc-hidden@s">
<oc-button id="shares_navigation_mobile" appearance="raw" v-text="$gettext('Shares pages')" />
<oc-drop toggle="#shares_navigation_mobile" mode="click" close-on-click padding-size="small">
<oc-list>
<li v-for="navItem in navItems" :key="`shares-navigation-mobile-${navItem.to}`">
<oc-button
type="router-link"
appearance="raw"
:variation="navItem.active ? 'primary' : 'passive'"
:to="navItem.to"
>
<span v-text="navItem.text" />
</oc-button>
</li>
</oc-list>
</oc-drop>
</div>
</nav>
</template>

<script>
import {
isLocationSharesActive,
locationSharesViaLink,
locationSharesWithMe,
locationSharesWithOthers
} from '../../router/shares'
import { computed, getCurrentInstance } from '@vue/composition-api'
import { useRouter } from 'web-pkg/src/composables'
export default {
setup() {
const $gettext = getCurrentInstance().proxy.$gettext
const router = useRouter()
const sharesRoutes = [
locationSharesWithMe,
locationSharesWithOthers,
locationSharesViaLink
].reduce((routes, route) => {
routes[route.name] = router.getRoutes().find((r) => r.name === route.name)
return routes
}, {})
const navItems = computed(() => [
{
to: sharesRoutes[locationSharesWithMe.name].path,
text: $gettext('Shared with me'),
active: isLocationSharesActive(router, 'files-shares-with-me')
},
{
to: sharesRoutes[locationSharesWithOthers.name].path,
text: $gettext('Shared with others'),
active: isLocationSharesActive(router, 'files-shares-with-others')
},
{
to: sharesRoutes[locationSharesViaLink.name].path,
text: $gettext('Shared via link'),
active: isLocationSharesActive(router, 'files-shares-via-link')
}
])
return {
navItems
}
}
}
</script>
<style lang="scss" scoped>
.router-link-active {
text-decoration: underline;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
v-if="!enforced && dateCurrent"
class="recipient-edit-expiration-btn-remove"
appearance="raw"
:aria-label="gettext('Remove expiration date')"
:aria-label="$gettext('Remove expiration date')"
@click="dateCurrent = null"
>
<oc-icon name="close" />
Expand Down Expand Up @@ -68,7 +68,6 @@ export default defineComponent({
setup(props, { emit }) {
const vm = getCurrentInstance().proxy
const language = computed(() => vm.$language)
const gettext = computed(() => vm.$gettext)
const store = useStore()
const capabilities = computed(() => store.getters.capabilities)
const optionsUser = computed(() => capabilities.value.files_sharing.user?.expire_date)
Expand Down Expand Up @@ -146,7 +145,6 @@ export default defineComponent({
return {
language,
gettext,
enforced,
available,
dateCurrent,
Expand Down
26 changes: 6 additions & 20 deletions packages/web-app-files/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import PrivateLink from './views/PrivateLink.vue'
import PublicFiles from './views/PublicFiles.vue'
import PublicLink from './views/PublicLink.vue'
import Personal from './views/Personal.vue'
import SharedWithMe from './views/SharedWithMe.vue'
import SharedWithOthers from './views/SharedWithOthers.vue'
import SharedViaLink from './views/SharedViaLink.vue'
import SharedWithMe from './views/shares/SharedWithMe.vue'
import SharedWithOthers from './views/shares/SharedWithOthers.vue'
import SharedViaLink from './views/shares/SharedViaLink.vue'
import SpaceProject from './views/spaces/Project.vue'
import SpaceProjects from './views/spaces/Projects.vue'
import Trashbin from './views/Trashbin.vue'
Expand Down Expand Up @@ -40,7 +40,7 @@ const appInfo = {
}
const navItems = [
{
name: $gettext('All files'),
name: $gettext('Personal'),
icon: appInfo.icon,
route: {
path: `/${appInfo.id}/spaces/personal/home`
Expand All @@ -57,24 +57,10 @@ const navItems = [
}
},
{
name: $gettext('Shared with me'),
name: $gettext('Shares'),
icon: 'share-forward',
route: {
path: `/${appInfo.id}/shares/with-me`
}
},
{
name: $gettext('Shared with others'),
icon: 'reply',
route: {
path: `/${appInfo.id}/shares/with-others`
}
},
{
name: $gettext('Shared via link'),
icon: 'link',
route: {
path: `/${appInfo.id}/shares/via-link`
path: `/${appInfo.id}/shares`
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,27 +48,27 @@

<script>
import { mapGetters, mapState, mapActions, mapMutations } from 'vuex'
import ResourceTable, { determineSortFields } from '../components/FilesList/ResourceTable.vue'
import { useFileListHeaderPosition, usePagination, useSort } from '../composables'
import ResourceTable, { determineSortFields } from '../../components/FilesList/ResourceTable.vue'
import { useFileListHeaderPosition, usePagination, useSort } from '../../composables'
import { useRouteQuery, useStore } from 'web-pkg/src/composables'
import { computed, unref } from '@vue/composition-api'
import { aggregateResourceShares } from '../helpers/resources'
import FileActions from '../mixins/fileActions'
import MixinFilesListFilter from '../mixins/filesListFilter'
import MixinResources from '../mixins/resources'
import MixinMountSideBar from '../mixins/sidebar/mountSideBar'
import { aggregateResourceShares } from '../../helpers/resources'
import FileActions from '../../mixins/fileActions'
import MixinFilesListFilter from '../../mixins/filesListFilter'
import MixinResources from '../../mixins/resources'
import MixinMountSideBar from '../../mixins/sidebar/mountSideBar'
import { VisibilityObserver } from 'web-pkg/src/observer'
import { ImageDimension, ImageType } from '../constants'
import { ImageDimension, ImageType } from '../../constants'
import debounce from 'lodash-es/debounce'
import { useTask } from 'vue-concurrency'
import ListLoader from '../components/FilesList/ListLoader.vue'
import NoContentMessage from '../components/FilesList/NoContentMessage.vue'
import ListInfo from '../components/FilesList/ListInfo.vue'
import Pagination from '../components/FilesList/Pagination.vue'
import ContextActions from '../components/FilesList/ContextActions.vue'
import { createLocationSpaces } from '../router'
import ListLoader from '../../components/FilesList/ListLoader.vue'
import NoContentMessage from '../../components/FilesList/NoContentMessage.vue'
import ListInfo from '../../components/FilesList/ListInfo.vue'
import Pagination from '../../components/FilesList/Pagination.vue'
import ContextActions from '../../components/FilesList/ContextActions.vue'
import { createLocationSpaces } from '../../router'
const visibilityObserver = new VisibilityObserver()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,27 +161,27 @@

<script>
import { mapGetters, mapState, mapActions, mapMutations } from 'vuex'
import ResourceTable, { determineSortFields } from '../components/FilesList/ResourceTable.vue'
import { aggregateResourceShares } from '../helpers/resources'
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 ResourceTable, { determineSortFields } from '../../components/FilesList/ResourceTable.vue'
import { aggregateResourceShares } from '../../helpers/resources'
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 { VisibilityObserver } from 'web-pkg/src/observer'
import { ImageDimension, ImageType } from '../constants'
import { useFileListHeaderPosition, useSort } from '../composables'
import { ImageDimension, ImageType } from '../../constants'
import { useFileListHeaderPosition, useSort } from '../../composables'
import { useRouteQuery, useStore } from 'web-pkg/src/composables'
import debounce from 'lodash-es/debounce'
import ListLoader from '../components/FilesList/ListLoader.vue'
import NoContentMessage from '../components/FilesList/NoContentMessage.vue'
import ListInfo from '../components/FilesList/ListInfo.vue'
import ContextActions from '../components/FilesList/ContextActions.vue'
import ListLoader from '../../components/FilesList/ListLoader.vue'
import NoContentMessage from '../../components/FilesList/NoContentMessage.vue'
import ListInfo from '../../components/FilesList/ListInfo.vue'
import ContextActions from '../../components/FilesList/ContextActions.vue'
import { useTask } from 'vue-concurrency'
import { ShareStatus } from '../helpers/share'
import { ShareStatus } from '../../helpers/share'
import { computed, unref } from '@vue/composition-api'
import { createLocationSpaces } from '../router'
import { createLocationSpaces } from '../../router'
const visibilityObserver = new VisibilityObserver()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,26 +51,26 @@
<script>
import { mapGetters, mapState, mapActions, mapMutations } from 'vuex'
import { computed, unref } from '@vue/composition-api'
import ResourceTable, { determineSortFields } from '../components/FilesList/ResourceTable.vue'
import ResourceTable, { determineSortFields } from '../../components/FilesList/ResourceTable.vue'
import { aggregateResourceShares } from '../helpers/resources'
import FileActions from '../mixins/fileActions'
import MixinFilesListFilter from '../mixins/filesListFilter'
import MixinResources from '../mixins/resources'
import MixinMountSideBar from '../mixins/sidebar/mountSideBar'
import { aggregateResourceShares } from '../../helpers/resources'
import FileActions from '../../mixins/fileActions'
import MixinFilesListFilter from '../../mixins/filesListFilter'
import MixinResources from '../../mixins/resources'
import MixinMountSideBar from '../../mixins/sidebar/mountSideBar'
import { VisibilityObserver } from 'web-pkg/src/observer'
import { ImageDimension, ImageType } from '../constants'
import { useFileListHeaderPosition, usePagination, useSort } from '../composables'
import { ImageDimension, ImageType } from '../../constants'
import { useFileListHeaderPosition, usePagination, useSort } from '../../composables'
import { useRouteQuery, useStore } from 'web-pkg/src/composables'
import debounce from 'lodash-es/debounce'
import { useTask } from 'vue-concurrency'
import ListLoader from '../components/FilesList/ListLoader.vue'
import NoContentMessage from '../components/FilesList/NoContentMessage.vue'
import ListInfo from '../components/FilesList/ListInfo.vue'
import Pagination from '../components/FilesList/Pagination.vue'
import ContextActions from '../components/FilesList/ContextActions.vue'
import { createLocationSpaces } from '../router'
import ListLoader from '../../components/FilesList/ListLoader.vue'
import NoContentMessage from '../../components/FilesList/NoContentMessage.vue'
import ListInfo from '../../components/FilesList/ListInfo.vue'
import Pagination from '../../components/FilesList/Pagination.vue'
import ContextActions from '../../components/FilesList/ContextActions.vue'
import { createLocationSpaces } from '../../router'
const visibilityObserver = new VisibilityObserver()
Expand Down
5 changes: 5 additions & 0 deletions packages/web-app-files/tests/integration/specs/appBar.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ describe('AppBar contains set of actions and informations', () => {
render(
AppBar,
{
setup: () => {
return {
isSharesLocation: false
}
},
store,
routes: [{ name: 'files-personal', path: '/files/list/personal/:item?/:page?' }]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import PrivateLink from '@files/src/views/PrivateLink.vue'
import PublicFiles from '@files/src/views/PublicFiles.vue'
import PublicLink from '@files/src/views/PublicLink.vue'
import Personal from '@files/src/views/Personal.vue'
import SharedWithMe from '@files/src/views/SharedWithMe.vue'
import SharedWithOthers from '@files/src/views/SharedWithOthers.vue'
import SharedViaLink from '@files/src/views/SharedViaLink.vue'
import SharedWithMe from '@files/src/views/shares/SharedWithMe.vue'
import SharedWithOthers from '@files/src/views/shares/SharedWithOthers.vue'
import SharedViaLink from '@files/src/views/shares/SharedViaLink.vue'
import SpaceProject from '@files/src/views/spaces/Project.vue'
import SpaceProjects from '@files/src/views/spaces/Projects.vue'
import Trashbin from '@files/src/views/Trashbin.vue'
Expand Down
Loading

0 comments on commit 2854ebf

Please sign in to comment.