refactor(management): replace standard form with carousel to separate info and access into two panels
This commit is contained in:
parent
a1b6748d95
commit
d8a1a87e98
|
|
@ -12,6 +12,29 @@ export default {
|
|||
},
|
||||
},
|
||||
|
||||
employee_management: {
|
||||
module_access: {
|
||||
dashboard: "Dashboard",
|
||||
employee_list: "employee list",
|
||||
employee_management: "employee management",
|
||||
personal_profile: "profile",
|
||||
timesheets: "timesheets",
|
||||
timesheets_approval: "timesheet approval",
|
||||
user_access: "module access",
|
||||
presets: "access presets",
|
||||
preset_admin: "administrator",
|
||||
preset_employee: "employee",
|
||||
uncheck_all: "remove all",
|
||||
admin_description: "Check all modules",
|
||||
employee_description: "Only check modules that are relevant to standard employees with no management access",
|
||||
none_description: "Uncheck all modules",
|
||||
},
|
||||
add_employee: "Add employee",
|
||||
modify_employee: "Modify employee",
|
||||
access_label: "access",
|
||||
details_label: "details",
|
||||
},
|
||||
|
||||
login: {
|
||||
page_header: "account login",
|
||||
email: "e-mail",
|
||||
|
|
@ -59,20 +82,6 @@ export default {
|
|||
supervisor: "supervisor",
|
||||
hired_date: "hiring date",
|
||||
bankroll_id: "payroll ID",
|
||||
module_access: {
|
||||
dashboard: "Dashboard",
|
||||
employee_list: "employee list",
|
||||
employee_management: "employee management",
|
||||
personal_profile: "profile",
|
||||
timesheets: "timesheets",
|
||||
timesheets_approval: "timesheet approval",
|
||||
user_access: "module access",
|
||||
presets: "access presets",
|
||||
preset_admin: "admin",
|
||||
preset_employee: "employee",
|
||||
uncheck_all: "remove all",
|
||||
|
||||
},
|
||||
},
|
||||
preferences: {
|
||||
tab_title: "preferences",
|
||||
|
|
|
|||
|
|
@ -12,6 +12,29 @@ export default {
|
|||
},
|
||||
},
|
||||
|
||||
employee_management: {
|
||||
module_access: {
|
||||
dashboard: "Dashboard",
|
||||
employee_list: "employee list",
|
||||
employee_management: "employee management",
|
||||
personal_profile: "profile",
|
||||
timesheets: "timesheets",
|
||||
timesheets_approval: "timesheet approval",
|
||||
user_access: "module access",
|
||||
presets: "access presets",
|
||||
preset_admin: "administrateur",
|
||||
preset_employee: "employé",
|
||||
uncheck_all: "Tout enlever",
|
||||
admin_description: "Selectionner tous les modules",
|
||||
employee_description: "Selectionner seulement les modules qui sont pertinents aux employés sans accès spéciaux",
|
||||
none_description: "Enlever tous les accès",
|
||||
},
|
||||
add_employee: "Ajouter employé",
|
||||
modify_employee: "Modifier employé",
|
||||
access_label: "accès",
|
||||
details_label: "détails",
|
||||
},
|
||||
|
||||
login: {
|
||||
page_header: "connexion au compte",
|
||||
email: "courriel",
|
||||
|
|
@ -59,19 +82,6 @@ export default {
|
|||
supervisor: "nom du superviseur",
|
||||
hired_date: "date d'embauche",
|
||||
bankroll_id: "identifiant de paie",
|
||||
module_access: {
|
||||
dashboard: "accueil",
|
||||
employee_list: "liste employés",
|
||||
employee_management: "gestion employés",
|
||||
personal_profile: "profil",
|
||||
timesheets: "feuilles de temps",
|
||||
timesheets_approval: "valider feuilles de temps",
|
||||
user_access: "accès aux modules",
|
||||
presets: "accès prédéfinis",
|
||||
preset_admin: "administrateur",
|
||||
preset_employee: "employé",
|
||||
uncheck_all: "aucun accès",
|
||||
},
|
||||
},
|
||||
preferences: {
|
||||
tab_title: "préférences",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,123 @@
|
|||
<script
|
||||
setup
|
||||
lang="ts"
|
||||
>
|
||||
import { ref } from 'vue';
|
||||
import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
|
||||
import { useEmployeeStore } from 'src/stores/employee-store';
|
||||
import { employee_access_options, type ModuleAccessPreset, type ModuleAccessName, employee_access_presets } from 'src/modules/employee-list/models/employee-profile.models';
|
||||
|
||||
const employee_store = useEmployeeStore();
|
||||
const preset_preview = ref<ModuleAccessPreset>();
|
||||
|
||||
const toggleInSelected = (value: ModuleAccessName) => {
|
||||
const i = employee_store.employee.user_module_access.indexOf(value);
|
||||
if (i === -1) employee_store.employee.user_module_access.push(value);
|
||||
else employee_store.employee.user_module_access.splice(i, 1);
|
||||
}
|
||||
|
||||
const applyAccessPreset = (preset: ModuleAccessPreset) => {
|
||||
employee_store.employee.user_module_access = unwrapAndClone(employee_access_presets[preset]);
|
||||
}
|
||||
|
||||
const getPreviewBackgroundColor = (name: ModuleAccessName) => {
|
||||
if (employee_access_presets[preset_preview.value!].includes(name)) {
|
||||
if (!employee_store.employee.user_module_access.includes(name)) return 'bg-info text-white';
|
||||
|
||||
return 'bg-accent text-white';
|
||||
}
|
||||
|
||||
if (employee_store.employee.user_module_access.includes(name)) return 'bg-negative text-white';
|
||||
|
||||
return 'bg-dark';
|
||||
};
|
||||
|
||||
const getBackgroundColor = (name: ModuleAccessName) => {
|
||||
if (employee_store.employee.user_module_access.includes(name)) return 'bg-accent text-white';
|
||||
|
||||
return 'bg-dark';
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="row full-width">
|
||||
<div class="column col-3 q-px-md">
|
||||
<q-item
|
||||
clickable
|
||||
class="shadow-2 rounded-5 q-ma-sm bg-dark"
|
||||
@click="applyAccessPreset('admin')"
|
||||
@mouseover="preset_preview = 'admin'"
|
||||
@mouseleave="preset_preview = undefined"
|
||||
>
|
||||
<q-item-section>
|
||||
<q-item-label class="text-uppercase text-weight-bold">
|
||||
{{ $t('employee_management.module_access.preset_admin') }}
|
||||
</q-item-label>
|
||||
|
||||
<q-item-label caption>
|
||||
{{ $t('employee_management.module_access.admin_description') }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
|
||||
<q-item
|
||||
clickable
|
||||
class="shadow-2 rounded-5 q-ma-sm bg-dark"
|
||||
@click="applyAccessPreset('employee')"
|
||||
@mouseover="preset_preview = 'employee'"
|
||||
@mouseleave="preset_preview = undefined"
|
||||
>
|
||||
<q-item-section>
|
||||
<q-item-label class="text-uppercase text-weight-bold">
|
||||
{{ $t('employee_management.module_access.preset_employee') }}
|
||||
</q-item-label>
|
||||
|
||||
<q-item-label caption>
|
||||
{{ $t('employee_management.module_access.employee_description') }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
|
||||
<q-item
|
||||
clickable
|
||||
class="shadow-2 rounded-5 q-ma-sm bg-dark"
|
||||
@click="applyAccessPreset('none')"
|
||||
@mouseover="preset_preview = 'none'"
|
||||
@mouseleave="preset_preview = undefined"
|
||||
>
|
||||
<q-item-section>
|
||||
<q-item-label class="text-uppercase text-weight-bold">
|
||||
{{ $t('employee_management.module_access.uncheck_all') }}
|
||||
</q-item-label>
|
||||
|
||||
<q-item-label caption>
|
||||
{{ $t('employee_management.module_access.none_description') }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</div>
|
||||
|
||||
<div class="row col items-start content-start">
|
||||
<div
|
||||
v-for="option in employee_access_options"
|
||||
:key="option.label"
|
||||
class="col-lg-6 col-sm-12 col-xs-12 q-pa-xs"
|
||||
>
|
||||
<div
|
||||
class="row full-width cursor-pointer flex-center q-pa-sm rounded-5 no-wrap shadow-5"
|
||||
:class="preset_preview !== undefined ? getPreviewBackgroundColor(option.value) : getBackgroundColor(option.value)"
|
||||
@click="toggleInSelected(option.value)"
|
||||
>
|
||||
<span class="text-uppercase text-weight-bold">
|
||||
{{ $t('employee_management.module_access.' + option.value) }}
|
||||
</span>
|
||||
<q-space />
|
||||
<q-icon
|
||||
:name="employee_store.employee.user_module_access.includes(option.value) ? 'check' : ''"
|
||||
size="sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -3,20 +3,8 @@
|
|||
lang="ts"
|
||||
>
|
||||
import { useEmployeeStore } from 'src/stores/employee-store';
|
||||
import { employee_access_options, type ModuleAccessPreset, type ModuleAccessName, employee_access_presets } from 'src/modules/employee-list/models/employee-profile.models';
|
||||
import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
|
||||
|
||||
const employee_store = useEmployeeStore();
|
||||
|
||||
const toggleInSelected = (value: ModuleAccessName) => {
|
||||
const i = employee_store.employee.user_module_access.indexOf(value);
|
||||
if (i === -1) employee_store.employee.user_module_access.push(value);
|
||||
else employee_store.employee.user_module_access.splice(i, 1);
|
||||
}
|
||||
|
||||
const applyAccessPreset = (preset: ModuleAccessPreset) => {
|
||||
employee_store.employee.user_module_access = unwrapAndClone(employee_access_presets[preset]);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -28,14 +16,16 @@ import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
|
|||
>
|
||||
<q-input
|
||||
v-model="employee_store.employee.first_name"
|
||||
standout="bg-accent"
|
||||
dense
|
||||
color="accent"
|
||||
stack-label
|
||||
label-slot
|
||||
class="col q-ma-xs"
|
||||
class="col q-mx-md"
|
||||
>
|
||||
<template #label>
|
||||
<span class="text-weight-bolder text-uppercase" style="font-size: 0.85em;">
|
||||
<span
|
||||
class="text-weight-bolder text-uppercase"
|
||||
style="font-size: 0.85em;"
|
||||
>
|
||||
{{ $t('profile.personal.first_name') }}
|
||||
</span>
|
||||
</template>
|
||||
|
|
@ -43,14 +33,16 @@ import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
|
|||
|
||||
<q-input
|
||||
v-model="employee_store.employee.last_name"
|
||||
standout="bg-accent"
|
||||
dense
|
||||
color="accent"
|
||||
stack-label
|
||||
label-slot
|
||||
class="col q-ma-xs"
|
||||
class="col q-mx-md"
|
||||
>
|
||||
<template #label>
|
||||
<span class="text-weight-bolder text-uppercase" style="font-size: 0.85em;">
|
||||
<span
|
||||
class="text-weight-bolder text-uppercase"
|
||||
style="font-size: 0.85em;"
|
||||
>
|
||||
{{ $t('profile.personal.last_name') }}
|
||||
</span>
|
||||
</template>
|
||||
|
|
@ -63,14 +55,16 @@ import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
|
|||
>
|
||||
<q-input
|
||||
v-model="employee_store.employee.email"
|
||||
standout="bg-accent"
|
||||
dense
|
||||
color="accent"
|
||||
stack-label
|
||||
label-slot
|
||||
class="col q-ma-xs"
|
||||
class="col q-mx-md"
|
||||
>
|
||||
<template #label>
|
||||
<span class="text-weight-bolder text-uppercase" style="font-size: 0.85em;">
|
||||
<span
|
||||
class="text-weight-bolder text-uppercase"
|
||||
style="font-size: 0.85em;"
|
||||
>
|
||||
{{ $t('profile.employee.email') }}
|
||||
</span>
|
||||
</template>
|
||||
|
|
@ -78,14 +72,16 @@ import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
|
|||
|
||||
<q-input
|
||||
v-model="employee_store.employee.phone_number"
|
||||
standout="bg-accent"
|
||||
dense
|
||||
color="accent"
|
||||
stack-label
|
||||
label-slot
|
||||
class="col q-ma-xs"
|
||||
class="col q-mx-md"
|
||||
>
|
||||
<template #label>
|
||||
<span class="text-weight-bolder text-uppercase" style="font-size: 0.85em;">
|
||||
<span
|
||||
class="text-weight-bolder text-uppercase"
|
||||
style="font-size: 0.85em;"
|
||||
>
|
||||
{{ $t('profile.personal.phone_number') }}
|
||||
</span>
|
||||
</template>
|
||||
|
|
@ -98,14 +94,16 @@ import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
|
|||
>
|
||||
<q-input
|
||||
v-model="employee_store.employee.job_title"
|
||||
standout="bg-accent"
|
||||
dense
|
||||
color="accent"
|
||||
stack-label
|
||||
label-slot
|
||||
class="col q-ma-xs"
|
||||
class="col q-mx-md"
|
||||
>
|
||||
<template #label>
|
||||
<span class="text-weight-bolder text-uppercase" style="font-size: 0.85em;">
|
||||
<span
|
||||
class="text-weight-bolder text-uppercase"
|
||||
style="font-size: 0.85em;"
|
||||
>
|
||||
{{ $t('profile.employee.job_title') }}
|
||||
</span>
|
||||
</template>
|
||||
|
|
@ -113,14 +111,16 @@ import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
|
|||
|
||||
<q-input
|
||||
v-model="employee_store.employee.company_name"
|
||||
standout="bg-accent"
|
||||
dense
|
||||
color="accent"
|
||||
stack-label
|
||||
label-slot
|
||||
class="col q-ma-xs"
|
||||
class="col q-mx-md"
|
||||
>
|
||||
<template #label>
|
||||
<span class="text-weight-bolder text-uppercase" style="font-size: 0.85em;">
|
||||
<span
|
||||
class="text-weight-bolder text-uppercase"
|
||||
style="font-size: 0.85em;"
|
||||
>
|
||||
{{ $t('profile.employee.company') }}
|
||||
</span>
|
||||
</template>
|
||||
|
|
@ -133,14 +133,16 @@ import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
|
|||
>
|
||||
<q-input
|
||||
v-model="employee_store.employee.supervisor_full_name"
|
||||
standout="bg-accent"
|
||||
dense
|
||||
color="accent"
|
||||
stack-label
|
||||
label-slot
|
||||
class="col q-ma-xs"
|
||||
class="col q-mx-md"
|
||||
>
|
||||
<template #label>
|
||||
<span class="text-weight-bolder text-uppercase" style="font-size: 0.85em;">
|
||||
<span
|
||||
class="text-weight-bolder text-uppercase"
|
||||
style="font-size: 0.85em;"
|
||||
>
|
||||
{{ $t('profile.employee.supervisor') }}
|
||||
</span>
|
||||
</template>
|
||||
|
|
@ -148,97 +150,21 @@ import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
|
|||
|
||||
<q-input
|
||||
v-model="employee_store.employee.phone_number"
|
||||
standout="bg-accent"
|
||||
dense
|
||||
color="accent"
|
||||
stack-label
|
||||
label-slot
|
||||
class="col q-ma-xs"
|
||||
class="col q-mx-md"
|
||||
>
|
||||
<template #label>
|
||||
<span class="text-weight-bolder text-uppercase" style="font-size: 0.85em;">
|
||||
<span
|
||||
class="text-weight-bolder text-uppercase"
|
||||
style="font-size: 0.85em;"
|
||||
>
|
||||
{{ $t('profile.employee.bankroll_id') }}
|
||||
</span>
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
|
||||
<q-field
|
||||
v-model="employee_store.employee.user_module_access"
|
||||
dense
|
||||
stack-label
|
||||
label-slot
|
||||
standout="transparent"
|
||||
class="col-12 q-ma-sm"
|
||||
>
|
||||
<template #label>
|
||||
<span class="text-weight-bolder text-uppercase" style="font-size: 0.85em;">
|
||||
{{ $t('profile.employee.module_access.user_access') }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<div class="col-12 column full-width">
|
||||
<div class="row col-auto flex-center">
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
color="accent"
|
||||
:label="$t('profile.employee.module_access.preset_admin')"
|
||||
class="col-3 q-mx-sm q-pa-xs text-weight-bold"
|
||||
@click="applyAccessPreset('admin')"
|
||||
/>
|
||||
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
color="accent"
|
||||
:label="$t('profile.employee.module_access.preset_employee')"
|
||||
class="col-3 q-mx-sm q-pa-xs text-weight-bold"
|
||||
@click="applyAccessPreset('employee')"
|
||||
/>
|
||||
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
color="negative"
|
||||
:label="$t('profile.employee.module_access.uncheck_all')"
|
||||
class="col-3 q-mx-sm q-pa-xs text-weight-bold"
|
||||
@click="applyAccessPreset('none')"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div
|
||||
v-for="option in employee_access_options"
|
||||
:key="option.label"
|
||||
class="col-xl-4 col-lg-6 col-sm-12 col-xs-12 q-pa-xs"
|
||||
>
|
||||
<div
|
||||
class="row full-width cursor-pointer flex-center q-pa-sm rounded-5 no-wrap shadow-1"
|
||||
:class="employee_store.employee.user_module_access.includes(option.value) ? 'bg-accent text-white' : ''"
|
||||
@click="toggleInSelected(option.value)"
|
||||
>
|
||||
<span class="text-uppercase text-caption">
|
||||
{{ $t('profile.employee.module_access.' + option.value) }}
|
||||
</span>
|
||||
<q-space />
|
||||
<q-icon
|
||||
:name="employee_store.employee.user_module_access.includes(option.value) ? 'check' : ''"
|
||||
size="sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <q-option-group
|
||||
v-model="selected_permissions"
|
||||
dense
|
||||
inline
|
||||
left-label
|
||||
type="checkbox"
|
||||
color="accent"
|
||||
:options="employee_access_options"
|
||||
/> -->
|
||||
</q-field>
|
||||
</q-form>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -3,20 +3,80 @@
|
|||
lang="ts"
|
||||
>
|
||||
import AddModifyDialogForm from 'src/modules/employee-list/components/employee/add-modify-dialog-form.vue';
|
||||
import AddModifyDialogAccess from 'src/modules/employee-list/components/employee/add-modify-dialog-access.vue';
|
||||
|
||||
import { useEmployeeStore } from 'src/stores/employee-store';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const employee_store = useEmployeeStore();
|
||||
const current_step = ref<'form' | 'access'>('form');
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-dialog v-model="employee_store.is_add_modify_dialog_open">
|
||||
<q-card>
|
||||
<q-card-section class="text-bolder text-white bg-primary text-center">
|
||||
<span >ADD EMPLOYEE</span>
|
||||
<q-dialog
|
||||
v-model="employee_store.is_add_modify_dialog_open"
|
||||
full-width
|
||||
@beforeShow="current_step = 'form'"
|
||||
>
|
||||
<q-card
|
||||
class="bg-secondary shadow-10 rounded-10"
|
||||
:style="$q.screen.lt.md ? '' : 'max-width: 70vw !important;'"
|
||||
>
|
||||
<q-card-section
|
||||
class="text-weight-bolder text-white text-h6 text-uppercase bg-primary text-center shadow-10 q-py-xs"
|
||||
>
|
||||
<span>{{ $t('employee_management.' + employee_store.management_mode) }}</span>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section>
|
||||
<q-carousel
|
||||
v-model="current_step"
|
||||
transition-prev="slide-right"
|
||||
transition-next="slide-left"
|
||||
animated
|
||||
control-color="accent"
|
||||
class="rounded-10 transparent"
|
||||
>
|
||||
<q-carousel-slide name="form">
|
||||
<div class="rounded-5 q-pb-sm bg-dark">
|
||||
<AddModifyDialogForm />
|
||||
</div>
|
||||
</q-carousel-slide>
|
||||
|
||||
<q-carousel-slide name="access">
|
||||
<AddModifyDialogAccess />
|
||||
</q-carousel-slide>
|
||||
|
||||
<template #control>
|
||||
<q-carousel-control position="bottom">
|
||||
<div class="row">
|
||||
<q-btn
|
||||
v-if="current_step === 'access'"
|
||||
flat
|
||||
size="lg"
|
||||
color="accent"
|
||||
icon="arrow_back"
|
||||
:label="$t('employee_management.details_label')"
|
||||
@click="current_step = 'form'"
|
||||
/>
|
||||
|
||||
<q-space />
|
||||
|
||||
<q-btn
|
||||
v-if="current_step === 'form'"
|
||||
flat
|
||||
size="lg"
|
||||
color="accent"
|
||||
icon-right="arrow_forward"
|
||||
:label="$t('employee_management.access_label')"
|
||||
@click="current_step = 'access'"
|
||||
/>
|
||||
</div>
|
||||
</q-carousel-control>
|
||||
</template>
|
||||
</q-carousel>
|
||||
</q-card-section>
|
||||
|
||||
<q-inner-loading :showing="employee_store.is_loading" />
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
|
|
|||
|
|
@ -7,18 +7,20 @@ export const useEmployeeStore = defineStore('employee', () => {
|
|||
const employee = ref<EmployeeProfile>(new EmployeeProfile);
|
||||
const employee_list = ref<EmployeeProfile[]>([]);
|
||||
const is_add_modify_dialog_open = ref<boolean>(false);
|
||||
const management_mode = ref<'modify_employee' | 'add_employee'>('add_employee');
|
||||
const is_loading = ref(false);
|
||||
|
||||
const openAddModifyDialog = async (employee_email?: string) =>{
|
||||
console.log('open window triggered');
|
||||
is_add_modify_dialog_open.value = true;
|
||||
|
||||
if (employee_email === undefined) {
|
||||
management_mode.value = 'add_employee'
|
||||
employee.value = new EmployeeProfile();
|
||||
return;
|
||||
}
|
||||
|
||||
is_loading.value = true;
|
||||
management_mode.value = 'modify_employee';
|
||||
await getEmployeeDetails(employee_email);
|
||||
is_loading.value = false;
|
||||
}
|
||||
|
|
@ -57,6 +59,7 @@ export const useEmployeeStore = defineStore('employee', () => {
|
|||
employee,
|
||||
employee_list,
|
||||
is_add_modify_dialog_open,
|
||||
management_mode,
|
||||
is_loading,
|
||||
getEmployeeList,
|
||||
getEmployeeDetails,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user