2つのデータ計算コンポーネントを追加する

This commit is contained in:
Mouriya
2024-05-13 06:56:44 +09:00
parent 371e2ee073
commit 64d2cadd82
6 changed files with 247 additions and 120 deletions

View File

@@ -23,9 +23,9 @@
<q-virtual-scroll style="max-height: 160px;" :items="selectedField.fields" separator v-slot="{ item, index }">
<q-item :key="index" dense clickable >
<q-item-section>
<q-item-label>
{{ item.label }}
</q-item-label>
<q-item-label>
{{ item.label }}
</q-item-label>
</q-item-section>
<q-item-section side>
<q-btn round flat size="sm" icon="clear" @click="removeField(index)" />
@@ -128,7 +128,7 @@ interface IAppFields{
export default defineComponent({
inheritAttrs:false,
name: 'FieldInput',
name: 'AppFieldSelect',
components: {
ShowDialog,
FieldSelect,

View File

@@ -1,12 +1,12 @@
<template>
<div v-bind="$attrs">
<q-field v-model="tree" :label="displayName" labelColor="primary" stack-label >
<template v-slot:control >
<q-field v-model="tree" :label="displayName" labelColor="primary" stack-label>
<template v-slot:control>
<q-card flat class="full-width">
<q-card-actions vertical>
<q-btn color="grey-3" text-color="black" @click="showDg()">クリックで設定{{ isSetted?'設定済み':'未設定' }}</q-btn>
<q-btn color="grey-3" text-color="black" @click="showDg()">クリックで設定{{ isSetted ? '設定済み' : '未設定' }}</q-btn>
</q-card-actions>
<q-card-section class="text-caption" >
<q-card-section class="text-caption">
<div v-if="!isSetted">{{ placeholder }}</div>
<div v-else>{{ conditionString }}</div>
</q-card-section>
@@ -17,82 +17,109 @@
</div>
</template>
<script lang="ts">
import { defineComponent, ref ,watchEffect,computed,reactive} from 'vue';
import { ConditionTree,GroupNode,ConditionNode,LogicalOperator,Operator } from 'app/src/types/Conditions';
import ConditionEditor from '../ConditionEditor/ConditionEditor.vue'
export default defineComponent({
name: 'FieldInput',
inheritAttrs:false,
components: {
ConditionEditor
},
props: {
displayName:{
type: String,
default: '',
},
name:{
type: String,
default: '',
},
placeholder: {
type: String,
default: '',
},
hint:{
type: String,
default: '',
},
modelValue: {
type: String,
default: null
},
},
setup(props, { emit }) {
const appDg = ref();
const show = ref(false);
const tree = reactive(new ConditionTree());
if(props.modelValue && props.modelValue!==''){
tree.fromJson(props.modelValue);
}else{
const newNode = new ConditionNode({},Operator.Equal,'',tree.root);
tree.addNode(tree.root,newNode);
}
const isSetted=ref(props.modelValue && props.modelValue!=='');
<script lang="ts">
import { ConditionNode, ConditionTree, Operator } from 'app/src/types/Conditions';
import { computed, defineComponent, provide, reactive, ref, watchEffect } from 'vue';
import ConditionEditor from '../ConditionEditor/ConditionEditor.vue';
const conditionString = computed(()=>{
return tree.buildConditionString(tree.root);
});
const showDg = () => {
show.value = true;
};
const onClosed = (val:string) => {
if (val == 'OK') {
const conditionJson = tree.toJson();
isSetted.value=true;
emit('update:modelValue', conditionJson);
}
};
watchEffect(() => {
const conditionJson = tree.toJson();
emit('update:modelValue', conditionJson);
});
return {
appDg,
isSetted,
show,
showDg,
onClosed,
tree,
conditionString
};
type Props = {
props?: {
name: string;
modelValue?: {
fields: {
type: string;
label: string;
code: string;
}[]
}
});
</script>
}
};
export default defineComponent({
name: 'FieldInput',
inheritAttrs: false,
components: {
ConditionEditor
},
props: {
context: {
type: Array<Props>,
default: '',
},
displayName: {
type: String,
default: '',
},
name: {
type: String,
default: '',
},
placeholder: {
type: String,
default: '',
},
hint: {
type: String,
default: '',
},
modelValue: {
type: String,
default: null
},
},
setup(props, { emit }) {
const source = props.context.find(element => element?.props?.name === 'sources')
if (source) {
provide('sourceFields', computed( () => source.props?.modelValue?.fields ?? []));
}
const appDg = ref();
const show = ref(false);
const tree = reactive(new ConditionTree());
if (props.modelValue && props.modelValue !== '') {
tree.fromJson(props.modelValue);
} else {
const newNode = new ConditionNode({}, Operator.Equal, '', tree.root);
tree.addNode(tree.root, newNode);
}
const isSetted = ref(props.modelValue && props.modelValue !== '');
const conditionString = computed(() => {
return tree.buildConditionString(tree.root);
});
const showDg = () => {
show.value = true;
};
const onClosed = (val: string) => {
if (val == 'OK') {
const conditionJson = tree.toJson();
isSetted.value = true;
emit('update:modelValue', conditionJson);
}
};
watchEffect(() => {
const conditionJson = tree.toJson();
emit('update:modelValue', conditionJson);
});
return {
appDg,
isSetted,
show,
showDg,
onClosed,
tree,
conditionString
};
}
});
</script>

View File

@@ -0,0 +1,95 @@
<template>
<q-input v-model="value" type="text" :label="displayName" label-color="primary">
<q-tooltip persistent no-parent-event v-model="tooltipEnable" anchor="center left" self="center right">
<div style="max-width: 24vw; ">
<div v-if="p">
<div class="row">字段名称:</div>
<div class="row q-col-gutter-x-xs q-col-gutter-y-sm">
<div class="col-4" style="min-width: 8vw;"
v-for="(item, index) in sources?.props?.modelValue?.fields" :key="index">
<div style="pointer-events: auto;">{{ item.type }}</div>
<div><i>{{ item.label }}</i></div>
</div>
</div>
<div class="row q-mt-md">示例:</div>
<div class="row" style="pointer-events: auto;"> {{ p }}</div>
</div>
<div v-else>
请先选择计算来源
</div>
</div>
</q-tooltip>
<template v-slot:append>
<q-btn round size="sm" padding="xs" color="secondary" icon="school"
@click="() => tooltipEnable = !tooltipEnable" />
</template>
</q-input>
</template>
<script lang="ts">
import { computed, defineComponent, ref } from 'vue';
type Props = {
props?: {
name: string;
modelValue?: {
fields: {
type: string;
label: string;
code: string;
}[]
}
}
};
export default defineComponent({
name: 'DataProcessing',
inheritAttrs: false,
props: {
context: {
type: Array<Props>,
default: '',
},
displayName: {
type: String,
default: '',
},
name: {
type: String,
default: '',
},
modelValue: {
type: String,
default: '',
},
},
setup(props, { emit }) {
const value = ref(' ');
const tooltipEnable = ref(false);
const sources = props.context.find(element => element?.props?.name === 'sources');
const p = computed(() => {
const fields = sources?.props?.modelValue?.fields
if (!fields || fields.length === 0) {
return '';
} else if (fields.length === 1) {
return fields[0].type;
} else if (fields.length === 2) {
return fields.map(field => field.type).join('+');
} else {
return `(${fields[0].type} + ${fields[1].type}) * ${fields[2].type}`;
}
});
return {
sources,
p,
value,
tooltipEnable,
};
},
});
</script>
<style lang="scss"></style>

View File

@@ -1,7 +1,7 @@
<template>
<div>
<div v-for="(item, index) in properties" :key="index" >
<component :is="item.component" v-bind="item.props" :connectProps="connectProps(item.props)" v-model="item.props.modelValue"></component>
<component :is="item.component" v-bind="item.props" :context="properties" :connectProps="connectProps(item.props)" v-model="item.props.modelValue"></component>
</div>
</div>
</template>
@@ -21,6 +21,7 @@ import ConditionInput from '../right/ConditionInput.vue';
import EventSetter from '../right/EventSetter.vue';
import ColorPicker from './ColorPicker.vue';
import NumInput from './NumInput.vue';
import DataProcessing from './DataProcessing.vue';
import { IActionNode,IActionProperty,IProp } from 'src/types/ActionTypes';
export default defineComponent({
@@ -35,7 +36,8 @@ export default defineComponent({
ConditionInput,
EventSetter,
ColorPicker,
NumInput
NumInput,
DataProcessing
},
props: {
nodeProps: {
@@ -50,7 +52,7 @@ export default defineComponent({
setup(props, context) {
const properties=ref(props.nodeProps);
const connectProps=(props:IProp)=>{
const connProps:any={};
const connProps:any={context:properties};
if(props && "connectProps" in props && props.connectProps!=undefined){
for(let connProp of props.connectProps){
let targetProp = properties.value.find((prop)=>prop.props.name===connProp.propName);