0
0
Fork 0

feat: AccountDescriptor

This commit is contained in:
Javier Segarra 2024-06-05 15:09:43 +02:00
parent 30c912fa62
commit de488169b7
7 changed files with 139 additions and 132 deletions

View File

@ -67,6 +67,7 @@ async function confirm() {
</QCardSection>
<QCardSection class="row items-center">
<span v-html="message"></span>
<slot name="customHTML"></slot>
</QCardSection>
<QCardActions align="right">
<QBtn

View File

@ -7,6 +7,8 @@ import VnLv from 'src/components/ui/VnLv.vue';
import useCardDescription from 'src/composables/useCardDescription';
import AccountDescriptorMenu from './AccountDescriptorMenu.vue';
import { useSession } from 'src/composables/useSession';
import FetchData from 'src/components/FetchData.vue';
const $props = defineProps({
id: {
type: Number,
@ -68,8 +70,7 @@ const hasAccount = ref(false);
</QBtn>
</template>
<template #menu>
{{}}
<AccountDescriptorMenu />
<AccountDescriptorMenu :has-account="hasAccount" />
</template>
<template #before>
<QImg :src="getAccountAvatar()" class="photo">
@ -95,28 +96,6 @@ const hasAccount = ref(false);
</template>
<template #actions="{ entity }">
<QCardActions class="q-gutter-x-md">
<QIcon
v-if="entity.hasAccount"
color="primary"
name="contact_mail"
flat
round
size="sm"
class="fill-icon"
>
<QTooltip>{{ t('account.card.enabled') }}</QTooltip>
</QIcon>
<QIcon
v-if="!entity.hasAccount"
color="primary"
name="contact_mail"
flat
round
size="sm"
class="fill-icon"
>
<QTooltip>{{ t('account.card.disabled') }}</QTooltip>
</QIcon>
<QIcon
v-if="!entity.active"
color="primary"
@ -128,6 +107,17 @@ const hasAccount = ref(false);
>
<QTooltip>{{ t('account.card.deactivated') }}</QTooltip>
</QIcon>
<QIcon
color="primary"
name="contact_mail"
v-if="entity.hasAccount"
flat
round
size="sm"
class="fill-icon"
>
<QTooltip>{{ t('account.card.enabled') }}</QTooltip>
</QIcon>
</QCardActions>
</template>
</CardDescriptor>

View File

@ -1,73 +1,109 @@
<script setup>
import axios from 'axios';
import { computed, ref } from 'vue';
import { computed, ref, toRefs } from 'vue';
import { useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import { usePrintService } from 'composables/usePrintService';
import { useVnConfirm } from 'composables/useVnConfirm';
import { useRoute } from 'vue-router';
import { useArrayData } from 'src/composables/useArrayData';
import CustomerChangePassword from 'src/pages/Customer/components/CustomerChangePassword.vue';
import VnConfirm from 'src/components/ui/VnConfirm.vue';
const quasar = useQuasar();
const $props = defineProps({
hasAccount: {
type: Boolean,
default: false,
required: true,
},
});
const { t } = useI18n();
const { openReport } = usePrintService();
const { hasAccount } = toRefs($props);
const { openConfirmationModal } = useVnConfirm();
const route = useRoute();
const account = computed(() => useArrayData('AccountId').store.data[0]);
const entityId = computed(() => route.params.id);
account.value.hasAccount = hasAccount.value;
const entityId = computed(() => +route.params.id);
async function setPassword() {
await axios.post(`Accounts`, { id: entityId });
async function updateStatusAccount(active) {
if (active) {
await axios.post(`Accounts`, { id: entityId.value });
} else {
await axios.delete(`Accounts/${entityId.value}`);
}
async function enableAccount() {
await axios.post(`Accounts`, { id: entityId });
account.value.hasAccount = true;
account.value.hasAccount = active;
const status = active ? 'enable' : 'disable';
quasar.notify({
message: t('globals.dataSaved'),
message: t(`account.card.${status}Account.success`),
type: 'positive',
});
}
async function disableAccount() {
await axios.post(`Accounts`, { id: entityId });
account.value.hasAccount = false;
async function updateStatusUser(active) {
await axios.patch(`VnUsers/${entityId.value}`, { active });
account.value.active = active;
const status = active ? 'activate' : 'deactivate';
quasar.notify({
message: t('globals.dataSaved'),
message: t(`account.card.actions.${status}User.success`),
type: 'positive',
});
}
async function activateUser() {
await axios.patch(`VnUsers/${entityId.value}`, { active: true });
account.value.active = true;
// quasar.notify({
// message: t('globals.dataSaved'),
// type: 'positive',
// });
function setPassword() {
quasar.dialog({
component: CustomerChangePassword,
componentProps: {
id: entityId.value,
},
});
}
async function deactivateUser() {
await axios.patch(`VnUsers/${entityId.value}`, { active: false });
account.value.active = false;
// quasar.notify({
// message: t('globals.dataSaved'),
// type: 'positive',
// });
const showSyncDialog = ref(false);
const syncPassword = ref(null);
const shouldSyncPassword = ref(false);
async function sync() {
const params = { force: true };
if (shouldSyncPassword.value) params.password = syncPassword.value;
await axios.patch(`Accounts/${account.value.name}/sync`, {
params,
});
quasar.notify({
message: t('account.card.actions.sync.success'),
type: 'positive',
});
}
</script>
<template>
{{ account }}
<QItem
v-ripple
clickable
@click="
openConfirmationModal(
t('Confirm deletion'),
t('Are you sure...TODO'),
setPassword
)
"
<VnConfirm
v-model="showSyncDialog"
:message="t('account.card.actions.sync.message')"
:title="t('account.card.actions.sync.title')"
:promise="sync"
>
<template #customHTML>
{{ shouldSyncPassword }}
<QCheckbox
:label="t('account.card.actions.sync.checkbox')"
v-model="shouldSyncPassword"
class="full-width"
clearable
clear-icon="close"
>
<QIcon style="padding-left: 10px" color="primary" name="info" size="sm">
<QTooltip>{{ t('account.card.actions.sync.tooltip') }}</QTooltip>
</QIcon></QCheckbox
>
<QInput
v-if="shouldSyncPassword"
:label="t('login.password')"
v-model="syncPassword"
class="full-width"
clearable
clear-icon="close"
type="password"
/>
</template>
</VnConfirm>
<QItem v-ripple clickable @click="setPassword">
<QItemSection>{{ t('account.card.actions.setPassword') }}</QItemSection>
</QItem>
<QItem
@ -78,7 +114,7 @@ async function deactivateUser() {
openConfirmationModal(
t('account.card.actions.enableAccount.title'),
t('account.card.actions.enableAccount.subtitle'),
enableAccount
() => updateStatusAccount(true)
)
"
>
@ -92,12 +128,27 @@ async function deactivateUser() {
openConfirmationModal(
t('account.card.actions.disableAccount.title'),
t('account.card.actions.disableAccount.subtitle'),
disableAccount
() => updateStatusAccount(false)
)
"
>
<QItemSection>{{ t('account.card.actions.disableAccount.name') }}</QItemSection>
</QItem>
<QItem
v-if="!account.active"
v-ripple
clickable
@click="
openConfirmationModal(
t('account.card.actions.activateUser.title'),
t('account.card.actions.activateUser.title'),
() => updateStatusUser(true)
)
"
>
<QItemSection>{{ t('account.card.actions.activateUser.name') }}</QItemSection>
</QItem>
<QItem
v-if="account.active"
v-ripple
@ -106,37 +157,13 @@ async function deactivateUser() {
openConfirmationModal(
t('account.card.actions.deactivateUser.title'),
t('account.card.actions.deactivateUser.title'),
deactivateUser
() => updateStatusUser(false)
)
"
>
<QItemSection>{{ t('account.card.actions.deactivateUser.name') }}</QItemSection>
</QItem>
<QItem
v-if="!account.active"
v-ripple
clickable
@click="
openConfirmationModal(
t('account.card.actions.activateUser.title'),
t('account.card.actions.activateUser.title'),
activateUser
)
"
>
<QItemSection>{{ t('account.card.actions.activateUser.name') }}</QItemSection>
</QItem>
<QItem
v-ripple
clickable
@click="
openConfirmationModal(
t('account.card.actions.sync.title'),
t('account.card.actions.sync.subtitle'),
sync
)
"
>
<QItem v-ripple clickable @click="showSyncDialog = true">
<QItemSection>{{ t('account.card.actions.sync.name') }}</QItemSection>
</QItem>
@ -158,24 +185,3 @@ async function deactivateUser() {
<QItemSection>{{ t('account.card.actions.delete.name') }}</QItemSection>
</QItem>
</template>
<i18n>
{
"en": {
"pickupOrder": "Pickup order",
"openPickupOrder": "Open pickup order",
"sendPickupOrder": "Send pickup order",
"deleteAccount": "Delete account",
"confirmDeletion": "Confirm deletion",
"confirmDeletionMessage": "Are you sure you want to delete this account?"
},
"es": {
"pickupOrder": "Orden de recogida",
"openPickupOrder": "Abrir orden de recogida",
"sendPickupOrder": "Enviar orden de recogida",
"deleteAccount": "Eliminar reclamación",
"confirmDeletion": "Confirmar eliminación",
"confirmDeletionMessage": "Seguro que quieres eliminar esta reclamación?"
}
}
</i18n>

View File

@ -40,26 +40,35 @@ account:
name: Disable account
title: The account will be disabled
subtitle: Are you sure you want to continue?
success: 'Account disabled!'
enableAccount:
name: Enable account
title: The account will be enabled
subtitle: Are you sure you want to continue?
success: 'Account enabled!'
deactivateUser:
name: Deactivate user
title: The user will be deactivated
subtitle: Are you sure you want to continue?
success: 'User deactivated!'
activateUser:
name: Activate user
title: The user will be disabled
subtitle: Are you sure you want to continue?
success: 'User activated!'
sync:
name: Sync
title: The account will be sync
subtitle: Are you sure you want to continue?
success: 'User synchronized!'
checkbox: Synchronize password
message: Do you want to synchronize user?
tooltip: If password is not specified, just user attributes are synchronized
delete:
name: Delete
title: The account will be deleted
subtitle: Are you sure you want to continue?
success: ''
search: Search user
searchInfo: You can search by id, name or nickname
create:

View File

@ -39,26 +39,35 @@ account:
name: Deshabilitar cuenta
title: La cuenta será deshabilitada
subtitle: ¿Seguro que quieres continuar?
success: '¡Cuenta deshabilitada!'
enableAccount:
name: Habilitar cuenta
title: La cuenta será habilitada
subtitle: ¿Seguro que quieres continuar?
success: '¡Cuenta habilitada!'
deactivateUser:
name: Desactivar usuario
title: El usuario será deshabilitado
subtitle: ¿Seguro que quieres continuar?
success: '¡Usuario desactivado!'
activateUser:
name: Activar usuario
title: El usuario será activado
subtitle: ¿Seguro que quieres continuar?
success: '¡Usuario activado!'
sync:
name: Sincronizar
title: El usuario será sincronizado
subtitle: ¿Seguro que quieres continuar?
success: '¡Usuario sincronizado!'
checkbox: Sincronizar contraseña
message: ¿Quieres sincronizar el usuario?
tooltip: Si la contraseña no se especifica solo se sincronizarán lo atributos del usuario
delete:
name: Eliminar
title: El usuario será eliminado
subtitle: ¿Seguro que quieres continuar?
success: ''
search: Buscar usuario
searchInfo: Puedes buscar por id, nombre o usuario
create:

View File

@ -28,7 +28,6 @@ const isLoading = ref(false);
const name = ref(null);
const usersPreviewRef = ref(null);
const user = ref([]);
const userPasswords = ref(0);
const dataChanges = computed(() => {
return (
@ -45,7 +44,6 @@ const showChangePasswordDialog = () => {
component: CustomerChangePassword,
componentProps: {
id: route.params.id,
userPasswords: userPasswords.value,
promise: usersPreviewRef.value.fetch(),
},
});
@ -97,11 +95,6 @@ const onSubmit = async () => {
@on-fetch="(data) => (canChangePassword = data)"
auto-load
/>
<FetchData
@on-fetch="(data) => (userPasswords = data[0])"
auto-load
url="UserPasswords"
/>
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
<QBtnGroup push class="q-gutter-x-sm">

View File

@ -9,6 +9,7 @@ import useNotify from 'src/composables/useNotify';
import VnRow from 'components/ui/VnRow.vue';
import VnInput from 'src/components/common/VnInput.vue';
import FetchData from 'src/components/FetchData.vue';
const { dialogRef } = useDialogPluginComponent();
const { notify } = useNotify();
@ -19,15 +20,12 @@ const $props = defineProps({
type: String,
required: true,
},
userPasswords: {
type: Object,
required: true,
},
promise: {
type: Function,
required: true,
},
});
const userPasswords = ref({});
const closeButton = ref(null);
const isLoading = ref(false);
@ -60,6 +58,11 @@ const onSubmit = async () => {
<template>
<QDialog ref="dialogRef">
<FetchData
@on-fetch="(data) => (userPasswords = data[0])"
auto-load
url="UserPasswords"
/>
<QCard class="q-pa-lg">
<QCardSection>
<QForm @submit.prevent="onSubmit">
@ -71,7 +74,7 @@ const onSubmit = async () => {
<QIcon name="close" size="sm" />
</span>
<VnRow class="row q-gutter-md q-mb-md">
<VnRow class="row q-gutter-md q-mb-md" style="flex-direction: column">
<div class="col">
<VnInput
:label="t('New password')"
@ -84,11 +87,7 @@ const onSubmit = async () => {
<QTooltip>
{{
t('customer.card.passwordRequirements', {
length: $props.userPasswords.length,
nAlpha: $props.userPasswords.nAlpha,
nDigits: $props.userPasswords.nDigits,
nPunct: $props.userPasswords.nPunct,
nUpper: $props.userPasswords.nUpper,
...userPasswords,
})
}}
</QTooltip>