forked from verdnatura/salix-front
Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix-front into 7323-fixErrors
This commit is contained in:
commit
bd67218a00
|
@ -100,7 +100,6 @@ const isResetting = ref(false);
|
||||||
const hasChanges = ref(!$props.observeFormChanges);
|
const hasChanges = ref(!$props.observeFormChanges);
|
||||||
const originalData = ref({});
|
const originalData = ref({});
|
||||||
const formData = computed(() => state.get(modelValue));
|
const formData = computed(() => state.get(modelValue));
|
||||||
const formUrl = computed(() => $props.url);
|
|
||||||
const defaultButtons = computed(() => ({
|
const defaultButtons = computed(() => ({
|
||||||
save: {
|
save: {
|
||||||
color: 'primary',
|
color: 'primary',
|
||||||
|
@ -148,11 +147,14 @@ if (!$props.url)
|
||||||
(val) => updateAndEmit('onFetch', val)
|
(val) => updateAndEmit('onFetch', val)
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(formUrl, async () => {
|
watch(
|
||||||
originalData.value = null;
|
() => [$props.url, $props.filter],
|
||||||
reset();
|
async () => {
|
||||||
await fetch();
|
originalData.value = null;
|
||||||
});
|
reset();
|
||||||
|
await fetch();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
onBeforeRouteLeave((to, from, next) => {
|
onBeforeRouteLeave((to, from, next) => {
|
||||||
if (hasChanges.value && $props.observeFormChanges)
|
if (hasChanges.value && $props.observeFormChanges)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onBeforeMount } from 'vue';
|
import { watch, computed } from 'vue';
|
||||||
import { date } from 'quasar';
|
import { date } from 'quasar';
|
||||||
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
||||||
import VnAvatar from '../ui/VnAvatar.vue';
|
import VnAvatar from '../ui/VnAvatar.vue';
|
||||||
|
@ -10,31 +10,32 @@ const $props = defineProps({
|
||||||
where: { type: Object, default: () => {} },
|
where: { type: Object, default: () => {} },
|
||||||
});
|
});
|
||||||
|
|
||||||
const filter = {
|
const filter = computed(() => {
|
||||||
fields: ['smsFk'],
|
return {
|
||||||
include: {
|
fields: ['smsFk'],
|
||||||
relation: 'sms',
|
include: {
|
||||||
scope: {
|
relation: 'sms',
|
||||||
fields: [
|
scope: {
|
||||||
'senderFk',
|
fields: [
|
||||||
'sender',
|
'senderFk',
|
||||||
'destination',
|
'sender',
|
||||||
'message',
|
'destination',
|
||||||
'statusCode',
|
'message',
|
||||||
'status',
|
'statusCode',
|
||||||
'created',
|
'status',
|
||||||
],
|
'created',
|
||||||
include: {
|
],
|
||||||
relation: 'sender',
|
include: {
|
||||||
scope: {
|
relation: 'sender',
|
||||||
fields: ['name'],
|
scope: {
|
||||||
|
fields: ['name'],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
...{ where: $props.where },
|
||||||
};
|
};
|
||||||
|
});
|
||||||
onBeforeMount(() => (filter.where = $props.where));
|
|
||||||
|
|
||||||
function formatNumber(number) {
|
function formatNumber(number) {
|
||||||
if (number.length <= 10) return number;
|
if (number.length <= 10) return number;
|
||||||
|
|
|
@ -90,6 +90,9 @@ globals:
|
||||||
salesPerson: SalesPerson
|
salesPerson: SalesPerson
|
||||||
send: Send
|
send: Send
|
||||||
code: Code
|
code: Code
|
||||||
|
since: Since
|
||||||
|
from: From
|
||||||
|
to: To
|
||||||
pageTitles:
|
pageTitles:
|
||||||
logIn: Login
|
logIn: Login
|
||||||
summary: Summary
|
summary: Summary
|
||||||
|
|
|
@ -90,6 +90,9 @@ globals:
|
||||||
salesPerson: Comercial
|
salesPerson: Comercial
|
||||||
send: Enviar
|
send: Enviar
|
||||||
code: Código
|
code: Código
|
||||||
|
since: Desde
|
||||||
|
from: Desde
|
||||||
|
to: Hasta
|
||||||
pageTitles:
|
pageTitles:
|
||||||
logIn: Inicio de sesión
|
logIn: Inicio de sesión
|
||||||
summary: Resumen
|
summary: Resumen
|
||||||
|
@ -697,8 +700,6 @@ invoiceOut:
|
||||||
percentageText: '{getPercentage}% {getAddressNumber} de {getNAddresses}'
|
percentageText: '{getPercentage}% {getAddressNumber} de {getNAddresses}'
|
||||||
pdfsNumberText: '{nPdfs} de {totalPdfs} PDFs'
|
pdfsNumberText: '{nPdfs} de {totalPdfs} PDFs'
|
||||||
negativeBases:
|
negativeBases:
|
||||||
from: Desde
|
|
||||||
to: Hasta
|
|
||||||
company: Empresa
|
company: Empresa
|
||||||
country: País
|
country: País
|
||||||
clientId: Id cliente
|
clientId: Id cliente
|
||||||
|
@ -1240,8 +1241,6 @@ components:
|
||||||
# LatestBuysFilter
|
# LatestBuysFilter
|
||||||
salesPersonFk: Comprador
|
salesPersonFk: Comprador
|
||||||
supplierFk: Proveedor
|
supplierFk: Proveedor
|
||||||
from: Desde
|
|
||||||
to: Hasta
|
|
||||||
active: Activo
|
active: Activo
|
||||||
visible: Visible
|
visible: Visible
|
||||||
floramondo: Floramondo
|
floramondo: Floramondo
|
||||||
|
|
|
@ -85,7 +85,7 @@ const fetchMailAliases = async () => {
|
||||||
paginateRef.value.fetch();
|
paginateRef.value.fetch();
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAccountData = async () => {
|
const getAccountData = async (reload = true) => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
hasAccount.value = await fetchAccountExistence();
|
hasAccount.value = await fetchAccountExistence();
|
||||||
if (!hasAccount.value) {
|
if (!hasAccount.value) {
|
||||||
|
@ -93,7 +93,7 @@ const getAccountData = async () => {
|
||||||
store.data = [];
|
store.data = [];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await fetchMailAliases();
|
reload && (await fetchMailAliases());
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -102,13 +102,11 @@ const openCreateMailAliasForm = () => createMailAliasDialogRef.value.show();
|
||||||
watch(
|
watch(
|
||||||
() => route.params.id,
|
() => route.params.id,
|
||||||
() => {
|
() => {
|
||||||
store.url = urlPath;
|
|
||||||
store.filter = filter.value;
|
|
||||||
getAccountData();
|
getAccountData();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(async () => await getAccountData());
|
onMounted(async () => await getAccountData(false));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -1,262 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onBeforeMount, ref } from 'vue';
|
import VnLog from 'src/components/common/VnLog.vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { useRoute } from 'vue-router';
|
|
||||||
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
|
||||||
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
|
||||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
const route = useRoute();
|
|
||||||
const stateStore = useStateStore();
|
|
||||||
|
|
||||||
const clientLogs = ref(null);
|
|
||||||
const urlClientLogsEditors = ref(null);
|
|
||||||
const urlClientLogsModels = ref(null);
|
|
||||||
const clientLogsModelsOptions = ref([]);
|
|
||||||
const clientLogsOptions = ref([]);
|
|
||||||
const clientLogsEditorsOptions = ref([]);
|
|
||||||
const radioButtonValue = ref('all');
|
|
||||||
const insert = ref(false);
|
|
||||||
const update = ref(false);
|
|
||||||
const deletes = ref(false);
|
|
||||||
const select = ref(false);
|
|
||||||
const neq = ref(null);
|
|
||||||
const inq = ref([]);
|
|
||||||
|
|
||||||
const filterClientLogs = {
|
|
||||||
fields: [
|
|
||||||
'id',
|
|
||||||
'originFk',
|
|
||||||
'userFk',
|
|
||||||
'action',
|
|
||||||
'changedModel',
|
|
||||||
'oldInstance',
|
|
||||||
'newInstance',
|
|
||||||
'creationDate',
|
|
||||||
'changedModel',
|
|
||||||
'changedModelId',
|
|
||||||
'changedModelValue',
|
|
||||||
'description',
|
|
||||||
],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
relation: 'user',
|
|
||||||
scope: {
|
|
||||||
fields: ['nickname', 'name', 'image'],
|
|
||||||
include: { relation: 'worker', scope: { fields: ['id'] } },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
order: ['creationDate DESC', 'id DESC'],
|
|
||||||
limit: 20,
|
|
||||||
};
|
|
||||||
const filterClientLogsEditors = {
|
|
||||||
fields: ['id', 'nickname', 'name', 'image'],
|
|
||||||
order: 'nickname',
|
|
||||||
limit: 30,
|
|
||||||
};
|
|
||||||
const filterClientLogsModels = { order: ['changedModel'] };
|
|
||||||
const urlBase = `ClientLogs/${route.params.id}`;
|
|
||||||
|
|
||||||
onBeforeMount(() => {
|
|
||||||
stateStore.rightDrawer = true;
|
|
||||||
filterClientLogs.where = {
|
|
||||||
and: [
|
|
||||||
{ originFk: `${route.params.id}` },
|
|
||||||
{ userFk: { neq: radioButtonValue.value } },
|
|
||||||
{ action: { inq: inq.value } },
|
|
||||||
],
|
|
||||||
};
|
|
||||||
urlClientLogsEditors.value = `${urlBase}/editors`;
|
|
||||||
urlClientLogsModels.value = `${urlBase}/models`;
|
|
||||||
});
|
|
||||||
|
|
||||||
const getClientLogs = async (value, status) => {
|
|
||||||
if (status === 'neq') {
|
|
||||||
neq.value = value;
|
|
||||||
} else {
|
|
||||||
setInq(value, status);
|
|
||||||
}
|
|
||||||
filterClientLogs.where = {
|
|
||||||
and: [
|
|
||||||
{ originFk: `${route.params.id}` },
|
|
||||||
{ userFk: { neq: neq.value } },
|
|
||||||
{ action: { inq: inq.value } },
|
|
||||||
],
|
|
||||||
};
|
|
||||||
clientLogs.value?.fetch();
|
|
||||||
};
|
|
||||||
|
|
||||||
const setInq = (value, status) => {
|
|
||||||
if (status) {
|
|
||||||
if (!inq.value.includes(value)) {
|
|
||||||
inq.value.push(value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
inq.value = inq.value.filter((item) => item !== value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
<VnLog model="Client" />
|
||||||
:filter="filterClientLogs"
|
|
||||||
@on-fetch="(data) => (clientLogsOptions = data)"
|
|
||||||
auto-load
|
|
||||||
url="ClientLogs"
|
|
||||||
ref="clientLogs"
|
|
||||||
/>
|
|
||||||
<FetchData
|
|
||||||
:filter="filterClientLogsEditors"
|
|
||||||
@on-fetch="(data) => (clientLogsEditorsOptions = data)"
|
|
||||||
auto-load
|
|
||||||
:url="urlClientLogsEditors"
|
|
||||||
/>
|
|
||||||
<FetchData
|
|
||||||
:filter="filterClientLogsModels"
|
|
||||||
@on-fetch="(data) => (clientLogsModelsOptions = data)"
|
|
||||||
auto-load
|
|
||||||
:url="urlClientLogsModels"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<h5 class="flex justify-center color-vn-label">
|
|
||||||
{{ t('globals.noResults') }}
|
|
||||||
</h5>
|
|
||||||
|
|
||||||
<QDrawer :width="256" show-if-above side="right" v-model="stateStore.rightDrawer">
|
|
||||||
<div class="q-mt-sm q-px-md">
|
|
||||||
<VnInput :label="t('Search')" clearable>
|
|
||||||
<template #append>
|
|
||||||
<QIcon name="info" class="cursor-pointer">
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('Search by id or concept') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</template>
|
|
||||||
</VnInput>
|
|
||||||
<VnSelect
|
|
||||||
:label="t('Entity')"
|
|
||||||
:options="[]"
|
|
||||||
class="q-mt-md"
|
|
||||||
hide-selected
|
|
||||||
option-label="name"
|
|
||||||
option-value="id"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div class="q-mt-lg">
|
|
||||||
<QRadio
|
|
||||||
:dark="true"
|
|
||||||
:label="t('All')"
|
|
||||||
@update:model-value="getClientLogs($event, 'neq')"
|
|
||||||
dense
|
|
||||||
v-model="radioButtonValue"
|
|
||||||
val="all"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="q-mt-md">
|
|
||||||
<QRadio
|
|
||||||
:dark="true"
|
|
||||||
:label="t('User')"
|
|
||||||
@update:model-value="getClientLogs($event, 'neq')"
|
|
||||||
dense
|
|
||||||
v-model="radioButtonValue"
|
|
||||||
val="user"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="q-mt-md">
|
|
||||||
<QRadio
|
|
||||||
:dark="true"
|
|
||||||
:label="t('System')"
|
|
||||||
@update:model-value="getClientLogs($event, 'neq')"
|
|
||||||
dense
|
|
||||||
v-model="radioButtonValue"
|
|
||||||
val="system"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<VnSelect
|
|
||||||
:label="t('User')"
|
|
||||||
:options="[]"
|
|
||||||
class="q-mt-sm"
|
|
||||||
hide-selected
|
|
||||||
option-label="name"
|
|
||||||
option-value="id"
|
|
||||||
/>
|
|
||||||
<VnInput :label="t('Changes')" clearable class="q-mt-sm">
|
|
||||||
<template #append>
|
|
||||||
<QIcon name="info" class="cursor-pointer">
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('Search by changes') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</template>
|
|
||||||
</VnInput>
|
|
||||||
|
|
||||||
<div class="q-mt-md">
|
|
||||||
<QCheckbox
|
|
||||||
:label="t('Creates')"
|
|
||||||
@update:model-value="getClientLogs('insert', $event)"
|
|
||||||
v-model="insert"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<QCheckbox
|
|
||||||
:label="t('Edits')"
|
|
||||||
@update:model-value="getClientLogs('update', $event)"
|
|
||||||
v-model="update"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<QCheckbox
|
|
||||||
:label="t('Deletes')"
|
|
||||||
@update:model-value="getClientLogs('delete', $event)"
|
|
||||||
v-model="deletes"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<QCheckbox
|
|
||||||
:label="t('Accesses')"
|
|
||||||
@update:model-value="getClientLogs('select', $event)"
|
|
||||||
v-model="select"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<VnInputDate :label="t('Date')" class="q-mt-sm" />
|
|
||||||
<VnInput :label="t('To')" clearable class="q-mt-md" />
|
|
||||||
</div>
|
|
||||||
</QDrawer>
|
|
||||||
|
|
||||||
<QPageSticky
|
|
||||||
:offset="[18, 18]"
|
|
||||||
v-if="radioButtonValue !== 'all' || insert || update || deletes || select"
|
|
||||||
>
|
|
||||||
<QBtn color="primary" fab icon="filter_alt_off" />
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('Quit filter') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QPageSticky>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
|
||||||
es:
|
|
||||||
Search: Buscar
|
|
||||||
Search by id or concept: xxx
|
|
||||||
Entity: Entidad
|
|
||||||
All: Todo
|
|
||||||
User: Usuario
|
|
||||||
System: Sistema
|
|
||||||
Changes: Cambios
|
|
||||||
Search by changes: xxx
|
|
||||||
Creates: Crea
|
|
||||||
Edits: Modifica
|
|
||||||
Deletes: Elimina
|
|
||||||
Accesses: Accede
|
|
||||||
Date: Fecha
|
|
||||||
To: Hasta
|
|
||||||
Quit filter: Quitar filtro
|
|
||||||
</i18n>
|
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { computed } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import VnNotes from 'src/components/ui/VnNotes.vue';
|
import VnNotes from 'src/components/ui/VnNotes.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
const noteFilter = {
|
const noteFilter = computed(() => {
|
||||||
order: 'created DESC',
|
return {
|
||||||
where: {
|
order: 'created DESC',
|
||||||
clientFk: `${route.params.id}`,
|
where: {
|
||||||
},
|
clientFk: `${route.params.id}`,
|
||||||
};
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -1,146 +1,107 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import axios from 'axios';
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
import { toCurrency, toDate } from 'src/filters';
|
import { toCurrency, toDate } from 'src/filters';
|
||||||
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
import VnTable from 'components/VnTable/VnTable.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const tableRef = ref();
|
||||||
const rows = ref([]);
|
const filter = computed(() => {
|
||||||
|
return {
|
||||||
const filter = {
|
where: { clientFk: route.params.id },
|
||||||
where: { clientFk: route.params.id },
|
};
|
||||||
order: ['started DESC'],
|
});
|
||||||
limit: 20,
|
const componentColumn = (type) => {
|
||||||
|
return {
|
||||||
|
columnFilter: {
|
||||||
|
component: type,
|
||||||
|
},
|
||||||
|
columnCreate: {
|
||||||
|
component: type,
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const tableColumnComponents = {
|
|
||||||
since: {
|
|
||||||
component: 'span',
|
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
|
||||||
to: {
|
|
||||||
component: 'span',
|
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
|
||||||
amount: {
|
|
||||||
component: 'span',
|
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
|
||||||
period: {
|
|
||||||
component: 'span',
|
|
||||||
props: () => {},
|
|
||||||
event: () => {},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
field: 'started',
|
label: t('globals.since'),
|
||||||
label: t('Since'),
|
name: 'started',
|
||||||
name: 'since',
|
format: ({ started }) => toDate(started),
|
||||||
format: (value) => toDate(value),
|
create: true,
|
||||||
|
...componentColumn('date'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
field: 'finished',
|
name: 'finished',
|
||||||
label: t('To'),
|
label: t('globals.to'),
|
||||||
name: 'to',
|
format: ({ finished }) => toDate(finished),
|
||||||
format: (value) => toDate(value),
|
create: true,
|
||||||
|
...componentColumn('date'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
field: 'amount',
|
|
||||||
label: t('Amount'),
|
|
||||||
name: 'amount',
|
name: 'amount',
|
||||||
format: (value) => toCurrency(value),
|
label: t('globals.amount'),
|
||||||
|
format: ({ amount }) => toCurrency(amount),
|
||||||
|
create: true,
|
||||||
|
...componentColumn('number'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
field: 'period',
|
|
||||||
label: t('Period'),
|
|
||||||
name: 'period',
|
name: 'period',
|
||||||
|
label: t('Period'),
|
||||||
|
create: true,
|
||||||
|
...componentColumn('number'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'tableActions',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
title: t('Finish that recovery period'),
|
||||||
|
icon: 'lock',
|
||||||
|
show: (row) => !row.finished,
|
||||||
|
action: ({ id }) => setFinished(id),
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const toCustomerRecoverieCreate = () => {
|
function setFinished(id) {
|
||||||
router.push({ name: 'CustomerRecoverieCreate' });
|
axios.patch(`Recoveries/${id}`, { finished: Date.vnNow() });
|
||||||
};
|
tableRef.value.reload();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
<VnTable
|
||||||
:filter="filter"
|
ref="tableRef"
|
||||||
@on-fetch="(data) => (rows = data)"
|
data-key="Recoveries"
|
||||||
auto-load
|
|
||||||
url="Recoveries"
|
url="Recoveries"
|
||||||
|
search-url="recoveries"
|
||||||
|
:filter="filter"
|
||||||
|
order="started DESC"
|
||||||
|
:columns="columns"
|
||||||
|
:use-model="true"
|
||||||
|
:right-search="false"
|
||||||
|
:create="{
|
||||||
|
urlCreate: 'Recoveries',
|
||||||
|
title: 'New recovery',
|
||||||
|
onDataSaved: () => tableRef.reload(),
|
||||||
|
formInitialData: { clientFk: route.params.id, started: Date.vnNew() },
|
||||||
|
}"
|
||||||
|
auto-load
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="full-width flex justify-center">
|
|
||||||
<QPage class="card-width q-pa-lg">
|
|
||||||
<QTable
|
|
||||||
:columns="columns"
|
|
||||||
:no-data-label="t('globals.noResults')"
|
|
||||||
:pagination="{ rowsPerPage: 12 }"
|
|
||||||
:rows="rows"
|
|
||||||
class="full-width q-mt-md"
|
|
||||||
row-key="id"
|
|
||||||
>
|
|
||||||
<template #body-cell="props">
|
|
||||||
<QTd :props="props">
|
|
||||||
<QTr :props="props" class="cursor-pointer">
|
|
||||||
<component
|
|
||||||
:is="tableColumnComponents[props.col.name].component"
|
|
||||||
class="col-content"
|
|
||||||
v-bind="
|
|
||||||
tableColumnComponents[props.col.name].props(props)
|
|
||||||
"
|
|
||||||
@click="
|
|
||||||
tableColumnComponents[props.col.name].event(props)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{ props.value }}
|
|
||||||
</component>
|
|
||||||
</QTr>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
</QTable>
|
|
||||||
</QPage>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<QPageSticky :offset="[18, 18]">
|
|
||||||
<QBtn @click.stop="toCustomerRecoverieCreate()" color="primary" fab icon="add" />
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('New recoverie') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QPageSticky>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.consignees-card {
|
|
||||||
border: 2px solid var(--vn-accent-color);
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label-color {
|
|
||||||
color: var(--vn-label-color);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Since: Desde
|
|
||||||
To: Hasta
|
|
||||||
Amount: Importe
|
|
||||||
Period: Periodo
|
Period: Periodo
|
||||||
New recoverie: Nuevo recobro
|
New recovery: Nuevo recobro
|
||||||
|
Finish that recovery period: Terminar recobro
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { computed } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import VnSms from 'src/components/ui/VnSms.vue';
|
import VnSms from 'src/components/ui/VnSms.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const id = route.params.id;
|
const where = computed(() => {
|
||||||
|
return {
|
||||||
const where = {
|
clientFk: route.params.id,
|
||||||
clientFk: id,
|
ticketFk: null,
|
||||||
ticketFk: null,
|
};
|
||||||
};
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="column items-center">
|
<VnSms url="clientSms" :where="where" />
|
||||||
<VnSms url="clientSms" :where="where" />
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -2,164 +2,81 @@
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
|
|
||||||
import { useValidator } from 'src/composables/useValidator';
|
|
||||||
import useNotify from 'src/composables/useNotify';
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
|
||||||
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import CustomerChangePassword from 'src/pages/Customer/components/CustomerChangePassword.vue';
|
import CustomerChangePassword from 'src/pages/Customer/components/CustomerChangePassword.vue';
|
||||||
|
import FormModel from 'components/FormModel.vue';
|
||||||
|
|
||||||
const { notify } = useNotify();
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { validate } = useValidator();
|
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const stateStore = useStateStore();
|
|
||||||
|
|
||||||
const active = ref(false);
|
|
||||||
const canChangePassword = ref(0);
|
const canChangePassword = ref(0);
|
||||||
const email = ref(null);
|
|
||||||
const isLoading = ref(false);
|
|
||||||
const name = ref(null);
|
|
||||||
const usersPreviewRef = ref(null);
|
|
||||||
const user = ref([]);
|
|
||||||
|
|
||||||
const dataChanges = computed(() => {
|
const filter = computed(() => {
|
||||||
return (
|
return {
|
||||||
user.value.active !== active.value ||
|
fields: ['active', 'email', 'name'],
|
||||||
user.value.email !== email.value ||
|
where: { id: route.params.id },
|
||||||
user.value.name !== name.value
|
};
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const filter = { where: { id: `${route.params.id}` } };
|
|
||||||
|
|
||||||
const showChangePasswordDialog = () => {
|
const showChangePasswordDialog = () => {
|
||||||
quasar.dialog({
|
quasar.dialog({
|
||||||
component: CustomerChangePassword,
|
component: CustomerChangePassword,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
id: route.params.id,
|
id: route.params.id,
|
||||||
promise: usersPreviewRef.value.fetch(),
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const setInitialData = () => {
|
async function hasCustomerRole() {
|
||||||
if (user.value.length) {
|
const { data } = await axios(`Clients/${route.params.id}/hasCustomerRole`);
|
||||||
active.value = user.value[0].active;
|
canChangePassword.value = data;
|
||||||
email.value = user.value[0].email;
|
}
|
||||||
name.value = user.value[0].name;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSubmit = async () => {
|
|
||||||
isLoading.value = true;
|
|
||||||
|
|
||||||
const payload = {
|
|
||||||
active: active.value,
|
|
||||||
email: email.value,
|
|
||||||
name: name.value,
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
await axios.patch(`Clients/${route.params.id}/updateUser`, payload);
|
|
||||||
notify('globals.dataSaved', 'positive');
|
|
||||||
if (usersPreviewRef.value) usersPreviewRef.value.fetch();
|
|
||||||
} catch (error) {
|
|
||||||
notify('errors.create', 'negative');
|
|
||||||
} finally {
|
|
||||||
isLoading.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
<FormModel
|
||||||
|
url="VnUsers/preview"
|
||||||
|
:url-update="`Clients/${route.params.id}/updateUser`"
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
@on-fetch="
|
model="webAccess"
|
||||||
(data) => {
|
:mapper="
|
||||||
user = data;
|
({ active, name, email }) => {
|
||||||
setInitialData();
|
return {
|
||||||
|
active,
|
||||||
|
name,
|
||||||
|
email,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
|
@on-fetch="hasCustomerRole()"
|
||||||
auto-load
|
auto-load
|
||||||
ref="usersPreviewRef"
|
>
|
||||||
url="VnUsers/preview"
|
<template #form="{ data, validate }">
|
||||||
/>
|
<QCheckbox :label="t('Enable web access')" v-model="data.active" />
|
||||||
<FetchData
|
<VnInput :label="t('User')" clearable v-model="data.name" />
|
||||||
:url="`Clients/${route.params.id}/hasCustomerRole`"
|
<VnInput
|
||||||
@on-fetch="(data) => (canChangePassword = data)"
|
:label="t('Recovery email')"
|
||||||
auto-load
|
:rules="validate('client.email')"
|
||||||
/>
|
clearable
|
||||||
|
type="email"
|
||||||
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
|
v-model="data.email"
|
||||||
<QBtnGroup push class="q-gutter-x-sm">
|
class="q-mt-sm"
|
||||||
<QBtn
|
:info="t('This email is used for user to regain access their account')"
|
||||||
:disabled="isLoading"
|
|
||||||
:label="t('globals.reset')"
|
|
||||||
:loading="isLoading"
|
|
||||||
@click="setInitialData"
|
|
||||||
color="primary"
|
|
||||||
flat
|
|
||||||
icon="restart_alt"
|
|
||||||
type="reset"
|
|
||||||
/>
|
/>
|
||||||
|
</template>
|
||||||
|
<template #moreActions>
|
||||||
<QBtn
|
<QBtn
|
||||||
:disabled="isLoading"
|
|
||||||
:label="t('Change password')"
|
:label="t('Change password')"
|
||||||
:loading="isLoading"
|
|
||||||
@click.stop="showChangePasswordDialog()"
|
|
||||||
color="primary"
|
color="primary"
|
||||||
flat
|
|
||||||
icon="edit"
|
icon="edit"
|
||||||
v-if="canChangePassword"
|
:disable="!canChangePassword"
|
||||||
|
@click="showChangePasswordDialog()"
|
||||||
/>
|
/>
|
||||||
<QBtn
|
</template>
|
||||||
:disabled="isLoading || !dataChanges"
|
</FormModel>
|
||||||
:label="t('globals.save')"
|
|
||||||
:loading="isLoading"
|
|
||||||
@click="onSubmit"
|
|
||||||
color="primary"
|
|
||||||
icon="save"
|
|
||||||
/>
|
|
||||||
</QBtnGroup>
|
|
||||||
</Teleport>
|
|
||||||
|
|
||||||
<div class="full-width flex justify-center">
|
|
||||||
<QCard class="card-width q-pa-lg">
|
|
||||||
<QCardSection>
|
|
||||||
<QForm>
|
|
||||||
<QCheckbox :label="t('Enable web access')" v-model="active" />
|
|
||||||
|
|
||||||
<div class="q-px-sm">
|
|
||||||
<VnInput :label="t('User')" clearable v-model="name" />
|
|
||||||
<VnInput
|
|
||||||
:label="t('Recovery email')"
|
|
||||||
:rules="validate('client.email')"
|
|
||||||
clearable
|
|
||||||
type="email"
|
|
||||||
v-model="email"
|
|
||||||
class="q-mt-sm"
|
|
||||||
>
|
|
||||||
<template #append>
|
|
||||||
<QIcon name="info" class="cursor-pointer">
|
|
||||||
<QTooltip>{{
|
|
||||||
t(
|
|
||||||
'This email is used for user to regain access their account'
|
|
||||||
)
|
|
||||||
}}</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</template>
|
|
||||||
</VnInput>
|
|
||||||
</div>
|
|
||||||
</QForm>
|
|
||||||
</QCardSection>
|
|
||||||
</QCard>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
|
|
|
@ -226,31 +226,13 @@ export default {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'recoveries',
|
path: 'recoveries',
|
||||||
name: 'RecoveriesCard',
|
name: 'CustomerRecoveries',
|
||||||
redirect: { name: 'CustomerRecoveries' },
|
meta: {
|
||||||
children: [
|
title: 'recoveries',
|
||||||
{
|
icon: 'vn:recovery',
|
||||||
path: '',
|
},
|
||||||
name: 'CustomerRecoveries',
|
component: () =>
|
||||||
meta: {
|
import('src/pages/Customer/Card/CustomerRecoveries.vue'),
|
||||||
title: 'recoveries',
|
|
||||||
icon: 'vn:recovery',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import('src/pages/Customer/Card/CustomerRecoveries.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
name: 'CustomerRecoverieCreate',
|
|
||||||
meta: {
|
|
||||||
title: 'recoverie-create',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import(
|
|
||||||
'src/pages/Customer/components/CustomerRecoverieCreate.vue'
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'web-access',
|
path: 'web-access',
|
||||||
|
|
Loading…
Reference in New Issue