フロー保存の実装
This commit is contained in:
Binary file not shown.
@@ -1,11 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div class="row app-box">
|
||||||
class="row"
|
|
||||||
style="
|
|
||||||
border-radius: 2px;
|
|
||||||
box-shadow: rgba(255, 255, 255, 0.1) 0px 0px 0px 1px inset,
|
|
||||||
rgba(0, 0, 0, 0.3) 0px 0px 0px 1px;
|
|
||||||
">
|
|
||||||
<q-icon
|
<q-icon
|
||||||
class="self-center q-ma-sm"
|
class="self-center q-ma-sm"
|
||||||
name="widgets"
|
name="widgets"
|
||||||
@@ -13,7 +7,7 @@
|
|||||||
style="font-size: 2em"
|
style="font-size: 2em"
|
||||||
/>
|
/>
|
||||||
<div class="col-7 self-center ellipsis">
|
<div class="col-7 self-center ellipsis">
|
||||||
{{ selectedApp.name }}
|
{{ store.appInfo?.name }}
|
||||||
</div>
|
</div>
|
||||||
<div class="self-center">
|
<div class="self-center">
|
||||||
<q-btn
|
<q-btn
|
||||||
@@ -51,22 +45,19 @@ export default defineComponent({
|
|||||||
const store = useFlowEditorStore();
|
const store = useFlowEditorStore();
|
||||||
const appDg = ref();
|
const appDg = ref();
|
||||||
const showSelectApp=ref(false);
|
const showSelectApp=ref(false);
|
||||||
const selectedApp =ref<AppInfo>({
|
|
||||||
appId:"",
|
|
||||||
name:"",
|
|
||||||
});
|
|
||||||
const closeDg=(val :any)=>{
|
const closeDg=(val :any)=>{
|
||||||
showSelectApp.value=false;
|
showSelectApp.value=false;
|
||||||
console.log("Dialog closed->",val);
|
console.log("Dialog closed->",val);
|
||||||
if (val == 'OK') {
|
if (val == 'OK') {
|
||||||
const data = appDg.value.selected[0];
|
const data = appDg.value.selected[0];
|
||||||
console.log(data);
|
console.log(data);
|
||||||
selectedApp.value={
|
const appInfo={
|
||||||
appId:data.id ,
|
appId:data.id ,
|
||||||
name:data.name
|
name:data.name
|
||||||
};
|
};
|
||||||
store.setApp(selectedApp.value);
|
store.setApp(appInfo);
|
||||||
store.setFlow();
|
store.loadFlow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const showAppDialog=()=>{
|
const showAppDialog=()=>{
|
||||||
@@ -74,7 +65,6 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
store,
|
store,
|
||||||
selectedApp,
|
|
||||||
showSelectApp,
|
showSelectApp,
|
||||||
showAppDialog,
|
showAppDialog,
|
||||||
closeDg,
|
closeDg,
|
||||||
@@ -83,3 +73,9 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.app-box{
|
||||||
|
border-radius: 2px;
|
||||||
|
box-shadow: rgba(255, 255, 255, 0.1) 0px 0px 0px 1px inset,rgba(0, 0, 0, 0.3) 0px 0px 0px 1px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="q-pa-md q-gutter-sm">
|
<!-- <div class="q-pa-md q-gutter-sm"> -->
|
||||||
<q-tree
|
<q-tree
|
||||||
:nodes="store.eventTree.screens"
|
:nodes="store.eventTree.screens"
|
||||||
node-key="label"
|
node-key="label"
|
||||||
children-key="events"
|
children-key="events"
|
||||||
no-connectors
|
no-connectors
|
||||||
v-model:expanded="expanded"
|
v-model:expanded="store.expandedScreen"
|
||||||
:dense="true"
|
:dense="true"
|
||||||
>
|
>
|
||||||
<template v-slot:default-header="prop">
|
<template v-slot:default-header="prop">
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</q-tree>
|
</q-tree>
|
||||||
</div>
|
<!-- </div> -->
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -36,9 +36,7 @@ export default defineComponent({
|
|||||||
// const eventTree=ref(kintoneEvents);
|
// const eventTree=ref(kintoneEvents);
|
||||||
// const selectedFlow = store.currentFlow;
|
// const selectedFlow = store.currentFlow;
|
||||||
|
|
||||||
const expanded=ref([
|
// const expanded=ref();
|
||||||
store.currentFlow?.getRoot()?.title
|
|
||||||
]);
|
|
||||||
const selectedEvent = ref<IKintoneEvent|null>(null);
|
const selectedEvent = ref<IKintoneEvent|null>(null);
|
||||||
const onSelected=(node:IKintoneEvent)=>{
|
const onSelected=(node:IKintoneEvent)=>{
|
||||||
if(!node.eventId){
|
if(!node.eventId){
|
||||||
@@ -63,7 +61,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
// eventTree,
|
// eventTree,
|
||||||
expanded,
|
// expanded,
|
||||||
onSelected,
|
onSelected,
|
||||||
selectedEvent,
|
selectedEvent,
|
||||||
store
|
store
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
|
|
||||||
<q-input v-model="selectedDate" :label="placeholder" mask="date" :rules="['date']">
|
<q-input v-model="selectedDate" :label="displayName" :placeholder="placeholder" mask="date" :rules="['date']">
|
||||||
<template v-slot:append>
|
<template v-slot:append>
|
||||||
<q-icon name="event" class="cursor-pointer">
|
<q-icon name="event" class="cursor-pointer">
|
||||||
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
||||||
@@ -21,6 +21,10 @@ import { defineComponent, ref ,watchEffect} from 'vue';
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'DatePicker',
|
name: 'DatePicker',
|
||||||
props: {
|
props: {
|
||||||
|
displayName:{
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
placeholder: {
|
placeholder: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<q-input v-model="selectedField" :label="placeholder">
|
<q-input v-model="selectedField" :label="displayName" :placeholder="placeholder" >
|
||||||
<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-input>
|
</q-input>
|
||||||
<show-dialog v-model:visible="show" name="フィールド一覧" @close="closeDg">
|
<show-dialog v-model:visible="show" name="フィールド一覧" @close="closeDg">
|
||||||
<field-select ref="appDg" name="フィールド" type="single" :appId="store.appInfo?.appId"></field-select>
|
<field-select ref="appDg" name="フィールド" type="single" :appId="store.appInfo?.appId"></field-select>
|
||||||
@@ -21,6 +21,10 @@ export default defineComponent({
|
|||||||
FieldSelect,
|
FieldSelect,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
displayName:{
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
placeholder: {
|
placeholder: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<q-input :label="placeholder" v-model="inputValue"/>
|
<q-input :label="displayName" :placeholder="placeholder" v-model="inputValue"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -8,6 +8,10 @@ import { defineComponent,ref,watchEffect } from 'vue';
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'InputText',
|
name: 'InputText',
|
||||||
props: {
|
props: {
|
||||||
|
displayName:{
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
placeholder: {
|
placeholder: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<q-select v-model="selectedValue" :label="placeholder" :options="options"/>
|
<q-select v-model="selectedValue" :label="displayName" :options="options"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -8,6 +8,10 @@ import { defineComponent,ref,watchEffect } from 'vue';
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SelectBox',
|
name: 'SelectBox',
|
||||||
props: {
|
props: {
|
||||||
|
displayName:{
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
placeholder: {
|
placeholder: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
|
|||||||
@@ -6,16 +6,22 @@ export class FlowCtrl
|
|||||||
|
|
||||||
async getFlows(appId:string):Promise<ActionFlow[]>
|
async getFlows(appId:string):Promise<ActionFlow[]>
|
||||||
{
|
{
|
||||||
|
const flows:ActionFlow[]=[];
|
||||||
|
try{
|
||||||
const result = await api.get(`http://127.0.0.1:8000/api/flows/${appId}`);
|
const result = await api.get(`http://127.0.0.1:8000/api/flows/${appId}`);
|
||||||
//console.info(result.data);
|
//console.info(result.data);
|
||||||
if(!result.data || !Array.isArray(result.data)){
|
if(!result.data || !Array.isArray(result.data)){
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const flows:ActionFlow[]=[];
|
|
||||||
for(const flow of result.data){
|
for(const flow of result.data){
|
||||||
flows.push(ActionFlow.fromJSON(flow.content));
|
flows.push(ActionFlow.fromJSON(flow.content));
|
||||||
}
|
}
|
||||||
return flows;
|
return flows;
|
||||||
|
}catch(error){
|
||||||
|
console.error(error);
|
||||||
|
return flows;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async SaveFlow(jsonData:any):Promise<boolean>
|
async SaveFlow(jsonData:any):Promise<boolean>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="q-pa-md q-gutter-sm event-tree">
|
<div class="q-pa-md q-gutter-sm event-tree ">
|
||||||
<q-drawer
|
<q-drawer
|
||||||
side="left"
|
side="left"
|
||||||
overlay
|
overlay
|
||||||
@@ -8,21 +8,23 @@
|
|||||||
:show-if-above="false"
|
:show-if-above="false"
|
||||||
elevated
|
elevated
|
||||||
>
|
>
|
||||||
<!-- <q-card class="column full-height" style="width: 300px">
|
<q-card class="column full-height" >
|
||||||
<q-card-section> -->
|
<q-card-section>
|
||||||
|
<div class="flex-center " >
|
||||||
<div class="flex-center fixd-top" >
|
|
||||||
<AppSelector />
|
<AppSelector />
|
||||||
</div>
|
</div>
|
||||||
|
<!-- </q-card-section>
|
||||||
<!-- </q-card-section> -->
|
<q-card-section> -->
|
||||||
<q-separator />
|
|
||||||
<!-- <q-card-section> -->
|
|
||||||
<div class="flex-center">
|
<div class="flex-center">
|
||||||
<EventTree />
|
<EventTree />
|
||||||
</div>
|
</div>
|
||||||
<!-- </q-card-section> -->
|
</q-card-section>
|
||||||
<!-- </q-card> -->
|
</q-card>
|
||||||
|
<div class="flex-center fixed-bottom bg-grey-3 q-pa-md row ">
|
||||||
|
<q-btn color="deep-orange" glossy label="デプロイ" @click="onDeploy" icon="sync"/>
|
||||||
|
<q-space></q-space>
|
||||||
|
<q-btn color="primary" label="保存" @click="onSaveFlow" icon="save" />
|
||||||
|
</div>
|
||||||
</q-drawer>
|
</q-drawer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -59,8 +61,9 @@ import PropertyPanel from 'components/right/PropertyPanel.vue';
|
|||||||
import AppSelector from 'components/left/AppSelector.vue';
|
import AppSelector from 'components/left/AppSelector.vue';
|
||||||
import EventTree from 'components/left/EventTree.vue';
|
import EventTree from 'components/left/EventTree.vue';
|
||||||
import {FlowCtrl } from '../control/flowctrl';
|
import {FlowCtrl } from '../control/flowctrl';
|
||||||
|
import { useQuasar } from 'quasar';
|
||||||
const drawerLeft = ref(true);
|
const drawerLeft = ref(true);
|
||||||
|
const $q=useQuasar();
|
||||||
const store = useFlowEditorStore();
|
const store = useFlowEditorStore();
|
||||||
// ref関数を使ってtemplateとバインド
|
// ref関数を使ってtemplateとバインド
|
||||||
const state=reactive({
|
const state=reactive({
|
||||||
@@ -73,7 +76,7 @@ const prevNodeIfo=ref({
|
|||||||
prevNode:{} as IActionNode,
|
prevNode:{} as IActionNode,
|
||||||
inputPoint:""
|
inputPoint:""
|
||||||
});
|
});
|
||||||
const refFlow = ref<ActionFlow|null>(null);
|
// const refFlow = ref<ActionFlow|null>(null);
|
||||||
const showAddAction=ref(false);
|
const showAddAction=ref(false);
|
||||||
const drawerRight=ref(false);
|
const drawerRight=ref(false);
|
||||||
const model=ref("");
|
const model=ref("");
|
||||||
@@ -120,7 +123,38 @@ const closeDg=(val :any)=>{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchData= async ()=>{
|
const onDeploy=()=>{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSaveFlow = async ()=>{
|
||||||
|
const targetFlow = store.selectedFlow;
|
||||||
|
if(targetFlow===undefined){
|
||||||
|
$q.notify({
|
||||||
|
type: 'negative',
|
||||||
|
caption:"エラー",
|
||||||
|
message: `編集中のフローがありません。`
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
await store.saveFlow(targetFlow);
|
||||||
|
$q.notify({
|
||||||
|
type: 'positive',
|
||||||
|
caption:"通知",
|
||||||
|
message: `${targetFlow.getRoot()?.subTitle}のフロー設定を保存しました。`
|
||||||
|
});
|
||||||
|
}catch(error){
|
||||||
|
$q.notify({
|
||||||
|
type: 'negative',
|
||||||
|
caption:"エラー",
|
||||||
|
message: `${targetFlow.getRoot()?.subTitle}のフローの設定の保存が失敗しました。`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchData = async ()=>{
|
||||||
const flowCtrl = new FlowCtrl();
|
const flowCtrl = new FlowCtrl();
|
||||||
if(store.appInfo===undefined) return;
|
if(store.appInfo===undefined) return;
|
||||||
const actionFlows = await flowCtrl.getFlows(store.appInfo?.appId);
|
const actionFlows = await flowCtrl.getFlows(store.appInfo?.appId);
|
||||||
@@ -130,8 +164,7 @@ const fetchData= async ()=>{
|
|||||||
if(actionFlows && actionFlows.length==1){
|
if(actionFlows && actionFlows.length==1){
|
||||||
store.selectFlow(actionFlows[0]);
|
store.selectFlow(actionFlows[0]);
|
||||||
}
|
}
|
||||||
refFlow.value=actionFlows[0];
|
const root =actionFlows[0].getRoot();
|
||||||
const root =refFlow.value.getRoot();
|
|
||||||
if(root){
|
if(root){
|
||||||
state.activeNode=root;
|
state.activeNode=root;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export interface FlowEditorState{
|
|||||||
selectedFlow?:IActionFlow|undefined;
|
selectedFlow?:IActionFlow|undefined;
|
||||||
eventTree:KintoneEventManager;
|
eventTree:KintoneEventManager;
|
||||||
selectedEvent:IKintoneEvent|undefined;
|
selectedEvent:IKintoneEvent|undefined;
|
||||||
|
expandedScreen:any[];
|
||||||
}
|
}
|
||||||
const flowCtrl=new FlowCtrl();
|
const flowCtrl=new FlowCtrl();
|
||||||
export const useFlowEditorStore = defineStore("flowEditor",{
|
export const useFlowEditorStore = defineStore("flowEditor",{
|
||||||
@@ -19,7 +20,8 @@ export const useFlowEditorStore = defineStore("flowEditor",{
|
|||||||
flows:[],
|
flows:[],
|
||||||
selectedFlow:undefined,
|
selectedFlow:undefined,
|
||||||
eventTree:kintoneEvents,
|
eventTree:kintoneEvents,
|
||||||
selectedEvent:undefined
|
selectedEvent:undefined,
|
||||||
|
expandedScreen:[]
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
/**
|
/**
|
||||||
@@ -54,17 +56,46 @@ export const useFlowEditorStore = defineStore("flowEditor",{
|
|||||||
setApp(app:AppInfo){
|
setApp(app:AppInfo){
|
||||||
this.appInfo=app;
|
this.appInfo=app;
|
||||||
},
|
},
|
||||||
async setFlow(){
|
/**
|
||||||
|
* DBからフルーを保存する
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async loadFlow(){
|
||||||
if(this.appInfo===undefined) return;
|
if(this.appInfo===undefined) return;
|
||||||
const actionFlows = await flowCtrl.getFlows(this.appInfo?.appId);
|
const actionFlows = await flowCtrl.getFlows(this.appInfo?.appId);
|
||||||
//eventTreeにバンドする
|
//eventTreeにバンドする
|
||||||
this.eventTree.bindFlows(actionFlows);
|
this.eventTree.bindFlows(actionFlows);
|
||||||
if(actionFlows && actionFlows.length>0){
|
if(actionFlows===undefined || actionFlows.length===0){
|
||||||
this.setFlows(actionFlows);
|
this.flows=[];
|
||||||
|
this.selectedFlow=undefined;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if(actionFlows && actionFlows.length==1){
|
this.setFlows(actionFlows);
|
||||||
|
if(actionFlows && actionFlows.length>0){
|
||||||
this.selectFlow(actionFlows[0]);
|
this.selectFlow(actionFlows[0]);
|
||||||
}
|
}
|
||||||
|
const expandName =actionFlows[0].getRoot()?.title;
|
||||||
|
this.expandedScreen=[expandName];
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* フローをDBに保存及び更新する
|
||||||
|
*/
|
||||||
|
async saveFlow(flow:IActionFlow){
|
||||||
|
const root=flow.getRoot();
|
||||||
|
const isNew = flow.id==='';
|
||||||
|
const jsonData={
|
||||||
|
flowid: isNew ? flow.createNewId():flow.id,
|
||||||
|
appid: this.appInfo?.appId,
|
||||||
|
eventid: root?.name,
|
||||||
|
name: root?.subTitle,
|
||||||
|
content: JSON.stringify(flow)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isNew){
|
||||||
|
return await flowCtrl.SaveFlow(jsonData);
|
||||||
|
}else{
|
||||||
|
return await flowCtrl.UpdateFlow(jsonData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
* アプリ情報
|
* アプリ情報
|
||||||
*/
|
*/
|
||||||
export interface AppInfo {
|
export interface AppInfo {
|
||||||
appId:string;
|
appId: string;
|
||||||
code?:string;
|
code?: string;
|
||||||
name:string;
|
name: string;
|
||||||
description?:string;
|
description?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -18,7 +18,7 @@ export interface IActionProperty {
|
|||||||
//プロパティ名
|
//プロパティ名
|
||||||
name: string;
|
name: string;
|
||||||
//プロパティ表示名
|
//プロパティ表示名
|
||||||
displayName:string;
|
displayName: string;
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
//プロパティ設定値
|
//プロパティ設定値
|
||||||
modelValue: any;
|
modelValue: any;
|
||||||
@@ -27,21 +27,21 @@ export interface IActionProperty {
|
|||||||
/**
|
/**
|
||||||
* アクションタイプ定義
|
* アクションタイプ定義
|
||||||
*/
|
*/
|
||||||
export interface IActionNode{
|
export interface IActionNode {
|
||||||
id:string;
|
id: string;
|
||||||
//アクション名
|
//アクション名
|
||||||
name:string;
|
name: string;
|
||||||
title:string;
|
title: string;
|
||||||
subTitle:string;
|
subTitle: string;
|
||||||
inputPoint:string;
|
inputPoint: string;
|
||||||
//出力ポイント(条件分岐以外未使用)
|
//出力ポイント(条件分岐以外未使用)
|
||||||
outputPoints:Array<string>;
|
outputPoints: Array<string>;
|
||||||
//ルートアクション(Kintone event)
|
//ルートアクション(Kintone event)
|
||||||
isRoot:boolean;
|
isRoot: boolean;
|
||||||
//アクションのプロパティ定義
|
//アクションのプロパティ定義
|
||||||
actionProps:Array<IActionProperty>;
|
actionProps: Array<IActionProperty>;
|
||||||
//アクションのプロパティ設定値抽出
|
//アクションのプロパティ設定値抽出
|
||||||
ActionValue:object
|
ActionValue: object
|
||||||
prevNodeId?: string;
|
prevNodeId?: string;
|
||||||
nextNodeIds: Map<string, string>;
|
nextNodeIds: Map<string, string>;
|
||||||
}
|
}
|
||||||
@@ -49,9 +49,10 @@ export interface IActionNode{
|
|||||||
* アクションフローの定義
|
* アクションフローの定義
|
||||||
*/
|
*/
|
||||||
export interface IActionFlow {
|
export interface IActionFlow {
|
||||||
id:string;
|
id: string;
|
||||||
actionNodes:Array<IActionNode>;
|
actionNodes: Array<IActionNode>;
|
||||||
getRoot():IActionNode|undefined;
|
getRoot(): IActionNode | undefined;
|
||||||
|
createNewId():string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,8 +70,8 @@ class ActionProperty implements IActionProperty {
|
|||||||
modelValue: any;
|
modelValue: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProperty():IActionProperty{
|
static defaultProperty(): IActionProperty {
|
||||||
return new ActionProperty('InputText','displayName','表示名','表示を入力してください','');
|
return new ActionProperty('InputText', 'displayName', '表示名', '表示を入力してください', '');
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -95,23 +96,26 @@ class ActionProperty implements IActionProperty {
|
|||||||
* IActionNodeの実装、RootActionNode以外のアクション定義
|
* IActionNodeの実装、RootActionNode以外のアクション定義
|
||||||
*/
|
*/
|
||||||
export class ActionNode implements IActionNode {
|
export class ActionNode implements IActionNode {
|
||||||
id:string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
title:string;
|
get title(): string {
|
||||||
get subTitle():string{
|
const prop = this.actionProps.find((prop) => prop.props.name === "displayName");
|
||||||
|
return prop?.props.modelValue;
|
||||||
|
};
|
||||||
|
get subTitle(): string {
|
||||||
return this.name;
|
return this.name;
|
||||||
};
|
};
|
||||||
inputPoint:string;
|
inputPoint: string;
|
||||||
//出力ポイント(条件分岐以外未使用)
|
//出力ポイント(条件分岐以外未使用)
|
||||||
outputPoints:Array<string>;
|
outputPoints: Array<string>;
|
||||||
actionProps: Array<IActionProperty>;
|
actionProps: Array<IActionProperty>;
|
||||||
get isRoot(): boolean{
|
get isRoot(): boolean {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
get ActionValue():object{
|
get ActionValue(): object {
|
||||||
const propValue:any={};
|
const propValue: any = {};
|
||||||
this.actionProps.forEach((value)=>{
|
this.actionProps.forEach((value) => {
|
||||||
propValue[value.props.name]=value.props.modelValue
|
propValue[value.props.name] = value.props.modelValue
|
||||||
});
|
});
|
||||||
return propValue;
|
return propValue;
|
||||||
};
|
};
|
||||||
@@ -119,24 +123,23 @@ export class ActionNode implements IActionNode {
|
|||||||
nextNodeIds: Map<string, string>;
|
nextNodeIds: Map<string, string>;
|
||||||
constructor(
|
constructor(
|
||||||
name: string,
|
name: string,
|
||||||
title:string,
|
title: string,
|
||||||
inputPoint:string,
|
inputPoint: string,
|
||||||
outputPoint: Array<string> = [],
|
outputPoint: Array<string> = [],
|
||||||
actionProps: Array<IActionProperty> =[ActionProperty.defaultProperty()],
|
actionProps: Array<IActionProperty> = [ActionProperty.defaultProperty()],
|
||||||
) {
|
) {
|
||||||
this.id=uuidv4();
|
this.id = uuidv4();
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.title=title;
|
this.inputPoint = inputPoint;
|
||||||
this.inputPoint=inputPoint;
|
|
||||||
this.outputPoints = outputPoint;
|
this.outputPoints = outputPoint;
|
||||||
const defProp =ActionProperty.defaultProperty();
|
const defProp = ActionProperty.defaultProperty();
|
||||||
defProp.props.displayName=title;
|
defProp.props.modelValue = title;
|
||||||
this.actionProps =actionProps;
|
this.actionProps = actionProps;
|
||||||
const prop = this.actionProps.find((prop)=>prop.props.name===defProp.props.name);
|
const prop = this.actionProps.find((prop) => prop.props.name === defProp.props.name);
|
||||||
if(prop===undefined){
|
if (prop === undefined) {
|
||||||
this.actionProps.unshift(defProp);
|
this.actionProps.unshift(defProp);
|
||||||
}
|
}
|
||||||
this.nextNodeIds=new Map<string,string>();
|
this.nextNodeIds = new Map<string, string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -144,33 +147,33 @@ export class ActionNode implements IActionNode {
|
|||||||
* ルートアクション定義
|
* ルートアクション定義
|
||||||
*/
|
*/
|
||||||
export class RootAction implements IActionNode {
|
export class RootAction implements IActionNode {
|
||||||
id:string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
title:string;
|
title: string;
|
||||||
subTitle:string;
|
subTitle: string;
|
||||||
inputPoint:string;
|
inputPoint: string;
|
||||||
//出力ポイント(条件分岐以外未使用)
|
//出力ポイント(条件分岐以外未使用)
|
||||||
outputPoints:Array<string>;
|
outputPoints: Array<string>;
|
||||||
isRoot: boolean;
|
isRoot: boolean;
|
||||||
actionProps: Array<IActionProperty>;
|
actionProps: Array<IActionProperty>;
|
||||||
ActionValue:object;
|
ActionValue: object;
|
||||||
prevNodeId?: string = undefined;
|
prevNodeId?: string = undefined;
|
||||||
nextNodeIds: Map<string, string>;
|
nextNodeIds: Map<string, string>;
|
||||||
constructor(
|
constructor(
|
||||||
name: string,
|
name: string,
|
||||||
title:string,
|
title: string,
|
||||||
subTitle:string,
|
subTitle: string,
|
||||||
) {
|
) {
|
||||||
this.id=uuidv4();
|
this.id = uuidv4();
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.title=title;
|
this.title = title;
|
||||||
this.subTitle=subTitle;
|
this.subTitle = subTitle;
|
||||||
this.inputPoint='';
|
this.inputPoint = '';
|
||||||
this.outputPoints = [];
|
this.outputPoints = [];
|
||||||
this.isRoot = true;
|
this.isRoot = true;
|
||||||
this.actionProps=[];
|
this.actionProps = [];
|
||||||
this.ActionValue={};
|
this.ActionValue = {};
|
||||||
this.nextNodeIds=new Map<string,string>();
|
this.nextNodeIds = new Map<string, string>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,15 +181,16 @@ export class RootAction implements IActionNode {
|
|||||||
* アクションフローの定義
|
* アクションフローの定義
|
||||||
*/
|
*/
|
||||||
export class ActionFlow implements IActionFlow {
|
export class ActionFlow implements IActionFlow {
|
||||||
id:string;
|
id: string;
|
||||||
actionNodes:Array<IActionNode>;
|
actionNodes: Array<IActionNode>;
|
||||||
constructor(actionNodes:Array<IActionNode>|RootAction){
|
constructor(actionNodes: Array<IActionNode> | RootAction) {
|
||||||
if(actionNodes instanceof Array){
|
if (actionNodes instanceof Array) {
|
||||||
this.actionNodes=actionNodes;
|
this.actionNodes = actionNodes;
|
||||||
}else{
|
} else {
|
||||||
this.actionNodes=[actionNodes];
|
this.actionNodes = [actionNodes];
|
||||||
}
|
}
|
||||||
this.id=uuidv4();
|
this.id = '';
|
||||||
|
//this.id = uuidv4();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* ノードを追加する
|
* ノードを追加する
|
||||||
@@ -198,23 +202,22 @@ export class ActionFlow implements IActionFlow {
|
|||||||
* @returns 追加されたノード
|
* @returns 追加されたノード
|
||||||
*/
|
*/
|
||||||
addNode(
|
addNode(
|
||||||
newNode:IActionNode,
|
newNode: IActionNode,
|
||||||
prevNode?:IActionNode,
|
prevNode?: IActionNode,
|
||||||
inputPoint?:string):IActionNode
|
inputPoint?: string): IActionNode {
|
||||||
{
|
if (inputPoint !== undefined) {
|
||||||
if(inputPoint!==undefined){
|
newNode.inputPoint = inputPoint;
|
||||||
newNode.inputPoint=inputPoint;
|
|
||||||
}
|
}
|
||||||
if(prevNode!==undefined){
|
if (prevNode !== undefined) {
|
||||||
this.connectNodes(prevNode,newNode,inputPoint||'');
|
this.connectNodes(prevNode, newNode, inputPoint || '');
|
||||||
}else{
|
} else {
|
||||||
prevNode=this.actionNodes[this.actionNodes.length-1];
|
prevNode = this.actionNodes[this.actionNodes.length - 1];
|
||||||
this.connectNodes(prevNode,newNode,inputPoint||'');
|
this.connectNodes(prevNode, newNode, inputPoint || '');
|
||||||
}
|
}
|
||||||
const index=this.actionNodes.findIndex(node=>node.id===prevNode?.id)
|
const index = this.actionNodes.findIndex(node => node.id === prevNode?.id)
|
||||||
if(index>=0){
|
if (index >= 0) {
|
||||||
this.actionNodes.splice(index+1,0,newNode);
|
this.actionNodes.splice(index + 1, 0, newNode);
|
||||||
}else{
|
} else {
|
||||||
this.actionNodes.push(newNode);
|
this.actionNodes.push(newNode);
|
||||||
}
|
}
|
||||||
return newNode;
|
return newNode;
|
||||||
@@ -223,40 +226,40 @@ export class ActionFlow implements IActionFlow {
|
|||||||
* ノードを削除する
|
* ノードを削除する
|
||||||
* @param delNode
|
* @param delNode
|
||||||
*/
|
*/
|
||||||
removeNode(targetNode :IActionNode):boolean{
|
removeNode(targetNode: IActionNode): boolean {
|
||||||
if (!targetNode ) {
|
if (!targetNode) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(targetNode.isRoot){
|
if (targetNode.isRoot) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this.disconnectFromPrevNode(targetNode);
|
this.disconnectFromPrevNode(targetNode);
|
||||||
this.reconnectOrRemoveNextNodes(targetNode);
|
this.reconnectOrRemoveNextNodes(targetNode);
|
||||||
this.removeFromActionNodes(targetNode.id);
|
this.removeFromActionNodes(targetNode.id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/***
|
/***
|
||||||
* 目標ノードの次のノードを全部削除する
|
* 目標ノードの次のノードを全部削除する
|
||||||
*/
|
*/
|
||||||
removeAllNext(targetNodeId :string){
|
removeAllNext(targetNodeId: string) {
|
||||||
if (!targetNodeId || targetNodeId==='') {
|
if (!targetNodeId || targetNodeId === '') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const targetNode=this.findNodeById(targetNodeId);
|
const targetNode = this.findNodeById(targetNodeId);
|
||||||
if(!targetNode){
|
if (!targetNode) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(targetNode.nextNodeIds.size==0){
|
if (targetNode.nextNodeIds.size == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (const [, id] of targetNode.nextNodeIds) {
|
for (const [, id] of targetNode.nextNodeIds) {
|
||||||
this.removeAllNext(id);
|
this.removeAllNext(id);
|
||||||
this.removeFromActionNodes(id);
|
this.removeFromActionNodes(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 断开与前一个节点的连接
|
// 断开与前一个节点的连接
|
||||||
disconnectFromPrevNode(targetNode: IActionNode): void {
|
disconnectFromPrevNode(targetNode: IActionNode): void {
|
||||||
const prevNodeId = targetNode.prevNodeId;
|
const prevNodeId = targetNode.prevNodeId;
|
||||||
if (prevNodeId) {
|
if (prevNodeId) {
|
||||||
const prevNode = this.findNodeById(prevNodeId);
|
const prevNode = this.findNodeById(prevNodeId);
|
||||||
@@ -268,79 +271,83 @@ disconnectFromPrevNode(targetNode: IActionNode): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从 actionNodes 数组中移除节点
|
// actionNodes からノードを削除する
|
||||||
private removeFromActionNodes(targetNodeId: string): void {
|
private removeFromActionNodes(targetNodeId: string): void {
|
||||||
const index = this.actionNodes.findIndex(node => node.id === targetNodeId);
|
const index = this.actionNodes.findIndex(node => node.id === targetNodeId);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
this.actionNodes.splice(index, 1);
|
this.actionNodes.splice(index, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ノード削除時、前のノードと次のノードを接続する
|
* ノード削除時、前のノードと次のノードを接続する
|
||||||
* @param targetNode
|
* @param targetNode
|
||||||
*/
|
*/
|
||||||
reconnectOrRemoveNextNodes(targetNode: IActionNode): void {
|
reconnectOrRemoveNextNodes(targetNode: IActionNode): void {
|
||||||
if(!targetNode || !targetNode.prevNodeId ){
|
if (!targetNode || !targetNode.prevNodeId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//前のノードを取得
|
//前のノードを取得
|
||||||
const prevNode = this.findNodeById(targetNode.prevNodeId);
|
const prevNode = this.findNodeById(targetNode.prevNodeId);
|
||||||
if(!prevNode) return;
|
if (!prevNode) return;
|
||||||
//次のノード取得
|
//次のノード取得
|
||||||
const nextNodeIds = targetNode.nextNodeIds;
|
const nextNodeIds = targetNode.nextNodeIds;
|
||||||
if(nextNodeIds.size==0){
|
if (nextNodeIds.size == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//次のノード一つの場合
|
//次のノード一つの場合
|
||||||
if(nextNodeIds.size==1){
|
if (nextNodeIds.size == 1) {
|
||||||
const nextNodeId = nextNodeIds.get('');
|
const nextNodeId = nextNodeIds.get('');
|
||||||
if(!nextNodeId) return;
|
if (!nextNodeId) return;
|
||||||
const nextNode = this.findNodeById(nextNodeId) ;
|
const nextNode = this.findNodeById(nextNodeId);
|
||||||
if(!nextNode) return;
|
if (!nextNode) return;
|
||||||
nextNode.prevNodeId=prevNode.id;
|
nextNode.prevNodeId = prevNode.id;
|
||||||
prevNode.nextNodeIds.set(targetNode.inputPoint||'',nextNodeId);
|
prevNode.nextNodeIds.set(targetNode.inputPoint || '', nextNodeId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//二つ以上の場合
|
//二つ以上の場合
|
||||||
for(const [point,nextid] of nextNodeIds){
|
for (const [point, nextid] of nextNodeIds) {
|
||||||
const nextNode = this.findNodeById(nextid);
|
const nextNode = this.findNodeById(nextid);
|
||||||
if(!nextNode) return;
|
if (!nextNode) return;
|
||||||
if(!this.connectNodes(prevNode,nextNode,point)){
|
if (!this.connectNodes(prevNode, nextNode, point)) {
|
||||||
this.removeAllNext(nextid);
|
this.removeAllNext(nextid);
|
||||||
this.removeFromActionNodes(nextid);
|
this.removeFromActionNodes(nextid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 二つノードを接続する
|
* 二つノードを接続する
|
||||||
* @param prevNode
|
* @param prevNode
|
||||||
* @param nextNodeId
|
* @param nextNodeId
|
||||||
* @param point
|
* @param point
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
connectNodes(prevNode:IActionNode,nextNode:IActionNode,point:string):boolean{
|
connectNodes(prevNode: IActionNode, nextNode: IActionNode, point: string): boolean {
|
||||||
if(!prevNode || !nextNode){
|
if (!prevNode || !nextNode) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(!nextNode) return false;
|
if (!nextNode) return false;
|
||||||
prevNode.nextNodeIds.set(point,nextNode.id);
|
prevNode.nextNodeIds.set(point, nextNode.id);
|
||||||
nextNode.prevNodeId=prevNode.id;
|
nextNode.prevNodeId = prevNode.id;
|
||||||
nextNode.inputPoint=point;
|
nextNode.inputPoint = point;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param prevNode ノードの接続をリセットする
|
||||||
|
* @param newNode
|
||||||
|
* @param inputPoint
|
||||||
|
*/
|
||||||
resetNodeRelation(prevNode: IActionNode, newNode: IActionNode, inputPoint?: string) {
|
resetNodeRelation(prevNode: IActionNode, newNode: IActionNode, inputPoint?: string) {
|
||||||
// 设置新节点和前节点的关联
|
//
|
||||||
prevNode.nextNodeIds.set(inputPoint || '', newNode.id);
|
prevNode.nextNodeIds.set(inputPoint || '', newNode.id);
|
||||||
newNode.prevNodeId = prevNode.id;
|
newNode.prevNodeId = prevNode.id;
|
||||||
// 保存前节点原有的后节点ID
|
|
||||||
const originalNextNodeId = prevNode.nextNodeIds.get(inputPoint || '');
|
const originalNextNodeId = prevNode.nextNodeIds.get(inputPoint || '');
|
||||||
this.setNewNodeNextId(newNode,originalNextNodeId,inputPoint);
|
this.setNewNodeNextId(newNode, originalNextNodeId, inputPoint);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -350,13 +357,13 @@ reconnectOrRemoveNextNodes(targetNode: IActionNode): void {
|
|||||||
* @param inputPoint
|
* @param inputPoint
|
||||||
*/
|
*/
|
||||||
private setNewNodeNextId(newNode: IActionNode, originalNextNodeId: string | undefined, inputPoint?: string) {
|
private setNewNodeNextId(newNode: IActionNode, originalNextNodeId: string | undefined, inputPoint?: string) {
|
||||||
// 如果原先的后节点存在
|
// 元の接続ノードが存在する
|
||||||
if (originalNextNodeId) {
|
if (originalNextNodeId) {
|
||||||
// 检查新节点的 outputPoints 是否包含该 inputPoint
|
// 新しいノードの outputPoints に該当 inputPointが存在するか場合をチェックする
|
||||||
if (newNode.outputPoints.includes(inputPoint || '')) {
|
if (newNode.outputPoints.includes(inputPoint || '')) {
|
||||||
newNode.nextNodeIds.set(inputPoint || '', originalNextNodeId);
|
newNode.nextNodeIds.set(inputPoint || '', originalNextNodeId);
|
||||||
} else {
|
} else {
|
||||||
// 如果不包含,选择新节点的一个 outputPoint
|
// inputPointが存在しない場合、outputPointのポイントの任意ポートを選択する
|
||||||
const alternativeOutputPoint = newNode.outputPoints.length > 0 ? newNode.outputPoints[0] : '';
|
const alternativeOutputPoint = newNode.outputPoints.length > 0 ? newNode.outputPoints[0] : '';
|
||||||
newNode.nextNodeIds.set(alternativeOutputPoint, originalNextNodeId);
|
newNode.nextNodeIds.set(alternativeOutputPoint, originalNextNodeId);
|
||||||
}
|
}
|
||||||
@@ -372,7 +379,7 @@ reconnectOrRemoveNextNodes(targetNode: IActionNode): void {
|
|||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
return {
|
return {
|
||||||
id:this.id,
|
id: this.id,
|
||||||
actionNodes: this.actionNodes.map(node => {
|
actionNodes: this.actionNodes.map(node => {
|
||||||
const { nextNodeIds, ...rest } = node;
|
const { nextNodeIds, ...rest } = node;
|
||||||
return {
|
return {
|
||||||
@@ -383,26 +390,29 @@ reconnectOrRemoveNextNodes(targetNode: IActionNode): void {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getRoot():IActionNode|undefined{
|
getRoot(): IActionNode | undefined {
|
||||||
return this.actionNodes.find(node=>node.isRoot)
|
return this.actionNodes.find(node => node.isRoot)
|
||||||
|
}
|
||||||
|
|
||||||
|
createNewId():string{
|
||||||
|
this.id=uuidv4();
|
||||||
|
return this.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJSON(json: string): ActionFlow {
|
static fromJSON(json: string): ActionFlow {
|
||||||
const parsedObject = JSON.parse(json);
|
const parsedObject = JSON.parse(json);
|
||||||
|
|
||||||
const actionNodes = parsedObject.actionNodes.map((node: any) => {
|
const actionNodes = parsedObject.actionNodes.map((node: any) => {
|
||||||
const nodeClass = !node.isRoot? new ActionNode(node.name,node.title,node.inputPoint,node.outputPoint,node.actionProps)
|
const nodeClass = !node.isRoot ? new ActionNode(node.name, node.title, node.inputPoint, node.outputPoint, node.actionProps)
|
||||||
:new RootAction(node.name,node.title,node.subTitle);
|
: new RootAction(node.name, node.title, node.subTitle);
|
||||||
nodeClass.nextNodeIds=new Map(node.nextNodeIds);
|
nodeClass.nextNodeIds = new Map(node.nextNodeIds);
|
||||||
nodeClass.prevNodeId=node.prevNodeId;
|
nodeClass.prevNodeId = node.prevNodeId;
|
||||||
nodeClass.id=node.id;
|
nodeClass.id = node.id;
|
||||||
return nodeClass;
|
return nodeClass;
|
||||||
});
|
});
|
||||||
const actionFlow = new ActionFlow(actionNodes);
|
const actionFlow = new ActionFlow(actionNodes);
|
||||||
actionFlow.id=parsedObject.id;
|
actionFlow.id = parsedObject.id;
|
||||||
return actionFlow;
|
return actionFlow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
134
sample.json
134
sample.json
@@ -1,138 +1,20 @@
|
|||||||
{
|
[
|
||||||
"id": "681ecde3-4439-4210-9fdf-424c6af98f09",
|
|
||||||
"actionNodes": [
|
|
||||||
{
|
|
||||||
"id": "34dfd32e-ba1a-440f-bb46-a8a1999109cd",
|
|
||||||
"name": "app.record.create.submit",
|
|
||||||
"title": "レコード追加画面",
|
|
||||||
"subTitle": "保存するとき",
|
|
||||||
"inputPoint": "",
|
|
||||||
"outputPoints": [],
|
|
||||||
"isRoot": true,
|
|
||||||
"actionProps": [],
|
|
||||||
"ActionValue": {},
|
|
||||||
"nextNodeIds": [
|
|
||||||
[
|
|
||||||
"",
|
|
||||||
"ce07775d-9729-4516-a88c-78ee8f2f851e"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "ce07775d-9729-4516-a88c-78ee8f2f851e",
|
|
||||||
"name": "自動採番",
|
|
||||||
"title": "文書番号を自動採番する",
|
|
||||||
"inputPoint": "",
|
|
||||||
"outputPoints": [],
|
|
||||||
"actionProps": [
|
|
||||||
{
|
|
||||||
"component": "InputText",
|
|
||||||
"props": {
|
|
||||||
"name": "displayName",
|
|
||||||
"displayName": "文書番号を自動採番する",
|
|
||||||
"placeholder": "表示を入力してください",
|
|
||||||
"modelValue": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"component": "InputText",
|
|
||||||
"props": {
|
|
||||||
"displayName": "フォーマット",
|
|
||||||
"modelValue": "",
|
|
||||||
"name": "format",
|
|
||||||
"placeholder": "フォーマットを入力してください"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"component": "FieldInput",
|
"component": "FieldInput",
|
||||||
"props": {
|
"props": {
|
||||||
"displayName": "採番項目",
|
"displayName": "フィールド",
|
||||||
"modelValue": "",
|
"modelValue": "",
|
||||||
"name": "field",
|
"name": "field",
|
||||||
"placeholder": "採番項目を選択してください"
|
"placeholder": "必須項目を選択してください"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
],
|
|
||||||
"prevNodeId": "34dfd32e-ba1a-440f-bb46-a8a1999109cd",
|
|
||||||
"nextNodeIds": [
|
|
||||||
[
|
|
||||||
"",
|
|
||||||
"0d18c3c9-abee-44e5-83eb-82074316219b"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "0d18c3c9-abee-44e5-83eb-82074316219b",
|
|
||||||
"name": "入力データ取得",
|
|
||||||
"title": "電話番号を取得する",
|
|
||||||
"inputPoint": "",
|
|
||||||
"outputPoints": [],
|
|
||||||
"actionProps": [
|
|
||||||
{
|
{
|
||||||
"component": "InputText",
|
"component": "InputText",
|
||||||
"props": {
|
"props": {
|
||||||
"name": "displayName",
|
"displayName": "エラーメッセージ",
|
||||||
"displayName": "表示名",
|
"modelValue": "",
|
||||||
"placeholder": "表示を入力してください",
|
"name": "format",
|
||||||
"modelValue": ""
|
"placeholder": "エラーメッセージを入力してください"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"prevNodeId": "ce07775d-9729-4516-a88c-78ee8f2f851e",
|
|
||||||
"nextNodeIds": [
|
|
||||||
[
|
|
||||||
"",
|
|
||||||
"399d7c04-5345-4bf6-8da3-d745df554524"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "399d7c04-5345-4bf6-8da3-d745df554524",
|
|
||||||
"name": "条件分岐",
|
|
||||||
"title": "電話番号入力形式チャック",
|
|
||||||
"inputPoint": "",
|
|
||||||
"outputPoints": [
|
|
||||||
"はい",
|
|
||||||
"いいえ"
|
|
||||||
],
|
|
||||||
"actionProps": [
|
|
||||||
{
|
|
||||||
"component": "InputText",
|
|
||||||
"props": {
|
|
||||||
"name": "displayName",
|
|
||||||
"displayName": "表示名",
|
|
||||||
"placeholder": "表示を入力してください",
|
|
||||||
"modelValue": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"prevNodeId": "0d18c3c9-abee-44e5-83eb-82074316219b",
|
|
||||||
"nextNodeIds": [
|
|
||||||
[
|
|
||||||
"いいえ",
|
|
||||||
"8173e6bc-3fa2-4403-b973-9368884e2dfa"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "8173e6bc-3fa2-4403-b973-9368884e2dfa",
|
|
||||||
"name": "エラー表示",
|
|
||||||
"title": "エラー表示して保存しない",
|
|
||||||
"inputPoint": "いいえ",
|
|
||||||
"outputPoints": [],
|
|
||||||
"actionProps": [
|
|
||||||
{
|
|
||||||
"component": "InputText",
|
|
||||||
"props": {
|
|
||||||
"name": "displayName",
|
|
||||||
"displayName": "表示名",
|
|
||||||
"placeholder": "表示を入力してください",
|
|
||||||
"modelValue": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"prevNodeId": "399d7c04-5345-4bf6-8da3-d745df554524",
|
|
||||||
"nextNodeIds": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user