新しい統合されたフィールド入力、すべての関連部品の一致修正. フィールドの値を取得する に新しいアクションを追加
This commit is contained in:
@@ -1,20 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<q-field v-model="selectedObject" labelColor="primary" class="condition-object"
|
<q-field labelColor="primary" class="condition-object" :clearable="isSelected" stack-label :dense="true"
|
||||||
:clearable="isSelected" stack-label :dense="true" :outlined="true" >
|
:outlined="true">
|
||||||
<template v-slot:control >
|
<template v-slot:control>
|
||||||
<q-chip color="primary" text-color="white" v-if="isSelected && selectedObject.objectType==='field'" :dense="true" class="selected-obj">
|
<!-- <q-chip color="primary" text-color="white" v-if="isSelected && selectedObject.objectType==='field'" :dense="true" class="selected-obj">
|
||||||
{{ 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.name }}
|
{{ selectedObject.name.name }}
|
||||||
</q-chip>
|
</q-chip> -->
|
||||||
|
{{ selectedObject?.sharedText }}
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:append>
|
<template v-slot:append>
|
||||||
<q-icon name="search" class="cursor-pointer" @click="showDg"/>
|
<q-icon name="search" class="cursor-pointer" @click="showDg" />
|
||||||
</template>
|
</template>
|
||||||
</q-field>
|
</q-field>
|
||||||
<show-dialog v-model:visible="show" name="設定項目一覧" @close="closeDg" min-width="400px">
|
<show-dialog v-model:visible="show" name="設定項目" @close="closeDg" min-width="400px">
|
||||||
<template v-slot:toolbar>
|
<!-- <template v-slot:toolbar>
|
||||||
<q-input dense debounce="200" v-model="filter" placeholder="検索" clearable>
|
<q-input dense debounce="200" v-model="filter" placeholder="検索" clearable>
|
||||||
<template v-slot:before>
|
<template v-slot:before>
|
||||||
<q-icon name="search" />
|
<q-icon name="search" />
|
||||||
@@ -22,47 +23,68 @@
|
|||||||
</q-input>
|
</q-input>
|
||||||
</template>
|
</template>
|
||||||
<condition-objects ref="appDg" name="フィールド" type="single" :filter="filter" :appId="store.appInfo?.appId" :vars="vars"></condition-objects>
|
<condition-objects ref="appDg" name="フィールド" type="single" :filter="filter" :appId="store.appInfo?.appId" :vars="vars"></condition-objects>
|
||||||
|
-->
|
||||||
|
<DynamicItemInput v-model:selectedObject="selectedObject" :canInput="config.canInput"
|
||||||
|
:buttonsConfig="config.buttonsConfig" :appId="store.appInfo?.appId" />
|
||||||
</show-dialog>
|
</show-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, reactive, ref ,watchEffect,computed} from 'vue';
|
import { defineComponent, reactive, ref, watchEffect, computed } from 'vue';
|
||||||
import ShowDialog from '../ShowDialog.vue';
|
import ShowDialog from '../ShowDialog.vue';
|
||||||
import ConditionObjects from '../ConditionObjects.vue';
|
// import ConditionObjects from '../ConditionObjects.vue';
|
||||||
import { useFlowEditorStore } from '../../stores/flowEditor';
|
import DynamicItemInput from '../DynamicItemInput/DynamicItemInput.vue';
|
||||||
import {IActionFlow,IActionNode,IActionVariable} from '../../types/ActionTypes';
|
import { useFlowEditorStore } from '../../stores/flowEditor';
|
||||||
export default defineComponent({
|
import { IActionFlow, IActionNode, IActionVariable } from '../../types/ActionTypes';
|
||||||
|
export default defineComponent({
|
||||||
name: 'ConditionObject',
|
name: 'ConditionObject',
|
||||||
components: {
|
components: {
|
||||||
ShowDialog,
|
ShowDialog,
|
||||||
ConditionObjects
|
DynamicItemInput,
|
||||||
|
// ConditionObjects
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
config: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
canInput: false,
|
||||||
|
buttonsConfig: [
|
||||||
|
{ label: 'フィールド', color: 'primary', type: 'FieldAdd' },
|
||||||
|
{ label: '変数', color: 'green', type: 'VariableAdd' },
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null
|
default: null
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const appDg = ref();
|
// const appDg = ref();
|
||||||
const show = ref(false);
|
const show = ref(false);
|
||||||
const selectedObject = ref(props.modelValue);
|
const selectedObject = ref(props.modelValue);
|
||||||
const store = useFlowEditorStore();
|
const store = useFlowEditorStore();
|
||||||
const isSelected = computed(()=>{
|
// const sharedText = ref(''); // 共享的文本状态
|
||||||
return selectedObject.value!==null && typeof selectedObject.value === 'object' && ('name' in selectedObject.value)
|
const isSelected = computed(() => {
|
||||||
|
return selectedObject?.value?.sharedText !== '';
|
||||||
});
|
});
|
||||||
let vars:IActionVariable[] =[];
|
// const isSelected = computed(()=>{
|
||||||
if(store.currentFlow!==undefined && store.activeNode!==undefined ){
|
// return selectedObject.value!==null && typeof selectedObject.value === 'object' && ('name' in selectedObject.value)
|
||||||
vars =store.currentFlow.getVarNames(store.activeNode);
|
// });
|
||||||
|
let vars: IActionVariable[] = [];
|
||||||
|
if (store.currentFlow !== undefined && store.activeNode !== undefined) {
|
||||||
|
vars = store.currentFlow.getVarNames(store.activeNode);
|
||||||
}
|
}
|
||||||
const filter=ref('');
|
// const filter=ref('');
|
||||||
const showDg = () => {
|
const showDg = () => {
|
||||||
show.value = true;
|
show.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const closeDg = (val:string) => {
|
const closeDg = (val: string) => {
|
||||||
if (val == 'OK') {
|
if (val == 'OK') {
|
||||||
selectedObject.value = appDg.value.selected[0];
|
// selectedObject.value = appDg.value.selected[0];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -72,25 +94,30 @@
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
store,
|
store,
|
||||||
appDg,
|
// appDg,
|
||||||
show,
|
show,
|
||||||
showDg,
|
showDg,
|
||||||
closeDg,
|
closeDg,
|
||||||
selectedObject,
|
selectedObject,
|
||||||
vars:reactive(vars),
|
vars: reactive(vars),
|
||||||
isSelected,
|
isSelected,
|
||||||
filter
|
buttonsConfig: [
|
||||||
|
{ label: 'フィールド', color: 'primary', type: 'FieldAdd' },
|
||||||
|
{ label: '変数', color: 'green', type: 'VariableAdd' },
|
||||||
|
]
|
||||||
|
// filter
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.condition-object{
|
.condition-object {
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
max-height: 40px;
|
max-height: 40px;
|
||||||
margin: 0 2px;
|
margin: 0 2px;
|
||||||
}
|
}
|
||||||
.selected-obj{
|
|
||||||
|
.selected-obj {
|
||||||
margin: 0 2px;
|
margin: 0 2px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -67,11 +67,13 @@
|
|||||||
<!-- condition -->
|
<!-- condition -->
|
||||||
<div @click.stop @keypress.stop v-else >
|
<div @click.stop @keypress.stop v-else >
|
||||||
<div class="row no-wrap items-center q-my-xs">
|
<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" :config="leftDynamicItemConfig" class="col-4"/>
|
||||||
<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)"
|
<ConditionObject v-bind="prop.node" v-model="prop.node.value" :config="rightDynamicItemConfig" class="col-4"/>
|
||||||
|
<!-- <ConditionObject v-bind="prop.node" v-model="prop.node.object" class="col-4"/> -->
|
||||||
|
<!-- <q-input v-if="!prop.node.object || !('options' in prop.node.object)"
|
||||||
v-model="prop.node.value"
|
v-model="prop.node.value"
|
||||||
class="condition-value" :outlined="true" :dense="true" ></q-input>
|
class="condition-value" :outlined="true" :dense="true" ></q-input> -->
|
||||||
<q-select v-if="prop.node.object && ('options' in prop.node.object)"
|
<q-select v-if="prop.node.object && ('options' in prop.node.object)"
|
||||||
v-model="prop.node.value"
|
v-model="prop.node.value"
|
||||||
:options="objectValueOptions(prop.node.object.options)"
|
:options="objectValueOptions(prop.node.object.options)"
|
||||||
@@ -225,6 +227,8 @@ export default defineComponent( {
|
|||||||
// addCondition(tree.root);
|
// addCondition(tree.root);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
leftDynamicItemConfig :inject('leftDynamicItemConfig'),
|
||||||
|
rightDynamicItemConfig:inject('rightDynamicItemConfig'),
|
||||||
showingCondition,
|
showingCondition,
|
||||||
conditionString,
|
conditionString,
|
||||||
tree,
|
tree,
|
||||||
|
|||||||
134
frontend/src/components/DynamicItemInput/DynamicItemInput.vue
Normal file
134
frontend/src/components/DynamicItemInput/DynamicItemInput.vue
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
<template>
|
||||||
|
<div class="q-mx-md" style="max-width: 600px;">
|
||||||
|
<!-- <q-card> -->
|
||||||
|
<div class="q-mb-md">
|
||||||
|
<q-input ref="inputRef" outlined dense debounce="200" @update:model-value="updateSharedText"
|
||||||
|
v-model="sharedText" :readonly="!canInput">
|
||||||
|
<template v-slot:append>
|
||||||
|
<q-btn flat round padding="none" icon="cancel" @click="clearSharedText" color="grey-6" />
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row q-gutter-sm">
|
||||||
|
<q-btn v-for="button in buttonsConfig" :key="button.type" :color="button.color" @mousedown.prevent
|
||||||
|
@click="openDialog(button)" size="sm">
|
||||||
|
{{ button.label }}
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<show-dialog v-model:visible="dialogVisible" :name="currentDialogName" @close="closeDialog" min-width="400px">
|
||||||
|
<template v-slot:toolbar>
|
||||||
|
<q-input dense debounce="200" v-model="filter" clearable>
|
||||||
|
<template v-slot:before>
|
||||||
|
<q-icon name="search" />
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
</template>
|
||||||
|
<!-- asdf -->
|
||||||
|
<component :is="currentComponent" @select="handleSelect" :filter="filter" :appId="appId" />
|
||||||
|
</show-dialog>
|
||||||
|
<!-- </q-card> -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { ref, inject, watchEffect, defineComponent } from 'vue';
|
||||||
|
import FieldAdd from './FieldAdd.vue';
|
||||||
|
import VariableAdd from './VariableAdd.vue';
|
||||||
|
// import FunctionAdd from './FunctionAdd.vue';
|
||||||
|
import ShowDialog from '../ShowDialog.vue';
|
||||||
|
|
||||||
|
type ButtonConfig = {
|
||||||
|
label: string;
|
||||||
|
color: string;
|
||||||
|
type: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'DynamicItemInput',
|
||||||
|
components: {
|
||||||
|
FieldAdd,
|
||||||
|
VariableAdd,
|
||||||
|
// FunctionAdd,
|
||||||
|
ShowDialog
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
canInput: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
appId: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
selectedObject: {
|
||||||
|
default: {}
|
||||||
|
},
|
||||||
|
buttonsConfig: {
|
||||||
|
type: Array as () => ButtonConfig[],
|
||||||
|
default: () => [
|
||||||
|
{ label: 'フィールド', color: 'primary', type: 'FieldAdd' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const filter = ref('');
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
const currentDialogName = ref('');
|
||||||
|
const currentComponent = ref('FieldAdd');
|
||||||
|
const sharedText = ref(props.selectedObject?.sharedText ?? '');
|
||||||
|
const inputRef = ref();
|
||||||
|
|
||||||
|
const openDialog = (button: ButtonConfig) => {
|
||||||
|
currentDialogName.value = button.label;
|
||||||
|
currentComponent.value = button.type;
|
||||||
|
dialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
dialogVisible.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSelect = (value) => {
|
||||||
|
// 获取当前光标位置
|
||||||
|
// const cursorPosition = inputRef.value.getNativeElement().selectionStart;
|
||||||
|
// if (cursorPosition === undefined || cursorPosition === 0) {
|
||||||
|
sharedText.value = `${value._t}`;
|
||||||
|
// } else {
|
||||||
|
// const textBefore = sharedText.value.substring(0, cursorPosition);
|
||||||
|
// const textAfter = sharedText.value.substring(cursorPosition);
|
||||||
|
// sharedText.value = `${textBefore}${value._t}${textAfter}`;
|
||||||
|
// }
|
||||||
|
|
||||||
|
emit('update:selectedObject', { sharedText: sharedText.value, ...value });
|
||||||
|
dialogVisible.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const clearSharedText = () => {
|
||||||
|
sharedText.value = '';
|
||||||
|
emit('update:selectedObject', {});
|
||||||
|
}
|
||||||
|
const updateSharedText = (value) => {
|
||||||
|
sharedText.value = value;
|
||||||
|
|
||||||
|
emit('update:selectedObject', { ...props.selectedObject, sharedText: value });
|
||||||
|
console.log(props.selectedObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
filter,
|
||||||
|
dialogVisible,
|
||||||
|
currentDialogName,
|
||||||
|
currentComponent,
|
||||||
|
openDialog,
|
||||||
|
closeDialog,
|
||||||
|
handleSelect,
|
||||||
|
clearSharedText,
|
||||||
|
updateSharedText,
|
||||||
|
sharedText,
|
||||||
|
inputRef
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
41
frontend/src/components/DynamicItemInput/FieldAdd.vue
Normal file
41
frontend/src/components/DynamicItemInput/FieldAdd.vue
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<template>
|
||||||
|
<field-list v-model="selected" type="single" :filter="filter" :appId="sourceApp ? sourceApp : appId"
|
||||||
|
:fields="sourceFields" @update:modelValue="handleSelect" />
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { computed, inject, ref } from 'vue';
|
||||||
|
import FieldList from '../FieldList.vue';
|
||||||
|
export default {
|
||||||
|
name: 'FieldAdd',
|
||||||
|
components: {
|
||||||
|
FieldList,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
appId: Number,
|
||||||
|
filter: String
|
||||||
|
},
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const sourceFields = inject<Array<unknown>>('sourceFields')
|
||||||
|
const sourceApp = inject<number>('sourceApp')
|
||||||
|
const appId = computed(() => {
|
||||||
|
if (sourceFields || sourceApp) {
|
||||||
|
return sourceApp.value
|
||||||
|
} else {
|
||||||
|
return props.appId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
sourceFields,
|
||||||
|
sourceApp,
|
||||||
|
selected: ref([]),
|
||||||
|
handleSelect: (newSelection: any[]) => {
|
||||||
|
|
||||||
|
if (newSelection.length > 0) {
|
||||||
|
const v = newSelection[0]
|
||||||
|
emit('select', { _t: `field(${appId.value},${v.name})`, ...v }); // 假设您只需要选择的第一个字段的名称
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
42
frontend/src/components/DynamicItemInput/VariableAdd.vue
Normal file
42
frontend/src/components/DynamicItemInput/VariableAdd.vue
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<template>
|
||||||
|
<variable-list v-model="selected" type="single" :vars="vars" :filter="filter" @update:modelValue="handleSelect" />
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import VariableList from '../VariableList.vue';
|
||||||
|
import { useFlowEditorStore } from 'src/stores/flowEditor';
|
||||||
|
import { IActionVariable } from 'src/types/ActionTypes';
|
||||||
|
export default {
|
||||||
|
name: 'VariableAdd',
|
||||||
|
components: {
|
||||||
|
VariableList,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
appId: Number,
|
||||||
|
filter: String
|
||||||
|
},
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const store = useFlowEditorStore();
|
||||||
|
let vars: IActionVariable[] = [];
|
||||||
|
console.log(store.currentFlow !== undefined && store.activeNode !== undefined);
|
||||||
|
|
||||||
|
if (store.currentFlow !== undefined && store.activeNode !== undefined) {
|
||||||
|
vars = store.currentFlow.getVarNames(store.activeNode);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
vars,
|
||||||
|
selected: ref([]),
|
||||||
|
handleSelect: (newSelection: any[]) => {
|
||||||
|
if (newSelection.length > 0) {
|
||||||
|
const v = newSelection[0];
|
||||||
|
let name = v.name
|
||||||
|
if (typeof name === 'object') {
|
||||||
|
name = name.name
|
||||||
|
}
|
||||||
|
emit('select', { _t: `var(${name})`, ...v }); // 假设您只需要选择的第一个字段的名称
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -1,20 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- <div class="q-pa-md q-gutter-sm" > -->
|
<!-- <div class="q-pa-md q-gutter-sm" > -->
|
||||||
<q-dialog :model-value="visible" persistent bordered >
|
<q-dialog :model-value="visible" persistent bordered >
|
||||||
<q-card style="min-width: 40vw; max-width: 80vw; max-height: 95vh;" :style="cardStyle">
|
<q-card class="" style="min-width: 40vw; max-width: 80vw; max-height: 95vh;" :style="cardStyle">
|
||||||
<q-toolbar class="bg-grey-4">
|
<q-toolbar class="bg-grey-4">
|
||||||
<q-toolbar-title>{{ name }}</q-toolbar-title>
|
<q-toolbar-title>{{ name }}</q-toolbar-title>
|
||||||
<q-space></q-space>
|
<q-space></q-space>
|
||||||
<slot name="toolbar"></slot>
|
<slot name="toolbar"></slot>
|
||||||
<q-btn flat round dense icon="close" @click="CloseDialogue('Cancel')" />
|
<q-btn flat round dense icon="close" @click="CloseDialogue('Cancel')" />
|
||||||
</q-toolbar>
|
</q-toolbar>
|
||||||
<q-card-section>
|
<q-card-section class="q-mt-md" :style="sectionStyle">
|
||||||
<!-- <div class="text-h6">{{ name }}</div> -->
|
|
||||||
</q-card-section>
|
|
||||||
<q-card-section class="q-pt-none" :style="sectionStyle">
|
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-actions align="right" class="text-primary q-mt-lg">
|
<q-card-actions align="right" class="text-primary">
|
||||||
<q-btn flat label="確定" v-close-popup @click="CloseDialogue('OK')" />
|
<q-btn flat label="確定" v-close-popup @click="CloseDialogue('OK')" />
|
||||||
<q-btn flat label="キャンセル" v-close-popup @click="CloseDialogue('Cancel')" />
|
<q-btn flat label="キャンセル" v-close-popup @click="CloseDialogue('Cancel')" />
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="q-pa-md">
|
<div class="q-pa-md">
|
||||||
<q-table flat bordered row-key="id" :selection="type" :selected="modelValue"
|
<q-table flat bordered row-key="id" :selection="type" :selected="modelValue" :filter="filter"
|
||||||
@update:selected="$emit('update:modelValue', $event)" :columns="columns" :rows="rows" />
|
@update:selected="$emit('update:modelValue', $event)" :columns="columns" :rows="rows" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -19,7 +19,8 @@ export default {
|
|||||||
reqired: true,
|
reqired: true,
|
||||||
default: () => []
|
default: () => []
|
||||||
},
|
},
|
||||||
modelValue: Array
|
modelValue: Array,
|
||||||
|
filter: String
|
||||||
},
|
},
|
||||||
emits: [
|
emits: [
|
||||||
'update:modelValue'
|
'update:modelValue'
|
||||||
|
|||||||
@@ -42,6 +42,15 @@ type Props = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type InputConfg = {
|
||||||
|
canInput: boolean;
|
||||||
|
buttonsConfig: {
|
||||||
|
label: string;
|
||||||
|
color: string;
|
||||||
|
type: string;
|
||||||
|
}[]
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'FieldInput',
|
name: 'FieldInput',
|
||||||
@@ -84,6 +93,24 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
operatorList: {
|
operatorList: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
},
|
||||||
|
inputConfig: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
left: {
|
||||||
|
canInput: false,
|
||||||
|
buttonsConfig: [
|
||||||
|
{ label: 'フィールド', color: 'primary', type: 'FieldAdd' },
|
||||||
|
{ label: '変数', color: 'green', type: 'VariableAdd' },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
right: {
|
||||||
|
canInput: true,
|
||||||
|
buttonsConfig: [
|
||||||
|
{ label: '変数', color: 'green', type: 'VariableAdd' },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -98,6 +125,8 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
provide('leftDynamicItemConfig', props.inputConfig.left);
|
||||||
|
provide('rightDynamicItemConfig', props.inputConfig.right);
|
||||||
provide('Operator', props.operatorList);
|
provide('Operator', props.operatorList);
|
||||||
|
|
||||||
const btnDisable = computed(() => {
|
const btnDisable = computed(() => {
|
||||||
|
|||||||
@@ -21,12 +21,12 @@
|
|||||||
<div class="q-mx-md">
|
<div class="q-mx-md">
|
||||||
<div class="row q-col-gutter-x-xs flex-center">
|
<div class="row q-col-gutter-x-xs flex-center">
|
||||||
<div class="col-5">
|
<div class="col-5">
|
||||||
<div class="q-mx-xs">From</div>
|
<div class="q-mx-xs">ソース</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-1">
|
<div class="col-1">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-5">
|
<div class="col-5">
|
||||||
<div class="q-mx-xs">To</div>
|
<div class="q-mx-xs">目標</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-1"><q-btn flat round dense icon="add" size="sm" @click="addMappingObject" />
|
<div class="col-1"><q-btn flat round dense icon="add" size="sm" @click="addMappingObject" />
|
||||||
</div>
|
</div>
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
<div class="q-my-sm" v-for="(item, index) in mappingProps" :key="item.id">
|
<div class="q-my-sm" v-for="(item, index) in mappingProps" :key="item.id">
|
||||||
<div class="row q-col-gutter-x-xs flex-center">
|
<div class="row q-col-gutter-x-xs flex-center">
|
||||||
<div class="col-5">
|
<div class="col-5">
|
||||||
<ConditionObject v-model="item.from" />
|
<ConditionObject :config="config" v-model="item.from" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col-1">
|
<div class="col-1">
|
||||||
</div>
|
</div>
|
||||||
@@ -99,7 +99,7 @@ type ValueType = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultMappingProp = () => ({ id: uuidv4(), to: { app: {}, fields: [], isDialogVisible: false } });
|
const defaultMappingProp = () => ({ id: uuidv4(), from: {}, to: { app: {}, fields: [], isDialogVisible: false } });
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'DataMapping',
|
name: 'DataMapping',
|
||||||
@@ -159,12 +159,9 @@ export default defineComponent({
|
|||||||
const mappingObjectsInputDisplay = computed(() =>
|
const mappingObjectsInputDisplay = computed(() =>
|
||||||
mappingProps ?
|
mappingProps ?
|
||||||
mappingProps
|
mappingProps
|
||||||
.filter(item => item.from?.name && item.to.fields?.length > 0)
|
.filter(item => item.from?.sharedText && item.to.fields?.length > 0)
|
||||||
.map(item => {
|
.map(item => {
|
||||||
const name = typeof item.from?.name === 'string'
|
return `field(${item.to.app?.id},${item.to.fields[0].label}) = ${item.from.sharedText} `;
|
||||||
? item.from.name
|
|
||||||
: item.from?.name.name;
|
|
||||||
return `[${name}] - (${item.to.app?.name} : ${item.to.fields[0].label})`;
|
|
||||||
})
|
})
|
||||||
: []
|
: []
|
||||||
);
|
);
|
||||||
@@ -194,7 +191,13 @@ export default defineComponent({
|
|||||||
mappingObjectsInputDisplay,
|
mappingObjectsInputDisplay,
|
||||||
sourceApp,
|
sourceApp,
|
||||||
sourceAppId,
|
sourceAppId,
|
||||||
btnDisable
|
btnDisable,
|
||||||
|
config: {
|
||||||
|
canInput: false,
|
||||||
|
buttonsConfig: [
|
||||||
|
{ label: '変数', color: 'green', type: 'VariableAdd' },
|
||||||
|
]
|
||||||
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}));
|
}));
|
||||||
|
provide('sourceApp', computed(() => source.props?.modelValue?.app?.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
const actionName = props.context.find(element => element?.props?.name === 'displayName')
|
const actionName = props.context.find(element => element?.props?.name === 'displayName')
|
||||||
@@ -168,12 +169,7 @@ export default defineComponent({
|
|||||||
processingObjects
|
processingObjects
|
||||||
.filter(item => item.field && item.logicalOperator && item.vName)
|
.filter(item => item.field && item.logicalOperator && item.vName)
|
||||||
.map(item => {
|
.map(item => {
|
||||||
const name = typeof item.field?.name === 'string'
|
return`var(${processingProps.name}.${item.vName}) = ${item.field.sharedText}`
|
||||||
? item.field.name
|
|
||||||
: item.field?.name.name;
|
|
||||||
return item.logicalOperator.operator!==''?
|
|
||||||
`${processingProps.name}.${item.vName} = ${item.logicalOperator.operator}(${name})`
|
|
||||||
:`${processingProps.name}.${item.vName} = ${name}`
|
|
||||||
})
|
})
|
||||||
: []
|
: []
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -201,11 +201,12 @@ export class ConditionTree {
|
|||||||
} else {
|
} else {
|
||||||
const condNode=node as ConditionNode;
|
const condNode=node as ConditionNode;
|
||||||
if (condNode.object && condNode.operator ) {
|
if (condNode.object && condNode.operator ) {
|
||||||
let value=condNode.value;
|
// let value=condNode.value;
|
||||||
if(value && typeof value ==='object' && ('label' in value)){
|
// if(value && typeof value ==='object' && ('label' in value)){
|
||||||
value =condNode.value.label;
|
// value =condNode.value.label;
|
||||||
}
|
// }
|
||||||
return `${typeof condNode.object.name === 'object' ? condNode.object.name.name : condNode.object.name} ${typeof condNode.operator === 'object' ? condNode.operator.label : condNode.operator} '${value}'`;
|
return `${condNode.object.sharedText} ${typeof condNode.operator === 'object' ? condNode.operator.label : condNode.operator} ${condNode.value.sharedText}`;
|
||||||
|
// return `${typeof condNode.object.name === 'object' ? condNode.object.name.name : condNode.object.name} ${typeof condNode.operator === 'object' ? condNode.operator.label : condNode.operator} '${value}'`;
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@@ -237,11 +238,10 @@ export class ConditionTree {
|
|||||||
} else {
|
} else {
|
||||||
const condNode=node as ConditionNode;
|
const condNode=node as ConditionNode;
|
||||||
if (condNode.object && condNode.operator ) {
|
if (condNode.object && condNode.operator ) {
|
||||||
let value=condNode.value;
|
if (!condNode.object.code || !condNode.value.sharedText){
|
||||||
if(value && typeof value ==='object' && ('label' in value)){
|
return '';
|
||||||
value =condNode.value.label;
|
|
||||||
}
|
}
|
||||||
return `${condNode.object.code} ${typeof condNode.operator === 'object' ? condNode.operator.value : condNode.operator} "${value}"`;
|
return `${condNode.object.code} ${typeof condNode.operator === 'object' ? condNode.operator.value : condNode.operator} "${condNode.value.sharedText}"`;
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|||||||
74
plugin/kintone-addins/src/actions/current-field-get.ts
Normal file
74
plugin/kintone-addins/src/actions/current-field-get.ts
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import {
|
||||||
|
IAction,
|
||||||
|
IActionResult,
|
||||||
|
IActionNode,
|
||||||
|
IActionProperty,
|
||||||
|
IContext,
|
||||||
|
} from "../types/ActionTypes";
|
||||||
|
import { actionAddins } from ".";
|
||||||
|
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
displayName: string;
|
||||||
|
field: Field;
|
||||||
|
verName: VerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface VerName {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Field {
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
code: string;
|
||||||
|
label: string;
|
||||||
|
noLabel: boolean;
|
||||||
|
required: boolean;
|
||||||
|
minLength: string;
|
||||||
|
maxLength: string;
|
||||||
|
expression: string;
|
||||||
|
hideExpression: boolean;
|
||||||
|
unique: boolean;
|
||||||
|
defaultValue: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CurrentFieldGetAction implements IAction {
|
||||||
|
name: string;
|
||||||
|
actionProps: IActionProperty[];
|
||||||
|
currentFieldGetProps: Props;
|
||||||
|
constructor() {
|
||||||
|
this.name = "フィールドの値を取得する";
|
||||||
|
this.actionProps = [];
|
||||||
|
this.currentFieldGetProps = {} as Props;
|
||||||
|
this.register();
|
||||||
|
}
|
||||||
|
|
||||||
|
async process(
|
||||||
|
prop: IActionNode,
|
||||||
|
event: any,
|
||||||
|
context: IContext
|
||||||
|
): Promise<IActionResult> {
|
||||||
|
this.currentFieldGetProps = prop.ActionValue as Props;
|
||||||
|
this.actionProps = prop.actionProps;
|
||||||
|
|
||||||
|
let result = {
|
||||||
|
canNext: true,
|
||||||
|
result: "",
|
||||||
|
} as IActionResult;
|
||||||
|
|
||||||
|
try {
|
||||||
|
context.variables[this.currentFieldGetProps.verName.name] = context.record[this.currentFieldGetProps.field.code].value;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("CurrentFieldGetAction error", error);
|
||||||
|
result.canNext = false;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
register(): void {
|
||||||
|
actionAddins[this.name] = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new CurrentFieldGetAction();
|
||||||
@@ -7,41 +7,70 @@ import {
|
|||||||
} from "../types/ActionTypes";
|
} from "../types/ActionTypes";
|
||||||
import { actionAddins } from ".";
|
import { actionAddins } from ".";
|
||||||
|
|
||||||
export type IApp = {
|
interface Props {
|
||||||
id: string;
|
displayName: string;
|
||||||
name: string;
|
sources: Sources;
|
||||||
};
|
dataMapping: DataMapping[];
|
||||||
export type IField = {
|
}
|
||||||
name: string;
|
|
||||||
code: string;
|
|
||||||
type: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type IAppFields = {
|
interface DataMapping {
|
||||||
app?: IApp;
|
|
||||||
fields: IField[];
|
|
||||||
};
|
|
||||||
|
|
||||||
type ValueType = {
|
|
||||||
id: string;
|
id: string;
|
||||||
from: {
|
from: From;
|
||||||
objectType: "variable" | "field";
|
to: To;
|
||||||
name: { name: string };
|
}
|
||||||
code: string;
|
|
||||||
};
|
interface To {
|
||||||
to: IAppFields & {
|
app: App;
|
||||||
|
fields: Field[];
|
||||||
isDialogVisible: boolean;
|
isDialogVisible: boolean;
|
||||||
};
|
}
|
||||||
};
|
|
||||||
|
|
||||||
type Props = { app: IApp; field: ValueType[] };
|
interface Field {
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
code: string;
|
||||||
|
label: string;
|
||||||
|
noLabel: boolean;
|
||||||
|
required: boolean;
|
||||||
|
minLength: string;
|
||||||
|
maxLength: string;
|
||||||
|
expression: string;
|
||||||
|
hideExpression: boolean;
|
||||||
|
unique: boolean;
|
||||||
|
defaultValue: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface From {
|
||||||
|
sharedText: string;
|
||||||
|
_t: string;
|
||||||
|
id: string;
|
||||||
|
objectType: string;
|
||||||
|
name: Name;
|
||||||
|
actionName: string;
|
||||||
|
displayName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Name {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Sources {
|
||||||
|
app: App;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface App {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
createdate: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class DataMappingAction implements IAction {
|
export class DataMappingAction implements IAction {
|
||||||
name: string;
|
name: string;
|
||||||
actionProps: IActionProperty[];
|
actionProps: IActionProperty[];
|
||||||
dataMappingProps: Props;
|
dataMappingProps: Props;
|
||||||
constructor() {
|
constructor() {
|
||||||
this.name = "DataMapping";
|
this.name = "データマッピング";
|
||||||
this.actionProps = [];
|
this.actionProps = [];
|
||||||
this.dataMappingProps = {} as Props;
|
this.dataMappingProps = {} as Props;
|
||||||
this.register();
|
this.register();
|
||||||
@@ -52,14 +81,17 @@ export class DataMappingAction implements IAction {
|
|||||||
event: any,
|
event: any,
|
||||||
context: IContext
|
context: IContext
|
||||||
): Promise<IActionResult> {
|
): Promise<IActionResult> {
|
||||||
this.initActionProps(prop);
|
this.actionProps = prop.actionProps;
|
||||||
this.initTypedActionProps();
|
this.dataMappingProps = prop.ActionValue as Props;
|
||||||
|
console.log(prop.ActionValue);
|
||||||
|
|
||||||
|
// this.initTypedActionProps();
|
||||||
let result = {
|
let result = {
|
||||||
canNext: true,
|
canNext: true,
|
||||||
result: "",
|
result: "",
|
||||||
} as IActionResult;
|
} as IActionResult;
|
||||||
try {
|
try {
|
||||||
for (const item of this.dataMappingProps.field) {
|
for (const item of this.dataMappingProps.dataMapping) {
|
||||||
if (item.from.objectType === "variable") {
|
if (item.from.objectType === "variable") {
|
||||||
if (
|
if (
|
||||||
item.from.name.name &&
|
item.from.name.name &&
|
||||||
@@ -86,32 +118,6 @@ export class DataMappingAction implements IAction {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (item.from.objectType === "field") {
|
|
||||||
if (
|
|
||||||
item.from.code &&
|
|
||||||
item.to.app &&
|
|
||||||
item.to.fields &&
|
|
||||||
item.to.fields.length > 0
|
|
||||||
) {
|
|
||||||
const value = await selectData(
|
|
||||||
item.to.app.id,
|
|
||||||
item.to.fields[0].code
|
|
||||||
);
|
|
||||||
if (value && value.type === context.record[item.from.code].type) {
|
|
||||||
await kintone.api(
|
|
||||||
kintone.api.url("/k/v1/records.json", true),
|
|
||||||
"POST",
|
|
||||||
{
|
|
||||||
app: item.to.app.id,
|
|
||||||
records: value.value.map((v) => ({
|
|
||||||
[item.to.fields[0].code]: {
|
|
||||||
value: v,
|
|
||||||
},
|
|
||||||
})),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -123,19 +129,6 @@ export class DataMappingAction implements IAction {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private initActionProps(nodes: IActionNode) {
|
|
||||||
this.actionProps = nodes.actionProps;
|
|
||||||
}
|
|
||||||
private initTypedActionProps() {
|
|
||||||
for (const action of this.actionProps) {
|
|
||||||
if (action.component === "DataMapping") {
|
|
||||||
this.dataMappingProps.field = action.props.modelValue as ValueType[];
|
|
||||||
} else if (action.component === "AppSelect") {
|
|
||||||
this.dataMappingProps.app = action.props.modelValue.app as IApp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(): void {
|
register(): void {
|
||||||
actionAddins[this.name] = this;
|
actionAddins[this.name] = this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,31 +7,135 @@ import {
|
|||||||
} from "../types/ActionTypes";
|
} from "../types/ActionTypes";
|
||||||
import { actionAddins } from ".";
|
import { actionAddins } from ".";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
displayName: string;
|
||||||
|
sources: Sources;
|
||||||
|
condition: Condition;
|
||||||
|
verName: VerName;
|
||||||
|
}
|
||||||
|
|
||||||
type DataProcessingProps = {
|
interface Condition {
|
||||||
app: {
|
queryString: string;
|
||||||
|
index: number;
|
||||||
|
type: string;
|
||||||
|
children: Child[];
|
||||||
|
parent: null;
|
||||||
|
logicalOperator: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Child {
|
||||||
|
index: number;
|
||||||
|
type: string;
|
||||||
|
parent: string;
|
||||||
|
object: Object;
|
||||||
|
operator: ChildOperator;
|
||||||
|
value: Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Value {
|
||||||
|
sharedText: string;
|
||||||
|
_t: string;
|
||||||
|
objectType: string;
|
||||||
|
actionName: string;
|
||||||
|
displayName: string;
|
||||||
|
name: Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Name {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ChildOperator {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Object {
|
||||||
|
sharedText: string;
|
||||||
|
_t: string;
|
||||||
|
name: string;
|
||||||
|
objectType: string;
|
||||||
|
type: string;
|
||||||
|
code: string;
|
||||||
|
label: string;
|
||||||
|
noLabel: boolean;
|
||||||
|
required: boolean;
|
||||||
|
minLength: string;
|
||||||
|
maxLength: string;
|
||||||
|
expression: string;
|
||||||
|
hideExpression: boolean;
|
||||||
|
unique: boolean;
|
||||||
|
defaultValue: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface VerName {
|
||||||
|
name: string;
|
||||||
|
actionName: string;
|
||||||
|
displayName: string;
|
||||||
|
vars: Var[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Var {
|
||||||
|
id: string;
|
||||||
|
field: Field2;
|
||||||
|
logicalOperator: LogicalOperator;
|
||||||
|
vName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LogicalOperator {
|
||||||
|
operator: string;
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Field2 {
|
||||||
|
sharedText: string;
|
||||||
|
_t: string;
|
||||||
|
name: string;
|
||||||
|
objectType: string;
|
||||||
|
type: string;
|
||||||
|
code: string;
|
||||||
|
label: string;
|
||||||
|
noLabel: boolean;
|
||||||
|
required: boolean;
|
||||||
|
minLength: string;
|
||||||
|
maxLength: string;
|
||||||
|
expression: string;
|
||||||
|
hideExpression: boolean;
|
||||||
|
unique: boolean;
|
||||||
|
defaultValue: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Sources {
|
||||||
|
app: App;
|
||||||
|
fields: Field[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Field {
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
code: string;
|
||||||
|
label: string;
|
||||||
|
noLabel: boolean;
|
||||||
|
required: boolean;
|
||||||
|
minLength: string;
|
||||||
|
maxLength: string;
|
||||||
|
expression: string;
|
||||||
|
hideExpression: boolean;
|
||||||
|
unique: boolean;
|
||||||
|
defaultValue: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface App {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
};
|
description: string;
|
||||||
conditionsQuery: string;
|
createdate: string;
|
||||||
propcessing: {
|
}
|
||||||
varRootName: string;
|
|
||||||
fields: Field[];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
type Field = {
|
|
||||||
name: string;
|
|
||||||
code: string;
|
|
||||||
type: string;
|
|
||||||
varName: string;
|
|
||||||
operator: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export class DataProcessingAction implements IAction {
|
export class DataProcessingAction implements IAction {
|
||||||
name: string;
|
name: string;
|
||||||
actionProps: IActionProperty[];
|
actionProps: IActionProperty[];
|
||||||
dataProcessingProps: DataProcessingProps | null;
|
dataProcessingProps: Props | null;
|
||||||
constructor() {
|
constructor() {
|
||||||
this.name = "データ処理";
|
this.name = "データ処理";
|
||||||
this.actionProps = [];
|
this.actionProps = [];
|
||||||
@@ -40,10 +144,13 @@ export class DataProcessingAction implements IAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async process(
|
async process(
|
||||||
nodes: IActionNode,event: any,context: IContext
|
nodes: IActionNode,
|
||||||
|
event: any,
|
||||||
|
context: IContext
|
||||||
): Promise<IActionResult> {
|
): Promise<IActionResult> {
|
||||||
this.initActionProps(nodes);
|
this.actionProps = nodes.actionProps;
|
||||||
this.initTypedActionProps();
|
this.dataProcessingProps = nodes.ActionValue as Props;
|
||||||
|
|
||||||
let result = {
|
let result = {
|
||||||
canNext: true,
|
canNext: true,
|
||||||
result: "",
|
result: "",
|
||||||
@@ -53,23 +160,23 @@ export class DataProcessingAction implements IAction {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await selectData(this.dataProcessingProps.conditionsQuery);
|
const data = await selectData(varGet(this.dataProcessingProps.condition.queryString,context.variables));
|
||||||
console.log("data ", data);
|
console.log("data ", data);
|
||||||
|
|
||||||
context.variables[this.dataProcessingProps.propcessing.varRootName] =
|
context.variables[this.dataProcessingProps.verName.name] =
|
||||||
this.dataProcessingProps.propcessing.fields.reduce((acc, f) => {
|
this.dataProcessingProps.verName.vars.reduce((acc, f) => {
|
||||||
const v = calc(f, data);
|
const v = calc(f, data);
|
||||||
if (v) {
|
if (v) {
|
||||||
acc[f.varName] = calc(f, data);
|
acc[f.vName] = calc(f, data);
|
||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
}, {} as Var);
|
}, {} as AnyObject);
|
||||||
|
|
||||||
console.log("context ", context);
|
console.log("context ", context);
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
event.error=error;
|
event.error = error;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,50 +184,24 @@ export class DataProcessingAction implements IAction {
|
|||||||
register(): void {
|
register(): void {
|
||||||
actionAddins[this.name] = this;
|
actionAddins[this.name] = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private initActionProps(nodes: IActionNode) {
|
|
||||||
this.actionProps = nodes.actionProps;
|
|
||||||
}
|
|
||||||
|
|
||||||
private initTypedActionProps() {
|
|
||||||
this.dataProcessingProps = {
|
|
||||||
app: {
|
|
||||||
id: "",
|
|
||||||
name: "",
|
|
||||||
},
|
|
||||||
conditionsQuery: "",
|
|
||||||
propcessing: {
|
|
||||||
varRootName: "",
|
|
||||||
fields: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
for (const action of this.actionProps) {
|
|
||||||
if (action.component === "AppFieldSelect") {
|
|
||||||
this.dataProcessingProps.app.id = action.props.modelValue.app.id;
|
|
||||||
this.dataProcessingProps.app.name = action.props.modelValue.app.name;
|
|
||||||
} else if (action.component === "DataProcessing") {
|
|
||||||
this.dataProcessingProps.propcessing.varRootName =
|
|
||||||
action.props.modelValue.name;
|
|
||||||
for (const f of action.props.modelValue.vars) {
|
|
||||||
this.dataProcessingProps.propcessing.fields.push({
|
|
||||||
name: f.field.name,
|
|
||||||
code: f.field.code,
|
|
||||||
type: f.field.type,
|
|
||||||
varName: f.vName,
|
|
||||||
operator: f.logicalOperator.operator,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (action.component === "ConditionInput") {
|
|
||||||
this.dataProcessingProps.conditionsQuery = JSON.parse(
|
|
||||||
action.props.modelValue
|
|
||||||
).queryString;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
new DataProcessingAction();
|
new DataProcessingAction();
|
||||||
|
|
||||||
|
const varGet = (str: string, vars: any) => {
|
||||||
|
const regex = /var\((.*?)\)/g;
|
||||||
|
let match;
|
||||||
|
while ((match = regex.exec(str)) !== null) {
|
||||||
|
const varName = match[1];
|
||||||
|
if (varName in vars) {
|
||||||
|
str = str.replace(match[0], vars[varName]);
|
||||||
|
} else {
|
||||||
|
throw new Error(`変数${varName}が見つかりません`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
};
|
||||||
|
|
||||||
const selectData = async (query?: string) => {
|
const selectData = async (query?: string) => {
|
||||||
return kintone
|
return kintone
|
||||||
.api(kintone.api.url("/k/v1/records", true), "GET", {
|
.api(kintone.api.url("/k/v1/records", true), "GET", {
|
||||||
@@ -157,24 +238,24 @@ type Result = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
type Var = {
|
type AnyObject = {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ERROR_TYPE = "ERROR_TYPE";
|
const ERROR_TYPE = "ERROR_TYPE";
|
||||||
|
|
||||||
const calc = (field: Field, result: Result) => {
|
const calc = (f: Var, result: Result) => {
|
||||||
const type = typeCheck(field.type);
|
const type = typeCheck(f.field.type);
|
||||||
if (!type) {
|
if (!type) {
|
||||||
return ERROR_TYPE;
|
return ERROR_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fun =
|
const fun =
|
||||||
calcFunc[`${type}_${Operator[field.operator as keyof typeof Operator]}`];
|
calcFunc[`${type}_${Operator[f.logicalOperator.operator as keyof typeof Operator]}`];
|
||||||
if (!fun) {
|
if (!fun) {
|
||||||
return ERROR_TYPE;
|
return ERROR_TYPE;
|
||||||
}
|
}
|
||||||
const values = result[field.code].value;
|
const values = result[f.field.code].value;
|
||||||
if (!values) {
|
if (!values) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -208,7 +289,7 @@ enum Operator {
|
|||||||
MAX = "MAX",
|
MAX = "MAX",
|
||||||
MIN = "MIN",
|
MIN = "MIN",
|
||||||
COUNT = "COUNT",
|
COUNT = "COUNT",
|
||||||
FIRST = "FIRST"
|
FIRST = "FIRST",
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CalcType {
|
enum CalcType {
|
||||||
@@ -274,7 +355,7 @@ const calcFunc: Record<string, (value: string[]) => string | null> = {
|
|||||||
? minDateTime
|
? minDateTime
|
||||||
: currentDateTime
|
: currentDateTime
|
||||||
),
|
),
|
||||||
[`${CalcType.STRING}_${Operator.FIRST}`]:(value: string[])=>{
|
[`${CalcType.STRING}_${Operator.FIRST}`]: (value: string[]) => {
|
||||||
return value[0];
|
return value[0];
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import '../actions/button-add';
|
|||||||
import '../actions/condition-action';
|
import '../actions/condition-action';
|
||||||
import '../actions/data-processing';
|
import '../actions/data-processing';
|
||||||
import '../actions/data-mapping';
|
import '../actions/data-mapping';
|
||||||
|
import '../actions/current-field-get';
|
||||||
import { ActionFlow,IActionFlow, IActionResult,IContext } from "./ActionTypes";
|
import { ActionFlow,IActionFlow, IActionResult,IContext } from "./ActionTypes";
|
||||||
|
|
||||||
export class ActionProcess{
|
export class ActionProcess{
|
||||||
|
|||||||
Reference in New Issue
Block a user