mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-21 14:29:34 +00:00
feat(modals): replace datepicker and time fields with employee timeblock component for improved time management
This commit is contained in:
1 parent
fdb4452447
commit
1ce56c544c
2 files changed
+111
-81
No files matched your search
@@ -46,49 +46,14 @@
|
||||
variant="solo"
|
||||
class="modal-input"
|
||||
/>
|
||||
<!-- <Z-autocomplete label="Vyhľadať zamestnanca" :value="blocker?.employee ? `${blocker?.employee?.name} ${blocker?.employee?.surname}` : ''" :options="enrichedEmployees.map(employee => ({key: employee.id, value: employee._fullName}))" :clear-on-submit="false" :class="{ error: v$.blocker.employee.$errors.length }" class="modal-input" @option-selected="onEmployeeSelected" /> -->
|
||||
<Z-datepicker
|
||||
v-model="datepicker"
|
||||
class="modal-input mb-5"
|
||||
:auto-apply="true"
|
||||
format="dd.MM.yyyy"
|
||||
locale="sk"
|
||||
:class="{ error: v$.datepicker.$errors?.length }"
|
||||
:validations="v$.datepicker"
|
||||
select-text="Vybrať"
|
||||
cancel-text="Zrušiť"
|
||||
placeholder="Dátum"
|
||||
label="Dátum"
|
||||
:enable-time-picker="false"
|
||||
/>
|
||||
|
||||
<v-text-field
|
||||
v-model="starts_at_time"
|
||||
type="time"
|
||||
variant="solo"
|
||||
bg-color="white"
|
||||
:hint="
|
||||
v$.starts_at_time.$errors
|
||||
? errorUtils.parseErrors(v$.starts_at_time.$errors)
|
||||
: null
|
||||
"
|
||||
:class="{ error: v$.starts_at_time.$errors.length }"
|
||||
class="mb-1 modal-input"
|
||||
label="Začiatok"
|
||||
/>
|
||||
<v-text-field
|
||||
v-model="ends_at_time"
|
||||
type="time"
|
||||
variant="solo"
|
||||
bg-color="white"
|
||||
:hint="
|
||||
v$.ends_at_time.$errors
|
||||
? errorUtils.parseErrors(v$.ends_at_time.$errors)
|
||||
: null
|
||||
"
|
||||
:class="{ error: v$.ends_at_time.$errors.length }"
|
||||
class="modal-input"
|
||||
label="Koniec"
|
||||
|
||||
<!-- Timeblock Component -->
|
||||
<a-employee-timeblock
|
||||
ref="employeeTimeblockRef"
|
||||
v-model="timeblockData"
|
||||
:employee="selectedEmployee"
|
||||
:deletable="false"
|
||||
:index="0"
|
||||
/>
|
||||
</v-card-actions>
|
||||
|
||||
@@ -107,7 +72,6 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ZDatepicker from '@/plugins/tm@_components/z-datepicker.vue';
|
||||
import useVuelidate from '@vuelidate/core';
|
||||
import { required } from '@vuelidate/validators';
|
||||
import errorUtils from '@/plugins/lib@auth/_utils/error.utils';
|
||||
@@ -118,14 +82,14 @@ import modalMixin from '@/plugins/tm@modal/_mixins/modal.mixin';
|
||||
import AResizeHandle from '@/plugins/tm@modal/_components/a-resize-handle.vue';
|
||||
import AResetSizeButton from '@/plugins/tm@modal/_components/a-reset-size-button.vue';
|
||||
import ACloseButton from '@/plugins/tm@modal/_components/a-close-button.vue';
|
||||
import AEmployeeTimeblock from '@/plugins/tm@modal/task/_components/employees/a-employee-timeblock.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ZDatepicker,
|
||||
// ZAutocomplete
|
||||
AResizeHandle,
|
||||
AResetSizeButton,
|
||||
ACloseButton,
|
||||
AEmployeeTimeblock,
|
||||
},
|
||||
mixins: [AutocompleteMixin, modalMixin],
|
||||
|
||||
@@ -137,9 +101,13 @@ export default {
|
||||
v$: useVuelidate(),
|
||||
errorUtils,
|
||||
blocker: null,
|
||||
datepicker: null,
|
||||
starts_at_time: null,
|
||||
ends_at_time: null,
|
||||
timeblockData: {
|
||||
id: null,
|
||||
date: new Date(),
|
||||
starts_at_time: null,
|
||||
ends_at_time: null,
|
||||
employee_id: null,
|
||||
},
|
||||
employee: null,
|
||||
modalName: 'z-blocker-modal',
|
||||
modalSize: 'large',
|
||||
@@ -150,6 +118,13 @@ export default {
|
||||
...mapGetters('tm', ['enrichedEmployees']),
|
||||
|
||||
...mapGetters('auth', ['user']),
|
||||
|
||||
selectedEmployee() {
|
||||
if (!this.blocker?.employee_id) return null;
|
||||
return this.enrichedEmployees.find(
|
||||
(emp) => emp.id === this.blocker.employee_id,
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
validations() {
|
||||
@@ -158,25 +133,27 @@ export default {
|
||||
name: { required },
|
||||
start: { required },
|
||||
end: { required },
|
||||
// employee: { required }
|
||||
},
|
||||
|
||||
starts_at_time: { required },
|
||||
ends_at_time: { required },
|
||||
datepicker: { required },
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
ends_at_time() {
|
||||
'blocker.employee_id'(newEmployeeId) {
|
||||
// Update timeblock employee_id when blocker employee changes
|
||||
if (this.timeblockData) {
|
||||
this.timeblockData.employee_id = newEmployeeId;
|
||||
}
|
||||
},
|
||||
|
||||
'timeblockData.date'() {
|
||||
this._syncDatesTimes();
|
||||
},
|
||||
|
||||
starts_at_time() {
|
||||
'timeblockData.starts_at_time'() {
|
||||
this._syncDatesTimes();
|
||||
},
|
||||
|
||||
datepicker() {
|
||||
'timeblockData.ends_at_time'() {
|
||||
this._syncDatesTimes();
|
||||
},
|
||||
},
|
||||
@@ -185,9 +162,13 @@ export default {
|
||||
async showModal({ blocker }) {
|
||||
this.visible = true;
|
||||
this.blocker = null;
|
||||
this.datepicker = null;
|
||||
this.starts_at_time = null;
|
||||
this.ends_at_time = null;
|
||||
this.timeblockData = {
|
||||
id: null,
|
||||
date: new Date(),
|
||||
starts_at_time: null,
|
||||
ends_at_time: null,
|
||||
employee_id: null,
|
||||
};
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.v$.$reset();
|
||||
@@ -199,11 +180,18 @@ export default {
|
||||
`v1/blockers/${blocker.id}`,
|
||||
);
|
||||
|
||||
this.starts_at_time = moment(blocker.start).format('HH:mm');
|
||||
this.ends_at_time = moment(blocker.end).format('HH:mm');
|
||||
this.datepicker = new Date(blocker.start);
|
||||
const startMoment = moment(blocker.start);
|
||||
const endMoment = moment(blocker.end);
|
||||
|
||||
this.timeblockData = {
|
||||
id: null,
|
||||
date: startMoment.toDate(),
|
||||
starts_at_time: startMoment.format('HH:mm'),
|
||||
ends_at_time: endMoment.format('HH:mm'),
|
||||
employee_id: blocker.employee.id,
|
||||
};
|
||||
|
||||
blocker.employee_id = blocker.employee.id;
|
||||
//fixnut validacie employee_id
|
||||
this.blocker = blocker;
|
||||
} else {
|
||||
this.blocker = { start: null, employee_id: this.user.id };
|
||||
@@ -213,9 +201,16 @@ export default {
|
||||
blocker.datepicker &&
|
||||
blocker.employee_id
|
||||
) {
|
||||
this.datepicker = blocker.datepicker;
|
||||
this.starts_at_time = blocker.starts_at_time;
|
||||
this.timeblockData = {
|
||||
id: null,
|
||||
date: blocker.datepicker,
|
||||
starts_at_time: blocker.starts_at_time,
|
||||
ends_at_time: blocker.ends_at_time,
|
||||
employee_id: blocker.employee_id,
|
||||
};
|
||||
this.blocker.employee_id = blocker.employee_id;
|
||||
} else {
|
||||
this.timeblockData.employee_id = this.user.id;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -224,11 +219,13 @@ export default {
|
||||
},
|
||||
|
||||
async save() {
|
||||
if (!(await this.v$.$validate())) return;
|
||||
// Validate using the employee timeblock component's validation
|
||||
const isTimeblockValid =
|
||||
await this.$refs.employeeTimeblockRef?.validate();
|
||||
|
||||
if (!isTimeblockValid || !(await this.v$.$validate())) return;
|
||||
|
||||
try {
|
||||
// this.blocker.employee_id = this.blocker.employee?.id
|
||||
|
||||
if (this.blocker.id) {
|
||||
const { blocker } = await this.$axios.put_auth(
|
||||
`v1/blockers/${this.blocker.id}`,
|
||||
@@ -253,29 +250,34 @@ export default {
|
||||
|
||||
closeModal() {
|
||||
this.visible = false;
|
||||
this.timeblockData = {
|
||||
id: null,
|
||||
date: new Date(),
|
||||
starts_at_time: null,
|
||||
ends_at_time: null,
|
||||
employee_id: null,
|
||||
};
|
||||
this.$emit('close', this.blocker);
|
||||
},
|
||||
|
||||
onEmployeeSelected({ key }) {
|
||||
this.blocker.employee = this.enrichedEmployees.find(
|
||||
(employee) => employee.id == key,
|
||||
);
|
||||
},
|
||||
|
||||
_syncDatesTimes() {
|
||||
if (!this.starts_at_time || !this.ends_at_time || !this.datepicker)
|
||||
if (
|
||||
!this.timeblockData.starts_at_time ||
|
||||
!this.timeblockData.ends_at_time ||
|
||||
!this.timeblockData.date
|
||||
)
|
||||
return;
|
||||
|
||||
const splittedStart = this.starts_at_time.split(':');
|
||||
const splittedEnd = this.ends_at_time.split(':');
|
||||
const splittedStart = this.timeblockData.starts_at_time.split(':');
|
||||
const splittedEnd = this.timeblockData.ends_at_time.split(':');
|
||||
|
||||
this.blocker.start = moment(this.datepicker)
|
||||
this.blocker.start = moment(this.timeblockData.date)
|
||||
.set({
|
||||
hours: parseInt(splittedStart[0]),
|
||||
minutes: parseInt(splittedStart[1]),
|
||||
})
|
||||
.format('YYYY-MM-DD HH:mm');
|
||||
this.blocker.end = moment(this.datepicker)
|
||||
this.blocker.end = moment(this.timeblockData.date)
|
||||
.set({
|
||||
hours: parseInt(splittedEnd[0]),
|
||||
minutes: parseInt(splittedEnd[1]),
|
||||
@@ -340,3 +342,13 @@ function oo_cm() {
|
||||
return v;
|
||||
} /*eslint unicorn/no-abusive-eslint-disable:,eslint-comments/disable-enable-pair:,eslint-comments/no-unlimited-disable:,eslint-comments/no-aggregating-enable:,eslint-comments/no-duplicate-disable:,eslint-comments/no-unused-disable:,eslint-comments/no-unused-enable:,*/
|
||||
</script>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
::v-deep
|
||||
// Hide employee select and add/remove buttons in timeblock component
|
||||
.timeblock__header__top
|
||||
display: none
|
||||
|
||||
.actions
|
||||
display: none
|
||||
</style>
|
||||
Reference in new issue
Block a user