8197-VnCardMain #1044
|
@ -92,15 +92,15 @@ function findMatches(search, item) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function addChildren(module, route, parent) {
|
function addChildren(module, route, parent) {
|
||||||
if (route.menus) {
|
const menus = route?.meta?.menu ?? route?.menus?.[props.source]; //backwards compatible
|
||||||
const mainMenus = route.menus[props.source];
|
if (!menus) return;
|
||||||
const matches = findMatches(mainMenus, route);
|
|
||||||
|
const matches = findMatches(menus, route);
|
||||||
|
|
||||||
for (const child of matches) {
|
for (const child of matches) {
|
||||||
navigation.addMenuItem(module, child, parent);
|
navigation.addMenuItem(module, child, parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function getRoutes() {
|
function getRoutes() {
|
||||||
if (props.source === 'main') {
|
if (props.source === 'main') {
|
||||||
|
@ -122,16 +122,26 @@ function getRoutes() {
|
||||||
if (props.source === 'card') {
|
if (props.source === 'card') {
|
||||||
const currentRoute = route.matched[1];
|
const currentRoute = route.matched[1];
|
||||||
const currentModule = toLowerCamel(currentRoute.name);
|
const currentModule = toLowerCamel(currentRoute.name);
|
||||||
const moduleDef = routes.find(
|
let moduleDef = routes.find(
|
||||||
(route) => toLowerCamel(route.name) === currentModule
|
(route) => toLowerCamel(route.name) === currentModule
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!moduleDef) return;
|
if (!moduleDef) return;
|
||||||
|
if (!moduleDef?.menus) moduleDef = betaGetRoutes();
|
||||||
addChildren(currentModule, moduleDef, items.value);
|
addChildren(currentModule, moduleDef, items.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function betaGetRoutes() {
|
||||||
|
let menuRoute;
|
||||||
|
let index = route.matched.length - 1;
|
||||||
|
while (!menuRoute && index > 0) {
|
||||||
|
if (route.matched[index]?.meta?.menu) menuRoute = route.matched[index];
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
return menuRoute;
|
||||||
|
}
|
||||||
|
|
||||||
async function togglePinned(item, event) {
|
async function togglePinned(item, event) {
|
||||||
if (event.defaultPrevented) return;
|
if (event.defaultPrevented) return;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
|
@ -59,6 +59,7 @@ const pinnedModulesRef = ref();
|
||||||
'no-visible': !stateQuery.isLoading().value,
|
'no-visible': !stateQuery.isLoading().value,
|
||||||
}"
|
}"
|
||||||
size="xs"
|
size="xs"
|
||||||
|
data-cy="loading-spinner"
|
||||||
/>
|
/>
|
||||||
<QSpace />
|
<QSpace />
|
||||||
<div id="searchbar" class="searchbar"></div>
|
<div id="searchbar" class="searchbar"></div>
|
||||||
|
|
|
@ -32,7 +32,10 @@ const $props = defineProps({
|
||||||
defineExpose({ addFilter, props: $props });
|
defineExpose({ addFilter, props: $props });
|
||||||
|
|
||||||
const model = defineModel(undefined, { required: true });
|
const model = defineModel(undefined, { required: true });
|
||||||
const arrayData = useArrayData($props.dataKey, { searchUrl: $props.searchUrl });
|
const arrayData = useArrayData(
|
||||||
|
$props.dataKey,
|
||||||
|
$props.searchUrl ? { searchUrl: $props.searchUrl } : null
|
||||||
|
);
|
||||||
const columnFilter = computed(() => $props.column?.columnFilter);
|
const columnFilter = computed(() => $props.column?.columnFilter);
|
||||||
|
|
||||||
const updateEvent = { 'update:modelValue': addFilter };
|
const updateEvent = { 'update:modelValue': addFilter };
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onBeforeMount, onMounted, computed, watch } from 'vue';
|
import { ref, onBeforeMount, onMounted, computed, watch, useAttrs } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
|
import { useFilterParams } from 'src/composables/useFilterParams';
|
||||||
|
|
||||||
import CrudModel from 'src/components/CrudModel.vue';
|
import CrudModel from 'src/components/CrudModel.vue';
|
||||||
import FormModelPopup from 'components/FormModelPopup.vue';
|
import FormModelPopup from 'components/FormModelPopup.vue';
|
||||||
|
|
||||||
import VnFilterPanel from 'components/ui/VnFilterPanel.vue';
|
|
||||||
import VnTableColumn from 'components/VnTable/VnColumn.vue';
|
import VnTableColumn from 'components/VnTable/VnColumn.vue';
|
||||||
import VnFilter from 'components/VnTable/VnFilter.vue';
|
import VnFilter from 'components/VnTable/VnFilter.vue';
|
||||||
import VnTableChip from 'components/VnTable/VnChip.vue';
|
import VnTableChip from 'components/VnTable/VnChip.vue';
|
||||||
import VnVisibleColumn from 'src/components/VnTable/VnVisibleColumn.vue';
|
import VnVisibleColumn from 'src/components/VnTable/VnVisibleColumn.vue';
|
||||||
import VnLv from 'components/ui/VnLv.vue';
|
import VnLv from 'components/ui/VnLv.vue';
|
||||||
import VnTableOrder from 'src/components/VnTable/VnOrder.vue';
|
import VnTableOrder from 'src/components/VnTable/VnOrder.vue';
|
||||||
|
import VnTableFilter from './VnTableFilter.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
columns: {
|
columns: {
|
||||||
|
@ -33,6 +34,10 @@ const $props = defineProps({
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
rightSearchIcon: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
rowClick: {
|
rowClick: {
|
||||||
type: [Function, Boolean],
|
type: [Function, Boolean],
|
||||||
default: null,
|
default: null,
|
||||||
|
@ -101,10 +106,6 @@ const $props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
default: '90vh',
|
default: '90vh',
|
||||||
},
|
},
|
||||||
chipLocale: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
footer: {
|
footer: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
|
@ -119,22 +120,21 @@ const stateStore = useStateStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
|
const $attrs = useAttrs();
|
||||||
|
|
||||||
const CARD_MODE = 'card';
|
const CARD_MODE = 'card';
|
||||||
const TABLE_MODE = 'table';
|
const TABLE_MODE = 'table';
|
||||||
const mode = ref(CARD_MODE);
|
const mode = ref(CARD_MODE);
|
||||||
const selected = ref([]);
|
const selected = ref([]);
|
||||||
const hasParams = ref(false);
|
const hasParams = ref(false);
|
||||||
const routeQuery = JSON.parse(route?.query[$props.searchUrl] ?? '{}');
|
|
||||||
const params = ref({ ...routeQuery, ...routeQuery.filter?.where });
|
|
||||||
const orders = ref(parseOrder(routeQuery.filter?.order));
|
|
||||||
const CrudModelRef = ref({});
|
const CrudModelRef = ref({});
|
||||||
const showForm = ref(false);
|
const showForm = ref(false);
|
||||||
const splittedColumns = ref({ columns: [] });
|
const splittedColumns = ref({ columns: [] });
|
||||||
const columnsVisibilitySkipped = ref();
|
const columnsVisibilitySkipped = ref();
|
||||||
const createForm = ref();
|
const createForm = ref();
|
||||||
const tableFilterRef = ref([]);
|
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
|
const params = ref(useFilterParams($attrs['data-key']).params);
|
||||||
|
const orders = ref(useFilterParams($attrs['data-key']).orders);
|
||||||
|
|
||||||
const tableModes = [
|
const tableModes = [
|
||||||
{
|
{
|
||||||
|
@ -183,41 +183,8 @@ watch(
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
|
||||||
() => route.query[$props.searchUrl],
|
|
||||||
(val) => setUserParams(val),
|
|
||||||
{ immediate: true, deep: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
const isTableMode = computed(() => mode.value == TABLE_MODE);
|
const isTableMode = computed(() => mode.value == TABLE_MODE);
|
||||||
|
const showRightIcon = computed(() => $props.rightSearch || $props.rightSearchIcon);
|
||||||
function setUserParams(watchedParams, watchedOrder) {
|
|
||||||
if (!watchedParams) return;
|
|
||||||
|
|
||||||
if (typeof watchedParams == 'string') watchedParams = JSON.parse(watchedParams);
|
|
||||||
const filter =
|
|
||||||
typeof watchedParams?.filter == 'string'
|
|
||||||
? JSON.parse(watchedParams?.filter ?? '{}')
|
|
||||||
: watchedParams?.filter;
|
|
||||||
const where = filter?.where;
|
|
||||||
const order = watchedOrder ?? filter?.order;
|
|
||||||
|
|
||||||
watchedParams = { ...watchedParams, ...where };
|
|
||||||
delete watchedParams.filter;
|
|
||||||
delete params.value?.filter;
|
|
||||||
params.value = { ...params.value, ...sanitizer(watchedParams) };
|
|
||||||
orders.value = parseOrder(order);
|
|
||||||
}
|
|
||||||
|
|
||||||
function sanitizer(params) {
|
|
||||||
for (const [key, value] of Object.entries(params)) {
|
|
||||||
if (value && typeof value == 'object') {
|
|
||||||
const param = Object.values(value)[0];
|
|
||||||
if (typeof param == 'string') params[key] = param.replaceAll('%', '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
function splitColumns(columns) {
|
function splitColumns(columns) {
|
||||||
splittedColumns.value = {
|
splittedColumns.value = {
|
||||||
|
@ -298,17 +265,6 @@ function getColAlign(col) {
|
||||||
return 'text-' + (col.align ?? 'left');
|
return 'text-' + (col.align ?? 'left');
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseOrder(urlOrders) {
|
|
||||||
const orderObject = {};
|
|
||||||
if (!urlOrders) return orderObject;
|
|
||||||
if (typeof urlOrders == 'string') urlOrders = [urlOrders];
|
|
||||||
for (const [index, orders] of urlOrders.entries()) {
|
|
||||||
const [name, direction] = orders.split(' ');
|
|
||||||
orderObject[name] = { direction, index: index + 1 };
|
|
||||||
}
|
|
||||||
return orderObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
|
const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
|
||||||
defineExpose({
|
defineExpose({
|
||||||
create: createForm,
|
create: createForm,
|
||||||
|
@ -357,61 +313,7 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
|
||||||
show-if-above
|
show-if-above
|
||||||
>
|
>
|
||||||
<QScrollArea class="fit">
|
<QScrollArea class="fit">
|
||||||
<VnFilterPanel
|
<VnTableFilter :data-key="$attrs['data-key']" :columns="columns" />
|
||||||
:data-key="$attrs['data-key']"
|
|
||||||
:search-button="true"
|
|
||||||
v-model="params"
|
|
||||||
:search-url="searchUrl"
|
|
||||||
:redirect="!!redirect"
|
|
||||||
@set-user-params="setUserParams"
|
|
||||||
:disable-submit-event="true"
|
|
||||||
@remove="
|
|
||||||
(key) =>
|
|
||||||
tableFilterRef
|
|
||||||
.find((f) => f.props?.column.name == key)
|
|
||||||
?.addFilter()
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<template #body>
|
|
||||||
<div
|
|
||||||
class="row no-wrap flex-center"
|
|
||||||
v-for="col of splittedColumns.columns.filter(
|
|
||||||
(c) => c.columnFilter ?? true
|
|
||||||
)"
|
|
||||||
:key="col.id"
|
|
||||||
>
|
|
||||||
<VnFilter
|
|
||||||
ref="tableFilterRef"
|
|
||||||
:column="col"
|
|
||||||
:data-key="$attrs['data-key']"
|
|
||||||
v-model="params[columnName(col)]"
|
|
||||||
:search-url="searchUrl"
|
|
||||||
/>
|
|
||||||
<VnTableOrder
|
|
||||||
v-if="
|
|
||||||
col?.columnFilter !== false &&
|
|
||||||
col?.name !== 'tableActions'
|
|
||||||
"
|
|
||||||
v-model="orders[col.orderBy ?? col.name]"
|
|
||||||
:name="col.orderBy ?? col.name"
|
|
||||||
:data-key="$attrs['data-key']"
|
|
||||||
:search-url="searchUrl"
|
|
||||||
:vertical="false"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<slot
|
|
||||||
name="moreFilterPanel"
|
|
||||||
:params="params"
|
|
||||||
:columns="splittedColumns.columns"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template #tags="{ tag, formatFn }" v-if="chipLocale">
|
|
||||||
<div class="q-gutter-x-xs">
|
|
||||||
<strong>{{ t(`${chipLocale}.${tag.label}`) }}: </strong>
|
|
||||||
<span>{{ formatFn(tag.value) }}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</VnFilterPanel>
|
|
||||||
</QScrollArea>
|
</QScrollArea>
|
||||||
</QDrawer>
|
</QDrawer>
|
||||||
<CrudModel
|
<CrudModel
|
||||||
|
@ -467,7 +369,7 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
|
||||||
:options="tableModes.filter((mode) => !mode.disable)"
|
:options="tableModes.filter((mode) => !mode.disable)"
|
||||||
/>
|
/>
|
||||||
<QBtn
|
<QBtn
|
||||||
v-if="$props.rightSearch"
|
v-if="showRightIcon"
|
||||||
icon="filter_alt"
|
icon="filter_alt"
|
||||||
class="bg-vn-section-color q-ml-sm"
|
class="bg-vn-section-color q-ml-sm"
|
||||||
dense
|
dense
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
import VnFilterPanel from 'components/ui/VnFilterPanel.vue';
|
||||||
|
import VnFilter from 'components/VnTable/VnFilter.vue';
|
||||||
|
import VnTableOrder from 'src/components/VnTable/VnOrder.vue';
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
columns: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
chipLocale: {
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
searchUrl: {
|
||||||
|
type: [String, Boolean],
|
||||||
|
default: 'table',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const tableFilterRef = ref([]);
|
||||||
|
|
||||||
|
function columnName(col) {
|
||||||
|
const column = { ...col, ...col.columnFilter };
|
||||||
|
let name = column.name;
|
||||||
|
if (column.alias) name = column.alias + '.' + name;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<VnFilterPanel v-bind="$attrs" :search-button="true" :disable-submit-event="true">
|
||||||
|
<template #body="{ params, orders }">
|
||||||
|
<div
|
||||||
|
class="row no-wrap flex-center"
|
||||||
|
v-for="col of columns.filter((c) => c.columnFilter ?? true)"
|
||||||
|
:key="col.id"
|
||||||
|
>
|
||||||
|
<VnFilter
|
||||||
|
ref="tableFilterRef"
|
||||||
|
:column="col"
|
||||||
|
:data-key="$attrs['data-key']"
|
||||||
|
v-model="params[columnName(col)]"
|
||||||
|
:search-url="searchUrl"
|
||||||
|
/>
|
||||||
|
<VnTableOrder
|
||||||
|
v-if="col?.columnFilter !== false && col?.name !== 'tableActions'"
|
||||||
|
v-model="orders[col.orderBy ?? col.name]"
|
||||||
|
:name="col.orderBy ?? col.name"
|
||||||
|
:data-key="$attrs['data-key']"
|
||||||
|
:search-url="searchUrl"
|
||||||
|
:vertical="true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<slot
|
||||||
|
name="moreFilterPanel"
|
||||||
|
:params="params"
|
||||||
|
:orders="orders"
|
||||||
|
:columns="columns"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #tags="{ tag, formatFn }" v-if="chipLocale">
|
||||||
|
<div class="q-gutter-x-xs">
|
||||||
|
<strong>{{ t(`${chipLocale}.${tag.label}`) }}: </strong>
|
||||||
|
<span>{{ formatFn(tag.value) }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</VnFilterPanel>
|
||||||
|
</template>
|
|
@ -15,7 +15,7 @@ let root = ref(null);
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
matched.value = currentRoute.value.matched.filter(
|
matched.value = currentRoute.value.matched.filter(
|
||||||
(matched) => Object.keys(matched.meta).length
|
(matched) => !!matched?.meta?.title || !!matched?.meta?.icon
|
||||||
);
|
);
|
||||||
breadcrumbs.value.length = 0;
|
breadcrumbs.value.length = 0;
|
||||||
if (!matched.value[0]) return;
|
if (!matched.value[0]) return;
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
<script setup>
|
||||||
|
import { onBeforeMount, computed } from 'vue';
|
||||||
|
import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
|
||||||
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
|
import useCardSize from 'src/composables/useCardSize';
|
||||||
|
import LeftMenu from 'components/LeftMenu.vue';
|
||||||
|
import VnSubToolbar from '../ui/VnSubToolbar.vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
dataKey: { type: String, required: true },
|
||||||
|
baseUrl: { type: String, default: undefined },
|
||||||
|
customUrl: { type: String, default: undefined },
|
||||||
|
filter: { type: Object, default: () => {} },
|
||||||
|
descriptor: { type: Object, required: true },
|
||||||
|
filterPanel: { type: Object, default: undefined },
|
||||||
|
searchDataKey: { type: String, default: undefined },
|
||||||
|
searchbarProps: { type: Object, default: undefined },
|
||||||
|
redirectOnError: { type: Boolean, default: false },
|
||||||
|
});
|
||||||
|
|
||||||
|
const stateStore = useStateStore();
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
const url = computed(() => {
|
||||||
|
if (props.baseUrl) {
|
||||||
|
return `${props.baseUrl}/${route.params.id}`;
|
||||||
|
}
|
||||||
|
return props.customUrl;
|
||||||
|
});
|
||||||
|
|
||||||
|
const arrayData = useArrayData(props.dataKey, {
|
||||||
|
url: url.value,
|
||||||
|
filter: props.filter,
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeMount(async () => {
|
||||||
|
try {
|
||||||
|
if (!props.baseUrl) arrayData.store.filter.where = { id: route.params.id };
|
||||||
|
await arrayData.fetch({ append: false, updateRouter: false });
|
||||||
|
} catch {
|
||||||
|
const { matched: matches } = router.currentRoute.value;
|
||||||
|
const { path } = matches.at(-1);
|
||||||
|
router.push({ path: path.replace(/:id.*/, '') });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (props.baseUrl) {
|
||||||
|
onBeforeRouteUpdate(async (to, from) => {
|
||||||
|
if (to.params.id !== from.params.id) {
|
||||||
|
arrayData.store.url = `${props.baseUrl}/${to.params.id}`;
|
||||||
|
await arrayData.fetch({ append: false, updateRouter: false });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<Teleport to="#left-panel" v-if="stateStore.isHeaderMounted()">
|
||||||
|
<component :is="descriptor" />
|
||||||
|
<QSeparator />
|
||||||
|
<LeftMenu source="card" />
|
||||||
jorgep marked this conversation as resolved
|
|||||||
|
</Teleport>
|
||||||
|
<VnSubToolbar />
|
||||||
|
<div :class="[useCardSize(), $attrs.class]">
|
||||||
|
<RouterView :key="route.path" />
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -1,8 +1,8 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import LeftMenu from 'components/LeftMenu.vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { onMounted } from 'vue';
|
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
|
import LeftMenu from '../LeftMenu.vue';
|
||||||
|
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
|
@ -14,12 +14,30 @@ const $props = defineProps({
|
||||||
onMounted(
|
onMounted(
|
||||||
() => (stateStore.leftDrawer = useQuasar().screen.gt.xs ? $props.leftDrawer : false)
|
() => (stateStore.leftDrawer = useQuasar().screen.gt.xs ? $props.leftDrawer : false)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const teleportRef = ref({});
|
||||||
|
const hasContent = ref();
|
||||||
|
let observer;
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (teleportRef.value) {
|
||||||
|
const checkContent = () => {
|
||||||
|
hasContent.value = teleportRef.value.innerHTML.trim() !== '';
|
||||||
|
};
|
||||||
|
|
||||||
|
observer = new MutationObserver(checkContent);
|
||||||
|
observer.observe(teleportRef.value, { childList: true, subtree: true });
|
||||||
|
|
||||||
|
checkContent();
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
<QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||||
<QScrollArea class="fit text-grey-8">
|
<QScrollArea class="fit text-grey-8">
|
||||||
<LeftMenu />
|
<div id="left-panel" ref="teleportRef"></div>
|
||||||
|
<LeftMenu v-if="!hasContent" />
|
||||||
</QScrollArea>
|
</QScrollArea>
|
||||||
</QDrawer>
|
</QDrawer>
|
||||||
<QPageContainer>
|
<QPageContainer>
|
|
@ -0,0 +1,79 @@
|
||||||
|
<script setup>
|
||||||
|
import RightMenu from './RightMenu.vue';
|
||||||
|
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
||||||
|
import VnTableFilter from '../VnTable/VnTableFilter.vue';
|
||||||
|
import { onBeforeMount, computed } from 'vue';
|
||||||
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
|
|
||||||
|
const $props = defineProps({
|
||||||
|
section: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
dataKey: {
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
searchBar: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
prefix: {
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
rightFilter: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
type: Array,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
arrayDataProps: {
|
||||||
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
redirect: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const sectionValue = computed(() => $props.section ?? $props.dataKey);
|
||||||
|
let arrayData;
|
||||||
|
onBeforeMount(() => {
|
||||||
|
if ($props.dataKey)
|
||||||
|
arrayData = useArrayData($props.dataKey, {
|
||||||
|
searchUrl: 'table',
|
||||||
|
...$props.arrayDataProps,
|
||||||
|
navigate: $props.redirect,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<slot name="searchbar">
|
||||||
|
<VnSearchbar
|
||||||
|
v-if="searchBar"
|
||||||
|
v-bind="arrayDataProps"
|
||||||
|
:data-key="dataKey"
|
||||||
|
:label="$t(`${prefix}.search`)"
|
||||||
|
:info="$t(`${prefix}.searchInfo`)"
|
||||||
|
/>
|
||||||
|
</slot>
|
||||||
|
|
||||||
|
<RightMenu>
|
||||||
|
<template #right-panel v-if="$slots['rightMenu'] || rightFilter">
|
||||||
|
<slot name="rightMenu">
|
||||||
|
<VnTableFilter
|
||||||
|
v-if="rightFilter && columns"
|
||||||
|
:data-key="dataKey"
|
||||||
|
:array-data="arrayData"
|
||||||
|
:columns="columns"
|
||||||
|
/>
|
||||||
|
</slot>
|
||||||
|
</template>
|
||||||
|
</RightMenu>
|
||||||
|
<slot name="body" v-if="sectionValue == $route.name" />
|
||||||
|
<RouterView v-else />
|
||||||
|
</template>
|
|
@ -206,7 +206,7 @@ async function fetchFilter(val) {
|
||||||
const fetchOptions = { where, include, limit };
|
const fetchOptions = { where, include, limit };
|
||||||
if (fields) fetchOptions.fields = fields;
|
if (fields) fetchOptions.fields = fields;
|
||||||
if (sortBy) fetchOptions.order = sortBy;
|
if (sortBy) fetchOptions.order = sortBy;
|
||||||
arrayData.reset(['skip', 'filter.skip', 'page']);
|
arrayData.resetPagination();
|
||||||
|
|
||||||
const { data } = await arrayData.applyFilter({ filter: fetchOptions });
|
const { data } = await arrayData.applyFilter({ filter: fetchOptions });
|
||||||
setOptions(data);
|
setOptions(data);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, ref, computed, watch } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useArrayData } from 'composables/useArrayData';
|
import { useArrayData } from 'composables/useArrayData';
|
||||||
import { useRoute } from 'vue-router';
|
|
||||||
import toDate from 'filters/toDate';
|
import toDate from 'filters/toDate';
|
||||||
import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue';
|
import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue';
|
||||||
|
import { useFilterParams } from 'src/composables/useFilterParams';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
|
@ -55,6 +55,10 @@ const $props = defineProps({
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
arrayData: {
|
||||||
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits([
|
const emit = defineEmits([
|
||||||
|
@ -66,52 +70,19 @@ const emit = defineEmits([
|
||||||
'setUserParams',
|
'setUserParams',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const arrayData = useArrayData($props.dataKey, {
|
const arrayData =
|
||||||
|
$props.arrayData ??
|
||||||
|
useArrayData($props.dataKey, {
|
||||||
exprBuilder: $props.exprBuilder,
|
exprBuilder: $props.exprBuilder,
|
||||||
searchUrl: $props.searchUrl,
|
searchUrl: $props.searchUrl,
|
||||||
navigate: $props.redirect ? {} : null,
|
navigate: $props.redirect ? {} : null,
|
||||||
});
|
});
|
||||||
const route = useRoute();
|
|
||||||
const store = arrayData.store;
|
const store = arrayData.store;
|
||||||
const userParams = ref({});
|
const userParams = ref(useFilterParams($props.dataKey).params);
|
||||||
|
const userOrders = ref(useFilterParams($props.dataKey).orders);
|
||||||
|
|
||||||
defineExpose({ search, sanitizer, params: userParams });
|
defineExpose({ search, params: userParams, remove });
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
if (!userParams.value) userParams.value = $props.modelValue ?? {};
|
|
||||||
emit('init', { params: userParams.value });
|
|
||||||
});
|
|
||||||
|
|
||||||
function setUserParams(watchedParams) {
|
|
||||||
if (!watchedParams || Object.keys(watchedParams).length == 0) return;
|
|
||||||
|
|
||||||
if (typeof watchedParams == 'string') watchedParams = JSON.parse(watchedParams);
|
|
||||||
if (typeof watchedParams?.filter == 'string')
|
|
||||||
watchedParams.filter = JSON.parse(watchedParams.filter);
|
|
||||||
|
|
||||||
watchedParams = { ...watchedParams, ...watchedParams.filter?.where };
|
|
||||||
const order = watchedParams.filter?.order;
|
|
||||||
|
|
||||||
delete watchedParams.filter;
|
|
||||||
userParams.value = sanitizer(watchedParams);
|
|
||||||
emit('setUserParams', userParams.value, order);
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => route.query[$props.searchUrl],
|
|
||||||
(val, oldValue) => (val || oldValue) && setUserParams(val)
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => arrayData.store.userParams,
|
|
||||||
(val, oldValue) => (val || oldValue) && setUserParams(val),
|
|
||||||
{ immediate: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => $props.modelValue,
|
|
||||||
(val) => (userParams.value = val ?? {})
|
|
||||||
);
|
|
||||||
|
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
async function search(evt) {
|
async function search(evt) {
|
||||||
|
@ -122,10 +93,9 @@ async function search(evt) {
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
const filter = { ...userParams.value, ...$props.modelValue };
|
const filter = { ...userParams.value, ...$props.modelValue };
|
||||||
store.userParamsChanged = true;
|
store.userParamsChanged = true;
|
||||||
const { params: newParams } = await arrayData.addFilter({
|
await arrayData.addFilter({
|
||||||
params: filter,
|
params: filter,
|
||||||
});
|
});
|
||||||
userParams.value = newParams;
|
|
||||||
|
|
||||||
if (!$props.showAll && !Object.values(filter).length) store.data = [];
|
if (!$props.showAll && !Object.values(filter).length) store.data = [];
|
||||||
emit('search');
|
emit('search');
|
||||||
|
@ -138,7 +108,7 @@ async function clearFilters() {
|
||||||
try {
|
try {
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
store.userParamsChanged = true;
|
store.userParamsChanged = true;
|
||||||
arrayData.reset(['skip', 'filter.skip', 'page']);
|
arrayData.resetPagination();
|
||||||
// Filtrar los params no removibles
|
// Filtrar los params no removibles
|
||||||
const removableFilters = Object.keys(userParams.value).filter((param) =>
|
const removableFilters = Object.keys(userParams.value).filter((param) =>
|
||||||
$props.unremovableParams.includes(param)
|
$props.unremovableParams.includes(param)
|
||||||
|
@ -148,9 +118,8 @@ async function clearFilters() {
|
||||||
for (const key of removableFilters) {
|
for (const key of removableFilters) {
|
||||||
newParams[key] = userParams.value[key];
|
newParams[key] = userParams.value[key];
|
||||||
}
|
}
|
||||||
userParams.value = {};
|
|
||||||
userParams.value = { ...newParams }; // Actualizar los params con los removibles
|
await arrayData.applyFilter({ params: { ...newParams } });
|
||||||
await arrayData.applyFilter({ params: userParams.value });
|
|
||||||
|
|
||||||
if (!$props.showAll) {
|
if (!$props.showAll) {
|
||||||
store.data = [];
|
store.data = [];
|
||||||
|
@ -212,21 +181,6 @@ function formatValue(value) {
|
||||||
|
|
||||||
return `"${value}"`;
|
return `"${value}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sanitizer(params) {
|
|
||||||
for (const [key, value] of Object.entries(params)) {
|
|
||||||
if (key === 'and' && Array.isArray(value)) {
|
|
||||||
value.forEach((item) => {
|
|
||||||
Object.assign(params, item);
|
|
||||||
});
|
|
||||||
delete params[key];
|
|
||||||
} else if (value && typeof value === 'object') {
|
|
||||||
const param = Object.values(value)[0];
|
|
||||||
if (typeof param == 'string') params[key] = param.replaceAll('%', '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -296,7 +250,12 @@ function sanitizer(params) {
|
||||||
<QSeparator />
|
<QSeparator />
|
||||||
</QList>
|
</QList>
|
||||||
<QList dense class="list q-gutter-y-sm q-mt-sm">
|
<QList dense class="list q-gutter-y-sm q-mt-sm">
|
||||||
<slot name="body" :params="sanitizer(userParams)" :search-fn="search"></slot>
|
<slot
|
||||||
|
name="body"
|
||||||
|
:params="userParams"
|
||||||
|
:orders="userOrders"
|
||||||
|
:search-fn="search"
|
||||||
|
></slot>
|
||||||
</QList>
|
</QList>
|
||||||
</QForm>
|
</QForm>
|
||||||
<QInnerLoading
|
<QInnerLoading
|
||||||
|
|
|
@ -106,10 +106,13 @@ const store = arrayData.store;
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
if (props.autoLoad && !store.data?.length) await fetch();
|
if (props.autoLoad && !store.data?.length) await fetch();
|
||||||
|
else emit('onFetch', store.data);
|
||||||
mounted.value = true;
|
mounted.value = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => arrayData.reset());
|
onBeforeUnmount(() => {
|
||||||
|
arrayData.resetPagination();
|
||||||
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.data,
|
() => props.data,
|
||||||
|
@ -137,8 +140,8 @@ const addFilter = async (filter, params) => {
|
||||||
|
|
||||||
async function fetch(params) {
|
async function fetch(params) {
|
||||||
useArrayData(props.dataKey, params);
|
useArrayData(props.dataKey, params);
|
||||||
arrayData.reset(['filter.skip', 'skip', 'page']);
|
arrayData.resetPagination();
|
||||||
await arrayData.fetch({ append: false, updateRouter: mounted.value });
|
await arrayData.fetch({ append: false });
|
||||||
return emitStoreData();
|
return emitStoreData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,13 +203,20 @@ async function onLoad(index, done) {
|
||||||
done(isDone);
|
done(isDone);
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ fetch, update, addFilter, paginate });
|
defineExpose({
|
||||||
|
fetch,
|
||||||
|
update,
|
||||||
|
addFilter,
|
||||||
|
paginate,
|
||||||
|
userParams: arrayData.store.userParams,
|
||||||
|
currentFilter: arrayData.store.currentFilter,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="full-width">
|
<div class="full-width">
|
||||||
<div
|
<div
|
||||||
v-if="!props.autoLoad && !store.data && !isLoading"
|
v-if="!store.data && !store.data?.length && !isLoading"
|
||||||
class="info-row q-pa-md text-center"
|
class="info-row q-pa-md text-center"
|
||||||
>
|
>
|
||||||
<h5>
|
<h5>
|
||||||
|
|
|
@ -100,8 +100,10 @@ onMounted(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
async function search() {
|
async function search() {
|
||||||
const staticParams = Object.entries(store.userParams);
|
const staticParams = Object.keys(store.userParams ?? {}).length
|
||||||
arrayData.reset(['skip', 'page']);
|
? store.userParams
|
||||||
|
: store.defaultParams;
|
||||||
|
arrayData.resetPagination();
|
||||||
|
|
||||||
const filter = {
|
const filter = {
|
||||||
params: {
|
params: {
|
||||||
|
@ -112,7 +114,7 @@ async function search() {
|
||||||
|
|
||||||
if (!props.searchRemoveParams || !searchText.value) {
|
if (!props.searchRemoveParams || !searchText.value) {
|
||||||
filter.params = {
|
filter.params = {
|
||||||
...Object.fromEntries(staticParams),
|
...staticParams,
|
||||||
search: searchText.value,
|
search: searchText.value,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,14 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
const searchUrl = store.searchUrl;
|
const searchUrl = store.searchUrl;
|
||||||
if (query[searchUrl]) {
|
if (query[searchUrl]) {
|
||||||
const params = JSON.parse(query[searchUrl]);
|
const params = JSON.parse(query[searchUrl]);
|
||||||
const filter = params?.filter && JSON.parse(params?.filter ?? '{}');
|
const filter =
|
||||||
|
params?.filter && typeof params?.filter == 'object'
|
||||||
|
? params?.filter
|
||||||
|
: JSON.parse(params?.filter ?? '{}');
|
||||||
delete params.filter;
|
delete params.filter;
|
||||||
|
|
||||||
store.userParams = { ...store.userParams, ...params };
|
store.userParams = { ...store.userParams, ...params };
|
||||||
store.userFilter = { ...filter, ...store.userFilter };
|
store.filter = { ...filter, ...store.userFilter };
|
||||||
if (filter?.order) store.order = filter.order;
|
if (filter?.order) store.order = filter.order;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -61,6 +64,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
store[option] = userOptions.keepOpts?.includes(option)
|
store[option] = userOptions.keepOpts?.includes(option)
|
||||||
? Object.assign(defaultOpts, store[option])
|
? Object.assign(defaultOpts, store[option])
|
||||||
: defaultOpts;
|
: defaultOpts;
|
||||||
|
if (option === 'userParams') store.defaultParams = store[option];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +79,6 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
const filter = {
|
const filter = {
|
||||||
limit: store.limit,
|
limit: store.limit,
|
||||||
};
|
};
|
||||||
|
|
||||||
let userParams = { ...store.userParams };
|
let userParams = { ...store.userParams };
|
||||||
|
|
||||||
Object.assign(filter, store.userFilter);
|
Object.assign(filter, store.userFilter);
|
||||||
|
@ -143,6 +146,10 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
if (arrayDataStore.get(key)) arrayDataStore.reset(key, opts);
|
if (arrayDataStore.get(key)) arrayDataStore.reset(key, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetPagination() {
|
||||||
|
if (arrayDataStore.get(key)) arrayDataStore.resetPagination(key);
|
||||||
|
}
|
||||||
|
|
||||||
function cancelRequest() {
|
function cancelRequest() {
|
||||||
if (canceller) {
|
if (canceller) {
|
||||||
canceller.abort();
|
canceller.abort();
|
||||||
|
@ -166,7 +173,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
userParams = sanitizerParams(userParams, store?.exprBuilder);
|
userParams = sanitizerParams(userParams, store?.exprBuilder);
|
||||||
|
|
||||||
store.userParams = userParams;
|
store.userParams = userParams;
|
||||||
reset(['skip', 'filter.skip', 'page']);
|
resetPagination();
|
||||||
|
|
||||||
await fetch({});
|
await fetch({});
|
||||||
return { filter, params };
|
return { filter, params };
|
||||||
|
@ -193,7 +200,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
store.order = order;
|
store.order = order;
|
||||||
reset(['skip', 'filter.skip', 'page']);
|
resetPagination();
|
||||||
fetch({});
|
fetch({});
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
|
@ -276,7 +283,6 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
const pushUrl = { path: to };
|
const pushUrl = { path: to };
|
||||||
if (to.endsWith('/list') || to.endsWith('/'))
|
if (to.endsWith('/list') || to.endsWith('/'))
|
||||||
pushUrl.query = newUrl.query;
|
pushUrl.query = newUrl.query;
|
||||||
else destroy();
|
|
||||||
return router.push(pushUrl);
|
return router.push(pushUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,5 +334,6 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
isLoading,
|
isLoading,
|
||||||
deleteOption,
|
deleteOption,
|
||||||
reset,
|
reset,
|
||||||
|
resetPagination,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
|
import { onBeforeMount, ref, watch } from 'vue';
|
||||||
|
|
||||||
|
export function useFilterParams(key) {
|
||||||
|
if (!key) throw new Error('ArrayData: A key is required to use this composable');
|
||||||
|
const params = ref({});
|
||||||
|
const orders = ref({});
|
||||||
|
const arrayData = ref({});
|
||||||
|
|
||||||
|
onBeforeMount(() => {
|
||||||
|
arrayData.value = useArrayData(key);
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => arrayData.value.store?.currentFilter,
|
||||||
|
(val, oldValue) => (val || oldValue) && setUserParams(val),
|
||||||
|
{ immediate: true, deep: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
function parseOrder(urlOrders) {
|
||||||
|
const orderObject = {};
|
||||||
|
if (urlOrders) {
|
||||||
|
if (typeof urlOrders == 'string') urlOrders = [urlOrders];
|
||||||
|
for (const [index, orders] of urlOrders.entries()) {
|
||||||
|
const [name, direction] = orders.split(' ');
|
||||||
|
orderObject[name] = { direction, index: index + 1 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
orders.value = orderObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setUserParams(watchedParams) {
|
||||||
|
if (!watchedParams || Object.keys(watchedParams).length == 0) return;
|
||||||
|
|
||||||
|
if (typeof watchedParams == 'string') watchedParams = JSON.parse(watchedParams);
|
||||||
|
if (typeof watchedParams?.filter == 'string')
|
||||||
|
watchedParams.filter = JSON.parse(watchedParams.filter);
|
||||||
|
|
||||||
|
watchedParams = { ...watchedParams, ...watchedParams.filter?.where };
|
||||||
|
parseOrder(watchedParams.filter?.order);
|
||||||
|
|
||||||
|
delete watchedParams.filter;
|
||||||
|
params.value = sanitizer(watchedParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sanitizer(params) {
|
||||||
|
for (const [key, value] of Object.entries(params)) {
|
||||||
|
if (key === 'and' && Array.isArray(value)) {
|
||||||
|
value.forEach((item) => {
|
||||||
|
Object.assign(params, item);
|
||||||
|
});
|
||||||
|
delete params[key];
|
||||||
|
} else if (value && typeof value === 'object') {
|
||||||
|
const param = Object.values(value)[0];
|
||||||
|
if (typeof param == 'string') params[key] = param.replaceAll('%', '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
params,
|
||||||
|
orders,
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,16 +1,15 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
|
|
||||||
import VnTable from 'components/VnTable/VnTable.vue';
|
import VnTable from 'components/VnTable/VnTable.vue';
|
||||||
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
|
||||||
import VnConfirm from 'components/ui/VnConfirm.vue';
|
import VnConfirm from 'components/ui/VnConfirm.vue';
|
||||||
import FetchData from 'src/components/FetchData.vue';
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
import { useValidator } from 'src/composables/useValidator';
|
import { useValidator } from 'src/composables/useValidator';
|
||||||
|
import VnSection from 'src/components/common/VnSection.vue';
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -21,13 +20,13 @@ defineProps({
|
||||||
|
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const stateStore = useStateStore();
|
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
|
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
const roles = ref();
|
const roles = ref();
|
||||||
const validationsStore = useValidator();
|
const validationsStore = useValidator();
|
||||||
const { models } = validationsStore;
|
const { models } = validationsStore;
|
||||||
|
const dataKey = 'AccountAcls';
|
||||||
alexm marked this conversation as resolved
jorgep
commented
Quitar y poner directamente en la prop, solo se usa 1 vez Quitar y poner directamente en la prop, solo se usa 1 vez
jorgep
commented
Quitar Quitar
|
|||||||
const exprBuilder = (param, value) => {
|
const exprBuilder = (param, value) => {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 'search':
|
case 'search':
|
||||||
|
@ -134,39 +133,41 @@ const deleteAcl = async ({ id }) => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnSearchbar
|
|
||||||
data-key="AccountAcls"
|
|
||||||
url="ACLs"
|
|
||||||
:expr-builder="exprBuilder"
|
|
||||||
:label="t('acls.search')"
|
|
||||||
:info="t('acls.searchInfo')"
|
|
||||||
/>
|
|
||||||
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
|
||||||
</QDrawer>
|
|
||||||
<FetchData
|
<FetchData
|
||||||
url="VnRoles?fields=['name']"
|
url="VnRoles?fields=['name']"
|
||||||
auto-load
|
auto-load
|
||||||
@on-fetch="(data) => (roles = data)"
|
@on-fetch="(data) => (roles = data)"
|
||||||
/>
|
/>
|
||||||
|
<VnSection
|
||||||
|
:data-key="dataKey"
|
||||||
alexm marked this conversation as resolved
jorgep
commented
Que esta prop tenga el valor por defecto de la prop datakey Que esta prop tenga el valor por defecto de la prop datakey
alexm
commented
Me gusta como piensas Me gusta como piensas
|
|||||||
|
:columns="columns"
|
||||||
|
prefix="acls"
|
||||||
|
:array-data-props="{
|
||||||
|
url: 'ACLs',
|
||||||
|
order: 'id DESC',
|
||||||
|
exprBuilder,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #body>
|
||||||
<VnTable
|
<VnTable
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
data-key="AccountAcls"
|
:data-key="dataKey"
|
||||||
:url="`ACLs`"
|
|
||||||
:create="{
|
:create="{
|
||||||
urlCreate: 'ACLs',
|
urlCreate: 'ACLs',
|
||||||
title: 'Create ACL',
|
title: 'Create ACL',
|
||||||
onDataSaved: () => tableRef.reload(),
|
onDataSaved: () => tableRef.reload(),
|
||||||
formInitialData: {},
|
formInitialData: {},
|
||||||
}"
|
}"
|
||||||
order="id DESC"
|
|
||||||
:disable-option="{ card: true }"
|
:disable-option="{ card: true }"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
default-mode="table"
|
default-mode="table"
|
||||||
:right-search="true"
|
:right-search="false"
|
||||||
:is-editable="true"
|
:is-editable="true"
|
||||||
:use-model="true"
|
:use-model="true"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
</VnSection>
|
||||||
|
</template>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
|
|
|
@ -2,21 +2,12 @@
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import VnTable from 'components/VnTable/VnTable.vue';
|
import VnTable from 'components/VnTable/VnTable.vue';
|
||||||
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
import VnSection from 'src/components/common/VnSection.vue';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
|
||||||
|
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const stateStore = useStateStore();
|
const dataKey = 'AccountAliasList';
|
||||||
alexm marked this conversation as resolved
jorgep
commented
quitar, solo se usa 1 vez. quitar, solo se usa 1 vez.
|
|||||||
|
|
||||||
const exprBuilder = (param, value) => {
|
|
||||||
switch (param) {
|
|
||||||
case 'search':
|
|
||||||
return /^\d+$/.test(value)
|
|
||||||
? { id: value }
|
|
||||||
: { alias: { like: `%${value}%` } };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -40,40 +31,45 @@ const columns = computed(() => [
|
||||||
create: true,
|
create: true,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const exprBuilder = (param, value) => {
|
||||||
|
switch (param) {
|
||||||
|
case 'search':
|
||||||
|
return /^\d+$/.test(value)
|
||||||
|
? { id: value }
|
||||||
|
: { alias: { like: `%${value}%` } };
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<template v-if="stateStore.isHeaderMounted()">
|
<VnSection
|
||||||
<Teleport to="#searchbar">
|
:data-key="dataKey"
|
||||||
alexm marked this conversation as resolved
jorgep
commented
Lo mismo que el AccountAcls Lo mismo que el AccountAcls
|
|||||||
<VnSearchbar
|
:columns="columns"
|
||||||
data-key="AccountAliasList"
|
prefix="mailAlias"
|
||||||
url="MailAliases"
|
:array-data-props="{ url: 'MailAliases', order: 'id DESC', exprBuilder }"
|
||||||
:expr-builder="exprBuilder"
|
>
|
||||||
:label="t('mailAlias.search')"
|
<template #body>
|
||||||
:info="t('mailAlias.searchInfo')"
|
|
||||||
/>
|
|
||||||
</Teleport>
|
|
||||||
</template>
|
|
||||||
<VnTable
|
<VnTable
|
||||||
|
:data-key="dataKey"
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
data-key="AccountAliasList"
|
|
||||||
url="MailAliases"
|
|
||||||
:create="{
|
:create="{
|
||||||
urlCreate: 'MailAliases',
|
urlCreate: 'MailAliases',
|
||||||
title: 'Create MailAlias',
|
title: 'Create MailAlias',
|
||||||
onDataSaved: ({ id }) => tableRef.redirect(id),
|
onDataSaved: ({ id }) => tableRef.redirect(id),
|
||||||
formInitialData: {},
|
formInitialData: {},
|
||||||
}"
|
}"
|
||||||
order="id DESC"
|
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:disable-option="{ card: true }"
|
:disable-option="{ card: true }"
|
||||||
default-mode="table"
|
default-mode="table"
|
||||||
redirect="account/alias"
|
redirect="account/alias"
|
||||||
:is-editable="true"
|
:is-editable="true"
|
||||||
:use-model="true"
|
:use-model="true"
|
||||||
|
:right-search="false"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
</VnSection>
|
||||||
|
</template>
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Id: Id
|
Id: Id
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { ref, computed } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import VnTable from 'components/VnTable/VnTable.vue';
|
import VnTable from 'components/VnTable/VnTable.vue';
|
||||||
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
|
||||||
import AccountSummary from './Card/AccountSummary.vue';
|
import AccountSummary from './Card/AccountSummary.vue';
|
||||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
import AccountFilter from './AccountFilter.vue';
|
import VnSection from 'src/components/common/VnSection.vue';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { viewSummary } = useSummaryDialog();
|
const { viewSummary } = useSummaryDialog();
|
||||||
const tableRef = ref();
|
|
||||||
const filter = {
|
const filter = {
|
||||||
include: { relation: 'role', scope: { fields: ['id', 'name'] } },
|
include: { relation: 'role', scope: { fields: ['id', 'name'] } },
|
||||||
};
|
};
|
||||||
|
const dataKey = 'AccountList';
|
||||||
|
const roles = ref([]);
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -30,7 +31,7 @@ const columns = computed(() => [
|
||||||
component: 'select',
|
component: 'select',
|
||||||
name: 'roleFk',
|
name: 'roleFk',
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'VnRoles',
|
options: roles,
|
||||||
optionValue: 'id',
|
optionValue: 'id',
|
||||||
optionLabel: 'name',
|
optionLabel: 'name',
|
||||||
},
|
},
|
||||||
|
@ -82,7 +83,8 @@ const columns = computed(() => [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
const exprBuilder = (param, value) => {
|
|
||||||
|
function exprBuilder(param, value) {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 'search':
|
case 'search':
|
||||||
return /^\d+$/.test(value)
|
return /^\d+$/.test(value)
|
||||||
|
@ -99,36 +101,34 @@ const exprBuilder = (param, value) => {
|
||||||
case 'roleFk':
|
case 'roleFk':
|
||||||
return { [param]: value };
|
return { [param]: value };
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnSearchbar
|
<FetchData url="VnRoles" @on-fetch="(data) => (roles = data)" auto-load />
|
||||||
data-key="AccountList"
|
<VnSection
|
||||||
:expr-builder="exprBuilder"
|
:data-key="dataKey"
|
||||||
:label="t('account.search')"
|
:columns="columns"
|
||||||
:info="t('account.searchInfo')"
|
prefix="account"
|
||||||
:filter="filter"
|
:array-data-props="{
|
||||||
/>
|
url: 'VnUsers/preview',
|
||||||
<RightMenu>
|
userFilter: filter,
|
||||||
<template #right-panel>
|
order: 'id DESC',
|
||||||
<AccountFilter data-key="AccountList" />
|
exprBuilder,
|
||||||
</template>
|
}"
|
||||||
</RightMenu>
|
>
|
||||||
|
<template #body>
|
||||||
<VnTable
|
<VnTable
|
||||||
ref="tableRef"
|
:data-key="dataKey"
|
||||||
data-key="AccountList"
|
|
||||||
url="VnUsers/preview"
|
|
||||||
:filter="filter"
|
|
||||||
order="id DESC"
|
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
default-mode="table"
|
default-mode="table"
|
||||||
redirect="account"
|
redirect="account"
|
||||||
:use-model="true"
|
:use-model="true"
|
||||||
:right-search="false"
|
:right-search="false"
|
||||||
auto-load
|
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
</VnSection>
|
||||||
|
</template>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import VnCard from 'components/common/VnCard.vue';
|
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
||||||
import AliasDescriptor from './AliasDescriptor.vue';
|
import AliasDescriptor from './AliasDescriptor.vue';
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnCard
|
<VnCardBeta
|
||||||
data-key="Alias"
|
data-key="Alias"
|
||||||
base-url="MailAliases"
|
base-url="MailAliases"
|
||||||
:descriptor="AliasDescriptor"
|
:descriptor="AliasDescriptor"
|
||||||
|
|
|
@ -1,20 +1,8 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useI18n } from 'vue-i18n';
|
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
||||||
import VnCard from 'components/common/VnCard.vue';
|
|
||||||
import AccountDescriptor from './AccountDescriptor.vue';
|
import AccountDescriptor from './AccountDescriptor.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnCard
|
<VnCardBeta data-key="AccountId" :descriptor="AccountDescriptor" />
|
||||||
data-key="Account"
|
|
||||||
:descriptor="AccountDescriptor"
|
|
||||||
search-data-key="AccountList"
|
|
||||||
:searchbar-props="{
|
|
||||||
url: 'VnUsers/preview',
|
|
||||||
label: t('account.search'),
|
|
||||||
info: t('account.searchInfo'),
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -41,7 +41,7 @@ const hasAccount = ref(false);
|
||||||
/>
|
/>
|
||||||
<CardDescriptor
|
<CardDescriptor
|
||||||
ref="descriptor"
|
ref="descriptor"
|
||||||
:url="`VnUsers/preview`"
|
url="VnUsers/preview"
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
module="Account"
|
module="Account"
|
||||||
@on-fetch="setData"
|
@on-fetch="setData"
|
||||||
|
|
|
@ -30,7 +30,7 @@ const filter = {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<CardSummary
|
<CardSummary
|
||||||
data-key="AccountSummary"
|
data-key="AccountId"
|
||||||
ref="AccountSummary"
|
ref="AccountSummary"
|
||||||
url="VnUsers/preview"
|
url="VnUsers/preview"
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
|
|
|
@ -3,11 +3,13 @@ import { useI18n } from 'vue-i18n';
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import VnTable from 'components/VnTable/VnTable.vue';
|
import VnTable from 'components/VnTable/VnTable.vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
|
||||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
import RoleSummary from './Card/RoleSummary.vue';
|
import RoleSummary from './Card/RoleSummary.vue';
|
||||||
|
import VnSection from 'src/components/common/VnSection.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const { viewSummary } = useSummaryDialog();
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
type: Number,
|
type: Number,
|
||||||
|
@ -15,8 +17,10 @@ const $props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
|
const url = 'VnRoles';
|
||||||
|
const dataKey = 'AccountRoleList';
|
||||||
alexm marked this conversation as resolved
jorgep
commented
quitar, solo se usa 1 vez. quitar, solo se usa 1 vez.
|
|||||||
|
|
||||||
const entityId = computed(() => $props.id || route.params.id);
|
const entityId = computed(() => $props.id || route.params.id);
|
||||||
const { viewSummary } = useSummaryDialog();
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -81,16 +85,16 @@ const exprBuilder = (param, value) => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnSearchbar
|
<VnSection
|
||||||
data-key="AccountRolesList"
|
:data-key="dataKey"
|
||||||
alexm marked this conversation as resolved
jorgep
commented
Lo mismo que AccountAcls Lo mismo que AccountAcls
|
|||||||
:expr-builder="exprBuilder"
|
:columns="columns"
|
||||||
:label="t('role.searchRoles')"
|
prefix="role"
|
||||||
:info="t('role.searchInfo')"
|
:array-data-props="{ url, exprBuilder, order: 'id ASC' }"
|
||||||
/>
|
>
|
||||||
|
<template #body>
|
||||||
<VnTable
|
<VnTable
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
data-key="AccountRolesList"
|
:data-key="dataKey"
|
||||||
:url="`VnRoles`"
|
|
||||||
:create="{
|
:create="{
|
||||||
urlCreate: 'VnRoles',
|
urlCreate: 'VnRoles',
|
||||||
title: t('Create rol'),
|
title: t('Create rol'),
|
||||||
|
@ -99,13 +103,15 @@ const exprBuilder = (param, value) => {
|
||||||
editorFk: entityId,
|
editorFk: entityId,
|
||||||
},
|
},
|
||||||
}"
|
}"
|
||||||
order="id ASC"
|
|
||||||
:disable-option="{ card: true }"
|
:disable-option="{ card: true }"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
default-mode="table"
|
default-mode="table"
|
||||||
redirect="account/role"
|
redirect="account/role"
|
||||||
|
:right-search="false"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
</VnSection>
|
||||||
|
</template>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
|
|
|
@ -1,20 +1,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useI18n } from 'vue-i18n';
|
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
||||||
import VnCard from 'components/common/VnCard.vue';
|
|
||||||
import RoleDescriptor from './RoleDescriptor.vue';
|
import RoleDescriptor from './RoleDescriptor.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VnCard
|
<VnCardBeta data-key="Role" :descriptor="RoleDescriptor" />
|
||||||
data-key="Role"
|
|
||||||
:descriptor="RoleDescriptor"
|
|
||||||
search-data-key="AccountRolesList"
|
|
||||||
:searchbar-props="{
|
|
||||||
url: 'VnRoles',
|
|
||||||
label: t('role.searchRoles'),
|
|
||||||
info: t('role.searchInfo'),
|
|
||||||
searchUrl: 'table',
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -43,7 +43,7 @@ const removeRole = async () => {
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
module="Role"
|
module="Role"
|
||||||
@on-fetch="setData"
|
@on-fetch="setData"
|
||||||
data-key="accountData"
|
data-key="Role"
|
||||||
alexm marked this conversation as resolved
jorgep
commented
RoleId RoleId
alexm
commented
No hace falta poner roleId, dado que el dataKey del list es AccountRoleList No hace falta poner roleId, dado que el dataKey del list es AccountRoleList
Siendo Role ya va guay
|
|||||||
:title="data.title"
|
:title="data.title"
|
||||||
:subtitle="data.subtitle"
|
:subtitle="data.subtitle"
|
||||||
:summary="$props.summary"
|
:summary="$props.summary"
|
||||||
|
|
|
@ -27,10 +27,10 @@ const filter = {
|
||||||
<template>
|
<template>
|
||||||
<CardSummary
|
<CardSummary
|
||||||
ref="summary"
|
ref="summary"
|
||||||
:url="`VnRoles`"
|
:url="`VnRoles/${entityId}`"
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
@on-fetch="(data) => (role = data)"
|
@on-fetch="(data) => (role = data)"
|
||||||
data-key="RoleSummary"
|
data-key="Role"
|
||||||
alexm marked this conversation as resolved
jorgep
commented
RoleId RoleId
|
|||||||
>
|
>
|
||||||
<template #header> {{ role.id }} - {{ role.name }} </template>
|
<template #header> {{ role.id }} - {{ role.name }} </template>
|
||||||
<template #body>
|
<template #body>
|
||||||
|
|
|
@ -66,7 +66,7 @@ account:
|
||||||
mailInputInfo: All emails will be forwarded to the specified address.
|
mailInputInfo: All emails will be forwarded to the specified address.
|
||||||
role:
|
role:
|
||||||
newRole: New role
|
newRole: New role
|
||||||
searchRoles: Search role
|
search: Search role
|
||||||
searchInfo: Search role by id or name
|
searchInfo: Search role by id or name
|
||||||
description: Description
|
description: Description
|
||||||
id: Id
|
id: Id
|
||||||
|
|
|
@ -419,7 +419,6 @@ function handleLocation(data, location) {
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
redirect="customer"
|
redirect="customer"
|
||||||
:right-search="false"
|
:right-search="false"
|
||||||
auto-load
|
|
||||||
>
|
>
|
||||||
<template #more-create-dialog="{ data }">
|
<template #more-create-dialog="{ data }">
|
||||||
<VnSelect
|
<VnSelect
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { date, useQuasar } from 'quasar';
|
import { date, useQuasar } from 'quasar';
|
||||||
import { computed, onMounted, reactive, ref } from 'vue';
|
import { computed, onMounted, onUnmounted, reactive, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const stateStore = useStateStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
stateStore.rightDrawer = true;
|
||||||
jorgep marked this conversation as resolved
jorgep
commented
En vista móvil se quedará abierto también. En vista móvil se quedará abierto también.
alexm
commented
Diria que es lo correcto pq hasta que no eliges video, no muestra nada Diria que es lo correcto pq hasta que no eliges video, no muestra nada
|
|||||||
await fetch();
|
await fetch();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -84,8 +87,7 @@ async function getVideoList(expeditionId, timed) {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<QDrawer show-if-above side="right">
|
<Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()">
|
||||||
<QScrollArea class="fit">
|
|
||||||
<QList bordered separator style="max-width: 318px">
|
<QList bordered separator style="max-width: 318px">
|
||||||
<QItem v-if="lastExpedition && videoList.length">
|
<QItem v-if="lastExpedition && videoList.length">
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
|
@ -138,9 +140,7 @@ async function getVideoList(expeditionId, timed) {
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QItemLabel caption>{{ t('globals.created') }}</QItemLabel>
|
<QItemLabel caption>{{ t('globals.created') }}</QItemLabel>
|
||||||
<QItemLabel>
|
<QItemLabel>
|
||||||
{{
|
{{ date.formatDate(expedition.created, 'YYYY-MM-DD HH:mm:ss') }}
|
||||||
date.formatDate(expedition.created, 'YYYY-MM-DD HH:mm:ss')
|
|
||||||
}}
|
|
||||||
</QItemLabel>
|
</QItemLabel>
|
||||||
<QItemLabel caption>{{ t('globals.item') }}</QItemLabel>
|
<QItemLabel caption>{{ t('globals.item') }}</QItemLabel>
|
||||||
<QItemLabel>{{ expedition.packagingItemFk }}</QItemLabel>
|
<QItemLabel>{{ expedition.packagingItemFk }}</QItemLabel>
|
||||||
|
@ -149,9 +149,7 @@ async function getVideoList(expeditionId, timed) {
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
</QList>
|
</QList>
|
||||||
</QScrollArea>
|
</Teleport>
|
||||||
</QDrawer>
|
|
||||||
|
|
||||||
<QCard>
|
<QCard>
|
||||||
<QCarousel animated v-model="slide" height="max-content">
|
<QCarousel animated v-model="slide" height="max-content">
|
||||||
<QCarouselSlide
|
<QCarouselSlide
|
||||||
|
|
|
@ -1,23 +1,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useI18n } from 'vue-i18n';
|
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
||||||
|
|
||||||
import VnCard from 'components/common/VnCard.vue';
|
|
||||||
import TicketDescriptor from './TicketDescriptor.vue';
|
import TicketDescriptor from './TicketDescriptor.vue';
|
||||||
import TicketFilter from '../TicketFilter.vue';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VnCard
|
<VnCardBeta data-key="Ticket" base-url="Tickets" :descriptor="TicketDescriptor" />
|
||||||
data-key="Ticket"
|
|
||||||
base-url="Tickets"
|
|
||||||
:filter-panel="TicketFilter"
|
|
||||||
:descriptor="TicketDescriptor"
|
|
||||||
search-data-key="TicketList"
|
|
||||||
:searchbar-props="{
|
|
||||||
url: 'Tickets/filter',
|
|
||||||
label: t('card.search'),
|
|
||||||
info: t('card.searchInfo'),
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -8,13 +8,11 @@ import { useQuasar } from 'quasar';
|
||||||
import { toDate, toCurrency, dashIfEmpty } from 'src/filters/index';
|
import { toDate, toCurrency, dashIfEmpty } from 'src/filters/index';
|
||||||
import useNotify from 'src/composables/useNotify';
|
import useNotify from 'src/composables/useNotify';
|
||||||
import TicketSummary from './Card/TicketSummary.vue';
|
import TicketSummary from './Card/TicketSummary.vue';
|
||||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
|
||||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
import VnTable from 'src/components/VnTable/VnTable.vue';
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||||
import VnRow from 'src/components/ui/VnRow.vue';
|
import VnRow from 'src/components/ui/VnRow.vue';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
|
||||||
import TicketFilter from './TicketFilter.vue';
|
import TicketFilter from './TicketFilter.vue';
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import FetchData from 'src/components/FetchData.vue';
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
|
@ -23,6 +21,7 @@ import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
|
||||||
import { toTimeFormat } from 'src/filters/date';
|
import { toTimeFormat } from 'src/filters/date';
|
||||||
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
|
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
|
||||||
import TicketProblems from 'src/components/TicketProblems.vue';
|
import TicketProblems from 'src/components/TicketProblems.vue';
|
||||||
|
import VnSection from 'src/components/common/VnSection.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -66,6 +65,7 @@ const dialogData = ref();
|
||||||
const companiesOptions = ref([]);
|
const companiesOptions = ref([]);
|
||||||
const accountingOptions = ref([]);
|
const accountingOptions = ref([]);
|
||||||
const amountToReturn = ref();
|
const amountToReturn = ref();
|
||||||
|
const dataKey = 'TicketList';
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
|
@ -452,21 +452,23 @@ function setReference(data) {
|
||||||
@on-fetch="(data) => (accountingOptions = data)"
|
@on-fetch="(data) => (accountingOptions = data)"
|
||||||
auto-load
|
auto-load
|
||||||
/>
|
/>
|
||||||
<VnSearchbar
|
<VnSection
|
||||||
data-key="TicketList"
|
:data-key="dataKey"
|
||||||
:label="t('Search ticket')"
|
:columns="columns"
|
||||||
:info="t('You can search by ticket id or alias')"
|
prefix="card"
|
||||||
data-cy="ticketListSearchBar"
|
:array-data-props="{
|
||||||
/>
|
url: 'Tickets/filter',
|
||||||
<RightMenu>
|
order: ['shippedDate DESC', 'shippedHour ASC', 'zoneLanding ASC', 'id'],
|
||||||
<template #right-panel>
|
exprBuilder,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #rightMenu>
|
||||||
<TicketFilter data-key="TicketList" />
|
<TicketFilter data-key="TicketList" />
|
||||||
</template>
|
</template>
|
||||||
</RightMenu>
|
<template #body>
|
||||||
<VnTable
|
<VnTable
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
data-key="TicketList"
|
:data-key="dataKey"
|
||||||
url="Tickets/filter"
|
|
||||||
:create="{
|
:create="{
|
||||||
urlCreate: 'Tickets/new',
|
urlCreate: 'Tickets/new',
|
||||||
title: t('ticketList.createTicket'),
|
title: t('ticketList.createTicket'),
|
||||||
|
@ -474,7 +476,6 @@ function setReference(data) {
|
||||||
formInitialData: { clientId: null },
|
formInitialData: { clientId: null },
|
||||||
}"
|
}"
|
||||||
default-mode="table"
|
default-mode="table"
|
||||||
:order="['shippedDate DESC', 'shippedHour ASC', 'zoneLanding ASC', 'id']"
|
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:user-params="userParams"
|
:user-params="userParams"
|
||||||
:right-search="false"
|
:right-search="false"
|
||||||
|
@ -598,7 +599,8 @@ function setReference(data) {
|
||||||
<QIcon
|
<QIcon
|
||||||
v-if="
|
v-if="
|
||||||
scope.opt.isActive &&
|
scope.opt.isActive &&
|
||||||
selectedClient?.defaultAddressFk === scope.opt.id
|
selectedClient?.defaultAddressFk ===
|
||||||
|
scope.opt.id
|
||||||
"
|
"
|
||||||
size="sm"
|
size="sm"
|
||||||
color="grey"
|
color="grey"
|
||||||
|
@ -621,7 +623,8 @@ function setReference(data) {
|
||||||
}}
|
}}
|
||||||
<span>
|
<span>
|
||||||
{{ scope.opt?.nickname }}:
|
{{ scope.opt?.nickname }}:
|
||||||
{{ scope.opt?.street }}, {{ scope.opt?.city }}
|
{{ scope.opt?.street }},
|
||||||
|
{{ scope.opt?.city }}
|
||||||
</span>
|
</span>
|
||||||
</QItemLabel>
|
</QItemLabel>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
|
@ -669,6 +672,8 @@ function setReference(data) {
|
||||||
</VnRow>
|
</VnRow>
|
||||||
</template>
|
</template>
|
||||||
</VnTable>
|
</VnTable>
|
||||||
|
</template>
|
||||||
|
</VnSection>
|
||||||
<QPageSticky :offset="[20, 80]" style="z-index: 2">
|
<QPageSticky :offset="[20, 80]" style="z-index: 2">
|
||||||
<QBtn
|
<QBtn
|
||||||
v-if="hasSelectedRows"
|
v-if="hasSelectedRows"
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import { RouterView } from 'vue-router';
|
import { RouterView } from 'vue-router';
|
||||||
|
import accountCard from './account/accountCard';
|
||||||
alexm marked this conversation as resolved
jorgep
commented
Consultaría a Juan si le parece bien separarlo en varios ficheros. Por mí bien Consultaría a Juan si le parece bien separarlo en varios ficheros. Por mí bien
alexm
commented
Entiendo que lo verán guay sino se hace un monstruo de archivo y de todas maneras como estaba ya estaba separado Entiendo que lo verán guay sino se hace un monstruo de archivo y de todas maneras como estaba ya estaba separado
|
|||||||
|
import roleCard from './account/roleCard';
|
||||||
|
import aliasCard from './account/aliasCard';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
path: '/account',
|
path: '/account',
|
||||||
|
@ -8,62 +11,76 @@ export default {
|
||||||
icon: 'face',
|
icon: 'face',
|
||||||
moduleName: 'Account',
|
moduleName: 'Account',
|
||||||
keyBinding: 'u',
|
keyBinding: 'u',
|
||||||
},
|
menu: [
|
||||||
component: RouterView,
|
|
||||||
redirect: { name: 'AccountMain' },
|
|
||||||
menus: {
|
|
||||||
main: [
|
|
||||||
'AccountList',
|
'AccountList',
|
||||||
'AccountAliasList',
|
|
||||||
'AccountRoles',
|
'AccountRoles',
|
||||||
|
'AccountAlias',
|
||||||
'AccountAccounts',
|
'AccountAccounts',
|
||||||
'AccountLdap',
|
'AccountLdap',
|
||||||
'AccountSamba',
|
'AccountSamba',
|
||||||
'AccountAcls',
|
'AccountAcls',
|
||||||
'AccountConnections',
|
'AccountConnections',
|
||||||
],
|
],
|
||||||
card: [
|
|
||||||
'AccountBasicData',
|
|
||||||
'AccountInheritedRoles',
|
|
||||||
'AccountMailForwarding',
|
|
||||||
'AccountMailAlias',
|
|
||||||
'AccountPrivileges',
|
|
||||||
'AccountLog',
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
|
component: RouterView,
|
||||||
|
redirect: { name: 'AccountMain' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
name: 'AccountMain',
|
name: 'AccountMain',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
redirect: { name: 'AccountList' },
|
redirect: { name: 'AccountIndexMain' },
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
name: 'AccountIndexMain',
|
||||||
|
redirect: { name: 'AccountList' },
|
||||||
|
component: () => import('src/pages/Account/AccountList.vue'),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'list',
|
|
||||||
name: 'AccountList',
|
name: 'AccountList',
|
||||||
|
path: 'list',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'list',
|
title: 'list',
|
||||||
icon: 'view_list',
|
icon: 'view_list',
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Account/AccountList.vue'),
|
},
|
||||||
|
accountCard,
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'role-list',
|
path: 'role',
|
||||||
name: 'AccountRoles',
|
name: 'AccountRoles',
|
||||||
|
redirect: { name: 'AccountRoleList' },
|
||||||
meta: {
|
meta: {
|
||||||
title: 'roles',
|
title: 'roles',
|
||||||
icon: 'group',
|
icon: 'group',
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Account/Role/AccountRoles.vue'),
|
component: () => import('src/pages/Account/Role/AccountRoles.vue'),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: 'AccountRoleList',
|
||||||
|
path: 'list',
|
||||||
|
},
|
||||||
|
roleCard,
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'alias-list',
|
path: 'alias',
|
||||||
name: 'AccountAliasList',
|
name: 'AccountAlias',
|
||||||
|
redirect: { name: 'AccountAliasList' },
|
||||||
meta: {
|
meta: {
|
||||||
title: 'alias',
|
title: 'alias',
|
||||||
icon: 'email',
|
icon: 'email',
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Account/AccountAliasList.vue'),
|
component: () => import('src/pages/Account/AccountAliasList.vue'),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: 'AccountAliasList',
|
||||||
|
path: 'list',
|
||||||
|
},
|
||||||
|
aliasCard,
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'acls',
|
path: 'acls',
|
||||||
|
@ -120,81 +137,5 @@ export default {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'AccountCard',
|
|
||||||
path: ':id',
|
|
||||||
component: () => import('src/pages/Account/Card/AccountCard.vue'),
|
|
||||||
redirect: { name: 'AccountSummary' },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'AccountSummary',
|
|
||||||
path: 'summary',
|
|
||||||
meta: {
|
|
||||||
title: 'summary',
|
|
||||||
icon: 'launch',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Account/Card/AccountSummary.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'AccountBasicData',
|
|
||||||
path: 'basic-data',
|
|
||||||
meta: {
|
|
||||||
title: 'basicData',
|
|
||||||
icon: 'vn:settings',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import('src/pages/Account/Card/AccountBasicData.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'AccountInheritedRoles',
|
|
||||||
path: 'inherited-roles',
|
|
||||||
meta: {
|
|
||||||
title: 'inheritedRoles',
|
|
||||||
icon: 'group',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import('src/pages/Account/Card/AccountInheritedRoles.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'AccountMailForwarding',
|
|
||||||
path: 'mail-forwarding',
|
|
||||||
meta: {
|
|
||||||
title: 'mailForwarding',
|
|
||||||
icon: 'forward',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import('src/pages/Account/Card/AccountMailForwarding.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'AccountMailAlias',
|
|
||||||
path: 'mail-alias',
|
|
||||||
meta: {
|
|
||||||
title: 'mailAlias',
|
|
||||||
icon: 'email',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import('src/pages/Account/Card/AccountMailAlias.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'AccountPrivileges',
|
|
||||||
path: 'privileges',
|
|
||||||
meta: {
|
|
||||||
title: 'privileges',
|
|
||||||
icon: 'badge',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import('src/pages/Account/Card/AccountPrivileges.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'AccountLog',
|
|
||||||
path: 'log',
|
|
||||||
meta: {
|
|
||||||
title: 'log',
|
|
||||||
icon: 'history',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Account/Card/AccountLog.vue'),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
export default {
|
||||||
|
name: 'AccountCard',
|
||||||
|
path: ':id',
|
||||||
|
redirect: { name: 'AccountSummary' },
|
||||||
|
component: () => import('src/pages/Account/Card/AccountCard.vue'),
|
||||||
|
meta: {
|
||||||
|
menu: [
|
||||||
|
'AccountBasicData',
|
||||||
|
'AccountInheritedRoles',
|
||||||
|
'AccountMailForwarding',
|
||||||
|
'AccountMailAlias',
|
||||||
|
'AccountPrivileges',
|
||||||
|
'AccountLog',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: 'AccountSummary',
|
||||||
|
path: 'summary',
|
||||||
|
meta: {
|
||||||
|
title: 'summary',
|
||||||
|
icon: 'launch',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Account/Card/AccountSummary.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'AccountBasicData',
|
||||||
|
path: 'basic-data',
|
||||||
|
meta: {
|
||||||
|
title: 'basicData',
|
||||||
|
icon: 'vn:settings',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Account/Card/AccountBasicData.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'AccountInheritedRoles',
|
||||||
|
path: 'inherited-roles',
|
||||||
|
meta: {
|
||||||
|
title: 'inheritedRoles',
|
||||||
|
icon: 'group',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Account/Card/AccountInheritedRoles.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'AccountMailForwarding',
|
||||||
|
path: 'mail-forwarding',
|
||||||
|
meta: {
|
||||||
|
title: 'mailForwarding',
|
||||||
|
icon: 'forward',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Account/Card/AccountMailForwarding.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'AccountMailAlias',
|
||||||
|
path: 'mail-alias',
|
||||||
|
meta: {
|
||||||
|
title: 'mailAlias',
|
||||||
|
icon: 'email',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Account/Card/AccountMailAlias.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'AccountPrivileges',
|
||||||
|
path: 'privileges',
|
||||||
|
meta: {
|
||||||
|
title: 'privileges',
|
||||||
|
icon: 'badge',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Account/Card/AccountPrivileges.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'AccountLog',
|
||||||
|
path: 'log',
|
||||||
|
meta: {
|
||||||
|
title: 'log',
|
||||||
|
icon: 'history',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Account/Card/AccountLog.vue'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
|
@ -0,0 +1,36 @@
|
||||||
|
export default {
|
||||||
|
name: 'AliasCard',
|
||||||
|
path: ':id',
|
||||||
|
component: () => import('src/pages/Account/Alias/Card/AliasCard.vue'),
|
||||||
|
redirect: { name: 'AliasSummary' },
|
||||||
|
meta: { menu: ['AliasBasicData', 'AliasUsers'] },
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: 'AliasSummary',
|
||||||
|
path: 'summary',
|
||||||
|
meta: {
|
||||||
|
title: 'summary',
|
||||||
|
icon: 'launch',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Account/Alias/Card/AliasSummary.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'AliasBasicData',
|
||||||
|
path: 'basic-data',
|
||||||
|
meta: {
|
||||||
|
title: 'basicData',
|
||||||
|
icon: 'vn:settings',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Account/Alias/Card/AliasBasicData.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'AliasUsers',
|
||||||
|
path: 'users',
|
||||||
|
meta: {
|
||||||
|
title: 'aliasUsers',
|
||||||
|
icon: 'group',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Account/Alias/Card/AliasUsers.vue'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
|
@ -0,0 +1,57 @@
|
||||||
|
export default {
|
||||||
|
name: 'RoleCard',
|
||||||
|
path: ':id',
|
||||||
|
component: () => import('src/pages/Account/Role/Card/RoleCard.vue'),
|
||||||
|
redirect: { name: 'RoleSummary' },
|
||||||
|
meta: {
|
||||||
|
menu: ['RoleBasicData', 'SubRoles', 'InheritedRoles', 'RoleLog'],
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: 'RoleSummary',
|
||||||
|
path: 'summary',
|
||||||
|
meta: {
|
||||||
|
title: 'summary',
|
||||||
|
icon: 'launch',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Account/Role/Card/RoleSummary.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'RoleBasicData',
|
||||||
|
path: 'basic-data',
|
||||||
|
meta: {
|
||||||
|
title: 'basicData',
|
||||||
|
icon: 'vn:settings',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Account/Role/Card/RoleBasicData.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'SubRoles',
|
||||||
|
path: 'sub-roles',
|
||||||
|
meta: {
|
||||||
|
title: 'subRoles',
|
||||||
|
icon: 'group',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Account/Role/Card/SubRoles.vue'),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'InheritedRoles',
|
||||||
|
path: 'inherited-roles',
|
||||||
|
meta: {
|
||||||
|
title: 'inheritedRoles',
|
||||||
|
icon: 'account_tree',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Account/Role/Card/InheritedRoles.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'RoleLog',
|
||||||
|
path: 'log',
|
||||||
|
meta: {
|
||||||
|
title: 'log',
|
||||||
|
icon: 'history',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Account/Role/Card/RoleLog.vue'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
|
@ -27,7 +27,7 @@ export default {
|
||||||
{
|
{
|
||||||
name: 'ClaimMain',
|
name: 'ClaimMain',
|
||||||
path: '',
|
path: '',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
redirect: { name: 'ClaimList' },
|
redirect: { name: 'ClaimList' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,7 +39,7 @@ export default {
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
name: 'CustomerMain',
|
name: 'CustomerMain',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
redirect: { name: 'CustomerList' },
|
redirect: { name: 'CustomerList' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,7 @@ export default {
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
name: 'EntryMain',
|
name: 'EntryMain',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
redirect: { name: 'EntryList' },
|
redirect: { name: 'EntryList' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@ import Worker from './worker';
|
||||||
import Shelving from './shelving';
|
import Shelving from './shelving';
|
||||||
import Wagon from './wagon';
|
import Wagon from './wagon';
|
||||||
import Route from './route';
|
import Route from './route';
|
||||||
import Supplier from './Supplier';
|
import Supplier from './supplier';
|
||||||
import Travel from './travel';
|
import Travel from './travel';
|
||||||
import Order from './order';
|
import Order from './order';
|
||||||
import Department from './department';
|
import Department from './department';
|
||||||
|
@ -20,8 +20,6 @@ import ItemType from './itemType';
|
||||||
import Zone from './zone';
|
import Zone from './zone';
|
||||||
import Account from './account';
|
import Account from './account';
|
||||||
import Monitor from './monitor';
|
import Monitor from './monitor';
|
||||||
import MailAlias from './mailAlias';
|
|
||||||
import Role from './role';
|
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
Item,
|
Item,
|
||||||
|
@ -45,7 +43,5 @@ export default [
|
||||||
ItemType,
|
ItemType,
|
||||||
Zone,
|
Zone,
|
||||||
Account,
|
Account,
|
||||||
MailAlias,
|
|
||||||
Monitor,
|
Monitor,
|
||||||
Role,
|
|
||||||
];
|
];
|
||||||
|
|
|
@ -25,7 +25,7 @@ export default {
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
name: 'InvoiceInMain',
|
name: 'InvoiceInMain',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
redirect: { name: 'InvoiceInList' },
|
redirect: { name: 'InvoiceInList' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,7 +18,7 @@ export default {
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
name: 'InvoiceOutMain',
|
name: 'InvoiceOutMain',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
redirect: { name: 'InvoiceOutList' },
|
redirect: { name: 'InvoiceOutList' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,7 +36,7 @@ export default {
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
name: 'ItemMain',
|
name: 'ItemMain',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
redirect: { name: 'ItemList' },
|
redirect: { name: 'ItemList' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
import { RouterView } from 'vue-router';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
path: 'account/alias',
|
|
||||||
name: 'Alias',
|
|
||||||
meta: {
|
|
||||||
title: 'alias',
|
|
||||||
icon: 'email',
|
|
||||||
moduleName: 'Alias',
|
|
||||||
},
|
|
||||||
component: RouterView,
|
|
||||||
redirect: { name: 'AccountAliasList' },
|
|
||||||
menus: {
|
|
||||||
main: [],
|
|
||||||
card: ['AliasBasicData', 'AliasUsers'],
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'AliasCard',
|
|
||||||
path: ':id',
|
|
||||||
component: () => import('src/pages/Account/Alias/Card/AliasCard.vue'),
|
|
||||||
redirect: { name: 'AliasSummary' },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'AliasSummary',
|
|
||||||
path: 'summary',
|
|
||||||
meta: {
|
|
||||||
title: 'summary',
|
|
||||||
icon: 'launch',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import('src/pages/Account/Alias/Card/AliasSummary.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'AliasBasicData',
|
|
||||||
path: 'basic-data',
|
|
||||||
meta: {
|
|
||||||
title: 'basicData',
|
|
||||||
icon: 'vn:settings',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import('src/pages/Account/Alias/Card/AliasBasicData.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'AliasUsers',
|
|
||||||
path: 'users',
|
|
||||||
meta: {
|
|
||||||
title: 'aliasUsers',
|
|
||||||
icon: 'group',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import('src/pages/Account/Alias/Card/AliasUsers.vue'),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
|
@ -19,7 +19,7 @@ export default {
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
name: 'MonitorMain',
|
name: 'MonitorMain',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
props: (route) => ({ leftDrawer: route.name === 'MonitorClientsActions' }),
|
props: (route) => ({ leftDrawer: route.name === 'MonitorClientsActions' }),
|
||||||
redirect: { name: 'MonitorTickets' },
|
redirect: { name: 'MonitorTickets' },
|
||||||
children: [
|
children: [
|
||||||
|
|
|
@ -19,7 +19,7 @@ export default {
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
name: 'OrderMain',
|
name: 'OrderMain',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
redirect: { name: 'OrderList' },
|
redirect: { name: 'OrderList' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
import { RouterView } from 'vue-router';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
path: 'account/role',
|
|
||||||
name: 'Role',
|
|
||||||
meta: {
|
|
||||||
title: 'role',
|
|
||||||
icon: 'vn:greuge',
|
|
||||||
moduleName: 'Role',
|
|
||||||
},
|
|
||||||
component: RouterView,
|
|
||||||
redirect: { name: 'AccountRoles' },
|
|
||||||
menus: {
|
|
||||||
main: [],
|
|
||||||
card: ['RoleBasicData', 'SubRoles', 'InheritedRoles', 'RoleLog'],
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'RoleCard',
|
|
||||||
path: ':id',
|
|
||||||
component: () => import('src/pages/Account/Role/Card/RoleCard.vue'),
|
|
||||||
redirect: { name: 'RoleSummary' },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'RoleSummary',
|
|
||||||
path: 'summary',
|
|
||||||
meta: {
|
|
||||||
title: 'summary',
|
|
||||||
icon: 'launch',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import('src/pages/Account/Role/Card/RoleSummary.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'RoleBasicData',
|
|
||||||
path: 'basic-data',
|
|
||||||
meta: {
|
|
||||||
title: 'basicData',
|
|
||||||
icon: 'vn:settings',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import('src/pages/Account/Role/Card/RoleBasicData.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'SubRoles',
|
|
||||||
path: 'sub-roles',
|
|
||||||
meta: {
|
|
||||||
title: 'subRoles',
|
|
||||||
icon: 'group',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Account/Role/Card/SubRoles.vue'),
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
name: 'InheritedRoles',
|
|
||||||
path: 'inherited-roles',
|
|
||||||
meta: {
|
|
||||||
title: 'inheritedRoles',
|
|
||||||
icon: 'account_tree',
|
|
||||||
},
|
|
||||||
component: () =>
|
|
||||||
import('src/pages/Account/Role/Card/InheritedRoles.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'RoleLog',
|
|
||||||
path: 'log',
|
|
||||||
meta: {
|
|
||||||
title: 'log',
|
|
||||||
icon: 'history',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Account/Role/Card/RoleLog.vue'),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
|
@ -25,7 +25,7 @@ export default {
|
||||||
{
|
{
|
||||||
path: '/route',
|
path: '/route',
|
||||||
name: 'RouteMain',
|
name: 'RouteMain',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
redirect: { name: 'RouteList' },
|
redirect: { name: 'RouteList' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,7 +18,7 @@ export default {
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
name: 'ShelvingMain',
|
name: 'ShelvingMain',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
redirect: { name: 'ShelvingList' },
|
redirect: { name: 'ShelvingList' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,7 +30,7 @@ export default {
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
name: 'SupplierMain',
|
name: 'SupplierMain',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
redirect: { name: 'SupplierList' },
|
redirect: { name: 'SupplierList' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
|
@ -1,19 +1,12 @@
|
||||||
import { RouterView } from 'vue-router';
|
import { RouterView } from 'vue-router';
|
||||||
|
|
||||||
export default {
|
const ticketCard = {
|
||||||
name: 'Ticket',
|
name: 'TicketCard',
|
||||||
path: '/ticket',
|
path: ':id',
|
||||||
|
component: () => import('src/pages/Ticket/Card/TicketCard.vue'),
|
||||||
|
redirect: { name: 'TicketSummary' },
|
||||||
meta: {
|
meta: {
|
||||||
title: 'tickets',
|
menu: [
|
||||||
icon: 'vn:ticket',
|
|
||||||
moduleName: 'Ticket',
|
|
||||||
keyBinding: 't',
|
|
||||||
},
|
|
||||||
component: RouterView,
|
|
||||||
redirect: { name: 'TicketMain' },
|
|
||||||
menus: {
|
|
||||||
main: ['TicketList', 'TicketAdvance', 'TicketWeekly', 'TicketFuture'],
|
|
||||||
card: [
|
|
||||||
'TicketBasicData',
|
'TicketBasicData',
|
||||||
'TicketSale',
|
'TicketSale',
|
||||||
'TicketLog',
|
'TicketLog',
|
||||||
|
@ -32,65 +25,6 @@ export default {
|
||||||
'TicketSms',
|
'TicketSms',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'TicketMain',
|
|
||||||
path: '',
|
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
|
||||||
redirect: { name: 'TicketList' },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'list',
|
|
||||||
name: 'TicketList',
|
|
||||||
meta: {
|
|
||||||
title: 'list',
|
|
||||||
icon: 'view_list',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Ticket/TicketList.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
name: 'TicketCreate',
|
|
||||||
meta: {
|
|
||||||
title: 'createTicket',
|
|
||||||
icon: 'vn:ticketAdd',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Ticket/TicketCreate.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'weekly',
|
|
||||||
name: 'TicketWeekly',
|
|
||||||
meta: {
|
|
||||||
title: 'weeklyTickets',
|
|
||||||
icon: 'access_time',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Ticket/TicketWeekly.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'future',
|
|
||||||
name: 'TicketFuture',
|
|
||||||
meta: {
|
|
||||||
title: 'futureTickets',
|
|
||||||
icon: 'keyboard_double_arrow_right',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Ticket/TicketFuture.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'TicketAdvance',
|
|
||||||
path: 'advance',
|
|
||||||
meta: {
|
|
||||||
title: 'ticketAdvance',
|
|
||||||
icon: 'keyboard_double_arrow_left',
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Ticket/TicketAdvance.vue'),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'TicketCard',
|
|
||||||
path: ':id',
|
|
||||||
component: () => import('src/pages/Ticket/Card/TicketCard.vue'),
|
|
||||||
redirect: { name: 'TicketSummary' },
|
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'summary',
|
path: 'summary',
|
||||||
|
@ -127,8 +61,7 @@ export default {
|
||||||
title: 'purchaseRequest',
|
title: 'purchaseRequest',
|
||||||
icon: 'vn:buyrequest',
|
icon: 'vn:buyrequest',
|
||||||
},
|
},
|
||||||
component: () =>
|
component: () => import('src/pages/Ticket/Card/TicketPurchaseRequest.vue'),
|
||||||
import('src/pages/Ticket/Card/TicketPurchaseRequest.vue'),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'tracking',
|
path: 'tracking',
|
||||||
|
@ -219,8 +152,7 @@ export default {
|
||||||
title: 'saleTracking',
|
title: 'saleTracking',
|
||||||
icon: 'assignment',
|
icon: 'assignment',
|
||||||
},
|
},
|
||||||
component: () =>
|
component: () => import('src/pages/Ticket/Card/TicketSaleTracking.vue'),
|
||||||
import('src/pages/Ticket/Card/TicketSaleTracking.vue'),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'dms',
|
path: 'dms',
|
||||||
|
@ -250,6 +182,81 @@ export default {
|
||||||
component: () => import('src/pages/Ticket/Card/TicketSms.vue'),
|
component: () => import('src/pages/Ticket/Card/TicketSms.vue'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Ticket',
|
||||||
|
path: '/ticket',
|
||||||
|
meta: {
|
||||||
|
title: 'tickets',
|
||||||
|
icon: 'vn:ticket',
|
||||||
|
moduleName: 'Ticket',
|
||||||
|
keyBinding: 't',
|
||||||
|
menu: ['TicketList', 'TicketAdvance', 'TicketWeekly', 'TicketFuture'],
|
||||||
|
},
|
||||||
|
component: RouterView,
|
||||||
|
redirect: { name: 'TicketMain' },
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: 'TicketMain',
|
||||||
|
path: '',
|
||||||
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
|
redirect: { name: 'TicketIndexMain' },
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
name: 'TicketIndexMain',
|
||||||
|
redirect: { name: 'TicketList' },
|
||||||
|
component: () => import('src/pages/Ticket/TicketList.vue'),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: 'TicketList',
|
||||||
|
path: 'list',
|
||||||
|
meta: {
|
||||||
|
title: 'list',
|
||||||
|
icon: 'view_list',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ticketCard,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'create',
|
||||||
|
name: 'TicketCreate',
|
||||||
|
meta: {
|
||||||
|
title: 'createTicket',
|
||||||
|
icon: 'vn:ticketAdd',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Ticket/TicketCreate.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'weekly',
|
||||||
|
name: 'TicketWeekly',
|
||||||
|
meta: {
|
||||||
|
title: 'weeklyTickets',
|
||||||
|
icon: 'access_time',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Ticket/TicketWeekly.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'future',
|
||||||
|
name: 'TicketFuture',
|
||||||
|
meta: {
|
||||||
|
title: 'futureTickets',
|
||||||
|
icon: 'keyboard_double_arrow_right',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Ticket/TicketFuture.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TicketAdvance',
|
||||||
|
path: 'advance',
|
||||||
|
meta: {
|
||||||
|
title: 'ticketAdvance',
|
||||||
|
icon: 'keyboard_double_arrow_left',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Ticket/TicketAdvance.vue'),
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,7 +18,7 @@ export default {
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
name: 'TravelMain',
|
name: 'TravelMain',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
redirect: { name: 'TravelList' },
|
redirect: { name: 'TravelList' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,7 +18,7 @@ export default {
|
||||||
{
|
{
|
||||||
path: '/wagon',
|
path: '/wagon',
|
||||||
name: 'WagonMain',
|
name: 'WagonMain',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
redirect: { name: 'WagonList' },
|
redirect: { name: 'WagonList' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -62,7 +62,7 @@ export default {
|
||||||
{
|
{
|
||||||
path: '/wagon/type',
|
path: '/wagon/type',
|
||||||
name: 'WagonTypeMain',
|
name: 'WagonTypeMain',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
redirect: { name: 'WagonTypeList' },
|
redirect: { name: 'WagonTypeList' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,7 +35,7 @@ export default {
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
name: 'WorkerMain',
|
name: 'WorkerMain',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
redirect: { name: 'WorkerList' },
|
redirect: { name: 'WorkerList' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,7 +30,7 @@ export default {
|
||||||
{
|
{
|
||||||
path: '/zone',
|
path: '/zone',
|
||||||
name: 'ZoneMain',
|
name: 'ZoneMain',
|
||||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
component: () => import('src/components/common/VnModule.vue'),
|
||||||
redirect: { name: 'ZoneList' },
|
redirect: { name: 'ZoneList' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,10 +7,9 @@ import worker from './modules/worker';
|
||||||
import invoiceOut from './modules/invoiceOut';
|
import invoiceOut from './modules/invoiceOut';
|
||||||
import invoiceIn from './modules/invoiceIn';
|
import invoiceIn from './modules/invoiceIn';
|
||||||
import wagon from './modules/wagon';
|
import wagon from './modules/wagon';
|
||||||
import supplier from './modules/Supplier';
|
import supplier from './modules/supplier';
|
||||||
import travel from './modules/travel';
|
import travel from './modules/travel';
|
||||||
import department from './modules/department';
|
import department from './modules/department';
|
||||||
import role from './modules/role';
|
|
||||||
import ItemType from './modules/itemType';
|
import ItemType from './modules/itemType';
|
||||||
import shelving from 'src/router/modules/shelving';
|
import shelving from 'src/router/modules/shelving';
|
||||||
import order from 'src/router/modules/order';
|
import order from 'src/router/modules/order';
|
||||||
|
@ -21,7 +20,6 @@ import agency from 'src/router/modules/agency';
|
||||||
import zone from 'src/router/modules/zone';
|
import zone from 'src/router/modules/zone';
|
||||||
import account from './modules/account';
|
import account from './modules/account';
|
||||||
import monitor from 'src/router/modules/monitor';
|
import monitor from 'src/router/modules/monitor';
|
||||||
import mailAlias from './modules/mailAlias';
|
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
|
@ -95,8 +93,6 @@ const routes = [
|
||||||
ItemType,
|
ItemType,
|
||||||
zone,
|
zone,
|
||||||
account,
|
account,
|
||||||
role,
|
|
||||||
mailAlias,
|
|
||||||
{
|
{
|
||||||
path: '/:catchAll(.*)*',
|
path: '/:catchAll(.*)*',
|
||||||
name: 'NotFound',
|
name: 'NotFound',
|
||||||
|
|
|
@ -51,10 +51,15 @@ export const useArrayDataStore = defineStore('arrayDataStore', () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetPagination(key) {
|
||||||
|
reset(key, ['skip', 'filter.skip', 'page']);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
get,
|
get,
|
||||||
set,
|
set,
|
||||||
clear,
|
clear,
|
||||||
reset,
|
reset,
|
||||||
|
resetPagination,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,10 +7,10 @@ describe('VnSearchBar', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
||||||
cy.visit('#/customer/list');
|
cy.visit('#/account/list');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should redirect to customer summary page', () => {
|
it('should redirect to account summary page', () => {
|
||||||
searchAndCheck('1', employeeId);
|
searchAndCheck('1', employeeId);
|
||||||
searchAndCheck('salesPerson', salesPersonId);
|
searchAndCheck('salesPerson', salesPersonId);
|
||||||
});
|
});
|
||||||
|
@ -20,7 +20,6 @@ describe('VnSearchBar', () => {
|
||||||
checkTableLength(2);
|
checkTableLength(2);
|
||||||
|
|
||||||
cy.clearSearchbar();
|
cy.clearSearchbar();
|
||||||
|
|
||||||
cy.writeSearchbar('0{enter}');
|
cy.writeSearchbar('0{enter}');
|
||||||
checkTableLength(0);
|
checkTableLength(0);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { describe, expect, it, beforeAll, beforeEach } from 'vitest';
|
import { describe, expect, it, beforeAll, beforeEach, vi } from 'vitest';
|
||||||
import { createWrapper } from 'app/test/vitest/helper';
|
import { createWrapper } from 'app/test/vitest/helper';
|
||||||
import VnTable from 'src/components/VnTable/VnTable.vue';
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||||
|
|
||||||
|
@ -13,6 +13,15 @@ describe('VnTable', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
vm = wrapper.vm;
|
vm = wrapper.vm;
|
||||||
|
|
||||||
|
vi.mock('src/composables/useFilterParams', () => {
|
||||||
|
return {
|
||||||
|
useFilterParams: vi.fn(() => ({
|
||||||
|
params: {},
|
||||||
|
orders: {},
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => (vm.selected = []));
|
beforeEach(() => (vm.selected = []));
|
||||||
|
|
Loading…
Reference in New Issue
No me acaba de gustar poner leftMenu en 2 sitios. No se le puede pasar el source en el meta o algo así? Como veo que este problema ya existía antes okey... Pero yo crearía tarea o algo...
Con el refactor que he hecho ya no hará falta poner el source pq te buscara de abajo a arriba. Me lo apunto en la tarea