refs #5673 feat(FormModel): basciFilter, feat: modul top toolbar
gitea/salix-front/pipeline/head This commit looks good
Details
gitea/salix-front/pipeline/head This commit looks good
Details
This commit is contained in:
parent
35ac3afe81
commit
0cdd090daf
|
@ -41,20 +41,10 @@ const $props = defineProps({
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
});
|
defaultActions: {
|
||||||
|
type: Boolean,
|
||||||
const emit = defineEmits(['onFetch']);
|
default: true,
|
||||||
|
},
|
||||||
defineExpose({
|
|
||||||
save,
|
|
||||||
insert,
|
|
||||||
remove,
|
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(async () => await fetch());
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
state.unset($props.model);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
|
@ -62,12 +52,38 @@ const hasChanges = ref(false);
|
||||||
const formData = computed(() => state.get($props.model));
|
const formData = computed(() => state.get($props.model));
|
||||||
const originalData = ref();
|
const originalData = ref();
|
||||||
const formUrl = computed(() => $props.url);
|
const formUrl = computed(() => $props.url);
|
||||||
|
const stActionsExist = ref(false);
|
||||||
|
|
||||||
|
const emit = defineEmits(['onFetch']);
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
save,
|
||||||
|
insert,
|
||||||
|
remove,
|
||||||
|
onSubmit,
|
||||||
|
reset,
|
||||||
|
hasChanges,
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetch();
|
||||||
|
stActionsExist.value = !!document.querySelector('#st-actions');
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
state.unset($props.model);
|
||||||
|
});
|
||||||
|
|
||||||
async function fetch() {
|
async function fetch() {
|
||||||
const { data } = await axios.get($props.url, {
|
const { data } = await axios.get($props.url, {
|
||||||
params: { filter: $props.filter },
|
params: { filter: $props.filter },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (Array.isArray(data)) {
|
||||||
|
let $index = 0;
|
||||||
|
data.map((d) => (d.$index = $index++));
|
||||||
|
}
|
||||||
|
|
||||||
state.set($props.model, data);
|
state.set($props.model, data);
|
||||||
originalData.value = JSON.parse(JSON.stringify(data));
|
originalData.value = JSON.parse(JSON.stringify(data));
|
||||||
|
|
||||||
|
@ -84,7 +100,11 @@ async function save() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
|
try {
|
||||||
await axios.patch($props.urlUpdate || $props.url, formData.value);
|
await axios.patch($props.urlUpdate || $props.url, formData.value);
|
||||||
|
} catch {
|
||||||
|
return (isLoading.value = false);
|
||||||
|
}
|
||||||
|
|
||||||
originalData.value = JSON.parse(JSON.stringify(formData.value));
|
originalData.value = JSON.parse(JSON.stringify(formData.value));
|
||||||
hasChanges.value = false;
|
hasChanges.value = false;
|
||||||
|
@ -93,6 +113,7 @@ async function save() {
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
state.set($props.model, originalData.value);
|
state.set($props.model, originalData.value);
|
||||||
|
watch(formData.value, () => (hasChanges.value = true));
|
||||||
hasChanges.value = false;
|
hasChanges.value = false;
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line vue/no-dupe-keys
|
// eslint-disable-next-line vue/no-dupe-keys
|
||||||
|
@ -118,28 +139,25 @@ async function crudSave() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
const changes = getChanges();
|
await saveChanges();
|
||||||
await saveChanges(changes);
|
|
||||||
if (changes.creates?.length) await fetch();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveChanges(changes) {
|
async function saveChanges() {
|
||||||
|
const changes = getChanges();
|
||||||
try {
|
try {
|
||||||
await axios.post($props.urlUpdate || $props.url + '/crud', changes);
|
await axios.post($props.urlUpdate || $props.url + '/crud', changes);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
quasar.notify({
|
return (isLoading.value = false);
|
||||||
type: 'negative',
|
|
||||||
message: 'Some fields are invalid',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
originalData.value = JSON.parse(JSON.stringify(formData.value));
|
originalData.value = JSON.parse(JSON.stringify(formData.value));
|
||||||
hasChanges.value = false;
|
hasChanges.value = false;
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
|
if (changes.creates?.length) await fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function insert() {
|
async function insert() {
|
||||||
const $index = formData.value.length + 1;
|
const $index = formData.value[formData.value.length - 1].$index + 1;
|
||||||
formData.value.push(Object.assign({ $index }, $props.dataRequired));
|
formData.value.push(Object.assign({ $index }, $props.dataRequired));
|
||||||
hasChanges.value = true;
|
hasChanges.value = true;
|
||||||
}
|
}
|
||||||
|
@ -156,6 +174,7 @@ async function insert() {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
async function remove(data) {
|
async function remove(data) {
|
||||||
|
console.log(data);
|
||||||
if (!data.length)
|
if (!data.length)
|
||||||
return quasar.notify({
|
return quasar.notify({
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
|
@ -253,25 +272,29 @@ function isEmpty(obj) {
|
||||||
</QBanner>
|
</QBanner>
|
||||||
<QForm v-if="formData" @submit="onSubmit" @reset="reset" class="q-pa-md">
|
<QForm v-if="formData" @submit="onSubmit" @reset="reset" class="q-pa-md">
|
||||||
<slot name="form" :data="formData" :validate="validate" :filter="filter"></slot>
|
<slot name="form" :data="formData" :validate="validate" :filter="filter"></slot>
|
||||||
<div class="q-mt-lg">
|
</QForm>
|
||||||
<slot name="actions">
|
<Teleport to="#st-actions" v-if="stActionsExist">
|
||||||
|
<div class="row q-gutter-x-sm">
|
||||||
|
<slot name="moreActions" />
|
||||||
|
<div v-if="$props.defaultActions">
|
||||||
<QBtn
|
<QBtn
|
||||||
:label="t('globals.save')"
|
:label="t('globals.save')"
|
||||||
type="submit"
|
|
||||||
color="primary"
|
color="primary"
|
||||||
|
icon="save"
|
||||||
|
@click="onSubmit"
|
||||||
:disable="!hasChanges"
|
:disable="!hasChanges"
|
||||||
/>
|
/>
|
||||||
<QBtn
|
<QBtn
|
||||||
:label="t('globals.reset')"
|
:label="t('globals.reset')"
|
||||||
type="reset"
|
|
||||||
class="q-ml-sm"
|
|
||||||
color="primary"
|
color="primary"
|
||||||
|
class="q-ml-sm"
|
||||||
flat
|
flat
|
||||||
|
@click="reset"
|
||||||
:disable="!hasChanges"
|
:disable="!hasChanges"
|
||||||
/>
|
/>
|
||||||
</slot>
|
|
||||||
</div>
|
</div>
|
||||||
</QForm>
|
</div>
|
||||||
|
</Teleport>
|
||||||
<SkeletonForm v-if="!formData" />
|
<SkeletonForm v-if="!formData" />
|
||||||
<QInnerLoading
|
<QInnerLoading
|
||||||
:showing="isLoading"
|
:showing="isLoading"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch, toRefs } from 'vue';
|
import { ref, toRefs } from 'vue';
|
||||||
const emit = defineEmits(['update:modelValue', 'update:options']);
|
const emit = defineEmits(['update:modelValue', 'update:options']);
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
|
@ -18,43 +18,42 @@ const $props = defineProps({
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateValue = (newValue) => emit('update:modelValue', newValue);
|
const updateValue = (newValue) => emit('update:modelValue', newValue);
|
||||||
const { modelValue, options, optionLabel } = toRefs($props);
|
const { modelValue, optionLabel, options } = toRefs($props);
|
||||||
|
const myOptions = ref(JSON.parse(JSON.stringify(options.value)));
|
||||||
|
const myOptionsOriginal = ref(JSON.parse(JSON.stringify(options.value)));
|
||||||
|
|
||||||
function filterFn(val, update) {
|
const filter = (val, options) => {
|
||||||
update(
|
const search = val.toLowerCase();
|
||||||
() => {
|
|
||||||
const needle = val.toLowerCase();
|
if (val === '') return options;
|
||||||
// $props.options.value = options.value.filter(
|
return options.filter((row) => {
|
||||||
// (v) => v[$props.optionLabel.value].toLowerCase().indexOf(needle) > -1
|
const id = row.id;
|
||||||
// );
|
const name = row[$props.optionLabel].toLowerCase();
|
||||||
// updateOptions(
|
|
||||||
// $props.options.filter(
|
const idMatches = id == search;
|
||||||
// (v) => v[$props.optionLabel].toLowerCase().indexOf(needle) > -1
|
const nameMatches = name.indexOf(search) > -1;
|
||||||
// )
|
|
||||||
// );
|
return idMatches || nameMatches;
|
||||||
const filteredOptions = options.value.filter(
|
});
|
||||||
(v) => v[optionLabel.value].toLowerCase().indexOf(needle) > -1
|
};
|
||||||
);
|
|
||||||
emit('update:options', filteredOptions);
|
const filterHandler = (val, update) => {
|
||||||
},
|
update(() => {
|
||||||
(ref) => {
|
myOptions.value = filter(val, myOptionsOriginal.value);
|
||||||
ref.setOptionIndex(-1);
|
});
|
||||||
ref.moveOptionSelection(1, true);
|
};
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<QSelect
|
<QSelect
|
||||||
v-model="modelValue"
|
v-model="modelValue"
|
||||||
@update:model-value="updateValue"
|
@update:model-value="updateValue"
|
||||||
:options="options"
|
:options="myOptions"
|
||||||
:option-label="optionLabel"
|
:option-label="optionLabel"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
emit-value
|
emit-value
|
||||||
map-options
|
map-options
|
||||||
use-input
|
use-input
|
||||||
@filter="(value, update) => filterFn(value, update)"
|
@filter="filterHandler"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -64,7 +64,13 @@ onMounted(async () => {
|
||||||
</QScrollArea>
|
</QScrollArea>
|
||||||
</QDrawer>
|
</QDrawer>
|
||||||
<QPageContainer>
|
<QPageContainer>
|
||||||
<div id="sub-toolbar"></div>
|
<QToolbar id="sub-toolbar" class="bg-dark text-white justify-end">
|
||||||
|
<div id="st-data">
|
||||||
|
{{ route.meta?.title && t(`claim.pageTitles.${route.meta.title}`) }}
|
||||||
|
</div>
|
||||||
|
<QSpace />
|
||||||
|
<div id="st-actions"></div>
|
||||||
|
</QToolbar>
|
||||||
<QPage class="q-pa-md">
|
<QPage class="q-pa-md">
|
||||||
<RouterView></RouterView>
|
<RouterView></RouterView>
|
||||||
</QPage>
|
</QPage>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed, onMounted } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import FormModel from 'components/FormModel.vue';
|
import FormModel from 'components/FormModel.vue';
|
||||||
|
@ -126,16 +126,25 @@ const columns = computed(() => [
|
||||||
url="ClaimDevelopments"
|
url="ClaimDevelopments"
|
||||||
:crud="true"
|
:crud="true"
|
||||||
:filter="developmentsFilter"
|
:filter="developmentsFilter"
|
||||||
model="claim"
|
model="claimDevelopment"
|
||||||
ref="claimDevelopmentForm"
|
ref="claimDevelopmentForm"
|
||||||
:data-required="{ claimFk: route.params.id }"
|
:data-required="{ claimFk: route.params.id }"
|
||||||
>
|
>
|
||||||
|
<template #moreActions>
|
||||||
|
<QBtn
|
||||||
|
:label="t('globals.remove')"
|
||||||
|
color="primary"
|
||||||
|
icon="delete"
|
||||||
|
@click="claimDevelopmentForm.remove(selected)"
|
||||||
|
:disable="!selected.length"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
<template #form="{ data }">
|
<template #form="{ data }">
|
||||||
<QTable
|
<QTable
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:rows="data"
|
:rows="data"
|
||||||
:pagination="{ rowsPerPage: 0 }"
|
:pagination="{ rowsPerPage: 0 }"
|
||||||
row-key="id"
|
row-key="$index"
|
||||||
selection="multiple"
|
selection="multiple"
|
||||||
hide-pagination
|
hide-pagination
|
||||||
v-model:selected="selected"
|
v-model:selected="selected"
|
||||||
|
@ -147,12 +156,6 @@ const columns = computed(() => [
|
||||||
:label="col.label"
|
:label="col.label"
|
||||||
v-model="row[col.model]"
|
v-model="row[col.model]"
|
||||||
:options="col.options"
|
:options="col.options"
|
||||||
@update:options="
|
|
||||||
(newOptions) => {
|
|
||||||
console.log(newOptions);
|
|
||||||
col.options = newOptions;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
:option-value="col.optionValue"
|
:option-value="col.optionValue"
|
||||||
:option-label="col.optionLabel"
|
:option-label="col.optionLabel"
|
||||||
/>
|
/>
|
||||||
|
@ -172,12 +175,6 @@ const columns = computed(() => [
|
||||||
:label="col.label"
|
:label="col.label"
|
||||||
v-model="props.row[col.model]"
|
v-model="props.row[col.model]"
|
||||||
:options="col.options"
|
:options="col.options"
|
||||||
@update:options="
|
|
||||||
(newOptions) => {
|
|
||||||
console.log(newOptions);
|
|
||||||
col.options = newOptions;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
:option-value="col.optionValue"
|
:option-value="col.optionValue"
|
||||||
:option-label="col.optionLabel"
|
:option-label="col.optionLabel"
|
||||||
dense
|
dense
|
||||||
|
@ -193,17 +190,6 @@ const columns = computed(() => [
|
||||||
</FormModel>
|
</FormModel>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Teleport to="#sub-toolbar">
|
|
||||||
<QToolbar class="bg-dark text-white justify-end">
|
|
||||||
<div class="row q-gutter-x-sm">
|
|
||||||
<QBtn
|
|
||||||
color="primary"
|
|
||||||
icon="delete"
|
|
||||||
@click="claimDevelopmentForm.remove(selected)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</QToolbar>
|
|
||||||
</Teleport>
|
|
||||||
<QPageSticky position="bottom-right" :offset="[25, 25]">
|
<QPageSticky position="bottom-right" :offset="[25, 25]">
|
||||||
<QBtn fab color="primary" icon="add" @click="claimDevelopmentForm.insert()" />
|
<QBtn fab color="primary" icon="add" @click="claimDevelopmentForm.insert()" />
|
||||||
</QPageSticky>
|
</QPageSticky>
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { ref, computed } from 'vue';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
|
||||||
import { useSession } from 'composables/useSession';
|
import { useSession } from 'composables/useSession';
|
||||||
import VnConfirm from 'components/ui/VnConfirm.vue';
|
import VnConfirm from 'components/ui/VnConfirm.vue';
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
|
@ -12,7 +11,6 @@ import FetchData from 'components/FetchData.vue';
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const stateStore = useStateStore();
|
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
const token = session.getToken();
|
const token = session.getToken();
|
||||||
|
|
||||||
|
@ -237,19 +235,9 @@ function onDrag() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Teleport
|
<QPageSticky position="bottom-right" :offset="[25, 25]">
|
||||||
v-if="stateStore.isHeaderMounted() && !quasar.platform.is.mobile"
|
|
||||||
to="#actions-prepend"
|
|
||||||
>
|
|
||||||
<div class="row q-gutter-x-sm">
|
|
||||||
<label for="fileInput">
|
<label for="fileInput">
|
||||||
<QBtn
|
<QBtn fab @click="inputFile.nativeEl.click()" icon="add" color="primary">
|
||||||
@click="inputFile.nativeEl.click()"
|
|
||||||
icon="add"
|
|
||||||
color="primary"
|
|
||||||
dense
|
|
||||||
rounded
|
|
||||||
>
|
|
||||||
<QInput
|
<QInput
|
||||||
ref="inputFile"
|
ref="inputFile"
|
||||||
type="file"
|
type="file"
|
||||||
|
@ -261,35 +249,6 @@ function onDrag() {
|
||||||
<QTooltip bottom> {{ t('globals.add') }} </QTooltip>
|
<QTooltip bottom> {{ t('globals.add') }} </QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</label>
|
</label>
|
||||||
<QSeparator vertical />
|
|
||||||
</div>
|
|
||||||
</Teleport>
|
|
||||||
|
|
||||||
<QPageSticky
|
|
||||||
v-if="quasar.platform.is.mobile"
|
|
||||||
position="bottom"
|
|
||||||
:offset="[0, 0]"
|
|
||||||
expand
|
|
||||||
>
|
|
||||||
<QToolbar class="bg-primary text-white q-pa-none">
|
|
||||||
<QTabs class="full-width" align="justify" inline-label narrow-indicator>
|
|
||||||
<QTab
|
|
||||||
@click="inputFile.nativeEl.click()"
|
|
||||||
icon="add_circle"
|
|
||||||
:label="t('globals.add')"
|
|
||||||
>
|
|
||||||
<QInput
|
|
||||||
ref="inputFile"
|
|
||||||
type="file"
|
|
||||||
style="display: none"
|
|
||||||
multiple
|
|
||||||
v-model="files"
|
|
||||||
@update:model-value="create()"
|
|
||||||
/>
|
|
||||||
<QTooltip bottom> {{ t('globals.add') }} </QTooltip>
|
|
||||||
</QTab>
|
|
||||||
</QTabs>
|
|
||||||
</QToolbar>
|
|
||||||
</QPageSticky>
|
</QPageSticky>
|
||||||
|
|
||||||
<!-- MULTIMEDIA DIALOG START-->
|
<!-- MULTIMEDIA DIALOG START-->
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { useI18n } from 'vue-i18n';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
|
||||||
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
import VnPaginate from 'src/components/ui/VnPaginate.vue';
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
||||||
|
@ -15,7 +14,6 @@ import { toDate } from 'src/filters';
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const stateStore = useStateStore();
|
|
||||||
const arrayData = useArrayData('ClaimRma');
|
const arrayData = useArrayData('ClaimRma');
|
||||||
|
|
||||||
const claim = ref();
|
const claim = ref();
|
||||||
|
@ -147,29 +145,20 @@ async function remove({ id }) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Teleport
|
<QPageSticky position="bottom-right" :offset="[25, 25]">
|
||||||
v-if="stateStore.isHeaderMounted() && !quasar.platform.is.mobile"
|
<label for="fileInput">
|
||||||
to="#actions-prepend"
|
<QBtn fab @click="inputFile.nativeEl.click()" icon="add" color="primary">
|
||||||
>
|
<QInput
|
||||||
<div class="row q-gutter-x-sm">
|
ref="inputFile"
|
||||||
<QBtn @click="addRow()" icon="add" color="primary" dense rounded>
|
type="file"
|
||||||
|
style="display: none"
|
||||||
|
multiple
|
||||||
|
v-model="files"
|
||||||
|
@update:model-value="create()"
|
||||||
|
/>
|
||||||
<QTooltip bottom> {{ t('globals.add') }} </QTooltip>
|
<QTooltip bottom> {{ t('globals.add') }} </QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
<QSeparator vertical />
|
</label>
|
||||||
</div>
|
|
||||||
</Teleport>
|
|
||||||
|
|
||||||
<QPageSticky
|
|
||||||
v-if="quasar.platform.is.mobile"
|
|
||||||
position="bottom"
|
|
||||||
:offset="[0, 0]"
|
|
||||||
expand
|
|
||||||
>
|
|
||||||
<QToolbar class="bg-primary text-white q-pa-none">
|
|
||||||
<QTabs class="full-width" align="justify" inline-label narrow-indicator>
|
|
||||||
<QTab @click="addRow()" icon="add_circle" :label="t('globals.add')" />
|
|
||||||
</QTabs>
|
|
||||||
</QToolbar>
|
|
||||||
</QPageSticky>
|
</QPageSticky>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
import CustomerDescriptor from './CustomerDescriptor.vue';
|
import CustomerDescriptor from './CustomerDescriptor.vue';
|
||||||
import LeftMenu from 'components/LeftMenu.vue';
|
import LeftMenu from 'components/LeftMenu.vue';
|
||||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
||||||
|
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
|
const route = useRoute();
|
||||||
|
console.log(route);
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
@ -25,6 +28,13 @@ const { t } = useI18n();
|
||||||
</QScrollArea>
|
</QScrollArea>
|
||||||
</QDrawer>
|
</QDrawer>
|
||||||
<QPageContainer>
|
<QPageContainer>
|
||||||
|
<QToolbar id="sub-toolbar" class="bg-dark text-white justify-end">
|
||||||
|
<div id="st-data">
|
||||||
|
{{ route.meta?.title && t(`customer.pageTitles.${route.meta.title}`) }}
|
||||||
|
</div>
|
||||||
|
<QSpace />
|
||||||
|
<div id="st-actions"></div>
|
||||||
|
</QToolbar>
|
||||||
<QPage class="q-pa-md">
|
<QPage class="q-pa-md">
|
||||||
<RouterView></RouterView>
|
<RouterView></RouterView>
|
||||||
</QPage>
|
</QPage>
|
||||||
|
|
|
@ -107,6 +107,7 @@ export default {
|
||||||
meta: {
|
meta: {
|
||||||
title: 'development',
|
title: 'development',
|
||||||
icon: 'vn:traceability',
|
icon: 'vn:traceability',
|
||||||
|
roles: ['claimManager'],
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Claim/Card/ClaimDevelopment.vue'),
|
component: () => import('src/pages/Claim/Card/ClaimDevelopment.vue'),
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue