Files
jandl-taskmanager-app/app/src/plugins/tm@modal/team/z-team-modal.vue
T

218 lines
5.8 KiB
Vue

<template>
<v-dialog
v-model="visible"
:width="modalWidth"
:height="modalHeight"
persistent
:retain-focus="false"
>
<W-loadable :content="team" class="h-100">
<v-card
height="100%"
class="d-flex flex-column"
style="position: relative"
>
<div class="d-flex justify-space-between align-center modal-header">
<h1>{{ team.id ? 'Upraviť tím' : 'Vytvoriť tím' }}</h1>
<div class="d-flex align-center">
<a-reset-size-button @reset="resetModalSize" />
<a-close-button @close="closeModal()" />
</div>
</div>
<v-card-actions class="d-flex flex-column modal-content">
<v-text-field
v-model="team.name"
class="modal-input"
label="Názov tímu"
variant="solo"
:class="{ error: v$.team.name.$errors.length }"
:hint="
v$.team.name.$errors
? errorUtils.parseErrors(v$.team.name.$errors)
: null
"
></v-text-field>
<div
v-for="(employee, index) in team.employees"
:key="employee.id"
class="relative w-100"
>
<v-text-field
v-model="team.employees[index]._fullName"
class="modal-input"
disabled
label="Zamestanec"
variant="solo"
>
</v-text-field>
<v-icon
class="remove-input"
icon="mdi-close"
size="small"
@click.stop="team.employees.splice(index, 1)"
></v-icon>
</div>
<v-autocomplete
ref="autocomplete"
v-model="employeeSelect"
:custom-filter="customFilter"
:match-any="true"
label="Priradený"
:class="{ error: v$.team.employees.$errors.length }"
:items="employeesOptions"
item-title="_fullName"
item-value="id"
variant="solo"
class="modal-input"
clearable
/>
</v-card-actions>
<v-btn class="button primary block" @click="save()">{{
team.id ? 'UPRAVIŤ' : 'VYTVORIŤ'
}}</v-btn>
<a-resize-handle
:current-width="modalWidthPx"
:current-height="modalHeightPx"
@resize="handleModalResize"
@resize-end="handleResizeEnd"
/>
</v-card>
</W-loadable>
</v-dialog>
</template>
<script>
import useVuelidate from '@vuelidate/core';
import { required } from '@vuelidate/validators';
import errorUtils from '@/plugins/lib@auth/_utils/error.utils';
import tmUtils from '@/plugins/tm@_utils/tm.utils';
import { mapGetters } from 'vuex';
import AutocompleteMixin from '@/plugins/tm@_mixins/autocomplete.mixin';
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';
const atLeastOne = (value) => value.length;
export default {
components: {
AResizeHandle,
AResetSizeButton,
ACloseButton,
},
mixins: [AutocompleteMixin, modalMixin],
emits: ['close', 'update'],
data() {
return {
visible: false,
v$: useVuelidate(),
errorUtils,
employeeSelect: null,
team: null,
modalName: 'z-team-modal',
};
},
computed: {
...mapGetters('tm', ['enrichedEmployees']),
employeesOptions() {
const selectedEmployeesIds = this.team.employees.map(
(employee) => employee.id,
);
return this.enrichedEmployees.filter(
(employee) => !selectedEmployeesIds.includes(employee.id),
);
},
},
validations() {
return {
team: {
name: { required },
employees: { atLeastOne },
},
};
},
watch: {
employeeSelect(employeeId) {
if (!employeeId) return;
const employee = this.enrichedEmployees.find(
(employee) => employee.id == employeeId,
);
this.team.employees.push(employee);
this.employeeSelect = null;
this.$refs.autocomplete.search = '';
},
},
methods: {
async showModal({ team = null }) {
this.visible = true;
this.team = null;
this.$nextTick(() => this.v$.$reset());
try {
if (team?.id) {
const t = await this.$axios.get_auth_data(`v1/teams/${team.id}`);
this.team = this._enrichTeam(t);
} else {
this.team = { employees: [] };
}
} catch (error) {
this.$toast.error(this.$parseError(error));
}
},
closeModal() {
this.visible = false;
this.$emit('close', this.team);
},
async save() {
if (!(await this.v$.$validate())) return;
try {
if (this.team.id) {
const { team } = await this.$axios.put_auth(
`v1/teams/${this.team.id}`,
this.team,
);
const fullTeamResource = await this.$axios.get_auth_data(
`v1/teams/${team.id}`,
);
this.$store.commit('tm/update_team', fullTeamResource);
} else {
const { team } = await this.$axios.post_auth(`v1/teams`, this.team);
const fullTeamResource = await this.$axios.get_auth_data(
`v1/teams/${team.id}`,
);
this.$store.commit('tm/save_team', fullTeamResource);
}
this.closeModal();
} catch (error) {
this.$toast.error(this.$parseError(error));
}
},
_enrichTeam(team) {
team.employees = tmUtils.enrichEmployees(team.employees);
return team;
},
},
};
</script>