8197-VnCardMain #1044
|
@ -92,13 +92,13 @@ function findMatches(search, item) {
|
|||
}
|
||||
|
||||
function addChildren(module, route, parent) {
|
||||
if (route.menus) {
|
||||
const mainMenus = route.menus[props.source];
|
||||
const matches = findMatches(mainMenus, route);
|
||||
const menus = route?.meta?.menu ?? route?.menus?.[props.source]; //backwards compatible
|
||||
if (!menus) return;
|
||||
|
||||
for (const child of matches) {
|
||||
navigation.addMenuItem(module, child, parent);
|
||||
}
|
||||
const matches = findMatches(menus, route);
|
||||
|
||||
for (const child of matches) {
|
||||
navigation.addMenuItem(module, child, parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,16 +122,26 @@ function getRoutes() {
|
|||
if (props.source === 'card') {
|
||||
const currentRoute = route.matched[1];
|
||||
const currentModule = toLowerCamel(currentRoute.name);
|
||||
const moduleDef = routes.find(
|
||||
let moduleDef = routes.find(
|
||||
(route) => toLowerCamel(route.name) === currentModule
|
||||
);
|
||||
|
||||
if (!moduleDef) return;
|
||||
|
||||
if (!moduleDef?.menus) moduleDef = betaGetRoutes();
|
||||
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) {
|
||||
if (event.defaultPrevented) return;
|
||||
event.preventDefault();
|
||||
|
|
|
@ -59,6 +59,7 @@ const pinnedModulesRef = ref();
|
|||
'no-visible': !stateQuery.isLoading().value,
|
||||
}"
|
||||
size="xs"
|
||||
data-cy="loading-spinner"
|
||||
/>
|
||||
<QSpace />
|
||||
<div id="searchbar" class="searchbar"></div>
|
||||
|
|
|
@ -32,7 +32,10 @@ const $props = defineProps({
|
|||
defineExpose({ addFilter, props: $props });
|
||||
|
||||
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 updateEvent = { 'update:modelValue': addFilter };
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
<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 { useRoute, useRouter } from 'vue-router';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import { useFilterParams } from 'src/composables/useFilterParams';
|
||||
|
||||
import CrudModel from 'src/components/CrudModel.vue';
|
||||
import FormModelPopup from 'components/FormModelPopup.vue';
|
||||
|
||||
import VnFilterPanel from 'components/ui/VnFilterPanel.vue';
|
||||
import VnTableColumn from 'components/VnTable/VnColumn.vue';
|
||||
import VnFilter from 'components/VnTable/VnFilter.vue';
|
||||
import VnTableChip from 'components/VnTable/VnChip.vue';
|
||||
import VnVisibleColumn from 'src/components/VnTable/VnVisibleColumn.vue';
|
||||
import VnLv from 'components/ui/VnLv.vue';
|
||||
import VnTableOrder from 'src/components/VnTable/VnOrder.vue';
|
||||
import VnTableFilter from './VnTableFilter.vue';
|
||||
|
||||
const $props = defineProps({
|
||||
columns: {
|
||||
|
@ -33,6 +34,10 @@ const $props = defineProps({
|
|||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
rightSearchIcon: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
rowClick: {
|
||||
type: [Function, Boolean],
|
||||
default: null,
|
||||
|
@ -101,10 +106,6 @@ const $props = defineProps({
|
|||
type: String,
|
||||
default: '90vh',
|
||||
},
|
||||
chipLocale: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
footer: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
|
@ -119,22 +120,21 @@ const stateStore = useStateStore();
|
|||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const quasar = useQuasar();
|
||||
const $attrs = useAttrs();
|
||||
|
||||
const CARD_MODE = 'card';
|
||||
const TABLE_MODE = 'table';
|
||||
const mode = ref(CARD_MODE);
|
||||
const selected = ref([]);
|
||||
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 showForm = ref(false);
|
||||
const splittedColumns = ref({ columns: [] });
|
||||
const columnsVisibilitySkipped = ref();
|
||||
const createForm = ref();
|
||||
const tableFilterRef = ref([]);
|
||||
const tableRef = ref();
|
||||
const params = ref(useFilterParams($attrs['data-key']).params);
|
||||
const orders = ref(useFilterParams($attrs['data-key']).orders);
|
||||
|
||||
const tableModes = [
|
||||
{
|
||||
|
@ -183,41 +183,8 @@ watch(
|
|||
{ immediate: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
() => route.query[$props.searchUrl],
|
||||
(val) => setUserParams(val),
|
||||
{ immediate: true, deep: true }
|
||||
);
|
||||
|
||||
const isTableMode = computed(() => mode.value == TABLE_MODE);
|
||||
|
||||
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;
|
||||
}
|
||||
const showRightIcon = computed(() => $props.rightSearch || $props.rightSearchIcon);
|
||||
|
||||
function splitColumns(columns) {
|
||||
splittedColumns.value = {
|
||||
|
@ -298,17 +265,6 @@ function getColAlign(col) {
|
|||
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']);
|
||||
defineExpose({
|
||||
create: createForm,
|
||||
|
@ -357,61 +313,7 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
|
|||
show-if-above
|
||||
>
|
||||
<QScrollArea class="fit">
|
||||
<VnFilterPanel
|
||||
: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>
|
||||
<VnTableFilter :data-key="$attrs['data-key']" :columns="columns" />
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<CrudModel
|
||||
|
@ -467,7 +369,7 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
|
|||
:options="tableModes.filter((mode) => !mode.disable)"
|
||||
/>
|
||||
<QBtn
|
||||
v-if="$props.rightSearch"
|
||||
v-if="showRightIcon"
|
||||
icon="filter_alt"
|
||||
class="bg-vn-section-color q-ml-sm"
|
||||
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(() => {
|
||||
matched.value = currentRoute.value.matched.filter(
|
||||
(matched) => Object.keys(matched.meta).length
|
||||
(matched) => !!matched?.meta?.title || !!matched?.meta?.icon
|
||||
);
|
||||
breadcrumbs.value.length = 0;
|
||||
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>
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import LeftMenu from 'components/LeftMenu.vue';
|
||||
import { onMounted } from 'vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useQuasar } from 'quasar';
|
||||
import LeftMenu from '../LeftMenu.vue';
|
||||
|
||||
const stateStore = useStateStore();
|
||||
const $props = defineProps({
|
||||
|
@ -14,12 +14,30 @@ const $props = defineProps({
|
|||
onMounted(
|
||||
() => (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>
|
||||
|
||||
<template>
|
||||
<QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256">
|
||||
<QScrollArea class="fit text-grey-8">
|
||||
<LeftMenu />
|
||||
<div id="left-panel" ref="teleportRef"></div>
|
||||
<LeftMenu v-if="!hasContent" />
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
<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 };
|
||||
if (fields) fetchOptions.fields = fields;
|
||||
if (sortBy) fetchOptions.order = sortBy;
|
||||
arrayData.reset(['skip', 'filter.skip', 'page']);
|
||||
arrayData.resetPagination();
|
||||
|
||||
const { data } = await arrayData.applyFilter({ filter: fetchOptions });
|
||||
setOptions(data);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script setup>
|
||||
import { onMounted, ref, computed, watch } from 'vue';
|
||||
import { ref, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useArrayData } from 'composables/useArrayData';
|
||||
import { useRoute } from 'vue-router';
|
||||
import toDate from 'filters/toDate';
|
||||
import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue';
|
||||
import { useFilterParams } from 'src/composables/useFilterParams';
|
||||
|
||||
const { t } = useI18n();
|
||||
const $props = defineProps({
|
||||
|
@ -55,6 +55,10 @@ const $props = defineProps({
|
|||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
arrayData: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits([
|
||||
|
@ -66,52 +70,19 @@ const emit = defineEmits([
|
|||
'setUserParams',
|
||||
]);
|
||||
|
||||
const arrayData = useArrayData($props.dataKey, {
|
||||
exprBuilder: $props.exprBuilder,
|
||||
searchUrl: $props.searchUrl,
|
||||
navigate: $props.redirect ? {} : null,
|
||||
});
|
||||
const route = useRoute();
|
||||
const arrayData =
|
||||
$props.arrayData ??
|
||||
useArrayData($props.dataKey, {
|
||||
exprBuilder: $props.exprBuilder,
|
||||
searchUrl: $props.searchUrl,
|
||||
navigate: $props.redirect ? {} : null,
|
||||
});
|
||||
|
||||
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 });
|
||||
|
||||
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 ?? {})
|
||||
);
|
||||
defineExpose({ search, params: userParams, remove });
|
||||
|
||||
const isLoading = ref(false);
|
||||
async function search(evt) {
|
||||
|
@ -122,10 +93,9 @@ async function search(evt) {
|
|||
isLoading.value = true;
|
||||
const filter = { ...userParams.value, ...$props.modelValue };
|
||||
store.userParamsChanged = true;
|
||||
const { params: newParams } = await arrayData.addFilter({
|
||||
await arrayData.addFilter({
|
||||
params: filter,
|
||||
});
|
||||
userParams.value = newParams;
|
||||
|
||||
if (!$props.showAll && !Object.values(filter).length) store.data = [];
|
||||
emit('search');
|
||||
|
@ -138,7 +108,7 @@ async function clearFilters() {
|
|||
try {
|
||||
isLoading.value = true;
|
||||
store.userParamsChanged = true;
|
||||
arrayData.reset(['skip', 'filter.skip', 'page']);
|
||||
arrayData.resetPagination();
|
||||
// Filtrar los params no removibles
|
||||
const removableFilters = Object.keys(userParams.value).filter((param) =>
|
||||
$props.unremovableParams.includes(param)
|
||||
|
@ -148,9 +118,8 @@ async function clearFilters() {
|
|||
for (const key of removableFilters) {
|
||||
newParams[key] = userParams.value[key];
|
||||
}
|
||||
userParams.value = {};
|
||||
userParams.value = { ...newParams }; // Actualizar los params con los removibles
|
||||
await arrayData.applyFilter({ params: userParams.value });
|
||||
|
||||
await arrayData.applyFilter({ params: { ...newParams } });
|
||||
|
||||
if (!$props.showAll) {
|
||||
store.data = [];
|
||||
|
@ -212,21 +181,6 @@ function formatValue(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>
|
||||
|
||||
<template>
|
||||
|
@ -296,7 +250,12 @@ function sanitizer(params) {
|
|||
<QSeparator />
|
||||
</QList>
|
||||
<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>
|
||||
</QForm>
|
||||
<QInnerLoading
|
||||
|
|
|
@ -106,10 +106,13 @@ const store = arrayData.store;
|
|||
|
||||
onMounted(async () => {
|
||||
if (props.autoLoad && !store.data?.length) await fetch();
|
||||
else emit('onFetch', store.data);
|
||||
mounted.value = true;
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => arrayData.reset());
|
||||
onBeforeUnmount(() => {
|
||||
arrayData.resetPagination();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
|
@ -137,8 +140,8 @@ const addFilter = async (filter, params) => {
|
|||
|
||||
async function fetch(params) {
|
||||
useArrayData(props.dataKey, params);
|
||||
arrayData.reset(['filter.skip', 'skip', 'page']);
|
||||
await arrayData.fetch({ append: false, updateRouter: mounted.value });
|
||||
arrayData.resetPagination();
|
||||
await arrayData.fetch({ append: false });
|
||||
return emitStoreData();
|
||||
}
|
||||
|
||||
|
@ -200,13 +203,20 @@ async function onLoad(index, done) {
|
|||
done(isDone);
|
||||
}
|
||||
|
||||
defineExpose({ fetch, update, addFilter, paginate });
|
||||
defineExpose({
|
||||
fetch,
|
||||
update,
|
||||
addFilter,
|
||||
paginate,
|
||||
userParams: arrayData.store.userParams,
|
||||
currentFilter: arrayData.store.currentFilter,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="full-width">
|
||||
<div
|
||||
v-if="!props.autoLoad && !store.data && !isLoading"
|
||||
v-if="!store.data && !store.data?.length && !isLoading"
|
||||
class="info-row q-pa-md text-center"
|
||||
>
|
||||
<h5>
|
||||
|
|
|
@ -100,8 +100,10 @@ onMounted(() => {
|
|||
});
|
||||
|
||||
async function search() {
|
||||
const staticParams = Object.entries(store.userParams);
|
||||
arrayData.reset(['skip', 'page']);
|
||||
const staticParams = Object.keys(store.userParams ?? {}).length
|
||||
? store.userParams
|
||||
: store.defaultParams;
|
||||
arrayData.resetPagination();
|
||||
|
||||
const filter = {
|
||||
params: {
|
||||
|
@ -112,7 +114,7 @@ async function search() {
|
|||
|
||||
if (!props.searchRemoveParams || !searchText.value) {
|
||||
filter.params = {
|
||||
...Object.fromEntries(staticParams),
|
||||
...staticParams,
|
||||
search: searchText.value,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -25,11 +25,14 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
|||
const searchUrl = store.searchUrl;
|
||||
if (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;
|
||||
|
||||
store.userParams = { ...store.userParams, ...params };
|
||||
store.userFilter = { ...filter, ...store.userFilter };
|
||||
store.filter = { ...filter, ...store.userFilter };
|
||||
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)
|
||||
? Object.assign(defaultOpts, store[option])
|
||||
: defaultOpts;
|
||||
if (option === 'userParams') store.defaultParams = store[option];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +79,6 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
|||
const filter = {
|
||||
limit: store.limit,
|
||||
};
|
||||
|
||||
let userParams = { ...store.userParams };
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
function resetPagination() {
|
||||
if (arrayDataStore.get(key)) arrayDataStore.resetPagination(key);
|
||||
}
|
||||
|
||||
function cancelRequest() {
|
||||
if (canceller) {
|
||||
canceller.abort();
|
||||
|
@ -166,7 +173,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
|||
userParams = sanitizerParams(userParams, store?.exprBuilder);
|
||||
|
||||
store.userParams = userParams;
|
||||
reset(['skip', 'filter.skip', 'page']);
|
||||
resetPagination();
|
||||
|
||||
await fetch({});
|
||||
return { filter, params };
|
||||
|
@ -193,7 +200,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
|||
}
|
||||
|
||||
store.order = order;
|
||||
reset(['skip', 'filter.skip', 'page']);
|
||||
resetPagination();
|
||||
fetch({});
|
||||
index++;
|
||||
|
||||
|
@ -276,7 +283,6 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
|||
const pushUrl = { path: to };
|
||||
if (to.endsWith('/list') || to.endsWith('/'))
|
||||
pushUrl.query = newUrl.query;
|
||||
else destroy();
|
||||
return router.push(pushUrl);
|
||||
}
|
||||
}
|
||||
|
@ -328,5 +334,6 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
|||
isLoading,
|
||||
deleteOption,
|
||||
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>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { ref, computed } from 'vue';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import axios from 'axios';
|
||||
import useNotify from 'src/composables/useNotify.js';
|
||||
import { useQuasar } from 'quasar';
|
||||
|
||||
import VnTable from 'components/VnTable/VnTable.vue';
|
||||
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
||||
import VnConfirm from 'components/ui/VnConfirm.vue';
|
||||
import FetchData from 'src/components/FetchData.vue';
|
||||
import { useValidator } from 'src/composables/useValidator';
|
||||
import VnSection from 'src/components/common/VnSection.vue';
|
||||
|
||||
defineProps({
|
||||
id: {
|
||||
|
@ -21,13 +20,13 @@ defineProps({
|
|||
|
||||
const { notify } = useNotify();
|
||||
const { t } = useI18n();
|
||||
const stateStore = useStateStore();
|
||||
const quasar = useQuasar();
|
||||
|
||||
const tableRef = ref();
|
||||
const roles = ref();
|
||||
const validationsStore = useValidator();
|
||||
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) => {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
|
@ -134,38 +133,40 @@ const deleteAcl = async ({ id }) => {
|
|||
</script>
|
||||
|
||||
<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
|
||||
url="VnRoles?fields=['name']"
|
||||
auto-load
|
||||
@on-fetch="(data) => (roles = data)"
|
||||
/>
|
||||
<VnTable
|
||||
ref="tableRef"
|
||||
data-key="AccountAcls"
|
||||
:url="`ACLs`"
|
||||
:create="{
|
||||
urlCreate: 'ACLs',
|
||||
title: 'Create ACL',
|
||||
onDataSaved: () => tableRef.reload(),
|
||||
formInitialData: {},
|
||||
}"
|
||||
order="id DESC"
|
||||
:disable-option="{ card: true }"
|
||||
<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"
|
||||
default-mode="table"
|
||||
:right-search="true"
|
||||
:is-editable="true"
|
||||
:use-model="true"
|
||||
/>
|
||||
prefix="acls"
|
||||
:array-data-props="{
|
||||
url: 'ACLs',
|
||||
order: 'id DESC',
|
||||
exprBuilder,
|
||||
}"
|
||||
>
|
||||
<template #body>
|
||||
<VnTable
|
||||
ref="tableRef"
|
||||
:data-key="dataKey"
|
||||
:create="{
|
||||
urlCreate: 'ACLs',
|
||||
title: 'Create ACL',
|
||||
onDataSaved: () => tableRef.reload(),
|
||||
formInitialData: {},
|
||||
}"
|
||||
:disable-option="{ card: true }"
|
||||
:columns="columns"
|
||||
default-mode="table"
|
||||
:right-search="false"
|
||||
:is-editable="true"
|
||||
:use-model="true"
|
||||
/>
|
||||
</template>
|
||||
</VnSection>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
|
|
|
@ -2,21 +2,12 @@
|
|||
import { useI18n } from 'vue-i18n';
|
||||
import { ref, computed } from 'vue';
|
||||
import VnTable from 'components/VnTable/VnTable.vue';
|
||||
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import VnSection from 'src/components/common/VnSection.vue';
|
||||
|
||||
const tableRef = ref();
|
||||
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(() => [
|
||||
{
|
||||
align: 'left',
|
||||
|
@ -40,40 +31,45 @@ const columns = computed(() => [
|
|||
create: true,
|
||||
},
|
||||
]);
|
||||
|
||||
const exprBuilder = (param, value) => {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
return /^\d+$/.test(value)
|
||||
? { id: value }
|
||||
: { alias: { like: `%${value}%` } };
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<template v-if="stateStore.isHeaderMounted()">
|
||||
<Teleport to="#searchbar">
|
||||
<VnSearchbar
|
||||
data-key="AccountAliasList"
|
||||
url="MailAliases"
|
||||
:expr-builder="exprBuilder"
|
||||
:label="t('mailAlias.search')"
|
||||
:info="t('mailAlias.searchInfo')"
|
||||
/>
|
||||
</Teleport>
|
||||
</template>
|
||||
<VnTable
|
||||
ref="tableRef"
|
||||
data-key="AccountAliasList"
|
||||
url="MailAliases"
|
||||
:create="{
|
||||
urlCreate: 'MailAliases',
|
||||
title: 'Create MailAlias',
|
||||
onDataSaved: ({ id }) => tableRef.redirect(id),
|
||||
formInitialData: {},
|
||||
}"
|
||||
order="id DESC"
|
||||
<VnSection
|
||||
:data-key="dataKey"
|
||||
alexm marked this conversation as resolved
jorgep
commented
Lo mismo que el AccountAcls Lo mismo que el AccountAcls
|
||||
:columns="columns"
|
||||
:disable-option="{ card: true }"
|
||||
default-mode="table"
|
||||
redirect="account/alias"
|
||||
:is-editable="true"
|
||||
:use-model="true"
|
||||
/>
|
||||
prefix="mailAlias"
|
||||
:array-data-props="{ url: 'MailAliases', order: 'id DESC', exprBuilder }"
|
||||
>
|
||||
<template #body>
|
||||
<VnTable
|
||||
:data-key="dataKey"
|
||||
ref="tableRef"
|
||||
:create="{
|
||||
urlCreate: 'MailAliases',
|
||||
title: 'Create MailAlias',
|
||||
onDataSaved: ({ id }) => tableRef.redirect(id),
|
||||
formInitialData: {},
|
||||
}"
|
||||
:columns="columns"
|
||||
:disable-option="{ card: true }"
|
||||
default-mode="table"
|
||||
redirect="account/alias"
|
||||
:is-editable="true"
|
||||
:use-model="true"
|
||||
:right-search="false"
|
||||
/>
|
||||
</template>
|
||||
</VnSection>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
es:
|
||||
Id: Id
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
<script setup>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { ref, computed } from 'vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import VnTable from 'components/VnTable/VnTable.vue';
|
||||
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
||||
import AccountSummary from './Card/AccountSummary.vue';
|
||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||
import AccountFilter from './AccountFilter.vue';
|
||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
||||
import VnSection from 'src/components/common/VnSection.vue';
|
||||
import FetchData from 'src/components/FetchData.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const { viewSummary } = useSummaryDialog();
|
||||
const tableRef = ref();
|
||||
const filter = {
|
||||
include: { relation: 'role', scope: { fields: ['id', 'name'] } },
|
||||
};
|
||||
const dataKey = 'AccountList';
|
||||
const roles = ref([]);
|
||||
const columns = computed(() => [
|
||||
{
|
||||
align: 'left',
|
||||
|
@ -30,7 +31,7 @@ const columns = computed(() => [
|
|||
component: 'select',
|
||||
name: 'roleFk',
|
||||
attrs: {
|
||||
url: 'VnRoles',
|
||||
options: roles,
|
||||
optionValue: 'id',
|
||||
optionLabel: 'name',
|
||||
},
|
||||
|
@ -82,7 +83,8 @@ const columns = computed(() => [
|
|||
],
|
||||
},
|
||||
]);
|
||||
const exprBuilder = (param, value) => {
|
||||
|
||||
function exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
return /^\d+$/.test(value)
|
||||
|
@ -99,35 +101,33 @@ const exprBuilder = (param, value) => {
|
|||
case 'roleFk':
|
||||
return { [param]: value };
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VnSearchbar
|
||||
data-key="AccountList"
|
||||
:expr-builder="exprBuilder"
|
||||
:label="t('account.search')"
|
||||
:info="t('account.searchInfo')"
|
||||
:filter="filter"
|
||||
/>
|
||||
<RightMenu>
|
||||
<template #right-panel>
|
||||
<AccountFilter data-key="AccountList" />
|
||||
</template>
|
||||
</RightMenu>
|
||||
<VnTable
|
||||
ref="tableRef"
|
||||
data-key="AccountList"
|
||||
url="VnUsers/preview"
|
||||
:filter="filter"
|
||||
order="id DESC"
|
||||
<FetchData url="VnRoles" @on-fetch="(data) => (roles = data)" auto-load />
|
||||
<VnSection
|
||||
:data-key="dataKey"
|
||||
:columns="columns"
|
||||
default-mode="table"
|
||||
redirect="account"
|
||||
:use-model="true"
|
||||
:right-search="false"
|
||||
auto-load
|
||||
/>
|
||||
prefix="account"
|
||||
:array-data-props="{
|
||||
url: 'VnUsers/preview',
|
||||
userFilter: filter,
|
||||
order: 'id DESC',
|
||||
exprBuilder,
|
||||
}"
|
||||
>
|
||||
<template #body>
|
||||
<VnTable
|
||||
:data-key="dataKey"
|
||||
:columns="columns"
|
||||
default-mode="table"
|
||||
redirect="account"
|
||||
:use-model="true"
|
||||
:right-search="false"
|
||||
/>
|
||||
</template>
|
||||
</VnSection>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<script setup>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import VnCard from 'components/common/VnCard.vue';
|
||||
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
||||
import AliasDescriptor from './AliasDescriptor.vue';
|
||||
const { t } = useI18n();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VnCard
|
||||
<VnCardBeta
|
||||
data-key="Alias"
|
||||
base-url="MailAliases"
|
||||
:descriptor="AliasDescriptor"
|
||||
|
|
|
@ -1,20 +1,8 @@
|
|||
<script setup>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import VnCard from 'components/common/VnCard.vue';
|
||||
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
||||
import AccountDescriptor from './AccountDescriptor.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VnCard
|
||||
data-key="Account"
|
||||
:descriptor="AccountDescriptor"
|
||||
search-data-key="AccountList"
|
||||
:searchbar-props="{
|
||||
url: 'VnUsers/preview',
|
||||
label: t('account.search'),
|
||||
info: t('account.searchInfo'),
|
||||
}"
|
||||
/>
|
||||
<VnCardBeta data-key="AccountId" :descriptor="AccountDescriptor" />
|
||||
</template>
|
||||
|
|
|
@ -41,7 +41,7 @@ const hasAccount = ref(false);
|
|||
/>
|
||||
<CardDescriptor
|
||||
ref="descriptor"
|
||||
:url="`VnUsers/preview`"
|
||||
url="VnUsers/preview"
|
||||
:filter="filter"
|
||||
module="Account"
|
||||
@on-fetch="setData"
|
||||
|
|
|
@ -30,7 +30,7 @@ const filter = {
|
|||
|
||||
<template>
|
||||
<CardSummary
|
||||
data-key="AccountSummary"
|
||||
data-key="AccountId"
|
||||
ref="AccountSummary"
|
||||
url="VnUsers/preview"
|
||||
:filter="filter"
|
||||
|
|
|
@ -3,11 +3,13 @@ import { useI18n } from 'vue-i18n';
|
|||
import { computed, ref } from 'vue';
|
||||
import VnTable from 'components/VnTable/VnTable.vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||
import RoleSummary from './Card/RoleSummary.vue';
|
||||
import VnSection from 'src/components/common/VnSection.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
const { viewSummary } = useSummaryDialog();
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
|
@ -15,8 +17,10 @@ const $props = defineProps({
|
|||
},
|
||||
});
|
||||
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 { viewSummary } = useSummaryDialog();
|
||||
const columns = computed(() => [
|
||||
{
|
||||
align: 'left',
|
||||
|
@ -81,30 +85,32 @@ const exprBuilder = (param, value) => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<VnSearchbar
|
||||
data-key="AccountRolesList"
|
||||
:expr-builder="exprBuilder"
|
||||
:label="t('role.searchRoles')"
|
||||
:info="t('role.searchInfo')"
|
||||
/>
|
||||
<VnTable
|
||||
ref="tableRef"
|
||||
data-key="AccountRolesList"
|
||||
:url="`VnRoles`"
|
||||
:create="{
|
||||
urlCreate: 'VnRoles',
|
||||
title: t('Create rol'),
|
||||
onDataSaved: ({ id }) => tableRef.redirect(id),
|
||||
formInitialData: {
|
||||
editorFk: entityId,
|
||||
},
|
||||
}"
|
||||
order="id ASC"
|
||||
:disable-option="{ card: true }"
|
||||
<VnSection
|
||||
:data-key="dataKey"
|
||||
alexm marked this conversation as resolved
jorgep
commented
Lo mismo que AccountAcls Lo mismo que AccountAcls
|
||||
:columns="columns"
|
||||
default-mode="table"
|
||||
redirect="account/role"
|
||||
/>
|
||||
prefix="role"
|
||||
:array-data-props="{ url, exprBuilder, order: 'id ASC' }"
|
||||
>
|
||||
<template #body>
|
||||
<VnTable
|
||||
ref="tableRef"
|
||||
:data-key="dataKey"
|
||||
:create="{
|
||||
urlCreate: 'VnRoles',
|
||||
title: t('Create rol'),
|
||||
onDataSaved: ({ id }) => tableRef.redirect(id),
|
||||
formInitialData: {
|
||||
editorFk: entityId,
|
||||
},
|
||||
}"
|
||||
:disable-option="{ card: true }"
|
||||
:columns="columns"
|
||||
default-mode="table"
|
||||
redirect="account/role"
|
||||
:right-search="false"
|
||||
/>
|
||||
</template>
|
||||
</VnSection>
|
||||
</template>
|
||||
|
||||
<i18n>
|
||||
|
|
|
@ -1,20 +1,7 @@
|
|||
<script setup>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import VnCard from 'components/common/VnCard.vue';
|
||||
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
||||
import RoleDescriptor from './RoleDescriptor.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
</script>
|
||||
<template>
|
||||
<VnCard
|
||||
data-key="Role"
|
||||
:descriptor="RoleDescriptor"
|
||||
search-data-key="AccountRolesList"
|
||||
:searchbar-props="{
|
||||
url: 'VnRoles',
|
||||
label: t('role.searchRoles'),
|
||||
info: t('role.searchInfo'),
|
||||
searchUrl: 'table',
|
||||
}"
|
||||
/>
|
||||
<VnCardBeta data-key="Role" :descriptor="RoleDescriptor" />
|
||||
</template>
|
||||
|
|
|
@ -43,7 +43,7 @@ const removeRole = async () => {
|
|||
:filter="filter"
|
||||
module="Role"
|
||||
@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"
|
||||
:subtitle="data.subtitle"
|
||||
:summary="$props.summary"
|
||||
|
|
|
@ -27,10 +27,10 @@ const filter = {
|
|||
<template>
|
||||
<CardSummary
|
||||
ref="summary"
|
||||
:url="`VnRoles`"
|
||||
:url="`VnRoles/${entityId}`"
|
||||
:filter="filter"
|
||||
@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 #body>
|
||||
|
|
|
@ -66,7 +66,7 @@ account:
|
|||
mailInputInfo: All emails will be forwarded to the specified address.
|
||||
role:
|
||||
newRole: New role
|
||||
searchRoles: Search role
|
||||
search: Search role
|
||||
searchInfo: Search role by id or name
|
||||
description: Description
|
||||
id: Id
|
||||
|
|
|
@ -419,7 +419,6 @@ function handleLocation(data, location) {
|
|||
:columns="columns"
|
||||
redirect="customer"
|
||||
:right-search="false"
|
||||
auto-load
|
||||
>
|
||||
<template #more-create-dialog="{ data }">
|
||||
<VnSelect
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
<script setup>
|
||||
import axios from 'axios';
|
||||
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 { useRouter } from 'vue-router';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
|
||||
const router = useRouter();
|
||||
const stateStore = useStateStore();
|
||||
const { t } = useI18n();
|
||||
const quasar = useQuasar();
|
||||
|
||||
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();
|
||||
});
|
||||
|
||||
|
@ -84,74 +87,69 @@ async function getVideoList(expeditionId, timed) {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<QDrawer show-if-above side="right">
|
||||
<QScrollArea class="fit">
|
||||
<QList bordered separator style="max-width: 318px">
|
||||
<QItem v-if="lastExpedition && videoList.length">
|
||||
<QItemSection>
|
||||
<QItemLabel class="text-h6">
|
||||
{{ t('ticket.boxing.selectTime') }} ({{ time.min }}-{{
|
||||
time.max
|
||||
}})
|
||||
</QItemLabel>
|
||||
<QRange
|
||||
v-model="time"
|
||||
@change="getVideoList(lastExpedition, time)"
|
||||
:min="0"
|
||||
:max="24"
|
||||
:step="1"
|
||||
:left-label-value="time.min + ':00'"
|
||||
:right-label-value="time.max + ':00'"
|
||||
label
|
||||
markers
|
||||
snap
|
||||
color="primary"
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="lastExpedition && videoList.length">
|
||||
<QItemSection>
|
||||
<QSelect
|
||||
color="primary"
|
||||
v-model="slide"
|
||||
:options="videoList"
|
||||
:label="t('ticket.boxing.selectVideo')"
|
||||
emit-value
|
||||
map-options
|
||||
>
|
||||
<template #prepend>
|
||||
<QIcon name="schedule" />
|
||||
</template>
|
||||
</QSelect>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem
|
||||
v-for="expedition in expeditions"
|
||||
:key="expedition.id"
|
||||
@click="getVideoList(expedition.id)"
|
||||
clickable
|
||||
v-ripple
|
||||
>
|
||||
<QItemSection>
|
||||
<QItemLabel class="text-h6">#{{ expedition.id }}</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{ t('globals.created') }}</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{
|
||||
date.formatDate(expedition.created, 'YYYY-MM-DD HH:mm:ss')
|
||||
}}
|
||||
</QItemLabel>
|
||||
<QItemLabel caption>{{ t('globals.item') }}</QItemLabel>
|
||||
<QItemLabel>{{ expedition.packagingItemFk }}</QItemLabel>
|
||||
<QItemLabel caption>{{ t('ticket.boxing.worker') }}</QItemLabel>
|
||||
<QItemLabel>{{ expedition.userName }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</QScrollArea>
|
||||
</QDrawer>
|
||||
|
||||
<Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()">
|
||||
<QList bordered separator style="max-width: 318px">
|
||||
<QItem v-if="lastExpedition && videoList.length">
|
||||
<QItemSection>
|
||||
<QItemLabel class="text-h6">
|
||||
{{ t('ticket.boxing.selectTime') }} ({{ time.min }}-{{
|
||||
time.max
|
||||
}})
|
||||
</QItemLabel>
|
||||
<QRange
|
||||
v-model="time"
|
||||
@change="getVideoList(lastExpedition, time)"
|
||||
:min="0"
|
||||
:max="24"
|
||||
:step="1"
|
||||
:left-label-value="time.min + ':00'"
|
||||
:right-label-value="time.max + ':00'"
|
||||
label
|
||||
markers
|
||||
snap
|
||||
color="primary"
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="lastExpedition && videoList.length">
|
||||
<QItemSection>
|
||||
<QSelect
|
||||
color="primary"
|
||||
v-model="slide"
|
||||
:options="videoList"
|
||||
:label="t('ticket.boxing.selectVideo')"
|
||||
emit-value
|
||||
map-options
|
||||
>
|
||||
<template #prepend>
|
||||
<QIcon name="schedule" />
|
||||
</template>
|
||||
</QSelect>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem
|
||||
v-for="expedition in expeditions"
|
||||
:key="expedition.id"
|
||||
@click="getVideoList(expedition.id)"
|
||||
clickable
|
||||
v-ripple
|
||||
>
|
||||
<QItemSection>
|
||||
<QItemLabel class="text-h6">#{{ expedition.id }}</QItemLabel>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel caption>{{ t('globals.created') }}</QItemLabel>
|
||||
<QItemLabel>
|
||||
{{ date.formatDate(expedition.created, 'YYYY-MM-DD HH:mm:ss') }}
|
||||
</QItemLabel>
|
||||
<QItemLabel caption>{{ t('globals.item') }}</QItemLabel>
|
||||
<QItemLabel>{{ expedition.packagingItemFk }}</QItemLabel>
|
||||
<QItemLabel caption>{{ t('ticket.boxing.worker') }}</QItemLabel>
|
||||
<QItemLabel>{{ expedition.userName }}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
</Teleport>
|
||||
<QCard>
|
||||
<QCarousel animated v-model="slide" height="max-content">
|
||||
<QCarouselSlide
|
||||
|
|
|
@ -1,23 +1,7 @@
|
|||
<script setup>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import VnCard from 'components/common/VnCard.vue';
|
||||
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
||||
import TicketDescriptor from './TicketDescriptor.vue';
|
||||
import TicketFilter from '../TicketFilter.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
</script>
|
||||
<template>
|
||||
<VnCard
|
||||
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'),
|
||||
}"
|
||||
/>
|
||||
<VnCardBeta data-key="Ticket" base-url="Tickets" :descriptor="TicketDescriptor" />
|
||||
</template>
|
||||
|
|
|
@ -8,13 +8,11 @@ import { useQuasar } from 'quasar';
|
|||
import { toDate, toCurrency, dashIfEmpty } from 'src/filters/index';
|
||||
import useNotify from 'src/composables/useNotify';
|
||||
import TicketSummary from './Card/TicketSummary.vue';
|
||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||
import VnRow from 'src/components/ui/VnRow.vue';
|
||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
||||
import TicketFilter from './TicketFilter.vue';
|
||||
import VnInput from 'src/components/common/VnInput.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 InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
|
||||
import TicketProblems from 'src/components/TicketProblems.vue';
|
||||
import VnSection from 'src/components/common/VnSection.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
@ -66,6 +65,7 @@ const dialogData = ref();
|
|||
const companiesOptions = ref([]);
|
||||
const accountingOptions = ref([]);
|
||||
const amountToReturn = ref();
|
||||
const dataKey = 'TicketList';
|
||||
|
||||
const columns = computed(() => [
|
||||
{
|
||||
|
@ -452,223 +452,228 @@ function setReference(data) {
|
|||
@on-fetch="(data) => (accountingOptions = data)"
|
||||
auto-load
|
||||
/>
|
||||
<VnSearchbar
|
||||
data-key="TicketList"
|
||||
:label="t('Search ticket')"
|
||||
:info="t('You can search by ticket id or alias')"
|
||||
data-cy="ticketListSearchBar"
|
||||
/>
|
||||
<RightMenu>
|
||||
<template #right-panel>
|
||||
<VnSection
|
||||
:data-key="dataKey"
|
||||
:columns="columns"
|
||||
prefix="card"
|
||||
:array-data-props="{
|
||||
url: 'Tickets/filter',
|
||||
order: ['shippedDate DESC', 'shippedHour ASC', 'zoneLanding ASC', 'id'],
|
||||
exprBuilder,
|
||||
}"
|
||||
>
|
||||
<template #rightMenu>
|
||||
<TicketFilter data-key="TicketList" />
|
||||
</template>
|
||||
</RightMenu>
|
||||
<VnTable
|
||||
ref="tableRef"
|
||||
data-key="TicketList"
|
||||
url="Tickets/filter"
|
||||
:create="{
|
||||
urlCreate: 'Tickets/new',
|
||||
title: t('ticketList.createTicket'),
|
||||
onDataSaved: ({ id }) => tableRef.redirect(id),
|
||||
formInitialData: { clientId: null },
|
||||
}"
|
||||
default-mode="table"
|
||||
:order="['shippedDate DESC', 'shippedHour ASC', 'zoneLanding ASC', 'id']"
|
||||
:columns="columns"
|
||||
:user-params="userParams"
|
||||
:right-search="false"
|
||||
redirect="ticket"
|
||||
v-model:selected="selectedRows"
|
||||
:table="{
|
||||
'row-key': 'id',
|
||||
selection: 'multiple',
|
||||
}"
|
||||
data-cy="ticketListTable"
|
||||
>
|
||||
<template #column-statusIcons="{ row }">
|
||||
<TicketProblems :row="row" />
|
||||
</template>
|
||||
<template #column-salesPersonFk="{ row }">
|
||||
<span class="link" @click.stop>
|
||||
{{ dashIfEmpty(row.userName) }}
|
||||
<CustomerDescriptorProxy :id="row.salesPersonFk" />
|
||||
</span>
|
||||
</template>
|
||||
<template #column-shippedDate="{ row }">
|
||||
<span v-if="getDateColor(row.shipped)">
|
||||
<QChip :class="getDateColor(row.shipped)" dense square>
|
||||
{{ toDate(row.shippedDate) }}
|
||||
</QChip>
|
||||
</span>
|
||||
</template>
|
||||
<template #column-nickname="{ row }">
|
||||
<span class="link" @click.stop>
|
||||
{{ row.nickname }}
|
||||
<CustomerDescriptorProxy :id="row.clientFk" />
|
||||
</span>
|
||||
</template>
|
||||
<template #column-addressNickname="{ row }">
|
||||
<span class="link" @click.stop>
|
||||
{{ row.addressNickname }}
|
||||
<CustomerDescriptorProxy :id="row.clientFk" />
|
||||
</span>
|
||||
</template>
|
||||
<template #column-stateFk="{ row }">
|
||||
<span v-if="row.refFk">
|
||||
<span class="link" @click.stop>
|
||||
{{ row.refFk }}
|
||||
<InvoiceOutDescriptorProxy :id="row.invoiceOutId" />
|
||||
</span>
|
||||
</span>
|
||||
<span v-else-if="getColor(row)">
|
||||
<QChip :class="getColor(row)" dense square>
|
||||
{{ row.state }}
|
||||
</QChip>
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ row.state }}
|
||||
</span>
|
||||
</template>
|
||||
<template #column-zoneFk="{ row }">
|
||||
<span class="link" @click.stop>
|
||||
{{ dashIfEmpty(row.zoneName) }}
|
||||
<ZoneDescriptorProxy :id="row.zoneFk" />
|
||||
</span>
|
||||
</template>
|
||||
<template #column-totalWithVat="{ row }">
|
||||
<QChip
|
||||
v-if="row.totalWithVat > 0 && row.totalWithVat < 50"
|
||||
class="bg-warning"
|
||||
dense
|
||||
square
|
||||
<template #body>
|
||||
<VnTable
|
||||
ref="tableRef"
|
||||
:data-key="dataKey"
|
||||
:create="{
|
||||
urlCreate: 'Tickets/new',
|
||||
title: t('ticketList.createTicket'),
|
||||
onDataSaved: ({ id }) => tableRef.redirect(id),
|
||||
formInitialData: { clientId: null },
|
||||
}"
|
||||
default-mode="table"
|
||||
:columns="columns"
|
||||
:user-params="userParams"
|
||||
:right-search="false"
|
||||
redirect="ticket"
|
||||
v-model:selected="selectedRows"
|
||||
:table="{
|
||||
'row-key': 'id',
|
||||
selection: 'multiple',
|
||||
}"
|
||||
data-cy="ticketListTable"
|
||||
>
|
||||
{{ row.totalWithVat }}
|
||||
</QChip>
|
||||
</template>
|
||||
<template #more-create-dialog="{ data }">
|
||||
<VnRow>
|
||||
<VnSelect
|
||||
url="Clients"
|
||||
:fields="['id', 'name']"
|
||||
:label="t('ticketList.client')"
|
||||
v-model="data.clientId"
|
||||
:options="clientsOptions"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
hide-selected
|
||||
required
|
||||
@update:model-value="(client) => onClientSelected(data)"
|
||||
:sort-by="'id ASC'"
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>
|
||||
{{ scope.opt.name }}
|
||||
</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{ `#${scope.opt.id}` }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnSelect
|
||||
:label="t('basicData.address')"
|
||||
v-model="data.addressId"
|
||||
:options="addressesOptions"
|
||||
option-value="id"
|
||||
option-label="nickname"
|
||||
hide-selected
|
||||
map-options
|
||||
required
|
||||
:disable="!data.clientId"
|
||||
:sort-by="'isActive DESC'"
|
||||
@update:model-value="() => fetchAvailableAgencies(data)"
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem
|
||||
v-bind="scope.itemProps"
|
||||
:class="{ disabled: !scope.opt.isActive }"
|
||||
<template #column-statusIcons="{ row }">
|
||||
<TicketProblems :row="row" />
|
||||
</template>
|
||||
<template #column-salesPersonFk="{ row }">
|
||||
<span class="link" @click.stop>
|
||||
{{ dashIfEmpty(row.userName) }}
|
||||
<CustomerDescriptorProxy :id="row.salesPersonFk" />
|
||||
</span>
|
||||
</template>
|
||||
<template #column-shippedDate="{ row }">
|
||||
<span v-if="getDateColor(row.shipped)">
|
||||
<QChip :class="getDateColor(row.shipped)" dense square>
|
||||
{{ toDate(row.shippedDate) }}
|
||||
</QChip>
|
||||
</span>
|
||||
</template>
|
||||
<template #column-nickname="{ row }">
|
||||
<span class="link" @click.stop>
|
||||
{{ row.nickname }}
|
||||
<CustomerDescriptorProxy :id="row.clientFk" />
|
||||
</span>
|
||||
</template>
|
||||
<template #column-addressNickname="{ row }">
|
||||
<span class="link" @click.stop>
|
||||
{{ row.addressNickname }}
|
||||
<CustomerDescriptorProxy :id="row.clientFk" />
|
||||
</span>
|
||||
</template>
|
||||
<template #column-stateFk="{ row }">
|
||||
<span v-if="row.refFk">
|
||||
<span class="link" @click.stop>
|
||||
{{ row.refFk }}
|
||||
<InvoiceOutDescriptorProxy :id="row.invoiceOutId" />
|
||||
</span>
|
||||
</span>
|
||||
<span v-else-if="getColor(row)">
|
||||
<QChip :class="getColor(row)" dense square>
|
||||
{{ row.state }}
|
||||
</QChip>
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ row.state }}
|
||||
</span>
|
||||
</template>
|
||||
<template #column-zoneFk="{ row }">
|
||||
<span class="link" @click.stop>
|
||||
{{ dashIfEmpty(row.zoneName) }}
|
||||
<ZoneDescriptorProxy :id="row.zoneFk" />
|
||||
</span>
|
||||
</template>
|
||||
<template #column-totalWithVat="{ row }">
|
||||
<QChip
|
||||
v-if="row.totalWithVat > 0 && row.totalWithVat < 50"
|
||||
class="bg-warning"
|
||||
dense
|
||||
square
|
||||
>
|
||||
{{ row.totalWithVat }}
|
||||
</QChip>
|
||||
</template>
|
||||
<template #more-create-dialog="{ data }">
|
||||
<VnRow>
|
||||
<VnSelect
|
||||
url="Clients"
|
||||
:fields="['id', 'name']"
|
||||
:label="t('ticketList.client')"
|
||||
v-model="data.clientId"
|
||||
:options="clientsOptions"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
hide-selected
|
||||
required
|
||||
@update:model-value="(client) => onClientSelected(data)"
|
||||
:sort-by="'id ASC'"
|
||||
>
|
||||
<QItemSection style="min-width: min-content" avatar>
|
||||
<QIcon
|
||||
v-if="
|
||||
scope.opt.isActive &&
|
||||
selectedClient?.defaultAddressFk === scope.opt.id
|
||||
"
|
||||
size="sm"
|
||||
color="grey"
|
||||
name="star"
|
||||
class="fill-icon"
|
||||
/>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel
|
||||
:class="{
|
||||
'color-vn-label': !scope.opt?.isActive,
|
||||
}"
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>
|
||||
{{ scope.opt.name }}
|
||||
</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{ `#${scope.opt.id}` }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnSelect
|
||||
:label="t('basicData.address')"
|
||||
v-model="data.addressId"
|
||||
:options="addressesOptions"
|
||||
option-value="id"
|
||||
option-label="nickname"
|
||||
hide-selected
|
||||
map-options
|
||||
required
|
||||
:disable="!data.clientId"
|
||||
:sort-by="'isActive DESC'"
|
||||
@update:model-value="() => fetchAvailableAgencies(data)"
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem
|
||||
v-bind="scope.itemProps"
|
||||
:class="{ disabled: !scope.opt.isActive }"
|
||||
>
|
||||
{{
|
||||
`${
|
||||
!scope.opt?.isActive
|
||||
? t('basicData.inactive')
|
||||
: ''
|
||||
} `
|
||||
}}
|
||||
<span>
|
||||
{{ scope.opt?.nickname }}:
|
||||
{{ scope.opt?.street }}, {{ scope.opt?.city }}
|
||||
</span>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<div class="col">
|
||||
<VnInputDate
|
||||
placeholder="dd-mm-aaa"
|
||||
:label="t('globals.landed')"
|
||||
v-model="data.landed"
|
||||
@update:model-value="() => fetchAvailableAgencies(data)"
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<div class="col">
|
||||
<VnSelect
|
||||
url="Warehouses"
|
||||
:sort-by="['name']"
|
||||
:label="t('globals.warehouse')"
|
||||
v-model="data.warehouseId"
|
||||
:options="warehousesOptions"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
hide-selected
|
||||
required
|
||||
@update:model-value="() => fetchAvailableAgencies(data)"
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<div class="col">
|
||||
<VnSelect
|
||||
:label="t('globals.agency')"
|
||||
v-model="data.agencyModeId"
|
||||
:options="agenciesOptions"
|
||||
option-value="agencyModeFk"
|
||||
option-label="agencyMode"
|
||||
hide-selected
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
<QItemSection style="min-width: min-content" avatar>
|
||||
<QIcon
|
||||
v-if="
|
||||
scope.opt.isActive &&
|
||||
selectedClient?.defaultAddressFk ===
|
||||
scope.opt.id
|
||||
"
|
||||
size="sm"
|
||||
color="grey"
|
||||
name="star"
|
||||
class="fill-icon"
|
||||
/>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QItemLabel
|
||||
:class="{
|
||||
'color-vn-label': !scope.opt?.isActive,
|
||||
}"
|
||||
>
|
||||
{{
|
||||
`${
|
||||
!scope.opt?.isActive
|
||||
? t('basicData.inactive')
|
||||
: ''
|
||||
} `
|
||||
}}
|
||||
<span>
|
||||
{{ scope.opt?.nickname }}:
|
||||
{{ scope.opt?.street }},
|
||||
{{ scope.opt?.city }}
|
||||
</span>
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<div class="col">
|
||||
<VnInputDate
|
||||
placeholder="dd-mm-aaa"
|
||||
:label="t('globals.landed')"
|
||||
v-model="data.landed"
|
||||
@update:model-value="() => fetchAvailableAgencies(data)"
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<div class="col">
|
||||
<VnSelect
|
||||
url="Warehouses"
|
||||
:sort-by="['name']"
|
||||
:label="t('globals.warehouse')"
|
||||
v-model="data.warehouseId"
|
||||
:options="warehousesOptions"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
hide-selected
|
||||
required
|
||||
@update:model-value="() => fetchAvailableAgencies(data)"
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<div class="col">
|
||||
<VnSelect
|
||||
:label="t('globals.agency')"
|
||||
v-model="data.agencyModeId"
|
||||
:options="agenciesOptions"
|
||||
option-value="agencyModeFk"
|
||||
option-label="agencyMode"
|
||||
hide-selected
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
</template>
|
||||
</VnTable>
|
||||
</template>
|
||||
</VnTable>
|
||||
</VnSection>
|
||||
<QPageSticky :offset="[20, 80]" style="z-index: 2">
|
||||
<QBtn
|
||||
v-if="hasSelectedRows"
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
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 {
|
||||
path: '/account',
|
||||
|
@ -8,62 +11,76 @@ export default {
|
|||
icon: 'face',
|
||||
moduleName: 'Account',
|
||||
keyBinding: 'u',
|
||||
},
|
||||
component: RouterView,
|
||||
redirect: { name: 'AccountMain' },
|
||||
menus: {
|
||||
main: [
|
||||
menu: [
|
||||
'AccountList',
|
||||
'AccountAliasList',
|
||||
'AccountRoles',
|
||||
'AccountAlias',
|
||||
'AccountAccounts',
|
||||
'AccountLdap',
|
||||
'AccountSamba',
|
||||
'AccountAcls',
|
||||
'AccountConnections',
|
||||
],
|
||||
card: [
|
||||
'AccountBasicData',
|
||||
'AccountInheritedRoles',
|
||||
'AccountMailForwarding',
|
||||
'AccountMailAlias',
|
||||
'AccountPrivileges',
|
||||
'AccountLog',
|
||||
],
|
||||
},
|
||||
component: RouterView,
|
||||
redirect: { name: 'AccountMain' },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'AccountMain',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
redirect: { name: 'AccountList' },
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'AccountIndexMain' },
|
||||
children: [
|
||||
{
|
||||
path: 'list',
|
||||
name: 'AccountList',
|
||||
meta: {
|
||||
title: 'list',
|
||||
icon: 'view_list',
|
||||
},
|
||||
path: '',
|
||||
name: 'AccountIndexMain',
|
||||
redirect: { name: 'AccountList' },
|
||||
component: () => import('src/pages/Account/AccountList.vue'),
|
||||
children: [
|
||||
{
|
||||
name: 'AccountList',
|
||||
path: 'list',
|
||||
meta: {
|
||||
title: 'list',
|
||||
icon: 'view_list',
|
||||
},
|
||||
},
|
||||
accountCard,
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'role-list',
|
||||
path: 'role',
|
||||
name: 'AccountRoles',
|
||||
redirect: { name: 'AccountRoleList' },
|
||||
meta: {
|
||||
title: 'roles',
|
||||
icon: 'group',
|
||||
},
|
||||
component: () => import('src/pages/Account/Role/AccountRoles.vue'),
|
||||
children: [
|
||||
{
|
||||
name: 'AccountRoleList',
|
||||
path: 'list',
|
||||
},
|
||||
roleCard,
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'alias-list',
|
||||
name: 'AccountAliasList',
|
||||
path: 'alias',
|
||||
name: 'AccountAlias',
|
||||
redirect: { name: 'AccountAliasList' },
|
||||
meta: {
|
||||
title: 'alias',
|
||||
icon: 'email',
|
||||
},
|
||||
component: () => import('src/pages/Account/AccountAliasList.vue'),
|
||||
children: [
|
||||
{
|
||||
name: 'AccountAliasList',
|
||||
path: 'list',
|
||||
},
|
||||
aliasCard,
|
||||
],
|
||||
},
|
||||
{
|
||||
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',
|
||||
path: '',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'ClaimList' },
|
||||
children: [
|
||||
{
|
||||
|
|
|
@ -39,7 +39,7 @@ export default {
|
|||
{
|
||||
path: '',
|
||||
name: 'CustomerMain',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'CustomerList' },
|
||||
children: [
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@ export default {
|
|||
{
|
||||
path: '',
|
||||
name: 'EntryMain',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'EntryList' },
|
||||
children: [
|
||||
{
|
||||
|
|
|
@ -8,7 +8,7 @@ import Worker from './worker';
|
|||
import Shelving from './shelving';
|
||||
import Wagon from './wagon';
|
||||
import Route from './route';
|
||||
import Supplier from './Supplier';
|
||||
import Supplier from './supplier';
|
||||
import Travel from './travel';
|
||||
import Order from './order';
|
||||
import Department from './department';
|
||||
|
@ -20,8 +20,6 @@ import ItemType from './itemType';
|
|||
import Zone from './zone';
|
||||
import Account from './account';
|
||||
import Monitor from './monitor';
|
||||
import MailAlias from './mailAlias';
|
||||
import Role from './role';
|
||||
|
||||
export default [
|
||||
Item,
|
||||
|
@ -45,7 +43,5 @@ export default [
|
|||
ItemType,
|
||||
Zone,
|
||||
Account,
|
||||
MailAlias,
|
||||
Monitor,
|
||||
Role,
|
||||
];
|
||||
|
|
|
@ -25,7 +25,7 @@ export default {
|
|||
{
|
||||
path: '',
|
||||
name: 'InvoiceInMain',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'InvoiceInList' },
|
||||
children: [
|
||||
{
|
||||
|
|
|
@ -18,7 +18,7 @@ export default {
|
|||
{
|
||||
path: '',
|
||||
name: 'InvoiceOutMain',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'InvoiceOutList' },
|
||||
children: [
|
||||
{
|
||||
|
|
|
@ -36,7 +36,7 @@ export default {
|
|||
{
|
||||
path: '',
|
||||
name: 'ItemMain',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'ItemList' },
|
||||
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: '',
|
||||
name: 'MonitorMain',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
props: (route) => ({ leftDrawer: route.name === 'MonitorClientsActions' }),
|
||||
redirect: { name: 'MonitorTickets' },
|
||||
children: [
|
||||
|
|
|
@ -19,7 +19,7 @@ export default {
|
|||
{
|
||||
path: '',
|
||||
name: 'OrderMain',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'OrderList' },
|
||||
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',
|
||||
name: 'RouteMain',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'RouteList' },
|
||||
children: [
|
||||
{
|
||||
|
|
|
@ -18,7 +18,7 @@ export default {
|
|||
{
|
||||
path: '',
|
||||
name: 'ShelvingMain',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'ShelvingList' },
|
||||
children: [
|
||||
{
|
||||
|
|
|
@ -30,7 +30,7 @@ export default {
|
|||
{
|
||||
path: '',
|
||||
name: 'SupplierMain',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'SupplierList' },
|
||||
children: [
|
||||
{
|
|
@ -1,19 +1,12 @@
|
|||
import { RouterView } from 'vue-router';
|
||||
|
||||
export default {
|
||||
name: 'Ticket',
|
||||
path: '/ticket',
|
||||
const ticketCard = {
|
||||
name: 'TicketCard',
|
||||
path: ':id',
|
||||
component: () => import('src/pages/Ticket/Card/TicketCard.vue'),
|
||||
redirect: { name: 'TicketSummary' },
|
||||
meta: {
|
||||
title: 'tickets',
|
||||
icon: 'vn:ticket',
|
||||
moduleName: 'Ticket',
|
||||
keyBinding: 't',
|
||||
},
|
||||
component: RouterView,
|
||||
redirect: { name: 'TicketMain' },
|
||||
menus: {
|
||||
main: ['TicketList', 'TicketAdvance', 'TicketWeekly', 'TicketFuture'],
|
||||
card: [
|
||||
menu: [
|
||||
'TicketBasicData',
|
||||
'TicketSale',
|
||||
'TicketLog',
|
||||
|
@ -32,21 +25,200 @@ export default {
|
|||
'TicketSms',
|
||||
],
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'summary',
|
||||
name: 'TicketSummary',
|
||||
meta: {
|
||||
title: 'summary',
|
||||
icon: 'launch',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketSummary.vue'),
|
||||
},
|
||||
{
|
||||
path: 'basic-data',
|
||||
name: 'TicketBasicData',
|
||||
meta: {
|
||||
title: 'basicData',
|
||||
icon: 'vn:settings',
|
||||
},
|
||||
component: () =>
|
||||
import('src/pages/Ticket/Card/BasicData/TicketBasicDataView.vue'),
|
||||
},
|
||||
{
|
||||
path: 'sale',
|
||||
name: 'TicketSale',
|
||||
meta: {
|
||||
title: 'sale',
|
||||
icon: 'vn:lines',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketSale.vue'),
|
||||
},
|
||||
{
|
||||
path: 'request',
|
||||
name: 'TicketPurchaseRequest',
|
||||
meta: {
|
||||
title: 'purchaseRequest',
|
||||
icon: 'vn:buyrequest',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketPurchaseRequest.vue'),
|
||||
},
|
||||
{
|
||||
path: 'tracking',
|
||||
name: 'TicketTracking',
|
||||
meta: {
|
||||
title: 'tracking',
|
||||
icon: 'vn:eye',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketTracking.vue'),
|
||||
},
|
||||
{
|
||||
path: 'log',
|
||||
name: 'TicketLog',
|
||||
meta: {
|
||||
title: 'log',
|
||||
icon: 'history',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketLog.vue'),
|
||||
},
|
||||
{
|
||||
path: 'observation',
|
||||
name: 'TicketNotes',
|
||||
meta: {
|
||||
title: 'notes',
|
||||
icon: 'vn:notes',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketNotes.vue'),
|
||||
},
|
||||
{
|
||||
path: 'picture',
|
||||
name: 'TicketPicture',
|
||||
meta: {
|
||||
title: 'pictures',
|
||||
icon: 'vn:photo',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketPicture.vue'),
|
||||
},
|
||||
{
|
||||
path: 'volume',
|
||||
name: 'TicketVolume',
|
||||
meta: {
|
||||
title: 'volume',
|
||||
icon: 'vn:volume',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketVolume.vue'),
|
||||
},
|
||||
{
|
||||
path: 'expedition',
|
||||
name: 'TicketExpedition',
|
||||
meta: {
|
||||
title: 'expedition',
|
||||
icon: 'vn:package',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketExpedition.vue'),
|
||||
},
|
||||
{
|
||||
path: 'service',
|
||||
name: 'TicketService',
|
||||
meta: {
|
||||
title: 'services',
|
||||
icon: 'vn:services',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketService.vue'),
|
||||
},
|
||||
{
|
||||
path: 'package',
|
||||
name: 'TicketPackage',
|
||||
meta: {
|
||||
title: 'packages',
|
||||
icon: 'vn:bucket',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketPackage.vue'),
|
||||
},
|
||||
{
|
||||
path: 'components',
|
||||
name: 'TicketComponents',
|
||||
meta: {
|
||||
title: 'components',
|
||||
icon: 'vn:components',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketComponents.vue'),
|
||||
},
|
||||
|
||||
{
|
||||
path: 'sale-tracking',
|
||||
name: 'TicketSaleTracking',
|
||||
meta: {
|
||||
title: 'saleTracking',
|
||||
icon: 'assignment',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketSaleTracking.vue'),
|
||||
},
|
||||
{
|
||||
path: 'dms',
|
||||
name: 'TicketDms',
|
||||
meta: {
|
||||
title: 'dms',
|
||||
icon: 'cloud_upload',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketDms.vue'),
|
||||
},
|
||||
{
|
||||
path: 'boxing',
|
||||
name: 'TicketBoxing',
|
||||
meta: {
|
||||
title: 'boxing',
|
||||
icon: 'science',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketBoxing.vue'),
|
||||
},
|
||||
{
|
||||
path: 'sms',
|
||||
name: 'TicketSms',
|
||||
meta: {
|
||||
title: 'sms',
|
||||
icon: 'sms',
|
||||
},
|
||||
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/VnSectionMain.vue'),
|
||||
redirect: { name: 'TicketList' },
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'TicketIndexMain' },
|
||||
children: [
|
||||
{
|
||||
path: 'list',
|
||||
name: 'TicketList',
|
||||
meta: {
|
||||
title: 'list',
|
||||
icon: 'view_list',
|
||||
},
|
||||
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',
|
||||
|
@ -86,170 +258,5 @@ export default {
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'TicketCard',
|
||||
path: ':id',
|
||||
component: () => import('src/pages/Ticket/Card/TicketCard.vue'),
|
||||
redirect: { name: 'TicketSummary' },
|
||||
children: [
|
||||
{
|
||||
path: 'summary',
|
||||
name: 'TicketSummary',
|
||||
meta: {
|
||||
title: 'summary',
|
||||
icon: 'launch',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketSummary.vue'),
|
||||
},
|
||||
{
|
||||
path: 'basic-data',
|
||||
name: 'TicketBasicData',
|
||||
meta: {
|
||||
title: 'basicData',
|
||||
icon: 'vn:settings',
|
||||
},
|
||||
component: () =>
|
||||
import('src/pages/Ticket/Card/BasicData/TicketBasicDataView.vue'),
|
||||
},
|
||||
{
|
||||
path: 'sale',
|
||||
name: 'TicketSale',
|
||||
meta: {
|
||||
title: 'sale',
|
||||
icon: 'vn:lines',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketSale.vue'),
|
||||
},
|
||||
{
|
||||
path: 'request',
|
||||
name: 'TicketPurchaseRequest',
|
||||
meta: {
|
||||
title: 'purchaseRequest',
|
||||
icon: 'vn:buyrequest',
|
||||
},
|
||||
component: () =>
|
||||
import('src/pages/Ticket/Card/TicketPurchaseRequest.vue'),
|
||||
},
|
||||
{
|
||||
path: 'tracking',
|
||||
name: 'TicketTracking',
|
||||
meta: {
|
||||
title: 'tracking',
|
||||
icon: 'vn:eye',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketTracking.vue'),
|
||||
},
|
||||
{
|
||||
path: 'log',
|
||||
name: 'TicketLog',
|
||||
meta: {
|
||||
title: 'log',
|
||||
icon: 'history',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketLog.vue'),
|
||||
},
|
||||
{
|
||||
path: 'observation',
|
||||
name: 'TicketNotes',
|
||||
meta: {
|
||||
title: 'notes',
|
||||
icon: 'vn:notes',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketNotes.vue'),
|
||||
},
|
||||
{
|
||||
path: 'picture',
|
||||
name: 'TicketPicture',
|
||||
meta: {
|
||||
title: 'pictures',
|
||||
icon: 'vn:photo',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketPicture.vue'),
|
||||
},
|
||||
{
|
||||
path: 'volume',
|
||||
name: 'TicketVolume',
|
||||
meta: {
|
||||
title: 'volume',
|
||||
icon: 'vn:volume',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketVolume.vue'),
|
||||
},
|
||||
{
|
||||
path: 'expedition',
|
||||
name: 'TicketExpedition',
|
||||
meta: {
|
||||
title: 'expedition',
|
||||
icon: 'vn:package',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketExpedition.vue'),
|
||||
},
|
||||
{
|
||||
path: 'service',
|
||||
name: 'TicketService',
|
||||
meta: {
|
||||
title: 'services',
|
||||
icon: 'vn:services',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketService.vue'),
|
||||
},
|
||||
{
|
||||
path: 'package',
|
||||
name: 'TicketPackage',
|
||||
meta: {
|
||||
title: 'packages',
|
||||
icon: 'vn:bucket',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketPackage.vue'),
|
||||
},
|
||||
{
|
||||
path: 'components',
|
||||
name: 'TicketComponents',
|
||||
meta: {
|
||||
title: 'components',
|
||||
icon: 'vn:components',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketComponents.vue'),
|
||||
},
|
||||
|
||||
{
|
||||
path: 'sale-tracking',
|
||||
name: 'TicketSaleTracking',
|
||||
meta: {
|
||||
title: 'saleTracking',
|
||||
icon: 'assignment',
|
||||
},
|
||||
component: () =>
|
||||
import('src/pages/Ticket/Card/TicketSaleTracking.vue'),
|
||||
},
|
||||
{
|
||||
path: 'dms',
|
||||
name: 'TicketDms',
|
||||
meta: {
|
||||
title: 'dms',
|
||||
icon: 'cloud_upload',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketDms.vue'),
|
||||
},
|
||||
{
|
||||
path: 'boxing',
|
||||
name: 'TicketBoxing',
|
||||
meta: {
|
||||
title: 'boxing',
|
||||
icon: 'science',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketBoxing.vue'),
|
||||
},
|
||||
{
|
||||
path: 'sms',
|
||||
name: 'TicketSms',
|
||||
meta: {
|
||||
title: 'sms',
|
||||
icon: 'sms',
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketSms.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@ export default {
|
|||
{
|
||||
path: '',
|
||||
name: 'TravelMain',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'TravelList' },
|
||||
children: [
|
||||
{
|
||||
|
|
|
@ -18,7 +18,7 @@ export default {
|
|||
{
|
||||
path: '/wagon',
|
||||
name: 'WagonMain',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'WagonList' },
|
||||
children: [
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ export default {
|
|||
{
|
||||
path: '/wagon/type',
|
||||
name: 'WagonTypeMain',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'WagonTypeList' },
|
||||
children: [
|
||||
{
|
||||
|
|
|
@ -35,7 +35,7 @@ export default {
|
|||
{
|
||||
path: '',
|
||||
name: 'WorkerMain',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'WorkerList' },
|
||||
children: [
|
||||
{
|
||||
|
|
|
@ -30,7 +30,7 @@ export default {
|
|||
{
|
||||
path: '/zone',
|
||||
name: 'ZoneMain',
|
||||
component: () => import('src/components/common/VnSectionMain.vue'),
|
||||
component: () => import('src/components/common/VnModule.vue'),
|
||||
redirect: { name: 'ZoneList' },
|
||||
children: [
|
||||
{
|
||||
|
|
|
@ -7,10 +7,9 @@ import worker from './modules/worker';
|
|||
import invoiceOut from './modules/invoiceOut';
|
||||
import invoiceIn from './modules/invoiceIn';
|
||||
import wagon from './modules/wagon';
|
||||
import supplier from './modules/Supplier';
|
||||
import supplier from './modules/supplier';
|
||||
import travel from './modules/travel';
|
||||
import department from './modules/department';
|
||||
import role from './modules/role';
|
||||
import ItemType from './modules/itemType';
|
||||
import shelving from 'src/router/modules/shelving';
|
||||
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 account from './modules/account';
|
||||
import monitor from 'src/router/modules/monitor';
|
||||
import mailAlias from './modules/mailAlias';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
|
@ -95,8 +93,6 @@ const routes = [
|
|||
ItemType,
|
||||
zone,
|
||||
account,
|
||||
role,
|
||||
mailAlias,
|
||||
{
|
||||
path: '/:catchAll(.*)*',
|
||||
name: 'NotFound',
|
||||
|
|
|
@ -51,10 +51,15 @@ export const useArrayDataStore = defineStore('arrayDataStore', () => {
|
|||
});
|
||||
}
|
||||
|
||||
function resetPagination(key) {
|
||||
reset(key, ['skip', 'filter.skip', 'page']);
|
||||
}
|
||||
|
||||
return {
|
||||
get,
|
||||
set,
|
||||
clear,
|
||||
reset,
|
||||
resetPagination,
|
||||
};
|
||||
});
|
||||
|
|
|
@ -7,10 +7,10 @@ describe('VnSearchBar', () => {
|
|||
beforeEach(() => {
|
||||
cy.viewport(1280, 720);
|
||||
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('salesPerson', salesPersonId);
|
||||
});
|
||||
|
@ -20,7 +20,6 @@ describe('VnSearchBar', () => {
|
|||
checkTableLength(2);
|
||||
|
||||
cy.clearSearchbar();
|
||||
|
||||
cy.writeSearchbar('0{enter}');
|
||||
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 VnTable from 'src/components/VnTable/VnTable.vue';
|
||||
|
||||
|
@ -13,6 +13,15 @@ describe('VnTable', () => {
|
|||
},
|
||||
});
|
||||
vm = wrapper.vm;
|
||||
|
||||
vi.mock('src/composables/useFilterParams', () => {
|
||||
return {
|
||||
useFilterParams: vi.fn(() => ({
|
||||
params: {},
|
||||
orders: {},
|
||||
})),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
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