condtion tree

This commit is contained in:
2023-12-25 17:07:40 +09:00
parent ea6e603036
commit 6e75a2a524
2 changed files with 213 additions and 0 deletions

View File

@@ -0,0 +1,195 @@
<template>
<div class="q-pa-md">
<q-tree :nodes="tree" node-key="num" v-if="tree.length" default-expand-all>
<template v-slot:header-root="prop">
<div class="row items-center" @click.stop>
<q-icon :name="prop.node.icon || 'share'" color="orange" size="28px" class="q-mr-sm" />
<div style="width:100px">
<q-select v-model="prop.node.logicalOperator" :options="logicalOperators" label="ロジクール"></q-select>
</div>
<q-btn @click="removeNode(prop.node)" class="q-ml-md" color="negative" icon="delete" size="5px"></q-btn>
<q-btn-dropdown class="q-ml-md" color="primary" icon="add" size="5px">
<q-list>
<q-item clickable v-close-popup @click="addGroup(prop.node, logicalOperators[0])">
<q-item-section>
<q-item-label>Group</q-item-label>
</q-item-section>
</q-item>
<q-item clickable v-close-popup @click.stop="addCondition(prop.node)">
<q-item-section>
<q-item-label>Condtion</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</div>
</template>
<template v-slot:header-generic="prop" >
<div class="row items-center" @click.stop>
<q-icon :name="prop.node.icon || 'star'" color="orange" size="28px" class="q-mr-sm" />
<div v-if="prop.node.type === 'group'">
<q-icon :name="prop.node.icon || 'share'" color="orange" size="28px" class="q-mr-sm" />
<div style="width:100px">
<q-select v-model="prop.node.logicalOperator" :options="logicalOperators" label="ロジクール"></q-select>
</div>
<q-btn @click="removeNode(prop.node)" class="q-ml-md" color="negative" icon="delete" size="5px"></q-btn>
<q-btn-dropdown class="q-ml-md" color="primary" icon="add" size="5px">
<q-list>
<q-item clickable v-close-popup @click="addGroup(prop.node, logicalOperators[0])">
<q-item-section>
<q-item-label>Group</q-item-label>
</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="addCondition(prop.node)">
<q-item-section>
<q-item-label>Condtion</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</div>
<div @click.stop @keypress.stop v-else >
<q-select v-model="prop.node.object" :options="objects" label="フィールド"></q-select>
<q-select v-model="prop.node.operator" :options="operators" label="オペレーター"></q-select>
<q-input v-model="prop.node.value" label="値"></q-input>
<q-btn @click="removeNode(prop.node)" class="q-ml-md" color="negative" icon="delete" size="5px"></q-btn>
</div>
</div>
</template>
</q-tree>
<q-btn @click="addGroup(null, logicalOperators[0])" class="q-mt-md" color="primary" icon="mdi-plus">Add Condition</q-btn>
<q-btn @click="getConditionString()" class="q-mt-md" color="primary" icon="mdi-plus">Show Condtion</q-btn>
<p>{{ conditionString }}</p>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const conditionString = ref('');
const tree = ref([]);
let num = 0;
const logicalOperators = [
{ label: 'AND', value: 'AND' },
{ label: 'OR', value: 'OR' },
];
const objects = [
{ label: 'Field 1', value: 'field1' },
{ label: 'Field 2', value: 'field2' },
{ label: 'Field 3', value: 'field3' },
];
const operators = [
{ label: 'Equals', value: '=' },
{ label: 'Not Equals', value: '<>' },
{ label: 'Greater Than', value: '>' },
{ label: 'Less Than', value: '<' },
];
const buildConditionString = (node) => {
if (node.type === 'group') {
let conditionString = '(';
for (let i = 0; i < node.children.length; i++) {
let childConditionString = buildConditionString(node.children[i]);
if (childConditionString !== '') {
conditionString += childConditionString;
if (i < node.children.length - 1) {
conditionString += ` ${node.logicalOperator.value} `;
}
}
}
conditionString += ')';
return conditionString;
} else {
if (node.object && node.operator && node.value) {
return `${node.object.value} ${node.operator.value} '${node.value}'`;
} else {
return '';
}
}
};
const getConditionString = () => {
conditionString.value = buildConditionString(tree.value[0]);
};
const addGroup = (node, logicalOperator = 'AND') => {
const newNode = {
header: 'generic',
num: num,
type: 'group',
logicalOperator: logicalOperator,
children: [],
parent: node,
};
num++;
const childNode = {
header: 'generic',
index: num,
type: 'condition',
logicalOperator: logicalOperator,
object: objects[0],
operator: operators[0],
value: '',
children: [],
parent: newNode,
};
newNode.children.push(childNode);
if (node === null) {
newNode.header = 'root';
tree.value.push(newNode);
} else {
node.children.push(newNode);
}
};
const addCondition = (node) => {
const newNode = {
header: 'generic',
num: num,
type: 'condition',
object: objects[0],
operator: operators[0],
value: '',
children: [],
parent: node,
};
num++;
node.children.push(newNode);
};
const removeNode = (node) => {
if (node.header === 'root') {
tree.value = [];
} else {
const index = node.parent.children.indexOf(node);
if (index != -1) {
node.parent.children.splice(index, 1);
if (node.parent.children.length == 0) {
removeNode(node.parent);
}
}
}
};
return {
conditionString,
tree,
num,
logicalOperators,
objects,
operators,
buildConditionString,
getConditionString,
addGroup,
addCondition,
removeNode,
};
},
};
</script>

View File

@@ -0,0 +1,18 @@
<template>
<q-page>
<div class="flowchart">
<node-condition></node-condition>
</div>
</q-page>
</template>
<script setup lang="ts">
import NodeCondition from 'src/components/main/NodeCondition.vue';
</script>
<style lang="scss">
.flowchart {
padding-top: 10px;
}
</style>