summaryrefslogtreecommitdiffstats
path: root/apps/files_sharing/src
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_sharing/src')
-rw-r--r--apps/files_sharing/src/components/SharingEntry.vue24
-rw-r--r--apps/files_sharing/src/components/SharingEntryInherited.vue112
-rw-r--r--apps/files_sharing/src/components/SharingEntryLink.vue24
-rw-r--r--apps/files_sharing/src/components/SharingEntrySimple.vue2
-rw-r--r--apps/files_sharing/src/components/SharingInput.vue4
-rw-r--r--apps/files_sharing/src/index.js36
-rw-r--r--apps/files_sharing/src/mixins/SharesMixin.js22
-rw-r--r--apps/files_sharing/src/services/ConfigService.js55
-rw-r--r--apps/files_sharing/src/share.js12
-rw-r--r--apps/files_sharing/src/views/SharingInherited.vue164
-rw-r--r--apps/files_sharing/src/views/SharingTab.vue11
11 files changed, 423 insertions, 43 deletions
diff --git a/apps/files_sharing/src/components/SharingEntry.vue b/apps/files_sharing/src/components/SharingEntry.vue
index 09d09d607fe..4d7f60cfa61 100644
--- a/apps/files_sharing/src/components/SharingEntry.vue
+++ b/apps/files_sharing/src/components/SharingEntry.vue
@@ -119,8 +119,6 @@ import ActionInput from 'nextcloud-vue/dist/Components/ActionInput'
import ActionTextEditable from 'nextcloud-vue/dist/Components/ActionTextEditable'
import Tooltip from 'nextcloud-vue/dist/Directives/Tooltip'
-// eslint-disable-next-line no-unused-vars
-import Share from '../models/Share'
import SharesMixin from '../mixins/SharesMixin'
export default {
@@ -213,6 +211,28 @@ export default {
set: function(checked) {
this.updatePermissions(this.canEdit, checked)
}
+ },
+
+ /**
+ * Does the current share have an expiration date
+ * @returns {boolean}
+ */
+ hasExpirationDate: {
+ get: function() {
+ return this.config.isDefaultInternalExpireDateEnforced || !!this.share.expireDate
+ },
+ set: function(enabled) {
+ this.share.expireDate = enabled
+ ? this.config.defaultInternalExpirationDateString !== ''
+ ? this.config.defaultInternalExpirationDateString
+ : moment().format('YYYY-MM-DD')
+ : ''
+ }
+ },
+
+ dateMaxEnforced() {
+ return this.config.isDefaultInternalExpireDateEnforced
+ && moment().add(1 + this.config.defaultInternalExpireDate, 'days')
}
},
diff --git a/apps/files_sharing/src/components/SharingEntryInherited.vue b/apps/files_sharing/src/components/SharingEntryInherited.vue
new file mode 100644
index 00000000000..0d355ed6d22
--- /dev/null
+++ b/apps/files_sharing/src/components/SharingEntryInherited.vue
@@ -0,0 +1,112 @@
+<!--
+ - @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
+ -
+ - @author John Molakvoæ <skjnldsv@protonmail.com>
+ -
+ - @license GNU AGPL version 3 or any later version
+ -
+ - This program is free software: you can redistribute it and/or modify
+ - it under the terms of the GNU Affero General Public License as
+ - published by the Free Software Foundation, either version 3 of the
+ - License, or (at your option) any later version.
+ -
+ - This program is distributed in the hope that it will be useful,
+ - but WITHOUT ANY WARRANTY; without even the implied warranty of
+ - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ - GNU Affero General Public License for more details.
+ -
+ - You should have received a copy of the GNU Affero General Public License
+ - along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -
+ -->
+
+<template>
+ <SharingEntrySimple
+ :key="share.id"
+ class="sharing-entry__inherited"
+ :title="share.shareWithDisplayName">
+ <template #avatar>
+ <Avatar
+ :user="share.shareWith"
+ :display-name="share.shareWithDisplayName"
+ class="sharing-entry__avatar"
+ tooltip-message="" />
+ </template>
+ <ActionText icon="icon-user">
+ {{ t('files_sharing', 'Invited by {initiator}', { initiator: share.ownerDisplayName }) }}
+ </ActionText>
+ <ActionLink v-if="share.fileSource"
+ icon="icon-folder"
+ :href="fileTargetUrl">
+ {{ t('files_sharing', 'Open folder') }}
+ </ActionLink>
+ <ActionButton v-if="share.canDelete"
+ icon="icon-delete"
+ @click.prevent="onDelete">
+ {{ t('files_sharing', 'Delete share') }}
+ </actionbutton>
+ </SharingEntrySimple>
+</template>
+
+<script>
+import { generateUrl } from '@nextcloud/router'
+import Avatar from 'nextcloud-vue/dist/Components/Avatar'
+import ActionButton from 'nextcloud-vue/dist/Components/ActionButton'
+import ActionLink from 'nextcloud-vue/dist/Components/ActionLink'
+import ActionText from 'nextcloud-vue/dist/Components/ActionText'
+
+// eslint-disable-next-line no-unused-vars
+import Share from '../models/Share'
+import SharesMixin from '../mixins/SharesMixin'
+import SharingEntrySimple from '../components/SharingEntrySimple'
+
+export default {
+ name: 'SharingEntryInherited',
+
+ components: {
+ ActionButton,
+ ActionLink,
+ ActionText,
+ Avatar,
+ SharingEntrySimple
+ },
+
+ mixins: [SharesMixin],
+
+ props: {
+ share: {
+ type: Share,
+ required: true
+ }
+ },
+
+ computed: {
+ fileTargetUrl() {
+ return generateUrl('/f/{fileid}', {
+ fileid: this.share.fileSource
+ })
+ }
+ }
+}
+</script>
+
+<style lang="scss" scoped>
+.sharing-entry {
+ display: flex;
+ align-items: center;
+ height: 44px;
+ &__desc {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ padding: 8px;
+ line-height: 1.2em;
+ p {
+ color: var(--color-text-maxcontrast);
+ }
+ }
+ &__actions {
+ margin-left: auto;
+ }
+}
+</style>
diff --git a/apps/files_sharing/src/components/SharingEntryLink.vue b/apps/files_sharing/src/components/SharingEntryLink.vue
index 6e333be2491..ddfe953e339 100644
--- a/apps/files_sharing/src/components/SharingEntryLink.vue
+++ b/apps/files_sharing/src/components/SharingEntryLink.vue
@@ -380,6 +380,28 @@ export default {
},
/**
+ * Does the current share have an expiration date
+ * @returns {boolean}
+ */
+ hasExpirationDate: {
+ get: function() {
+ return this.config.isDefaultExpireDateEnforced || !!this.share.expireDate
+ },
+ set: function(enabled) {
+ this.share.expireDate = enabled
+ ? this.config.defaultExpirationDateString !== ''
+ ? this.config.defaultExpirationDateString
+ : moment().format('YYYY-MM-DD')
+ : ''
+ }
+ },
+
+ dateMaxEnforced() {
+ return this.config.isDefaultExpireDateEnforced
+ && moment().add(1 + this.config.defaultExpireDate, 'days')
+ },
+
+ /**
* Is the current share password protected ?
* @returns {boolean}
*/
@@ -735,7 +757,7 @@ export default {
.sharing-entry {
display: flex;
align-items: center;
- height: 44px;
+ min-height: 44px;
&__desc {
display: flex;
flex-direction: column;
diff --git a/apps/files_sharing/src/components/SharingEntrySimple.vue b/apps/files_sharing/src/components/SharingEntrySimple.vue
index 4538950a831..4abc5e52a90 100644
--- a/apps/files_sharing/src/components/SharingEntrySimple.vue
+++ b/apps/files_sharing/src/components/SharingEntrySimple.vue
@@ -73,7 +73,7 @@ export default {
.sharing-entry {
display: flex;
align-items: center;
- height: 44px;
+ min-height: 44px;
&__desc {
padding: 8px;
line-height: 1.2em;
diff --git a/apps/files_sharing/src/components/SharingInput.vue b/apps/files_sharing/src/components/SharingInput.vue
index ffa77f26784..8b4a115a4ba 100644
--- a/apps/files_sharing/src/components/SharingInput.vue
+++ b/apps/files_sharing/src/components/SharingInput.vue
@@ -207,8 +207,12 @@ export default {
// remove invalid data and format to user-select layout
const exactSuggestions = this.filterOutExistingShares(rawExactSuggestions)
.map(share => this.formatForMultiselect(share))
+ // sort by type so we can get user&groups first...
+ .sort((a, b) => a.shareType - b.shareType)
const suggestions = this.filterOutExistingShares(rawSuggestions)
.map(share => this.formatForMultiselect(share))
+ // sort by type so we can get user&groups first...
+ .sort((a, b) => a.shareType - b.shareType)
// lookup clickable entry
const lookupEntry = []
diff --git a/apps/files_sharing/src/index.js b/apps/files_sharing/src/index.js
new file mode 100644
index 00000000000..cc2e1c6e698
--- /dev/null
+++ b/apps/files_sharing/src/index.js
@@ -0,0 +1,36 @@
+/**
+ * @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @author John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// register default shares types
+Object.assign(OC, {
+ Share: {
+ SHARE_TYPE_USER: 0,
+ SHARE_TYPE_GROUP: 1,
+ SHARE_TYPE_LINK: 3,
+ SHARE_TYPE_EMAIL: 4,
+ SHARE_TYPE_REMOTE: 6,
+ SHARE_TYPE_CIRCLE: 7,
+ SHARE_TYPE_GUEST: 8,
+ SHARE_TYPE_REMOTE_GROUP: 9,
+ SHARE_TYPE_ROOM: 10
+ }
+})
diff --git a/apps/files_sharing/src/mixins/SharesMixin.js b/apps/files_sharing/src/mixins/SharesMixin.js
index d012f35591d..a0ec0748951 100644
--- a/apps/files_sharing/src/mixins/SharesMixin.js
+++ b/apps/files_sharing/src/mixins/SharesMixin.js
@@ -83,23 +83,6 @@ export default {
computed: {
/**
- * Does the current share have an expiration date
- * @returns {boolean}
- */
- hasExpirationDate: {
- get: function() {
- return this.config.isDefaultExpireDateEnforced || !!this.share.expireDate
- },
- set: function(enabled) {
- this.share.expireDate = enabled
- ? this.config.defaultExpirationDateString !== ''
- ? this.config.defaultExpirationDateString
- : moment().format('YYYY-MM-DD')
- : ''
- }
- },
-
- /**
* Does the current share have a note
* @returns {boolean}
*/
@@ -118,11 +101,6 @@ export default {
return moment().add(1, 'days')
},
- dateMaxEnforced() {
- return this.config.isDefaultExpireDateEnforced
- && moment().add(1 + this.config.defaultExpireDate, 'days')
- },
-
/**
* Datepicker lang values
* https://github.com/nextcloud/nextcloud-vue/pull/146
diff --git a/apps/files_sharing/src/services/ConfigService.js b/apps/files_sharing/src/services/ConfigService.js
index 7058c714776..7e0ae960c64 100644
--- a/apps/files_sharing/src/services/ConfigService.js
+++ b/apps/files_sharing/src/services/ConfigService.js
@@ -58,7 +58,7 @@ export default class Config {
}
/**
- * Get the default expiration date as string
+ * Get the default link share expiration date as string
*
* @returns {string}
* @readonly
@@ -76,6 +76,24 @@ export default class Config {
}
/**
+ * Get the default internal expiration date as string
+ *
+ * @returns {string}
+ * @readonly
+ * @memberof Config
+ */
+ get defaultInternalExpirationDateString() {
+ let expireDateString = ''
+ if (this.isDefaultInternalExpireDateEnabled) {
+ const date = window.moment.utc()
+ const expireAfterDays = this.defaultInternalExpireDate
+ date.add(expireAfterDays, 'days')
+ expireDateString = date.format('YYYY-MM-DD')
+ }
+ return expireDateString
+ }
+
+ /**
* Are link shares password-enforced ?
*
* @returns {boolean}
@@ -120,6 +138,28 @@ export default class Config {
}
/**
+ * Is internal shares expiration enforced ?
+ *
+ * @returns {boolean}
+ * @readonly
+ * @memberof Config
+ */
+ get isDefaultInternalExpireDateEnforced() {
+ return OC.appConfig.core.defaultInternalExpireDateEnforced === true
+ }
+
+ /**
+ * Is there a default expiration date for new internal shares ?
+ *
+ * @returns {boolean}
+ * @readonly
+ * @memberof Config
+ */
+ get isDefaultInternalExpireDateEnabled() {
+ return OC.appConfig.core.defaultInternalExpireDateEnabled === true
+ }
+
+ /**
* Are users on this server allowed to send shares to other servers ?
*
* @returns {boolean}
@@ -142,7 +182,7 @@ export default class Config {
}
/**
- * Get the default days to expiration
+ * Get the default days to link shares expiration
*
* @returns {int}
* @readonly
@@ -153,6 +193,17 @@ export default class Config {
}
/**
+ * Get the default days to internal shares expiration
+ *
+ * @returns {int}
+ * @readonly
+ * @memberof Config
+ */
+ get defaultInternalExpireDate() {
+ return OC.appConfig.core.defaultInternalExpireDate
+ }
+
+ /**
* Is resharing allowed ?
*
* @returns {boolean}
diff --git a/apps/files_sharing/src/share.js b/apps/files_sharing/src/share.js
index a59cfda4b12..07c367fddab 100644
--- a/apps/files_sharing/src/share.js
+++ b/apps/files_sharing/src/share.js
@@ -21,18 +21,6 @@
OCA.Sharing = {}
}
- OC.Share = _.extend(OC.Share || {}, {
- SHARE_TYPE_USER: 0,
- SHARE_TYPE_GROUP: 1,
- SHARE_TYPE_LINK: 3,
- SHARE_TYPE_EMAIL: 4,
- SHARE_TYPE_REMOTE: 6,
- SHARE_TYPE_CIRCLE: 7,
- SHARE_TYPE_GUEST: 8,
- SHARE_TYPE_REMOTE_GROUP: 9,
- SHARE_TYPE_ROOM: 10
- })
-
/**
* @namespace
*/
diff --git a/apps/files_sharing/src/views/SharingInherited.vue b/apps/files_sharing/src/views/SharingInherited.vue
new file mode 100644
index 00000000000..be3c5ef2dc3
--- /dev/null
+++ b/apps/files_sharing/src/views/SharingInherited.vue
@@ -0,0 +1,164 @@
+<!--
+ - @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
+ -
+ - @author John Molakvoæ <skjnldsv@protonmail.com>
+ -
+ - @license GNU AGPL version 3 or any later version
+ -
+ - This program is free software: you can redistribute it and/or modify
+ - it under the terms of the GNU Affero General Public License as
+ - published by the Free Software Foundation, either version 3 of the
+ - License, or (at your option) any later version.
+ -
+ - This program is distributed in the hope that it will be useful,
+ - but WITHOUT ANY WARRANTY; without even the implied warranty of
+ - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ - GNU Affero General Public License for more details.
+ -
+ - You should have received a copy of the GNU Affero General Public License
+ - along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -
+ -->
+
+<template>
+ <ul id="sharing-inherited-shares">
+ <!-- Main collapsible entry -->
+ <SharingEntrySimple
+ class="sharing-entry__inherited"
+ :title="mainTitle">
+ <template #avatar>
+ <div class="avatar-shared icon-more-white" />
+ </template>
+ <ActionButton :icon="showInheritedSharesIcon" @click.prevent.stop="toggleInheritedShares">
+ {{ toggleTooltip }}
+ </ActionButton>
+ </SharingEntrySimple>
+
+ <!-- Inherited shares list -->
+ <SharingEntryInherited v-for="share in shares"
+ :key="share.id"
+ :share="share" />
+ </ul>
+</template>
+
+<script>
+import { generateOcsUrl } from '@nextcloud/router'
+import ActionButton from 'nextcloud-vue/dist/Components/ActionButton'
+import axios from '@nextcloud/axios'
+
+import Share from '../models/Share'
+import SharingEntryInherited from '../components/SharingEntryInherited'
+import SharingEntrySimple from '../components/SharingEntrySimple'
+
+export default {
+ name: 'SharingInherited',
+
+ components: {
+ ActionButton,
+ SharingEntryInherited,
+ SharingEntrySimple
+ },
+
+ props: {
+ fileInfo: {
+ type: Object,
+ default: () => {},
+ required: true
+ }
+ },
+
+ data() {
+ return {
+ loaded: false,
+ loading: false,
+ showInheritedShares: false,
+ shares: []
+ }
+ },
+ computed: {
+ showInheritedSharesIcon() {
+ if (this.loading) {
+ return 'icon-loading-small'
+ }
+ if (this.showInheritedShares) {
+ return 'icon-triangle-n'
+ }
+ return 'icon-triangle-s'
+ },
+ mainTitle() {
+ return t('files_sharing', 'Others with access {count}', {
+ count: this.loaded ? `: ${this.shares.length}` : ''
+ })
+ },
+ toggleTooltip() {
+ return this.fileInfo.type === 'dir'
+ ? t('files_sharing', 'Toggle list of others with access to this directory')
+ : t('files_sharing', 'Toggle list of others with access to this file')
+ },
+ fullPath() {
+ const path = `${this.fileInfo.path}/${this.fileInfo.name}`
+ return path.replace('//', '/')
+ }
+ },
+ watch: {
+ fileInfo() {
+ this.resetState()
+ }
+ },
+ methods: {
+ /**
+ * Toggle the list view and fetch/reset the state
+ */
+ toggleInheritedShares() {
+ this.showInheritedShares = !this.showInheritedShares
+ if (this.showInheritedShares) {
+ this.fetchInheritedShares()
+ } else {
+ this.resetState()
+ }
+ },
+ /**
+ * Fetch the Inherited Shares array
+ */
+ async fetchInheritedShares() {
+ this.loading = true
+ try {
+ const url = generateOcsUrl(`apps/files_sharing/api/v1/shares/inherited?format=json&path=${this.fullPath}`, 2)
+ const shares = await axios.get(url.replace(/\/$/, ''))
+ this.shares = shares.data.ocs.data
+ .map(share => new Share(share))
+ .sort((a, b) => b.createdTime - a.createdTime)
+ console.info(this.shares)
+ this.loaded = true
+ } catch (error) {
+ OC.Notification.showTemporary(t('files_sharing', 'Unable to fetch inherited shares'), { type: 'error' })
+ } finally {
+ this.loading = false
+ }
+ },
+ /**
+ * Reset current component state
+ */
+ resetState() {
+ this.loaded = false
+ this.loading = false
+ this.showInheritedShares = false
+ this.shares = []
+ }
+ }
+}
+</script>
+
+<style lang="scss" scoped>
+.sharing-entry__inherited {
+ .avatar-shared {
+ width: 32px;
+ height: 32px;
+ line-height: 32px;
+ font-size: 18px;
+ background-color: var(--color-text-maxcontrast);
+ border-radius: 50%;
+ flex-shrink: 0;
+ }
+}
+</style>
diff --git a/apps/files_sharing/src/views/SharingTab.vue b/apps/files_sharing/src/views/SharingTab.vue
index 216b2e74ffc..b15ec5e9a64 100644
--- a/apps/files_sharing/src/views/SharingTab.vue
+++ b/apps/files_sharing/src/views/SharingTab.vue
@@ -33,7 +33,7 @@
<!-- shared with me information -->
<SharingEntrySimple v-if="isSharedWithMe" v-bind="sharedWithMe" class="sharing-entry__reshare">
<template #avatar>
- <Avatar #avatar
+ <Avatar
:user="sharedWithMe.user"
:display-name="sharedWithMe.displayName"
class="sharing-entry__avatar"
@@ -61,6 +61,9 @@
:shares="shares"
:file-info="fileInfo" />
+ <!-- inherited shares -->
+ <SharingInherited v-if="!loading" :file-info="fileInfo" />
+
<!-- internal link copy -->
<SharingEntryInternal :file-info="fileInfo" />
@@ -82,11 +85,11 @@
</template>
<script>
+import { CollectionList } from 'nextcloud-vue-collections'
import { generateOcsUrl } from '@nextcloud/router'
-import Tab from 'nextcloud-vue/dist/Components/AppSidebarTab'
import Avatar from 'nextcloud-vue/dist/Components/Avatar'
import axios from '@nextcloud/axios'
-import { CollectionList } from 'nextcloud-vue-collections'
+import Tab from 'nextcloud-vue/dist/Components/AppSidebarTab'
import { shareWithTitle } from '../utils/SharedWithMe'
import Share from '../models/Share'
@@ -95,6 +98,7 @@ import SharingEntryInternal from '../components/SharingEntryInternal'
import SharingEntrySimple from '../components/SharingEntrySimple'
import SharingInput from '../components/SharingInput'
+import SharingInherited from './SharingInherited'
import SharingLinkList from './SharingLinkList'
import SharingList from './SharingList'
@@ -106,6 +110,7 @@ export default {
CollectionList,
SharingEntryInternal,
SharingEntrySimple,
+ SharingInherited,
SharingInput,
SharingLinkList,
SharingList,