forms/src/views/Sidebar.vue
John Molakvoæ (skjnldsv) cd63980601
Fix expiration display
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
2020-05-01 11:38:28 +02:00

349 lines
7.7 KiB
Vue

<!--
- @copyright Copyright (c) 2020 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>
<AppSidebar v-if="form"
v-show="opened"
:title="form.title"
@close="onClose">
<h3>{{ t('forms', 'Settings') }}</h3>
<ul>
<li>
<input id="isAnonymous"
v-model="form.isAnonymous"
type="checkbox"
class="checkbox"
@change="onAnonChange">
<label for="isAnonymous">
{{ t('forms', 'Anonymous responses') }}
</label>
</li>
<li>
<input id="submitOnce"
v-model="form.submitOnce"
:disabled="isPublic || form.isAnonymous"
type="checkbox"
class="checkbox"
@change="onSubmOnceChange">
<label for="submitOnce">
{{ t('forms', 'Only allow one response per user') }}
</label>
</li>
<li>
<input id="expires"
v-model="formExpires"
type="checkbox"
class="checkbox">
<label for="expires">
{{ t('forms', 'Set expiration date') }}
</label>
<DatetimePicker v-show="formExpires"
id="expiresDatetimePicker"
:clearable="false"
: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" />
</li>
</ul>
<h3>{{ t('forms', 'Sharing') }}</h3>
<ul>
<li>
<input id="registered"
v-model="form.access.type"
type="radio"
value="registered"
class="radio"
@change="onAccessChange">
<label for="registered">
<span class="icon-group">
{{ t('forms', 'Show to all users of this instance') }}
</span>
</label>
</li>
<li>
<input id="public"
v-model="form.access.type"
type="radio"
value="public"
class="radio"
@change="onAccessChange">
<label for="public">
<span class="icon-link">
{{ t('forms', 'Share link') }}
</span>
</label>
</li>
<li>
<input id="selected"
v-model="form.access.type"
type="radio"
value="selected"
class="radio"
@change="onAccessChange">
<label for="selected">
<span class="icon-shared">
{{ t('forms', 'Choose users to share with') }}
</span>
</label>
<ShareDiv v-show="form.access.type === 'selected'"
:active-shares="form.shares"
:placeholder="t('forms', 'Name of user or group')"
:hide-names="true"
@update-shares="updateShares"
@remove-share="removeShare" />
</li>
</ul>
</AppSidebar>
</template>
<script>
import AppSidebar from '@nextcloud/vue/dist/Components/AppSidebar'
import DatetimePicker from '@nextcloud/vue/dist/Components/DatetimePicker'
import moment from '@nextcloud/moment'
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
import { getLocale, getDayNamesShort, getMonthNamesShort } from '@nextcloud/l10n'
import ShareDiv from '../components/shareDiv'
import ViewsMixin from '../mixins/ViewsMixin'
export default {
name: 'Sidebar',
components: {
AppSidebar,
DatetimePicker,
ShareDiv,
},
mixins: [ViewsMixin],
data() {
return {
opened: false,
lang: {
days: getDayNamesShort(),
months: getMonthNamesShort(),
placeholder: {
date: t('forms', 'Select expiration date'),
},
},
locale: 'en',
format: {
stringify: this.stringify,
parse: this.parse,
},
}
},
computed: {
formExpires: {
get() {
return this.form.expires !== 0
},
set(checked) {
if (checked) {
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
},
},
async created() {
// Load the locale
// convert format like en_GB to en-gb for `moment.js`
let locale = getLocale().replace('_', '-').toLowerCase()
try {
// default load e.g. fr-fr
await import(/* webpackChunkName: 'moment' */'moment/locale/' + locale)
this.locale = locale
} catch (e) {
try {
// failure: fallback to fr
locale = locale.split('-')[0]
await import(/* webpackChunkName: 'moment' */'moment/locale/' + locale)
} 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)
}
},
beforeMount() {
// Watch for Sidebar toggle
subscribe('toggleSidebar', this.onToggle)
},
beforeDestroy() {
unsubscribe('toggleSidebar')
},
methods: {
addShare(item) {
this.form.shares.push(item)
},
updateShares(share) {
this.form.shares = share.slice(0)
},
removeShare(item) {
this.form.shares.splice(this.form.shares.indexOf(item), 1)
},
/**
* Sidebar state methods
*/
onClose() {
this.opened = false
},
onToggle() {
this.opened = !this.opened
},
/**
* Save Form-Properties
*/
onAnonChange() {
this.saveFormProperty('isAnonymous')
},
onSubmOnceChange() {
this.saveFormProperty('submitOnce')
},
onAccessChange() {
this.saveFormProperty('access')
},
/**
* On date picker change
* @param {Date} datetime the expiration Date
*/
onExpiresChange(datetime) {
this.form.expires = parseInt(moment(datetime).format('X'))
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>
<style lang="scss" scoped>
h3 {
margin-left: 8px;
margin-bottom: 8px;
}
ul {
margin-bottom: 24px;
label {
padding: 8px;
display: block;
span[class^='icon-'],
span[class*=' icon-'] {
background-position: 4px;
padding-left: 24px;
}
}
}
input,
textarea {
&.error {
border: 2px solid var(--color-error);
box-shadow: 1px 0 var(--border-radius) var(--color-box-shadow);
}
}
#expiresDatetimePicker {
left: 36px;
width: calc(100% - 44px);
}
</style>