@nu-art/work-hub-frontend 0.400.7 → 0.400.13

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.
@@ -3,18 +3,22 @@ import { MouseEvent, ReactNode } from 'react';
3
3
  import { ModuleFE_BaseDB } from '@nu-art/thunderstorm-frontend';
4
4
  import { WorkHubTab } from '@nu-art/work-hub-shared';
5
5
  import { WorkHubItem_MenuSection } from '../_ui/Component_WorkHubActionMenu/types.js';
6
+ type MenuResolver = (tab: WorkHubTab) => (Promise<WorkHubItem_MenuSection[]> | WorkHubItem_MenuSection[]);
7
+ type WorkHubItemRenderer<Args extends any = void> = (workHubItem: WorkHubItem<Args>, tabId: string, args: Args) => ReactNode;
6
8
  export declare class WorkHubItem<Args extends any = void> extends Logger {
7
9
  readonly key: string;
8
10
  modulesToAwait: ModuleFE_BaseDB<any>[] | undefined;
9
- renderer: (workHubItem: WorkHubItem<Args>, args: Args) => ReactNode;
11
+ renderer: WorkHubItemRenderer<Args>;
10
12
  private tabTag;
11
13
  private customMenuActionsResolver;
12
14
  constructor(key: string);
13
- setRenderer: (renderer: (workHubItem: WorkHubItem<Args>, args: Args) => ReactNode) => this;
15
+ setRenderer: (renderer: WorkHubItemRenderer<Args>) => this;
14
16
  setTag: (tag: string) => this;
15
17
  setModulesToAwait: (modules: ModuleFE_BaseDB<any>[]) => this;
16
- setCustomMenuActionsResolver: (resolver: (tab: WorkHubTab) => WorkHubItem_MenuSection[]) => this;
18
+ setCustomMenuActionsResolver: (resolver: MenuResolver) => this;
17
19
  openTab: (id: string, label: string, args: Args) => void;
18
- openTabMenu: (e: MouseEvent<HTMLDivElement>, tab: WorkHubTab) => void;
20
+ closeTab: (tabId: string) => void;
21
+ openTabMenu: (e: MouseEvent<HTMLDivElement>, tab: WorkHubTab) => Promise<void>;
19
22
  updateArgs: (tabId: string, args: Partial<Args>) => void;
20
23
  }
24
+ export {};
@@ -41,8 +41,11 @@ export class WorkHubItem extends Logger {
41
41
  renderArgs: args,
42
42
  });
43
43
  };
44
- openTabMenu = (e, tab) => {
45
- const customSections = this.customMenuActionsResolver(tab);
44
+ closeTab = (tabId) => {
45
+ ModuleFE_WorkHub.tabs.remove(tabId);
46
+ };
47
+ openTabMenu = async (e, tab) => {
48
+ const customSections = await this.customMenuActionsResolver(tab);
46
49
  Component_WorkHubActionMenu.show(e, {
47
50
  tabId: tab.id,
48
51
  customSections
@@ -8,12 +8,14 @@ declare class ModuleFE_WorkHub_Class extends Module {
8
8
  private readonly _workHubItemMap;
9
9
  private readonly storage_tabs;
10
10
  private readonly storage_tabStack;
11
+ private postTabAdditionCallback;
11
12
  private tabStack;
12
13
  tabs: ModuleFE_WorkHub_TabActions;
13
14
  workHubItem: {
14
15
  register: (item: WorkHubItem<any>) => void;
15
16
  getByKey: (key: string) => WorkHubItem<any>;
16
17
  };
18
+ setPostTabAdditionCallback: (callback: VoidFunction) => VoidFunction;
17
19
  }
18
20
  export declare const ModuleFE_WorkHub: ModuleFE_WorkHub_Class;
19
21
  export {};
@@ -14,16 +14,17 @@ class ModuleFE_WorkHub_Class extends Module {
14
14
  _workHubItemMap;
15
15
  storage_tabs = new StorageKey('work-hub__tabs');
16
16
  storage_tabStack = new StorageKey('work-hub__tab-stack');
17
+ postTabAdditionCallback = undefined;
17
18
  //######################### Internal Methods #########################
18
19
  tabStack = {
19
20
  push: (tabId) => {
20
21
  this.tabStack.pop(tabId);
21
22
  this._tabStack.push(tabId);
22
- this.storage_tabStack.set(this._tabStack);
23
+ this.storage_tabStack.set([...this._tabStack]);
23
24
  },
24
25
  pop: (tabId) => {
25
26
  removeItemFromArray(this._tabStack, tabId);
26
- this.storage_tabStack.set(this._tabStack);
27
+ this.storage_tabStack.set([...this._tabStack]);
27
28
  },
28
29
  };
29
30
  //######################### Public Methods #########################
@@ -45,6 +46,7 @@ class ModuleFE_WorkHub_Class extends Module {
45
46
  if (setAsSelected)
46
47
  this.tabStack.push(tab.id);
47
48
  dispatch_OnWorkHubTabsUpdated.dispatchUI();
49
+ this.postTabAdditionCallback?.();
48
50
  }
49
51
  },
50
52
  remove: (tabId) => {
@@ -81,5 +83,6 @@ class ModuleFE_WorkHub_Class extends Module {
81
83
  return this._workHubItemMap[key];
82
84
  }
83
85
  };
86
+ setPostTabAdditionCallback = (callback) => this.postTabAdditionCallback = callback;
84
87
  }
85
88
  export const ModuleFE_WorkHub = new ModuleFE_WorkHub_Class();
@@ -14,5 +14,7 @@ export declare class Component_WorkHubActionMenu extends ComponentSync<Props> {
14
14
  render(): import("react/jsx-runtime").JSX.Element[];
15
15
  private render_Section;
16
16
  private render_Action;
17
+ private render_ActionButton;
18
+ private render_ActionWithInner;
17
19
  }
18
20
  export {};
@@ -1,7 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Button, ComponentSync, LL_V_L, ModuleFE_MouseInteractivity, mouseInteractivity_PopUp } from '@nu-art/thunderstorm-frontend';
2
+ import { _className, Button, ComponentSync, LL_H_C, LL_V_L, ModuleFE_MouseInteractivity, mouseInteractivity_PopUp } from '@nu-art/thunderstorm-frontend';
3
3
  import { ModuleFE_WorkHub } from '../../_module/index.js';
4
4
  import './Component_WorkHubActionMenu.scss';
5
+ import { TS_Icons } from '@nu-art/ts-styles';
6
+ import { generateHex } from '@nu-art/ts-common';
5
7
  export class Component_WorkHubActionMenu extends ComponentSync {
6
8
  // ######################## Static ########################
7
9
  static show = (e, props) => {
@@ -39,9 +41,22 @@ export class Component_WorkHubActionMenu extends ComponentSync {
39
41
  return _jsxs(LL_V_L, { className: 'action-menu__section', children: [!!section.label?.length && _jsx("div", { className: 'action-menu__section-label', children: section.label }), section.actions.map(this.render_Action)] }, index);
40
42
  };
41
43
  render_Action = (action, index) => {
44
+ if (action.action)
45
+ return this.render_ActionButton(action, index);
46
+ return this.render_ActionWithInner(action, index);
47
+ };
48
+ render_ActionButton = (action, index) => {
42
49
  return _jsx(Button, { variant: 'work-hub-menu-action', disabled: action.disabled, onClick: async () => {
43
50
  await action.action();
44
51
  this.closeMenu();
45
52
  }, children: action.label }, index);
46
53
  };
54
+ render_ActionWithInner = (action, index) => {
55
+ const hasInner = !!action.innerActions?.length;
56
+ const renderInner = hasInner && !action.disabled;
57
+ const anchorId = generateHex(4);
58
+ const style = { '--anchor-id': anchorId };
59
+ const className = _className('work-hub-menu-action-with-inner', action.disabled && 'disabled');
60
+ return _jsxs("div", { className: className, style: style, children: [_jsxs(LL_H_C, { className: 'work-hub-menu-action', children: [_jsx("div", { className: 'work-hub-menu-action__label', children: action.label }), hasInner && _jsx(TS_Icons.treeCollapse.component, {})] }), renderInner && _jsx(LL_V_L, { className: 'work-hub-menu-action__inner-actions', children: action.innerActions?.map(this.render_Action) })] }, index);
61
+ };
47
62
  }
@@ -6,7 +6,6 @@
6
6
  box-shadow: 0 0 15px 0 #BAB8E6;
7
7
  padding: 4px;
8
8
  border-radius: 10px;
9
- overflow: hidden;
10
9
 
11
10
  .ts-button[data-variant='work-hub-menu-action'] {
12
11
  --ts-button--content-color: #{S.black(1)};
@@ -37,13 +36,88 @@
37
36
  }
38
37
  }
39
38
 
39
+ .work-hub-menu-action-with-inner {
40
+ height: 24px;
41
+ width: 100%;
42
+ position: relative;
43
+
44
+ & > .work-hub-menu-action {
45
+ justify-content: space-between;
46
+ height: 100%;
47
+ width: 100%;
48
+ gap: 8px;
49
+ padding-left: 6px;
50
+ border-radius: 6px;
51
+ transition: background 300ms ease-out;
52
+
53
+ .work-hub-menu-action__label {
54
+ color: S.black(1);
55
+ font: {
56
+ size: 14px;
57
+ weight: 500;
58
+ }
59
+ }
60
+
61
+ .icon--wrapper {
62
+ @include S.color-svg(S.black(1));
63
+ }
64
+ }
65
+
66
+ & > .work-hub-menu-action__inner-actions {
67
+ width: 300px;
68
+ position: absolute;
69
+ top: -4px;
70
+ right: calc(-100% - 10px);
71
+ border: 1px solid #333;
72
+ box-shadow: 0 0 15px 0 #BAB8E6;
73
+ background: #fff;
74
+ padding: 4px;
75
+ gap: 4px;
76
+ border-radius: 6px;
77
+ opacity: 0;
78
+ pointer-events: none;
79
+ }
80
+
81
+ &:hover {
82
+ & > .work-hub-menu-action {
83
+ background: S.dark-blue(6);
84
+ }
85
+
86
+ & > .work-hub-menu-action__inner-actions {
87
+ opacity: 1;
88
+ pointer-events: unset;
89
+ }
90
+ }
91
+
92
+ &.disabled {
93
+ & > .work-hub-menu-action {
94
+ background: transparent;
95
+
96
+ .work-hub-menu-action__label {
97
+ color: S.black(5);
98
+ }
99
+
100
+ .icon--wrapper {
101
+ @include S.color-svg(S.black(5));
102
+ }
103
+ }
104
+ }
105
+ }
106
+
40
107
  .action-menu__section {
41
108
  width: 100%;
42
109
  padding: 4px 0;
43
110
  gap: 4px;
44
111
 
45
112
  .action-menu__section-label {
46
-
113
+ color: S.black(1);
114
+ height: 24px;
115
+ padding: 0 6px;
116
+ line-height: 24px;
117
+ font: {
118
+ size: 12px;
119
+ weight: 800;
120
+ }
47
121
  }
48
122
 
49
123
  &:not(:last-child) {
@@ -1,7 +1,8 @@
1
1
  export type WorkHubItem_MenuAction = {
2
2
  label: string;
3
- action: () => (Promise<void> | void);
3
+ action?: () => (Promise<void> | void);
4
4
  disabled?: boolean;
5
+ innerActions?: WorkHubItem_MenuAction[];
5
6
  };
6
7
  export type WorkHubItem_MenuSection = {
7
8
  label?: string;
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { createRef, useEffect } from 'react';
3
3
  import { ModuleFE_WorkHub } from '../../_module/index.js';
4
4
  import './Component_WorkHub_TabContent.scss';
5
- import { AwaitModules } from '@nu-art/thunderstorm-frontend';
5
+ import { AwaitModules, TS_ErrorBoundary } from '@nu-art/thunderstorm-frontend';
6
6
  export const Component_WorkHub_TabContent = (props) => {
7
7
  const item = ModuleFE_WorkHub.workHubItem.getByKey(props.tab.itemKey);
8
8
  const ref = createRef();
@@ -10,6 +10,6 @@ export const Component_WorkHub_TabContent = (props) => {
10
10
  ref.current?.focus();
11
11
  });
12
12
  if (item.modulesToAwait?.length)
13
- return _jsx("div", { className: 'c__work-hub-tab-content', ref: ref, tabIndex: 0, children: _jsx(AwaitModules, { modules: item.modulesToAwait, children: item.renderer(item, props.tab.renderArgs) }) });
14
- return _jsx("div", { className: 'c__work-hub-tab-content', ref: ref, tabIndex: 0, children: item.renderer(item, props.tab.renderArgs) });
13
+ return _jsx("div", { className: 'c__work-hub-tab-content', ref: ref, tabIndex: 0, children: _jsx(AwaitModules, { modules: item.modulesToAwait, children: _jsx(TS_ErrorBoundary, { children: item.renderer(item, props.tab.id, props.tab.renderArgs) }) }) });
14
+ return _jsx("div", { className: 'c__work-hub-tab-content', ref: ref, tabIndex: 0, children: _jsx(TS_ErrorBoundary, { children: item.renderer(item, props.tab.id, props.tab.renderArgs) }) });
15
15
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nu-art/work-hub-frontend",
3
- "version": "0.400.7",
3
+ "version": "0.400.13",
4
4
  "description": "TS WorkHub Frontend",
5
5
  "keywords": [
6
6
  "TacB0sS",
@@ -21,11 +21,11 @@
21
21
  "linkDirectory": true
22
22
  },
23
23
  "dependencies": {
24
- "@nu-art/work-hub-shared": "0.400.7",
25
- "@nu-art/ts-common": "0.400.7",
26
- "@nu-art/ts-styles": "0.400.7",
27
- "@nu-art/thunderstorm-shared": "0.400.7",
28
- "@nu-art/thunderstorm-frontend": "0.400.7",
24
+ "@nu-art/work-hub-shared": "0.400.13",
25
+ "@nu-art/ts-common": "0.400.13",
26
+ "@nu-art/ts-styles": "0.400.13",
27
+ "@nu-art/thunderstorm-shared": "0.400.13",
28
+ "@nu-art/thunderstorm-frontend": "0.400.13",
29
29
  "react": "^18.0.0"
30
30
  },
31
31
  "devDependencies": {
@@ -43,6 +43,10 @@
43
43
  "./ui": {
44
44
  "types": "./_ui/index.d.ts",
45
45
  "import": "./_ui/index.js"
46
+ },
47
+ "./modules": {
48
+ "types": "./_module/ModuleFE_WorkHub/ModuleFE_WorkHub.d.ts",
49
+ "import": "./_module/ModuleFE_WorkHub/ModuleFE_WorkHub.js"
46
50
  }
47
51
  }
48
52
  }