mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2026-01-08 20:17:03 +00:00
Compare commits
2 Commits
2262580
...
defect2280
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57fa554178 | ||
|
|
ce3a7debb3 |
@@ -36,7 +36,7 @@ export const CollapsedResourceTree: FunctionComponent<CollapsedResourceTreeProps
|
|||||||
id="collapseToggleLeftPaneButton"
|
id="collapseToggleLeftPaneButton"
|
||||||
role="button"
|
role="button"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
aria-label={getApiShortDisplayName() + `Expand tree`}
|
aria-label="Expand Tree"
|
||||||
onClick={toggleLeftPaneExpanded}
|
onClick={toggleLeftPaneExpanded}
|
||||||
onKeyPress={onKeyPressToggleLeftPaneExpanded}
|
onKeyPress={onKeyPressToggleLeftPaneExpanded}
|
||||||
ref={focusButton}
|
ref={focusButton}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ export const EntityValue: FunctionComponent<TableEntityProps> = ({
|
|||||||
label={entityValueLabel && entityValueLabel}
|
label={entityValueLabel && entityValueLabel}
|
||||||
className="addEntityTextField"
|
className="addEntityTextField"
|
||||||
id="entityValueId"
|
id="entityValueId"
|
||||||
|
autoFocus
|
||||||
disabled={isEntityValueDisable}
|
disabled={isEntityValueDisable}
|
||||||
type={entityValueType}
|
type={entityValueType}
|
||||||
placeholder={entityValuePlaceholder}
|
placeholder={entityValuePlaceholder}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export const ResourceTreeContainer: FunctionComponent<ResourceTreeContainerProps
|
|||||||
role="button"
|
role="button"
|
||||||
data-bind="click: onRefreshResourcesClick, clickBubble: false, event: { keypress: onRefreshDatabasesKeyPress }"
|
data-bind="click: onRefreshResourcesClick, clickBubble: false, event: { keypress: onRefreshDatabasesKeyPress }"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
aria-label={getApiShortDisplayName() + `Refresh tree`}
|
aria-label="Refresh tree"
|
||||||
title="Refresh tree"
|
title="Refresh tree"
|
||||||
>
|
>
|
||||||
<img className="refreshcol" src={refreshImg} alt="Refresh Tree" />
|
<img className="refreshcol" src={refreshImg} alt="Refresh Tree" />
|
||||||
@@ -63,7 +63,7 @@ export const ResourceTreeContainer: FunctionComponent<ResourceTreeContainerProps
|
|||||||
onClick={toggleLeftPaneExpanded}
|
onClick={toggleLeftPaneExpanded}
|
||||||
onKeyPress={onKeyPressToggleLeftPaneExpanded}
|
onKeyPress={onKeyPressToggleLeftPaneExpanded}
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
aria-label={getApiShortDisplayName() + `Collapse Tree`}
|
aria-label="Collapse Tree"
|
||||||
title="Collapse Tree"
|
title="Collapse Tree"
|
||||||
ref={focusButton}
|
ref={focusButton}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ export const TableEntity: FunctionComponent<TableEntityProps> = ({
|
|||||||
{...imageProps}
|
{...imageProps}
|
||||||
src={EditIcon}
|
src={EditIcon}
|
||||||
alt="editEntity"
|
alt="editEntity"
|
||||||
|
id="editEntity"
|
||||||
onClick={onEditEntity}
|
onClick={onEditEntity}
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onKeyPress={handleKeyPress}
|
onKeyPress={handleKeyPress}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ export class AccordionItemComponent extends React.Component<AccordionItemCompone
|
|||||||
<img
|
<img
|
||||||
className="expandCollapseIcon"
|
className="expandCollapseIcon"
|
||||||
src={this.state.isExpanded ? TriangleDownIcon : TriangleRightIcon}
|
src={this.state.isExpanded ? TriangleDownIcon : TriangleRightIcon}
|
||||||
alt={this.state.isExpanded ? `${this.props.title} hide` : `${this.props.title} expand`}
|
alt="Hide"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
role="button"
|
role="button"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ import { calculateEstimateNumber, usageInGB } from "../../../../../Utils/Pricing
|
|||||||
import { Int32 } from "../../../../Panes/Tables/Validators/EntityPropertyValidationCommon";
|
import { Int32 } from "../../../../Panes/Tables/Validators/EntityPropertyValidationCommon";
|
||||||
import {
|
import {
|
||||||
AutoscaleEstimatedSpendingDisplayProps,
|
AutoscaleEstimatedSpendingDisplayProps,
|
||||||
ManualEstimatedSpendingDisplayProps,
|
|
||||||
PriceBreakdown,
|
|
||||||
checkBoxAndInputStackProps,
|
checkBoxAndInputStackProps,
|
||||||
getAutoPilotV3SpendElement,
|
getAutoPilotV3SpendElement,
|
||||||
getChoiceGroupStyles,
|
getChoiceGroupStyles,
|
||||||
@@ -33,14 +31,16 @@ import {
|
|||||||
getRuPriceBreakdown,
|
getRuPriceBreakdown,
|
||||||
getTextFieldStyles,
|
getTextFieldStyles,
|
||||||
getToolTipContainer,
|
getToolTipContainer,
|
||||||
|
ManualEstimatedSpendingDisplayProps,
|
||||||
manualToAutoscaleDisclaimerElement,
|
manualToAutoscaleDisclaimerElement,
|
||||||
messageBarStyles,
|
messageBarStyles,
|
||||||
noLeftPaddingCheckBoxStyle,
|
noLeftPaddingCheckBoxStyle,
|
||||||
|
PriceBreakdown,
|
||||||
saveThroughputWarningMessage,
|
saveThroughputWarningMessage,
|
||||||
titleAndInputStackProps,
|
titleAndInputStackProps,
|
||||||
transparentDetailsHeaderStyle,
|
transparentDetailsHeaderStyle,
|
||||||
} from "../../SettingsRenderUtils";
|
} from "../../SettingsRenderUtils";
|
||||||
import { IsComponentDirtyResult, getSanitizedInputValue, isDirty } from "../../SettingsUtils";
|
import { getSanitizedInputValue, IsComponentDirtyResult, isDirty } from "../../SettingsUtils";
|
||||||
import { ToolTipLabelComponent } from "../ToolTipLabelComponent";
|
import { ToolTipLabelComponent } from "../ToolTipLabelComponent";
|
||||||
|
|
||||||
export interface ThroughputInputAutoPilotV3Props {
|
export interface ThroughputInputAutoPilotV3Props {
|
||||||
@@ -218,7 +218,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
|||||||
const estimatedSpendingColumns: IColumn[] = [
|
const estimatedSpendingColumns: IColumn[] = [
|
||||||
{
|
{
|
||||||
key: "costType",
|
key: "costType",
|
||||||
name: "Cost Type",
|
name: "",
|
||||||
fieldName: "costType",
|
fieldName: "costType",
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
maxWidth: 200,
|
maxWidth: 200,
|
||||||
@@ -312,7 +312,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
|||||||
const estimatedSpendingColumns: IColumn[] = [
|
const estimatedSpendingColumns: IColumn[] = [
|
||||||
{
|
{
|
||||||
key: "costType",
|
key: "costType",
|
||||||
name: "Cost type",
|
name: "",
|
||||||
fieldName: "costType",
|
fieldName: "costType",
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
maxWidth: 200,
|
maxWidth: 200,
|
||||||
|
|||||||
@@ -311,7 +311,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
|
|||||||
"key": "costType",
|
"key": "costType",
|
||||||
"maxWidth": 200,
|
"maxWidth": 200,
|
||||||
"minWidth": 100,
|
"minWidth": 100,
|
||||||
"name": "Cost type",
|
"name": "",
|
||||||
"styles": Object {
|
"styles": Object {
|
||||||
"root": Object {
|
"root": Object {
|
||||||
"selectors": Object {
|
"selectors": Object {
|
||||||
@@ -586,7 +586,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
|
|||||||
"key": "costType",
|
"key": "costType",
|
||||||
"maxWidth": 200,
|
"maxWidth": 200,
|
||||||
"minWidth": 100,
|
"minWidth": 100,
|
||||||
"name": "Cost type",
|
"name": "",
|
||||||
"styles": Object {
|
"styles": Object {
|
||||||
"root": Object {
|
"root": Object {
|
||||||
"selectors": Object {
|
"selectors": Object {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { AccessibleElement } from "../../Controls/AccessibleElement/AccessibleElement";
|
|
||||||
import "./TabComponent.less";
|
import "./TabComponent.less";
|
||||||
|
|
||||||
export interface TabContent {
|
export interface TabContent {
|
||||||
@@ -19,11 +18,15 @@ interface TabComponentProps {
|
|||||||
onTabIndexChange: (newIndex: number) => void;
|
onTabIndexChange: (newIndex: number) => void;
|
||||||
hideHeader: boolean;
|
hideHeader: boolean;
|
||||||
}
|
}
|
||||||
|
interface TabRefs {
|
||||||
|
[key: string]: HTMLElement;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We assume there's at least one tab
|
* We assume there's at least one tab
|
||||||
*/
|
*/
|
||||||
export class TabComponent extends React.Component<TabComponentProps> {
|
export class TabComponent extends React.Component<TabComponentProps> {
|
||||||
|
private tabRefs: TabRefs = {};
|
||||||
public constructor(props: TabComponentProps) {
|
public constructor(props: TabComponentProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
@@ -33,11 +36,41 @@ export class TabComponent extends React.Component<TabComponentProps> {
|
|||||||
throw new Error(msg);
|
throw new Error(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
state = {
|
||||||
|
activeTabIndex: this.props.currentTabIndex,
|
||||||
|
};
|
||||||
|
|
||||||
private setActiveTab(index: number): void {
|
private setActiveTab(index: number): void {
|
||||||
this.setState({ activeTabIndex: index });
|
this.setState({ activeTabIndex: index });
|
||||||
this.props.onTabIndexChange(index);
|
this.props.onTabIndexChange(index);
|
||||||
}
|
}
|
||||||
|
private setIndex = (index: number) => {
|
||||||
|
const tab = this.tabRefs[index];
|
||||||
|
if (tab) {
|
||||||
|
tab.focus();
|
||||||
|
this.setState({ activeTabIndex: index });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private handlekeypress = (event: React.KeyboardEvent<HTMLSpanElement>): void => {
|
||||||
|
const { tabs, onTabIndexChange } = this.props;
|
||||||
|
const { activeTabIndex } = this.state;
|
||||||
|
const count = tabs.length;
|
||||||
|
|
||||||
|
const prevTab = () => {
|
||||||
|
this.setIndex((activeTabIndex - 1 + count) % count);
|
||||||
|
onTabIndexChange((activeTabIndex - 1 + count) % count);
|
||||||
|
};
|
||||||
|
const nextTab = () => {
|
||||||
|
this.setIndex((activeTabIndex + 1) % count);
|
||||||
|
onTabIndexChange((activeTabIndex + 1) % count);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (event.key === "ArrowLeft") {
|
||||||
|
prevTab();
|
||||||
|
} else if (event.key === "ArrowRight") {
|
||||||
|
nextTab();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private renderTabTitles(): JSX.Element[] {
|
private renderTabTitles(): JSX.Element[] {
|
||||||
return this.props.tabs.map((tab: Tab, index: number) => {
|
return this.props.tabs.map((tab: Tab, index: number) => {
|
||||||
@@ -47,26 +80,32 @@ export class TabComponent extends React.Component<TabComponentProps> {
|
|||||||
|
|
||||||
let className = "toggleSwitch";
|
let className = "toggleSwitch";
|
||||||
let ariaselected;
|
let ariaselected;
|
||||||
|
let tabindex;
|
||||||
if (index === this.props.currentTabIndex) {
|
if (index === this.props.currentTabIndex) {
|
||||||
className += " selectedToggle";
|
className += " selectedToggle";
|
||||||
ariaselected = true;
|
ariaselected = true;
|
||||||
|
tabindex = 0;
|
||||||
} else {
|
} else {
|
||||||
className += " unselectedToggle";
|
className += " unselectedToggle";
|
||||||
ariaselected = false;
|
ariaselected = false;
|
||||||
|
tabindex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="tab" key={index}>
|
<div className="tab" key={index}>
|
||||||
<AccessibleElement
|
<span
|
||||||
as="span"
|
|
||||||
className={className}
|
className={className}
|
||||||
role="tab"
|
role="tab"
|
||||||
onActivated={() => this.setActiveTab(index)}
|
onClick={() => this.setActiveTab(index)}
|
||||||
|
onKeyDown={(event: React.KeyboardEvent<HTMLSpanElement>) => this.handlekeypress(event)}
|
||||||
|
onFocus={() => this.setState({ activeTabIndex: index })}
|
||||||
aria-label={`Select tab: ${tab.title}`}
|
aria-label={`Select tab: ${tab.title}`}
|
||||||
aria-selected={ariaselected}
|
aria-selected={ariaselected}
|
||||||
|
tabIndex={tabindex}
|
||||||
|
ref={(element) => (this.tabRefs[index] = element)}
|
||||||
>
|
>
|
||||||
{tab.title}
|
{tab.title}
|
||||||
</AccessibleElement>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
|||||||
step={AutoPilotUtils.autoPilotIncrementStep}
|
step={AutoPilotUtils.autoPilotIncrementStep}
|
||||||
min={AutoPilotUtils.autoPilotThroughput1K}
|
min={AutoPilotUtils.autoPilotThroughput1K}
|
||||||
value={throughput.toString()}
|
value={throughput.toString()}
|
||||||
ariaLabel={`${isDatabase ? "Database" : getCollectionName()} max RU/s`}
|
aria-label="Max request units per second"
|
||||||
required={true}
|
required={true}
|
||||||
errorMessage={throughputError}
|
errorMessage={throughputError}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1640,7 +1640,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</Stack>
|
</Stack>
|
||||||
<StyledTextFieldBase
|
<StyledTextFieldBase
|
||||||
ariaLabel="Container max RU/s"
|
aria-label="Max request units per second"
|
||||||
errorMessage=""
|
errorMessage=""
|
||||||
id="autoscaleRUValueField"
|
id="autoscaleRUValueField"
|
||||||
key=".0:$.2"
|
key=".0:$.2"
|
||||||
@@ -1663,7 +1663,7 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
|||||||
value="4000"
|
value="4000"
|
||||||
>
|
>
|
||||||
<TextFieldBase
|
<TextFieldBase
|
||||||
ariaLabel="Container max RU/s"
|
aria-label="Max request units per second"
|
||||||
deferredValidationTime={200}
|
deferredValidationTime={200}
|
||||||
errorMessage=""
|
errorMessage=""
|
||||||
id="autoscaleRUValueField"
|
id="autoscaleRUValueField"
|
||||||
@@ -1961,7 +1961,6 @@ exports[`ThroughputInput Pane should render Default properly 1`] = `
|
|||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
aria-invalid={false}
|
aria-invalid={false}
|
||||||
aria-label="Container max RU/s"
|
|
||||||
className="ms-TextField-field field-64"
|
className="ms-TextField-field field-64"
|
||||||
id="autoscaleRUValueField"
|
id="autoscaleRUValueField"
|
||||||
min={1000}
|
min={1000}
|
||||||
|
|||||||
@@ -729,7 +729,6 @@ export class D3ForceGraph implements GraphRenderer {
|
|||||||
var iconGroup = newNodes
|
var iconGroup = newNodes
|
||||||
.append("g")
|
.append("g")
|
||||||
.attr("class", "iconContainer")
|
.attr("class", "iconContainer")
|
||||||
.attr("role", "group")
|
|
||||||
.attr("tabindex", 0)
|
.attr("tabindex", 0)
|
||||||
.attr("aria-label", (d: D3Node) => {
|
.attr("aria-label", (d: D3Node) => {
|
||||||
return this.retrieveNodeCaption(d);
|
return this.retrieveNodeCaption(d);
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ export class MiddlePaneComponent extends React.Component<MiddlePaneComponentProp
|
|||||||
onClick={this.props.toggleExpandGraph}
|
onClick={this.props.toggleExpandGraph}
|
||||||
role="button"
|
role="button"
|
||||||
aria-expanded={this.props.isTabsContentExpanded}
|
aria-expanded={this.props.isTabsContentExpanded}
|
||||||
aria-label={
|
aria-name="View graph in full screen"
|
||||||
this.props.isTabsContentExpanded ? "Collapse graph to minimized view" : "View graph in full screen"
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src={this.props.isTabsContentExpanded ? CollapseArrowIcon : ExpandIcon}
|
src={this.props.isTabsContentExpanded ? CollapseArrowIcon : ExpandIcon}
|
||||||
|
|||||||
@@ -107,11 +107,11 @@ describe("New Vertex Component", () => {
|
|||||||
it("should call onTypeChange method on type dropdown change", () => {
|
it("should call onTypeChange method on type dropdown change", () => {
|
||||||
const DOWN_ARROW = { keyCode: 40 };
|
const DOWN_ARROW = { keyCode: 40 };
|
||||||
const onTypeChange = jest.fn();
|
const onTypeChange = jest.fn();
|
||||||
const dropdown = screen.getByRole("combobox");
|
const dropdown = screen.getByRole("listbox");
|
||||||
dropdown.onclick = onTypeChange();
|
dropdown.onclick = onTypeChange();
|
||||||
dropdown.onkeydown = onTypeChange();
|
dropdown.onkeydown = onTypeChange();
|
||||||
|
|
||||||
fireEvent.keyDown(screen.getByRole("combobox"), DOWN_ARROW);
|
fireEvent.keyDown(screen.getByRole("listbox"), DOWN_ARROW);
|
||||||
fireEvent.click(screen.getByText(/number/));
|
fireEvent.click(screen.getByText(/number/));
|
||||||
expect(onTypeChange).toHaveBeenCalled();
|
expect(onTypeChange).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -145,7 +145,6 @@ export const NewVertexComponent: FunctionComponent<INewVertexComponentProps> = (
|
|||||||
type="text"
|
type="text"
|
||||||
id="propertyKeyNewVertexPane"
|
id="propertyKeyNewVertexPane"
|
||||||
componentRef={input}
|
componentRef={input}
|
||||||
aria-required="true"
|
|
||||||
placeholder="Key"
|
placeholder="Key"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
aria-label={`Enter value for propery ${index + 1}`}
|
aria-label={`Enter value for propery ${index + 1}`}
|
||||||
@@ -153,8 +152,6 @@ export const NewVertexComponent: FunctionComponent<INewVertexComponentProps> = (
|
|||||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => onKeyChange(event, index)}
|
onChange={(event: React.ChangeEvent<HTMLInputElement>) => onKeyChange(event, index)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="mandatoryStar">* </span>
|
|
||||||
|
|
||||||
<div className="valueCol">
|
<div className="valueCol">
|
||||||
<TextField
|
<TextField
|
||||||
className="edgeInput"
|
className="edgeInput"
|
||||||
@@ -168,7 +165,7 @@ export const NewVertexComponent: FunctionComponent<INewVertexComponentProps> = (
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
role="combobox"
|
role="listbox"
|
||||||
placeholder="Select an option"
|
placeholder="Select an option"
|
||||||
defaultSelectedKey={data.values[0].type}
|
defaultSelectedKey={data.values[0].type}
|
||||||
style={{ width: 100 }}
|
style={{ width: 100 }}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export const PanelInfoErrorComponent: React.FunctionComponent<PanelInfoErrorProp
|
|||||||
)}
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
{showErrorDetails && (
|
{showErrorDetails && (
|
||||||
<a className="paneErrorLink" role="button" onClick={expandConsole} tabIndex={0} onKeyPress={expandConsole}>
|
<a className="paneErrorLink" role="link" onClick={expandConsole} tabIndex={0} onKeyPress={expandConsole}>
|
||||||
More details
|
More details
|
||||||
</a>
|
</a>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -134,7 +134,6 @@
|
|||||||
data-bind="click: selectQueryOptions, event: { keydown: onselectQueryOptionsKeyDown }"
|
data-bind="click: selectQueryOptions, event: { keydown: onselectQueryOptionsKeyDown }"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
role="button"
|
role="button"
|
||||||
href=""
|
|
||||||
>
|
>
|
||||||
<span>Choose Columns... </span>
|
<span>Choose Columns... </span>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import { SplashScreen } from "Explorer/SplashScreen/SplashScreen";
|
|||||||
import { ConnectTab } from "Explorer/Tabs/ConnectTab";
|
import { ConnectTab } from "Explorer/Tabs/ConnectTab";
|
||||||
import { PostgresConnectTab } from "Explorer/Tabs/PostgresConnectTab";
|
import { PostgresConnectTab } from "Explorer/Tabs/PostgresConnectTab";
|
||||||
import { QuickstartTab } from "Explorer/Tabs/QuickstartTab";
|
import { QuickstartTab } from "Explorer/Tabs/QuickstartTab";
|
||||||
import { userContext } from "UserContext";
|
|
||||||
import { useTeachingBubble } from "hooks/useTeachingBubble";
|
import { useTeachingBubble } from "hooks/useTeachingBubble";
|
||||||
import ko from "knockout";
|
import ko from "knockout";
|
||||||
import React, { MutableRefObject, useEffect, useRef, useState } from "react";
|
import React, { MutableRefObject, useEffect, useRef, useState } from "react";
|
||||||
|
import { userContext } from "UserContext";
|
||||||
import loadingIcon from "../../../images/circular_loader_black_16x16.gif";
|
import loadingIcon from "../../../images/circular_loader_black_16x16.gif";
|
||||||
import errorIcon from "../../../images/close-black.svg";
|
import errorIcon from "../../../images/close-black.svg";
|
||||||
import { useObservable } from "../../hooks/useObservable";
|
import { useObservable } from "../../hooks/useObservable";
|
||||||
@@ -102,20 +102,22 @@ function TabNav({ tab, active, tabKind }: { tab?: Tab; active: boolean; tabKind?
|
|||||||
ref={focusTab}
|
ref={focusTab}
|
||||||
>
|
>
|
||||||
<span className="tabNavContentContainer">
|
<span className="tabNavContentContainer">
|
||||||
<div className="tab_Content">
|
<a data-toggle="tab" href={"#" + tabId} tabIndex={-1}>
|
||||||
<span className="statusIconContainer" style={{ width: tabKind === ReactTabKind.Home ? 0 : 18 }}>
|
<div className="tab_Content">
|
||||||
{useObservable(tab?.isExecutionError || ko.observable(false)) && <ErrorIcon tab={tab} active={active} />}
|
<span className="statusIconContainer" style={{ width: tabKind === ReactTabKind.Home ? 0 : 18 }}>
|
||||||
{useObservable(tab?.isExecuting || ko.observable(false)) && (
|
{useObservable(tab?.isExecutionError || ko.observable(false)) && <ErrorIcon tab={tab} active={active} />}
|
||||||
<img className="loadingIcon" title="Loading" src={loadingIcon} alt="Loading" />
|
{useObservable(tab?.isExecuting || ko.observable(false)) && (
|
||||||
)}
|
<img className="loadingIcon" title="Loading" src={loadingIcon} alt="Loading" />
|
||||||
</span>
|
)}
|
||||||
<span className="tabNavText">{useObservable(tab?.tabTitle || ko.observable(ReactTabKind[tabKind]))}</span>
|
|
||||||
{tabKind !== ReactTabKind.Home && (
|
|
||||||
<span className="tabIconSection">
|
|
||||||
<CloseButton tab={tab} active={active} hovering={hovering} tabKind={tabKind} />
|
|
||||||
</span>
|
</span>
|
||||||
)}
|
<span className="tabNavText">{useObservable(tab?.tabTitle || ko.observable(ReactTabKind[tabKind]))}</span>
|
||||||
</div>
|
{tabKind !== ReactTabKind.Home && (
|
||||||
|
<span className="tabIconSection">
|
||||||
|
<CloseButton tab={tab} active={active} hovering={hovering} tabKind={tabKind} />
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user