- corretto componente CDateTime
- aggiunto componente CDateTimeStartEnd
This commit is contained in:
@@ -1,10 +1,87 @@
|
||||
.calendar_comp{
|
||||
max-width: 170px;
|
||||
@media (max-width: 400px) {
|
||||
max-width: 400px;
|
||||
/* ====== Config ====== */
|
||||
:root {
|
||||
--picker-actions-h: 56px; /* altezza footer azioni */
|
||||
}
|
||||
|
||||
/* Per device piccolissimi riduciamo l'altezza */
|
||||
@media (max-width: 360px) {
|
||||
:root { --picker-actions-h: 48px; }
|
||||
}
|
||||
|
||||
/* ====== Campo visualizzazione valore (nel q-field) ====== */
|
||||
.cdt-display {
|
||||
min-height: 1.5rem;
|
||||
line-height: 1.5rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* ====== Contenitori popup/dialog del picker ====== */
|
||||
.picker-popup,
|
||||
.picker-sheet {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
.picker-toolbar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
background: var(--q-color-white);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.picker-body {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
padding: 0.5rem;
|
||||
/* spazio per non coprire il contenuto col footer */
|
||||
padding-bottom: calc(var(--picker-actions-h) + 0.5rem);
|
||||
}
|
||||
|
||||
.picker-actions {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
z-index: 2;
|
||||
background: var(--q-color-white);
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.08);
|
||||
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06);
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
min-height: var(--picker-actions-h);
|
||||
padding: 0.5rem;
|
||||
|
||||
.row {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.q-btn {
|
||||
min-width: 0; /* evita overflow su schermi stretti */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.calendar_comp {
|
||||
vertical-align: center;
|
||||
/* ====== Stile responsive del contenitore input ====== */
|
||||
.calendar_comp {
|
||||
width: 100%;
|
||||
max-width: 320px; /* dimensione confortevole su desktop stretti */
|
||||
display: flex;
|
||||
align-items: center; /* allinea testo/icone verticalmente */
|
||||
vertical-align: middle; /* per elementi inline-block eventualmente ereditati */
|
||||
|
||||
@media (max-width: 400px) {
|
||||
max-width: 100%; /* su mobile usa tutta la larghezza disponibile */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ====== Micro-tweak tipografici per bottoni, se serve compattezza ====== */
|
||||
@media (max-width: 360px) {
|
||||
.picker-actions .q-btn {
|
||||
padding: 0 0.5rem;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,190 +1,173 @@
|
||||
import { defineComponent, ref, toRef, watch } from 'vue'
|
||||
import { tools } from '@src/store/Modules/tools'
|
||||
|
||||
import { useQuasar } from 'quasar'
|
||||
import { useCalendarStore } from '@store/CalendarStore'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { toolsext } from '@store/Modules/toolsext'
|
||||
import { defineComponent, ref, watch, computed } from 'vue';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { tools } from '@src/store/Modules/tools';
|
||||
import { toolsext } from '@store/Modules/toolsext';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CDate',
|
||||
emits: ['update:value', 'savetoclose', 'show', 'clear'],
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
valueDate: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
data_class: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
canEdit: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: 'Val:',
|
||||
},
|
||||
disable: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
bgcolor: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
dense: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
view: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'date-time',
|
||||
},
|
||||
addstrrequired: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
value: { type: [String, null] as unknown as () => string | null, default: null },
|
||||
valueDate: { type: String, default: '' },
|
||||
data_class: { type: String, default: '' },
|
||||
canEdit: { type: Boolean, default: true },
|
||||
label: { type: String, required: true, default: 'Val:' },
|
||||
disable: { type: Boolean, default: false },
|
||||
bgcolor: { type: String, default: '' },
|
||||
dense: { type: Boolean, default: false },
|
||||
view: { type: String as () => 'date-time' | 'date' | 'time', default: 'date-time' },
|
||||
addstrrequired: { type: String, default: '' },
|
||||
nullable: { type: Boolean, default: true },
|
||||
nullText: { type: String, default: '—' },
|
||||
clearIcon: { type: String, default: 'fas fa-ban' },
|
||||
calendarIcon: { type: String, default: 'fas fa-calendar-day' },
|
||||
clockIcon: { type: String, default: 'fas fa-clock' },
|
||||
},
|
||||
components: {},
|
||||
setup(props, { emit }) {
|
||||
const $q = useQuasar()
|
||||
const $q = useQuasar();
|
||||
const { t } = useI18n();
|
||||
|
||||
const showDateTimeScroller = ref(false)
|
||||
const saveit = ref(false)
|
||||
const myvalue = ref('')
|
||||
const mydate = ref(false)
|
||||
const mytime = ref(false)
|
||||
const valueprec = ref('')
|
||||
// const myvalueDate = toRef(props, 'valueDate')
|
||||
const isMobile = computed(() => $q.screen.lt.sm);
|
||||
const isDesktop = computed(() => $q.screen.gt.sm)
|
||||
|
||||
// LABEL RESPONSIVE per il bottone di conferma
|
||||
const confirmLabelDate = computed(() =>
|
||||
isMobile.value
|
||||
? t('common.set') || 'Imposta'
|
||||
: `Imposta a ${tools.getstrDateLong(myvalue.value)}`
|
||||
);
|
||||
const confirmLabelTime = computed(() =>
|
||||
isMobile.value
|
||||
? t('common.set') || 'Imposta'
|
||||
: `Imposta a ${tools.getstrTime(myvalue.value)}`
|
||||
);
|
||||
|
||||
const showDateTimeScroller = ref(false); // desktop popup v-model
|
||||
const saveit = ref(false);
|
||||
const myvalue = ref<string | null>(null);
|
||||
const mydate = ref(false);
|
||||
const mytime = ref(false);
|
||||
const valueprec = ref<string | null>(null);
|
||||
|
||||
// mobile dialog state
|
||||
const dateDialog = ref(false);
|
||||
const timeDialog = ref(false);
|
||||
|
||||
const dateDesktopDialog = ref(false)
|
||||
const timeDesktopDialog = ref(false)
|
||||
|
||||
const hasValue = computed(() => !!myvalue.value);
|
||||
|
||||
function getclass() {
|
||||
return 'calendar_comp ' + props.data_class
|
||||
return 'calendar_comp ' + props.data_class;
|
||||
}
|
||||
|
||||
function Opening() {
|
||||
console.log('Opening', 'myvalue', myvalue.value)
|
||||
saveit.value = false
|
||||
valueprec.value = myvalue.value
|
||||
if (myvalue.value === '') {
|
||||
// myvalueDate.value = tools.getstrYYMMDDDateTime(new Date())
|
||||
myvalue.value = tools.getstrYYMMDDDateTime(new Date())
|
||||
}
|
||||
// console.log('Opening', myvalueDate, myvalue)
|
||||
emit('show')
|
||||
saveit.value = false;
|
||||
valueprec.value = myvalue.value;
|
||||
if (!myvalue.value) myvalue.value = tools.getstrYYMMDDDateTime(new Date());
|
||||
emit('show');
|
||||
}
|
||||
|
||||
function Closing() {
|
||||
mydate.value = false
|
||||
mytime.value = false
|
||||
// console.log('Closing')
|
||||
if (!saveit.value) {
|
||||
if (myvalue.value !== valueprec.value) {
|
||||
myvalue.value = valueprec.value
|
||||
tools.showNeutralNotif($q, t('db.reccanceled'))
|
||||
}
|
||||
mydate.value = false;
|
||||
mytime.value = false;
|
||||
if (!saveit.value && myvalue.value !== valueprec.value) {
|
||||
myvalue.value = valueprec.value;
|
||||
tools.showNeutralNotif($q, t('db.reccanceled'));
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => props.value, (value, oldval) => {
|
||||
if (value) {
|
||||
myvalue.value = tools.getstrYYMMDDDateTime(value)
|
||||
// myvalueDate.value = myvalue.value
|
||||
console.log('myvalue Date = ', myvalue.value)
|
||||
}
|
||||
|
||||
})
|
||||
watch(
|
||||
() => props.value,
|
||||
(val) => {
|
||||
if (val === null || val === '') myvalue.value = null;
|
||||
else myvalue.value = tools.getstrYYMMDDDateTime(val);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
function savetoclose() {
|
||||
// console.log('Close')
|
||||
saveit.value = true
|
||||
showDateTimeScroller.value = false
|
||||
|
||||
// chiudi mobile
|
||||
dateDialog.value = false
|
||||
timeDialog.value = false
|
||||
|
||||
// chiudi desktop
|
||||
dateDesktopDialog.value = false
|
||||
timeDesktopDialog.value = false
|
||||
|
||||
emit('savetoclose', myvalue.value, valueprec.value)
|
||||
}
|
||||
|
||||
function scrollerPopupStyle280() {
|
||||
if ($q.screen.lt.sm) {
|
||||
return {
|
||||
width: '100vw',
|
||||
height: '100vh',
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
maxHeight: '400px',
|
||||
height: '400px',
|
||||
width: '280px',
|
||||
}
|
||||
}
|
||||
return { maxHeight: '420px', height: '420px', width: '320px' };
|
||||
}
|
||||
|
||||
function created() {
|
||||
if (props.value !== null) {
|
||||
myvalue.value = tools.getstrYYMMDDDateTime(props.value)
|
||||
}
|
||||
|
||||
// console.log('created myvalue', myvalue)
|
||||
function changeval(newval: string | Date) {
|
||||
const out =
|
||||
typeof newval === 'string' ? newval : tools.getstrYYMMDDDateTime(newval);
|
||||
myvalue.value = out;
|
||||
emit('update:value', out);
|
||||
saveit.value = true;
|
||||
emit('savetoclose', out, valueprec.value);
|
||||
}
|
||||
|
||||
function changeval(newval: Date) {
|
||||
// console.log('changeval', newval, 'value=', value, 'myvalue=', myvalue)
|
||||
emit('update:value', newval)
|
||||
saveit.value = true
|
||||
emit('savetoclose', myvalue.value, valueprec.value)
|
||||
}
|
||||
|
||||
function replacevalue() {
|
||||
// console.log('changeval', newval, 'value=', value, 'myvalue=', myvalue)
|
||||
if (valueprec.value) {
|
||||
emit('update:value', valueprec.value)
|
||||
saveit.value = true
|
||||
showDateTimeScroller.value = false
|
||||
emit('savetoclose', valueprec.value, valueprec.value)
|
||||
}
|
||||
}
|
||||
|
||||
function mystyle() {
|
||||
if (props.label !== '')
|
||||
return ''
|
||||
else
|
||||
return ''
|
||||
}
|
||||
|
||||
function getstrDate(mydate: Date | string) {
|
||||
if (props.view === 'date-time') {
|
||||
return tools.getstrDateTime(mydate)
|
||||
} else {
|
||||
return tools.getstrDate(mydate)
|
||||
}
|
||||
}
|
||||
|
||||
function azzera() {
|
||||
function replacevalue() {
|
||||
emit('update:value', valueprec.value as unknown as string)
|
||||
saveit.value = true
|
||||
showDateTimeScroller.value = false
|
||||
emit('savetoclose', null, valueprec.value)
|
||||
|
||||
// chiudi mobile
|
||||
dateDialog.value = false
|
||||
timeDialog.value = false
|
||||
|
||||
// chiudi desktop
|
||||
dateDesktopDialog.value = false
|
||||
timeDesktopDialog.value = false
|
||||
|
||||
emit('savetoclose', valueprec.value, valueprec.value)
|
||||
}
|
||||
|
||||
function clearDate() {
|
||||
saveit.value = true
|
||||
showDateTimeScroller.value = false
|
||||
dateDialog.value = false
|
||||
timeDialog.value = false
|
||||
dateDesktopDialog.value = false
|
||||
timeDesktopDialog.value = false
|
||||
myvalue.value = null
|
||||
emit('update:value', null as unknown as string)
|
||||
emit('savetoclose', null, valueprec.value)
|
||||
emit('clear')
|
||||
tools.showNeutralNotif($q, t('common.cleared') || 'Valore rimosso')
|
||||
}
|
||||
|
||||
function openDate() {
|
||||
if (isMobile.value) { Opening(); dateDialog.value = true }
|
||||
else { Opening(); dateDesktopDialog.value = true }
|
||||
}
|
||||
function openTime() {
|
||||
if (isMobile.value) { Opening(); timeDialog.value = true }
|
||||
else { Opening(); timeDesktopDialog.value = true }
|
||||
}
|
||||
|
||||
|
||||
function getstrDate(myd: string | Date | null) {
|
||||
if (!myd) return props.nullText;
|
||||
if (props.view === 'date-time') return tools.getstrDateTime(myd);
|
||||
if (props.view === 'date') return tools.getstrDate(myd);
|
||||
return tools.getstrTime(myd);
|
||||
}
|
||||
|
||||
created()
|
||||
|
||||
return {
|
||||
toolsext,
|
||||
changeval,
|
||||
scrollerPopupStyle280,
|
||||
mystyle,
|
||||
getstrDate,
|
||||
savetoclose,
|
||||
Closing,
|
||||
@@ -196,7 +179,20 @@ export default defineComponent({
|
||||
mydate,
|
||||
mytime,
|
||||
tools,
|
||||
azzera,
|
||||
}
|
||||
clearDate,
|
||||
hasValue,
|
||||
// responsive
|
||||
isMobile,
|
||||
dateDialog,
|
||||
timeDialog,
|
||||
openDate,
|
||||
openTime,
|
||||
valueprec,
|
||||
confirmLabelDate,
|
||||
confirmLabelTime,
|
||||
isDesktop,
|
||||
dateDesktopDialog,
|
||||
timeDesktopDialog,
|
||||
};
|
||||
},
|
||||
})
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<div class="" :style="mystyle()">
|
||||
<div>
|
||||
<!-- input nascosto per compatibilità -->
|
||||
<q-input
|
||||
v-model="myvalue"
|
||||
v-show="false"
|
||||
@@ -15,8 +16,7 @@
|
||||
debounce="500"
|
||||
@update:model-value="changeval"
|
||||
:input-class="getclass()"
|
||||
>
|
||||
</q-input>
|
||||
/>
|
||||
|
||||
<q-field
|
||||
:label="label"
|
||||
@@ -28,117 +28,202 @@
|
||||
:bg-color="bgcolor"
|
||||
debounce="500"
|
||||
:input-class="getclass()"
|
||||
:disable="disable"
|
||||
>
|
||||
|
||||
<template v-slot:control>
|
||||
<div style="">
|
||||
<div
|
||||
class="self-center full-width no-outline"
|
||||
:style="mystyle()"
|
||||
tabindex="0"
|
||||
>
|
||||
{{ getstrDate(myvalue) }}
|
||||
</div>
|
||||
<template #control>
|
||||
<div
|
||||
class="self-center full-width no-outline cdt-display"
|
||||
tabindex="0"
|
||||
>
|
||||
{{ getstrDate(myvalue) }}
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:append>
|
||||
|
||||
<template #append>
|
||||
<!-- Disattiva -->
|
||||
<q-btn
|
||||
v-if="canEdit && nullable"
|
||||
dense
|
||||
flat
|
||||
:icon="clearIcon"
|
||||
:title="$t('common.clear') || 'Disattiva'"
|
||||
@click="clearDate"
|
||||
class="q-mr-xs"
|
||||
/>
|
||||
|
||||
<!-- Apri Date -->
|
||||
<q-btn
|
||||
v-if="canEdit"
|
||||
dense
|
||||
color="primary"
|
||||
v-if="canEdit"
|
||||
icon="fas fa-calendar-day"
|
||||
:icon="calendarIcon"
|
||||
class="cursor-pointer"
|
||||
@click="mydate = !mydate"
|
||||
>
|
||||
</q-btn>
|
||||
@click="openDate"
|
||||
/>
|
||||
|
||||
<!-- Apri Time -->
|
||||
<q-btn
|
||||
v-if="canEdit"
|
||||
dense
|
||||
color="primary"
|
||||
v-if="canEdit"
|
||||
icon="fas fa-clock"
|
||||
:icon="clockIcon"
|
||||
class="cursor-pointer"
|
||||
@click="mytime = !mytime"
|
||||
>
|
||||
</q-btn>
|
||||
<q-popup-proxy
|
||||
v-if="mydate"
|
||||
transition-show="flip-up"
|
||||
v-model="showDateTimeScroller"
|
||||
@before-show="Opening"
|
||||
@before-hide="Closing"
|
||||
>
|
||||
<q-card class="justify-center">
|
||||
<div class="q-gutter-md justify-center">
|
||||
<q-date
|
||||
v-model="myvalue"
|
||||
mask="YYYY-MM-DD HH:mm"
|
||||
color="purple"
|
||||
@update:model-value="changeval"
|
||||
@close="
|
||||
() => {
|
||||
savetoclose();
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<q-card-actions align="center">
|
||||
<q-btn icon="fas fa-trash"
|
||||
@click="azzera"></q-btn>
|
||||
<div class="row justify-center">
|
||||
<q-btn
|
||||
:label="$t('dialog.cancel')"
|
||||
@click="replacevalue"
|
||||
></q-btn>
|
||||
<q-btn
|
||||
:label="'Imposta a ' + tools.getstrDateLong(myvalue)"
|
||||
color="primary"
|
||||
v-close-popup
|
||||
></q-btn>
|
||||
</div>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-popup-proxy>
|
||||
<q-popup-proxy
|
||||
v-if="mytime"
|
||||
transition-show="flip-up"
|
||||
v-model="showDateTimeScroller"
|
||||
@before-show="Opening"
|
||||
@before-hide="Closing"
|
||||
>
|
||||
<q-card class="justify-center">
|
||||
<div class="q-gutter-md justify-center">
|
||||
<q-time
|
||||
v-model="myvalue"
|
||||
mask="YYYY-MM-DD HH:mm"
|
||||
color="purple"
|
||||
@update:model-value="changeval"
|
||||
@close="
|
||||
() => {
|
||||
savetoclose();
|
||||
}
|
||||
"
|
||||
/>
|
||||
<div class="row justify-center">
|
||||
<q-btn
|
||||
:label="$t('dialog.cancel')"
|
||||
@click="replacevalue"
|
||||
></q-btn>
|
||||
<q-btn
|
||||
:label="'Imposta a ' + tools.getstrTime(myvalue)"
|
||||
color="primary"
|
||||
v-close-popup
|
||||
></q-btn>
|
||||
</div>
|
||||
</div>
|
||||
</q-card>
|
||||
</q-popup-proxy>
|
||||
@click="openTime"
|
||||
/>
|
||||
</template>
|
||||
</q-field>
|
||||
|
||||
<!-- ===== Desktop: Dialog centrati e limitati ===== -->
|
||||
|
||||
<!-- DATE (desktop) -->
|
||||
<q-dialog
|
||||
v-model="dateDesktopDialog"
|
||||
transition-show="fade"
|
||||
transition-hide="fade"
|
||||
>
|
||||
<q-card class="picker-modal-desktop">
|
||||
<q-toolbar class="picker-toolbar">
|
||||
<div class="text-subtitle2">{{ label }}</div>
|
||||
<q-space />
|
||||
<q-btn
|
||||
v-if="nullable"
|
||||
flat dense :icon="clearIcon"
|
||||
:label="$t('common.clear') || 'Disattiva'"
|
||||
color="negative"
|
||||
@click="clearDate"
|
||||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<div class="picker-body">
|
||||
<q-date
|
||||
v-model="myvalue"
|
||||
mask="YYYY-MM-DD HH:mm"
|
||||
color="purple"
|
||||
class="fit"
|
||||
@update:model-value="changeval"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="picker-actions q-pa-sm">
|
||||
<q-btn flat :label="$t('dialog.cancel')" @click="replacevalue" />
|
||||
<q-btn :label="confirmLabelDate" color="primary" @click="savetoclose" />
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<!-- TIME (desktop) -->
|
||||
<q-dialog
|
||||
v-model="timeDesktopDialog"
|
||||
transition-show="fade"
|
||||
transition-hide="fade"
|
||||
>
|
||||
<q-card class="picker-modal-desktop">
|
||||
<q-toolbar class="picker-toolbar">
|
||||
<div class="text-subtitle2">{{ label }}</div>
|
||||
<q-space />
|
||||
</q-toolbar>
|
||||
|
||||
<div class="picker-body">
|
||||
<q-time
|
||||
v-model="myvalue"
|
||||
mask="YYYY-MM-DD HH:mm"
|
||||
color="purple"
|
||||
class="fit"
|
||||
@update:model-value="changeval"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="picker-actions q-pa-sm">
|
||||
<q-btn flat :label="$t('dialog.cancel')" @click="replacevalue" />
|
||||
<q-btn :label="confirmLabelTime" color="primary" @click="savetoclose" />
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<!-- ===== Mobile: Dialog full screen ===== -->
|
||||
<q-dialog
|
||||
v-model="dateDialog"
|
||||
maximized
|
||||
transition-show="slide-up"
|
||||
transition-hide="slide-down"
|
||||
>
|
||||
<q-card class="picker-sheet">
|
||||
<q-toolbar class="picker-toolbar">
|
||||
<q-btn
|
||||
flat round dense icon="arrow_back"
|
||||
@click="replacevalue"
|
||||
/>
|
||||
<div class="text-subtitle1 q-ml-sm">{{ label }}</div>
|
||||
<q-space />
|
||||
<q-btn
|
||||
v-if="nullable"
|
||||
flat dense :icon="clearIcon"
|
||||
:label="$t('common.clear') || 'Disattiva'"
|
||||
color="negative"
|
||||
@click="clearDate"
|
||||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<div class="picker-body">
|
||||
<q-date
|
||||
v-model="myvalue"
|
||||
mask="YYYY-MM-DD HH:mm"
|
||||
color="purple"
|
||||
class="fit"
|
||||
@update:model-value="changeval"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="picker-actions q-pa-sm">
|
||||
<q-btn flat :label="$t('dialog.cancel')" @click="replacevalue" />
|
||||
<q-btn :label="confirmLabelDate" color="primary" @click="savetoclose" />
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<q-dialog
|
||||
v-model="timeDialog"
|
||||
maximized
|
||||
transition-show="slide-up"
|
||||
transition-hide="slide-down"
|
||||
>
|
||||
<q-card class="picker-sheet">
|
||||
<q-toolbar class="picker-toolbar">
|
||||
<q-btn
|
||||
flat round dense icon="arrow_back"
|
||||
@click="replacevalue"
|
||||
/>
|
||||
<div class="text-subtitle1 q-ml-sm">{{ label }}</div>
|
||||
<q-space />
|
||||
<q-btn
|
||||
v-if="nullable"
|
||||
flat dense :icon="clearIcon"
|
||||
:label="$t('common.clear') || 'Disattiva'"
|
||||
color="negative"
|
||||
@click="clearDate"
|
||||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<div class="picker-body">
|
||||
<q-time
|
||||
v-model="myvalue"
|
||||
mask="YYYY-MM-DD HH:mm"
|
||||
color="purple"
|
||||
class="fit"
|
||||
@update:model-value="changeval"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="picker-actions q-pa-sm">
|
||||
<q-btn flat :label="$t('dialog.cancel')" @click="replacevalue" />
|
||||
<q-btn :label="confirmLabelTime" color="primary" @click="savetoclose" />
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" src="./CDateTime.ts">
|
||||
</script>
|
||||
<script lang="ts" src="./CDateTime.ts"></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './CDateTime.scss';
|
||||
|
||||
95
src/components/CDateTimeStartEnd/CDateTimeStartEnd.scss
Executable file
95
src/components/CDateTimeStartEnd/CDateTimeStartEnd.scss
Executable file
@@ -0,0 +1,95 @@
|
||||
:root { --picker-actions-h: 56px; }
|
||||
@media (max-width: 360px) { :root { --picker-actions-h: 48px; } }
|
||||
|
||||
.cdt-display {
|
||||
min-height: 1.5rem;
|
||||
line-height: 1.5rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.calendar_comp {
|
||||
width: 100%;
|
||||
max-width: 320px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
vertical-align: middle;
|
||||
|
||||
@media (max-width: 400px) { max-width: 100%; }
|
||||
}
|
||||
|
||||
/* Desktop dialog centrato */
|
||||
.picker-modal-desktop {
|
||||
width: clamp(420px, 56vw, 720px);
|
||||
max-height: min(80vh, 640px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
border-radius: 16px;
|
||||
|
||||
.picker-toolbar {
|
||||
position: sticky; top: 0; z-index: 2;
|
||||
background: var(--q-color-white);
|
||||
border-bottom: 1px solid rgba(0,0,0,.08);
|
||||
}
|
||||
|
||||
.picker-body {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
padding: .5rem;
|
||||
padding-bottom: calc(var(--picker-actions-h) + .5rem);
|
||||
}
|
||||
|
||||
.picker-actions {
|
||||
position: sticky; bottom: 0; z-index: 2;
|
||||
background: var(--q-color-white);
|
||||
border-top: 1px solid rgba(0,0,0,.08);
|
||||
box-shadow: 0 -2px 8px rgba(0,0,0,.06);
|
||||
display: flex; justify-content: flex-end; align-items: center;
|
||||
gap: .5rem; min-height: var(--picker-actions-h); padding: .5rem;
|
||||
|
||||
.q-btn { min-width: 0; }
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile full-screen */
|
||||
.picker-sheet {
|
||||
display: flex; flex-direction: column; height: 100vh; overflow: hidden;
|
||||
|
||||
.picker-toolbar {
|
||||
position: sticky; top: 0; z-index: 2;
|
||||
background: var(--q-color-white);
|
||||
border-bottom: 1px solid rgba(0,0,0,.08);
|
||||
}
|
||||
.picker-body {
|
||||
flex: 1 1 auto; overflow: auto; padding: .5rem;
|
||||
padding-bottom: calc(var(--picker-actions-h) + .5rem);
|
||||
}
|
||||
.picker-actions {
|
||||
position: sticky; bottom: 0; z-index: 2;
|
||||
background: var(--q-color-white);
|
||||
border-top: 1px solid rgba(0,0,0,.08);
|
||||
box-shadow: 0 -2px 8px rgba(0,0,0,.06);
|
||||
display: flex; justify-content: flex-end; align-items: center;
|
||||
gap: .5rem; min-height: var(--picker-actions-h); padding: .5rem;
|
||||
|
||||
.q-btn { min-width: 0; }
|
||||
}
|
||||
}
|
||||
|
||||
/* Dark mode */
|
||||
.body--dark .picker-modal-desktop,
|
||||
.q-dark .picker-modal-desktop,
|
||||
.body--dark .picker-sheet,
|
||||
.q-dark .picker-sheet {
|
||||
.picker-toolbar, .picker-actions {
|
||||
background: var(--q-color-dark) !important;
|
||||
border-color: rgba(255,255,255,.12);
|
||||
box-shadow: 0 -2px 8px rgba(0,0,0,.4);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 360px) {
|
||||
.picker-actions .q-btn { padding: 0 .5rem; font-size: .85rem; }
|
||||
}
|
||||
363
src/components/CDateTimeStartEnd/CDateTimeStartEnd.ts
Executable file
363
src/components/CDateTimeStartEnd/CDateTimeStartEnd.ts
Executable file
@@ -0,0 +1,363 @@
|
||||
import { defineComponent, ref, watch, computed } from 'vue';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { tools } from '@src/store/Modules/tools';
|
||||
import { toolsext } from '@store/Modules/toolsext';
|
||||
|
||||
function toTS(s: string | null): number | null {
|
||||
if (!s) return null;
|
||||
const iso = s.includes('T') ? s : s.replace(' ', 'T');
|
||||
const ts = Date.parse(iso);
|
||||
return Number.isNaN(ts) ? null : ts;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CDateTimeStartEnd',
|
||||
emits: [
|
||||
'update:startValue',
|
||||
'update:endValue',
|
||||
'show',
|
||||
'savetoclose',
|
||||
'clear-start',
|
||||
'clear-end',
|
||||
],
|
||||
props: {
|
||||
startValue: { type: [String, null] as unknown as () => string | null, default: null },
|
||||
endValue: { type: [String, null] as unknown as () => string | null, default: null },
|
||||
|
||||
startLabel: { type: String, default: 'Inizio' },
|
||||
endLabel: { type: String, default: 'Fine' },
|
||||
|
||||
data_class: { type: String, default: '' },
|
||||
canEdit: { type: Boolean, default: true },
|
||||
disable: { type: Boolean, default: false },
|
||||
bgcolor: { type: String, default: '' },
|
||||
dense: { type: Boolean, default: false },
|
||||
|
||||
view: { type: String as () => 'date-time' | 'date' | 'time', default: 'date-time' },
|
||||
nullableStart: { type: Boolean, default: true },
|
||||
nullableEnd: { type: Boolean, default: true },
|
||||
nullText: { type: String, default: '—' },
|
||||
|
||||
calendarIcon: { type: String, default: 'fas fa-calendar-day' },
|
||||
clockIcon: { type: String, default: 'fas fa-clock' },
|
||||
clearIcon: { type: String, default: 'fas fa-ban' },
|
||||
|
||||
optionalText: { type: String, default: 'opzionale' },
|
||||
enableEndText: { type: String, default: 'Attiva' },
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const $q = useQuasar();
|
||||
const { t } = useI18n();
|
||||
|
||||
const isMobile = computed(() => $q.screen.lt.sm);
|
||||
|
||||
// local state
|
||||
const startVal = ref<string | null>(null);
|
||||
const endVal = ref<string | null>(null);
|
||||
const startPrev = ref<string | null>(null);
|
||||
const endPrev = ref<string | null>(null);
|
||||
|
||||
// dialog states
|
||||
const startDateDialog = ref(false);
|
||||
const startTimeDialog = ref(false);
|
||||
const endDateDialog = ref(false);
|
||||
const endTimeDialog = ref(false);
|
||||
|
||||
const startDateDesktopDialog = ref(false);
|
||||
const startTimeDesktopDialog = ref(false);
|
||||
const endDateDesktopDialog = ref(false);
|
||||
const endTimeDesktopDialog = ref(false);
|
||||
|
||||
const endError = ref<string>('');
|
||||
|
||||
// sync props -> local
|
||||
watch(
|
||||
() => props.startValue,
|
||||
(v) => {
|
||||
startVal.value = v ? tools.getstrYYMMDDDateTime(v) : null;
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
watch(
|
||||
() => props.endValue,
|
||||
(v) => {
|
||||
endVal.value = v ? tools.getstrYYMMDDDateTime(v) : null;
|
||||
validateRange();
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
function getstrDate(val: string | Date | null) {
|
||||
if (!val) return props.nullText;
|
||||
if (props.view === 'date-time') return tools.getstrDateTime(val);
|
||||
if (props.view === 'date') return tools.getstrDate(val);
|
||||
return tools.getstrTime(val);
|
||||
}
|
||||
|
||||
function opening(kind: 'start' | 'end') {
|
||||
if (kind === 'start') {
|
||||
startPrev.value = startVal.value;
|
||||
if (!startVal.value) startVal.value = tools.getstrYYMMDDDateTime(new Date());
|
||||
} else {
|
||||
endPrev.value = endVal.value;
|
||||
if (!endVal.value)
|
||||
endVal.value = startVal.value || tools.getstrYYMMDDDateTime(new Date());
|
||||
}
|
||||
endError.value = '';
|
||||
emit('show');
|
||||
}
|
||||
|
||||
function cancelStart() {
|
||||
startVal.value = startPrev.value;
|
||||
closeAllStart();
|
||||
}
|
||||
function cancelEnd() {
|
||||
endVal.value = endPrev.value;
|
||||
endError.value = '';
|
||||
closeAllEnd();
|
||||
}
|
||||
|
||||
function saveStart() {
|
||||
const currStart = startVal.value;
|
||||
const prevStart = startPrev.value;
|
||||
|
||||
// salva start
|
||||
emit('update:startValue', currStart as unknown as string);
|
||||
emit('savetoclose', { which: 'start', current: currStart, prev: prevStart });
|
||||
|
||||
// Se esiste end e l'intervallo è invalido, riallinea fine preservando l'ora originale
|
||||
if (endVal.value) {
|
||||
const tsStart = toTS(currStart);
|
||||
const tsEnd = toTS(endVal.value);
|
||||
if (tsStart !== null && tsEnd !== null && tsEnd < tsStart) {
|
||||
endVal.value = buildEndWithStartDatePreservingEndTime(tsStart, tsEnd);
|
||||
endError.value = '';
|
||||
emit('update:endValue', endVal.value as unknown as string);
|
||||
emit('savetoclose', { which: 'end', current: endVal.value, prev: endPrev.value });
|
||||
tools.showNeutralNotif(
|
||||
$q,
|
||||
t('date.rangeFixed') || 'Fine allineata all’inizio mantenendo l’ora originale'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
closeAllStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Costruisce una nuova data di fine usando:
|
||||
* - data (Y/M/D) = quella di start
|
||||
* - ora (h:m:s:ms) = quella di end originale
|
||||
* Se il risultato è ancora < start, sposta end al giorno successivo mantenendo la stessa ora.
|
||||
*/
|
||||
function buildEndWithStartDatePreservingEndTime(
|
||||
tsStart: number,
|
||||
tsEnd: number
|
||||
): string {
|
||||
// Se il componente è solo 'date', non c'è ora da preservare: end = start
|
||||
if (props.view === 'date') {
|
||||
return tools.getstrYYMMDDDateTime(new Date(tsStart));
|
||||
}
|
||||
|
||||
const dStart = new Date(tsStart);
|
||||
const dEnd = new Date(tsEnd);
|
||||
|
||||
// Ricostruisci end: data = start, ora = end originale
|
||||
const newEnd = new Date(
|
||||
dStart.getFullYear(),
|
||||
dStart.getMonth(),
|
||||
dStart.getDate(),
|
||||
dEnd.getHours(),
|
||||
dEnd.getMinutes(),
|
||||
dEnd.getSeconds(),
|
||||
dEnd.getMilliseconds()
|
||||
);
|
||||
|
||||
// Se così è ancora < start (es. end 08:00, start 10:00 stesso giorno) → bump di 1 giorno
|
||||
if (newEnd.getTime() < tsStart) {
|
||||
newEnd.setDate(newEnd.getDate() + 1);
|
||||
}
|
||||
|
||||
return tools.getstrYYMMDDDateTime(newEnd);
|
||||
}
|
||||
|
||||
function saveEnd() {
|
||||
if (!validateRange(true)) {
|
||||
// blocco il salvataggio se ancora invalida
|
||||
return;
|
||||
}
|
||||
emit('update:endValue', endVal.value as unknown as string);
|
||||
emit('savetoclose', { which: 'end', current: endVal.value, prev: endPrev.value });
|
||||
closeAllEnd();
|
||||
}
|
||||
|
||||
function onStartChange(v: string | Date) {
|
||||
startVal.value = typeof v === 'string' ? v : tools.getstrYYMMDDDateTime(v);
|
||||
}
|
||||
function onEndChange(v: string | Date) {
|
||||
endVal.value = typeof v === 'string' ? v : tools.getstrYYMMDDDateTime(v);
|
||||
validateRange();
|
||||
}
|
||||
|
||||
function clearStart() {
|
||||
startVal.value = null;
|
||||
emit('update:startValue', null as unknown as string);
|
||||
emit('savetoclose', { which: 'start', current: null, prev: startPrev.value });
|
||||
// se non c'è inizio, rimuovo anche fine per coerenza
|
||||
if (endVal.value) {
|
||||
endVal.value = null;
|
||||
emit('update:endValue', null as unknown as string);
|
||||
emit('savetoclose', { which: 'end', current: null, prev: endPrev.value });
|
||||
}
|
||||
emit('clear-start');
|
||||
tools.showNeutralNotif($q, t('common.cleared') || 'Valore rimosso');
|
||||
closeAllStart();
|
||||
}
|
||||
function clearEnd() {
|
||||
endVal.value = null;
|
||||
emit('update:endValue', null as unknown as string);
|
||||
emit('clear-end');
|
||||
tools.showNeutralNotif($q, t('common.cleared') || 'Valore rimosso');
|
||||
endError.value = '';
|
||||
closeAllEnd();
|
||||
}
|
||||
function enableEnd() {
|
||||
endVal.value = startVal.value || tools.getstrYYMMDDDateTime(new Date());
|
||||
validateRange(true);
|
||||
emit('update:endValue', endVal.value as unknown as string);
|
||||
}
|
||||
|
||||
function openStartDate() {
|
||||
opening('start');
|
||||
if (isMobile.value) startDateDialog.value = true;
|
||||
else startDateDesktopDialog.value = true;
|
||||
}
|
||||
function openStartTime() {
|
||||
opening('start');
|
||||
if (isMobile.value) startTimeDialog.value = true;
|
||||
else startTimeDesktopDialog.value = true;
|
||||
}
|
||||
function openEndDate() {
|
||||
opening('end');
|
||||
if (isMobile.value) endDateDialog.value = true;
|
||||
else endDateDesktopDialog.value = true;
|
||||
}
|
||||
function openEndTime() {
|
||||
opening('end');
|
||||
if (isMobile.value) endTimeDialog.value = true;
|
||||
else endTimeDesktopDialog.value = true;
|
||||
}
|
||||
|
||||
function closeAllStart() {
|
||||
startDateDialog.value = false;
|
||||
startTimeDialog.value = false;
|
||||
startDateDesktopDialog.value = false;
|
||||
startTimeDesktopDialog.value = false;
|
||||
}
|
||||
function closeAllEnd() {
|
||||
endDateDialog.value = false;
|
||||
endTimeDialog.value = false;
|
||||
endDateDesktopDialog.value = false;
|
||||
endTimeDesktopDialog.value = false;
|
||||
}
|
||||
|
||||
function validateRange(showMsg = false): boolean {
|
||||
endError.value = '';
|
||||
const tsStart = toTS(startVal.value);
|
||||
const tsEnd = toTS(endVal.value);
|
||||
if (tsStart != null && tsEnd != null && tsEnd < tsStart) {
|
||||
endError.value =
|
||||
t('date.invalidRange') || 'La data di fine non può precedere l’inizio';
|
||||
if (showMsg) tools.showNeutralNotif($q, endError.value);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const confirmLabelStartDate = computed(() =>
|
||||
isMobile.value
|
||||
? t('common.set') || 'Imposta'
|
||||
: `Imposta a ${tools.getstrDateLong(startVal.value)}`
|
||||
);
|
||||
const confirmLabelStartTime = computed(() =>
|
||||
isMobile.value
|
||||
? t('common.set') || 'Imposta'
|
||||
: `Imposta a ${tools.getstrTime(startVal.value)}`
|
||||
);
|
||||
const confirmLabelEndDate = computed(() =>
|
||||
isMobile.value
|
||||
? t('common.set') || 'Imposta'
|
||||
: `Imposta a ${tools.getstrDateLong(endVal.value)}`
|
||||
);
|
||||
const confirmLabelEndTime = computed(() =>
|
||||
isMobile.value
|
||||
? t('common.set') || 'Imposta'
|
||||
: `Imposta a ${tools.getstrTime(endVal.value)}`
|
||||
);
|
||||
|
||||
const canEditEnd = computed(() => !!endVal.value || !props.nullableEnd);
|
||||
|
||||
return {
|
||||
toolsext,
|
||||
tools,
|
||||
// values & labels
|
||||
startVal,
|
||||
endVal,
|
||||
startLabel: computed(() => props.startLabel),
|
||||
endLabel: computed(() => props.endLabel),
|
||||
|
||||
// ui flags
|
||||
dense: props.dense,
|
||||
bgcolor: props.bgcolor,
|
||||
disable: props.disable,
|
||||
data_class: props.data_class,
|
||||
canEdit: props.canEdit,
|
||||
nullableStart: props.nullableStart,
|
||||
nullableEnd: props.nullableEnd,
|
||||
nullText: props.nullText,
|
||||
optionalText: props.optionalText,
|
||||
enableEndText: props.enableEndText,
|
||||
|
||||
calendarIcon: props.calendarIcon,
|
||||
clockIcon: props.clockIcon,
|
||||
clearIcon: props.clearIcon,
|
||||
|
||||
// dialogs
|
||||
startDateDialog,
|
||||
startTimeDialog,
|
||||
endDateDialog,
|
||||
endTimeDialog,
|
||||
startDateDesktopDialog,
|
||||
startTimeDesktopDialog,
|
||||
endDateDesktopDialog,
|
||||
endTimeDesktopDialog,
|
||||
|
||||
// methods
|
||||
getstrDate,
|
||||
openStartDate,
|
||||
openStartTime,
|
||||
openEndDate,
|
||||
openEndTime,
|
||||
cancelStart,
|
||||
cancelEnd,
|
||||
saveStart,
|
||||
saveEnd,
|
||||
onStartChange,
|
||||
onEndChange,
|
||||
clearStart,
|
||||
clearEnd,
|
||||
enableEnd,
|
||||
|
||||
// helpers
|
||||
confirmLabelStartDate,
|
||||
confirmLabelStartTime,
|
||||
confirmLabelEndDate,
|
||||
confirmLabelEndTime,
|
||||
isMobile,
|
||||
canEditEnd,
|
||||
|
||||
endError,
|
||||
};
|
||||
},
|
||||
});
|
||||
271
src/components/CDateTimeStartEnd/CDateTimeStartEnd.vue
Executable file
271
src/components/CDateTimeStartEnd/CDateTimeStartEnd.vue
Executable file
@@ -0,0 +1,271 @@
|
||||
<template>
|
||||
<div class="dtse">
|
||||
<!-- ===== RIGA CAMPO INIZIO ===== -->
|
||||
<q-field
|
||||
:label="startLabel"
|
||||
:stack-label="!!startLabel"
|
||||
:value="startVal"
|
||||
standout
|
||||
:dense="dense"
|
||||
label-color="blue-6"
|
||||
:bg-color="bgcolor"
|
||||
:disable="disable"
|
||||
:input-class="'calendar_comp ' + data_class"
|
||||
>
|
||||
<template #control>
|
||||
<div class="self-center full-width no-outline cdt-display" tabindex="0">
|
||||
{{ getstrDate(startVal) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #append>
|
||||
<!-- Disattiva INIZIO -->
|
||||
<q-btn
|
||||
v-if="canEdit && nullableStart && startVal"
|
||||
dense flat :icon="clearIcon"
|
||||
:title="$t('common.clear') || 'Disattiva'"
|
||||
@click="clearStart"
|
||||
class="q-mr-xs"
|
||||
/>
|
||||
<!-- Apri Date INIZIO -->
|
||||
<q-btn
|
||||
v-if="canEdit"
|
||||
dense color="primary"
|
||||
:icon="calendarIcon"
|
||||
class="cursor-pointer"
|
||||
@click="openStartDate"
|
||||
/>
|
||||
<!-- Apri Time INIZIO -->
|
||||
<q-btn
|
||||
v-if="canEdit"
|
||||
dense color="primary"
|
||||
:icon="clockIcon"
|
||||
class="cursor-pointer"
|
||||
@click="openStartTime"
|
||||
/>
|
||||
</template>
|
||||
</q-field>
|
||||
|
||||
<!-- ===== RIGA CAMPO FINE ===== -->
|
||||
<q-field
|
||||
:label="endLabel + ' ' + (endVal ? '' : '(' + (optionalText || 'opzionale') + ')')"
|
||||
:stack-label="!!endLabel"
|
||||
:value="endVal"
|
||||
standout
|
||||
:dense="dense"
|
||||
label-color="blue-6"
|
||||
:bg-color="bgcolor"
|
||||
:disable="disable"
|
||||
:error="!!endError"
|
||||
:error-message="endError"
|
||||
:input-class="'calendar_comp ' + data_class"
|
||||
class="q-mt-sm"
|
||||
>
|
||||
<template #control>
|
||||
<div class="self-center full-width no-outline cdt-display" tabindex="0">
|
||||
{{ endVal ? getstrDate(endVal) : nullText }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #append>
|
||||
<!-- Attiva/Disattiva FINE -->
|
||||
<q-btn
|
||||
v-if="canEdit && !endVal && nullableEnd"
|
||||
dense flat icon="add"
|
||||
:label="enableEndText || 'Attiva'"
|
||||
@click="enableEnd"
|
||||
class="q-mr-xs"
|
||||
/>
|
||||
<q-btn
|
||||
v-if="canEdit && endVal && nullableEnd"
|
||||
dense flat :icon="clearIcon"
|
||||
:title="$t('common.clear') || 'Disattiva'"
|
||||
@click="clearEnd"
|
||||
class="q-mr-xs"
|
||||
/>
|
||||
<!-- Apri Date FINE -->
|
||||
<q-btn
|
||||
v-if="canEdit"
|
||||
dense color="primary"
|
||||
:icon="calendarIcon"
|
||||
class="cursor-pointer"
|
||||
@click="openEndDate"
|
||||
:disable="!canEditEnd"
|
||||
/>
|
||||
<!-- Apri Time FINE -->
|
||||
<q-btn
|
||||
v-if="canEdit"
|
||||
dense color="primary"
|
||||
:icon="clockIcon"
|
||||
class="cursor-pointer"
|
||||
@click="openEndTime"
|
||||
:disable="!canEditEnd"
|
||||
/>
|
||||
</template>
|
||||
</q-field>
|
||||
|
||||
<!-- ===== DESKTOP: Dialog centrati ===== -->
|
||||
<!-- START DATE (desktop) -->
|
||||
<q-dialog v-model="startDateDesktopDialog" transition-show="fade" transition-hide="fade">
|
||||
<q-card class="picker-modal-desktop">
|
||||
<q-toolbar class="picker-toolbar">
|
||||
<div class="text-subtitle2">{{ startLabel }}</div>
|
||||
<q-space />
|
||||
<q-btn v-if="nullableStart && startVal" flat dense :icon="clearIcon" :label="$t('common.clear') || 'Disattiva'"
|
||||
color="negative" @click="clearStart" />
|
||||
</q-toolbar>
|
||||
<div class="picker-body">
|
||||
<q-date v-model="startVal" mask="YYYY-MM-DD HH:mm" color="purple" class="fit" @update:model-value="onStartChange" />
|
||||
</div>
|
||||
<div class="picker-actions q-pa-sm">
|
||||
<q-btn flat :label="$t('dialog.cancel')" @click="cancelStart" />
|
||||
<q-btn :label="confirmLabelStartDate" color="primary" @click="saveStart" />
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<!-- START TIME (desktop) -->
|
||||
<q-dialog v-model="startTimeDesktopDialog" transition-show="fade" transition-hide="fade">
|
||||
<q-card class="picker-modal-desktop">
|
||||
<q-toolbar class="picker-toolbar">
|
||||
<div class="text-subtitle2">{{ startLabel }}</div>
|
||||
<q-space />
|
||||
<q-btn v-if="nullableStart && startVal" flat dense :icon="clearIcon" :label="$t('common.clear') || 'Disattiva'"
|
||||
color="negative" @click="clearStart" />
|
||||
</q-toolbar>
|
||||
<div class="picker-body">
|
||||
<q-time v-model="startVal" mask="YYYY-MM-DD HH:mm" color="purple" class="fit" @update:model-value="onStartChange" />
|
||||
</div>
|
||||
<div class="picker-actions q-pa-sm">
|
||||
<q-btn flat :label="$t('dialog.cancel')" @click="cancelStart" />
|
||||
<q-btn :label="confirmLabelStartTime" color="primary" @click="saveStart" />
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<!-- END DATE (desktop) -->
|
||||
<q-dialog v-model="endDateDesktopDialog" transition-show="fade" transition-hide="fade">
|
||||
<q-card class="picker-modal-desktop">
|
||||
<q-toolbar class="picker-toolbar">
|
||||
<div class="text-subtitle2">{{ endLabel }}</div>
|
||||
<q-space />
|
||||
<q-btn v-if="nullableEnd && endVal" flat dense :icon="clearIcon" :label="$t('common.clear') || 'Disattiva'"
|
||||
color="negative" @click="clearEnd" />
|
||||
</q-toolbar>
|
||||
<div class="picker-body">
|
||||
<q-date v-model="endVal" mask="YYYY-MM-DD HH:mm" color="purple" class="fit" @update:model-value="onEndChange" />
|
||||
</div>
|
||||
<div class="picker-actions q-pa-sm">
|
||||
<q-btn flat :label="$t('dialog.cancel')" @click="cancelEnd" />
|
||||
<q-btn :label="confirmLabelEndDate" color="primary" @click="saveEnd" :disable="!!endError" />
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<!-- END TIME (desktop) -->
|
||||
<q-dialog v-model="endTimeDesktopDialog" transition-show="fade" transition-hide="fade">
|
||||
<q-card class="picker-modal-desktop">
|
||||
<q-toolbar class="picker-toolbar">
|
||||
<div class="text-subtitle2">{{ endLabel }}</div>
|
||||
<q-space />
|
||||
<q-btn v-if="nullableEnd && endVal" flat dense :icon="clearIcon" :label="$t('common.clear') || 'Disattiva'"
|
||||
color="negative" @click="clearEnd" />
|
||||
</q-toolbar>
|
||||
<div class="picker-body">
|
||||
<q-time v-model="endVal" mask="YYYY-MM-DD HH:mm" color="purple" class="fit" @update:model-value="onEndChange" />
|
||||
</div>
|
||||
<div class="picker-actions q-pa-sm">
|
||||
<q-btn flat :label="$t('dialog.cancel')" @click="cancelEnd" />
|
||||
<q-btn :label="confirmLabelEndTime" color="primary" @click="saveEnd" :disable="!!endError" />
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<!-- ===== MOBILE: Full-screen ===== -->
|
||||
<!-- START DATE -->
|
||||
<q-dialog v-model="startDateDialog" maximized transition-show="slide-up" transition-hide="slide-down">
|
||||
<q-card class="picker-sheet">
|
||||
<q-toolbar class="picker-toolbar">
|
||||
<q-btn flat round dense icon="arrow_back" @click="cancelStart" />
|
||||
<div class="text-subtitle1 q-ml-sm">{{ startLabel }}</div>
|
||||
<q-space />
|
||||
<q-btn v-if="nullableStart && startVal" flat dense :icon="clearIcon" :label="$t('common.clear') || 'Disattiva'"
|
||||
color="negative" @click="clearStart" />
|
||||
</q-toolbar>
|
||||
<div class="picker-body">
|
||||
<q-date v-model="startVal" mask="YYYY-MM-DD HH:mm" color="purple" class="fit" @update:model-value="onStartChange" />
|
||||
</div>
|
||||
<div class="picker-actions q-pa-sm">
|
||||
<q-btn flat :label="$t('dialog.cancel')" @click="cancelStart" />
|
||||
<q-btn :label="confirmLabelStartDate" color="primary" @click="saveStart" />
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<!-- START TIME -->
|
||||
<q-dialog v-model="startTimeDialog" maximized transition-show="slide-up" transition-hide="slide-down">
|
||||
<q-card class="picker-sheet">
|
||||
<q-toolbar class="picker-toolbar">
|
||||
<q-btn flat round dense icon="arrow_back" @click="cancelStart" />
|
||||
<div class="text-subtitle1 q-ml-sm">{{ startLabel }}</div>
|
||||
<q-space />
|
||||
<q-btn v-if="nullableStart && startVal" flat dense :icon="clearIcon" :label="$t('common.clear') || 'Disattiva'"
|
||||
color="negative" @click="clearStart" />
|
||||
</q-toolbar>
|
||||
<div class="picker-body">
|
||||
<q-time v-model="startVal" mask="YYYY-MM-DD HH:mm" color="purple" class="fit" @update:model-value="onStartChange" />
|
||||
</div>
|
||||
<div class="picker-actions q-pa-sm">
|
||||
<q-btn flat :label="$t('dialog.cancel')" @click="cancelStart" />
|
||||
<q-btn :label="confirmLabelStartTime" color="primary" @click="saveStart" />
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<!-- END DATE -->
|
||||
<q-dialog v-model="endDateDialog" maximized transition-show="slide-up" transition-hide="slide-down">
|
||||
<q-card class="picker-sheet">
|
||||
<q-toolbar class="picker-toolbar">
|
||||
<q-btn flat round dense icon="arrow_back" @click="cancelEnd" />
|
||||
<div class="text-subtitle1 q-ml-sm">{{ endLabel }}</div>
|
||||
<q-space />
|
||||
<q-btn v-if="nullableEnd && endVal" flat dense :icon="clearIcon" :label="$t('common.clear') || 'Disattiva'"
|
||||
color="negative" @click="clearEnd" />
|
||||
</q-toolbar>
|
||||
<div class="picker-body">
|
||||
<q-date v-model="endVal" mask="YYYY-MM-DD HH:mm" color="purple" class="fit" @update:model-value="onEndChange" />
|
||||
</div>
|
||||
<div class="picker-actions q-pa-sm">
|
||||
<q-btn flat :label="$t('dialog.cancel')" @click="cancelEnd" />
|
||||
<q-btn :label="confirmLabelEndDate" color="primary" @click="saveEnd" :disable="!!endError" />
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<!-- END TIME -->
|
||||
<q-dialog v-model="endTimeDialog" maximized transition-show="slide-up" transition-hide="slide-down">
|
||||
<q-card class="picker-sheet">
|
||||
<q-toolbar class="picker-toolbar">
|
||||
<q-btn flat round dense icon="arrow_back" @click="cancelEnd" />
|
||||
<div class="text-subtitle1 q-ml-sm">{{ endLabel }}</div>
|
||||
<q-space />
|
||||
<q-btn v-if="nullableEnd && endVal" flat dense :icon="clearIcon" :label="$t('common.clear') || 'Disattiva'"
|
||||
color="negative" @click="clearEnd" />
|
||||
</q-toolbar>
|
||||
<div class="picker-body">
|
||||
<q-time v-model="endVal" mask="YYYY-MM-DD HH:mm" color="purple" class="fit" @update:model-value="onEndChange" />
|
||||
</div>
|
||||
<div class="picker-actions q-pa-sm">
|
||||
<q-btn flat :label="$t('dialog.cancel')" @click="cancelEnd" />
|
||||
<q-btn :label="confirmLabelEndTime" color="primary" @click="saveEnd" :disable="!!endError" />
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" src="./CDateTimeStartEnd.ts"></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './CDateTimeStartEnd.scss';
|
||||
</style>
|
||||
1
src/components/CDateTimeStartEnd/index.ts
Executable file
1
src/components/CDateTimeStartEnd/index.ts
Executable file
@@ -0,0 +1 @@
|
||||
export {default as CDateTimeStartEnd} from './CDateTimeStartEnd.vue'
|
||||
@@ -1876,14 +1876,19 @@ export default defineComponent({
|
||||
newRecord.value = {};
|
||||
}
|
||||
|
||||
function SaveValue(newVal: any, valinitial: any) {
|
||||
function SaveValue(newVal: any, valinitial: any, which?: string) {
|
||||
// console.log('SaveValue', newVal)
|
||||
// console.log('rowsel', rowsel, 'colsel', colsel.value)
|
||||
let myfield = '';
|
||||
let subf = '';
|
||||
if (colsel.value) {
|
||||
myfield = colsel.value.field!;
|
||||
subf = colsel.value.subfield!;
|
||||
if (which === 'end') {
|
||||
myfield = colsel.value.field2!;
|
||||
subf = colsel.value.subfield2!;
|
||||
} else {
|
||||
myfield = colsel.value.field!;
|
||||
subf = colsel.value.subfield!;
|
||||
}
|
||||
}
|
||||
|
||||
let myrec = rowsel.value;
|
||||
@@ -2159,8 +2164,8 @@ export default defineComponent({
|
||||
};
|
||||
|
||||
if (col.action === lists.MenuAction.CAN_EDIT_TABLE) {
|
||||
canEditPrec.value = canEdit.value
|
||||
canEdit.value = true
|
||||
canEditPrec.value = canEdit.value;
|
||||
canEdit.value = true;
|
||||
// console.log('Edit', item);
|
||||
selItem(item, col);
|
||||
recModif.value = { ...item };
|
||||
@@ -2713,8 +2718,8 @@ export default defineComponent({
|
||||
|
||||
const check = tools.checkIfShowField(col, tipovis, visulabel, value);
|
||||
let valuePresent =
|
||||
colVisib.value.includes(col.field! + (col.subfield ? ('.' + col.subfield) : '')) ||
|
||||
colVisib.value.includes(col.field + (col.subfield ? ('.' + col.subfield) : ''))
|
||||
colVisib.value.includes(col.field! + (col.subfield ? '.' + col.subfield : '')) ||
|
||||
colVisib.value.includes(col.field + (col.subfield ? '.' + col.subfield : ''));
|
||||
|
||||
if (valuePresent && col.visibleif! > 0 && record) {
|
||||
if (col.visib_field) {
|
||||
@@ -2944,7 +2949,7 @@ export default defineComponent({
|
||||
|
||||
function hidewindowEdit() {
|
||||
annulla(0);
|
||||
canEdit.value = canEditPrec.value
|
||||
canEdit.value = canEditPrec.value;
|
||||
}
|
||||
|
||||
function clickMarker(id: any) {
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
:disable="disabilita()"
|
||||
:val="lists.MenuAction.CAN_EDIT_TABLE"
|
||||
icon="fas fa-pencil-alt"
|
||||
:label="canEdit ? t('grid.edit_table') : t('grid.disable_edit_table')"
|
||||
:label="canEdit ? t('grid.edit_table') : ''"
|
||||
@update:model-value="canEdit = !canEdit"
|
||||
@click="canEdit = !canEdit"
|
||||
>
|
||||
@@ -1142,6 +1142,8 @@
|
||||
v-model:row="props.row"
|
||||
:field="col.field"
|
||||
:subfield="col.subfield"
|
||||
:field2="col.field2"
|
||||
:subfield2="col.subfield2"
|
||||
minuteinterval="1"
|
||||
@save="SaveValue"
|
||||
@show="selItem(props.row, col)"
|
||||
@@ -1278,6 +1280,8 @@
|
||||
v-model:row="props.row"
|
||||
:field="col.field"
|
||||
:subfield="col.subfield"
|
||||
:field2="col.field2"
|
||||
:subfield2="col.subfield2"
|
||||
minuteinterval="1"
|
||||
@save="SaveValue"
|
||||
@show="selItem(props.row, col)"
|
||||
@@ -1484,6 +1488,8 @@
|
||||
:tablesel="mycol.tablesel"
|
||||
:field="mycol.field"
|
||||
:subfield="mycol.subfield"
|
||||
:field2="mycol.field2"
|
||||
:subfield2="mycol.subfield2"
|
||||
@save="SaveValdb"
|
||||
@show="selItem(rowclicksel, mycol)"
|
||||
@showandsave="showandsave"
|
||||
@@ -1552,6 +1558,7 @@
|
||||
"
|
||||
>
|
||||
<div class="">
|
||||
MODIF_B: {{col.field2}}
|
||||
<CMyPopupEdit
|
||||
:table="mytable"
|
||||
:canEdit="true"
|
||||
@@ -1560,6 +1567,8 @@
|
||||
v-model:row="newRecord"
|
||||
:field="col.field"
|
||||
:subfield="col.subfield"
|
||||
:field2="col.field2"
|
||||
:subfield2="col.subfield2"
|
||||
:tablesel="col.tablesel"
|
||||
:value_extra="getValueExtra(col, newRecord)"
|
||||
:isInModif="true"
|
||||
@@ -1642,6 +1651,7 @@
|
||||
class="tdclass"
|
||||
>
|
||||
<div>
|
||||
MODIF_C: {{col.field2}}
|
||||
<CMyPopupEdit
|
||||
:table="mytable"
|
||||
:canEdit="true"
|
||||
@@ -1652,6 +1662,8 @@
|
||||
v-model:row="recModif"
|
||||
:field="col.field"
|
||||
:subfield="col.subfield"
|
||||
:field2="col.field2"
|
||||
:subfield2="col.subfield2"
|
||||
:dense="false"
|
||||
:value_extra="getValueExtra(col, recModif)"
|
||||
minuteinterval="1"
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
filled
|
||||
:label="label || undefined"
|
||||
type="number"
|
||||
inputmode="decimal"
|
||||
:dense="dense"
|
||||
@focus="onFocus"
|
||||
@update:model-value="onInputChange"
|
||||
@keydown="onKeyDown"
|
||||
@wheel.prevent
|
||||
/>
|
||||
|
||||
<!-- Mostra i bottoni solo se l'utente ha modificato il valore -->
|
||||
|
||||
@@ -16,6 +16,7 @@ import type { IColGridTable, IImgGallery, ISpecialField } from 'model';
|
||||
import { CMyChipList } from '../CMyChipList';
|
||||
import { CDate } from '../CDate';
|
||||
import { CDateTime } from '../CDateTime';
|
||||
import { CDateTimeStartEnd } from '../CDateTimeStartEnd';
|
||||
import { CLabel } from '../CLabel';
|
||||
import { CMyToggleList } from '../CMyToggleList';
|
||||
import { CMySelect } from '../CMySelect';
|
||||
@@ -110,11 +111,21 @@ export default defineComponent({
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
field2: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
subfield: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
subfield2: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
mysubsubkey: {
|
||||
type: String,
|
||||
required: false,
|
||||
@@ -229,6 +240,7 @@ export default defineComponent({
|
||||
components: {
|
||||
CMyChipList,
|
||||
CDateTime,
|
||||
CDateTimeStartEnd,
|
||||
CDate,
|
||||
CMyToggleList,
|
||||
CMySelect,
|
||||
@@ -250,6 +262,7 @@ export default defineComponent({
|
||||
const globalStore = useGlobalStore();
|
||||
|
||||
const myvalue = ref(null as any);
|
||||
const myvalue2 = ref(null as any);
|
||||
const myvalueprec = ref('false');
|
||||
const countryname = ref('');
|
||||
const visueditor = ref(false);
|
||||
@@ -391,6 +404,18 @@ export default defineComponent({
|
||||
props.mysubsubkey,
|
||||
props.specialField
|
||||
);
|
||||
myvalue2.value = getValDb(
|
||||
props.field2,
|
||||
props.serv,
|
||||
'',
|
||||
props.table,
|
||||
props.subfield2,
|
||||
props.id,
|
||||
props.idmain,
|
||||
props.indrec,
|
||||
'',
|
||||
props.specialField
|
||||
);
|
||||
} else {
|
||||
if (props.mycol && props.mycol.name) col.value = { ...props.mycol };
|
||||
}
|
||||
@@ -591,11 +616,14 @@ export default defineComponent({
|
||||
miorecord = myrow.value.arrvariazioni[0];
|
||||
}
|
||||
|
||||
if (props.field !== '') myvalue.value = miorecord[props.field];
|
||||
else {
|
||||
// @ts-ignore
|
||||
if (props.field !== '') {
|
||||
myvalue.value = miorecord[props.field];
|
||||
} else {
|
||||
myvalue.value = myrow.value;
|
||||
}
|
||||
if (props.field2 !== '') {
|
||||
myvalue2.value = miorecord[props.field2];
|
||||
}
|
||||
}
|
||||
// console.log('props.field', props.field, 'props.subfield', props.subfield, 'myvalue: ', myvalue)
|
||||
}
|
||||
@@ -700,6 +728,19 @@ export default defineComponent({
|
||||
async function SaveValueInt(newVal: any, valinitial: any) {
|
||||
console.log('SaveValueInt', newVal, valinitial);
|
||||
|
||||
let copynewval = { ...newVal };
|
||||
|
||||
let isEnd = false;
|
||||
|
||||
if (copynewval.which === 'start' || copynewval.which === 'end') {
|
||||
newVal = copynewval.current;
|
||||
valinitial = copynewval.prev;
|
||||
if (copynewval.which === 'end') {
|
||||
isEnd = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (col.value.fieldtype === costanti.FieldType.verifica) {
|
||||
newVal.username = userStore.my.username;
|
||||
newVal.data = tools.getDateNow();
|
||||
@@ -724,14 +765,25 @@ export default defineComponent({
|
||||
console.log('newVal', newVal);
|
||||
|
||||
if (isFieldDb()) {
|
||||
await savefield(newVal, valinitial, $q);
|
||||
} else {
|
||||
// Update value in table memory
|
||||
if (props.subfield !== '') {
|
||||
if (myrow.value[props.field] === undefined) myrow.value[props.field] = {};
|
||||
myrow.value[props.field][props.subfield] = newVal;
|
||||
if (isEnd) {
|
||||
await savefield2(newVal, valinitial, $q);
|
||||
} else {
|
||||
if (props.field !== '') myrow.value[props.field] = newVal;
|
||||
await savefield(newVal, valinitial, $q);
|
||||
}
|
||||
} else {
|
||||
let subfield = props.subfield;
|
||||
let field = props.field;
|
||||
if (isEnd) {
|
||||
subfield = props.subfield2;
|
||||
field = props.field2;
|
||||
}
|
||||
|
||||
// Update value in table memory
|
||||
if (subfield !== '') {
|
||||
if (myrow.value[field] === undefined) myrow.value[field] = {};
|
||||
myrow.value[field][subfield] = newVal;
|
||||
} else {
|
||||
if (field !== '') myrow.value[field] = newVal;
|
||||
else {
|
||||
if (!props.isrec) {
|
||||
// @ts-ignore
|
||||
@@ -743,11 +795,12 @@ export default defineComponent({
|
||||
|
||||
console.log('SaveValueInt', newVal, valinitial);
|
||||
|
||||
emit('save', newVal, valinitial);
|
||||
emit('save', newVal, valinitial, copynewval.which!);
|
||||
}
|
||||
|
||||
async function savefield(value: any, initialval: any, myq: any) {
|
||||
if (!props.insertMode) {
|
||||
let ret = null;
|
||||
myvalue.value = value;
|
||||
return tools.saveInDBForTypes(
|
||||
myq,
|
||||
@@ -764,6 +817,25 @@ export default defineComponent({
|
||||
);
|
||||
}
|
||||
}
|
||||
async function savefield2(value: any, initialval: any, myq: any) {
|
||||
if (!props.insertMode) {
|
||||
let ret = null;
|
||||
myvalue2.value = value;
|
||||
return tools.saveInDBForTypes(
|
||||
myq,
|
||||
props.field2,
|
||||
myvalue2.value,
|
||||
props.type,
|
||||
props.serv,
|
||||
props.table,
|
||||
props.subfield2,
|
||||
props.id,
|
||||
props.indrec,
|
||||
props.mysubsubkey,
|
||||
props.specialField
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function annulla(val: any) {
|
||||
emit('annulla', true);
|
||||
@@ -1082,6 +1154,7 @@ export default defineComponent({
|
||||
|
||||
return {
|
||||
myvalue,
|
||||
myvalue2,
|
||||
countryname,
|
||||
visueditor,
|
||||
visuhtml,
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
<div v-if="isInModif">
|
||||
<q-toggle
|
||||
:disable="!isInModif || col.disable"
|
||||
dark
|
||||
color="green"
|
||||
v-model="myvalue"
|
||||
:label="title ? title : col.label"
|
||||
@@ -31,8 +30,6 @@
|
||||
</div>
|
||||
<div v-else>
|
||||
<q-toggle
|
||||
dark
|
||||
color="green"
|
||||
v-model="myvalue"
|
||||
:label="title"
|
||||
:disable="
|
||||
@@ -40,7 +37,12 @@
|
||||
(!isInModif && !canModify && !canEdit)
|
||||
"
|
||||
@update:model-value="Savedb"
|
||||
></q-toggle>
|
||||
color="green"
|
||||
checked-icon="check"
|
||||
unchecked-icon="close"
|
||||
keep-color
|
||||
class="toggle-enhanced"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="col.fieldtype === costanti.FieldType.link">
|
||||
@@ -995,6 +997,51 @@
|
||||
<div v-else-if="canEdit">
|
||||
<q-btn
|
||||
:dense="dense"
|
||||
:label="
|
||||
col.label
|
||||
? addstrrequired + col.label
|
||||
: col.label_trans
|
||||
? addstrrequired + t(col.label_trans)
|
||||
: undefined
|
||||
"
|
||||
color="primary"
|
||||
@click="OpenEditDateToday"
|
||||
icon="fas fa-calendar-day"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="col.fieldtype === costanti.FieldType.date2startend">
|
||||
<div v-if="myvalue">
|
||||
<CDateTimeStartEnd
|
||||
:label="
|
||||
col.label
|
||||
? addstrrequired + col.label
|
||||
: col.label_trans
|
||||
? addstrrequired + t(col.label_trans)
|
||||
: undefined
|
||||
"
|
||||
:class="{ 'cursor-pointer': canEdit }"
|
||||
v-model:startValue="myvalue"
|
||||
v-model:endValue="myvalue2"
|
||||
:readonly="false"
|
||||
:dense="dense"
|
||||
:canEdit="canEdit"
|
||||
@savetoclose="SaveValueInt"
|
||||
@show="OpenEdit"
|
||||
:nullable-end="true"
|
||||
>
|
||||
</CDateTimeStartEnd>
|
||||
</div>
|
||||
<div v-else-if="canEdit">
|
||||
<q-btn
|
||||
:dense="dense"
|
||||
:label="
|
||||
col.label
|
||||
? addstrrequired + col.label
|
||||
: col.label_trans
|
||||
? addstrrequired + t(col.label_trans)
|
||||
: undefined
|
||||
"
|
||||
color="primary"
|
||||
@click="OpenEditDateToday"
|
||||
icon="fas fa-calendar-day"
|
||||
@@ -1068,7 +1115,6 @@
|
||||
</div>
|
||||
<!-- Show Value -->
|
||||
<div v-else-if="col.fieldtype === costanti.FieldType.multiselect">
|
||||
|
||||
<div v-if="isInModif">
|
||||
<CMySelect
|
||||
:type_out="col.field_outtype"
|
||||
|
||||
Reference in New Issue
Block a user