@nu-art/ts-workspace-frontend 0.400.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ export declare const ModulePack_Frontend_TSWorkspace: import("../modules/ModuleFE_Workspace.js").ModuleFE_Workspace_Class[];
2
+ export * from '../modules/ModuleFE_Workspace.js';
@@ -0,0 +1,22 @@
1
+ /*
2
+ * Live-Docs will allow you to add and edit tool-tips from within your app...
3
+ *
4
+ * Copyright (C) 2020 Adam van der Kruk aka TacB0sS
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+ import { ModuleFE_Workspace } from '../modules/ModuleFE_Workspace.js';
19
+ export const ModulePack_Frontend_TSWorkspace = [
20
+ ModuleFE_Workspace,
21
+ ];
22
+ export * from '../modules/ModuleFE_Workspace.js';
package/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from './core/module-pack.js';
2
+ export * from './ui/TS_Workspace.js';
3
+ export * from './ui/Panels.js';
4
+ export * from './ui/TS_OrientedWorkspace.js';
5
+ export * from './ui/types.js';
package/index.js ADDED
@@ -0,0 +1,23 @@
1
+ /*
2
+ * Permissions management system, define access level for each of
3
+ * your server apis, and restrict users by giving them access levels
4
+ *
5
+ * Copyright (C) 2020 Adam van der Kruk aka TacB0sS
6
+ *
7
+ * Licensed under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License.
9
+ * You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */
19
+ export * from './core/module-pack.js';
20
+ export * from './ui/TS_Workspace.js';
21
+ export * from './ui/Panels.js';
22
+ export * from './ui/TS_OrientedWorkspace.js';
23
+ export * from './ui/types.js';
@@ -0,0 +1,17 @@
1
+ import { Module, TypedMap } from '@nu-art/ts-common';
2
+ import { PanelConfig } from '../index.js';
3
+ type Config = {
4
+ defaultConfigs: TypedMap<PanelConfig>;
5
+ accountResolver: () => string;
6
+ };
7
+ export declare class ModuleFE_Workspace_Class extends Module<Config> {
8
+ private workspacesToUpsert;
9
+ private upsertRunnable;
10
+ getWorkspaceConfigByKey: (key: string) => PanelConfig<any>;
11
+ private getWorkspaceByKey;
12
+ private getStorageKeyForWorkspace;
13
+ setWorkspaceByKey: (key: string, config: PanelConfig<any>) => Promise<void>;
14
+ deleteWorkspaceByKey: (key: string) => Promise<void>;
15
+ }
16
+ export declare const ModuleFE_Workspace: ModuleFE_Workspace_Class;
17
+ export {};
@@ -0,0 +1,50 @@
1
+ /*
2
+ * A typescript & react boilerplate with api call example
3
+ *
4
+ * Copyright (C) 2020 Adam van der Kruk aka TacB0sS
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+ import { StorageKey } from '@nu-art/thunderstorm-frontend/index';
19
+ import { _values, BadImplementationException, Module } from '@nu-art/ts-common';
20
+ export class ModuleFE_Workspace_Class extends Module {
21
+ workspacesToUpsert = {};
22
+ upsertRunnable;
23
+ getWorkspaceConfigByKey = (key) => {
24
+ const workspace = this.getWorkspaceByKey(key);
25
+ const config = workspace?.config || this.config.defaultConfigs[key];
26
+ if (!config)
27
+ throw new BadImplementationException(`Could not find config for key ${key}`);
28
+ return config;
29
+ };
30
+ getWorkspaceByKey = (key) => {
31
+ return this.getStorageKeyForWorkspace(key).get();
32
+ };
33
+ getStorageKeyForWorkspace = (key) => new StorageKey(`workspace_key__${key}`);
34
+ setWorkspaceByKey = async (key, config) => {
35
+ this.workspacesToUpsert[key] = { key: key, config: config };
36
+ clearTimeout(this.upsertRunnable);
37
+ this.upsertRunnable = setTimeout(async () => {
38
+ const values = _values(this.workspacesToUpsert);
39
+ values.forEach(workspace => {
40
+ this.logInfo('SET WORKSPACE KEY', `KEY: ${workspace.key}`);
41
+ this.getStorageKeyForWorkspace(workspace.key).set(workspace);
42
+ });
43
+ this.workspacesToUpsert = {};
44
+ }, 500);
45
+ };
46
+ deleteWorkspaceByKey = async (key) => {
47
+ this.getStorageKeyForWorkspace(key).delete();
48
+ };
49
+ }
50
+ export const ModuleFE_Workspace = new ModuleFE_Workspace_Class();
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@nu-art/ts-workspace-frontend",
3
+ "version": "0.400.7",
4
+ "description": "TS Workspace Frontend",
5
+ "keywords": [
6
+ "TacB0sS",
7
+ "express",
8
+ "infra",
9
+ "live-docs",
10
+ "nu-art",
11
+ "thunderstorm",
12
+ "typescript"
13
+ ],
14
+ "license": "Apache-2.0",
15
+ "author": "TacB0sS",
16
+ "scripts": {
17
+ "build": "tsc"
18
+ },
19
+ "publishConfig": {
20
+ "directory": "dist",
21
+ "linkDirectory": true
22
+ },
23
+ "dependencies": {
24
+ "@nu-art/ts-workspace-shared": "0.400.7",
25
+ "@nu-art/firebase-frontend": "0.400.7",
26
+ "@nu-art/firebase-shared": "0.400.7",
27
+ "@nu-art/thunderstorm-frontend": "0.400.7",
28
+ "@nu-art/thunderstorm-shared": "0.400.7",
29
+ "@nu-art/ts-common": "0.400.7",
30
+ "@nu-art/user-account-frontend": "0.400.7",
31
+ "@nu-art/user-account-shared": "0.400.7",
32
+ "express": "^4.18.2",
33
+ "firebase": "^11.9.0",
34
+ "firebase-admin": "13.4.0",
35
+ "firebase-functions": "6.3.2",
36
+ "moment": "^2.29.4",
37
+ "react": "^18.0.0",
38
+ "react-dom": "^18.0.0",
39
+ "react-router-dom": "^6.9.0",
40
+ "request": "^2.88.0"
41
+ },
42
+ "devDependencies": {
43
+ "@types/react": "^18.0.0",
44
+ "@types/express": "^4.17.17",
45
+ "@types/history": "^4.7.2",
46
+ "@types/request": "^2.48.1"
47
+ },
48
+ "unitConfig": {
49
+ "type": "typescript-lib"
50
+ },
51
+ "type": "module",
52
+ "exports": {
53
+ ".": {
54
+ "types": "./index.d.ts",
55
+ "import": "./index.js"
56
+ },
57
+ "./*": {
58
+ "types": "./*.d.ts",
59
+ "import": "./*.js"
60
+ }
61
+ }
62
+ }
package/ui/Panels.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { Config_PanelParent, PanelConfig, Props_WorkspacePanel, State_WorkspacePanel } from './types.js';
2
+ import { ComponentAsync, ComponentSync } from '@nu-art/thunderstorm-frontend/index';
3
+ export declare abstract class PanelBaseSync<Config, State = {}, Props = {}> extends ComponentSync<Props_WorkspacePanel<Config, Props> & Props, State_WorkspacePanel<Config, State>> {
4
+ protected shouldAlwaysReDerive: boolean;
5
+ protected deriveStateFromProps(nextProps: Props_WorkspacePanel<Config, Props>): State_WorkspacePanel<Config, State>;
6
+ shouldReDeriveState(nextProps: Readonly<Props_WorkspacePanel<Config, Props>>): boolean;
7
+ }
8
+ export declare abstract class PanelBaseAsync<Config, State = {}, Props = {}> extends ComponentAsync<Props_WorkspacePanel<Config, Props>, State_WorkspacePanel<Config, State>> {
9
+ protected deriveStateFromProps(nextProps: Props_WorkspacePanel<Config, Props>): Promise<State_WorkspacePanel<Config, State>>;
10
+ shouldReDeriveState(nextProps: Readonly<Props_WorkspacePanel<Config, Props>>): boolean;
11
+ }
12
+ export declare abstract class PanelParentSync<Config = {}, State = {}, Props = {}> extends PanelBaseSync<Config_PanelParent<Config>, State, Props> {
13
+ renderPanel(panel: PanelConfig): string | number | true | Iterable<import("react").ReactNode> | import("react/jsx-runtime").JSX.Element;
14
+ }
15
+ export declare abstract class PanelParentAsync<Config = {}, State = {}, Props = {}> extends PanelBaseAsync<Config_PanelParent<Config>, State, Props> {
16
+ renderPanel(panel: PanelConfig): string | number | true | Iterable<import("react").ReactNode> | import("react/jsx-runtime").JSX.Element;
17
+ }
package/ui/Panels.js ADDED
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { ComponentAsync, ComponentSync } from '@nu-art/thunderstorm-frontend/index';
3
+ import { compare, resolveContent } from '@nu-art/ts-common';
4
+ export class PanelBaseSync extends ComponentSync {
5
+ shouldAlwaysReDerive = false;
6
+ deriveStateFromProps(nextProps) {
7
+ return { config: { ...nextProps.config } };
8
+ }
9
+ shouldReDeriveState(nextProps) {
10
+ return this.shouldAlwaysReDerive || !compare(this.state.config, nextProps.config);
11
+ }
12
+ }
13
+ export class PanelBaseAsync extends ComponentAsync {
14
+ async deriveStateFromProps(nextProps) {
15
+ return { config: { ...nextProps.config } };
16
+ }
17
+ shouldReDeriveState(nextProps) {
18
+ return !compare(this.state.config, nextProps.config);
19
+ }
20
+ }
21
+ export class PanelParentSync extends PanelBaseSync {
22
+ renderPanel(panel) {
23
+ const ComponentToRender = resolveContent(this.props.instances?.[panel.key], panel.data, this.props.onConfigChanged);
24
+ if (ComponentToRender) {
25
+ this.shouldAlwaysReDerive = true;
26
+ return ComponentToRender;
27
+ }
28
+ const PanelRenderer = this.props.renderers[panel.key];
29
+ return _jsx(PanelRenderer, { config: panel.data, instances: this.props.instances, renderers: this.props.renderers, onConfigChanged: this.props.onConfigChanged });
30
+ }
31
+ }
32
+ export class PanelParentAsync extends PanelBaseAsync {
33
+ renderPanel(panel) {
34
+ const ComponentToRender = resolveContent(this.props.instances?.[panel.key], panel.data, this.props.onConfigChanged);
35
+ if (ComponentToRender)
36
+ return ComponentToRender;
37
+ const PanelRenderer = this.props.renderers[panel.key];
38
+ if (!PanelRenderer)
39
+ return `NO RENDERER DEFINED FOR KEY: ${panel.key}`;
40
+ return _jsx(PanelRenderer, { config: panel.data, renderers: this.props.renderers, instances: this.props.instances });
41
+ }
42
+ }
@@ -0,0 +1,44 @@
1
+ import * as React from 'react';
2
+ import { PanelParentSync } from './Panels.js';
3
+ import { Config_PanelParent, Props_OrientedWorkspace, Props_WorkspaceParentPanel, State_WorkspaceParentPanel } from './types.js';
4
+ type State = {
5
+ factors: number[];
6
+ panelRefs: React.RefObject<HTMLDivElement>[];
7
+ };
8
+ export declare class TS_OrientedWorkspace extends PanelParentSync<{}, State, Props_OrientedWorkspace> {
9
+ private dragStart;
10
+ private firstPanelBounds;
11
+ private secondPanelBounds;
12
+ private ref?;
13
+ protected deriveStateFromProps(nextProps: Props_WorkspaceParentPanel<Config_PanelParent, Props_OrientedWorkspace>): State_WorkspaceParentPanel<{}, State>;
14
+ private calcFactors;
15
+ separatorOnDrag: (e: React.DragEvent<HTMLDivElement>, firstPanelIndex: number, secondPanelIndex: number) => void;
16
+ onDragStart: (e: React.DragEvent<HTMLDivElement>) => void;
17
+ onDragEnd: (e: React.DragEvent<HTMLDivElement>, firstPanelIndex: number, secondPanelIndex: number) => void;
18
+ implementFactors: (factors: {
19
+ index: number;
20
+ factor: number;
21
+ }[]) => void;
22
+ render(): import("react/jsx-runtime").JSX.Element;
23
+ }
24
+ export declare class TS_HorizontalWorkspace extends TS_OrientedWorkspace {
25
+ static defaultProps: {
26
+ firstEdge: string;
27
+ secondEdge: string;
28
+ orientation: string;
29
+ dimensionProp: string;
30
+ dimensionClientProp: string;
31
+ mousePos: string;
32
+ };
33
+ }
34
+ export declare class TS_VerticalWorkspace extends TS_OrientedWorkspace {
35
+ static defaultProps: {
36
+ firstEdge: string;
37
+ secondEdge: string;
38
+ orientation: string;
39
+ dimensionProp: string;
40
+ dimensionClientProp: string;
41
+ mousePos: string;
42
+ };
43
+ }
44
+ export {};
@@ -0,0 +1,129 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /* QWorkspaceVertical - content display and resizing
3
+ * When given panel contents and a page, displays content in resizable panels.*/
4
+ import * as React from 'react';
5
+ import { Fragment } from 'react';
6
+ import { PanelParentSync } from './Panels.js';
7
+ export class TS_OrientedWorkspace extends PanelParentSync {
8
+ dragStart = 0;
9
+ firstPanelBounds;
10
+ secondPanelBounds;
11
+ ref;
12
+ deriveStateFromProps(nextProps) {
13
+ this.ref = undefined;
14
+ const panelRefs = this.state?.panelRefs || nextProps.config.panels.map(i => React.createRef());
15
+ return { ...super.deriveStateFromProps(nextProps), factors: [], panelRefs };
16
+ }
17
+ calcFactors(nextProps) {
18
+ let factors = nextProps.config.panels.map(p => p.factor);
19
+ const current = this.ref;
20
+ if (current) {
21
+ const wrapperWidth = current.getBoundingClientRect()[this.props.dimensionProp];
22
+ const separatorPixels = Array.from(current.children).reduce((toRet, element, index) => {
23
+ if (index % 2 === 0)
24
+ return toRet;
25
+ const rect = element.getBoundingClientRect();
26
+ return toRet + rect[this.props.dimensionProp];
27
+ }, 0);
28
+ const containerFactor = (wrapperWidth - separatorPixels) / wrapperWidth;
29
+ factors = factors.map(f => f * containerFactor);
30
+ }
31
+ // const sumOfFactors = factors.reduce((a, b) => a + b, 0);
32
+ this.implementFactors(factors.map((factor, index) => ({ factor, index })));
33
+ return { factors };
34
+ }
35
+ //On drag logic for separator
36
+ separatorOnDrag = (e, firstPanelIndex, secondPanelIndex) => {
37
+ const firstPanel = this.props.config.panels[firstPanelIndex];
38
+ const secondPanel = this.props.config.panels[secondPanelIndex];
39
+ const statePanelsFactors = this.state.factors;
40
+ //Gather data
41
+ const delta = e[this.props.mousePos] - this.dragStart;
42
+ const parentSize = e.currentTarget.parentElement?.[this.props.dimensionClientProp];
43
+ const separatorSize = e.currentTarget?.[this.props.dimensionClientProp];
44
+ //Calculate new heights
45
+ const firstPanelDimension = this.firstPanelBounds[this.props.secondEdge] - this.firstPanelBounds[this.props.firstEdge];
46
+ const secondPanelDimension = this.secondPanelBounds[this.props.secondEdge] - this.secondPanelBounds[this.props.firstEdge];
47
+ let firstPanelSize = firstPanelDimension + delta;
48
+ let secondPanelSize = secondPanelDimension - delta;
49
+ const minFirstPanel = firstPanel.min || 100;
50
+ const minSecondPanel = secondPanel.min || 100;
51
+ if (firstPanelDimension + delta < minFirstPanel) {
52
+ firstPanelSize = minFirstPanel;
53
+ secondPanelSize = firstPanelDimension + secondPanelDimension - firstPanelSize;
54
+ }
55
+ if (secondPanelDimension - delta < minSecondPanel) {
56
+ secondPanelSize = minSecondPanel;
57
+ firstPanelSize = firstPanelDimension + secondPanelDimension - secondPanelSize;
58
+ }
59
+ const firstPanelFactor = firstPanelSize / parentSize;
60
+ const sum = statePanelsFactors[firstPanelIndex] + statePanelsFactors[secondPanelIndex];
61
+ statePanelsFactors[firstPanelIndex] = firstPanelFactor;
62
+ statePanelsFactors[secondPanelIndex] = sum - firstPanelFactor;
63
+ //Set config panels factors
64
+ const originalFactorSum = firstPanel.factor + secondPanel.factor;
65
+ firstPanel.factor = (firstPanelSize + separatorSize / 2) / parentSize;
66
+ secondPanel.factor = originalFactorSum - firstPanel.factor;
67
+ this.implementFactors([
68
+ { index: firstPanelIndex, factor: firstPanel.factor },
69
+ { index: secondPanelIndex, factor: secondPanel.factor }
70
+ ]);
71
+ };
72
+ //Gets called whenever dragging starts
73
+ onDragStart = (e) => {
74
+ //Set new empty image as the ghost image, position far offscreen
75
+ const img = new Image();
76
+ e.dataTransfer.setDragImage(img, -9999, -9999);
77
+ e.dataTransfer.effectAllowed = 'move';
78
+ e.dataTransfer.dropEffect = 'none';
79
+ this.dragStart = e[this.props.mousePos];
80
+ this.firstPanelBounds = e.currentTarget.previousElementSibling?.getBoundingClientRect();
81
+ this.secondPanelBounds = e.currentTarget.nextElementSibling?.getBoundingClientRect();
82
+ };
83
+ //Gets called whenever dragging stops
84
+ onDragEnd = (e, firstPanelIndex, secondPanelIndex) => {
85
+ //Init vars
86
+ this.dragStart = 0;
87
+ this.props.onConfigChanged();
88
+ };
89
+ //Script to implement the factor on panels in the dom
90
+ implementFactors = (factors) => {
91
+ factors.forEach(factor => {
92
+ const element = this.state.panelRefs[factor.index].current;
93
+ if (!element)
94
+ return;
95
+ element.style[this.props.dimensionProp] = ((factor.factor) * 100) + '%';
96
+ });
97
+ };
98
+ //Main Render
99
+ render() {
100
+ const panels = this.props.config.panels;
101
+ return (_jsx("div", { ref: _ref => {
102
+ if (this.ref || !_ref)
103
+ return;
104
+ this.ref = _ref;
105
+ this.setState(this.calcFactors(this.props));
106
+ }, className: `ts-workspace__${this.props.orientation}`, children: panels.map((panel, i) => _jsxs(Fragment, { children: [_jsx("div", { className: 'ts-workspace__panel', ref: this.state.panelRefs[i], draggable: false, children: this.renderPanel(panel) }), i !== (panels.length - 1) &&
107
+ _jsx("div", { className: `ts-workspace__separator`, draggable: true, tabIndex: 1, onDragStart: this.onDragStart, onDrag: (e) => this.separatorOnDrag(e, i, i + 1), onDragEnd: (e) => this.onDragEnd(e, i, i + 1) })] }, i)) }));
108
+ }
109
+ }
110
+ export class TS_HorizontalWorkspace extends TS_OrientedWorkspace {
111
+ static defaultProps = {
112
+ firstEdge: 'left',
113
+ secondEdge: 'right',
114
+ orientation: 'horizontal',
115
+ dimensionProp: 'width',
116
+ dimensionClientProp: 'clientWidth',
117
+ mousePos: 'pageX'
118
+ };
119
+ }
120
+ export class TS_VerticalWorkspace extends TS_OrientedWorkspace {
121
+ static defaultProps = {
122
+ firstEdge: 'top',
123
+ secondEdge: 'bottom',
124
+ orientation: 'vertical',
125
+ dimensionProp: 'height',
126
+ dimensionClientProp: 'clientHeight',
127
+ mousePos: 'pageY'
128
+ };
129
+ }
@@ -0,0 +1,20 @@
1
+ import { BaseAsyncState, ComponentSync } from '@nu-art/thunderstorm-frontend/index';
2
+ import './TS_Workspace.scss';
3
+ import { Props_BaseWorkspace } from './types.js';
4
+ type Props = Props_BaseWorkspace & {
5
+ workspaceKey: string;
6
+ id?: string;
7
+ className?: string;
8
+ };
9
+ type State = {
10
+ key: string;
11
+ };
12
+ export declare class TS_Workspace extends ComponentSync<Props, State> {
13
+ private toRender;
14
+ protected deriveStateFromProps(nextProps: Props, state: State): State;
15
+ protected _deriveStateFromProps(nextProps: Props): (BaseAsyncState & State) | undefined;
16
+ shouldComponentUpdate(nextProps: Readonly<Props>, nextState: Readonly<BaseAsyncState & State>, nextContext: any): boolean;
17
+ private onConfigChanged;
18
+ render(): string | import("react/jsx-runtime").JSX.Element;
19
+ }
20
+ export {};
@@ -0,0 +1,57 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /*
3
+ * Thunderstorm is a full web app framework!
4
+ *
5
+ * Typescript & Express backend infrastructure that natively runs on firebase function
6
+ * Typescript & React frontend infrastructure
7
+ *
8
+ * Copyright (C) 2020 Adam van der Kruk aka TacB0sS
9
+ *
10
+ * Licensed under the Apache License, Version 2.0 (the "License");
11
+ * you may not use this file except in compliance with the License.
12
+ * You may obtain a copy of the License at
13
+ *
14
+ * http://www.apache.org/licenses/LICENSE-2.0
15
+ *
16
+ * Unless required by applicable law or agreed to in writing, software
17
+ * distributed under the License is distributed on an "AS IS" BASIS,
18
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
+ * See the License for the specific language governing permissions and
20
+ * limitations under the License.
21
+ */
22
+ /* QWorkspaceVertical - content display and resizing
23
+ * When given panel contents and a page, displays content in resizable panels.*/
24
+ import { _className, ComponentSync } from '@nu-art/thunderstorm-frontend/index';
25
+ import './TS_Workspace.scss';
26
+ import { ModuleFE_Workspace } from '../modules/ModuleFE_Workspace.js';
27
+ export class TS_Workspace extends ComponentSync {
28
+ toRender = false;
29
+ deriveStateFromProps(nextProps, state) {
30
+ state.key = nextProps.workspaceKey;
31
+ return state;
32
+ }
33
+ _deriveStateFromProps(nextProps) {
34
+ const state = super._deriveStateFromProps(nextProps);
35
+ this.toRender = true;
36
+ return state;
37
+ }
38
+ shouldComponentUpdate(nextProps, nextState, nextContext) {
39
+ if (this.toRender) {
40
+ this.toRender = false;
41
+ return true;
42
+ }
43
+ return super.shouldComponentUpdate(nextProps, nextState, nextContext);
44
+ }
45
+ onConfigChanged = async () => {
46
+ const config = ModuleFE_Workspace.getWorkspaceConfigByKey(this.state.key);
47
+ await ModuleFE_Workspace.setWorkspaceByKey(this.state.key, config);
48
+ };
49
+ render() {
50
+ const config = ModuleFE_Workspace.getWorkspaceConfigByKey(this.state.key);
51
+ const PanelRenderer = this.props.renderers[config.key];
52
+ if (!PanelRenderer)
53
+ return `COULD NOT GET THE WORKSPACE RENDERER FOR KEY ${config.key}`;
54
+ const className = _className('ts-workspace', this.props.className);
55
+ return _jsx("div", { className: className, id: this.props.id, children: _jsx(PanelRenderer, { config: config.data, renderers: this.props.renderers, instances: this.props.instances, onConfigChanged: this.onConfigChanged }) });
56
+ }
57
+ }
@@ -0,0 +1,69 @@
1
+ @mixin separator ($dir) {
2
+ background: #eeeeee;
3
+ position: relative;
4
+ -webkit-user-drag: element;
5
+
6
+ @if $dir == 'horizontal' {
7
+ width: 5px;
8
+ height: 100%;
9
+ cursor: col-resize;
10
+ border-right: 1px solid black;
11
+ }
12
+ @if $dir == 'vertical' {
13
+ width: 100%;
14
+ height: 5px;
15
+ cursor: row-resize;
16
+ border-bottom: 1px solid black;
17
+ }
18
+ }
19
+
20
+ @mixin tsWorkspace ($dir) {
21
+ width: 100%;
22
+ height: 100%;
23
+ display: flex;
24
+
25
+ @if $dir == 'horizontal' {
26
+ & > .ts-workspace__separator {
27
+ @include separator($dir);
28
+ }
29
+ & > .ts-workspace__panel {
30
+ width: 33%;
31
+ height: 100%;
32
+ display: flex;
33
+ position: relative;
34
+ overflow: hidden;
35
+ //Apply right padding to left and middle panels for scrollbar
36
+ &.left, &.middle {
37
+ padding-right: 5px;
38
+ }
39
+ }
40
+ }
41
+ @if $dir == 'vertical' {
42
+ flex-direction: column;
43
+
44
+ & > .ts-workspace__separator {
45
+ @include separator($dir);
46
+ }
47
+
48
+ & > .ts-workspace__panel {
49
+ width: 100%;
50
+ display: flex;
51
+ position: relative;
52
+ overflow: hidden;
53
+ }
54
+ }
55
+ }
56
+
57
+ .ts-workspace {
58
+ width: 100%;
59
+ height: 100%;
60
+ display: flex;
61
+ flex-direction: column;
62
+
63
+ .ts-workspace__vertical {
64
+ @include tsWorkspace('vertical')
65
+ }
66
+ .ts-workspace__horizontal {
67
+ @include tsWorkspace('horizontal')
68
+ }
69
+ }
package/ui/types.d.ts ADDED
@@ -0,0 +1,52 @@
1
+ import * as React from 'react';
2
+ import { DB_Object, ResolvableContent, TypedMap } from '@nu-art/ts-common';
3
+ import { BaseAsyncState } from '@nu-art/thunderstorm-frontend/index';
4
+ export type Props_BaseWorkspace = {
5
+ renderers: TypedMap<React.ElementType>;
6
+ instances?: TypedMap<ResolvableContent<React.ReactNode, [any, Props_ConfigChanged['onConfigChanged']]>>;
7
+ };
8
+ export type Props_ConfigChanged = {
9
+ onConfigChanged: () => void;
10
+ };
11
+ export type Props_WorkspacePanel<Config, Props = {}> = Props & Props_ConfigChanged & Props_BaseWorkspace & {
12
+ config: Config;
13
+ };
14
+ export type State_WorkspacePanel<Config, State = {}> = BaseAsyncState & State & {
15
+ config: Config;
16
+ };
17
+ export type Config_PanelParent<ChildConfig = {}> = ChildConfig & {
18
+ panels: PanelConfig[];
19
+ };
20
+ export type State_WorkspaceParentPanel<Config, State = {}> = State_WorkspacePanel<Config_PanelParent<Config>, State>;
21
+ export type Props_WorkspaceParentPanel<Config, Props = {}> = Props_WorkspacePanel<Config_PanelParent<Config>, Props>;
22
+ export type Props_OrientedWorkspace = {
23
+ firstEdge: 'top' | 'left';
24
+ secondEdge: 'bottom' | 'right';
25
+ orientation: 'horizontal' | 'vertical';
26
+ dimensionProp: 'height' | 'width';
27
+ dimensionClientProp: 'clientHeight' | 'clientWidth';
28
+ mousePos: 'pageY' | 'pageX';
29
+ };
30
+ export type PanelsData = {
31
+ horizontalSpace: {
32
+ panels: PanelConfig<any, any>[];
33
+ };
34
+ verticalSpace: {
35
+ panels: PanelConfig<any, any>[];
36
+ };
37
+ topPanel: never;
38
+ leftPanel: never;
39
+ centerPanel: never;
40
+ rightPanel: never;
41
+ bottomPanel: never;
42
+ };
43
+ export type PanelConfig<PanelType extends keyof PanelsData = keyof PanelsData, PanelData extends PanelsData[PanelType] = PanelsData[PanelType]> = {
44
+ name: string;
45
+ visible: boolean;
46
+ factor: number;
47
+ min: number;
48
+ key: PanelType;
49
+ } & {
50
+ data?: PanelData;
51
+ };
52
+ export type WorkspaceConfig = DB_Object & PanelConfig;
package/ui/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};