Skip to content

Commit

Permalink
Move sharing indicators into own component and add extension point
Browse files Browse the repository at this point in the history
Moved to smaller components

Load custom indicators as part of extension

Added click handler
  • Loading branch information
LukasHirt committed Jan 29, 2020
1 parent 20f5913 commit 2f4bfff
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 79 deletions.
82 changes: 4 additions & 78 deletions apps/files/src/components/AllFilesList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,7 @@
class="uk-margin-small-left"
/>
</div>
<div>
<oc-button v-if="$_isUserShare(item)" class="file-row-share-indicator uk-text-middle" :aria-label="$_shareUserIconLabel(item)" @click="$_openSideBar(item, 'files-sharing')" variation="raw">
<oc-icon name="group" class="uk-text-middle" size="small" :variation="$_shareUserIconVariation(item)"/>
</oc-button>
<oc-button v-if="$_isLinkShare(item)" class="file-row-share-indicator uk-text-middle" :aria-label="$_shareLinkIconLabel(item)" @click="$_openSideBar(item, 'file-link')" variation="raw">
<oc-icon name="link" class="uk-text-middle" size="small" :variation="$_shareLinkIconVariation(item)"/>
</oc-button>
</div>
<StatusIndicators :item="item" :currentFolderPath="currentFolder.path" @click="$_openSideBar" />
<div class="uk-text-meta uk-text-nowrap uk-width-small" :class="{ 'uk-visible@s' : !_sidebarOpen, 'uk-hidden' : _sidebarOpen }">
{{ item.size | fileSize }}
</div>
Expand Down Expand Up @@ -75,18 +68,16 @@
<script>
import FileList from './FileList.vue'
import { mapGetters, mapActions, mapState } from 'vuex'
import { shareTypes } from '../helpers/shareTypes'
import { getParentPaths } from '../helpers/path'
import Mixins from '../mixins'
import FileActions from '../fileactions'
import intersection from 'lodash/intersection'
const userShareTypes = [shareTypes.user, shareTypes.group, shareTypes.guest, shareTypes.remote]
const StatusIndicators = () => import('./FilesLists/StatusIndicators/StatusIndicators.vue')
export default {
components: {
FileList
FileList,
StatusIndicators
},
mixins: [
Mixins,
Expand All @@ -110,46 +101,6 @@ export default {
this.$emit('sideBarOpen', item, sideBarName)
},
$_isDirectUserShare (item) {
return (intersection(userShareTypes, item.shareTypes).length > 0)
},
$_isIndirectUserShare (item) {
return (item.isReceivedShare() || intersection(userShareTypes, this.$_shareTypesIndirect).length > 0)
},
$_isDirectLinkShare (item) {
return (item.shareTypes.indexOf(shareTypes.link) >= 0)
},
$_isIndirectLinkShare (item) {
return (this.$_shareTypesIndirect.indexOf(shareTypes.link) >= 0)
},
$_isUserShare (item) {
return this.$_isDirectUserShare(item) || this.$_isIndirectUserShare(item)
},
$_isLinkShare (item) {
return this.$_isDirectLinkShare(item) || this.$_isIndirectLinkShare(item)
},
$_shareUserIconVariation (item) {
return this.$_isDirectUserShare(item) ? 'active' : 'passive'
},
$_shareLinkIconVariation (item) {
return this.$_isDirectLinkShare(item) ? 'active' : 'passive'
},
$_shareUserIconLabel (item) {
return this.$_isDirectUserShare(item) ? this.$gettext('Directly shared with collaborators') : this.$gettext('Shared with collaborators through one of the parent folders')
},
$_shareLinkIconLabel (item) {
return this.$_isDirectLinkShare(item) ? this.$gettext('Directly shared with links') : this.$gettext('Shared with links through one of the parent folders')
},
$_ocFilesFolder_getFolder () {
this.setFilterTerm('')
let absolutePath
Expand Down Expand Up @@ -223,31 +174,6 @@ export default {
return this.$route.params.item
},
$_shareTypesIndirect () {
const parentPaths = getParentPaths(this.currentFolder.path, true)
if (parentPaths.length === 0) {
return []
}
// remove root entry
parentPaths.pop()
const shareTypes = {}
parentPaths.forEach((parentPath) => {
// TODO: optimize for performance by skipping once we got all known types
const shares = this.sharesTree[parentPath]
if (shares) {
shares.forEach((share) => {
// note: no distinction between incoming and outgoing shares as we display the same
// indirect indicator for them
shareTypes[share.info.share_type] = true
})
}
})
return Object.keys(shareTypes).map(shareType => parseInt(shareType, 10))
},
quotaVisible () {
return (
!this.publicPage() &&
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<template>
<div>
<oc-button
v-for="(indicator, index) in indicators"
:key="index"
class="file-row-share-indicator uk-text-middle"
:class="{ 'uk-margin-xsmall-left' : index > 0 }"
:aria-label="indicator.label"
@click="indicator.handler(item, indicator.id)"
variation="raw"
>
<oc-icon
:name="indicator.icon"
class="uk-text-middle"
size="small"
:variation="indicator.status"
/>
</oc-button>
</div>
</template>

<script>
import intersection from 'lodash/intersection'
import { shareTypes } from '../../../helpers/shareTypes'
import { getParentPaths } from '../../../helpers/path'
const userShareTypes = [shareTypes.user, shareTypes.group, shareTypes.guest, shareTypes.remote]
export default {
name: 'StatusIndicators',
props: {
item: {
type: Object,
required: true
},
currentFolderPath: {
type: String,
required: true
}
},
computed: {
indicators () {
const indicators = []
if (this.isUserShare(this.item)) {
indicators.push({
id: 'files-sharing',
label: this.shareUserIconLabel(this.item),
icon: 'group',
status: this.shareUserIconVariation(this.item),
handler: this.indicatorHandler
})
}
if (this.isLinkShare(this.item)) {
indicators.push({
id: 'file-link',
label: this.shareLinkIconLabel(this.item),
icon: 'link',
status: this.shareLinkIconVariation(this.item),
handler: this.indicatorHandler
})
}
return indicators
},
shareTypesIndirect () {
const parentPaths = getParentPaths(this.currentFolderPath, true)
if (parentPaths.length === 0) {
return []
}
// remove root entry
parentPaths.pop()
const shareTypes = {}
parentPaths.forEach((parentPath) => {
// TODO: optimize for performance by skipping once we got all known types
const shares = this.sharesTree[parentPath]
if (shares) {
shares.forEach((share) => {
// note: no distinction between incoming and outgoing shares as we display the same
// indirect indicator for them
shareTypes[share.info.share_type] = true
})
}
})
return Object.keys(shareTypes).map(shareType => parseInt(shareType, 10))
}
},
methods: {
isDirectUserShare (item) {
return (intersection(userShareTypes, item.shareTypes).length > 0)
},
isIndirectUserShare (item) {
return (item.isReceivedShare() || intersection(userShareTypes, this.shareTypesIndirect).length > 0)
},
isDirectLinkShare (item) {
return (item.shareTypes.indexOf(shareTypes.link) >= 0)
},
isIndirectLinkShare () {
return (this.shareTypesIndirect.indexOf(shareTypes.link) >= 0)
},
isUserShare (item) {
return this.isDirectUserShare(item) || this.isIndirectUserShare(item)
},
isLinkShare (item) {
return this.isDirectLinkShare(item) || this.isIndirectLinkShare(item)
},
shareUserIconVariation (item) {
return this.isDirectUserShare(item) ? 'active' : 'passive'
},
shareLinkIconVariation (item) {
return this.isDirectLinkShare(item) ? 'active' : 'passive'
},
shareUserIconLabel (item) {
return this.isDirectUserShare(item) ? this.$gettext('Directly shared with collaborators') : this.$gettext('Shared with collaborators through one of the parent folders')
},
shareLinkIconLabel (item) {
return this.isDirectLinkShare(item) ? this.$gettext('Directly shared with links') : this.$gettext('Shared with links through one of the parent folders')
},
indicatorHandler (item, sideBarName) {
this.$emit('click', item, sideBarName)
}
}
}
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<template>
<div class="uk-flex uk-flex-middle">
<DefaultIndicators
v-if="displayDefaultIndicators"
:item="item"
:currentFolderPath="currentFolderPath"
:class="{ 'uk-margin-xsmall-right' : customIndicators }"
@click="openSidebar"
/>
<template v-if="customIndicators">
<component
v-for="(indicator, index) in customIndicators"
:is="indicator"
:key="index"
:item="item"
:currentFolderPath="currentFolderPath"
/>
</template>
</div>
</template>

<script>
import { mapGetters } from 'vuex'
const DefaultIndicators = () => import('./DefaultIndicators.vue')
export default {
name: 'StatusIndicators',
components: {
DefaultIndicators
},
props: {
item: {
type: Object,
required: true
},
currentFolderPath: {
type: String,
required: true
}
},
computed: {
...mapGetters(['configuration', 'customFilesListIndicators']),
displayDefaultIndicators () {
return !this.configuration.theme.filesList.hideDefaultStatusIndicators
},
customIndicators () {
return this.customFilesListIndicators
}
},
methods: {
// TODO: Adjust to send the event via store
openSidebar (item, indicatorId) {
this.$emit('click', item, indicatorId)
}
}
}
</script>
8 changes: 8 additions & 0 deletions changelog/unreleased/2895
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Enhancement: Add status indicator extension point

We've added the ability for the extension to inject custom status indicator into files list.
New indicators will then appear next to the default one.
We've also added ability to disable default indicators.

https://github.com/owncloud/phoenix/issues/2895
https://github.com/owncloud/phoenix/pull/2928
13 changes: 12 additions & 1 deletion src/store/apps.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const state = {
extensions: {},
newFileHandlers: [],
fileSideBars: [],
customFilesListIndicators: [],
meta: {}
}

Expand Down Expand Up @@ -118,6 +119,15 @@ const mutations = {
})
state.fileSideBars = list
}

if (appInfo.filesListIndicators) {
const indicators = state.customFilesListIndicators
appInfo.filesListIndicators.forEach(indicator => {
indicators.push(indicator)
})
state.customFilesListIndicators = indicators
}

if (!appInfo.id) return
// name: use id as fallback display name
// icon: use empty box as fallback icon
Expand Down Expand Up @@ -164,7 +174,8 @@ const getters = {
},
fileSideBars: state => {
return state.fileSideBars
}
},
customFilesListIndicators: state => state.customFilesListIndicators
}

export default {
Expand Down
3 changes: 3 additions & 0 deletions src/store/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ const state = {
},
logo: {
favicon: ''
},
filesList: {
hideDefaultStatusIndicators: false
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions themes/owncloud.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@
},
"logo": {
"favicon": "themes/owncloud/favicon.jpg"
},
"filesList": {
"hideDefaultStatusIndicators": false
}
}

0 comments on commit 2f4bfff

Please sign in to comment.