in gui/frontend/src/modules/db-editor/DocumentModule.tsx [342:744]
public override render(): ComponentChild {
const {
selectedPage, connectionTabs, documentTabs, shellSessionTabs, sidebarState, showSidebar, showTabs, loading,
progressMessage,
} = this.state;
let sqlIcon = Assets.file.mysqlIcon;
const isEmbedded = appParameters.embedded;
// Generate the main toolbar items based on the current display mode.
const toolbarItems: IToolbarItems = { navigation: [], execution: [], editor: [], auxiliary: [] };
const dropDownItems = [];
if (webSession.runMode !== RunMode.SingleServer) {
dropDownItems.push(<DropdownItem
id={this.documentDataModel.overview.id}
key={this.documentDataModel.overview.id}
caption="DB Connection Overview"
picture={<Icon src={Assets.documents.overviewPageIcon} />}
/>);
}
let selectedEntry: string | undefined;
connectionTabs.forEach((info: IConnectionTab) => {
const page = info.dataModelEntry;
const connectionState = this.connectionPresentation.get(page)!;
// Add one entry per connection.
const iconName = page.details.dbType === DBType.MySQL
? Assets.db.mysqlConnectionIcon
: Assets.db.sqliteConnectionIcon;
dropDownItems.push(
<DropdownItem
key={page.id}
caption={info.dataModelEntry.caption}
picture={<Icon src={iconName} />}
payload={info.dataModelEntry}
/>,
);
// After that add an entry for each open document (indented).
connectionState.documentStates.forEach((entry) => {
let picture;
if (entry.state) {
const language = entry.state.model.getLanguageId() as EditorLanguage;
const iconName = documentTypeToFileIcon.get(language);
if (language === "msg") {
picture = <Icon src={iconName ?? Assets.file.defaultIcon} />;
} else {
picture = <Image src={iconName as string ?? Assets.file.defaultIcon} />;
}
} else if (entry.document.type === OdmEntityType.AdminPage) {
const name = pageTypeToDocumentIcon.get((entry.document).pageType) ?? Assets.file.defaultIcon;
picture = <Icon src={name} />;
}
dropDownItems.push((
<DropdownItem
page={page.id}
document={entry.document}
id={entry.document.id}
key={entry.document.id}
caption={entry.document.caption}
picture={picture}
style={{ marginLeft: 16 }}
payload={entry.document}
/>
));
if (selectedPage === page.id && entry.document.id === connectionState.activeEntry) {
selectedEntry = entry.document.id;
if (page.details.dbType === DBType.Sqlite) {
sqlIcon = Assets.file.sqliteIcon;
}
}
});
});
documentTabs.forEach((info) => {
const document = info.dataModelEntry;
const iconName = documentTypeToFileIcon.get(document.language!) ?? Assets.file.defaultIcon;
dropDownItems.push(
<DropdownItem
key={document.id}
id={document.id}
caption={info.dataModelEntry.caption}
picture={<Icon src={iconName} />}
payload={info.dataModelEntry}
/>,
);
});
if (shellSessionTabs.length > 0) {
const root = shellSessionTabs[0].dataModelEntry.parent;
dropDownItems.push(
<DropdownItem
key={root.id}
id={root.id}
caption={root.caption}
picture={<Icon src={Assets.documents.sessionIcon} />}
/>,
);
shellSessionTabs.forEach((info) => {
const document = info.dataModelEntry;
dropDownItems.push(
<DropdownItem
key={document.id}
id={document.id}
caption={info.dataModelEntry.caption}
picture={<Icon src={Assets.documents.sessionIcon} />}
style={{ marginLeft: 16 }}
payload={info.dataModelEntry}
/>,
);
});
}
toolbarItems.navigation.push(
<Label key="mainLabel" style={{ marginRight: "8px" }}>Editor:</Label>,
<Dropdown
id="documentSelector"
key="selector"
selection={selectedEntry ?? selectedPage}
onSelect={this.handleDropdownSelection}
>
{dropDownItems}
</Dropdown>,
);
if (selectedPage === this.documentDataModel.overview.id) {
toolbarItems.navigation.push(
<Button
key="button1"
id="newConsoleMenuButton"
data-tooltip="Open New Shell Console"
style={{ marginLeft: "4px" }}
onClick={this.addNewConsole}
>
<Icon key="newIcon" src={Assets.toolbar.newShellConsoleIcon} data-tooltip="inherit" />
</Button>,
<Divider key="divider2" id="actionDivider" vertical={true} thickness={1} />,
);
}
const pages: ITabviewPage[] = [];
let actualSelection = selectedPage;
if (loading) {
const content = <>
<ProgressIndicator
id="loadingProgressIndicator"
backgroundOpacity={0.95}
linear={false}
/>
<Label
id="progressMessageId"
caption={progressMessage}
/>
</>;
pages.push({
icon: Assets.documents.overviewPageIcon,
caption: "Open Connection",
id: "progress",
content,
});
actualSelection = "progress";
} else if (webSession.runMode !== RunMode.SingleServer) {
// Don't render the overview, if we can only have a single connection.
const overview = (
<Container
id="overviewHost"
orientation={Orientation.TopDown}
>
<ConnectionBrowser
toolbarItems={toolbarItems}
onAddConnection={this.handleAddConnection}
onUpdateConnection={this.handleUpdateConnection}
onRemoveConnection={this.handleRemoveConnection}
/>
</Container>
);
pages.push({
icon: Assets.documents.overviewPageIcon,
caption: "Connection Overview",
id: this.documentDataModel.overview.id,
content: overview,
});
}
let selectedDocument = this.documentDataModel.overview.id;
connectionTabs.forEach((info: IConnectionTab) => {
const page = info.dataModelEntry;
const connectionState = this.connectionPresentation.get(page)!;
const content = (<ConnectionTab
id={page.id}
ref={page.id === actualSelection ? this.currentTabRef : undefined}
caption={page.caption}
showAbout={!info.suppressAbout}
workerPool={this.workerPool}
connection={info.connection}
toolbarItems={toolbarItems}
extraLibs={[{ code: scriptingRuntime, path: "runtime" }]}
savedState={connectionState}
onHelpCommand={this.handleHelpCommand}
onAddEditor={this.handleAddNotebook}
onLoadScript={this.handleLoadScript}
onSelectItem={this.handleSelectItem}
onEditorRename={this.handleEditorRename}
onGraphDataChange={this.handleGraphDataChange}
onChatOptionsChange={this.onChatOptionsChange}
/>);
if (page.id === selectedPage) {
selectedDocument = connectionState.activeEntry;
}
pages.push({
icon: Assets.misc.scriptingIcon,
caption: page.caption,
id: page.id,
content,
auxiliary: (
<Button
id={page.id}
className="closeButton"
round={true}
onClick={this.handleCloseTab}>
<Icon src={Assets.misc.close2Icon} />
</Button>
),
canClose: !appParameters.embedded,
});
});
documentTabs.forEach((info: IDocumentTab) => {
const document = info.dataModelEntry;
const content = (<SimpleEditor
key={document.id}
id={document.id}
savedState={info.savedState}
fileName={document.caption}
toolbarItemsTemplate={toolbarItems}
/>);
if (document.id === selectedPage) {
selectedDocument = selectedPage;
}
pages.push({
icon: Assets.misc.scriptingIcon,
caption: document.caption,
id: document.id,
content,
auxiliary: (
<Button
id={document.id}
className="closeButton"
round={true}
onClick={this.handleCloseTab}>
<Icon src={Assets.misc.close2Icon} />
</Button>
),
canClose: !appParameters.embedded,
});
});
shellSessionTabs.forEach((info) => {
const document = info.dataModelEntry;
const content = (<ShellTab
key={document.id}
id={document.id}
savedState={info.savedState}
toolbarItemsTemplate={toolbarItems}
onQuit={(id) => { void this.removeShellTab(id); }}
/>);
if (document.id === selectedPage) {
selectedDocument = selectedPage;
}
pages.push({
icon: Assets.misc.scriptingIcon,
caption: document.caption,
id: document.id,
content,
auxiliary: (
<Button
id={document.id}
className="closeButton"
round={true}
onClick={this.handleCloseTab}>
<Icon src={Assets.misc.close2Icon} />
</Button>
),
canClose: !appParameters.embedded,
});
});
const className = "dbModuleTabview";
const content = <>
<Tabview
className={className}
tabPosition={TabPosition.Top}
selectedId={actualSelection}
stretchTabs={false}
showTabs={showTabs}
canReorderTabs
pages={pages}
onSelectTab={this.handleSelectTab}
closeTabs={this.removeTabs}
canCloseTab={this.canCloseTab}
/>
{isEmbedded &&
<Menu
key="actionMenu"
id="editorToolbarActionMenu"
ref={this.actionMenuRef}
placement={ComponentPlacement.BottomLeft}
onItemClick={this.handleNewScriptClick}
>
<MenuItem
key="item1"
command={{ title: "New DB Notebook", command: "addEditor" }}
icon={Assets.misc.newNotebookIcon}
/>
<MenuItem
key="item2"
command={{ title: "New SQL Script", command: "addSQLScript" }}
icon={sqlIcon}
/>
<MenuItem
key="item3"
command={{ title: "New TS Script", command: "addTSScript" }}
icon={Assets.file.typescriptIcon}
/>
<MenuItem
key="item4"
command={{ title: "New JS Script", command: "addJSScript" }}
icon={Assets.file.javascriptIcon}
/>
</Menu>
}
<MrsHub ref={this.mrsHubRef} />
</>;
const selectedTab = connectionTabs.find((entry) => { return entry.dataModelEntry.id === selectedPage; });
const splitterPanes: ISplitterPane[] = [];
if (!appParameters.embedded) {
// Don't render the sidebar when embedded.
splitterPanes.push({
content: <DocumentSideBar
selectedOpenDocument={selectedDocument}
markedSchema={selectedTab?.connection.currentSchema ?? ""}
savedSectionState={sidebarState}
overviewId={this.documentDataModel.overview.id}
onSaveState={this.handleSaveExplorerState}
onSelectDocumentItem={this.handleDocumentSelection}
onSelectConnectionItem={this.handleConnectionEntrySelection}
onConnectionTreeCommand={this.handleSideBarConnectionCommand}
onDocumentTreeCommand={this.handleSideBarDocumentCommand}
onOciTreeCommand={this.handleSideBarOciCommand}
/>,
minSize: 0,
initialSize: showSidebar ? 250 : 0,
resizable: true,
snap: true,
collapsed: !showSidebar,
});
}
splitterPanes.push({
content,
minSize: 500,
resizable: true,
stretch: true,
});
return (
<DocumentContext.Provider
value={{
connectionsDataModel: this.connectionsDataModel,
documentDataModel: this.documentDataModel,
ociDataModel: this.ociDataModel,
shellTaskDataModel: this.shellTaskDataModel,
}}>
<SplitContainer
id="mainSplitHost"
innerRef={this.containerRef}
orientation={Orientation.LeftToRight}
panes={splitterPanes}
/>
</DocumentContext.Provider >
);
}