diff --git a/frontend/src/components/main/NodeItem.vue b/frontend/src/components/main/NodeItem.vue new file mode 100644 index 0000000..071fb25 --- /dev/null +++ b/frontend/src/components/main/NodeItem.vue @@ -0,0 +1,107 @@ + + + + diff --git a/frontend/src/components/main/NodeLine.vue b/frontend/src/components/main/NodeLine.vue new file mode 100644 index 0000000..61d5c0f --- /dev/null +++ b/frontend/src/components/main/NodeLine.vue @@ -0,0 +1,99 @@ + + + + diff --git a/frontend/src/components/models.ts b/frontend/src/components/models.ts index 3b8b6be..7cf42c9 100644 --- a/frontend/src/components/models.ts +++ b/frontend/src/components/models.ts @@ -32,4 +32,3 @@ export interface AppInfo { creator?:User; modifier?:User; } - diff --git a/frontend/src/components/right/ActionProperty.vue b/frontend/src/components/right/ActionProperty.vue new file mode 100644 index 0000000..69f24c1 --- /dev/null +++ b/frontend/src/components/right/ActionProperty.vue @@ -0,0 +1,57 @@ + + + diff --git a/frontend/src/components/right/DatePicker.vue b/frontend/src/components/right/DatePicker.vue new file mode 100644 index 0000000..6f6b146 --- /dev/null +++ b/frontend/src/components/right/DatePicker.vue @@ -0,0 +1,45 @@ + + + diff --git a/frontend/src/components/right/FieldInput.vue b/frontend/src/components/right/FieldInput.vue new file mode 100644 index 0000000..c49865d --- /dev/null +++ b/frontend/src/components/right/FieldInput.vue @@ -0,0 +1,62 @@ + + + diff --git a/frontend/src/components/right/InputText.vue b/frontend/src/components/right/InputText.vue new file mode 100644 index 0000000..b548966 --- /dev/null +++ b/frontend/src/components/right/InputText.vue @@ -0,0 +1,33 @@ + + + diff --git a/frontend/src/components/right/SelectBox.vue b/frontend/src/components/right/SelectBox.vue new file mode 100644 index 0000000..f8a34c1 --- /dev/null +++ b/frontend/src/components/right/SelectBox.vue @@ -0,0 +1,36 @@ + + + diff --git a/frontend/src/pages/FlowChartTest.vue b/frontend/src/pages/FlowChartTest.vue new file mode 100644 index 0000000..1cf394b --- /dev/null +++ b/frontend/src/pages/FlowChartTest.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/frontend/src/pages/testFlow.vue b/frontend/src/pages/testFlow.vue new file mode 100644 index 0000000..6b9c9ff --- /dev/null +++ b/frontend/src/pages/testFlow.vue @@ -0,0 +1,95 @@ + + diff --git a/frontend/src/router/routes.ts b/frontend/src/router/routes.ts index 95669d3..a6d6df1 100644 --- a/frontend/src/router/routes.ts +++ b/frontend/src/router/routes.ts @@ -7,15 +7,12 @@ const routes: RouteRecordRaw[] = [ children: [ { path: '', component: () => import('pages/IndexPage.vue') }, { path: 'ruleEditor', component: () => import('pages/RuleEditor.vue') }, + { path: 'test', component: () => import('pages/testQursar.vue') }, + { path: 'flow', component: () => import('pages/testFlow.vue') }, + { path: 'flowchart', component: () => import('pages/FlowChartTest.vue') }, { path: 'flowEditor', component: () => import('pages/FlowEditorPage.vue') } - ] + ], }, - { - path: '/test/', - children: [{ path: '', component: () => import('pages/testQursar.vue') }], - component: () => import('layouts/MainLayout.vue'), - }, - // Always leave this as last one, // but you can also remove it { diff --git a/frontend/src/types/ActionTypes.ts b/frontend/src/types/ActionTypes.ts new file mode 100644 index 0000000..eaecb6a --- /dev/null +++ b/frontend/src/types/ActionTypes.ts @@ -0,0 +1,251 @@ +/** + * アクションのプロパティ定義 + */ +interface IActionProperty { + component: string; + props: { + //プロパティ名 + name: string; + //プロパティ表示名 + displayName:string; + placeholder: string; + //プロパティ設定値 + modelValue: any; + }; +} +/** + * アクションタイプ定義 + */ +export interface IActionNode{ + id:string; + //アクション名 + name:string; + title:string; + subTitle:string; + inputPoint:string; + //出力ポイント(条件分岐以外未使用) + outputPoints:Array; + //ルートアクション(Kintone event) + isRoot:boolean; + //アクションのプロパティ定義 + actionProps:Array; + //アクションのプロパティ設定値抽出 + ActionValue:object + prevNode?: IActionNode; + nextNodes:Map; +} +/** + * アクションフローの定義 + */ +export interface IActionFlow { + actionNodes:Array +} + +/** + * アクションのプロパティ定義に基づいたクラス + */ +class ActionProperty implements IActionProperty { + component: string; + props: { + // プロパティ名 + name: string; + // プロパティ表示名 + displayName: string; + placeholder: string; + // プロパティ設定値 + modelValue: any; + }; + + static defaultProperty():IActionProperty{ + return new ActionProperty("InputText","displayName","表示名","表示を入力してください",""); + }; + + constructor( + component: string, + name: string, + displayName: string, + placeholder: string, + modelValue: any + ) { + this.component = component; + this.props = { + name: name, + displayName: displayName, + placeholder: placeholder, + modelValue: modelValue + }; + } + + +} + + +/** + * IActionNodeの実装、RootActionNode以外のアクション定義 + */ +export class ActionNode implements IActionNode { + id:string; + name: string; + title:string; + get subTitle():string{ + return this.name; + }; + inputPoint:string; + //出力ポイント(条件分岐以外未使用) + outputPoints:Array; + actionProps: Array; + get isRoot(): boolean{ + return false; + }; + get ActionValue():object{ + const propValue:any={}; + this.actionProps.forEach((value)=>{ + propValue[value.props.name]=value.props.modelValue + }); + return propValue; + }; + prevNode?: IActionNode; + nextNodes:Map; + constructor( + name: string, + title:string, + inputPoint:string, + outputPoint: Array = [], + actionProps: Array =[ActionProperty.defaultProperty()] + ) { + this.id=''; + this.name = name; + this.title=title; + this.inputPoint=inputPoint; + this.outputPoints = outputPoint; + const defProp =ActionProperty.defaultProperty(); + defProp.props.displayName=title; + this.actionProps =actionProps; + const prop = this.actionProps.find((prop)=>prop.props.name===defProp.props.name); + if(prop===undefined){ + this.actionProps.unshift(defProp); + } + this.nextNodes=new Map(); + } + +} +/** + * ルートアクション定義 + */ +export class RootAction implements IActionNode { + id:string; + name: string; + title:string; + subTitle:string; + inputPoint:string; + //出力ポイント(条件分岐以外未使用) + outputPoints:Array; + isRoot: boolean; + actionProps: Array; + ActionValue:object; + prevNode?: IActionNode=undefined; + nextNodes:Map; + constructor( + name: string, + title:string, + subTitle:string, + ) { + this.id=''; + this.name = name; + this.title=title; + this.subTitle=subTitle; + this.inputPoint=''; + this.outputPoints = []; + this.isRoot = true; + this.actionProps=[]; + this.ActionValue={}; + this.nextNodes=new Map(); + } +} + +/** + * アクションフローの定義 + */ +export class ActionFlow implements IActionFlow { + nextId:number; + actionNodes:Array; + constructor(actionNodes:Array|RootAction){ + this.nextId=0; + + if(actionNodes instanceof Array){ + this.actionNodes=actionNodes; + }else{ + this.actionNodes=[actionNodes]; + } + } + /** + * ノードを追加する + * 1.ID採番する + * 2.前のノードを関連付け + * @param newNode 新規追加するノード + * @param prevNode 前のノード + * @param inputPoint 入力ポイント + * @returns 追加されたノード + */ + addNode( + newNode:IActionNode, + prevNode?:IActionNode, + inputPoint?:string):IActionNode + { + newNode.id = this.generateId(); + if(inputPoint!==undefined){ + newNode.inputPoint=inputPoint; + } + if(prevNode!==undefined){ + newNode.prevNode=prevNode; + const nextNodes = prevNode.nextNodes; + if(nextNodes!==undefined && nextNodes.size>0){ + const nextNode=inputPoint!==undefined?nextNodes.get(inputPoint):nextNodes.get(''); + if(nextNode ){ + nextNode.prevNode=newNode; + if(newNode.outputPoints.length>0){ + if(!newNode.outputPoints.some((point)=>point==nextNode.inputPoint)){ + nextNode.inputPoint=newNode.outputPoints[0]; + } + }else{ + nextNode.inputPoint=''; + } + newNode.nextNodes.set(nextNode.inputPoint,nextNode); + } + } + prevNode.nextNodes.set(inputPoint?inputPoint:'',newNode); + }else{ + prevNode=this.actionNodes[this.actionNodes.length-1]; + prevNode.nextNodes.set(inputPoint?inputPoint:'',newNode); + newNode.prevNode=prevNode; + } + this.actionNodes.push(newNode); + return newNode; + } + /** + * ノードを削除する + * @param delNode + */ + removeNode(delNode:IActionNode){ + const prevNode = delNode; + const nextNode = this.findNextNode(delNode); + if(nextNode!==undefined){ + nextNode.prevNode=prevNode; + nextNode.inputPoint=delNode.inputPoint; + } + } + /** + * 次のノードを探す + * @param delNode + */ + findNextNode(targetNode: IActionNode):ActionNode|undefined { + return this.actionNodes.find((node)=>node.prevNode===targetNode); + } + + generateId():string{ + const no = this.nextId++; + return no.toString().padStart(10,'0'); + } + +} +