From 428e3dcd58ae6b2cb47057feb5d30dd01613ffee Mon Sep 17 00:00:00 2001 From: GiordanoT Date: Fri, 20 Oct 2023 08:46:36 +0200 Subject: [PATCH] tree editor and selected fixes --- src/App.tsx | 2 +- src/components/abstract/DockLayout.tsx | 32 +---- src/components/abstract/tabs/TestTab.tsx | 18 ++- src/components/contextMenu/ContextMenu.tsx | 114 ++++++++---------- src/components/forEndUser/Input.tsx | 3 - src/components/forEndUser/Tree.tsx | 16 ++- src/components/forEndUser/style.scss | 5 + .../rightbar/structureEditor/Structure.tsx | 4 +- .../structureEditor/StructureEditor.tsx | 25 ++-- .../rightbar/treeEditor/treeEditor.tsx | 66 +++------- .../rightbar/treeEditor/treeEditorOLD.tsx | 82 +++++++++++++ src/components/toolbar/ToolBar.tsx | 31 +++-- src/graph/graphElement/graphElement.tsx | 35 ++---- src/graph/vertex/Vertex.tsx | 26 ++-- src/joiner/classes.ts | 27 +++-- src/joiner/types.ts | 4 +- src/model/dataStructure/GraphDataElements.tsx | 2 +- src/redux/selectors/selectors.ts | 3 +- src/redux/store.tsx | 4 +- 19 files changed, 248 insertions(+), 251 deletions(-) create mode 100644 src/components/rightbar/treeEditor/treeEditorOLD.tsx diff --git a/src/App.tsx b/src/App.tsx index cc7ecebba..b50e4b57a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -13,7 +13,7 @@ function App(props: AllProps) { return(
statehistory.globalcanundostate = true}> - {/**/} +
); diff --git a/src/components/abstract/DockLayout.tsx b/src/components/abstract/DockLayout.tsx index d33621d18..b17c8f41f 100644 --- a/src/components/abstract/DockLayout.tsx +++ b/src/components/abstract/DockLayout.tsx @@ -16,7 +16,7 @@ import { Pointer, Selectors, U, - LPackage, SetRootFieldAction + LPackage, SetRootFieldAction, Dictionary, DUser } from '../../joiner'; import StructureEditor from "../rightbar/structureEditor/StructureEditor"; import TreeEditor from "../rightbar/treeEditor/treeEditor"; @@ -29,6 +29,7 @@ import ModelTab from "./tabs/ModelTab"; import InfoTab from "./tabs/InfoTab"; import TestTab from "./tabs/TestTab"; import IotTab from "./tabs/IotTab"; +import {FakeStateProps} from "../../joiner/types"; export class TabDataMaker { static metamodel (model: LModel | DModel): TabData { @@ -88,7 +89,6 @@ class DockLayoutComponent extends PureComponent{ private viewpointEditor = { id: '6', title: 'Viewpoints', group: 'group2', closable: false, content: }; private console = { id: '7', title: 'Console', group: 'group2', closable: false, content: }; - private selected = this.props.selected; private views = this.props.views; private moveOnStructure = false; private moveOnViews = false; @@ -116,7 +116,6 @@ class DockLayoutComponent extends PureComponent{ shouldComponentUpdate(newProps: Readonly, newState: Readonly, newContext: any): boolean { const oldProps = this.props; - // if(oldProps.selected !== newProps.selected) { this.moveOnStructure = true; return true; } if (oldProps.views !== newProps.views) { this.moveOnViews = true; return true; } const deltaM2 = U.arrayDifference(oldProps.m2, newProps.m2); @@ -131,7 +130,7 @@ class DockLayoutComponent extends PureComponent{ for(let model of addedM1) this.OPEN(model); for(let pointer of removedM1) this.CLOSE(pointer); - return !!(deltaM2.added.length || deltaM1.added.length || this.props.iot); + return !!(deltaM2.added.length || deltaM1.added.length); } @@ -147,20 +146,6 @@ class DockLayoutComponent extends PureComponent{ this.moveOnStructure = false; return; } - if(this.props.iot && !this.iotLoaded) { - const layout = this.dock.getLayout(); - const tabs = [ - this.iotEditor, - this.structureEditor, - this.treeEditor, - this.viewsEditor, - this.viewpointEditor, - this.console, - ]; - layout.dockbox.children[1] = {tabs}; - this.dock.setLayout(layout); - this.iotLoaded = true; - } } } @@ -197,15 +182,13 @@ class DockLayoutComponent extends PureComponent{ async addMetamodel(evt: undefined|React.MouseEvent, context: DockContext, panelData: PanelData, model?: DModel) { let name = 'metamodel_' + 0; - let names: (string)[] = Selectors.getAllMetamodels().map(m => m.name); + let names: string[] = Selectors.getAllMetamodels().map(m => m.name); name = U.increaseEndingNumber(name, false, false, (newName) => names.indexOf(newName) >= 0) const dModel = model || DModel.new(name, undefined, true); const lModel: LModel = LModel.fromD(dModel); const dPackage = lModel.addChild('package'); const lPackage: LPackage = LPackage.fromD(dPackage); lPackage.name = 'default'; - SetRootFieldAction.new('selected', lPackage.id, '', true); - SetRootFieldAction.new('_lastSelected', {modelElement: lPackage.id}); this.OPEN(dModel); } addModel(evt: React.MouseEvent, context: DockContext, panelData: PanelData) { @@ -268,24 +251,19 @@ class DockLayoutComponent extends PureComponent{ interface OwnProps { } interface StateProps { - selected: Pointer; views: number; m2: Pointer; m1: Pointer; - iot: null|boolean; } interface DispatchProps {} type AllProps = OwnProps & StateProps & DispatchProps; function mapStateToProps(state: DState, ownProps: OwnProps): StateProps { - const ret: StateProps = {} as any; - const selected = state._lastSelected?.modelElement; - if(selected) ret.selected = selected; + const ret: StateProps = {} as FakeStateProps; ret.views = state.viewelements.length; ret.m2 = state.m2models; ret.m1 = state.m1models; - ret.iot = state.iot; return ret; } diff --git a/src/components/abstract/tabs/TestTab.tsx b/src/components/abstract/tabs/TestTab.tsx index a231af376..c19e1547e 100644 --- a/src/components/abstract/tabs/TestTab.tsx +++ b/src/components/abstract/tabs/TestTab.tsx @@ -1,29 +1,25 @@ import React, {Dispatch, ReactElement} from "react"; import {connect} from "react-redux"; -import {DState, DUser, GObject, LModelElement, Selectors, U} from "../../../joiner"; -import {useStateIfMounted} from "use-state-if-mounted"; +import {DState} from "../../../joiner"; +import {FakeStateProps, Selected} from "../../../joiner/types"; function TestTabComponent(props: AllProps) { const selected = props.selected; - const click = () => { - } - - return(
- - {selected?.id} + return(
+ {JSON.stringify(selected)}
); } interface OwnProps {} -interface StateProps {selected: LModelElement|null} +interface StateProps {selected: Selected} interface DispatchProps {} type AllProps = OwnProps & StateProps & DispatchProps; function mapStateToProps(state: DState, ownProps: OwnProps): StateProps { - const ret: StateProps = {} as any; - ret.selected = null; + const ret: StateProps = {} as FakeStateProps; + ret.selected = state.selected; return ret; } diff --git a/src/components/contextMenu/ContextMenu.tsx b/src/components/contextMenu/ContextMenu.tsx index bc35c2e21..c19ad9fba 100644 --- a/src/components/contextMenu/ContextMenu.tsx +++ b/src/components/contextMenu/ContextMenu.tsx @@ -3,35 +3,36 @@ import {connect} from 'react-redux'; import './style.scss'; import {CreateElementAction, SetRootFieldAction} from '../../redux/action/action'; import { + DState, + DUser, DValue, DViewElement, GObject, LClass, - LGraphElement, - LNamedElement, + LGraphElement, LNamedElement, LPackage, LUser, - LValue, DState, U, + LValue, + Selectors, + U, } from '../../joiner'; import MemoRec from '../../memorec/api'; import {useStateIfMounted} from 'use-state-if-mounted'; import ModellingIcon from "../forEndUser/ModellingIcon"; +import {FakeStateProps} from "../../joiner/types"; function ContextMenuComponent(props: AllProps) { const user = props.user; const display = props.display; const position = props.position; - const me = props.me; //refer to selected const node = props.node; + const data: LNamedElement = LNamedElement.fromPointer(node?.model?.id); const jsxList: ReactNode[] = []; const [memorec, setMemorec] = useStateIfMounted<{data:GObject[], type:'class'|'package'}|null>(null); const [suggestedName, setSuggestedName] = useStateIfMounted(''); - - useEffect(() => { - if(!display) close(); - },[display]) + if(!node || !data) return(<>); const close = () => { setSuggestedName(''); @@ -39,78 +40,69 @@ function ContextMenuComponent(props: AllProps) { SetRootFieldAction.new('contextMenu', {display: false, x: 0, y: 0}); } const addView = async() => { - if(me) { - const jsx =`
Hello World!
`; - const dView: DViewElement = DViewElement.new(me.name + 'View', jsx); - switch(me.className) { - case 'DClass': - dView.query = `context DObject inv: self.instanceof.id = '${me.id}'`; - break; - case 'DAttribute': - case 'DReference': - dView.query = `context DValue inv: self.instanceof.id = '${me.id}'`; - break; - default: - dView.query = `context ${me.className} inv: self.id = '${me.id}'`; - break; - } - CreateElementAction.new(dView); - SetRootFieldAction.new('stackViews', [], '', false); - await U.sleep(1); - SetRootFieldAction.new('stackViews', dView.id, '+=', true); + const jsx =`
Hello World!
`; + const dView: DViewElement = DViewElement.new(data.name + 'View', jsx); + switch(data.className) { + case 'DClass': + dView.query = `context DObject inv: self.instanceof.id = '${data.id}'`; + break; + case 'DAttribute': + case 'DReference': + dView.query = `context DValue inv: self.instanceof.id = '${data.id}'`; + break; + default: + dView.query = `context ${data.className} inv: self.id = '${data.id}'`; + break; } - } - const structuralFeature = async () => { - if(!me) return; - const data = await MemoRec.structuralFeature(me); - setMemorec(data); + CreateElementAction.new(dView); + SetRootFieldAction.new('stackViews', [], '', false); + await U.sleep(1); + SetRootFieldAction.new('stackViews', dView.id, '+=', true); } - const classifier = async() => { - if (!me) return; - const data = await MemoRec.classifier(me); - setMemorec(data); - } + const structuralFeature = async () => {setMemorec(await MemoRec.structuralFeature(data))} + + const classifier = async() => {setMemorec(await MemoRec.classifier(data))} const suggestOnClass = (isAttribute:boolean) => { - if(!me) return; - const lClass: LClass = LClass.fromPointer(me.id); + const lClass: LClass = LClass.fromPointer(data.id); if(isAttribute) lClass.addAttribute(suggestedName); else lClass.addReference(suggestedName); - //add attribute/refence to class close(); } const suggestOnPackage = () => { - if(!me) return; - const lPackage: LPackage = LPackage.fromPointer(me.id); + const lPackage: LPackage = LPackage.fromPointer(data.id); lPackage.addClass(suggestedName); - //add class to package close(); } - if(display && me && node) { - jsxList.push(
{me.className}
); + if(display) { + jsxList.push(
{data.className}
); jsxList.push(
); /* Memorec */ - if(me.className === 'DClass') + if(data.className === 'DClass') jsxList.push(
AI Suggest
); - if(me.className === 'DPackage') + if(data.className === 'DPackage') jsxList.push(
AI Suggest
); + jsxList.push(
{ + close(); + SetRootFieldAction.new(`selected.${DUser.current}`, '', '', false); + }} className={'col item'}>Deselect
); jsxList.push(
{close(); node.zIndex += 1;}} className={'col item'}>Up
); jsxList.push(
{close(); node.zIndex -= 1;}} className={'col item'}>Down
); - jsxList.push(
{close(); addView();}} className={'col item'}>Add View
); - jsxList.push(
{close(); me?.delete();}} className={'col item'}>Delete
); - switch (me.className) { - case 'DValue': if ((me as any as LValue).instanceof) jsxList.pop(); break; + jsxList.push(
{close(); await addView();}} className={'col item'}>Add View
); + jsxList.push(
{close(); data.delete(); node.delete();}} className={'col item'}>Delete
); + switch (data.className) { + case 'DValue': if ((data as any as LValue).instanceof) jsxList.pop(); break; case 'DClass': jsxList.push(
{ close(); - SetRootFieldAction.new('isEdgePending', {user: user.id, source: me.id}); + SetRootFieldAction.new('isEdgePending', {user: user.id, source: data.id}); }} className={'col item'}>Extend
); break; } @@ -161,22 +153,20 @@ interface StateProps { user: LUser, display: boolean, position: {x: number, y: number}, - me?: LNamedElement, - node?: LGraphElement, + node: LGraphElement|null, } interface DispatchProps {} type AllProps = OwnProps & StateProps & DispatchProps; function mapStateToProps(state: DState, ownProps: OwnProps): StateProps { - const user = LUser.from(state.currentUser); - const display = state.contextMenu.display; - const position = {x: state.contextMenu.x, y: state.contextMenu.y} - const mePointer = state._lastSelected?.modelElement; - const me: LNamedElement | undefined = mePointer ? LNamedElement.fromPointer(mePointer) : undefined; - const nodePointer = state._lastSelected?.node; - const node: LGraphElement | undefined = nodePointer ? LGraphElement.fromPointer(nodePointer) : undefined; - const ret: StateProps = { user, display, position, me, node }; + const ret: StateProps = {} as FakeStateProps; + ret.user = LUser.from(state.currentUser); + ret.display = state.contextMenu.display; + ret.position = {x: state.contextMenu.x, y: state.contextMenu.y}; + const nodeid = state.selected[DUser.current]; + if(nodeid) ret.node = LGraphElement.fromPointer(nodeid); + else ret.node = null; return ret; } diff --git a/src/components/forEndUser/Input.tsx b/src/components/forEndUser/Input.tsx index c2ef9d0a2..7a7f70cf9 100644 --- a/src/components/forEndUser/Input.tsx +++ b/src/components/forEndUser/Input.tsx @@ -41,8 +41,6 @@ function InputComponent(props: AllProps) { } }) - - if (!data) return(<>); const readOnly = (props.readonly !== undefined) ? props.readonly : data.id.indexOf("Pointer_View") !== -1 // more efficient than U.getDefaultViewsID().includes(data.id); const type = (props.type) ? props.type : 'text'; const label: string|undefined = props.label; @@ -105,7 +103,6 @@ function InputComponent(props: AllProps) { type={type} value={value} onChange={change} onBlur={blur} checked={(['checkbox', 'radio'].includes(type)) ? !!value : undefined} /> - // style={{cursor: (tooltip) ? 'help' : 'auto'}} return(