aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/files_sharing/src/components/SharingEntryLink.vue10
-rw-r--r--apps/files_sharing/src/mixins/SharesMixin.js16
-rw-r--r--apps/files_sharing/src/views/SharingDetailsTab.vue366
-rw-r--r--apps/files_sharing/src/views/SharingTab.vue18
4 files changed, 217 insertions, 193 deletions
diff --git a/apps/files_sharing/src/components/SharingEntryLink.vue b/apps/files_sharing/src/components/SharingEntryLink.vue
index 896ca1bbc95..9218d7afe2e 100644
--- a/apps/files_sharing/src/components/SharingEntryLink.vue
+++ b/apps/files_sharing/src/components/SharingEntryLink.vue
@@ -97,13 +97,13 @@
</NcActionText>
<NcActionInput v-if="pendingExpirationDate"
class="share-link-expire-date"
- :disabled="saving || isExpiryDateEnforced"
+ :disabled="saving"
:is-native-picker="true"
:hide-label="true"
:value="new Date(share.expireDate)"
type="date"
:min="dateTomorrow"
- :max="dateMaxEnforced"
+ :max="maxExpirationDateEnforced"
@input="onExpirationChange">
<!-- let's not submit when picked, the user
might want to still edit or copy the password -->
@@ -302,12 +302,6 @@ export default {
}
return null
},
- dateMaxEnforced() {
- if (this.config.isDefaultExpireDateEnforced) {
- return new Date(new Date().setDate(new Date().getDate() + this.config.defaultExpireDate))
- }
- return null
- },
/**
* Is the current share password protected ?
*
diff --git a/apps/files_sharing/src/mixins/SharesMixin.js b/apps/files_sharing/src/mixins/SharesMixin.js
index 860d1716fe0..41bdf302f7a 100644
--- a/apps/files_sharing/src/mixins/SharesMixin.js
+++ b/apps/files_sharing/src/mixins/SharesMixin.js
@@ -132,6 +132,9 @@ export default {
const shareType = this.share.shareType ?? this.share.type
return [this.SHARE_TYPES.SHARE_TYPE_LINK, this.SHARE_TYPES.SHARE_TYPE_EMAIL].includes(shareType)
},
+ isRemoteShare() {
+ return this.share.type === this.SHARE_TYPES.SHARE_TYPE_REMOTE_GROUP || this.share.type === this.SHARE_TYPES.SHARE_TYPE_REMOTE
+ },
isShareOwner() {
return this.share && this.share.owner === getCurrentUser().uid
},
@@ -152,6 +155,19 @@ export default {
]
return !bundledPermissions.includes(this.share.permissions)
},
+ maxExpirationDateEnforced() {
+ if (this.isExpiryDateEnforced) {
+ if (this.isPublicShare) {
+ return this.config.defaultExpirationDate
+ }
+ if (this.isRemoteShare) {
+ return this.config.defaultRemoteExpirationDateString
+ }
+ // If it get's here then it must be an internal share
+ return this.config.defaultInternalExpirationDate
+ }
+ return null
+ },
},
methods: {
diff --git a/apps/files_sharing/src/views/SharingDetailsTab.vue b/apps/files_sharing/src/views/SharingDetailsTab.vue
index a398829dbb0..580d24eae58 100644
--- a/apps/files_sharing/src/views/SharingDetailsTab.vue
+++ b/apps/files_sharing/src/views/SharingDetailsTab.vue
@@ -15,169 +15,179 @@
<h1>{{ title }}</h1>
</span>
</div>
- <div class="sharingTabDetailsView__quick-permissions">
- <div>
- <NcCheckboxRadioSwitch :button-variant="true"
- :checked.sync="sharingPermission"
- :value="bundledPermissions.READ_ONLY.toString()"
- name="sharing_permission_radio"
- type="radio"
- button-variant-grouped="vertical"
- @update:checked="toggleCustomPermissions">
- <ViewIcon :size="20" />
- <span>{{ t('files_sharing', 'View only') }}</span>
- </NcCheckboxRadioSwitch>
- <NcCheckboxRadioSwitch :button-variant="true"
- :checked.sync="sharingPermission"
- :value="bundledPermissions.ALL.toString()"
- name="sharing_permission_radio"
- type="radio"
- button-variant-grouped="vertical"
- @update:checked="toggleCustomPermissions">
- <EditIcon :size="20" />
- <template v-if="allowsFileDrop">
- <span>{{ t('files_sharing', 'Allow upload and editing') }}</span>
- </template>
- <template v-else>
- <span>{{ t('files_sharing', 'Allow editing') }}</span>
+ <div class="sharingTabDetailsView__wrapper">
+ <div ref="quickPermissions"
+ class="sharingTabDetailsView__quick-permissions">
+ <div>
+ <NcCheckboxRadioSwitch :button-variant="true"
+ :checked.sync="sharingPermission"
+ :value="bundledPermissions.READ_ONLY.toString()"
+ name="sharing_permission_radio"
+ type="radio"
+ button-variant-grouped="vertical"
+ @update:checked="toggleCustomPermissions">
+ <ViewIcon :size="20" />
+ <span>{{ t('files_sharing', 'View only') }}</span>
+ </NcCheckboxRadioSwitch>
+ <NcCheckboxRadioSwitch :button-variant="true"
+ :checked.sync="sharingPermission"
+ :value="bundledPermissions.ALL.toString()"
+ name="sharing_permission_radio"
+ type="radio"
+ button-variant-grouped="vertical"
+ @update:checked="toggleCustomPermissions">
+ <EditIcon :size="20" />
+ <template v-if="allowsFileDrop">
+ <span>{{ t('files_sharing', 'Allow upload and editing') }}</span>
+ </template>
+ <template v-else>
+ <span>{{ t('files_sharing', 'Allow editing') }}</span>
+ </template>
+ </NcCheckboxRadioSwitch>
+ <NcCheckboxRadioSwitch v-if="allowsFileDrop"
+ :button-variant="true"
+ :checked.sync="sharingPermission"
+ :value="bundledPermissions.FILE_DROP.toString()"
+ name="sharing_permission_radio"
+ type="radio"
+ button-variant-grouped="vertical"
+ @update:checked="toggleCustomPermissions">
+ <UploadIcon :size="20" />
+ <span>{{ t('files_sharing', 'File drop') }}</span>
+ <small>{{ t('files_sharing', 'Upload only') }}</small>
+ </NcCheckboxRadioSwitch>
+ <NcCheckboxRadioSwitch :button-variant="true"
+ :checked.sync="sharingPermission"
+ :value="'custom'"
+ name="sharing_permission_radio"
+ type="radio"
+ button-variant-grouped="vertical"
+ @update:checked="expandCustomPermissions">
+ <DotsHorizontalIcon :size="20" />
+ <span>{{ t('files_sharing', 'Custom permissions') }}</span>
+ <small>{{ customPermissionsList }}</small>
+ </NcCheckboxRadioSwitch>
+ </div>
+ </div>
+ <div class="sharingTabDetailsView__advanced-control">
+ <NcButton id="advancedSectionAccordionAdvancedControl"
+ type="tertiary"
+ alignment="end-reverse"
+ @click="advancedSectionAccordionExpanded = !advancedSectionAccordionExpanded">
+ {{ t('files_sharing', 'Advanced settings') }}
+ <template #icon>
+ <MenuDownIcon />
</template>
- </NcCheckboxRadioSwitch>
- <NcCheckboxRadioSwitch v-if="allowsFileDrop"
- :button-variant="true"
- :checked.sync="sharingPermission"
- :value="bundledPermissions.FILE_DROP.toString()"
- name="sharing_permission_radio"
- type="radio"
- button-variant-grouped="vertical"
- @update:checked="toggleCustomPermissions">
- <UploadIcon :size="20" />
- <span>{{ t('files_sharing', 'File drop') }}</span>
- <small>{{ t('files_sharing', 'Upload only') }}</small>
- </NcCheckboxRadioSwitch>
- <NcCheckboxRadioSwitch :button-variant="true"
- :checked.sync="sharingPermission"
- :value="'custom'"
- name="sharing_permission_radio"
- type="radio"
- button-variant-grouped="vertical"
- @update:checked="expandCustomPermissions">
- <DotsHorizontalIcon :size="20" />
- <span>{{ t('files_sharing', 'Custom permissions') }}</span>
- <small>{{ customPermissionsList }}</small>
- </NcCheckboxRadioSwitch>
+ </NcButton>
</div>
- </div>
- <div class="sharingTabDetailsView__advanced-control">
- <NcButton type="tertiary"
- alignment="end-reverse"
- @click="advancedSectionAccordionExpanded = !advancedSectionAccordionExpanded">
- {{ t('files_sharing', 'Advanced settings') }}
- <template #icon>
- <MenuDownIcon />
- </template>
- </NcButton>
- </div>
- <div v-if="advancedSectionAccordionExpanded" class="sharingTabDetailsView__advanced">
- <section>
- <NcInputField v-if="isPublicShare"
- :value.sync="share.label"
- type="text"
- :label="t('files_sharing', 'Share label')" />
- <template v-if="isPublicShare">
- <NcCheckboxRadioSwitch :checked.sync="isPasswordProtected" :disabled="isPasswordEnforced">
- {{ t('files_sharing', 'Set password') }}
+ <div v-if="advancedSectionAccordionExpanded"
+ id="advancedSectionAccordionAdvanced"
+ class="sharingTabDetailsView__advanced"
+ aria-labelledby="advancedSectionAccordionAdvancedControl"
+ role="region">
+ <section>
+ <NcInputField v-if="isPublicShare"
+ :value.sync="share.label"
+ type="text"
+ :label="t('files_sharing', 'Share label')" />
+ <template v-if="isPublicShare">
+ <NcCheckboxRadioSwitch :checked.sync="isPasswordProtected" :disabled="isPasswordEnforced">
+ {{ t('files_sharing', 'Set password') }}
+ </NcCheckboxRadioSwitch>
+ <NcInputField v-if="isPasswordProtected"
+ :type="hasUnsavedPassword ? 'text' : 'password'"
+ :value="hasUnsavedPassword ? share.newPassword : '***************'"
+ :error="passwordError"
+ :required="isPasswordEnforced"
+ :label="t('files_sharing', 'Password')"
+ @update:value="onPasswordChange" />
+
+ <!-- Migrate icons and remote -> icon="icon-info"-->
+ <span v-if="isEmailShareType && passwordExpirationTime" icon="icon-info">
+ {{ t('files_sharing', 'Password expires {passwordExpirationTime}', { passwordExpirationTime }) }}
+ </span>
+ <span v-else-if="isEmailShareType && passwordExpirationTime !== null" icon="icon-error">
+ {{ t('files_sharing', 'Password expired') }}
+ </span>
+ </template>
+ <NcCheckboxRadioSwitch :checked.sync="hasExpirationDate" :disabled="isExpiryDateEnforced">
+ {{ isExpiryDateEnforced
+ ? t('files_sharing', 'Expiration date (enforced)')
+ : t('files_sharing', 'Set expiration date') }}
</NcCheckboxRadioSwitch>
- <NcInputField v-if="isPasswordProtected"
- :type="hasUnsavedPassword ? 'text' : 'password'"
- :value="hasUnsavedPassword ? share.newPassword : '***************'"
- :error="passwordError"
- :required="isPasswordEnforced"
- :label="t('files_sharing', 'Password')"
- @update:value="onPasswordChange" />
-
- <!-- Migrate icons and remote -> icon="icon-info"-->
- <span v-if="isEmailShareType && passwordExpirationTime" icon="icon-info">
- {{ t('files_sharing', 'Password expires {passwordExpirationTime}', { passwordExpirationTime }) }}
- </span>
- <span v-else-if="isEmailShareType && passwordExpirationTime !== null" icon="icon-error">
- {{ t('files_sharing', 'Password expired') }}
- </span>
- </template>
- <NcCheckboxRadioSwitch :checked.sync="hasExpirationDate" :disabled="isExpiryDateEnforced">
- {{ isExpiryDateEnforced
- ? t('files_sharing', 'Expiration date (enforced)')
- : t('files_sharing', 'Set expiration date') }}
- </NcCheckboxRadioSwitch>
- <NcDateTimePickerNative v-if="hasExpirationDate"
- id="share-date-picker"
- :value="new Date(share.expireDate ?? dateTomorrow)"
- :min="dateTomorrow"
- :max="maxExpirationDateEnforced"
- :hide-label="true"
- :placeholder="t('files_sharing', 'Expiration date')"
- type="date"
- @input="onExpirationChange" />
- <NcCheckboxRadioSwitch v-if="isPublicShare"
- :disabled="canChangeHideDownload"
- :checked.sync="share.hideDownload"
- @update:checked="queueUpdate('hideDownload')">
- {{ t('files_sharing', 'Hide download') }}
- </NcCheckboxRadioSwitch>
- <NcCheckboxRadioSwitch v-if="canTogglePasswordProtectedByTalkAvailable"
- :checked.sync="isPasswordProtectedByTalk"
- @update:checked="onPasswordProtectedByTalkChange">
- {{ t('files_sharing', 'Video verification') }}
- </NcCheckboxRadioSwitch>
- <NcCheckboxRadioSwitch v-if="!isPublicShare" :disabled="!canSetDownload" :checked.sync="canDownload">
- {{ t('files_sharing', 'Allow download') }}
- </NcCheckboxRadioSwitch>
- <NcCheckboxRadioSwitch :checked.sync="writeNoteToRecipientIsChecked">
- {{ t('files_sharing', 'Note to recipient') }}
- </NcCheckboxRadioSwitch>
- <template v-if="writeNoteToRecipientIsChecked">
- <label for="share-note-textarea">
- {{ t('files_sharing', 'Enter a note for the share recipient') }}
- </label>
- <textarea id="share-note-textarea" :value="share.note" @input="share.note = $event.target.value" />
- </template>
- <NcCheckboxRadioSwitch :checked.sync="setCustomPermissions">
- {{ t('files_sharing', 'Custom permissions') }}
- </NcCheckboxRadioSwitch>
- <section v-if="setCustomPermissions" class="custom-permissions-group">
- <NcCheckboxRadioSwitch :disabled="!allowsFileDrop && share.type === SHARE_TYPES.SHARE_TYPE_LINK"
- :checked.sync="hasRead">
- {{ t('files_sharing', 'Read') }}
+ <NcDateTimePickerNative v-if="hasExpirationDate"
+ id="share-date-picker"
+ :value="new Date(share.expireDate ?? dateTomorrow)"
+ :min="dateTomorrow"
+ :max="maxExpirationDateEnforced"
+ :hide-label="true"
+ :placeholder="t('files_sharing', 'Expiration date')"
+ type="date"
+ @input="onExpirationChange" />
+ <NcCheckboxRadioSwitch v-if="isPublicShare"
+ :disabled="canChangeHideDownload"
+ :checked.sync="share.hideDownload"
+ @update:checked="queueUpdate('hideDownload')">
+ {{ t('files_sharing', 'Hide download') }}
</NcCheckboxRadioSwitch>
- <NcCheckboxRadioSwitch v-if="isFolder" :disabled="!canSetCreate" :checked.sync="canCreate">
- {{ t('files_sharing', 'Create') }}
+ <NcCheckboxRadioSwitch v-if="canTogglePasswordProtectedByTalkAvailable"
+ :checked.sync="isPasswordProtectedByTalk"
+ @update:checked="onPasswordProtectedByTalkChange">
+ {{ t('files_sharing', 'Video verification') }}
</NcCheckboxRadioSwitch>
- <NcCheckboxRadioSwitch :disabled="!canSetEdit" :checked.sync="canEdit">
- {{ t('files_sharing', 'Edit') }}
+ <NcCheckboxRadioSwitch v-if="!isPublicShare" :disabled="!canSetDownload" :checked.sync="canDownload">
+ {{ t('files_sharing', 'Allow download') }}
</NcCheckboxRadioSwitch>
- <NcCheckboxRadioSwitch v-if="config.isResharingAllowed && share.type !== SHARE_TYPES.SHARE_TYPE_LINK"
- :disabled="!canSetReshare"
- :checked.sync="canReshare">
- {{ t('files_sharing', 'Share') }}
+ <NcCheckboxRadioSwitch :checked.sync="writeNoteToRecipientIsChecked">
+ {{ t('files_sharing', 'Note to recipient') }}
</NcCheckboxRadioSwitch>
- <NcCheckboxRadioSwitch :disabled="!canSetDelete" :checked.sync="canDelete">
- {{ t('files_sharing', 'Delete') }}
+ <template v-if="writeNoteToRecipientIsChecked">
+ <label for="share-note-textarea">
+ {{ t('files_sharing', 'Enter a note for the share recipient') }}
+ </label>
+ <textarea id="share-note-textarea" :value="share.note" @input="share.note = $event.target.value" />
+ </template>
+ <NcCheckboxRadioSwitch :checked.sync="setCustomPermissions">
+ {{ t('files_sharing', 'Custom permissions') }}
</NcCheckboxRadioSwitch>
+ <section v-if="setCustomPermissions" class="custom-permissions-group">
+ <NcCheckboxRadioSwitch :disabled="!allowsFileDrop && share.type === SHARE_TYPES.SHARE_TYPE_LINK"
+ :checked.sync="hasRead">
+ {{ t('files_sharing', 'Read') }}
+ </NcCheckboxRadioSwitch>
+ <NcCheckboxRadioSwitch v-if="isFolder" :disabled="!canSetCreate" :checked.sync="canCreate">
+ {{ t('files_sharing', 'Create') }}
+ </NcCheckboxRadioSwitch>
+ <NcCheckboxRadioSwitch :disabled="!canSetEdit" :checked.sync="canEdit">
+ {{ t('files_sharing', 'Update') }}
+ </NcCheckboxRadioSwitch>
+ <NcCheckboxRadioSwitch v-if="config.isResharingAllowed && share.type !== SHARE_TYPES.SHARE_TYPE_LINK"
+ :disabled="!canSetReshare"
+ :checked.sync="canReshare">
+ {{ t('files_sharing', 'Share') }}
+ </NcCheckboxRadioSwitch>
+ <NcCheckboxRadioSwitch :disabled="!canSetDelete" :checked.sync="canDelete">
+ {{ t('files_sharing', 'Delete') }}
+ </NcCheckboxRadioSwitch>
+ </section>
</section>
- </section>
+ </div>
</div>
<div class="sharingTabDetailsView__footer">
- <NcButton v-if="!isNewShare"
- :aria-label="t('files_sharing', 'Delete share')"
- :disabled="false"
- :readonly="false"
- type="tertiary"
- @click.prevent="removeShare">
- <template #icon>
- <CloseIcon :size="16" />
- </template>
- {{ t('files_sharing', 'Delete share') }}
- </NcButton>
+ <div class="sharingTabDetailsView__delete">
+ <NcButton v-if="!isNewShare"
+ :aria-label="t('files_sharing', 'Delete share')"
+ :disabled="false"
+ :readonly="false"
+ type="tertiary"
+ @click.prevent="removeShare">
+ <template #icon>
+ <CloseIcon :size="16" />
+ </template>
+ {{ t('files_sharing', 'Delete share') }}
+ </NcButton>
+ </div>
<div class="button-group">
<NcButton @click="$emit('close-sharing-details')">
{{ t('files_sharing', 'Cancel') }}
@@ -401,19 +411,6 @@ export default {
isFolder() {
return this.fileInfo.type === 'dir'
},
- maxExpirationDateEnforced() {
- if (this.isExpiryDateEnforced) {
- if (this.isPublicShare) {
- return this.config.defaultExpirationDate
- }
- if (this.isRemoteShare) {
- return this.config.defaultRemoteExpirationDateString
- }
- // If it get's here then it must be an internal share
- return this.config.defaultInternalExpirationDate
- }
- return null
- },
/**
* @return {boolean}
*/
@@ -452,9 +449,6 @@ export default {
isGroupShare() {
return this.share.type === this.SHARE_TYPES.SHARE_TYPE_GROUP
},
- isRemoteShare() {
- return this.share.type === this.SHARE_TYPES.SHARE_TYPE_REMOTE_GROUP || this.share.type === this.SHARE_TYPES.SHARE_TYPE_REMOTE
- },
isNewShare() {
return this.share.id === null || this.share.id === undefined
},
@@ -626,6 +620,9 @@ export default {
: translatedPermissions[permission].toLocaleLowerCase(getLanguage()))
.join(', ')
},
+ advancedControlExpandedValue() {
+ return this.advancedSectionAccordionExpanded ? 'true' : 'false'
+ },
},
watch: {
setCustomPermissions(isChecked) {
@@ -643,6 +640,10 @@ export default {
console.debug('config', this.config)
},
+ mounted() {
+ this.$refs.quickPermissions?.querySelector('input:checked')?.focus()
+ },
+
methods: {
updateAtomicPermissions({
isReadChecked = this.hasRead,
@@ -698,6 +699,12 @@ export default {
return
}
+ // If there is an enforced expiry date, then existing shares created before enforcement
+ // have no expiry date, hence we set it here.
+ if (!this.isValidShareAttribute(this.share.expireDate) && this.isExpiryDateEnforced) {
+ this.hasExpirationDate = true
+ }
+
if (
this.isValidShareAttribute(this.share.password)
|| this.isValidShareAttribute(this.share.expireDate)
@@ -753,16 +760,12 @@ export default {
if (!this.writeNoteToRecipientIsChecked) {
this.share.note = ''
}
-
if (this.isPasswordProtected) {
- if (this.isValidShareAttribute(this.share.newPassword)) {
+ if (this.hasUnsavedPassword && this.isValidShareAttribute(this.share.newPassword)) {
this.share.password = this.share.newPassword
this.$delete(this.share, 'newPassword')
- } else {
- if (this.isPasswordEnforced) {
- this.passwordError = true
- return
- }
+ } else if (this.isPasswordEnforced && !this.isValidShareAttribute(this.share.password)) {
+ this.passwordError = true
}
} else {
this.share.password = ''
@@ -901,9 +904,11 @@ export default {
.sharingTabDetailsView {
display: flex;
flex-direction: column;
- align-items: flex-start;
- width: 96%;
+ width: 100%;
margin: 0 auto;
+ position: relative;
+ height: 100%;
+ overflow: hidden;
&__header {
display: flex;
@@ -923,10 +928,16 @@ export default {
}
}
+ &__wrapper {
+ overflow: scroll;
+ flex-shrink: 1;
+ padding: 4px;
+ padding-right: 12px;
+ }
+
&__quick-permissions {
display: flex;
justify-content: center;
- margin-bottom: 0.2em;
width: 100%;
margin: 0 auto;
border-radius: 0;
@@ -995,6 +1006,7 @@ export default {
textarea {
height: 80px;
+ margin: 0;
}
/*
diff --git a/apps/files_sharing/src/views/SharingTab.vue b/apps/files_sharing/src/views/SharingTab.vue
index f37f2095a90..4019a99dbe0 100644
--- a/apps/files_sharing/src/views/SharingTab.vue
+++ b/apps/files_sharing/src/views/SharingTab.vue
@@ -21,7 +21,7 @@
-->
<template>
- <div :class="{ 'icon-loading': loading }">
+ <div class="sharingTab" :class="{ 'icon-loading': loading }">
<!-- error message -->
<div v-if="error" class="emptycontent" :class="{ emptyContentWithSections: sections.length > 0 }">
<div class="icon icon-error" />
@@ -87,13 +87,12 @@
</template>
<!-- share details -->
- <div v-else>
- <SharingDetailsTab :file-info="shareDetailsData.fileInfo"
- :share="shareDetailsData.share"
- @close-sharing-details="toggleShareDetailsView"
- @add:share="addShare"
- @remove:share="removeShare" />
- </div>
+ <SharingDetailsTab v-else
+ :file-info="shareDetailsData.fileInfo"
+ :share="shareDetailsData.share"
+ @close-sharing-details="toggleShareDetailsView"
+ @add:share="addShare"
+ @remove:share="removeShare" />
</div>
</template>
@@ -406,6 +405,9 @@ export default {
}
.sharingTab {
+ position: relative;
+ height: 100%;
+
&__content {
padding: 0 6px;
}