Fix expiration display
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
This commit is contained in:
parent
224cc7d6d9
commit
cd63980601
|
@ -24,10 +24,9 @@
|
||||||
<AppNavigationItem
|
<AppNavigationItem
|
||||||
ref="navigationItem"
|
ref="navigationItem"
|
||||||
:exact="true"
|
:exact="true"
|
||||||
:icon="loading ? 'icon-loading-small' : ''"
|
:icon="icon"
|
||||||
:title="form.title"
|
:title="form.title"
|
||||||
:to="{ name: 'edit', params: { hash: form.hash } }">
|
:to="{ name: 'edit', params: { hash: form.hash } }">
|
||||||
<AppNavigationIconBullet slot="icon" :color="bulletColor" />
|
|
||||||
<template v-if="!loading" #actions>
|
<template v-if="!loading" #actions>
|
||||||
<ActionLink
|
<ActionLink
|
||||||
:href="formLink"
|
:href="formLink"
|
||||||
|
@ -63,7 +62,6 @@ import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
|
||||||
import ActionLink from '@nextcloud/vue/dist/Components/ActionLink'
|
import ActionLink from '@nextcloud/vue/dist/Components/ActionLink'
|
||||||
import ActionRouter from '@nextcloud/vue/dist/Components/ActionRouter'
|
import ActionRouter from '@nextcloud/vue/dist/Components/ActionRouter'
|
||||||
import ActionSeparator from '@nextcloud/vue/dist/Components/ActionSeparator'
|
import ActionSeparator from '@nextcloud/vue/dist/Components/ActionSeparator'
|
||||||
import AppNavigationIconBullet from '@nextcloud/vue/dist/Components/AppNavigationIconBullet'
|
|
||||||
import AppNavigationItem from '@nextcloud/vue/dist/Components/AppNavigationItem'
|
import AppNavigationItem from '@nextcloud/vue/dist/Components/AppNavigationItem'
|
||||||
import axios from '@nextcloud/axios'
|
import axios from '@nextcloud/axios'
|
||||||
import moment from '@nextcloud/moment'
|
import moment from '@nextcloud/moment'
|
||||||
|
@ -77,7 +75,6 @@ export default {
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
AppNavigationItem,
|
AppNavigationItem,
|
||||||
AppNavigationIconBullet,
|
|
||||||
ActionButton,
|
ActionButton,
|
||||||
ActionLink,
|
ActionLink,
|
||||||
ActionRouter,
|
ActionRouter,
|
||||||
|
@ -113,6 +110,20 @@ export default {
|
||||||
return style.getPropertyValue('--color-success').slice(-6)
|
return style.getPropertyValue('--color-success').slice(-6)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
icon() {
|
||||||
|
if (this.loading) {
|
||||||
|
return 'icon-loading-small'
|
||||||
|
}
|
||||||
|
if (this.isExpired) {
|
||||||
|
return 'icon-checkmark'
|
||||||
|
}
|
||||||
|
return 'icon-forms'
|
||||||
|
},
|
||||||
|
|
||||||
|
isExpired() {
|
||||||
|
return this.form.expires && moment().unix() > this.form.expires
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the form share link
|
* Return the form share link
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
|
|
@ -21,7 +21,10 @@
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<AppSidebar v-show="opened" :title="form.title" @close="onClose">
|
<AppSidebar v-if="form"
|
||||||
|
v-show="opened"
|
||||||
|
:title="form.title"
|
||||||
|
@close="onClose">
|
||||||
<h3>{{ t('forms', 'Settings') }}</h3>
|
<h3>{{ t('forms', 'Settings') }}</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
|
@ -38,7 +41,7 @@
|
||||||
<li>
|
<li>
|
||||||
<input id="submitOnce"
|
<input id="submitOnce"
|
||||||
v-model="form.submitOnce"
|
v-model="form.submitOnce"
|
||||||
:disabled="form.access.type === 'public' || form.isAnonymous"
|
:disabled="isPublic || form.isAnonymous"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="checkbox"
|
class="checkbox"
|
||||||
@change="onSubmOnceChange">
|
@change="onSubmOnceChange">
|
||||||
|
@ -56,8 +59,15 @@
|
||||||
</label>
|
</label>
|
||||||
<DatetimePicker v-show="formExpires"
|
<DatetimePicker v-show="formExpires"
|
||||||
id="expiresDatetimePicker"
|
id="expiresDatetimePicker"
|
||||||
v-model="form.expires"
|
:clearable="false"
|
||||||
v-bind="expirationDatePicker"
|
:disabled-date="notBeforeToday"
|
||||||
|
:disabled-time="notBeforeNow"
|
||||||
|
:format="format"
|
||||||
|
:minute-step="5"
|
||||||
|
:placeholder="t('forms', 'Expiration date')"
|
||||||
|
:show-second="false"
|
||||||
|
:value="expirationDate"
|
||||||
|
type="datetime"
|
||||||
@change="onExpiresChange" />
|
@change="onExpiresChange" />
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -118,7 +128,7 @@ import AppSidebar from '@nextcloud/vue/dist/Components/AppSidebar'
|
||||||
import DatetimePicker from '@nextcloud/vue/dist/Components/DatetimePicker'
|
import DatetimePicker from '@nextcloud/vue/dist/Components/DatetimePicker'
|
||||||
import moment from '@nextcloud/moment'
|
import moment from '@nextcloud/moment'
|
||||||
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
|
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
|
||||||
import { getLocale, getLanguage } from '@nextcloud/l10n'
|
import { getLocale, getDayNamesShort, getMonthNamesShort } from '@nextcloud/l10n'
|
||||||
|
|
||||||
import ShareDiv from '../components/shareDiv'
|
import ShareDiv from '../components/shareDiv'
|
||||||
import ViewsMixin from '../mixins/ViewsMixin'
|
import ViewsMixin from '../mixins/ViewsMixin'
|
||||||
|
@ -136,69 +146,75 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
opened: false,
|
opened: false,
|
||||||
lang: '',
|
lang: {
|
||||||
locale: '',
|
days: getDayNamesShort(),
|
||||||
longDateFormat: '',
|
months: getMonthNamesShort(),
|
||||||
dateTimeFormat: '',
|
placeholder: {
|
||||||
formExpires: false,
|
date: t('forms', 'Select expiration date'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
locale: 'en',
|
||||||
|
format: {
|
||||||
|
stringify: this.stringify,
|
||||||
|
parse: this.parse,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
expirationDatePicker() {
|
|
||||||
return {
|
|
||||||
editable: true,
|
|
||||||
minuteStep: 1,
|
|
||||||
type: 'datetime',
|
|
||||||
valueType: 'X', // unix-timestamp
|
|
||||||
format: moment.localeData().longDateFormat('L') + ' ' + moment.localeData().longDateFormat('LT'),
|
|
||||||
lang: this.lang.split('-')[0],
|
|
||||||
placeholder: t('forms', 'Expiration date'),
|
|
||||||
timePickerOptions: {
|
|
||||||
start: '00:00',
|
|
||||||
step: '00:15',
|
|
||||||
end: '23:45',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
formExpires: {
|
formExpires: {
|
||||||
handler: function() {
|
get() {
|
||||||
if (!this.formExpires) {
|
return this.form.expires !== 0
|
||||||
this.form.expires = 0
|
},
|
||||||
this.onExpiresChange()
|
set(checked) {
|
||||||
} else {
|
if (checked) {
|
||||||
this.form.expires = moment().unix() + 3600 // Expires in one hour.
|
this.form.expires = moment().unix() + 3600 // Expires in one hour.
|
||||||
|
} else {
|
||||||
|
this.form.expires = 0
|
||||||
}
|
}
|
||||||
|
this.saveFormProperty('expires')
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
isPublic() {
|
||||||
|
return this.form?.access?.type === 'public'
|
||||||
|
},
|
||||||
|
|
||||||
|
expirationDate() {
|
||||||
|
return moment(this.form.expires, 'X').toDate()
|
||||||
|
},
|
||||||
|
|
||||||
|
isExpired() {
|
||||||
|
return this.form.expires && moment().unix() > this.form.expires
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
async created() {
|
||||||
this.lang = getLanguage()
|
// Load the locale
|
||||||
|
// convert format like en_GB to en-gb for `moment.js`
|
||||||
|
let locale = getLocale().replace('_', '-').toLowerCase()
|
||||||
try {
|
try {
|
||||||
this.locale = getLocale()
|
// default load e.g. fr-fr
|
||||||
|
await import(/* webpackChunkName: 'moment' */'moment/locale/' + locale)
|
||||||
|
this.locale = locale
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof TypeError) {
|
try {
|
||||||
this.locale = this.lang
|
// failure: fallback to fr
|
||||||
} else {
|
locale = locale.split('-')[0]
|
||||||
/* eslint-disable-next-line no-console */
|
await import(/* webpackChunkName: 'moment' */'moment/locale/' + locale)
|
||||||
console.log(e)
|
} catch (e) {
|
||||||
|
// failure, fallback to english
|
||||||
|
console.debug('Fallback to locale', 'en')
|
||||||
|
locale = 'en'
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
// force locale change to update
|
||||||
|
// the component once done loading
|
||||||
|
this.locale = locale
|
||||||
|
console.debug('Locale used', locale)
|
||||||
}
|
}
|
||||||
moment.locale(this.locale)
|
},
|
||||||
this.longDateFormat = moment.localeData().longDateFormat('L')
|
|
||||||
this.dateTimeFormat = moment.localeData().longDateFormat('L') + ' ' + moment.localeData().longDateFormat('LT')
|
|
||||||
|
|
||||||
// Compute current formExpires for checkbox
|
|
||||||
if (this.form.expires) {
|
|
||||||
this.formExpires = true
|
|
||||||
} else {
|
|
||||||
this.formExpires = false
|
|
||||||
}
|
|
||||||
|
|
||||||
|
beforeMount() {
|
||||||
// Watch for Sidebar toggle
|
// Watch for Sidebar toggle
|
||||||
subscribe('toggleSidebar', this.onToggle)
|
subscribe('toggleSidebar', this.onToggle)
|
||||||
},
|
},
|
||||||
|
@ -242,9 +258,56 @@ export default {
|
||||||
onAccessChange() {
|
onAccessChange() {
|
||||||
this.saveFormProperty('access')
|
this.saveFormProperty('access')
|
||||||
},
|
},
|
||||||
onExpiresChange() {
|
|
||||||
|
/**
|
||||||
|
* On date picker change
|
||||||
|
* @param {Date} datetime the expiration Date
|
||||||
|
*/
|
||||||
|
onExpiresChange(datetime) {
|
||||||
|
this.form.expires = parseInt(moment(datetime).format('X'))
|
||||||
this.saveFormProperty('expires')
|
this.saveFormProperty('expires')
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Datepicker timestamp to string
|
||||||
|
* @param {Date} datetime the datepicker Date
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
stringify(datetime) {
|
||||||
|
const date = moment(datetime).locale(this.locale).format('LLL')
|
||||||
|
|
||||||
|
if (this.isExpired) {
|
||||||
|
return t('forms', 'Expired on {date}', { date })
|
||||||
|
}
|
||||||
|
return t('forms', 'Expires on {date}', { date })
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Form expires timestamp to Date form the datepicker
|
||||||
|
* @param {number} value the expires timestamp
|
||||||
|
* @returns {Date}
|
||||||
|
*/
|
||||||
|
parse(value) {
|
||||||
|
return moment(value, 'X').toDate()
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent selecting a day before today
|
||||||
|
* @param {Date} datetime the datepicker Date
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
notBeforeToday(datetime) {
|
||||||
|
return datetime < moment().add(-1, 'day').toDate()
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent selecting a time before the current one + 1hour
|
||||||
|
* @param {Date} datetime the datepicker Date
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
notBeforeNow(datetime) {
|
||||||
|
return datetime < moment().add(1, 'hour').toDate()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -55,6 +55,7 @@ module.exports = {
|
||||||
// Make appName & appVersion available as a constant
|
// Make appName & appVersion available as a constant
|
||||||
new webpack.DefinePlugin({ appName }),
|
new webpack.DefinePlugin({ appName }),
|
||||||
new webpack.DefinePlugin({ appVersion }),
|
new webpack.DefinePlugin({ appVersion }),
|
||||||
|
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
||||||
],
|
],
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['*', '.js', '.vue'],
|
extensions: ['*', '.js', '.vue'],
|
||||||
|
|
Loading…
Reference in a new issue