データ処理書き込み完了

This commit is contained in:
Mouriya
2024-05-17 23:32:14 +09:00
parent 61ac281134
commit cf4209333d
5 changed files with 197 additions and 73 deletions

View File

@@ -6,7 +6,7 @@
{{ selectedObject.name }} {{ selectedObject.name }}
</q-chip> </q-chip>
<q-chip color="info" text-color="white" v-if="isSelected && selectedObject.objectType==='variable'" :dense="true" class="selected-obj"> <q-chip color="info" text-color="white" v-if="isSelected && selectedObject.objectType==='variable'" :dense="true" class="selected-obj">
{{ selectedObject.name }} {{ selectedObject.name.name }}
</q-chip> </q-chip>
</template> </template>
<template v-slot:append> <template v-slot:append>
@@ -88,9 +88,9 @@
.condition-object{ .condition-object{
min-width: 200px; min-width: 200px;
max-height: 40px; max-height: 40px;
padding: 2px; margin: 0 2px;
} }
.selected-obj{ .selected-obj{
margin: 0px; margin: 0 2px;
} }
</style> </style>

View File

@@ -66,7 +66,7 @@
</div> </div>
<!-- condition --> <!-- condition -->
<div @click.stop @keypress.stop v-else > <div @click.stop @keypress.stop v-else >
<div class="row no-wrap items-center"> <div class="row no-wrap items-center q-my-xs">
<ConditionObject v-bind="prop.node" v-model="prop.node.object" class="col-4"></ConditionObject> <ConditionObject v-bind="prop.node" v-model="prop.node.object" class="col-4"></ConditionObject>
<q-select v-model="prop.node.operator" :options="operators" class="operator" :outlined="true" :dense="true"></q-select> <q-select v-model="prop.node.operator" :options="operators" class="operator" :outlined="true" :dense="true"></q-select>
<q-input v-if="!prop.node.object || !('options' in prop.node.object)" <q-input v-if="!prop.node.object || !('options' in prop.node.object)"
@@ -257,12 +257,12 @@ export default defineComponent( {
.condition-value{ .condition-value{
min-width: 200px; min-width: 200px;
max-height: 40px; max-height: 40px;
padding: 2px; margin: 0 2px;
} }
.operator{ .operator{
min-width: 150px; min-width: 150px;
max-height: 40px; max-height: 40px;
padding: 2px; margin: 0 2px;
text-align: center; text-align: center;
font-size: 12pt; font-size: 12pt;
} }

View File

@@ -1,43 +1,57 @@
<template> <template>
<div class="q-pa-md"> <div class="q-pa-md">
<q-table flat bordered row-key="name" :selection="type" <q-table flat bordered row-key="name" :selection="type" :selected="modelValue"
:selected="modelValue" @update:selected="$emit('update:modelValue', $event)" :columns="columns" :rows="rows" />
@update:selected="$emit('update:modelValue', $event)"
:columns="columns" :rows="rows" />
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { ref, reactive, PropType, compile } from 'vue'; import { PropType, reactive } from 'vue';
import {IActionNode,IActionVariable} from '../types/ActionTypes'; import { IActionVariable } from '../types/ActionTypes';
export default { export default {
name: 'VariableList', name: 'VariableList',
props: { props: {
name: String, name: String,
type: String, type: String,
vars:{ vars: {
type:Array as PropType<IActionVariable[]>, type: Array as PropType<IActionVariable[]>,
reqired:true, reqired: true,
default:()=>[] default: () => []
}, },
modelValue:Array modelValue: Array
}, },
emits:[ emits: [
'update:modelValue' 'update:modelValue'
], ],
setup(props) { setup(props) {
const columns= [ const variableName = (field) => {
{ name: 'actionName', label: 'アクション名',align: 'left',field: 'actionName',sortable: true}, const name = field.name;
{ name: 'displayName', label: '変数表示名', align: 'left',field: 'displayName', sortable: true }, return name.name;
{ name: 'name', label: '変数名', align: 'left',field: 'name',required: true, sortable: true } }
const columns = [
{ name: 'actionName', label: 'アクション名', align: 'left', field: 'actionName', sortable: true },
{ name: 'displayName', label: '変数表示名', align: 'left', field: 'displayName', sortable: true },
{ name: 'name', label: '変数名', align: 'left', field: variableName, required: true, sortable: true }
]; ];
const rows= props.vars.map((v)=>{
return {objectType:'variable',...v}; const rows = props.vars.flatMap((v) => {
if (v.name.vars && v.name.vars.length > 0) {
return v.name.vars
.filter(o => o.vName && o.logicalOperator && o.field)
.map(o => ({
objectType: 'variable',
name: { name: `${v.name.name}.${o.vName}` },
actionName: v.name.actionName,
displayName: v.name.displayName
}));
} else {
return [{ objectType: 'variable', ...v }];
}
}); });
return { return {
columns, columns,
rows:reactive(rows) rows: reactive(rows)
} }
} }
} }

View File

@@ -1,34 +1,66 @@
<template> <template>
<q-input v-model="value" type="text" :label="displayName" label-color="primary"> <div>
<q-tooltip persistent no-parent-event v-model="tooltipEnable" anchor="center left" self="center right"> <q-field :label="displayName" labelColor="primary" stack-label>
<div style="max-width: 24vw; "> <template v-slot:control>
<div v-if="p"> <q-card flat class="full-width">
<div class="row">字段名称:</div> <q-card-actions vertical>
<div class="row q-col-gutter-x-xs q-col-gutter-y-sm"> <q-btn color="grey-3" text-color="black" @click="() => { dgIsShow = true }">クリックで設定</q-btn>
<div class="col-4" style="min-width: 8vw;" </q-card-actions>
v-for="(item, index) in sources?.props?.modelValue?.fields" :key="index"> <q-card-section class="text-caption">
<div style="pointer-events: auto;">{{ item.type }}</div> <div v-for="(item) in processingObjectsInputDisplay" :key="item">{{ item }}</div>
<div><i>{{ item.label }}</i></div> </q-card-section>
</q-card>
</template>
</q-field>
<show-dialog v-model:visible="dgIsShow" name="条件エディタ" @close="closeDg" min-width="60vw" min-height="60vh">
<div class="q-mx-md q-mb-md">
<q-input v-model="processingProps.name" type="text" label-color="primary" label="変数名を入力してください"
placeholder="varName" />
</div>
<div class="q-mx-md">
<div class="row q-col-gutter-x-xs flex-center">
<div class="col-5">
<div class="q-mx-xs">数据源</div>
</div>
<div class="col-2">
<div class="q-mx-xs">运算符</div>
</div>
<div class="col-4">
<div class="q-mx-xs">目标变量</div>
</div>
<div class="col-1"><q-btn flat round dense icon="add" size="sm" @click="addProcessingObject" />
</div>
</div>
<div class="q-my-sm" v-for="(item, index) in processingObjects" :key="item.id">
<div class="row q-col-gutter-x-xs flex-center">
<div class="col-5">
<ConditionObject v-model="item.field" />
</div>
<div class="col-2">
<q-select v-model="item.logicalOperator" :options="logicalOperators" outlined
dense></q-select>
</div>
<div class="col-4">
<q-input v-model="item.vName" type="text" label="Label" outlined dense />
</div>
<div class="col-1">
<q-btn flat round dense icon="delete" size="sm"
@click="() => deleteProcessingObject(index)" />
</div> </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>
</div> </div>
</q-tooltip> </show-dialog>
<template v-slot:append> </div>
<q-btn round size="sm" padding="xs" color="secondary" icon="school"
@click="() => tooltipEnable = !tooltipEnable" />
</template>
</q-input>
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, ref } from 'vue'; import { v4 as uuidv4 } from 'uuid';
import { computed, defineComponent, provide, reactive, ref, watchEffect } from 'vue';
import ConditionObject from '../ConditionEditor/ConditionObject.vue';
import ShowDialog from '../ShowDialog.vue';
type Props = { type Props = {
props?: { props?: {
@@ -39,13 +71,40 @@ type Props = {
label: string; label: string;
code: string; code: string;
}[] }[]
} } | string
} }
}; };
type ProcessingObjectType = {
field?: {
name: string | {
name: string;
};
objectType: string;
type: string;
code: string;
label: string;
noLabel: boolean;
};
logicalOperator?: string;
vName?: string;
id: string;
}
type ValueType = {
name: string;
actionName: string,
displayName: string,
vars: ProcessingObjectType[];
}
export default defineComponent({ export default defineComponent({
name: 'DataProcessing', name: 'DataProcessing',
inheritAttrs: false, inheritAttrs: false,
components: {
ShowDialog,
ConditionObject,
},
props: { props: {
context: { context: {
type: Array<Props>, type: Array<Props>,
@@ -60,34 +119,70 @@ export default defineComponent({
default: '', default: '',
}, },
modelValue: { modelValue: {
type: String, type: Object as () => ValueType,
default: '',
}, },
}, },
setup(props, { emit }) { setup(props, { emit }) {
const value = ref(' '); const source = props.context.find(element => element?.props?.name === 'sources')
const tooltipEnable = ref(false);
const sources = props.context.find(element => element?.props?.name === 'sources');
const p = computed(() => { if (source) {
const fields = sources?.props?.modelValue?.fields provide('sourceFields', computed(() => {
if (!fields || fields.length === 0) { const modelValue = source.props?.modelValue;
return ''; if (modelValue && typeof modelValue !== 'string') {
} else if (fields.length === 1) { return modelValue.fields;
return fields[0].type; }
} else if (fields.length === 2) { return null;
return fields.map(field => field.type).join('+'); }));
} else { }
return `(${fields[0].type} + ${fields[1].type}) * ${fields[2].type}`;
} const actionName = props.context.find(element => element?.props?.name === 'displayName')
const processingProps: ValueType = props.modelValue && props.modelValue.vars
? props.modelValue
: reactive({
name: '',
actionName: actionName?.props?.modelValue as string,
displayName: '結果(戻り値)',
vars: [{ id: uuidv4() }]
});
const closeDg = () => {
emit('update:modelValue', processingProps
);
}
const processingObjects = processingProps.vars;
const deleteProcessingObject = (index: number) => processingObjects.length === 1
? processingObjects.splice(0, processingObjects.length, { id: uuidv4() })
: processingObjects.splice(index, 1);
const processingObjectsInputDisplay = computed(() =>
processingObjects ?
processingObjects
.filter(item => item.field && item.logicalOperator && item.vName)
.map(item => {
const name = typeof item.field?.name === 'string'
? item.field.name
: item.field?.name.name;
return `${processingProps.name}.${item.vName} = ${item.logicalOperator}(${name})`
})
: ''
);
watchEffect(() => {
emit('update:modelValue', processingProps);
}); });
return { return {
sources, uuidv4,
p, dgIsShow: ref(false),
value, closeDg,
tooltipEnable, processingObjects,
processingProps,
addProcessingObject: () => processingObjects.push({ id: uuidv4() }),
deleteProcessingObject,
logicalOperators: reactive(['MAX', 'SUM']),
processingObjectsInputDisplay,
}; };
}, },
}); });

View File

@@ -45,7 +45,16 @@ export interface IActionProperty {
export interface IActionVariable{ export interface IActionVariable{
actionName:string; actionName:string;
displayName:string; displayName:string;
name:string; name: {
name:string;
actionName:string;
displayName:string;
vars : {
vName:string;
logicalOperator:string;
field: object;
}[]
};
} }
/** /**
* アクションタイプ定義 * アクションタイプ定義
@@ -448,6 +457,12 @@ export class ActionFlow implements IActionFlow {
getPrevVarNames(prevNode:IActionNode):IActionVariable[]{ getPrevVarNames(prevNode:IActionNode):IActionVariable[]{
let varNames:IActionVariable[]=[]; let varNames:IActionVariable[]=[];
if(prevNode.varName!==undefined && prevNode.varName.modelValue){ if(prevNode.varName!==undefined && prevNode.varName.modelValue){
if(prevNode.varName.modelValue ==='object'){
console.log(prevNode);
}
varNames.unshift({ varNames.unshift({
actionName:prevNode.name, actionName:prevNode.name,
displayName:prevNode.varName.displayName, displayName:prevNode.varName.displayName,