cd63980601
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
349 lines
7.7 KiB
Vue
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>
|