Skip to content

Commit

Permalink
tree editor and selected fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
GiordanoT committed Oct 20, 2023
1 parent 7e0a4fd commit 428e3dc
Show file tree
Hide file tree
Showing 19 changed files with 248 additions and 251 deletions.
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function App(props: AllProps) {

return(<div className={'d-flex flex-column h-100 p-1 REACT-ROOT' + (props.debug ? " debug" : "")}
onClick={e => statehistory.globalcanundostate = true}>
{/*<Navbar />*/}
<Navbar />
<Dock />
<Loader />
</div>);
Expand Down
32 changes: 5 additions & 27 deletions src/components/abstract/DockLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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 {
Expand Down Expand Up @@ -88,7 +89,6 @@ class DockLayoutComponent extends PureComponent<AllProps, ThisState>{
private viewpointEditor = { id: '6', title: 'Viewpoints', group: 'group2', closable: false, content: <ViewpointEditor /> };
private console = { id: '7', title: 'Console', group: 'group2', closable: false, content: <Console /> };

private selected = this.props.selected;
private views = this.props.views;
private moveOnStructure = false;
private moveOnViews = false;
Expand Down Expand Up @@ -116,7 +116,6 @@ class DockLayoutComponent extends PureComponent<AllProps, ThisState>{

shouldComponentUpdate(newProps: Readonly<AllProps>, newState: Readonly<ThisState>, 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);
Expand All @@ -131,7 +130,7 @@ class DockLayoutComponent extends PureComponent<AllProps, ThisState>{
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);

}

Expand All @@ -147,20 +146,6 @@ class DockLayoutComponent extends PureComponent<AllProps, ThisState>{
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;
}
}
}

Expand Down Expand Up @@ -197,15 +182,13 @@ class DockLayoutComponent extends PureComponent<AllProps, ThisState>{

async addMetamodel(evt: undefined|React.MouseEvent<HTMLButtonElement>, 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<HTMLButtonElement>, context: DockContext, panelData: PanelData) {
Expand Down Expand Up @@ -268,24 +251,19 @@ class DockLayoutComponent extends PureComponent<AllProps, ThisState>{

interface OwnProps { }
interface StateProps {
selected: Pointer<DModelElement, 0, 1, LModelElement>;
views: number;
m2: Pointer<DModel, 0, 'N', LModel>;
m1: Pointer<DModel, 0, 'N', LModel>;
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;
}

Expand Down
18 changes: 7 additions & 11 deletions src/components/abstract/tabs/TestTab.tsx
Original file line number Diff line number Diff line change
@@ -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(<div>
<button onClick={click}>click</button>
{selected?.id}
return(<div className={'p-2 border border-dark'}>
{JSON.stringify(selected)}
</div>);
}
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;
}

Expand Down
114 changes: 52 additions & 62 deletions src/components/contextMenu/ContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,114 +3,106 @@ 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('');
setMemorec(null);
SetRootFieldAction.new('contextMenu', {display: false, x: 0, y: 0});
}
const addView = async() => {
if(me) {
const jsx =`<div className={'root bg-white'}>Hello World!</div>`;
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 =`<div className={'root bg-white'}>Hello World!</div>`;
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(<div className={'mt-1 col text-center'}><b>{me.className}</b></div>);
if(display) {
jsxList.push(<div className={'mt-1 col text-center'}><b>{data.className}</b></div>);
jsxList.push(<hr className={'my-1'} />);

/* Memorec */
if(me.className === 'DClass')
if(data.className === 'DClass')
jsxList.push(<div onClick={structuralFeature} className={'col item'}>AI Suggest <i
className='bi bi-arrow-right-short'></i></div>);
if(me.className === 'DPackage')
if(data.className === 'DPackage')
jsxList.push(<div onClick={classifier} className={'col item'}>
AI Suggest
<i className={'ms-1 bi bi-arrow-right'}></i>
</div>);
jsxList.push(<div onClick={() => {
close();
SetRootFieldAction.new(`selected.${DUser.current}`, '', '', false);
}} className={'col item'}>Deselect</div>);
jsxList.push(<div onClick={() => {close(); node.zIndex += 1;}} className={'col item'}>Up</div>);
jsxList.push(<div onClick={() => {close(); node.zIndex -= 1;}} className={'col item'}>Down</div>);
jsxList.push(<div onClick={() => {close(); addView();}} className={'col item'}>Add View</div>);
jsxList.push(<div onClick={() => {close(); me?.delete();}} className={'col item'}>Delete</div>);
switch (me.className) {
case 'DValue': if ((me as any as LValue).instanceof) jsxList.pop(); break;
jsxList.push(<div onClick={async () => {close(); await addView();}} className={'col item'}>Add View</div>);
jsxList.push(<div onClick={() => {close(); data.delete(); node.delete();}} className={'col item'}>Delete</div>);
switch (data.className) {
case 'DValue': if ((data as any as LValue).instanceof) jsxList.pop(); break;
case 'DClass':
jsxList.push(<div onClick={() => {
close();
SetRootFieldAction.new('isEdgePending', {user: user.id, source: me.id});
SetRootFieldAction.new('isEdgePending', {user: user.id, source: data.id});
}} className={'col item'}>Extend</div>);
break;
}
Expand Down Expand Up @@ -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;
}

Expand Down
3 changes: 0 additions & 3 deletions src/components/forEndUser/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(<label className={'p-1'} {...otherprops}
style={{display: (jsxLabel || label) ? 'flex' : 'block', cursor: tooltip ? 'help' : 'auto', ...((props as any).style || {})}}>

Expand Down
Loading

0 comments on commit 428e3dc

Please sign in to comment.