Account Submodule #412
|
@ -1,15 +1,31 @@
|
|||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import VnCard from 'components/common/VnCard.vue';
|
||||
import AccountDescriptor from './AccountDescriptor.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
|
||||
const routeName = computed(() => route.name);
|
||||
const customRouteRedirectName = computed(() => routeName.value);
|
||||
const searchBarDataKeys = {
|
||||
AccountSummary: 'AccountSummary',
|
||||
AccountInheritedRoles: 'AccountInheritedRoles',
|
||||
AccountMailForwarding: 'AccountMailForwarding',
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VnCard
|
||||
data-key="Account"
|
||||
base-url="Accounts"
|
||||
:descriptor="AccountDescriptor"
|
||||
searchbar-data-key="AccountList"
|
||||
searchbar-url="Accounts/filter"
|
||||
searchbar-label="Search account"
|
||||
searchbar-info="You can search by account id or customer name"
|
||||
:search-data-key="searchBarDataKeys[routeName]"
|
||||
:search-custom-route-redirect="customRouteRedirectName"
|
||||
:search-redirect="!!customRouteRedirectName"
|
||||
:searchbar-label="t('account.search')"
|
||||
:searchbar-info="t('account.searchInfo')"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<script setup>
|
||||
import InheritedRoles from '../InheritedRoles.vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<InheritedRoles data-key="AccountInheritedRoles" />
|
||||
</template>
|
|
@ -0,0 +1,151 @@
|
|||
<script setup>
|
||||
import { ref, onMounted, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnRow from 'components/ui/VnRow.vue';
|
||||
|
||||
import axios from 'axios';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import useNotify from 'src/composables/useNotify.js';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const stateStore = useStateStore();
|
||||
const { notify } = useNotify();
|
||||
|
||||
const formData = ref({
|
||||
forwardTo: null,
|
||||
account: null,
|
||||
});
|
||||
|
||||
const hasAccount = ref(false);
|
||||
const hasData = ref(false);
|
||||
const loading = ref(false);
|
||||
|
||||
const fetchAccountExistence = async () => {
|
||||
try {
|
||||
const { data } = await axios.get(`Accounts/${route.params.id}/exists`);
|
||||
return data.exists;
|
||||
} catch (error) {
|
||||
console.error('Error fetching account existence', error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const fetchMailForwards = async () => {
|
||||
try {
|
||||
const response = await axios.get(`MailForwards/${route.params.id}`);
|
||||
return response.data;
|
||||
} catch (err) {
|
||||
console.error('Error fetching mail forwards', err);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const deleteMailForward = async () => {
|
||||
try {
|
||||
await axios.delete(`MailForwards/${route.params.id}`);
|
||||
formData.value.forwardTo = null;
|
||||
notify(t('globals.dataSaved'), 'positive');
|
||||
} catch (err) {
|
||||
console.error('Error deleting mail forward', err);
|
||||
}
|
||||
};
|
||||
|
||||
const updateMailForward = async () => {
|
||||
try {
|
||||
await axios.patch('MailForwards', formData.value);
|
||||
} catch (err) {
|
||||
console.error('Error creating mail forward', err);
|
||||
}
|
||||
};
|
||||
|
||||
const onSubmit = async () => {
|
||||
if (hasData.value) await updateMailForward();
|
||||
else await deleteMailForward();
|
||||
};
|
||||
|
||||
const setInitialData = async () => {
|
||||
loading.value = true;
|
||||
formData.value.account = route.params.id;
|
||||
hasAccount.value = await fetchAccountExistence(route.params.id);
|
||||
if (!hasAccount.value) {
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await fetchMailForwards(route.params.id);
|
||||
const forwardTo = result ? result.forwardTo : null;
|
||||
formData.value.forwardTo = forwardTo;
|
||||
|
||||
hasData.value = hasAccount.value && !!forwardTo;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
watch(
|
||||
() => route.params.id,
|
||||
() => setInitialData()
|
||||
);
|
||||
|
||||
onMounted(async () => {
|
||||
await setInitialData();
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<FetchData
|
||||
:url="`Accounts/${route.params.id}/exists`"
|
||||
@on-fetch="(data) => (hasAccount = data)"
|
||||
auto-load
|
||||
/>
|
||||
<div class="flex justify-center">
|
||||
<QSpinner v-if="loading" color="primary" size="md" />
|
||||
<QForm
|
||||
v-else-if="hasAccount"
|
||||
@submit="onSubmit()"
|
||||
class="full-width"
|
||||
style="max-width: 800px"
|
||||
>
|
||||
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
|
||||
<div>
|
||||
<QBtnGroup push class="q-gutter-x-sm">
|
||||
<slot name="moreActions" />
|
||||
<QBtn
|
||||
color="primary"
|
||||
icon="restart_alt"
|
||||
flat
|
||||
@click="reset()"
|
||||
:label="t('globals.reset')"
|
||||
/>
|
||||
<QBtn
|
||||
color="primary"
|
||||
icon="save"
|
||||
@click="onSubmit()"
|
||||
:label="t('globals.save')"
|
||||
/>
|
||||
</QBtnGroup>
|
||||
</div>
|
||||
</Teleport>
|
||||
<QCard class="q-pa-lg">
|
||||
<VnRow class="row q-mb-md">
|
||||
<QCheckbox
|
||||
v-model="hasData"
|
||||
:label="t('account.mailForwarding.enableMailForwarding')"
|
||||
:toggle-indeterminate="false"
|
||||
/>
|
||||
</VnRow>
|
||||
<VnRow v-if="hasData" class="row q-gutter-md q-mb-md">
|
||||
<VnInput
|
||||
v-model="formData.forwardTo"
|
||||
:label="t('account.mailForwarding.forwardingMail')"
|
||||
/>
|
||||
</VnRow>
|
||||
</QCard>
|
||||
</QForm>
|
||||
<h5 v-else class="text-center">
|
||||
{{ t('account.mailForwarding.accountNotEnabled') }}
|
||||
</h5>
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,99 @@
|
|||
<script setup>
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
|
||||
import VnPaginate from 'components/ui/VnPaginate.vue';
|
||||
|
||||
import { useArrayData } from 'composables/useArrayData';
|
||||
|
||||
const props = defineProps({
|
||||
dataKey: { type: String, required: true },
|
||||
});
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const paginateRef = ref(null);
|
||||
|
||||
const arrayData = useArrayData(props.dataKey);
|
||||
const store = arrayData.store;
|
||||
|
||||
const data = computed(() => {
|
||||
const dataCopy = store.data;
|
||||
return dataCopy.sort((a, b) => a.inherits?.name.localeCompare(b.inherits?.name));
|
||||
});
|
||||
|
||||
const filter = computed(() => ({
|
||||
where: { role: route.params.id },
|
||||
include: {
|
||||
relation: 'inherits',
|
||||
scope: {
|
||||
fields: ['id', 'name', 'description'],
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
const urlPath = computed(() => 'RoleRoles');
|
||||
|
||||
const columns = computed(() => [
|
||||
{
|
||||
name: 'name',
|
||||
},
|
||||
]);
|
||||
|
||||
watch(
|
||||
() => route.params.id,
|
||||
() => {
|
||||
store.url = urlPath.value;
|
||||
store.filter = filter.value;
|
||||
fetchSubRoles();
|
||||
}
|
||||
);
|
||||
|
||||
const fetchSubRoles = () => paginateRef.value.fetch();
|
||||
|
||||
const redirectToRoleSummary = (id) =>
|
||||
router.push({ name: 'RoleSummary', params: { id } });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QPage class="column items-center q-pa-md">
|
||||
<div class="full-width" style="max-width: 400px">
|
||||
<VnPaginate
|
||||
ref="paginateRef"
|
||||
:data-key="dataKey"
|
||||
:filter="filter"
|
||||
:url="urlPath"
|
||||
auto-load
|
||||
>
|
||||
<template #body>
|
||||
<QTable :rows="data" :columns="columns" hide-header>
|
||||
<template #body="{ row }">
|
||||
<QTr
|
||||
@click="redirectToRoleSummary(row.inherits?.id)"
|
||||
class="cursor-pointer"
|
||||
>
|
||||
<QTd>
|
||||
<div class="column">
|
||||
<span>{{ row.inherits?.name }}</span>
|
||||
<span class="color-vn-label">{{
|
||||
row.inherits?.description
|
||||
}}</span>
|
||||
</div>
|
||||
</QTd>
|
||||
</QTr>
|
||||
</template>
|
||||
</QTable>
|
||||
</template>
|
||||
</VnPaginate>
|
||||
</div>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Role removed. Changes will take a while to fully propagate.: Rol eliminado. Los cambios tardaran un tiempo en propagarse completamente.
|
||||
Role added! Changes will take a while to fully propagate.: ¡Rol añadido! Los cambios tardaran un tiempo en propagarse completamente.
|
||||
El rol va a ser eliminado: Role will be removed
|
||||
¿Seguro que quieres continuar?: Are you sure you want to continue?
|
||||
</i18n>
|
|
@ -43,6 +43,10 @@ account:
|
|||
role: Role
|
||||
password: Password
|
||||
active: Active
|
||||
mailForwarding:
|
||||
forwardingMail: Dirección de reenvío
|
||||
accountNotEnabled: Account not enabled
|
||||
enableMailForwarding: Enable mail forwarding
|
||||
role:
|
||||
pageTitles:
|
||||
inheritedRoles: Inherited Roles
|
||||
|
|
|
@ -52,6 +52,10 @@ account:
|
|||
role: Rol
|
||||
password: Contraseña
|
||||
active: Activo
|
||||
mailForwarding:
|
||||
forwardingMail: Dirección de reenvío
|
||||
accountNotEnabled: Cuenta no habilitada
|
||||
enableMailForwarding: Habilitar redirección de correo
|
||||
role:
|
||||
pageTitles:
|
||||
inheritedRoles: Roles heredados
|
||||
|
|
|
@ -147,7 +147,7 @@ export default {
|
|||
},
|
||||
{
|
||||
name: 'AccountInheritedRoles',
|
||||
path: 'inherited-oles',
|
||||
path: 'inherited-roles',
|
||||
meta: {
|
||||
title: 'inheritedRoles',
|
||||
icon: 'group',
|
||||
|
|
Loading…
Reference in New Issue