@finsemble/finsemble-ui 6.4.0-beta.2 → 6.4.0
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.
- package/package.json +1 -1
- package/react/components/windowTitleBar/components/windowTitle.d.ts +4 -4
- package/react/components/windowTitleBar/components/windowTitle.js +95 -50
- package/react/components/windowTitleBar/components/windowTitle.js.map +1 -1
- package/react/types/windowTitleBar.d.ts +2 -1
- package/react/types/windowTitleBar.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { WindowIdentifier } from "@finsemble/finsemble-core";
|
|
1
2
|
import { Component } from "react";
|
|
2
3
|
declare type TitleProps = {
|
|
3
|
-
windowIdentifier:
|
|
4
|
+
windowIdentifier: WindowIdentifier;
|
|
4
5
|
onUpdate?: Function;
|
|
5
6
|
titleWidth?: number;
|
|
6
7
|
onClick?: () => void;
|
|
@@ -11,10 +12,9 @@ declare type TitleState = {
|
|
|
11
12
|
windowName?: string;
|
|
12
13
|
};
|
|
13
14
|
export declare class Title extends Component<TitleProps, TitleState> {
|
|
15
|
+
tabTitleChangedStoreSubscription: any;
|
|
14
16
|
constructor(props: TitleProps);
|
|
15
|
-
|
|
16
|
-
handleTitleChange(title: string, isRemoteCall?: boolean): Promise<void>;
|
|
17
|
-
handleTabTitleChange(error: any, response: any): void;
|
|
17
|
+
updateTitle(): Promise<void>;
|
|
18
18
|
componentDidMount(): void;
|
|
19
19
|
componentDidUpdate(): void;
|
|
20
20
|
componentWillUnmount(): void;
|
|
@@ -2,15 +2,41 @@ import React, { Component } from "react";
|
|
|
2
2
|
import { Icon } from "../../icon/Icon";
|
|
3
3
|
import { iconFromConfig } from "../../icon/Icon";
|
|
4
4
|
import { Store } from "../stores/windowTitleBarStore";
|
|
5
|
+
const WINDOW_TAB_TITLE_STORE = "window-tab-title";
|
|
6
|
+
const FIELD_NAME_PERSISTED_TITLE = "persistedTitle";
|
|
7
|
+
const getWindowTabNameStore = () => new Promise((resolve, reject) => {
|
|
8
|
+
FSBL.Clients.DistributedStoreClient.createGlobalStore({ store: WINDOW_TAB_TITLE_STORE }, (err, store) => {
|
|
9
|
+
if (!!err || !store) {
|
|
10
|
+
reject(err || "Could not get store");
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
resolve(store);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
const getCorrespondingFinsembleWindow = async (windowIdentifier) => (await FSBL.FinsembleWindow.getInstance(windowIdentifier)).wrap;
|
|
5
18
|
function EditTab(props) {
|
|
6
19
|
const [editingTitle, setEditingTitle] = React.useState(false);
|
|
7
20
|
const [clickTimeout, setClickTimeout] = React.useState(undefined);
|
|
8
21
|
const inputEl = React.useRef(null);
|
|
9
22
|
const updateTabTitle = (e) => {
|
|
10
23
|
const title = e.target.value;
|
|
11
|
-
|
|
12
|
-
props.
|
|
13
|
-
|
|
24
|
+
getWindowTabNameStore()
|
|
25
|
+
.then((store) => store.setValue({ field: props.windowIdentifier.windowName, value: title }))
|
|
26
|
+
.then(() => getCorrespondingFinsembleWindow(props.windowIdentifier))
|
|
27
|
+
.then((win) => new Promise((resolve, reject) => {
|
|
28
|
+
FSBL.Clients.Logger.debug(`Setting component state "${FIELD_NAME_PERSISTED_TITLE}" with value "${title}"`);
|
|
29
|
+
win.setComponentState({ field: FIELD_NAME_PERSISTED_TITLE, value: title }, (err, res) => {
|
|
30
|
+
if (!!err) {
|
|
31
|
+
reject(err);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
resolve(res);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}))
|
|
38
|
+
.catch((err) => FSBL.Clients.Logger.error("Error persisting tab title via EditTab", err))
|
|
39
|
+
.finally(() => setEditingTitle(false));
|
|
14
40
|
};
|
|
15
41
|
const beginEditing = async () => {
|
|
16
42
|
var _a, _b;
|
|
@@ -52,61 +78,73 @@ function EditTab(props) {
|
|
|
52
78
|
}
|
|
53
79
|
export class Title extends Component {
|
|
54
80
|
constructor(props) {
|
|
55
|
-
var _a;
|
|
81
|
+
var _a, _b;
|
|
56
82
|
super(props);
|
|
57
83
|
this.state = {
|
|
58
|
-
title: document.title,
|
|
84
|
+
title: ((_a = props.windowIdentifier) === null || _a === void 0 ? void 0 : _a.windowName) || document.title,
|
|
59
85
|
icon: null,
|
|
60
|
-
windowName: (
|
|
86
|
+
windowName: (_b = props.windowIdentifier) === null || _b === void 0 ? void 0 : _b.windowName,
|
|
61
87
|
};
|
|
62
|
-
this.
|
|
63
|
-
this.
|
|
88
|
+
this.updateTitle = this.updateTitle.bind(this);
|
|
89
|
+
this.updateTitle();
|
|
64
90
|
}
|
|
65
|
-
async
|
|
66
|
-
var _a
|
|
67
|
-
if (!((_a = this.props) === null || _a === void 0 ? void 0 : _a.windowIdentifier))
|
|
91
|
+
async updateTitle() {
|
|
92
|
+
var _a;
|
|
93
|
+
if (!((_a = this.props) === null || _a === void 0 ? void 0 : _a.windowIdentifier)) {
|
|
68
94
|
return;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
95
|
+
}
|
|
96
|
+
let store = await getWindowTabNameStore();
|
|
97
|
+
store.getValue(this.props.windowIdentifier.windowName, async (err, res) => {
|
|
98
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
99
|
+
if (!!err) {
|
|
100
|
+
FSBL.Clients.Logger.error(`Error getting the tab name from the store "${WINDOW_TAB_TITLE_STORE}" for the window "${this.props.windowIdentifier.windowName}"`, err);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const tabWindow = await getCorrespondingFinsembleWindow(this.props.windowIdentifier);
|
|
104
|
+
const { data } = await tabWindow.getOptions();
|
|
105
|
+
let title = res;
|
|
106
|
+
if (!title) {
|
|
107
|
+
FSBL.Clients.Logger.debug(`No stored tab tile for "${this.props.windowIdentifier.windowName}"; falling back to code-based derivation`);
|
|
108
|
+
const { options } = FSBL.Clients.WindowClient;
|
|
109
|
+
const windowTitleBarConfig = (_b = (_a = options === null || options === void 0 ? void 0 : options.customData) === null || _a === void 0 ? void 0 : _a.foreign) === null || _b === void 0 ? void 0 : _b.components["Window Manager"];
|
|
110
|
+
const displayName = ((_f = (_e = (_d = (_c = data === null || data === void 0 ? void 0 : data.customData) === null || _c === void 0 ? void 0 : _c.appDConfig) === null || _d === void 0 ? void 0 : _d.manifest) === null || _e === void 0 ? void 0 : _e.component) === null || _f === void 0 ? void 0 : _f.displayName) ||
|
|
111
|
+
((_h = (_g = data === null || data === void 0 ? void 0 : data.customData) === null || _g === void 0 ? void 0 : _g.component) === null || _h === void 0 ? void 0 : _h.displayName);
|
|
112
|
+
title = displayName || FSBL.Clients.WindowClient.title || (windowTitleBarConfig === null || windowTitleBarConfig === void 0 ? void 0 : windowTitleBarConfig.title) || tabWindow.name || "";
|
|
77
113
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
114
|
+
const icon = iconFromConfig((_l = (_k = (_j = data === null || data === void 0 ? void 0 : data.customData) === null || _j === void 0 ? void 0 : _j.foreign) === null || _k === void 0 ? void 0 : _k.components) === null || _l === void 0 ? void 0 : _l.Toolbar, title);
|
|
115
|
+
tabWindow.getComponentState({ field: FIELD_NAME_PERSISTED_TITLE }, (error, persistedTitle) => {
|
|
116
|
+
if (persistedTitle) {
|
|
117
|
+
title = persistedTitle;
|
|
118
|
+
}
|
|
119
|
+
FSBL.Clients.Logger.debug(`Setting tab title ${title} for window ${this.props.windowIdentifier.windowName}`);
|
|
120
|
+
this.setState({
|
|
121
|
+
title: title,
|
|
122
|
+
icon: icon,
|
|
123
|
+
});
|
|
81
124
|
});
|
|
82
125
|
});
|
|
83
126
|
}
|
|
84
|
-
async handleTitleChange(title, isRemoteCall = false) {
|
|
85
|
-
this.setState({
|
|
86
|
-
title: title,
|
|
87
|
-
});
|
|
88
|
-
if (isRemoteCall) {
|
|
89
|
-
const { wrap: win } = await FSBL.FinsembleWindow.getInstance(this.props.windowIdentifier);
|
|
90
|
-
win.setComponentState({ field: "persistedTitle", value: title });
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
document.title = title;
|
|
94
|
-
finsembleWindow.setComponentState({ field: "persistedTitle", value: title });
|
|
95
|
-
FSBL.Clients.RouterClient.transmit("tab-title-changed", { title: title, identifier: finsembleWindow.identifier });
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
handleTabTitleChange(error, response) {
|
|
99
|
-
var _a;
|
|
100
|
-
if (this.props.windowIdentifier.windowName != ((_a = finsembleWindow.identifier) === null || _a === void 0 ? void 0 : _a.windowName) &&
|
|
101
|
-
this.props.windowIdentifier.windowName == response.data.identifier.windowName &&
|
|
102
|
-
response.data.identifier.windowName != this.state.windowName) {
|
|
103
|
-
this.handleTitleChange(response.data.title, true);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
127
|
componentDidMount() {
|
|
107
|
-
this.
|
|
108
|
-
|
|
109
|
-
|
|
128
|
+
this.updateTitle();
|
|
129
|
+
if (!!this.props.windowIdentifier) {
|
|
130
|
+
getWindowTabNameStore().then((store) => {
|
|
131
|
+
this.tabTitleChangedStoreSubscription = (err, res) => {
|
|
132
|
+
if (!!err) {
|
|
133
|
+
FSBL.Clients.Logger.warn(`Listener error for store "${WINDOW_TAB_TITLE_STORE}" for field "${this.props.windowIdentifier.windowName}"`, err);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
FSBL.Clients.Logger.debug(`Store "${WINDOW_TAB_TITLE_STORE}" notified of new title "${res.name}" for window "${res.field}"`);
|
|
137
|
+
this.updateTitle();
|
|
138
|
+
};
|
|
139
|
+
store.addListener({ field: this.props.windowIdentifier.windowName }, this.tabTitleChangedStoreSubscription, (subErr, subRes) => {
|
|
140
|
+
if (!!subErr) {
|
|
141
|
+
FSBL.Clients.Logger.warn(`Could not add listener to store "${WINDOW_TAB_TITLE_STORE}" for field "${this.props.windowIdentifier.windowName}"`, subErr);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
FSBL.Clients.Logger.debug(`Added listener to store "${WINDOW_TAB_TITLE_STORE}" for field "${this.props.windowIdentifier.windowName}"`);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
}
|
|
110
148
|
}
|
|
111
149
|
componentDidUpdate() {
|
|
112
150
|
if (typeof this.props.onUpdate === "function") {
|
|
@@ -114,14 +152,21 @@ export class Title extends Component {
|
|
|
114
152
|
}
|
|
115
153
|
}
|
|
116
154
|
componentWillUnmount() {
|
|
117
|
-
|
|
118
|
-
|
|
155
|
+
getWindowTabNameStore().then((store) => {
|
|
156
|
+
store.removeListener({ field: this.props.windowIdentifier.windowName }, this.tabTitleChangedStoreSubscription, (subErr, subRes) => {
|
|
157
|
+
if (!!subErr) {
|
|
158
|
+
FSBL.Clients.Logger.warn(`Could not remove listener from store "${WINDOW_TAB_TITLE_STORE}" for field "${this.props.windowIdentifier.windowName}"`, subErr);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
FSBL.Clients.Logger.debug(`Removed listener to store "${WINDOW_TAB_TITLE_STORE}" for field "${this.props.windowIdentifier.windowName}"`);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
119
164
|
}
|
|
120
165
|
render() {
|
|
121
166
|
var _a;
|
|
122
167
|
const { titleWidth } = this.props;
|
|
123
168
|
const style = titleWidth ? { width: titleWidth } : {};
|
|
124
|
-
return (React.createElement(EditTab, { tabWidth: titleWidth, setActiveTab: (_a = this === null || this === void 0 ? void 0 : this.props) === null || _a === void 0 ? void 0 : _a.onClick,
|
|
169
|
+
return (React.createElement(EditTab, { tabWidth: titleWidth, setActiveTab: (_a = this === null || this === void 0 ? void 0 : this.props) === null || _a === void 0 ? void 0 : _a.onClick, title: this.state.title, windowIdentifier: this.props.windowIdentifier },
|
|
125
170
|
React.createElement("div", { className: "fsbl-tab-title", style: style },
|
|
126
171
|
this.state.icon && React.createElement(Icon, Object.assign({}, this.state.icon)),
|
|
127
172
|
React.createElement("div", { className: "title-text" }, this.state.title))));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"windowTitle.js","sourceRoot":"","sources":["../../../../src/components/windowTitleBar/components/windowTitle.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { Component } from \"react\";\nimport { EditTabProps } from \"../../../types/windowTitleBar\";\nimport { Icon } from \"../../icon/Icon\";\nimport { iconFromConfig } from \"../../icon/Icon\";\nimport { Store } from \"../stores/windowTitleBarStore\";\n\ntype TitleProps = {\n\twindowIdentifier: any;\n\tonUpdate?: Function;\n\ttitleWidth?: number;\n\tonClick?: () => void;\n};\n\ntype TitleState = {\n\ttitle: string | undefined;\n\ticon: any;\n\twindowName?: string;\n};\n\n/**\n * The wrapper component for tab renaming\n * @param {*} props\n */\nfunction EditTab(props: EditTabProps) {\n\tconst [editingTitle, setEditingTitle] = React.useState(false);\n\tconst [clickTimeout, setClickTimeout] = React.useState<NodeJS.Timeout | undefined>(undefined);\n\tconst inputEl = React.useRef<HTMLInputElement>(null);\n\n\tconst updateTabTitle = (e: React.KeyboardEvent<HTMLInputElement> | React.FocusEvent<HTMLInputElement>) => {\n\t\tconst title = (e.target as HTMLInputElement).value;\n\t\t// notify that title was updated\n\t\tif (props.onTitleChange) props.onTitleChange(title);\n\t\tsetEditingTitle(false);\n\t};\n\n\tconst beginEditing = async () => {\n\t\tawait setEditingTitle(true);\n\t\tawait inputEl?.current?.focus();\n\t\tif (inputEl?.current) {\n\t\t\tinputEl.current.value = props.title ?? \"\";\n\t\t}\n\t};\n\n\tconst clickHandler = () => {\n\t\tconst allowTabEditing = Store.getValue(\"allowTabEditing\");\n\n\t\tif (clickTimeout) {\n\t\t\t// double click\n\t\t\tif (allowTabEditing) {\n\t\t\t\tbeginEditing();\n\t\t\t}\n\t\t} else if (!editingTitle) {\n\t\t\t// single click\n\t\t\tlet timeout = setTimeout(() => {\n\t\t\t\tclearTimeout(clickTimeout);\n\t\t\t\tsetClickTimeout(undefined);\n\t\t\t}, 500);\n\t\t\tsetClickTimeout(timeout);\n\t\t\tif (props.setActiveTab) props.setActiveTab();\n\t\t}\n\t};\n\n\tconst blurHandler = (e: React.FocusEvent<HTMLInputElement>) => {\n\t\tupdateTabTitle(e);\n\t};\n\n\tconst keyDownHandler = (e: React.KeyboardEvent<HTMLInputElement>) => {\n\t\te.key === \"Enter\" && updateTabTitle(e);\n\t};\n\n\treturn (\n\t\t<div\n\t\t\tclassName=\"fsbl-tab-editor\"\n\t\t\t//We can't use Click and Dblclick events together cause for one dblclick fires two click events which close title editor.\n\t\t\t//Workaround with setTimeout should resolve this behaviour.\n\t\t\tonClick={clickHandler}\n\t\t>\n\t\t\t{editingTitle ? (\n\t\t\t\t<div className=\"fsbl-tab fsbl-active-tab\" style={{ width: props.tabWidth || \"auto\" }}>\n\t\t\t\t\t{/* workaround to disable tab dragging in the edit mode */}\n\t\t\t\t\t<div\n\t\t\t\t\t\tdraggable={true}\n\t\t\t\t\t\tonDragStart={(e) => {\n\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tref={inputEl}\n\t\t\t\t\t\t\tonBlur={blurHandler}\n\t\t\t\t\t\t\tonKeyDown={keyDownHandler}\n\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\tclassName=\"tab__input\"\n\t\t\t\t\t\t\tmaxLength={32}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\tprops.children\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\n/*\n * Description how stacked window tabs work.\n *\n * The simplest case - when you have only 2 tabs. In that case you will actually have 2 windows and 4 tabs.\n * Lets call them as: window 1 - w1, window 2 - w2, tab 1 from window 1 - w1_t1, tab 2 from window 1 - w1_t2, for tabs from window 2 - w2_t1 and w2_t2.\n * When you switch tabs you activate w1 or w2 with active tab w1_t1 or w2_t2 coresponderly.\n * Tabs w1_t2 and w2_t1 are inactive. They needed only for rendering. I call them as remote tabs, cause their titles must be synchronized with active tabs titles.\n * Thus when you rename active tab (w1_t1), the corresponding remote tab (w2_t1) should be updated automatically.\n */\n\nexport class Title extends Component<TitleProps, TitleState> {\n\tconstructor(props: TitleProps) {\n\t\tsuper(props);\n\t\tthis.state = {\n\t\t\ttitle: document.title,\n\t\t\ticon: null,\n\t\t\t// save active window name\n\t\t\twindowName: finsembleWindow.identifier?.windowName,\n\t\t};\n\n\t\tthis.handleTitleChange = this.handleTitleChange.bind(this);\n\t\tthis.handleTabTitleChange = this.handleTabTitleChange.bind(this);\n\t}\n\n\tasync initializeTitle() {\n\t\t// happens when a stacked window loads\n\t\tif (!this.props?.windowIdentifier) return;\n\n\t\tconst { wrap: win } = await FSBL.FinsembleWindow.getInstance(this.props.windowIdentifier);\n\t\tconst windowManagerConfig = win.windowOptions.customData?.foreign.components[\"Window Manager\"];\n\t\tconst { data } = await win.getOptions();\n\t\tlet title = windowManagerConfig?.title || (data as any)?.title || finsembleWindow.name || \"\";\n\t\tconst icon = iconFromConfig(data?.customData?.foreign?.components?.Toolbar, title);\n\t\twin.getComponentState({ field: \"persistedTitle\" }, (error: any, persistedTitle: any) => {\n\t\t\tif (persistedTitle) {\n\t\t\t\ttitle = persistedTitle;\n\t\t\t}\n\t\t\tthis.setState({\n\t\t\t\ttitle: title,\n\t\t\t\ticon: icon,\n\t\t\t});\n\t\t});\n\t}\n\n\tasync handleTitleChange(title: string, isRemoteCall = false) {\n\t\tthis.setState({\n\t\t\ttitle: title,\n\t\t});\n\n\t\t// the remote tab was renamed\n\t\tif (isRemoteCall) {\n\t\t\tconst { wrap: win } = await FSBL.FinsembleWindow.getInstance(this.props.windowIdentifier);\n\t\t\twin.setComponentState({ field: \"persistedTitle\", value: title });\n\t\t}\n\t\t// the active tab was renamed\n\t\telse {\n\t\t\tdocument.title = title;\n\t\t\tfinsembleWindow.setComponentState({ field: \"persistedTitle\", value: title });\n\t\t\t// notify that tab was renamed\n\t\t\tFSBL.Clients.RouterClient.transmit(\"tab-title-changed\", { title: title, identifier: finsembleWindow.identifier });\n\t\t}\n\t}\n\n\thandleTabTitleChange(error: any, response: any) {\n\t\t// Update title only for corrsponding remote tab.\n\t\tif (\n\t\t\tthis.props.windowIdentifier.windowName != finsembleWindow.identifier?.windowName &&\n\t\t\tthis.props.windowIdentifier.windowName == response.data.identifier.windowName &&\n\t\t\tresponse.data.identifier.windowName != this.state.windowName\n\t\t) {\n\t\t\t// update tab name when remote tab was renamed\n\t\t\tthis.handleTitleChange(response.data.title, true);\n\t\t}\n\t}\n\n\tcomponentDidMount() {\n\t\tthis.initializeTitle();\n\t\t// subscrite on remote tab-title-changed event\n\t\tFSBL.Clients.RouterClient.addListener(\"tab-title-changed\", this.handleTabTitleChange);\n\n\t\t// While spawning a window we set document.title multiple times (set a short window title for example). This listener should reinitialize title if it has been changed.\n\t\tfinsembleWindow.addEventListener(\"title-changed\", this.initializeTitle);\n\t}\n\n\t// Triggers a re-rendering of the drag handle in the title bar.\n\tcomponentDidUpdate() {\n\t\tif (typeof this.props.onUpdate === \"function\") {\n\t\t\tthis.props.onUpdate();\n\t\t}\n\t}\n\n\tcomponentWillUnmount() {\n\t\tFSBL.Clients.RouterClient.removeListener(\"tab-title-changed\", this.handleTabTitleChange);\n\t\tfinsembleWindow.removeEventListener(\"title-changed\", this.initializeTitle);\n\t}\n\n\trender() {\n\t\tconst { titleWidth } = this.props;\n\t\tconst style = titleWidth ? { width: titleWidth } : {};\n\t\treturn (\n\t\t\t<EditTab\n\t\t\t\ttabWidth={titleWidth}\n\t\t\t\tsetActiveTab={this?.props?.onClick}\n\t\t\t\tonTitleChange={this.handleTitleChange}\n\t\t\t\ttitle={this.state.title}\n\t\t\t>\n\t\t\t\t<div className=\"fsbl-tab-title\" style={style}>\n\t\t\t\t\t{this.state.icon && <Icon {...this.state.icon} />}\n\t\t\t\t\t<div className=\"title-text\">{this.state.title}</div>\n\t\t\t\t</div>\n\t\t\t</EditTab>\n\t\t);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"windowTitle.js","sourceRoot":"","sources":["../../../../src/components/windowTitleBar/components/windowTitle.tsx"],"names":[],"mappings":"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","sourcesContent":["import { FinsembleWindow, WindowIdentifier } from \"@finsemble/finsemble-core\";\n// TODO: Circular reference during \"yarn dev\"\n// This error is referenced as \"WT01\" in this file; search for the string \"WT01\" and uncomment appropriate changes\n// import { StandardError, StoreModel } from \"@finsemble/finsemble-core/types/types\"; // WT01 - uncomment to import\nimport React, { Component } from \"react\";\nimport { EditTabProps } from \"../../../types/windowTitleBar\";\nimport { Icon } from \"../../icon/Icon\";\nimport { iconFromConfig } from \"../../icon/Icon\";\nimport { Store } from \"../stores/windowTitleBarStore\";\n\n/**\n * TAB TITLES: HOW DO THEY WORK?\n *\n * Each component, when stacked, will have several tab titles. For each component, there is a window. For each window, there are 2 tab titles per component.\n *\n * Whichever component is \"active\" will render all tabs - exactly one \"active\" tab and n-1 \"inactive\" tabs (where n is the number of components in the stack). When\n * the active component is changed (via a click, for example), then the visible window becomes the window associated with the active component.\n *\n * Tab titles may change at any time, and for a number of reasons. For example, the component may execute \"document.title='...some title'\". Or perhaps the tab title has\n * been edited by the user. In order to account for all title changes, the following flow is used:\n * *something* updates document.title\n * The WindowClient for the component will notice the title change and send a router message (via FinsembleWindow.setTitle) with a topic representitive of the windowName\n * BaseWindow listens to router changes on the same topic and updates a DistributedStore dedicated to tab names\n * The tab components all subscribe to the DistributedStore dedicated to tab names and will update the title accordingly\n *\n * This is a \"one-way\" operation; that is to say that some code will ultimately alter the DistributedStore and the tab title components will read the changes. While this generally\n * happens with a write to document.title, it can also happen when a user edits the tab title manually. In this case, the component state is altered with a field \"persistedTitle\"\n * whose value is the edited title. At render time, the tab title component will use any value in \"persistedTitle\" as the title, irregardless of any other value.\n *\n * NOTE: A tab may be edited only when it is the active component; ergo the call to \"setComponentState\" is safe.\n */\n\ntype TitleProps = {\n\twindowIdentifier: WindowIdentifier;\n\tonUpdate?: Function;\n\ttitleWidth?: number;\n\tonClick?: () => void;\n};\n\ntype TitleState = {\n\ttitle: string | undefined;\n\ticon: any;\n\twindowName?: string;\n};\n\n// The store name for the distributed store which tracks tab titles\nconst WINDOW_TAB_TITLE_STORE = \"window-tab-title\";\n// The field name to watch for tab title edits\nconst FIELD_NAME_PERSISTED_TITLE = \"persistedTitle\";\n\n/**\n * Gets the store which tracks the tab title for a windowName. This is a distributed store shared by all components.\n *\n * @returns the StoreModel associated with window and tab names\n */\nconst getWindowTabNameStore = () =>\n\tnew Promise<any>(\n\t\t/*<StoreModel>*/ (resolve, reject) => {\n\t\t\t// WT01 - Change the \"any\" generic to \"StoreModel\"\n\t\t\tFSBL.Clients.DistributedStoreClient.createGlobalStore(\n\t\t\t\t{ store: WINDOW_TAB_TITLE_STORE },\n\t\t\t\t(err /*:StandardError*/, store /*:StoreModel*/) => {\n\t\t\t\t\t// WT01 - Define the types for \"err\" and \"store\"\n\t\t\t\t\tif (!!err || !store) {\n\t\t\t\t\t\treject(err || \"Could not get store\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresolve(store);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t);\n\n/**\n * Gets the FinsembleWindow instance associated with the specified <i>windowIdentifier</i>\n *\n * @param windowIdentifier the windowIdentifier for the FinsembleWindow to obtain a reference for\n * @returns a Promise which resolves to the FinsembleWindow associated with the <i>windowIdentifier</i>\n */\nconst getCorrespondingFinsembleWindow = async (windowIdentifier: WindowIdentifier): Promise<FinsembleWindow> =>\n\t(await FSBL.FinsembleWindow.getInstance(windowIdentifier)).wrap;\n\n/**\n * The wrapper component for tab renaming\n * @param {*} props\n */\nfunction EditTab(props: EditTabProps) {\n\tconst [editingTitle, setEditingTitle] = React.useState(false);\n\tconst [clickTimeout, setClickTimeout] = React.useState<NodeJS.Timeout | undefined>(undefined);\n\tconst inputEl = React.useRef<HTMLInputElement>(null);\n\n\tconst updateTabTitle = (e: React.KeyboardEvent<HTMLInputElement> | React.FocusEvent<HTMLInputElement>) => {\n\t\tconst title = (e.target as HTMLInputElement).value;\n\n\t\t// Get the tab name store\n\t\tgetWindowTabNameStore()\n\t\t\t// Set the title for the window identified in the windowName\n\t\t\t.then((store /*: StoreModel*/) => store.setValue({ field: props.windowIdentifier.windowName, value: title })) // WT01 - Type \"store\"\n\t\t\t// Get the FinsembleWindow for the window\n\t\t\t.then(() => getCorrespondingFinsembleWindow(props.windowIdentifier))\n\t\t\t// Set the component state \"persistedTitle\" (which is the edited title)\n\t\t\t.then(\n\t\t\t\t(win) =>\n\t\t\t\t\tnew Promise((resolve, reject) => {\n\t\t\t\t\t\tFSBL.Clients.Logger.debug(`Setting component state \"${FIELD_NAME_PERSISTED_TITLE}\" with value \"${title}\"`);\n\t\t\t\t\t\twin.setComponentState({ field: FIELD_NAME_PERSISTED_TITLE, value: title }, (err, res) => {\n\t\t\t\t\t\t\tif (!!err) {\n\t\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tresolve(res);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})\n\t\t\t)\n\t\t\t.catch((err) => FSBL.Clients.Logger.error(\"Error persisting tab title via EditTab\", err))\n\t\t\t// Stop editing in all cases\n\t\t\t.finally(() => setEditingTitle(false));\n\t};\n\n\tconst beginEditing = async () => {\n\t\tawait setEditingTitle(true);\n\t\tawait inputEl?.current?.focus();\n\t\tif (inputEl?.current) {\n\t\t\tinputEl.current.value = props.title ?? \"\";\n\t\t}\n\t};\n\n\tconst clickHandler = () => {\n\t\tconst allowTabEditing = Store.getValue(\"allowTabEditing\");\n\n\t\tif (clickTimeout) {\n\t\t\t// double click\n\t\t\tif (allowTabEditing) {\n\t\t\t\tbeginEditing();\n\t\t\t}\n\t\t} else if (!editingTitle) {\n\t\t\t// single click\n\t\t\tlet timeout = setTimeout(() => {\n\t\t\t\tclearTimeout(clickTimeout);\n\t\t\t\tsetClickTimeout(undefined);\n\t\t\t}, 500);\n\t\t\tsetClickTimeout(timeout);\n\t\t\tif (props.setActiveTab) props.setActiveTab();\n\t\t}\n\t};\n\n\tconst blurHandler = (e: React.FocusEvent<HTMLInputElement>) => {\n\t\tupdateTabTitle(e);\n\t};\n\n\tconst keyDownHandler = (e: React.KeyboardEvent<HTMLInputElement>) => {\n\t\te.key === \"Enter\" && updateTabTitle(e);\n\t};\n\n\treturn (\n\t\t<div\n\t\t\tclassName=\"fsbl-tab-editor\"\n\t\t\t// We can't use Click and Dblclick events together cause for one dblclick fires two click events which close title editor.\n\t\t\t// Workaround with setTimeout should resolve this behavior.\n\t\t\tonClick={clickHandler}\n\t\t>\n\t\t\t{editingTitle ? (\n\t\t\t\t<div className=\"fsbl-tab fsbl-active-tab\" style={{ width: props.tabWidth || \"auto\" }}>\n\t\t\t\t\t{/* workaround to disable tab dragging in the edit mode */}\n\t\t\t\t\t<div\n\t\t\t\t\t\tdraggable={true}\n\t\t\t\t\t\tonDragStart={(e) => {\n\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tref={inputEl}\n\t\t\t\t\t\t\tonBlur={blurHandler}\n\t\t\t\t\t\t\tonKeyDown={keyDownHandler}\n\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\tclassName=\"tab__input\"\n\t\t\t\t\t\t\tmaxLength={32}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\tprops.children\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\n/*\n * Description how stacked window tabs work.\n *\n * The simplest case - when you have only 2 tabs. In that case you will actually have 2 windows and 4 tabs.\n * Lets call them as: window 1 - w1, window 2 - w2, tab 1 from window 1 - w1_t1, tab 2 from window 1 - w1_t2, for tabs from window 2 - w2_t1 and w2_t2.\n * When you switch tabs you activate w1 or w2 with active tab w1_t1 or w2_t2 correspondingly.\n * Tabs w1_t2 and w2_t1 are inactive. They needed only for rendering. I call them as remote tabs, cause their titles must be synchronized with active tabs titles.\n * Thus when you rename active tab (w1_t1), the corresponding remote tab (w2_t1) should be updated automatically.\n */\n\nexport class Title extends Component<TitleProps, TitleState> {\n\t// The subscription for tab title change events via the DistributedStoreClient\n\ttabTitleChangedStoreSubscription: any;\n\n\tconstructor(props: TitleProps) {\n\t\tsuper(props);\n\t\tthis.state = {\n\t\t\ttitle: props.windowIdentifier?.windowName || document.title,\n\t\t\ticon: null,\n\t\t\t// save active window name\n\t\t\twindowName: props.windowIdentifier?.windowName,\n\t\t};\n\n\t\t// Bind the \"updateTitle\" function (in order to use React component functions)\n\t\tthis.updateTitle = this.updateTitle.bind(this);\n\n\t\t// Invoke \"updateTitle\" to set the initial title\n\t\tthis.updateTitle();\n\t}\n\n\tasync updateTitle() {\n\t\t// happens when a stacked window loads\n\t\tif (!this.props?.windowIdentifier) {\n\t\t\t// Nothing to do here\n\t\t\treturn;\n\t\t}\n\n\t\t// Get the window/tab store\n\t\tlet store = await getWindowTabNameStore(); // WT01 - Type \"store\"\n\t\t// Get the title for the tab represented by the window\n\t\tstore.getValue(this.props.windowIdentifier.windowName, async (err: any, res: any) => {\n\t\t\t// WT01 - Type \"err\" and \"res\"\n\t\t\tif (!!err) {\n\t\t\t\tFSBL.Clients.Logger.error(\n\t\t\t\t\t`Error getting the tab name from the store \"${WINDOW_TAB_TITLE_STORE}\" for the window \"${this.props.windowIdentifier.windowName}\"`,\n\t\t\t\t\terr\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The window represented by this tab title instance\n\t\t\tconst tabWindow = await getCorrespondingFinsembleWindow(this.props.windowIdentifier);\n\t\t\t// \"data\" refers to the options from the window which hosts the component represented by this tab\n\t\t\tconst { data } = await tabWindow.getOptions();\n\n\t\t\t// The title variable\n\t\t\tlet title = res;\n\n\t\t\t// If there is no title then use some logic to derive a title\n\t\t\tif (!title) {\n\t\t\t\t// This code runs when there is no tab name in the store. This happens when a workspace is loaded and\n\t\t\t\t// the workspace has stacked windows. In this case, fallback to:\n\t\t\t\t// 1.) the displayName from the manifest (there are TWO places to look in the manifest!)\n\t\t\t\t// 2.) the title from the WindowClient (this is only correct for the hosting tab!)\n\t\t\t\t// 3.) the title from the window title bar (this is only correct for the hosting tab!)\n\t\t\t\t// 4.) the name of the window which is hosting the window associated with the tab\n\t\t\t\t// 5.) the empty string\n\t\t\t\t//\n\t\t\t\t// Note that in most cases this name is temporarty since most components will update their title with\n\t\t\t\t// a call to \"document.title='...some title!'\"\n\t\t\t\tFSBL.Clients.Logger.debug(\n\t\t\t\t\t`No stored tab tile for \"${this.props.windowIdentifier.windowName}\"; falling back to code-based derivation`\n\t\t\t\t);\n\n\t\t\t\t// \"options\" refers to the options from the window which hosts all the tabs (this will always be the currently active component/window)\n\t\t\t\tconst { options } = FSBL.Clients.WindowClient;\n\t\t\t\tconst windowTitleBarConfig = options?.customData?.foreign?.components[\"Window Manager\"];\n\n\t\t\t\t// Display name is the first candidate for the title\n\t\t\t\tconst displayName =\n\t\t\t\t\t// From the appd manifest\n\t\t\t\t\tdata?.customData?.appDConfig?.manifest?.component?.displayName ||\n\t\t\t\t\t// This seems like a default\n\t\t\t\t\tdata?.customData?.component?.displayName;\n\n\t\t\t\t// The title assignment\n\t\t\t\ttitle = displayName || FSBL.Clients.WindowClient.title || windowTitleBarConfig?.title || tabWindow.name || \"\";\n\t\t\t}\n\n\t\t\t// Get the icon from the config for the TAB window (not the CURRENT window)\n\t\t\tconst icon = iconFromConfig(data?.customData?.foreign?.components?.Toolbar, title);\n\n\t\t\t// Get the component state for THIS component (the tab title)\n\t\t\t// The field \"persistedTitle\" is set when a tab has been edited via EditTab\n\t\t\ttabWindow.getComponentState({ field: FIELD_NAME_PERSISTED_TITLE }, (error: any, persistedTitle: any) => {\n\t\t\t\tif (persistedTitle) {\n\t\t\t\t\ttitle = persistedTitle;\n\t\t\t\t}\n\t\t\t\tFSBL.Clients.Logger.debug(`Setting tab title ${title} for window ${this.props.windowIdentifier.windowName}`);\n\t\t\t\tthis.setState({\n\t\t\t\t\ttitle: title,\n\t\t\t\t\ticon: icon,\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t}\n\n\tcomponentDidMount() {\n\t\tthis.updateTitle();\n\t\t// Subscribe to the DistributedStoreClient (these messages originate from BaseWindow or EventTab - when the DistributedStore has been updated)\n\t\tif (!!this.props.windowIdentifier) {\n\t\t\tgetWindowTabNameStore().then((store) => {\n\t\t\t\t// WT01 - Type \"store\"\n\t\t\t\tthis.tabTitleChangedStoreSubscription = (err: any, res: any) => {\n\t\t\t\t\t// WT01 - Type \"err\" and \"res\"\n\t\t\t\t\tif (!!err) {\n\t\t\t\t\t\t// This is not critical; in the worst case this tab title will be stale\n\t\t\t\t\t\tFSBL.Clients.Logger.warn(\n\t\t\t\t\t\t\t`Listener error for store \"${WINDOW_TAB_TITLE_STORE}\" for field \"${this.props.windowIdentifier.windowName}\"`,\n\t\t\t\t\t\t\terr\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Log a message\n\t\t\t\t\tFSBL.Clients.Logger.debug(\n\t\t\t\t\t\t`Store \"${WINDOW_TAB_TITLE_STORE}\" notified of new title \"${res.name}\" for window \"${res.field}\"`\n\t\t\t\t\t);\n\t\t\t\t\t// Invoke updateTitle\n\t\t\t\t\tthis.updateTitle();\n\t\t\t\t};\n\t\t\t\tstore.addListener(\n\t\t\t\t\t{ field: this.props.windowIdentifier.windowName },\n\t\t\t\t\tthis.tabTitleChangedStoreSubscription,\n\t\t\t\t\t(subErr: any, subRes: any) => {\n\t\t\t\t\t\t// WT01 - Type \"err\", \"res\", \"subErr\" and \"subRes\"\n\t\t\t\t\t\tif (!!subErr) {\n\t\t\t\t\t\t\t// This is not critical; in the worst case this tab title will be stale\n\t\t\t\t\t\t\tFSBL.Clients.Logger.warn(\n\t\t\t\t\t\t\t\t`Could not add listener to store \"${WINDOW_TAB_TITLE_STORE}\" for field \"${this.props.windowIdentifier.windowName}\"`,\n\t\t\t\t\t\t\t\tsubErr\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tFSBL.Clients.Logger.debug(\n\t\t\t\t\t\t\t`Added listener to store \"${WINDOW_TAB_TITLE_STORE}\" for field \"${this.props.windowIdentifier.windowName}\"`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\t}\n\n\t// Triggers a re-rendering of the drag handle in the title bar.\n\tcomponentDidUpdate() {\n\t\tif (typeof this.props.onUpdate === \"function\") {\n\t\t\tthis.props.onUpdate();\n\t\t}\n\t}\n\n\tcomponentWillUnmount() {\n\t\t// Unsubscribe from the window/tab store\n\t\tgetWindowTabNameStore().then((store) => {\n\t\t\t// WT01 - Type \"store\"\n\t\t\tstore.removeListener(\n\t\t\t\t{ field: this.props.windowIdentifier.windowName },\n\t\t\t\tthis.tabTitleChangedStoreSubscription,\n\t\t\t\t(subErr: any, subRes: any) => {\n\t\t\t\t\t// WT01 - Type \"err\", \"res\", \"subErr\" and \"subRes\"\n\t\t\t\t\tif (!!subErr) {\n\t\t\t\t\t\t// This is not critical; the listener could not be removed from the store - this may be a memory leak\n\t\t\t\t\t\tFSBL.Clients.Logger.warn(\n\t\t\t\t\t\t\t`Could not remove listener from store \"${WINDOW_TAB_TITLE_STORE}\" for field \"${this.props.windowIdentifier.windowName}\"`,\n\t\t\t\t\t\t\tsubErr\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tFSBL.Clients.Logger.debug(\n\t\t\t\t\t\t`Removed listener to store \"${WINDOW_TAB_TITLE_STORE}\" for field \"${this.props.windowIdentifier.windowName}\"`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t);\n\t\t});\n\t}\n\n\trender() {\n\t\tconst { titleWidth } = this.props;\n\t\tconst style = titleWidth ? { width: titleWidth } : {};\n\t\treturn (\n\t\t\t<EditTab\n\t\t\t\ttabWidth={titleWidth}\n\t\t\t\tsetActiveTab={this?.props?.onClick}\n\t\t\t\ttitle={this.state.title}\n\t\t\t\twindowIdentifier={this.props.windowIdentifier}\n\t\t\t>\n\t\t\t\t<div className=\"fsbl-tab-title\" style={style}>\n\t\t\t\t\t{this.state.icon && <Icon {...this.state.icon} />}\n\t\t\t\t\t<div className=\"title-text\">{this.state.title}</div>\n\t\t\t\t</div>\n\t\t\t</EditTab>\n\t\t);\n\t}\n}\n"]}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
+
import { WindowIdentifier } from "@finsemble/finsemble-core";
|
|
2
3
|
export declare type ValueOf<T> = T[keyof T];
|
|
3
4
|
export interface EditTabProps {
|
|
4
5
|
tabWidth?: number;
|
|
5
6
|
tab?: TabProperties;
|
|
6
7
|
setActiveTab?: () => void;
|
|
7
8
|
children: React.ReactNode;
|
|
8
|
-
onTitleChange?: (title: string) => void;
|
|
9
9
|
title?: string;
|
|
10
|
+
windowIdentifier: WindowIdentifier;
|
|
10
11
|
}
|
|
11
12
|
export interface TabProperties {
|
|
12
13
|
windowName: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"windowTitleBar.js","sourceRoot":"","sources":["../../src/types/windowTitleBar.ts"],"names":[],"mappings":"","sourcesContent":["
|
|
1
|
+
{"version":3,"file":"windowTitleBar.js","sourceRoot":"","sources":["../../src/types/windowTitleBar.ts"],"names":[],"mappings":"","sourcesContent":["import { WindowIdentifier } from \"@finsemble/finsemble-core\";\n\nexport type ValueOf<T> = T[keyof T];\n\nexport interface EditTabProps {\n\ttabWidth?: number;\n\ttab?: TabProperties;\n\tsetActiveTab?: () => void;\n\tchildren: React.ReactNode;\n\ttitle?: string;\n\twindowIdentifier: WindowIdentifier;\n}\n\nexport interface TabProperties {\n\twindowName: string;\n\tuuid: string;\n\tname?: string;\n\ttitle: string;\n}\n\nexport interface TabListProps {\n\tlistenForDragOver: boolean;\n\tclassName: string;\n\tonTitleUpdated: Function;\n\tonTabDropped: Function;\n\tthisWindowTitle: string;\n\tboundingBox: BoundingBox;\n\ttabs: TabProperties[];\n}\n\ninterface BoundingBox {\n\ttop: number;\n\tbottom: number;\n\tright: number;\n\tleft: number;\n\twidth: number;\n\theight: number;\n}\n\nexport interface TabListState {\n\ttranslateX: number;\n\ttabs: TabProperties[];\n\tactiveTab: TabProperties;\n\tboundingBox: BoundingBox;\n\tiAmDragging: boolean;\n\thoverState: string;\n\ttabWidth: number;\n\thoveredTabIndex: number | undefined;\n}\n\nexport interface GetTabWidthParams {\n\tboundingBox?: BoundingBox;\n\ttabList?: TabProperties[];\n}\n"]}
|