diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/files_sharing/src/components/SharingEntryLink.vue | 10 | ||||
-rw-r--r-- | apps/files_sharing/src/mixins/SharesMixin.js | 16 | ||||
-rw-r--r-- | apps/files_sharing/src/views/SharingDetailsTab.vue | 366 | ||||
-rw-r--r-- | apps/files_sharing/src/views/SharingTab.vue | 18 |
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; } |