Commit 33258562 authored by MARCO Jonathan's avatar MARCO Jonathan
Browse files

馃攢 Merge branch 'bugfix/bugs' into develop

parents 9259d5d1 5e349451
Pipeline #62955 passed with stage
in 15 seconds
<template>
<v-menu
v-show="editorMode || visible"
v-if="editorMode || exist"
v-model="menu.isVisible"
offset-y
:close-on-content-click="menu.closeOnContentClick"
:min-width="menu.minWidth"
v-show="editorMode || visible"
v-if="editorMode || exist"
v-model="menu.isVisible"
offset-y
:close-on-content-click="menu.closeOnContentClick"
:min-width="menu.minWidth"
>
<template #activator="{ on }">
<v-text-field
:value="getDateOrTimeFormat(value)"
:class="editorMode ? 'picker-text-field mx-2' : 'picker-text-field'"
:label="label"
:hint="translated(fieldId, 'hint')"
:persistent-hint="field.persistentHint"
:prepend-icon="textFieldPrependIcon"
readonly
clearable
:rules="[handleRequired]"
v-on="on"
:value="getDateOrTimeFormat(value)"
:class="editorMode ? 'picker-text-field mx-2' : 'picker-text-field'"
:label="label"
:hint="translated(fieldId, 'hint')"
:persistent-hint="field.persistentHint"
:prepend-icon="textFieldPrependIcon"
readonly
clearable
:rules="[handleRequired]"
:disabled="fieldOnReadOnly"
v-on="on"
>
<template #append-outer>
<v-icon
v-if="field.repeatable"
@click="repeat"
v-if="field.repeatable"
@click="repeat"
>
mdi-plus
</v-icon>
......@@ -32,33 +33,35 @@
</template>
<v-date-picker
v-if="field.type === 'date'"
:ref="pickerRef"
v-model="value"
:locale="field.locale"
:min="dateMin"
:max="dateMax"
no-title
@input="menu.isVisible = false"
color="primary"
v-if="field.type === 'date'"
:ref="pickerRef"
v-model="value"
:locale="field.locale"
:min="dateMin"
:max="dateMax"
no-title
@input="menu.isVisible = false"
color="primary"
/>
<v-time-picker
v-if="field.type === 'time'"
:ref="pickerRef"
v-model="value"
:locale="field.locale"
@input="menu.isVisible = false"
:format="timeFormat"
color="primary"
v-if="field.type === 'time'"
:ref="pickerRef"
v-model="value"
:locale="field.locale"
@input="menu.isVisible = false"
:format="timeFormat"
color="primary"
/>
</v-menu>
</template>
<script lang="ts">
import {usfFieldMixin, usfHandleConditional} from '../../../mixins'
import dayjs from '../../../utils/dayjs'
import Vue from 'vue'
import {UnitTypeLongPlural} from 'dayjs';
import { usfFieldMixin, usfHandleConditional, usfDefaultTokenMixin } from '@form-plugin/mixins';
import dayjs from '@form-plugin/utils/dayjs';
import Vue from 'vue';
import { UnitTypeLongPlural } from 'dayjs';
import { Field } from '#form-plugin/models/form';
import { mapGetters } from 'vuex';
interface ComponentData {
menu: {
......@@ -74,6 +77,7 @@ export default Vue.extend({
mixins: [
usfFieldMixin,
usfHandleConditional,
usfDefaultTokenMixin,
],
props: {
......@@ -93,33 +97,34 @@ export default Vue.extend({
}),
computed: {
...mapGetters('form', ['getFieldById']),
textFieldPrependIcon(): string {
return this.field.type === 'date' ? 'mdi-calendar-outline' : 'mdi-clock-outline'
return this.field.type === 'date' ? 'mdi-calendar-outline' : 'mdi-clock-outline';
},
pickerRef(): string {
return `${this.field.type}Picker`
return `${this.field.type}Picker`;
},
dateMin(): undefined | string {
return this.getDateFromDelta(this.field.minValue, this.field.minUnit, 'min')
return this.getDateFromDelta(this.field.minValue, this.field.minUnit, 'min');
},
dateMax() {
return this.getDateFromDelta(this.field.maxValue, this.field.maxUnit, 'max')
return this.getDateFromDelta(this.field.maxValue, this.field.maxUnit, 'max');
},
timeFormat() {
return this._globaleLocale === 'fr' ? '24hr' : 'ampm'
return this._globaleLocale === 'fr' ? '24hr' : 'ampm';
},
},
watch: {
'field.type': function () {
this.field.value = ''
'field.type': function() {
this.field.value = '';
},
'menu.isVisible': function (val) {
'menu.isVisible': function(val) {
if (val && this.field.type === 'date' && this.field.style === 'standard') {
setTimeout(() => (this.$refs[this.pickerRef].activePicker = 'DATE'))
setTimeout(() => (this.$refs[this.pickerRef].activePicker = 'DATE'));
}
if (val && this.field.type === 'date' && this.field.style === 'birthday') {
setTimeout(() => (this.$refs[this.pickerRef].activePicker = 'YEAR'))
setTimeout(() => (this.$refs[this.pickerRef].activePicker = 'YEAR'));
}
},
},
......@@ -134,42 +139,42 @@ export default Vue.extend({
* @return {string | undefined}
*/
getDateFromDelta(
delta: number | undefined,
unit: UnitTypeLongPlural | undefined,
type: 'max' | 'min',
delta: number | undefined,
unit: UnitTypeLongPlural | undefined,
type: 'max' | 'min',
): undefined | string {
if (unit) {
const now = dayjs()
const now = dayjs();
if (delta === 0) {
return now.toISOString()
return now.toISOString();
}
return (type === 'max' && this.field.maxDateFuture) || (type === 'min' && this.field.minDateFuture)
? now.add(delta, unit)
.toISOString()
: now.subtract(delta, unit)
.toISOString()
? now.add(delta, unit)
.toISOString()
: now.subtract(delta, unit)
.toISOString();
}
return undefined
return undefined;
},
getDateOrTimeFormat(dateOrTime: string): string {
if (!dateOrTime) return dateOrTime
if (!dateOrTime) return dateOrTime;
if (this.field.type === 'time') {
return this._globaleLocale === 'fr'
? dayjs(dateOrTime, 'HH:mm').format('HH:mm')
: dayjs(dateOrTime, 'h:mm').format('hh:mm a')
? dayjs(dateOrTime, 'HH:mm').format('HH:mm')
: dayjs(dateOrTime, 'h:mm').format('hh:mm a');
}
const format = this._globaleLocale === 'fr'
? 'DD/MM/YYYY'
: 'YYYY-MM-DD'
return dayjs(dateOrTime).format(format)
? 'DD/MM/YYYY'
: 'YYYY-MM-DD';
return dayjs(dateOrTime).format(format);
},
},
})
});
</script>
<style lang="scss" scoped>
......
......@@ -35,14 +35,13 @@
</template>
<script lang="ts">
import { usfFieldMixin, usfHandleConditional } from '../../../mixins';
import { usfFieldMixin, usfHandleConditional, usfDefaultTokenMixin } from '@form-plugin/mixins';
import Vue from 'vue';
import { mapGetters } from 'vuex';
export default Vue.extend({
name: 'UsfText',
mixins: [usfFieldMixin, usfHandleConditional],
mixins: [usfFieldMixin, usfHandleConditional, usfDefaultTokenMixin],
props: {
editorMode: {
......@@ -53,7 +52,6 @@ export default Vue.extend({
},
computed: {
...mapGetters('form', ['autoCompletionIsActive']),
rules(): (boolean | string)[] {
const rules = [
this.handleRequired,
......@@ -78,9 +76,6 @@ export default Vue.extend({
? `${this.field.label} doit 锚tre inf茅rieur ou 茅gal 脿 ${this.field.max}`
: `${this.field.label} doit comporter ${this.field.max} caract猫res ou moins`;
},
fieldOnReadOnly(): boolean {
return !!this.field.defaultTokenValue && this.autoCompletionIsActive;
},
},
mounted() {
......@@ -89,17 +84,6 @@ export default Vue.extend({
}
},
watch: {
autoCompletionIsActive: function() {
if (this.autoCompletionIsActive) {
this.$store.dispatch('submission/updateValue', {
key: this.field.name,
value: this.user[this.field.defaultTokenValue],
});
}
},
},
methods: {
handleMin(): boolean | string {
const test = this.field.type === 'number'
......
......@@ -15,7 +15,7 @@
<template v-if="!field.protected || admin">
<v-spacer />
<v-dialog
v-model="duplicateDialog"
v-model="duplicateDialogDisplayed"
persistent
scrollable
width="400"
......@@ -35,7 +35,7 @@
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn color="primary" outlined elevation="0" @click.stop="duplicateDialog = false">
<v-btn color="primary" outlined elevation="0" @click.stop="duplicateDialogDisplayed = false">
{{ _uct('builder.duplicate.dialog.buttons.cancel') }}
</v-btn>
<v-btn color="primary" elevation="0" @click="onDuplicateThisField">
......@@ -61,9 +61,32 @@
@close-settings-modal="closeSettingsModal"
/>
</v-dialog>
<v-btn icon x-small @click="removeField">
<v-icon>mdi-close</v-icon>
</v-btn>
<v-dialog
v-model="deleteDialogDisplayed"
persistent
scrollable
width="400"
>
<template v-slot:activator="{on, attrs}">
<v-btn icon x-small v-on="on" v-bind="attrs">
<v-icon>mdi-close</v-icon>
</v-btn>
</template>
<v-card>
<v-card-title>{{ _uct('builder.delete.dialog.title') }}</v-card-title>
<v-card-text>{{ _uct('builder.delete.dialog.text') }}</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn color="primary" outlined elevation="0" @click.stop="deleteDialogDisplayed = false">
{{ _uct('builder.delete.dialog.buttons.cancel') }}
</v-btn>
<v-btn color="primary" elevation="0" @click="removeField">
{{ _uct('builder.delete.dialog.buttons.delete') }}
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
</v-system-bar>
<v-card-text class="d-flex pa-0">
......@@ -82,8 +105,9 @@ import { Field } from '#form-plugin/models/form';
import { Control } from '#form-plugin/models/control';
interface ComponentData {
duplicateDialog: boolean;
duplicateDialogDisplayed: boolean;
settingsModal: boolean;
deleteDialogDisplayed: false;
}
export default Vue.extend({
......@@ -106,8 +130,9 @@ export default Vue.extend({
},
data: (): ComponentData => ({
duplicateDialog: false,
duplicateDialogDisplayed: false,
settingsModal: false,
deleteDialogDisplayed: false,
}),
computed: {
......@@ -150,13 +175,16 @@ export default Vue.extend({
fieldId: this.fieldId,
fieldIndex: this.fieldIndex,
});
this.duplicateDialog = false;
this.duplicateDialogDisplayed = false;
},
closeSettingsModal(): void {
this.settingsModal = false;
},
removeField(): void {
this.$store.dispatch('form/removeField', { ...this.field, index: this.fieldIndex });
this.$store.dispatch('form/removeField', { ...this.field, index: this.fieldIndex })
.then(() => {
this.deleteDialogDisplayed = false;
});
},
},
});
......
......@@ -3,7 +3,7 @@
<v-expansion-panel>
<header>
<v-subheader class="subtitle-1">{{ _uct('builder.tabs.conditional.title') }}</v-subheader>
<v-btn icon small color="primary" @click="conditionModalDisplayed = true">
<v-btn icon small color="primary" @click="onAddConditional">
<v-icon>mdi-plus</v-icon>
</v-btn>
</header>
......@@ -86,7 +86,7 @@ export default vue.extend({
},
},
data: () => ({
data: (): {conditionModalDisplayed: boolean, conditionModalType: string} => ({
conditionModalDisplayed: false,
conditionModalType: '',
}),
......@@ -136,6 +136,10 @@ export default vue.extend({
},
methods: {
onAddConditional(): void {
this.conditionModalType = ''
this.conditionModalDisplayed = true
},
onEditConditional(type: string): void {
this.conditionModalType = type
this.conditionModalDisplayed = true
......
......@@ -185,12 +185,13 @@ export default Vue.extend({
},
watch: {
type: function() {
if (this.type) {
displayed: function() {
if (this.displayed && this.type) {
this.typeSelected = this.type;
this.items.splice(0, this.items.length);
const conditions = ConditionService.getConditions(this.field.conditional.basic[this.type]);
console.log(conditions);
if (conditions) {
conditions.forEach((condition) => {
this.items.push(condition);
......
......@@ -102,6 +102,7 @@
:headers="optionsTableHeaders"
:items="fieldOptions"
:search="searchOption"
:custom-filter="customFilter"
>
<template v-slot:item.label="{ item }">
<v-edit-dialog :return-value="item.label">
......@@ -189,10 +190,11 @@
import { UsfTabDataInputDisplayedBySelect } from '../UsfTabDataInputDisplayedBySelect';
import { mapActions } from 'vuex';
import Vue from 'vue';
import { Field } from '../../../../../../../types/models/form';
import { Field, Option } from '#form-plugin/models/form';
import UsfTabDataInputSelectImportOptions
from '../UsfTabDataInputSelectImportOptions/UsfTabDataInputSelectImportOptions.vue';
import { Control } from '#form-plugin/models/control';
import { DataTableHeader } from 'vuetify';
export default Vue.extend({
name: 'UsfTabDataInput',
......@@ -275,8 +277,8 @@ export default Vue.extend({
fieldOptions() {
return this.field.options.map(optionId => this.$store.getters['form/getOptionByIdOrValue'](optionId));
},
optionsTableHeaders() {
const optionsTableHeaders = [
optionsTableHeaders(): DataTableHeader[] {
const optionsTableHeaders: DataTableHeader[] = [
{
text: this._uct('builder.tabs.data.dataTable.headers.label'),
value: 'label',
......@@ -308,7 +310,6 @@ export default Vue.extend({
text: this._uct('builder.tabs.data.dataTable.headers.displayBy'),
value: 'displayedBy',
sortable: false,
filterable: false,
});
}
return optionsTableHeaders;
......@@ -330,6 +331,21 @@ export default Vue.extend({
this.newOption = Object.assign({}, this.newOptionDefault);
}, 300);
},
customFilter(itemLabel: string, search: string | null, item: Option): boolean {
if (search === null) return true;
if (item.displayedBy !== undefined && item.displayedBy.length) {
return itemLabel.includes(search) || item.displayedBy.some((optionId) => {
const option: Option | undefined = this.getOption(optionId);
if (option) {
return optionId.includes(search) || option.label.includes(search);
}
return false;
});
}
return itemLabel.includes(search)
},
getOption(id) {
return this.$store.getters['form/getOptionByIdOrValue'](id);
},
......
......@@ -106,7 +106,7 @@ export default Vue.extend({
await store.dispatch('form/updateField', {
id: this.field.id,
label,
name: this.field.name ? undefined : camelCase(label),
name: this.field.name || camelCase(label),
});
},
},
......
export * from 'Content'
export * from 'Repeat'
export * from 'Style'
export * from 'Visibility'
export * from './Content'
export * from './Repeat'
export * from './Style'
export * from './Visibility'
......@@ -113,20 +113,22 @@ export default Vue.extend({
mixins: [tabValidationMixin],
data: (): componentData => ({
dateUnitOptions: [
// @ts-ignore
{ value: 'days', label: this._uct('builder.tabs.validation.date.days') },
// @ts-ignore
{ value: 'weeks', label: this._uct('builder.tabs.validation.date.weeks') },
// @ts-ignore
{ value: 'months', label: this._uct('builder.tabs.validation.date.months') },
// @ts-ignore
{ value: 'years', label: this._uct('builder.tabs.validation.date.years') },
],
dateMinErrorMessages: [],
dateMaxErrorMessages: [],
}),
data: function(): componentData {
return {
dateUnitOptions: [
// @ts-ignore
{ value: 'days', label: this._uct('builder.tabs.validation.date.days') },
// @ts-ignore
{ value: 'weeks', label: this._uct('builder.tabs.validation.date.weeks') },
// @ts-ignore
{ value: 'months', label: this._uct('builder.tabs.validation.date.months') },
// @ts-ignore
{ value: 'years', label: this._uct('builder.tabs.validation.date.years') },
],
dateMinErrorMessages: [],
dateMaxErrorMessages: [],
};
},
computed: {
dateMinError(): boolean {
......
<template>
<section>
<v-switch
input-value="isTokenField"
v-if="isHybridForm && isDefaultTokenValueField"
:input-value="linkTokenValue"
:label="_uct('builder.tabs.validation.tokenField.switchLabel')"
@change="onUpdateTokenFieldStatus"
/>
<div v-if="isTokenField">
<v-select
:items="tokenFields"
:label="_uct('builder.tabs.validation.tokenField.selectLabel')"
:value="field.defaultTokenValue"
@change="onUpdateField($event, 'defaultTokenValue')"
/>
</div>
<v-select
v-if="linkTokenValue"
:items="tokenFields"
:label="_uct('builder.tabs.validation.tokenField.selectLabel')"
:value="field.defaultTokenValue"
@change="onUpdateField($event, 'defaultTokenValue')"
/>
<v-text-field
v-else
v-else-if="!linkTokenValue && !isDateField"
:label="_uct('builder.tabs.validation.defaultValue')"
:value="field.defaultValue"
@change="onUpdateField($event, 'defaultText')"
......@@ -33,19 +33,36 @@ export default Vue.extend({
mixins: [tabValidationMixin],
data: (): { linkTokenValue: boolean } => ({
linkTokenValue: false,
}),
computed: {
...mapGetters('form', ['isHybridForm']),