Commit ff463609 authored by MatusT's avatar MatusT
Browse files

tracks basically done

parent a867dccb
Loading
Loading
Loading
Loading
Loading
+59 −13
Original line number Diff line number Diff line
@@ -44,7 +44,8 @@
        "simple-statistics": "^7.7.0",
        "stream": "^0.0.2",
        "ua-parser-js": "^1.0.2",
        "use-deep-compare-effect": "^1.8.1"
        "use-deep-compare-effect": "^1.8.1",
        "uuid": "^9.0.0"
      },
      "devDependencies": {
        "@fluentui/react": "^8.30.3",
@@ -65,6 +66,7 @@
        "@types/react-dom": "^17.0.9",
        "@types/react-redux": "^7.1.18",
        "@types/resize-observer-browser": "^0.1.6",
        "@types/uuid": "^8.3.4",
        "@typescript-eslint/eslint-plugin": "^4.30.0",
        "@typescript-eslint/parser": "^4.30.0",
        "@webgpu/types": "^0.1.21",
@@ -1646,6 +1648,12 @@
      "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.36.tgz",
      "integrity": "sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ=="
    },
    "node_modules/@types/uuid": {
      "version": "8.3.4",
      "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz",
      "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==",
      "dev": true
    },
    "node_modules/@types/ws": {
      "version": "8.2.2",
      "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.2.2.tgz",
@@ -4556,6 +4564,14 @@
        "react-dom": "^17.0.2"
      }
    },
    "node_modules/flexlayout-react/node_modules/uuid": {
      "version": "8.3.2",
      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
      "bin": {
        "uuid": "dist/bin/uuid"
      }
    },
    "node_modules/fmin": {
      "version": "0.0.2",
      "resolved": "https://registry.npmjs.org/fmin/-/fmin-0.0.2.tgz",
@@ -8381,9 +8397,9 @@
      }
    },
    "node_modules/rtl-css-js": {
      "version": "1.15.0",
      "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.15.0.tgz",
      "integrity": "sha512-99Cu4wNNIhrI10xxUaABHsdDqzalrSRTie4GeCmbGVuehm4oj+fIy8fTzB+16pmKe8Bv9rl+hxIBez6KxExTew==",
      "version": "1.16.0",
      "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.0.tgz",
      "integrity": "sha512-Oc7PnzwIEU4M0K1J4h/7qUUaljXhQ0kCObRsZjxs2HjkpKsnoTMvSmvJ4sqgJZd0zBoEfAyTdnK/jMIYvrjySQ==",
      "dependencies": {
        "@babel/runtime": "^7.1.2"
      }
@@ -8828,6 +8844,15 @@
        "websocket-driver": "^0.7.4"
      }
    },
    "node_modules/sockjs/node_modules/uuid": {
      "version": "8.3.2",
      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
      "dev": true,
      "bin": {
        "uuid": "dist/bin/uuid"
      }
    },
    "node_modules/source-map": {
      "version": "0.7.3",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
@@ -9690,9 +9715,9 @@
      }
    },
    "node_modules/uuid": {
      "version": "8.3.2",
      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
      "version": "9.0.0",
      "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
      "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
      "bin": {
        "uuid": "dist/bin/uuid"
      }
@@ -11493,6 +11518,12 @@
      "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.36.tgz",
      "integrity": "sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ=="
    },
    "@types/uuid": {
      "version": "8.3.4",
      "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz",
      "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==",
      "dev": true
    },
    "@types/ws": {
      "version": "8.2.2",
      "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.2.2.tgz",
@@ -13768,6 +13799,13 @@
      "integrity": "sha512-rqXkYADckkxi2I5On2ZtxVXcb8tfAP75Semf38ognWd3UHu4rEjKbSM4UqJtSMK9xIqo0PlpyVCOTc4E1N3CPg==",
      "requires": {
        "uuid": "^8.3.2"
      },
      "dependencies": {
        "uuid": {
          "version": "8.3.2",
          "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
          "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
        }
      }
    },
    "fmin": {
@@ -16686,9 +16724,9 @@
      }
    },
    "rtl-css-js": {
      "version": "1.15.0",
      "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.15.0.tgz",
      "integrity": "sha512-99Cu4wNNIhrI10xxUaABHsdDqzalrSRTie4GeCmbGVuehm4oj+fIy8fTzB+16pmKe8Bv9rl+hxIBez6KxExTew==",
      "version": "1.16.0",
      "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.0.tgz",
      "integrity": "sha512-Oc7PnzwIEU4M0K1J4h/7qUUaljXhQ0kCObRsZjxs2HjkpKsnoTMvSmvJ4sqgJZd0zBoEfAyTdnK/jMIYvrjySQ==",
      "requires": {
        "@babel/runtime": "^7.1.2"
      }
@@ -17014,6 +17052,14 @@
        "faye-websocket": "^0.11.3",
        "uuid": "^8.3.2",
        "websocket-driver": "^0.7.4"
      },
      "dependencies": {
        "uuid": {
          "version": "8.3.2",
          "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
          "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
          "dev": true
        }
      }
    },
    "source-map": {
@@ -17671,9 +17717,9 @@
      "dev": true
    },
    "uuid": {
      "version": "8.3.2",
      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
      "version": "9.0.0",
      "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
      "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg=="
    },
    "v8-compile-cache": {
      "version": "2.3.0",
+3 −1
Original line number Diff line number Diff line
@@ -48,7 +48,8 @@
    "simple-statistics": "^7.7.0",
    "stream": "^0.0.2",
    "ua-parser-js": "^1.0.2",
    "use-deep-compare-effect": "^1.8.1"
    "use-deep-compare-effect": "^1.8.1",
    "uuid": "^9.0.0"
  },
  "devDependencies": {
    "@fluentui/react": "^8.30.3",
@@ -69,6 +70,7 @@
    "@types/react-dom": "^17.0.9",
    "@types/react-redux": "^7.1.18",
    "@types/resize-observer-browser": "^0.1.6",
    "@types/uuid": "^8.3.4",
    "@typescript-eslint/eslint-plugin": "^4.30.0",
    "@typescript-eslint/parser": "^4.30.0",
    "@webgpu/types": "^0.1.21",
+7 −6
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ import { ConfigurationAction, ConfigurationState, DistanceDataConfiguration, Dis
import { DataAction, DataID, DataState, isoDataID } from "../../modules/storage/models/data";
import { isoSelectionID, SelectionAction, SelectionState } from "../../modules/storage/models/selections";
import { useConfiguration, useSelections, useViewportName } from '../hooks';
import { SelectionsPart } from './SelectionsPart';
import { SelectionsTrack } from './tracks/SelectionsTrack';

export function TADMapViewportConfiguration(props: {
    model: Model,
@@ -120,12 +120,13 @@ export function TADMapViewportConfiguration(props: {
        />
        <div style={{ display: 'block', width: '100%', marginTop: '32px' }}></div>
        <Separator></Separator>
        <SelectionsPart
            selections={selections}
            configurationReducer={configurationReducer}
        {configuration.selectedTrackID != null && (<SelectionsTrack
            configurationID={props.node.getConfig()}
            configurationsReducer={props.configurationsReducer}
            dataReducer={props.dataReducer}
            selectionsReducer={props.selectionsReducer}
            selectedDataIndex={0}
        ></SelectionsPart>
            trackID={configuration.selectedTrackID}
        ></SelectionsTrack>
        )}
    </div>
}
+105 −0
Original line number Diff line number Diff line
import React, { Dispatch, Fragment, useMemo } from "react";

import { ConfigurationAction, ConfigurationState, DistanceDataConfiguration, DistanceMapDataConfiguration, DistanceViewportConfiguration, TrackType } from '../../../modules/storage/models/viewports';
import { DataAction, DataState } from "../../../modules/storage/models/data";
import { isoSelectionID, SelectionAction, SelectionState } from "../../../modules/storage/models/selections";
import { useConfiguration } from '../../hooks';
import { Delete16Regular } from "@fluentui/react-icons";
import { ComboBox, DefaultButton, IComboBox, IComboBoxOption } from "@fluentui/react";
import { Text } from '@fluentui/react/lib/Text';
import { notEmpty } from "../../../modules/utils";

export function SelectionsTrack(props: {
    configurationID: number,
    configurationsReducer: [ConfigurationState, Dispatch<ConfigurationAction>],
    dataReducer: [DataState, Dispatch<DataAction>],
    selectionsReducer: [SelectionState, Dispatch<SelectionAction>],
    trackID: string,
}): JSX.Element {
    // Configuration/Data
    const configurationReducer = useConfiguration<DistanceViewportConfiguration>(props.configurationID, props.configurationsReducer);

    const [configuration, updateConfiguration] = configurationReducer;
    const [data, dataDispatch] = props.dataReducer;
    const [allSelections, allSelectionsDispatch] = props.selectionsReducer;

    const trackIndex = configuration.tracks.findIndex(t => t.id === props.trackID);
    const track = configuration.tracks[trackIndex];

    if (track.type != TrackType.Selections) {
        throw "";
    }

    const selectionsList = allSelections.selections.map(s => {
        return {
            key: isoSelectionID.unwrap(s.id),
            text: s.name,
        } as IComboBoxOption;
    });

    const addSelection = (event: React.FormEvent<IComboBox>, option?: IComboBoxOption) => {
        if (!option) return;

        const key = option.key as number;

        const selectionID = isoSelectionID.wrap(key);

        const newTracks = [...configuration.tracks];
        const oldTrack = newTracks[trackIndex];

        if (oldTrack.type === TrackType.Selections) {
            const newSelections = [...new Set([...oldTrack.selections, selectionID])];
            newTracks[trackIndex] = {
                ...oldTrack,
                selections: newSelections
            };
        }

        updateConfiguration({
            ...configuration,
            tracks: newTracks
        });
    };

    const selections = useMemo(() => track.selections.map(selectionID => {
        if (configuration.data == null || configuration.data.type != DistanceMapDataConfiguration.Data) {
            return undefined;
        } else {
            const d = configuration.data as DistanceDataConfiguration;
            return allSelections.selections.find(s => s.id == selectionID && s.dataID == d.id);
        }
    }).filter(notEmpty), [configuration.data, track.selections, allSelections]);

    return <Fragment><ComboBox
        label="Add a selection"
        allowFreeform={true}
        autoComplete={'on'}
        options={selectionsList}
        onChange={addSelection}
    /><div className="treeViewList" style={{ marginTop: '16px' }}>
            {track.type == TrackType.Selections && (selections.map(selection => {
                return <div className="treeViewListItem" key={isoSelectionID.unwrap(selection.id)}>
                    <DefaultButton id="selectionColorButton"
                        style={{
                            padding: 0,
                            minWidth: "0px",
                        }}
                        onRenderText={(p) => <div
                            style={{
                                width: '1.2rem',
                                height: '1.2rem',
                                margin: '0px 4px',
                                backgroundColor: `rgb(${selection.color.r * 255}, ${selection.color.g * 255}, ${selection.color.b * 255})`,
                            }}
                        ></div>}
                        disabled={true}
                    />
                    <span style={{ display: 'block', width: '4px' }}></span>
                    <Text className="text" nowrap>{selection.name}</Text>
                    <Delete16Regular primaryFill={'white'} className='icon iconHoverRed'></Delete16Regular>
                </div>
            })
            )}
        </div>
    </Fragment >;
}
+30 −3
Original line number Diff line number Diff line
@@ -12,8 +12,10 @@ import { useConfiguration, useSelections } from "../hooks";
import { sasa } from "../../modules/sasa";
import { SelectionsTrack } from "./tracks/SelectionsTrack";
import { Dropdown, IDropdownOption } from "@fluentui/react";
import { v4 } from 'uuid';

import './Tracks.css';
import { BreakoutRoom20Filled } from "@fluentui/react-icons";

export function TADViewport(props: {
    graphicsLibrary: GraphicsModule.GraphicsLibrary,
@@ -59,7 +61,7 @@ export function TADViewport(props: {

    useEffect(() => {
        viewport.cameraConfiguration = cameraConfiguration;
    }, [cameraConfiguration]);
    }, [viewport, cameraConfiguration]);

    const [isControlPressed, setControlPressed] = useState(false);
    const [isAltPressed, setAltPressed] = useState(false);
@@ -374,6 +376,27 @@ export function TADViewport(props: {
        { key: TrackType.Selections, text: 'Selections' }
    ];

    const addTrack = (event: React.FormEvent<HTMLDivElement>, option?: IDropdownOption, index?: number): void => {
        if (!option) return;
        const trackType = option.key as TrackType;

        switch (trackType) {
            case TrackType.Selections: {
                updateConfiguration({
                    ...configuration,
                    tracks: [...configuration.tracks, {
                        id: v4(),
                        type: TrackType.Selections,
                        selections: [],
                    }]
                })
                break;
            }
        }
    };

    // console.log(configuration.tracks);

    return (<div style={{ width: '100%', height: '100%', overflow: 'hidden', position: 'relative' }}>
        <canvas ref={canvasElement} style={{ width: '100%', height: '100%', overflow: 'hidden', position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }}
            onClick={onClick}
@@ -392,22 +415,26 @@ export function TADViewport(props: {
                    switch (t.type) {
                        case TrackType.Selections: {
                            return <SelectionsTrack
                                key={t.id}
                                graphicsLibrary={props.graphicsLibrary}
                                configurationID={props.configurationID}
                                configurationsReducer={props.configurationsReducer}
                                dataReducer={props.dataReducer}
                                selectionsReducer={props.selectionsReducer}
                                track={t}
                                viewport={viewport}
                            ></SelectionsTrack>
                        }
                    }
                })}
                <div className="track-add">
                <div className="track track-add">
                    <Dropdown
                        placeholder="Select a track to add"
                        label=""
                        options={tracksDropdownOptions}
                        style={{pointerEvents: 'all', maxWidth: 200, margin: 'auto'}}
                        style={{ pointerEvents: 'all', maxWidth: 200, margin: 'auto' }}
                        onChange={addTrack}
                        notifyOnReselect={true}
                    ></Dropdown>
                </div>
            </div>
Loading