First commit
This commit is contained in:
41
resources/js/components/EssentialLink.vue
Normal file
41
resources/js/components/EssentialLink.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<q-item clickable tag="a" target="_blank" :href="link">
|
||||
<q-item-section v-if="icon" avatar>
|
||||
<q-icon :name="icon" />
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section>
|
||||
<q-item-label>{{ title }}</q-item-label>
|
||||
<q-item-label caption>{{ caption }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "EssentialLink",
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
|
||||
caption: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
|
||||
link: {
|
||||
type: String,
|
||||
default: "#",
|
||||
},
|
||||
|
||||
icon: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
50
resources/js/components/JsonQueryBuilder.vue
Normal file
50
resources/js/components/JsonQueryBuilder.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<script setup>
|
||||
import Multiselect from 'vue-multiselect';
|
||||
import JsonQueryBuilderGroup from '@/Components/JsonQueryBuilderGroup.vue';
|
||||
import { FolderAddIcon, PlusCircleIcon, TrashIcon, ArrowCircleRightIcon} from '@vue-hero-icons/outline';
|
||||
import VueTailwindDatepicker from 'vue-tailwind-datepicker'
|
||||
import { ref } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
|
||||
defineProps(['query', 'currentQuery', 'queryOptions', 'i18n']);
|
||||
defineEmits(['update:query', 'update:queryOptions', 'runQuery']);
|
||||
|
||||
const level = ref(0);
|
||||
const expanded = ref(true);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<div class="q-pa-md row items-start q-gutter-md">
|
||||
<!-- Card -->
|
||||
<q-card class="my-card q-pa-sm">
|
||||
<!-- Header -->
|
||||
<q-card-section class="bg-red-4 text-white">
|
||||
<div class="row items-center">
|
||||
<div class="col text-h6">Query Builder</div>
|
||||
<q-card-actions align="right" class="col">
|
||||
<q-btn
|
||||
color="grey"
|
||||
round
|
||||
flat
|
||||
dense
|
||||
:icon="expanded ? 'keyboard_arrow_up' : 'keyboard_arrow_down'"
|
||||
@click="expanded = !expanded"
|
||||
/>
|
||||
</q-card-actions>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-slide-transition>
|
||||
<div v-show="expanded">
|
||||
<q-separator />
|
||||
<JsonQueryBuilderGroup :currentQuery="query" :queryOptions="queryOptions" :level="level+1"> </JsonQueryBuilderGroup>
|
||||
</div>
|
||||
</q-slide-transition>
|
||||
|
||||
<div class="row no-wrap justify-end q-mt-md q-pa-sm bg-grey-8 text-white">
|
||||
<q-btn rounded color="brown-4" @click="$emit('runQuery')" label="Spusti vyhľadávanie" icon="sync" />
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
86
resources/js/components/JsonQueryBuilderGroup.vue
Normal file
86
resources/js/components/JsonQueryBuilderGroup.vue
Normal file
@@ -0,0 +1,86 @@
|
||||
<script setup>
|
||||
import { FolderAddIcon, PlusCircleIcon, TrashIcon} from '@vue-hero-icons/outline';
|
||||
|
||||
import JsonQueryBuilderRule from '@/Components/JsonQueryBuilderRule.vue';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
|
||||
const props = defineProps(['currentQuery', 'queryOptions', 'i18n', 'level']);
|
||||
|
||||
function AddGroup(query) {
|
||||
console.log(query.rules);
|
||||
let len = query.rules.push({
|
||||
condition: 'and',
|
||||
rules: []
|
||||
});
|
||||
AddRule(query.rules[len-1]);
|
||||
}
|
||||
|
||||
function DeleteGroup(query,item) {
|
||||
console.log(item);
|
||||
query.rules.splice(query.rules.indexOf(item), 1);
|
||||
}
|
||||
|
||||
function AddRule(query){
|
||||
console.log(query.rules);
|
||||
query.rules.push({
|
||||
id: '',
|
||||
operator: '=',
|
||||
value: ''
|
||||
})
|
||||
}
|
||||
|
||||
function DeleteRule(rules, rule) {
|
||||
console.log(rule);
|
||||
rules.splice(rules.indexOf(rule), 1);
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div :class="level > 1 ? 'border-4 border-blue-300 q-pa-xs' : 'q-pa-xs'">
|
||||
<div class="row q-pa-sm q-gutter-sm items-center justify-between">
|
||||
<div class="p-3 text-gray-700 text-lg font-bold">
|
||||
<q-btn-toggle
|
||||
v-model="currentQuery.condition"
|
||||
|
||||
class="q-"
|
||||
no-caps
|
||||
rounded
|
||||
unelevated
|
||||
toggle-color="blue"
|
||||
color="white"
|
||||
text-color="primary"
|
||||
:options="[
|
||||
{label: 'AND', value: 'and'},
|
||||
{label: 'OR', value: 'or'}
|
||||
]"
|
||||
/>
|
||||
|
||||
</div>
|
||||
<div class="p-3 text-gray-700 text-md font-bold">
|
||||
|
||||
<q-btn-group push>
|
||||
<q-btn v-if="level > 1" @click="$emit('deleteGroup')" color="yellow" glossy text-color="black" push label="Zmaž skupinu" icon="delete" />
|
||||
<q-btn color="amber" @click="AddGroup(currentQuery)" glossy text-color="black" push label="Pridaj skupinu" icon="folder"/>
|
||||
<q-btn color="orange" @click="AddRule(currentQuery)" glossy text-color="black" push label="Pridaj pravidlo" icon="add" />
|
||||
</q-btn-group>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="q-pa-xs" v-for="(item) in currentQuery.rules" :key="item._uuid">
|
||||
<JsonQueryBuilderGroup v-if="typeof item.condition === 'string'" :currentQuery="item" :queryOptions="queryOptions" @delete-group="DeleteGroup(currentQuery,item)" :level="level + 1"></JsonQueryBuilderGroup>
|
||||
<JsonQueryBuilderRule v-else :rule="item" :options="queryOptions" @delete-rule="DeleteRule(currentQuery.rules,item)"></JsonQueryBuilderRule>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
.q-btn-group {
|
||||
border: 1px solid gray;
|
||||
}
|
||||
.border-4 {
|
||||
border: 4px solid blue;
|
||||
}
|
||||
</style>
|
||||
166
resources/js/components/JsonQueryBuilderRule.vue
Normal file
166
resources/js/components/JsonQueryBuilderRule.vue
Normal file
@@ -0,0 +1,166 @@
|
||||
<script setup>
|
||||
import Multiselect from 'vue-multiselect';
|
||||
import { matDelete } from '@quasar/extras/material-icons';
|
||||
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
|
||||
const props = defineProps(['rule', 'options', 'i18n']);
|
||||
|
||||
console.log("VALUE",props.rule.value);
|
||||
const dateValue = ref(props.rule.value);
|
||||
const filteredOptions = ref(props.options);
|
||||
|
||||
const formatter = ref({
|
||||
date: 'D.M.YYYY',
|
||||
month: 'MMM'
|
||||
});
|
||||
|
||||
|
||||
|
||||
const fieldValue = ref(selectByValue(props.options,"name",props.rule.id));
|
||||
|
||||
const rulesOperatorOptions = computed({
|
||||
get () {
|
||||
switch(fieldValue.value.type) {
|
||||
case 'Number':
|
||||
return [
|
||||
{id: '=', name: 'rovná sa'},
|
||||
{id: '!=', name: 'nerovná sa'},
|
||||
{id: '>', name: 'je väčšie'},
|
||||
{id: '<', name: 'je menšie'},
|
||||
{id: '>=', name: 'je rovné, vačšie'},
|
||||
{id: '<=', name: 'je menšie, rovné'}
|
||||
];
|
||||
case 'Date':
|
||||
return [
|
||||
{id: '=', name: 'rovná sa'},
|
||||
{id: '!=', name: 'nerovný'},
|
||||
{id: '>', name: 'je väčší'},
|
||||
{id: '<', name: 'je menší'},
|
||||
{id: '>=', name: 'je rovný, vačší'},
|
||||
{id: '<=', name: 'je menši, rovný'}
|
||||
];
|
||||
case 'String':
|
||||
default:
|
||||
return [
|
||||
{id: '=', name: 'rovná'},
|
||||
{id: '!=', name: 'nerovná sa'},
|
||||
{id: 'in', name: 'je v'},
|
||||
{id: 'not in', name: 'nieje v'},
|
||||
{id: '()', name: 'obsahuje'},
|
||||
{id: '!()', name: 'neobsahuje'},
|
||||
{id: '(', name: 'začína'},
|
||||
{id: ')', name: 'končí'},
|
||||
{id: '!(', name: 'nezačína'},
|
||||
{id: '!)', name: 'nekončí'}
|
||||
];
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
const criteria = ref(selectByValue(rulesOperatorOptions.value,"id",props.rule.operator));
|
||||
const input = ref(props.rule.value);
|
||||
|
||||
function filterFn (val, update, abort) {
|
||||
update(() => {
|
||||
const needle = val.toLocaleLowerCase();
|
||||
filteredOptions.value = props.options.filter(v => v.desc.toLocaleLowerCase().indexOf(needle) > -1)
|
||||
})
|
||||
}
|
||||
|
||||
function setModel (val) {
|
||||
fieldValue.value.value = val
|
||||
}
|
||||
|
||||
function selectByValue(arr, id, value, single = true) {
|
||||
let filtered = arr.filter(a => a[id] == value);
|
||||
console.log(filtered);
|
||||
if (single && filtered.length > 0)
|
||||
return filtered[0];
|
||||
return filtered;
|
||||
}
|
||||
|
||||
function FieldChange(val) {
|
||||
console.log(val);
|
||||
props.rule.id = val.name;
|
||||
fieldValue.value.type = val.type;
|
||||
input.value = null;
|
||||
props.rule.value = null;
|
||||
}
|
||||
|
||||
function CriteriaChange(params) {
|
||||
console.log("PARAMS=",params);
|
||||
props.rule.operator = params.id;
|
||||
}
|
||||
|
||||
function DateChange(params) {
|
||||
console.log(params);
|
||||
props.rule.value = params[0];
|
||||
}
|
||||
|
||||
function InputChange(params) {
|
||||
console.log(params);
|
||||
props.rule.value = params;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div class="row qa-pa-xs q-gutter-sm justify-between ">
|
||||
<div class="">
|
||||
<q-select
|
||||
dense
|
||||
filled
|
||||
use-input
|
||||
hide-selected
|
||||
fill-input
|
||||
v-model="fieldValue"
|
||||
option-label="desc"
|
||||
option-value="id"
|
||||
:options="filteredOptions"
|
||||
@input-value="setModel"
|
||||
@filter="filterFn"
|
||||
style="min-width: 400px;"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-select
|
||||
dense
|
||||
filled
|
||||
fill-input
|
||||
v-model="criteria"
|
||||
option-label="name"
|
||||
option-value="name"
|
||||
@update:model-value="CriteriaChange"
|
||||
:options="rulesOperatorOptions"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-input v-if="fieldValue.type == 'Date'" dense filled v-model="dateValue" mask="date" >
|
||||
<template v-slot:append>
|
||||
<q-icon name="event" class="cursor-pointer">
|
||||
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
||||
<q-date v-model="dateValue">
|
||||
<div class="row items-center justify-end">
|
||||
<q-btn v-close-popup label="Close" color="primary" flat />
|
||||
</div>
|
||||
</q-date>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<q-input v-if="fieldValue.type == 'String'" id="value" outlined dense filled type="text" class="block w-full" v-model="input" required @update:model-value="InputChange" />
|
||||
<q-input v-if="fieldValue.type == 'Number'" id="value" outlined dense filled type="number" class="block w-full" v-model="input" required @update:model-value="InputChange" />
|
||||
</div>
|
||||
<div>
|
||||
<q-btn rounded color="red" text-color="black" :icon="matDelete" @click="$emit('deleteRule')" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
@import 'vue-multiselect/dist/vue-multiselect.css';
|
||||
</style>
|
||||
28
resources/js/components/Pagination.vue
Normal file
28
resources/js/components/Pagination.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<script setup>
|
||||
import { Link } from '@inertiajs/vue3';
|
||||
|
||||
defineProps({
|
||||
links: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="links.length > 3">
|
||||
<div class="flex flex-wrap -mb-1">
|
||||
<template v-for="(link, p) in links" :key="p">
|
||||
<div v-if="link.url === null" class="mr-1 mb-1 px-4 py-3 text-sm leading-4 text-gray-400 border rounded"
|
||||
v-html="link.label" />
|
||||
<Link v-else
|
||||
class="mr-1 mb-1 px-4 py-3 text-sm leading-4 border rounded hover:bg-white focus:border-indigo-500 focus:text-indigo-500"
|
||||
:class="{ 'bg-blue-700 text-white': link.active }" method="post" :data="data" :href="link.url" v-html="link.label" as="button" />
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
60
resources/js/components/Pagination2.vue
Normal file
60
resources/js/components/Pagination2.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<script setup>
|
||||
import { Link } from '@inertiajs/inertia-vue3';
|
||||
|
||||
defineProps({
|
||||
links: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<template>
|
||||
<ul v-if="links.length > 3" class="inline-flex -space-x-px">
|
||||
<template v-for="(link, p) in links" :key="p">
|
||||
|
||||
<li v-if="link.url === null" class="bg-white border border-gray-300 text-gray-500 hover:bg-gray-100 hover:text-gray-700 ml-0 rounded-l-lg leading-tight py-2 px-3 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white" v-html=""/>
|
||||
<a href="#"
|
||||
class="bg-white border border-gray-300 text-gray-500 hover:bg-gray-100 hover:text-gray-700 leading-tight py-2 px-3 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">1</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#"
|
||||
class="bg-white border border-gray-300 text-gray-500 hover:bg-gray-100 hover:text-gray-700 leading-tight py-2 px-3 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">2</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" aria-current="page"
|
||||
class="bg-blue-50 border border-gray-300 text-blue-600 hover:bg-blue-100 hover:text-blue-700 py-2 px-3 dark:border-gray-700 dark:bg-gray-700 dark:text-white">3</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#"
|
||||
class="bg-white border border-gray-300 text-gray-500 hover:bg-gray-100 hover:text-gray-700 leading-tight py-2 px-3 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">4</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#"
|
||||
class="bg-white border border-gray-300 text-gray-500 hover:bg-gray-100 hover:text-gray-700 leading-tight py-2 px-3 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">5</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#"
|
||||
class="bg-white border border-gray-300 text-gray-500 hover:bg-gray-100 hover:text-gray-700 rounded-r-lg leading-tight py-2 px-3 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">Next</a>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
|
||||
<div v-if="links.length > 3">
|
||||
<div class="flex flex-wrap -mb-1">
|
||||
<template v-for="(link, p) in links" :key="p">
|
||||
<div v-if="link.url === null" class="mr-1 mb-1 px-4 py-3 text-sm leading-4 text-gray-400 border rounded"
|
||||
v-html="link.label" />
|
||||
<Link v-else
|
||||
class="mr-1 mb-1 px-4 py-3 text-sm leading-4 border rounded hover:bg-white focus:border-indigo-500 focus:text-indigo-500"
|
||||
:class="{ 'bg-blue-700 text-white': link.active }" method="post" :data="data" :href="link.url" v-html="link.label" as="button" />
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
118
resources/js/components/RpoRecord.vue
Normal file
118
resources/js/components/RpoRecord.vue
Normal file
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div class="table-main">
|
||||
<div
|
||||
v-for="(row, index) in arrData"
|
||||
:key="index"
|
||||
class="row-data m-2 d-flex"
|
||||
>
|
||||
<div class="key p-2 d-inline-block">
|
||||
<div class="text-capitalize ">
|
||||
{{ printRpoName(row) }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="['string', 'number'].includes(checkValueType(data[row]))">
|
||||
<div class="value p-2 d-inline-block">{{ data[row] }}</div>
|
||||
</div>
|
||||
<div v-else-if="checkValueType(data[row]) === 'array'">
|
||||
<div v-for="(arrRow, index2) in data[row]" :key="index2" class="d-flex">
|
||||
<div v-if="['string', 'number'].includes(checkValueType(arrRow))">
|
||||
{{ arrRow }}
|
||||
</div>
|
||||
<div v-else>
|
||||
<RpoRecord :data="arrRow" :rpo="subRpo(arrRow, row,index2)"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<RpoRecord :data="data[row]" :rpo="subRpo(data[row],row,index)" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import rpoJsonData from '../Data/RpoTree.json';
|
||||
|
||||
export default {
|
||||
name: "RpoRecord",
|
||||
props: {
|
||||
data: {
|
||||
type: Object
|
||||
},
|
||||
rpo: {
|
||||
type: Object,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
arrData() {
|
||||
return Object.keys(this.data);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
keyTitle(key) {
|
||||
return key.split("_").join(" ");
|
||||
},
|
||||
checkValueType(val) {
|
||||
if (typeof val !== "object") {
|
||||
return typeof val;
|
||||
}
|
||||
return Array.isArray(val) ? "array" : "object";
|
||||
},
|
||||
printRpoName(key) {
|
||||
|
||||
console.log('data',typeof this.rpo[key]);
|
||||
if (typeof this.rpo[key] !== 'undefined'){
|
||||
console.log(this.rpo[key]);
|
||||
return this.rpo[key]["desc"];
|
||||
}
|
||||
if (typeof this.rpo[key] !== 'undefined' && typeof this.rpo[key]["value"] !== 'undefined') {
|
||||
console.log(this.rpo[key]);
|
||||
return this.rpo[key].value.desc;
|
||||
}
|
||||
|
||||
return key;
|
||||
},
|
||||
subRpo(val,kz,i) {
|
||||
console.log('val=',val,'k=',kz,'i=',i);
|
||||
console.log(this.rpo);
|
||||
return this.rpo[kz];
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
console.log('JSON=',this.rpo);
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.table-main {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
}
|
||||
.m-2 {
|
||||
margin: .5rem!important;
|
||||
}
|
||||
.mx-2 {
|
||||
margin-right: .5rem!important;
|
||||
}
|
||||
.p-2 {
|
||||
padding: .5rem!important;
|
||||
}
|
||||
.d-flex {
|
||||
display: flex!important;
|
||||
}
|
||||
.d-inline-block {
|
||||
display: inline-block!important;
|
||||
}
|
||||
.text-capitalize {
|
||||
text-transform: capitalize!important;
|
||||
}
|
||||
.key {
|
||||
background: lightgray;
|
||||
}
|
||||
.table-main .row-data {
|
||||
border: 2px solid grey;
|
||||
border-radius: 2px;
|
||||
}
|
||||
</style>
|
||||
204
resources/js/components/RpoRecord2.vue
Normal file
204
resources/js/components/RpoRecord2.vue
Normal file
@@ -0,0 +1,204 @@
|
||||
<script setup>
|
||||
import rpoJsonData from '../Data/RpoTree.json';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
rpo: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: rpoJsonData
|
||||
}
|
||||
});
|
||||
|
||||
const columns = [
|
||||
{
|
||||
name: 'translated',
|
||||
required: true,
|
||||
label: 'Nazov',
|
||||
align: 'left',
|
||||
field: 'translated',
|
||||
sortable: false,
|
||||
},
|
||||
{ name: 'val', align: 'left', label: 'Hodnota', field: 'val', sortable: false },
|
||||
]
|
||||
|
||||
|
||||
const arrData = computed(() => Object.keys(props.data));
|
||||
|
||||
const title = ref(props.data["fullNames"][0]["value"]);
|
||||
console.log('TITLE', title);
|
||||
|
||||
function keyTitle(key) {
|
||||
return key.split("_").join(" ");
|
||||
}
|
||||
|
||||
function checkValueType(val) {
|
||||
if (typeof val !== "object") {
|
||||
return typeof val;
|
||||
}
|
||||
return Array.isArray(val) ? "array" : "object";
|
||||
}
|
||||
|
||||
function printRpoName(rpoKey) {
|
||||
|
||||
console.log('data', typeof props.rpo[rpoKey]);
|
||||
console.log('rpoKey', rpoKey);
|
||||
if (typeof props.rpo[rpoKey] !== 'undefined') {
|
||||
if (typeof props.rpo[rpoKey]["desc"] !== 'undefined') {
|
||||
console.log(props.rpo[rpoKey]);
|
||||
return props.rpo[rpoKey].desc;
|
||||
}
|
||||
if (typeof props.rpo[rpoKey]["value"] !== 'undefined') {
|
||||
console.log(props.rpo[rpoKey]);
|
||||
return props.rpo[rpoKey].value.desc;
|
||||
}
|
||||
|
||||
console.log(props.rpo[rpoKey]);
|
||||
return props.rpo[rpoKey]["desc"];
|
||||
}
|
||||
|
||||
return rpoKey;
|
||||
}
|
||||
|
||||
function createRPOflatList(resultTree, flatList, RpoTree, lastKey = undefined, level = 0, fullPathRpo = []) {
|
||||
console.log('RESTREE=', resultTree);
|
||||
let fullPath = [...fullPathRpo];
|
||||
if (lastKey != undefined) fullPath.push(lastKey);
|
||||
|
||||
if (level == 0 || checkValueType(resultTree) == "object") {
|
||||
let i = 0;
|
||||
Object.keys(resultTree).forEach(k => {
|
||||
if (typeof resultTree[k] != 'string') {
|
||||
if (RpoTree[k] !== undefined) {
|
||||
flatList.push({ "level": level, "key": k, "val": undefined, "translated": RpoTree[k].desc, "full": fullPath.join(' => '), "index": i++ });
|
||||
createRPOflatList(resultTree[k], flatList, RpoTree[k], k, level + 1, fullPath);
|
||||
}
|
||||
} else {
|
||||
console.log('RT=', RpoTree);
|
||||
console.log('K=', k);
|
||||
if (RpoTree[k] !== undefined)
|
||||
flatList.push({ "level": level, "key": k, "val": resultTree[k], "translated": RpoTree[k].desc, "full": fullPath.join(' => '), "index": i++ });
|
||||
}
|
||||
});
|
||||
} else if (checkValueType(resultTree) == "array") {
|
||||
let i = 0;
|
||||
for (const e of resultTree) {
|
||||
console.log('e=', e);
|
||||
if (checkValueType(e) == "object" || checkValueType(e) == "array") {
|
||||
createRPOflatList(e, flatList, RpoTree, lastKey, level + 1, fullPath);
|
||||
} else {
|
||||
console.log('RT=', RpoTree);
|
||||
flatList.push({ "level": level, "key": lastKey, "val": e, "translated": RpoTree.desc !== undefined ? RpoTree.desc : '', "full": fullPath.join(' => '), "index": i++ });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function subRpo(val, kz, i) {
|
||||
console.log('val=', val, 'k=', kz, 'i=', i);
|
||||
console.log(props.rpo);
|
||||
return props.rpo[kz];
|
||||
}
|
||||
|
||||
var flatListRpo = [];
|
||||
createRPOflatList(props.data, flatListRpo, props.rpo);
|
||||
console.log('FLAT=', flatListRpo);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- https://github.com/quasarframework/quasar/blob/dev/docs/src/examples/QTable/VirtscrollExpandedRow.vue -->
|
||||
<div class="col q-pa-md" style="overflow: auto;">
|
||||
<q-table style="height: 700px;" separator="cell" flat bordered dense :rows-per-page-options="[0]"
|
||||
:title="title" :rows="flatListRpo" :columns="columns" wrap-cells card-class="bg-deep-purple-7 text-white"
|
||||
table-header-class="bg-deep-purple-1 text-black" row-key="name">
|
||||
|
||||
<template v-slot:body="props">
|
||||
<q-tr :props="props" :key="`e_${props.row.index}`" class="q-virtual-scroll--with-prev">
|
||||
<q-td class="bg-grey-8">
|
||||
<div :class="`text-left level-${props.row.level}`">{{ props.row.translated }}</div>
|
||||
</q-td>
|
||||
<q-td class="bg-grey-6">
|
||||
<div class="text-left">{{ props.row.val }}</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</q-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.table-main {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
}
|
||||
|
||||
.level-1 {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.level-2 {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.level-3 {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.level-4 {
|
||||
padding-left: 40px;
|
||||
}
|
||||
|
||||
.level-5 {
|
||||
padding-left: 50px;
|
||||
}
|
||||
|
||||
|
||||
.m-2 {
|
||||
margin: 0rem !important;
|
||||
}
|
||||
|
||||
.mx-2 {
|
||||
margin-right: .5rem !important;
|
||||
}
|
||||
|
||||
.p-2 {
|
||||
padding: .5rem !important;
|
||||
}
|
||||
|
||||
.d-flex {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.d-inline-block {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
.text-capitalize {
|
||||
text-transform: capitalize !important;
|
||||
}
|
||||
|
||||
.key {
|
||||
background: lightgray;
|
||||
box-shadow:
|
||||
2px 0 0 0 #888,
|
||||
0 2px 0 0 #888,
|
||||
2px 2px 0 0 #888,
|
||||
/* Just to fix the corner */
|
||||
2px 0 0 0 #888 inset,
|
||||
0 2px 0 0 #888 inset;
|
||||
}
|
||||
|
||||
.table-main .row-data {
|
||||
box-shadow:
|
||||
2px 0 0 0 #000,
|
||||
0 2px 0 0 #000,
|
||||
2px 2px 0 0 #000,
|
||||
/* Just to fix the corner */
|
||||
2px 0 0 0 #000 inset,
|
||||
0 2px 0 0 #000 inset;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user