Skip to content

Commit

Permalink
differentiate collaborator test-id for user and group
Browse files Browse the repository at this point in the history
support enforced and max expiration share dates
  • Loading branch information
fschade committed Dec 21, 2021
1 parent 54fc59d commit 926bc0b
Show file tree
Hide file tree
Showing 13 changed files with 303 additions and 121 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Enhancement: Respect share max, min and enforced expiration date

if the expiration date max and/or enforcement is supported (defined by the capabilities) the UI now handles the different cases and respects the backend settings.
In oc10 there are options to enforce the maximum available date for group and user shares, this is now considered in the UI and updates dynamically in both cases.

https://github.com/owncloud/web/pull/6176
https://github.com/owncloud/web/pull/6039
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div
:data-testid="`collaborator-item-${share.collaborator.name}`"
:data-testid="`collaborator-${isUser ? 'user' : 'group'}-item-${share.collaborator.name}`"
class="files-collaborators-collaborator uk-flex uk-flex-middle oc-py-xs"
>
<div class="uk-width-2-3 uk-flex uk-flex-middle" style="gap: 10px">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<template>
<div v-if="expirationSupported" class="uk-flex uk-flex-middle uk-flex-nowrap">
<div v-if="available" class="uk-flex uk-flex-middle uk-flex-nowrap">
<oc-datepicker
v-model="enteredExpirationDate"
:min-date="minExpirationDate"
:max-date="maxExpirationDate"
:locale="$language.current"
:is-required="expirationDateEnforced"
v-model="dateCurrent"
:min-date="dateMin"
:max-date="dateMax"
:locale="language.current"
:is-required="enforced"
class="files-recipient-expiration-datepicker"
data-testid="recipient-datepicker"
>
Expand All @@ -17,141 +17,146 @@
gap-size="none"
@click="togglePopover"
>
<translate v-if="!enteredExpirationDate" key="no-expiration-date-label"
<translate v-if="!dateCurrent" key="no-expiration-date-label"
>Set expiration date</translate
>
<translate
v-else
key="set-expiration-date-label"
:translate-params="{ expires: relativeExpirationDate }"
:translate-params="{ expires: dateExpire }"
>
Expires %{expires}
</translate>
<oc-icon v-if="!enteredExpirationDate" name="expand_more" />
<oc-icon v-if="!dateCurrent" name="expand_more" />
</oc-button>
</template>
</oc-datepicker>
<oc-button
v-if="!expirationDateEnforced && enteredExpirationDate"
v-if="!enforced && dateCurrent"
class="recipient-edit-expiration-btn-remove"
appearance="raw"
:aria-label="$gettext('Remove expiration date')"
@click="clearExpirationDate"
:aria-label="gettext('Remove expiration date')"
@click="dateCurrent = null"
>
<oc-icon name="close" />
</oc-button>
</div>
</template>

<script>
import { mapGetters } from 'vuex'
<script lang="ts">
import { DateTime } from 'luxon'
export default {
name: 'ExpirationDatepicker',
import {
computed,
getCurrentInstance,
watch,
defineComponent,
customRef
} from '@vue/composition-api'
import { useStore } from '../../../../composables'
import { ShareTypes } from '../../../../helpers/share'
export default defineComponent({
name: 'DateCurrentpicker',
props: {
expirationDate: {
type: Date,
shareTypes: {
type: Array,
required: false,
default: undefined
default: () => []
}
},
data() {
return {
enteredExpirationDate: null
}
},
computed: {
...mapGetters(['capabilities']),
expirationSupported() {
return this.userExpirationDate && this.groupExpirationDate
},
defaultExpirationDateSet() {
return this.userExpirationDate.enabled || this.groupExpirationDate.enabled
},
userExpirationDate() {
return this.capabilities.files_sharing.user.expire_date
},
groupExpirationDate() {
return this.capabilities.files_sharing.group.expire_date
},
defaultExpirationDate() {
if (!this.defaultExpirationDateSet) {
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)
const optionsGroup = computed(() => capabilities.value.files_sharing.group?.expire_date)
const available = computed(() => optionsUser.value || optionsGroup.value)
const enforced = computed(() => optionsUser.value?.enforced || optionsGroup.value?.enforced)
const dateMin = DateTime.now().setLocale(language.value.current).toJSDate()
const dateDefault = computed(() => {
const hasUserCollaborators = props.shareTypes.includes(ShareTypes.user.value)
const hasGroupCollaborators = props.shareTypes.includes(ShareTypes.group.value)
const userMaxExpirationDays = parseInt(optionsUser.value?.days)
const groupMaxExpirationDays = parseInt(optionsGroup.value?.days)
if (!(optionsUser.value?.enabled || optionsGroup.value?.enabled)) {
return null
}
const userMaxExpirationDays = parseInt(this.userExpirationDate.days, 10)
const groupMaxExpirationDays = parseInt(this.groupExpirationDate.days, 10)
let days = 0
if (userMaxExpirationDays && groupMaxExpirationDays) {
if (
userMaxExpirationDays &&
hasUserCollaborators &&
groupMaxExpirationDays &&
hasGroupCollaborators
) {
days = Math.min(userMaxExpirationDays, groupMaxExpirationDays)
} else {
days = userMaxExpirationDays || groupMaxExpirationDays
} else if (userMaxExpirationDays && hasUserCollaborators) {
days = userMaxExpirationDays
} else if (groupMaxExpirationDays && hasGroupCollaborators) {
days = groupMaxExpirationDays
}
return DateTime.now().setLocale(this.$language.current).plus({ days }).toJSDate()
},
expirationDateEnforced() {
return this.userExpirationDate.enforced || this.groupExpirationDate.enforced
},
maxExpirationDate() {
if (!this.expirationDateEnforced) {
if (!days) {
return null
}
return this.defaultExpirationDate
},
minExpirationDate() {
return DateTime.now().setLocale(this.$language.current).toJSDate()
},
relativeExpirationDate() {
return DateTime.fromJSDate(this.enteredExpirationDate)
.setLocale(this.$language.current)
return DateTime.now().setLocale(language.value.current).plus({ days }).toJSDate()
})
const dateMax = computed(() => (enforced.value ? dateDefault.value : null))
const dateCurrent = customRef<Date>((track, trigger) => {
let date = null
return {
get() {
track()
return date || dateDefault.value
},
set(val) {
date = val
const dateCurrent = DateTime.fromJSDate(val)
.setLocale(language.value.current)
.endOf('day')
emit('optionChange', {
expirationDate: dateCurrent.isValid
? dateCurrent.toFormat("yyyy-MM-dd'T'HH:mm:ssZZZ")
: null
})
trigger()
}
}
})
const dateExpire = computed(() =>
DateTime.fromJSDate(dateCurrent.value)
.setLocale(language.value.current)
.endOf('day')
.toRelative()
}
},
)
mounted() {
if (this.expirationSupported && this.defaultExpirationDateSet) {
this.enteredExpirationDate = this.defaultExpirationDate
}
},
watch(dateMax, (val) => {
if (!val || dateCurrent.value < val) {
return
}
watch: {
enteredExpirationDate: {
handler: 'publishChange'
}
},
dateCurrent.value = val
})
methods: {
publishChange() {
const expirationDate = DateTime.fromJSDate(this.enteredExpirationDate)
.setLocale(this.$language.current)
.endOf('day')
this.$emit('optionChange', {
expirationDate: expirationDate.isValid
? expirationDate.toFormat("yyyy-MM-dd'T'HH:mm:ssZZZ")
: null
})
},
clearExpirationDate() {
this.enteredExpirationDate = null
return {
language,
gettext,
enforced,
available,
dateCurrent,
dateMin,
dateMax,
dateExpire
}
}
}
})
</script>

<style lang="scss" scoped>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@
:allow-share-permission="!isOcis"
@optionChange="collaboratorRoleChanged"
/>
<expiration-datepicker @optionChange="collaboratorExpiryChanged" />
<expiration-datepicker
:share-types="selectedCollaborators.map((c) => c.value.shareType)"
@optionChange="collaboratorExpiryChanged"
/>
<oc-button v-if="saving" key="new-collaborator-saving-button" :disabled="true">
<oc-spinner :aria-label="$gettext('Creating share')" size="small" />
<span v-translate :aria-hidden="true">Share</span>
Expand Down
6 changes: 0 additions & 6 deletions packages/web-app-files/src/composables/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,3 @@ export * from './store'
export * from './useDefaults'
export * from './useFileListHeaderPosition'
export * from './usePagination'

declare module 'vue/types/vue' {
interface Vue {
[key: string]: any
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const selectors = {
containerPrefix: 'recipient-container-'
},
listItem: {
containerPrefix: 'collaborator-item-',
containerPrefix: 'collaborator-user-item-',
expiration: 'recipient-info-expiration-date',
editBtn: 'collaborator-edit',
removeExpirationBtn: 'collaborator-remove-expiration-btn'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const collaborators = [Collaborators[0], Collaborators[1]]

const selectors = {
showCollaboratorButton: 'button[data-testid="collaborators-show-people"]',
firstCollaboratorListItem: `div[data-testid="collaborator-item-${Collaborators[0].collaborator.name}"]`
firstCollaboratorListItem: `div[data-testid="collaborator-user-item-${Collaborators[0].collaborator.name}"]`
}

describe('FileShares', () => {
Expand Down

This file was deleted.

Loading

0 comments on commit 926bc0b

Please sign in to comment.