public override render()

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 >
        );
    }