condtion tree
This commit is contained in:
195
frontend/src/components/main/NodeCondition.vue
Normal file
195
frontend/src/components/main/NodeCondition.vue
Normal 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>
|
||||
18
frontend/src/pages/conditionPage.vue
Normal file
18
frontend/src/pages/conditionPage.vue
Normal 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>
|
||||
Reference in New Issue
Block a user