Compare commits

..

4 Commits

Author SHA1 Message Date
vaidankarswapnil
f108ed4fbd Resolved test case issue 2021-09-16 22:49:50 +05:30
vaidankarswapnil
74095b6bc4 Update test snapshot issue 2021-09-16 15:32:47 +05:30
vaidankarswapnil
5a4b170857 Merge branch 'master' of https://github.com/Azure/cosmos-explorer into fix_a11y_database_throughput_radiobuttons 2021-09-16 12:36:25 +05:30
vaidankarswapnil
8ebd0f9b01 Fix a11y new collection throughput radiobutton issue 2021-09-16 12:36:13 +05:30
83 changed files with 2781 additions and 1815 deletions

View File

@@ -3,8 +3,8 @@ module.exports = {
browser: true,
es6: true,
},
plugins: ["@typescript-eslint", "no-null", "prefer-arrow", "react-hooks", "jsx-a11y"],
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:jsx-a11y/recommended"],
plugins: ["@typescript-eslint", "no-null", "prefer-arrow", "react-hooks"],
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
globals: {
Atomics: "readonly",
SharedArrayBuffer: "readonly",

View File

@@ -1,8 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"
<svg
width="16"
height="16"
version="1.1"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path
d="M14,2.691l-5.301,5.309l5.301,5.309l-0.691,0.691l-5.309,-5.301l-5.309,5.301l-0.691,-0.691l5.301,-5.309l-5.301,-5.309l0.691,-0.691l5.309,5.301l5.309,-5.301l0.691,0.691Z"
transform="scale(0.5)" fill="#000" stroke="#000">
<path
d="M14,2.691l-5.301,5.309l5.301,5.309l-0.691,0.691l-5.309,-5.301l-5.309,5.301l-0.691,-0.691l5.301,-5.309l-5.301,-5.309l0.691,-0.691l5.309,5.301l5.309,-5.301l0.691,0.691Z"
transform="scale(0.5)"
fill="#000"
stroke="#CCC"
>
</path>
</svg>

Before

Width:  |  Height:  |  Size: 449 B

After

Width:  |  Height:  |  Size: 503 B

View File

@@ -2357,8 +2357,6 @@ a:link {
height: 100%;
flex-grow: 1;
overflow: hidden;
min-height: 300px;
overflow-y: scroll;
}
.tabs {
@@ -2834,8 +2832,6 @@ a:link {
#explorerNotificationConsole {
z-index: 1000;
overflow-y: auto;
overflow-x: clip;
}
.uniqueIndexesContainer {
@@ -3079,6 +3075,3 @@ settings-pane {
background: white;
height: 100%;
}
.moreOption {
color: #337ab7;
}

91
package-lock.json generated
View File

@@ -6809,11 +6809,6 @@
"integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=",
"dev": true
},
"ast-types-flow": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
"integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0="
},
"astral-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
@@ -6881,11 +6876,6 @@
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
},
"axe-core": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.3.3.tgz",
"integrity": "sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA=="
},
"axios": {
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
@@ -6901,11 +6891,6 @@
}
}
},
"axobject-query": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
"integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA=="
},
"babel-code-frame": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
@@ -8893,11 +8878,6 @@
"d3-transition": "2"
}
},
"damerau-levenshtein": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz",
"integrity": "sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw=="
},
"dashdash": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
@@ -10191,64 +10171,6 @@
"@typescript-eslint/experimental-utils": "^2.5.0"
}
},
"eslint-plugin-jsx-a11y": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz",
"integrity": "sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg==",
"requires": {
"@babel/runtime": "^7.11.2",
"aria-query": "^4.2.2",
"array-includes": "^3.1.1",
"ast-types-flow": "^0.0.7",
"axe-core": "^4.0.2",
"axobject-query": "^2.2.0",
"damerau-levenshtein": "^1.0.6",
"emoji-regex": "^9.0.0",
"has": "^1.0.3",
"jsx-ast-utils": "^3.1.0",
"language-tags": "^1.0.5"
},
"dependencies": {
"emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
},
"get-intrinsic": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
"integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
"requires": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1"
}
},
"jsx-ast-utils": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz",
"integrity": "sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA==",
"requires": {
"array-includes": "^3.1.3",
"object.assign": "^4.1.2"
},
"dependencies": {
"array-includes": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz",
"integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==",
"requires": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3",
"es-abstract": "^1.18.0-next.2",
"get-intrinsic": "^1.1.1",
"is-string": "^1.0.5"
}
}
}
}
}
},
"eslint-plugin-no-null": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-no-null/-/eslint-plugin-no-null-1.0.2.tgz",
@@ -18143,19 +18065,6 @@
"resolved": "https://registry.npmjs.org/labella/-/labella-1.1.4.tgz",
"integrity": "sha1-xsxaNA6N80DrM1YzaD6lm4KMMi0="
},
"language-subtag-registry": {
"version": "0.3.21",
"resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz",
"integrity": "sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg=="
},
"language-tags": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz",
"integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=",
"requires": {
"language-subtag-registry": "~0.3.2"
}
},
"lcid": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",

View File

@@ -61,7 +61,6 @@
"dom-to-image": "2.6.0",
"dotenv": "8.2.0",
"eslint-plugin-jest": "23.13.2",
"eslint-plugin-jsx-a11y": "6.4.1",
"eslint-plugin-react": "7.20.0",
"hasher": "1.2.0",
"html2canvas": "1.0.0-rc.5",

View File

@@ -1,7 +1,6 @@
import React, { FunctionComponent, MutableRefObject, useEffect, useRef } from "react";
import React, { FunctionComponent } from "react";
import arrowLeftImg from "../../images/imgarrowlefticon.svg";
import { userContext } from "../UserContext";
import { NormalizedEventKey } from "./Constants";
export interface CollapsedResourceTreeProps {
toggleLeftPaneExpanded: () => void;
@@ -12,37 +11,21 @@ export const CollapsedResourceTree: FunctionComponent<CollapsedResourceTreeProps
toggleLeftPaneExpanded,
isLeftPaneExpanded,
}: CollapsedResourceTreeProps): JSX.Element => {
const focusButton = useRef<HTMLLIElement>() as MutableRefObject<HTMLLIElement>;
useEffect(() => {
if (focusButton.current) {
focusButton.current.focus();
}
});
const onKeyPressToggleLeftPaneExpanded = (event: React.KeyboardEvent) => {
if (event.key === NormalizedEventKey.Space || event.key === NormalizedEventKey.Enter) {
toggleLeftPaneExpanded();
event.stopPropagation();
}
};
return (
<div id="mini" className={!isLeftPaneExpanded ? "mini toggle-mini" : "hiddenMain"}>
<div className="main-nav nav">
<ul className="nav">
<li className="resourceTreeCollapse" id="collapseToggleLeftPaneButton" aria-label="Expand Tree">
<span
className="leftarrowCollapsed"
role="button"
tabIndex={0}
onClick={toggleLeftPaneExpanded}
onKeyPress={onKeyPressToggleLeftPaneExpanded}
ref={focusButton}
>
<li
className="resourceTreeCollapse"
id="collapseToggleLeftPaneButton"
role="button"
tabIndex={0}
aria-label="Expand Tree"
>
<span className="leftarrowCollapsed" onClick={toggleLeftPaneExpanded}>
<img className="arrowCollapsed" src={arrowLeftImg} alt="Expand" />
</span>
<span className="collectionCollapsed">
<span className="collectionCollapsed" onClick={toggleLeftPaneExpanded}>
<span>{userContext.apiType} API</span>
</span>
</li>

View File

@@ -40,6 +40,7 @@ export const EntityValue: FunctionComponent<TableEntityProps> = ({
<TextField
label={entityValueLabel && entityValueLabel}
id="entityTimeId"
autoFocus
type="time"
value={entityTimeValue}
onChange={onEntityTimeValueChange}
@@ -54,6 +55,7 @@ export const EntityValue: FunctionComponent<TableEntityProps> = ({
label={entityValueLabel && entityValueLabel}
className="addEntityTextField"
id="entityValueId"
autoFocus
disabled={isEntityValueDisable}
type={entityValueType}
placeholder={entityValuePlaceholder}

View File

@@ -1,4 +1,4 @@
import React, { FunctionComponent, MutableRefObject, useEffect, useRef } from "react";
import React, { FunctionComponent } from "react";
import arrowLeftImg from "../../images/imgarrowlefticon.svg";
import refreshImg from "../../images/refresh-cosmos.svg";
import { AuthType } from "../AuthType";
@@ -6,7 +6,6 @@ import Explorer from "../Explorer/Explorer";
import { ResourceTokenTree } from "../Explorer/Tree/ResourceTokenTree";
import { ResourceTree } from "../Explorer/Tree/ResourceTree";
import { userContext } from "../UserContext";
import { NormalizedEventKey } from "./Constants";
export interface ResourceTreeContainerProps {
toggleLeftPaneExpanded: () => void;
@@ -19,22 +18,6 @@ export const ResourceTreeContainer: FunctionComponent<ResourceTreeContainerProps
isLeftPaneExpanded,
container,
}: ResourceTreeContainerProps): JSX.Element => {
const focusButton = useRef<HTMLLIElement>() as MutableRefObject<HTMLLIElement>;
useEffect(() => {
if (isLeftPaneExpanded) {
if (focusButton.current) {
focusButton.current.focus();
}
}
});
const onKeyPressToggleLeftPaneExpanded = (event: React.KeyboardEvent) => {
if (event.key === NormalizedEventKey.Space || event.key === NormalizedEventKey.Enter) {
toggleLeftPaneExpanded();
event.stopPropagation();
}
};
return (
<div id="main" className={isLeftPaneExpanded ? "main" : "hiddenMain"}>
{/* Collections Window - - Start */}
@@ -60,11 +43,9 @@ export const ResourceTreeContainer: FunctionComponent<ResourceTreeContainerProps
id="expandToggleLeftPaneButton"
role="button"
onClick={toggleLeftPaneExpanded}
onKeyPress={onKeyPressToggleLeftPaneExpanded}
tabIndex={0}
aria-label="Collapse Tree"
title="Collapse Tree"
ref={focusButton}
>
<img className="refreshcol1" src={arrowLeftImg} alt="Hide" />
</span>

View File

@@ -96,6 +96,7 @@ export const TableEntity: FunctionComponent<TableEntityProps> = ({
<TextField
label={entityPropertyLabel && entityPropertyLabel}
id="entityPropertyId"
autoFocus
disabled={isPropertyTypeDisable}
placeholder={entityPropertyPlaceHolder}
value={entityProperty}

View File

@@ -9,7 +9,7 @@ export const InfoTooltip: React.FunctionComponent<TooltipProps> = ({ children }:
return (
<span>
<TooltipHost content={children}>
<Icon iconName="Info" ariaLabel="Info" className="panelInfoIcon" tabIndex={0} />
<Icon iconName="Info" ariaLabel="Info" className="panelInfoIcon" />
</TooltipHost>
</span>
);

View File

@@ -66,15 +66,9 @@ export const Upload: FunctionComponent<UploadProps> = ({
onChange={onUpload}
role="button"
/>
<span
id="fileImportLinkNotebook"
role="button"
tabIndex={0}
onClick={onImportLinkClick}
onKeyPress={onImportLinkKeyPress}
>
<a href="#" id="fileImportLinkNotebook" onClick={onImportLinkClick} onKeyPress={onImportLinkKeyPress}>
<Image className="fileImportImg" src={FolderIcon} alt={title} title={title} />
</span>
</a>
</Stack>
</div>
);

View File

@@ -55,13 +55,7 @@ export class AccordionItemComponent extends React.Component<AccordionItemCompone
public render(): JSX.Element {
return (
<div className="accordionItemContainer">
<div
className="accordionItemHeader"
onClick={this.onHeaderClick}
onKeyPress={this.onHeaderKeyPress}
role="button"
tabIndex={0}
>
<div className="accordionItemHeader" onClick={this.onHeaderClick} onKeyPress={this.onHeaderKeyPress}>
{this.renderCollapseExpandIcon()}
{this.props.title}
</div>
@@ -80,6 +74,8 @@ export class AccordionItemComponent extends React.Component<AccordionItemCompone
className="expandCollapseIcon"
src={this.state.isExpanded ? TriangleDownIcon : TriangleRightIcon}
alt="Hide"
tabIndex={0}
role="button"
/>
);
}

View File

@@ -1,6 +1,5 @@
import { Icon, Label, Stack } from "@fluentui/react";
import * as React from "react";
import { NormalizedEventKey } from "../../../Common/Constants";
import { accordionStackTokens } from "../Settings/SettingsRenderUtils";
export interface CollapsibleSectionProps {
@@ -31,13 +30,6 @@ export class CollapsibleSectionComponent extends React.Component<CollapsibleSect
}
}
private onKeyPress = (event: React.KeyboardEvent) => {
if (event.key === NormalizedEventKey.Space || event.key === NormalizedEventKey.Enter) {
this.toggleCollapsed();
event.stopPropagation();
}
};
public render(): JSX.Element {
return (
<>
@@ -47,11 +39,6 @@ export class CollapsibleSectionComponent extends React.Component<CollapsibleSect
verticalAlign="center"
tokens={accordionStackTokens}
onClick={this.toggleCollapsed}
onKeyPress={this.onKeyPress}
tabIndex={0}
aria-label="Advanced"
role="button"
aria-expanded={this.state.isExpanded}
>
<Icon iconName={this.state.isExpanded ? "ChevronDown" : "ChevronRight"} />
<Label>{this.props.title}</Label>

View File

@@ -3,14 +3,9 @@
exports[`CollapsibleSectionComponent renders 1`] = `
<Fragment>
<Stack
aria-expanded={true}
aria-label="Advanced"
className="collapsibleSection"
horizontal={true}
onClick={[Function]}
onKeyPress={[Function]}
role="button"
tabIndex={0}
tokens={
Object {
"childrenGap": 10,

View File

@@ -188,13 +188,12 @@ export class CommandButtonComponent extends React.Component<CommandButtonCompone
ref={(ref: HTMLElement) => {
this.expandButtonElt = ref;
}}
role="button"
onKeyDown={(e: React.KeyboardEvent<HTMLDivElement>) => this.onLauncherKeyDown(e)}
>
<div className="commandDropdownLauncher">
<span className="partialSplitter" />
<span className="expandDropdown">
<img src={CollapseChevronDownIcon} alt="Collapse down icon" />
<img src={CollapseChevronDownIcon} />
</span>
</div>
<div

View File

@@ -8,9 +8,6 @@
.input-type-head-text-field {
width: 100%;
}
.input-query-form {
width: 100%;
}
textarea {
width: 100%;
line-height: 1;

View File

@@ -160,21 +160,18 @@ export class InputTypeaheadComponent extends React.Component<
return (
<div className="input-typeahead-container">
<Stack horizontal>
<form aria-labelledby="input" className="input-query-form">
<TextField
multiline={useTextarea}
rows={1}
id="input"
defaultValue={defaultValue}
ariaLabel="Input query"
placeholder={placeholder}
className="input-type-head-text-field"
value={defaultValue}
onKeyDown={this.onSubmit}
onFocus={() => this.setState({ isSuggestionVisible: true })}
onChange={(_event, newValue?: string) => this.handleChange(newValue)}
/>
</form>
<TextField
multiline={useTextarea}
rows={1}
defaultValue={defaultValue}
ariaLabel="Input query"
placeholder={placeholder}
className="input-type-head-text-field"
value={defaultValue}
onKeyDown={this.onSubmit}
onFocus={() => this.setState({ isSuggestionVisible: true })}
onChange={(_event, newValue?: string) => this.handleChange(newValue)}
/>
{this.props.showCancelButton && (
<IconButton
styles={iconButtonStyles}

View File

@@ -7,22 +7,16 @@ exports[`inputTypeahead renders <input /> 1`] = `
<Stack
horizontal={true}
>
<form
aria-labelledby="input"
className="input-query-form"
>
<StyledTextFieldBase
ariaLabel="Input query"
className="input-type-head-text-field"
id="input"
multiline={false}
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
placeholder="placeholder"
rows={1}
/>
</form>
<StyledTextFieldBase
ariaLabel="Input query"
className="input-type-head-text-field"
multiline={false}
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
placeholder="placeholder"
rows={1}
/>
</Stack>
</div>
`;
@@ -34,22 +28,16 @@ exports[`inputTypeahead renders <textarea /> 1`] = `
<Stack
horizontal={true}
>
<form
aria-labelledby="input"
className="input-query-form"
>
<StyledTextFieldBase
ariaLabel="Input query"
className="input-type-head-text-field"
id="input"
multiline={true}
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
placeholder="placeholder"
rows={1}
/>
</form>
<StyledTextFieldBase
ariaLabel="Input query"
className="input-type-head-text-field"
multiline={true}
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
placeholder="placeholder"
rows={1}
/>
</Stack>
</div>
`;

View File

@@ -150,7 +150,7 @@ export class QueriesGridComponent extends React.Component<QueriesGridComponentPr
To write a new query, open a new query tab and enter the desired query. Once ready to save, click on Save
Query and follow the prompt in order to save the query.
</div>
<img {...bannerProps} alt="Save query helper banner" />
<img {...bannerProps} />
</div>
);
}

View File

@@ -65,7 +65,7 @@ export interface PriceBreakdown {
currencySign: string;
}
export const infoAndToolTipTextStyle: ITextStyles = { root: { fontSize: 14, color: "windowtext" } };
export const infoAndToolTipTextStyle: ITextStyles = { root: { fontSize: 14 } };
export const noLeftPaddingCheckBoxStyle: ICheckboxStyles = {
label: {
@@ -272,7 +272,7 @@ export const manualToAutoscaleDisclaimerElement: JSX.Element = (
<Text styles={infoAndToolTipTextStyle} id="manualToAutoscaleDisclaimerElement">
The starting autoscale max RU/s will be determined by the system, based on the current manual throughput settings
and storage of your resource. After autoscale has been enabled, you can change the max RU/s.{" "}
<Link href={Urls.autoscaleMigration}>Learn more</Link>
<a href={Urls.autoscaleMigration}>Learn more</a>
</Text>
);

View File

@@ -122,7 +122,7 @@ export class IndexingPolicyComponent extends React.Component<
{isDirty(this.props.indexingPolicyContent, this.props.indexingPolicyContentBaseline) && (
<MessageBar messageBarType={MessageBarType.warning}>{indexingPolicynUnsavedWarningMessage}</MessageBar>
)}
<div className="settingsV2IndexingPolicyEditor" ref={this.indexingPolicyDiv}></div>
<div className="settingsV2IndexingPolicyEditor" tabIndex={0} ref={this.indexingPolicyDiv}></div>
</Stack>
);
}

View File

@@ -8,7 +8,6 @@ exports[`IndexingPolicyRefreshComponent renders 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}

View File

@@ -20,7 +20,6 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -40,7 +39,6 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -75,7 +73,6 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -83,11 +80,11 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
>
The starting autoscale max RU/s will be determined by the system, based on the current manual throughput settings and storage of your resource. After autoscale has been enabled, you can change the max RU/s.
<StyledLinkBase
<a
href="https://aka.ms/cosmos-autoscale-migration"
>
Learn more
</StyledLinkBase>
</a>
</Text>
</StyledMessageBar>
<StyledChoiceGroup
@@ -189,7 +186,6 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -464,7 +460,6 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}

View File

@@ -13,6 +13,7 @@ exports[`IndexingPolicyComponent renders 1`] = `
/>
<div
className="settingsV2IndexingPolicyEditor"
tabIndex={0}
/>
</Stack>
`;

View File

@@ -16,7 +16,6 @@ exports[`ScaleComponent renders with correct initial notification 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}

View File

@@ -136,7 +136,6 @@ exports[`SubSettingsComponent analyticalTimeToLive hidden 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -413,7 +412,6 @@ exports[`SubSettingsComponent analyticalTimeToLiveSeconds hidden 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -954,7 +952,6 @@ exports[`SubSettingsComponent renders 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -1231,7 +1228,6 @@ exports[`SubSettingsComponent timeToLiveSeconds hidden 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}

View File

@@ -159,7 +159,6 @@ exports[`SettingsUtils functions render 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -167,17 +166,16 @@ exports[`SettingsUtils functions render 1`] = `
>
The starting autoscale max RU/s will be determined by the system, based on the current manual throughput settings and storage of your resource. After autoscale has been enabled, you can change the max RU/s.
<StyledLinkBase
<a
href="https://aka.ms/cosmos-autoscale-migration"
>
Learn more
</StyledLinkBase>
</a>
</Text>
<Text
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -197,7 +195,6 @@ exports[`SettingsUtils functions render 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -210,7 +207,6 @@ exports[`SettingsUtils functions render 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -223,7 +219,6 @@ exports[`SettingsUtils functions render 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -235,7 +230,6 @@ exports[`SettingsUtils functions render 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -255,7 +249,6 @@ exports[`SettingsUtils functions render 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -271,7 +264,6 @@ exports[`SettingsUtils functions render 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -286,7 +278,6 @@ exports[`SettingsUtils functions render 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -300,7 +291,6 @@ exports[`SettingsUtils functions render 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -312,7 +302,6 @@ exports[`SettingsUtils functions render 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -332,7 +321,6 @@ exports[`SettingsUtils functions render 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -375,7 +363,6 @@ exports[`SettingsUtils functions render 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -391,7 +378,6 @@ exports[`SettingsUtils functions render 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}
@@ -408,7 +394,6 @@ exports[`SettingsUtils functions render 1`] = `
styles={
Object {
"root": Object {
"color": "windowtext",
"fontSize": 14,
},
}

View File

@@ -1,6 +1,7 @@
@import "../../../../less/Common/Constants";
.tabComponentContainer {
overflow: hidden;
height: 100%;
.flex-display();
.flex-direction();

View File

@@ -21,12 +21,10 @@ describe("ThroughputInput Pane", () => {
});
it("should switch mode properly", () => {
wrapper.find('[aria-label="Manual mode"]').simulate("change");
expect(wrapper.find('[aria-label="Throughput header"]').at(0).text()).toBe(
"Container throughput (400 - unlimited RU/s)"
);
wrapper.find(".ms-ChoiceField-input").at(0).simulate("change");
expect(wrapper.find("#throughPut").at(0).text()).toBe("Container throughput (autoscale)");
wrapper.find('[aria-label="Autoscale mode"]').simulate("change");
expect(wrapper.find('[aria-label="Throughput header"]').at(0).text()).toBe("Container throughput (autoscale)");
wrapper.find(".ms-ChoiceField-input").at(1).simulate("change");
expect(wrapper.find("#throughPut").at(0).text()).toBe("Container throughput (400 - unlimited RU/s)");
});
});

View File

@@ -1,4 +1,15 @@
import { Checkbox, DirectionalHint, Link, Stack, Text, TextField, TooltipHost } from "@fluentui/react";
import {
Checkbox,
ChoiceGroup,
DirectionalHint,
IChoiceGroupOption,
Label,
Link,
Stack,
Text,
TextField,
TooltipHost,
} from "@fluentui/react";
import React, { FunctionComponent, useState } from "react";
import * as Constants from "../../../Common/Constants";
import { InfoTooltip } from "../../../Common/Tooltip/InfoTooltip";
@@ -90,7 +101,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
);
};
const handleOnChangeMode = (event: React.ChangeEvent<HTMLInputElement>, mode: string): void => {
const handleOnChangeMode = (_: React.ChangeEvent<HTMLInputElement>, mode: string): void => {
if (mode === "Autoscale") {
setThroughput(AutoPilotUtils.minAutoPilotThroughput);
setIsAutoScaleSelected(true);
@@ -103,37 +114,46 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
setIsAutoscale(false);
}
};
const choiceButtonStyles = {
flexContainer: [
{
selectors: {
".ms-ChoiceField-wrapper label": {
fontSize: 12,
paddingTop: 0,
},
".ms-ChoiceField": {
marginTop: 0,
},
},
},
],
};
const throughPutOptions: IChoiceGroupOption[] = [
{ key: "Autoscale", text: "Autoscale" },
{ key: "Manual", text: "Manual" },
];
return (
<div className="throughputInputContainer throughputInputSpacing">
<Stack horizontal>
<span className="mandatoryStar">*&nbsp;</span>
<Text aria-label="Throughput header" variant="small" style={{ lineHeight: "20px", fontWeight: 600 }}>
<Label id="throughPut" aria-label={getThroughputLabelText()} style={{ lineHeight: "20px", fontWeight: 600 }}>
{getThroughputLabelText()}
</Text>
</Label>
<InfoTooltip>{PricingUtils.getRuToolTipText()}</InfoTooltip>
</Stack>
<Stack horizontal verticalAlign="center">
<input
className="throughputInputRadioBtn"
aria-label="Autoscale mode"
checked={isAutoscaleSelected}
type="radio"
tabIndex={0}
onChange={(e) => handleOnChangeMode(e, "Autoscale")}
<Stack verticalAlign="center">
<ChoiceGroup
ariaLabelledBy="throughPut"
styles={choiceButtonStyles}
options={throughPutOptions}
defaultSelectedKey={throughPutOptions[0].key}
onChange={(_: React.ChangeEvent<HTMLInputElement>, options: IChoiceGroupOption) =>
handleOnChangeMode(_, options.key.toString())
}
required
/>
<span className="throughputInputRadioBtnLabel">Autoscale</span>
<input
className="throughputInputRadioBtn"
aria-label="Manual mode"
checked={!isAutoscaleSelected}
type="radio"
tabIndex={0}
onChange={(e) => handleOnChangeMode(e, "Manual")}
/>
<span className="throughputInputRadioBtnLabel">Manual</span>
</Stack>
{isAutoscaleSelected && (

View File

@@ -243,7 +243,6 @@ export class TreeNodeComponent extends React.Component<TreeNodeComponentProps, T
<div ref={this.contextMenuRef} onContextMenu={this.onRightClick} onKeyPress={this.onMoreButtonKeyPress}>
<IconButton
name="More"
title="More"
className="treeMenuEllipsis"
ariaLabel={menuItemLabel}
menuIconProps={{

View File

@@ -211,7 +211,6 @@ exports[`TreeNodeComponent renders a simple node (sorted children, expanded) 1`]
},
}
}
title="More"
/>
</div>
</div>
@@ -424,7 +423,6 @@ exports[`TreeNodeComponent renders sorted children, expanded, leaves and parents
},
}
}
title="More"
/>
</div>
</div>

View File

@@ -214,14 +214,8 @@ export class EditorNeighborsComponent extends React.Component<EditorNeighborsCom
/>
</td>
<td className="actionCol">
<span
className="rightPaneTrashIcon rightPaneBtns"
role="button"
onKeyPress={() => this.removeAddedEdgeToNeighbor(index)}
onClick={() => this.removeAddedEdgeToNeighbor(index)}
tabIndex={0}
>
<img src={DeleteIcon} alt="Delete" />
<span className="rightPaneTrashIcon rightPaneBtns">
<img src={DeleteIcon} alt="Delete" onClick={() => this.removeAddedEdgeToNeighbor(index)} />
</span>
</td>
</tr>

View File

@@ -123,7 +123,7 @@ export class EditorNodePropertiesComponent extends React.Component<EditorNodePro
<select
className="typeSelect"
value={singleValue.type}
onBlur={(e) => {
onChange={(e) => {
singleValue.type = e.target.value as ViewModels.InputPropertyValueTypeString;
if (singleValue.type === "null") {
singleValue.value = undefined;
@@ -217,7 +217,7 @@ export class EditorNodePropertiesComponent extends React.Component<EditorNodePro
<select
className="typeSelect"
value={firstValue.type}
onBlur={(e) => {
onChange={(e) => {
firstValue.type = e.target.value as ViewModels.InputPropertyValueTypeString;
this.props.onUpdateProperties(this.props.editedProperties);
}}

View File

@@ -1,8 +1,8 @@
import * as React from "react";
import { GraphVizComponent, GraphVizComponentProps } from "./GraphVizComponent";
import CollapseArrowIcon from "../../../../images/Collapse_arrow_14x14.svg";
import ExpandIcon from "../../../../images/Expand_14x14.svg";
import LoadingIndicatorIcon from "../../../../images/LoadingIndicator_3Squares.gif";
import { GraphVizComponent, GraphVizComponentProps } from "./GraphVizComponent";
interface MiddlePaneComponentProps {
isTabsContentExpanded: boolean;
@@ -17,14 +17,7 @@ export class MiddlePaneComponent extends React.Component<MiddlePaneComponentProp
<div className="middlePane">
<div className="graphTitle">
<span className="paneTitle">Graph</span>
<span
className="graphExpandCollapseBtn pull-right"
onClick={this.props.toggleExpandGraph}
role="button"
aria-expanded={this.props.isTabsContentExpanded}
aria-name="View graph in full screen"
tabIndex={0}
>
<span className="graphExpandCollapseBtn pull-right" onClick={this.props.toggleExpandGraph}>
<img
src={this.props.isTabsContentExpanded ? CollapseArrowIcon : ExpandIcon}
alt={this.props.isTabsContentExpanded ? "collapse graph content" : "expand graph content"}

View File

@@ -93,7 +93,7 @@ exports[`<EditorNodePropertiesComponent /> renders component 1`] = `
<td>
<select
className="typeSelect"
onBlur={[Function]}
onChange={[Function]}
required={true}
value="string"
>
@@ -282,7 +282,7 @@ exports[`<EditorNodePropertiesComponent /> renders proper unicode 1`] = `
<td>
<select
className="typeSelect"
onBlur={[Function]}
onChange={[Function]}
required={true}
value="string"
>
@@ -344,7 +344,7 @@ exports[`<EditorNodePropertiesComponent /> renders proper unicode 1`] = `
<td>
<select
className="typeSelect"
onBlur={[Function]}
onChange={[Function]}
required={true}
value="string"
>

File diff suppressed because it is too large Load Diff

View File

@@ -132,6 +132,7 @@ export const NewVertexComponent: FunctionComponent<INewVertexComponentProps> = (
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
onLabelChange(event);
}}
autoFocus
/>
<div className="actionCol"></div>
</div>

View File

@@ -103,7 +103,6 @@ export class NotificationConsoleComponent extends React.Component<
onClick={() => this.expandCollapseConsole()}
onKeyDown={(event: React.KeyboardEvent<HTMLDivElement>) => this.onExpandCollapseKeyPress(event)}
tabIndex={0}
role="button"
>
<div className="statusBar">
<span className="dataTypeIcons">
@@ -130,7 +129,7 @@ export class NotificationConsoleComponent extends React.Component<
className="expandCollapseButton"
role="button"
tabIndex={0}
aria-label={"console button" + (this.props.isConsoleExpanded ? " expanded" : " collapsed")}
aria-label={"console button" + (this.props.isConsoleExpanded ? " collapsed" : " expanded")}
aria-expanded={!this.props.isConsoleExpanded}
>
<img
@@ -163,7 +162,7 @@ export class NotificationConsoleComponent extends React.Component<
onKeyDown={(event: React.KeyboardEvent<HTMLSpanElement>) => this.onClearNotificationsKeyPress(event)}
tabIndex={0}
>
<img src={ClearIcon} alt="clear notifications icon" />
<img src={ClearIcon} alt="clear notifications image" />
Clear Notifications
</span>
</div>
@@ -206,9 +205,7 @@ export class NotificationConsoleComponent extends React.Component<
{item.type === ConsoleDataType.Error && <img className="errorIcon" src={ErrorRedIcon} alt="error" />}
{item.type === ConsoleDataType.InProgress && <img className="loaderIcon" src={LoaderIcon} alt="in progress" />}
<span className="date">{item.date}</span>
<span className="message" role="alert" aria-live="assertive">
{item.message}
</span>
<span className="message">{item.message}</span>
</div>
));
}

View File

@@ -9,7 +9,6 @@ exports[`NotificationConsoleComponent renders the console 1`] = `
id="notificationConsoleHeader"
onClick={[Function]}
onKeyDown={[Function]}
role="button"
tabIndex={0}
>
<div
@@ -71,7 +70,7 @@ exports[`NotificationConsoleComponent renders the console 1`] = `
</div>
<div
aria-expanded={true}
aria-label="console button collapsed"
aria-label="console button expanded"
className="expandCollapseButton"
role="button"
tabIndex={0}
@@ -151,7 +150,7 @@ exports[`NotificationConsoleComponent renders the console 1`] = `
tabIndex={0}
>
<img
alt="clear notifications icon"
alt="clear notifications image"
src=""
/>
Clear Notifications
@@ -174,7 +173,6 @@ exports[`NotificationConsoleComponent renders the console 2`] = `
id="notificationConsoleHeader"
onClick={[Function]}
onKeyDown={[Function]}
role="button"
tabIndex={0}
>
<div
@@ -238,7 +236,7 @@ exports[`NotificationConsoleComponent renders the console 2`] = `
</div>
<div
aria-expanded={true}
aria-label="console button collapsed"
aria-label="console button expanded"
className="expandCollapseButton"
role="button"
tabIndex={0}
@@ -318,7 +316,7 @@ exports[`NotificationConsoleComponent renders the console 2`] = `
tabIndex={0}
>
<img
alt="clear notifications icon"
alt="clear notifications image"
src=""
/>
Clear Notifications
@@ -342,9 +340,7 @@ exports[`NotificationConsoleComponent renders the console 2`] = `
date
</span>
<span
aria-live="assertive"
className="message"
role="alert"
>
message
</span>

View File

@@ -161,7 +161,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
true
).toLocaleLowerCase()}.`}
>
<Icon iconName="Info" className="panelInfoIcon" tabIndex={0} />
<Icon iconName="Info" className="panelInfoIcon" />
</TooltipHost>
</Stack>
@@ -173,6 +173,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
aria-checked={this.state.createNewDatabase}
name="databaseType"
type="radio"
role="radio"
id="databaseCreateNew"
tabIndex={0}
onChange={this.onCreateNewDatabaseRadioBtnChange.bind(this)}
@@ -186,6 +187,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
aria-checked={!this.state.createNewDatabase}
name="databaseType"
type="radio"
role="radio"
tabIndex={0}
onChange={this.onUseExistingDatabaseRadioBtnChange.bind(this)}
/>
@@ -207,7 +209,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
size={40}
className="panelTextField"
aria-label="New database id"
tabIndex={0}
autoFocus
value={this.state.newDatabaseId}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
this.setState({ newDatabaseId: event.target.value })
@@ -234,7 +236,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
true
).toLocaleLowerCase()} within the database.`}
>
<Icon iconName="Info" className="panelInfoIcon" tabIndex={0} />
<Icon iconName="Info" className="panelInfoIcon" />
</TooltipHost>
</Stack>
)}
@@ -277,7 +279,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
directionalHint={DirectionalHint.bottomLeftEdge}
content={`Unique identifier for the ${getCollectionName().toLocaleLowerCase()} and used for id-based routing through REST and all SDKs.`}
>
<Icon iconName="Info" className="panelInfoIcon" tabIndex={0} />
<Icon iconName="Info" className="panelInfoIcon" />
</TooltipHost>
</Stack>
@@ -317,6 +319,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
aria-label="Turn on indexing"
aria-checked={this.state.enableIndexing}
type="radio"
role="radio"
tabIndex={0}
onChange={this.onTurnOnIndexing.bind(this)}
/>
@@ -328,6 +331,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
aria-label="Turn off indexing"
aria-checked={!this.state.enableIndexing}
type="radio"
role="radio"
tabIndex={0}
onChange={this.onTurnOffIndexing.bind(this)}
/>
@@ -358,7 +362,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
"Sharded collections split your data across many replica sets (shards) to achieve unlimited scalability. Sharded collections require choosing a shard key (field) to evenly distribute your data."
}
>
<Icon iconName="Info" className="panelInfoIcon" tabIndex={0} />
<Icon iconName="Info" className="panelInfoIcon" />
</TooltipHost>
</Stack>
@@ -370,6 +374,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
aria-checked={!this.state.isSharded}
name="unsharded"
type="radio"
role="radio"
id="unshardedOption"
tabIndex={0}
onChange={this.onUnshardedRadioBtnChange.bind(this)}
@@ -383,6 +388,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
aria-checked={this.state.isSharded}
name="sharded"
type="radio"
role="radio"
id="shardedOption"
tabIndex={0}
onChange={this.onShardedRadioBtnChange.bind(this)}
@@ -403,7 +409,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
directionalHint={DirectionalHint.bottomLeftEdge}
content={this.getPartitionKeyTooltipText()}
>
<Icon iconName="Info" className="panelInfoIcon" tabIndex={0} />
<Icon iconName="Info" className="panelInfoIcon" />
</TooltipHost>
</Stack>
@@ -461,7 +467,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
does not count towards the throughput you provisioned for the database. This throughput amount will be
billed in addition to the throughput amount you provisioned at the database level.`}
>
<Icon iconName="Info" className="panelInfoIcon" tabIndex={0} />
<Icon iconName="Info" className="panelInfoIcon" />
</TooltipHost>
</Stack>
)}
@@ -491,7 +497,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
creating a unique key policy when a container is created, you ensure the uniqueness of one or more values
per partition key."
>
<Icon iconName="Info" className="panelInfoIcon" tabIndex={0} />
<Icon iconName="Info" className="panelInfoIcon" />
</TooltipHost>
</Stack>
@@ -508,6 +514,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
: "Comma separated paths e.g. /firstName,/address/zipCode"
}
className="panelTextField"
autoFocus
value={uniqueKey}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
const uniqueKeys = this.state.uniqueKeys.map((uniqueKey: string, j: number) => {
@@ -553,7 +560,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
directionalHint={DirectionalHint.bottomLeftEdge}
content={this.getAnalyticalStorageTooltipContent()}
>
<Icon iconName="Info" className="panelInfoIcon" tabIndex={0} />
<Icon iconName="Info" className="panelInfoIcon" />
</TooltipHost>
</Stack>
@@ -566,6 +573,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
aria-checked={this.state.enableAnalyticalStore}
name="analyticalStore"
type="radio"
role="radio"
id="enableAnalyticalStoreBtn"
tabIndex={0}
onChange={this.onEnableAnalyticalStoreRadioBtnChange.bind(this)}
@@ -580,6 +588,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
aria-checked={!this.state.enableAnalyticalStore}
name="analyticalStore"
type="radio"
role="radio"
id="disableAnalyticalStoreBtn"
tabIndex={0}
onChange={this.onDisableAnalyticalStoreRadioBtnChange.bind(this)}
@@ -628,7 +637,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
directionalHint={DirectionalHint.bottomLeftEdge}
content="The _id field is indexed by default. Creating a wildcard index for all fields will optimize queries and is recommended for development."
>
<Icon iconName="Info" className="panelInfoIcon" tabIndex={0} />
<Icon iconName="Info" className="panelInfoIcon" />
</TooltipHost>
</Stack>

View File

@@ -23,12 +23,10 @@ import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneFor
export interface AddDatabasePaneProps {
explorer: Explorer;
buttonElement?: HTMLElement;
}
export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
explorer: container,
buttonElement,
}: AddDatabasePaneProps) => {
const closeSidePanel = useSidePanel((state) => state.closeSidePanel);
let throughput: number;
@@ -79,7 +77,6 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
dataExplorerArea: Constants.Areas.ContextualPane,
};
TelemetryProcessor.trace(Action.CreateDatabase, ActionModifiers.Open, addDatabasePaneOpenMessage);
buttonElement.focus();
}, []);
const onSubmit = () => {
@@ -210,6 +207,7 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
placeholder={databaseIdPlaceHolder}
value={databaseId}
onChange={handleonChangeDBId}
autoFocus
styles={getTextFieldStyles()}
/>

View File

@@ -33,6 +33,7 @@ exports[`AddDatabasePane Pane should render Default properly 1`] = `
aria-label="Database id"
aria-required="true"
autoComplete="off"
autoFocus={true}
id="database-id"
onChange={[Function]}
pattern="[^/?#\\\\\\\\]*[^/?# \\\\\\\\]"

View File

@@ -169,6 +169,7 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
aria-label="Create new keyspace"
checked={keyspaceCreateNew}
type="radio"
role="radio"
tabIndex={0}
onChange={() => {
setKeyspaceCreateNew(true);
@@ -183,6 +184,7 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
aria-label="Use existing keyspace"
checked={!keyspaceCreateNew}
type="radio"
role="radio"
tabIndex={0}
onChange={() => {
setKeyspaceCreateNew(false);
@@ -196,7 +198,6 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
<Stack className="panelGroupSpacing">
<TextField
aria-required="true"
required={true}
autoComplete="off"
styles={getTextFieldStyles()}
pattern="[^/?#\\]*[^/?# \\]"
@@ -206,6 +207,7 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
value={newKeyspaceId}
onChange={(e, newValue) => setNewKeyspaceId(newValue)}
ariaLabel="Keyspace id"
autoFocus
/>
{!isServerlessAccount() && (
@@ -283,7 +285,6 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
underlined
styles={getTextFieldStyles({ fontSize: 12, width: 150 })}
aria-required="true"
required={true}
ariaLabel="addCollection-tableId"
autoComplete="off"
pattern="[^/?#\\]*[^/?# \\]"

View File

@@ -108,8 +108,6 @@ export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectio
submitButtonText: "OK",
onSubmit,
};
const confirmContainer = `Confirm by typing the ${collectionName.toLowerCase()} id`;
const reasonInfo = `Help us improve Azure Cosmos DB! What is the reason why you are deleting this ${collectionName}?`;
return (
<RightPaneForm {...props}>
<div className="panelFormWrapper">
@@ -119,12 +117,12 @@ export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectio
<Text variant="small">Confirm by typing the {collectionName.toLowerCase()} id</Text>
<TextField
id="confirmCollectionId"
autoFocus
value={inputCollectionName}
styles={{ fieldGroup: { width: 300 } }}
onChange={(event, newInput?: string) => {
setInputCollectionName(newInput);
}}
ariaLabel={confirmContainer}
/>
</div>
{shouldRecordFeedback() && (
@@ -144,7 +142,6 @@ export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectio
onChange={(event, newInput?: string) => {
setDeleteCollectionFeedback(newInput);
}}
ariaLabel={reasonInfo}
/>
</div>
)}

View File

@@ -40,7 +40,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
</span>
</Text>
<StyledTextFieldBase
ariaLabel="Confirm by typing the container id"
autoFocus={true}
id="confirmCollectionId"
onChange={[Function]}
styles={
@@ -53,7 +53,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
value=""
>
<TextFieldBase
ariaLabel="Confirm by typing the container id"
autoFocus={true}
deferredValidationTime={200}
id="confirmCollectionId"
onChange={[Function]}
@@ -346,7 +346,7 @@ exports[`Delete Collection Confirmation Pane submit() should call delete collect
>
<input
aria-invalid={false}
aria-label="Confirm by typing the container id"
autoFocus={true}
className="ms-TextField-field field-57"
id="confirmCollectionId"
onBlur={[Function]}

View File

@@ -118,8 +118,7 @@ export const DeleteDatabaseConfirmationPanel: FunctionComponent<DeleteDatabaseCo
message:
"Warning! The action you are about to take cannot be undone. Continuing will permanently delete this resource and all of its children resources.",
};
const confirmDatabase = "Confirm by typing the database id";
const reasonInfo = "Help us improve Azure Cosmos DB! What is the reason why you are deleting this database?";
return (
<RightPaneForm {...props}>
{!formError && <PanelInfoErrorComponent {...errorProps} />}
@@ -129,11 +128,11 @@ export const DeleteDatabaseConfirmationPanel: FunctionComponent<DeleteDatabaseCo
<Text variant="small">Confirm by typing the database id</Text>
<TextField
id="confirmDatabaseId"
autoFocus
styles={{ fieldGroup: { width: 300 } }}
onChange={(event, newInput?: string) => {
setDatabaseInput(newInput);
}}
ariaLabel={confirmDatabase}
/>
</div>
{isLastNonEmptyDatabase() && (
@@ -152,7 +151,6 @@ export const DeleteDatabaseConfirmationPanel: FunctionComponent<DeleteDatabaseCo
onChange={(event, newInput?: string) => {
setDatabaseFeedbackInput(newInput);
}}
ariaLabel={reasonInfo}
/>
</div>
)}

View File

@@ -153,7 +153,7 @@ export const ExecuteSprocParamsPane: FunctionComponent<ExecuteSprocParamsPanePro
selectedKey={paramKeyValue && paramKeyValue.key}
/>
))}
<Stack horizontal onClick={addNewParamAtLastIndex} tabIndex={0}>
<Stack horizontal onClick={addNewParamAtLastIndex}>
<Image {...imageProps} src={AddPropertyIcon} alt="Add param" />
<Text className="addNewParamStyle">Add New Param</Text>
</Stack>

View File

@@ -59,22 +59,30 @@ export const InputParameter: FunctionComponent<InputParameterProps> = ({
onChange={onParamKeyChange}
options={options}
styles={dropdownStyles}
tabIndex={0}
/>
<TextField
label={inputLabel && inputLabel}
id="confirmCollectionId"
autoFocus
value={paramValue}
onChange={onParamValueChange}
/>
{isAddRemoveVisible && (
<>
<div tabIndex={0} onClick={onDeleteParamKeyPress} role="button" onKeyPress={onDeleteParamKeyPress}>
<Image {...imageProps} src={EntityCancelIcon} alt="Delete param" id="deleteparam" />
</div>
<div tabIndex={0} onClick={onAddNewParamKeyPress} role="button" onKeyPress={onAddNewParamKeyPress}>
<Image {...imageProps} src={AddPropertyIcon} alt="Add param" id="addparam" />
</div>
<Image
{...imageProps}
src={EntityCancelIcon}
alt="Delete param"
id="deleteparam"
onClick={onDeleteParamKeyPress}
/>
<Image
{...imageProps}
src={AddPropertyIcon}
alt="Add param"
id="addparam"
onClick={onAddNewParamKeyPress}
/>
</>
)}
</Stack>

View File

@@ -92,6 +92,7 @@ export const LoadQueryPane: FunctionComponent = (): JSX.Element => {
id="confirmCollectionId"
label="Select a query document"
value={selectedFileName}
autoFocus
readOnly
styles={{ fieldGroup: { width: 300 } }}
/>

View File

@@ -17,6 +17,7 @@ exports[`Load Query Pane should render Default properly 1`] = `
horizontal={true}
>
<StyledTextFieldBase
autoFocus={true}
id="confirmCollectionId"
label="Select a query document"
readOnly={true}

View File

@@ -3,13 +3,13 @@
.panelFormWrapper {
display: flex;
flex-direction: column;
min-height: 100%;
height: 100%;
.panelMainContent {
flex-grow: 1;
padding: 0 34px;
margin: 20px 0;
overflow-x: hidden;
overflow: auto;
& > :not(.collapsibleSection) {
margin-bottom: @DefaultSpace;

View File

@@ -33,13 +33,7 @@ export const PanelInfoErrorComponent: React.FunctionComponent<PanelInfoErrorProp
<Stack className="panelInfoErrorContainer" horizontal verticalAlign="center">
{icon}
<span className="panelWarningErrorDetailsLinkContainer">
<Text
role="alert"
aria-live="assertive"
aria-label={message}
className="panelWarningErrorMessage"
variant="small"
>
<Text className="panelWarningErrorMessage" variant="small" aria-label="message">
{message}
{link && linkText && (
<Link target="_blank" href={link}>
@@ -48,15 +42,9 @@ export const PanelInfoErrorComponent: React.FunctionComponent<PanelInfoErrorProp
)}
</Text>
{showErrorDetails && (
<span
className="paneErrorLink moreOption"
role="link"
onClick={expandConsole}
onKeyPress={expandConsole}
tabIndex={0}
>
<a className="paneErrorLink" role="link" onClick={expandConsole}>
More details
</span>
</a>
)}
</span>
</Stack>

View File

@@ -3,6 +3,6 @@ import LoadingIndicator_3Squares from "../../../images/LoadingIndicator_3Squares
export const PanelLoadingScreen: React.FunctionComponent = () => (
<div className="dataExplorerLoaderContainer dataExplorerPaneLoaderContainer">
<img className="dataExplorerLoader" src={LoadingIndicator_3Squares} alt="loading indicator" />
<img className="dataExplorerLoader" src={LoadingIndicator_3Squares} />
</div>
);

View File

@@ -34,6 +34,6 @@ describe("Right Pane Form", () => {
it("should render error in header", () => {
render(<RightPaneForm {...props} formError="file already Exist" />);
expect(screen.getByLabelText("error")).toBeDefined();
expect(screen.getByRole("alert").innerHTML).toEqual("file already Exist");
expect(screen.getByLabelText("message").innerHTML).toEqual("file already Exist");
});
});

View File

@@ -146,6 +146,7 @@ export const SaveQueryPane: FunctionComponent<SaveQueryPaneProps> = ({ explorer
<TextField
id="saveQueryInput"
label="Name"
autoFocus
styles={{ fieldGroup: { width: 300 } }}
onChange={(event, newInput?: string) => {
setQueryName(newInput);

View File

@@ -195,6 +195,7 @@ export const SettingsPane: FunctionComponent = () => {
step={1}
className="textfontclr"
role="textbox"
tabIndex={0}
id="max-degree"
value={"" + maxDegreeOfParallelism}
onIncrement={(newValue) => setMaxDegreeOfParallelism(parseInt(newValue) + 1 || maxDegreeOfParallelism)}

View File

@@ -123,6 +123,7 @@ exports[`Settings Pane should render Default properly 1`] = `
onValidate={[Function]}
role="textbox"
step={1}
tabIndex={0}
value="6"
/>
</div>

View File

@@ -97,6 +97,7 @@ export const StringInputPane: FunctionComponent<StringInputPanelProps> = ({
label={inputLabel}
name="collectionIdConfirmation"
value={stringInput}
autoFocus
required
onChange={(event: FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string) =>
setStringInput(newValue)

View File

@@ -56,6 +56,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
>
<StyledTextFieldBase
aria-label="Enter new directory name"
autoFocus={true}
label="Enter new directory name"
name="collectionIdConfirmation"
onChange={[Function]}
@@ -64,6 +65,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
>
<TextFieldBase
aria-label="Enter new directory name"
autoFocus={true}
deferredValidationTime={200}
label="Enter new directory name"
name="collectionIdConfirmation"
@@ -653,6 +655,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
<input
aria-invalid={false}
aria-labelledby="TextFieldLabel2"
autoFocus={true}
className="ms-TextField-field field-56"
id="TextField0"
name="collectionIdConfirmation"

View File

@@ -29,7 +29,6 @@ describe("Table query select Panel", () => {
it("Should checked availableCheckbox by default", () => {
const wrapper = mount(<TableQuerySelectPanel {...props} />);
expect(wrapper.find("#availableCheckbox").first().props()).toEqual({
ariaPositionInSet: 0,
id: "availableCheckbox",
label: "Available Columns",
checked: true,

View File

@@ -128,9 +128,8 @@ export const TableQuerySelectPanel: FunctionComponent<TableQuerySelectPanelProps
label="Available Columns"
checked={isAvailableColumnChecked}
onChange={availableColumnsCheckboxClick}
ariaPositionInSet={0}
/>
{columnOptions.map((column, index) => {
{columnOptions.map((column) => {
return (
<Checkbox
label={column.columnName}
@@ -138,7 +137,6 @@ export const TableQuerySelectPanel: FunctionComponent<TableQuerySelectPanelProps
key={column.columnName}
checked={column.selected}
disabled={!column.editable}
ariaPositionInSet={index + 1}
/>
);
})}

View File

@@ -37,14 +37,12 @@ exports[`Table query select Panel should render Default properly 1`] = `
className="column-select-view"
>
<StyledCheckboxBase
ariaPositionInSet={0}
checked={true}
id="availableCheckbox"
label="Available Columns"
onChange={[Function]}
>
<CheckboxBase
ariaPositionInSet={0}
checked={true}
id="availableCheckbox"
label="Available Columns"
@@ -330,7 +328,6 @@ exports[`Table query select Panel should render Default properly 1`] = `
<input
aria-checked="true"
aria-label="Available Columns"
aria-posinset={0}
checked={true}
className="input-55"
data-ktp-execute-target={true}
@@ -649,7 +646,6 @@ exports[`Table query select Panel should render Default properly 1`] = `
</CheckboxBase>
</StyledCheckboxBase>
<StyledCheckboxBase
ariaPositionInSet={1}
checked={true}
disabled={false}
key=""
@@ -657,7 +653,6 @@ exports[`Table query select Panel should render Default properly 1`] = `
onChange={[Function]}
>
<CheckboxBase
ariaPositionInSet={1}
checked={true}
disabled={false}
label=""
@@ -944,7 +939,6 @@ exports[`Table query select Panel should render Default properly 1`] = `
aria-checked="true"
aria-disabled={false}
aria-label=""
aria-posinset={1}
checked={true}
className="input-55"
data-ktp-execute-target={true}

View File

@@ -327,17 +327,13 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
key=".0:$.1"
>
<Text
aria-label="Warning! The action you are about to take cannot be undone. Continuing will permanently delete this resource and all of its children resources."
aria-live="assertive"
aria-label="message"
className="panelWarningErrorMessage"
role="alert"
variant="small"
>
<span
aria-label="Warning! The action you are about to take cannot be undone. Continuing will permanently delete this resource and all of its children resources."
aria-live="assertive"
aria-label="message"
className="panelWarningErrorMessage css-56"
role="alert"
>
Warning! The action you are about to take cannot be undone. Continuing will permanently delete this resource and all of its children resources.
</span>
@@ -367,7 +363,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
</span>
</Text>
<StyledTextFieldBase
ariaLabel="Confirm by typing the database id"
autoFocus={true}
id="confirmDatabaseId"
onChange={[Function]}
styles={
@@ -379,7 +375,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
}
>
<TextFieldBase
ariaLabel="Confirm by typing the database id"
autoFocus={true}
deferredValidationTime={200}
id="confirmDatabaseId"
onChange={[Function]}
@@ -671,7 +667,7 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
>
<input
aria-invalid={false}
aria-label="Confirm by typing the database id"
autoFocus={true}
className="ms-TextField-field field-60"
id="confirmDatabaseId"
onBlur={[Function]}
@@ -711,7 +707,6 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
</span>
</Text>
<StyledTextFieldBase
ariaLabel="Help us improve Azure Cosmos DB! What is the reason why you are deleting this database?"
id="deleteDatabaseFeedbackInput"
multiline={true}
onChange={[Function]}
@@ -725,7 +720,6 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
}
>
<TextFieldBase
ariaLabel="Help us improve Azure Cosmos DB! What is the reason why you are deleting this database?"
deferredValidationTime={200}
id="deleteDatabaseFeedbackInput"
multiline={true}
@@ -1019,7 +1013,6 @@ exports[`Delete Database Confirmation Pane Should call delete database 1`] = `
>
<textarea
aria-invalid={false}
aria-label="Help us improve Azure Cosmos DB! What is the reason why you are deleting this database?"
className="ms-TextField-field field-71"
id="deleteDatabaseFeedbackInput"
onBlur={[Function]}

View File

@@ -108,8 +108,7 @@
}
.oneLineContent {
margin-top: 6px;
margin-left: 6px;
margin-top: 4px;
}
.twoLineContent {
@@ -134,18 +133,18 @@
.flex-display();
.flex-direction();
.title {
color: @BaseDark;
padding: 0px;
font-size: 12px;
}
.description {
color: @BaseDark;
}
>.title {
color: @BaseDark;
padding: 0px;
font-size: 12px;
}
>.description {
color: @BaseDark;
}
&:not(:hover):not(:focus) {
background-color: @BaseLow;
}
&:not(:hover):not(:focus) {
background-color: @BaseLow;
}
}
&.commonTasks {

View File

@@ -128,18 +128,18 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
<div className="title">Common Tasks</div>
<ul>
{commonTaskItems.map((item) => (
<li className="focusable" key={`${item.title}${item.description}`}>
<div
onClick={item.onClick}
onKeyPress={(event: React.KeyboardEvent) => this.onSplashScreenItemKeyPress(event, item.onClick)}
tabIndex={0}
role="button"
>
<img src={item.iconSrc} alt="" />
<span className="oneLineContent" title={item.info}>
{item.title}
</span>
</div>
<li
className="focusable"
key={`${item.title}${item.description}`}
onClick={item.onClick}
onKeyPress={(event: React.KeyboardEvent) => this.onSplashScreenItemKeyPress(event, item.onClick)}
tabIndex={0}
role="button"
>
<img src={item.iconSrc} alt="" />
<span className="oneLineContent" title={item.info}>
{item.title}
</span>
</li>
))}
</ul>
@@ -165,23 +165,22 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
<div className="title">Tips</div>
<ul>
{tipsItems.map((item) => (
<li className="tipContainer focusable" key={`${item.title}${item.description}`}>
<div
onClick={item.onClick}
onKeyPress={(event: React.KeyboardEvent) => this.onSplashScreenItemKeyPress(event, item.onClick)}
tabIndex={0}
role="button"
className="tipsWrapper"
>
<div className="title" title={item.info}>
{item.title}
</div>
<div className="description">{item.description}</div>
<li
className="tipContainer focusable"
key={`${item.title}${item.description}`}
onClick={item.onClick}
onKeyPress={(event: React.KeyboardEvent) => this.onSplashScreenItemKeyPress(event, item.onClick)}
tabIndex={0}
role="link"
>
<div className="title" title={item.info}>
{item.title}
</div>
<div className="description">{item.description}</div>
</li>
))}
<li>
<a href={SplashScreen.seeMoreItemUrl} rel="noreferrer" target="_blank" tabIndex={0}>
<a role="link" href={SplashScreen.seeMoreItemUrl} rel="noreferrer" target="_blank" tabIndex={0}>
{SplashScreen.seeMoreItemTitle}
</a>
</li>
@@ -308,23 +307,16 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
iconSrc: AddDatabaseIcon,
title: "New " + getDatabaseName(),
description: undefined,
onClick: () => this.openAddDatabasePanel(),
onClick: () =>
useSidePanel
.getState()
.openSidePanel("New " + getDatabaseName(), <AddDatabasePanel explorer={this.container} />),
});
}
return items;
}
private openAddDatabasePanel() {
const newDatabaseButton = document.activeElement as HTMLElement;
useSidePanel
.getState()
.openSidePanel(
"New " + getDatabaseName(),
<AddDatabasePanel explorer={this.container} buttonElement={newDatabaseButton} />
);
}
private decorateOpenCollectionActivity({ databaseId, collectionId }: MostRecentActivity.OpenCollectionItem) {
return {
iconSrc: NotebookIcon,

View File

@@ -1,4 +1,4 @@
import { DetailsList, DetailsListLayoutMode, IColumn, Pivot, PivotItem, SelectionMode, Text } from "@fluentui/react";
import { DetailsList, DetailsListLayoutMode, IColumn, Pivot, PivotItem, SelectionMode } from "@fluentui/react";
import React, { Fragment } from "react";
import SplitterLayout from "react-splitter-layout";
import "react-splitter-layout/lib/index.css";
@@ -120,13 +120,21 @@ export default class QueryTabComponent extends React.Component<IQueryTabComponen
constructor(props: IQueryTabComponentProps) {
super(props);
const columns: IColumn[] = [
{
key: "column1",
name: "",
minWidth: 16,
maxWidth: 16,
data: String,
fieldName: "toolTip",
onRender: this.onRenderColumnItem,
},
{
key: "column2",
name: "METRIC",
minWidth: 200,
data: String,
fieldName: "metric",
onRender: this.onRenderColumnItem,
},
{
key: "column3",
@@ -198,12 +206,7 @@ export default class QueryTabComponent extends React.Component<IQueryTabComponen
public onRenderColumnItem(item: IDocument): JSX.Element {
if (item.toolTip !== "") {
return (
<>
<InfoTooltip>{`${item.toolTip}`}</InfoTooltip>
<Text style={{ paddingLeft: 10, margin: 0 }}>{`${item.metric}`}</Text>
</>
);
return <InfoTooltip>{`${item.toolTip}`}</InfoTooltip>;
} else {
return undefined;
}
@@ -966,15 +969,10 @@ export default class QueryTabComponent extends React.Component<IQueryTabComponen
<>
<span className="queryResultDivider">|</span>
<span className="queryResultNextEnable">
<div
onClick={this.onFetchNextPageClick.bind(this)}
role="button"
tabIndex={0}
onKeyPress={this.onFetchNextPageClick.bind(this)}
>
<span className="moreOption">Load more</span>
<a onClick={this.onFetchNextPageClick.bind(this)}>
<span>Load more</span>
<img className="queryResultnextImg" src={QueryEditorNext} alt="Fetch next page" />
</div>
</a>
</span>
</>
)}
@@ -1004,7 +1002,7 @@ export default class QueryTabComponent extends React.Component<IQueryTabComponen
"data-order": 2,
"data-title": "Query Stats",
}}
style={{ height: "100%", overflowY: "scroll" }}
style={{ height: "100%" }}
>
{this.state.allResultsMetadata.length > 0 && !this.state.error && (
<div className="queryMetricsSummaryContainer">
@@ -1020,7 +1018,7 @@ export default class QueryTabComponent extends React.Component<IQueryTabComponen
</div>
{this.state.isQueryMetricsEnabled && (
<div className="downloadMetricsLinkContainer">
<span
<a
id="downloadMetricsLink"
role="button"
tabIndex={0}
@@ -1035,7 +1033,7 @@ export default class QueryTabComponent extends React.Component<IQueryTabComponen
alt="download query metrics csv"
/>
<span>Per-partition query metrics (CSV)</span>
</span>
</a>
</div>
)}
</div>
@@ -1049,7 +1047,7 @@ export default class QueryTabComponent extends React.Component<IQueryTabComponen
<div className="errorContent">
<span className="errorMessage">{this.state.error}</span>
<span className="errorDetailsLink">
<span
<a
onClick={() => this.onErrorDetailsClick()}
onKeyPress={(event: React.KeyboardEvent<HTMLAnchorElement>) =>
this.onErrorDetailsKeyPress(event)
@@ -1057,11 +1055,9 @@ export default class QueryTabComponent extends React.Component<IQueryTabComponen
id="error-display"
tabIndex={0}
aria-label="Error details link"
role="button"
className="moreOption"
>
More details
</span>
</a>
</span>
</div>
</div>

View File

@@ -47,9 +47,7 @@
<img class="and-or-svg" src="/And-Or.svg" alt="Group selected clauses" />
</button>
</th>
<th class="clause-table-cell header-background">
<!-- Grouping indicator -->
</th>
<th class="clause-table-cell header-background"><!-- Grouping indicator --></th>
<th class="clause-table-cell header-background and-or-header">
<span data-bind="text: andLabel"></span>
</th>
@@ -138,7 +136,7 @@
class="select-options-link"
data-bind="click: selectQueryOptions, event: { keydown: onselectQueryOptionsKeyDown }"
tabindex="0"
role="button"
role="link"
>
<span>Choose Columns... </span>
</a>

View File

@@ -579,16 +579,13 @@ export default class StoredProcedureTabComponent extends React.Component<
<div className="errorContent">
<span className="errorMessage">{this.state.error}</span>
<span className="errorDetailsLink">
<span
role="button"
tabIndex={0}
className="moreOption"
<a
aria-label="Error details link"
onClick={() => this.onErrorDetailsClick()}
onKeyPress={(event: React.KeyboardEvent<HTMLAnchorElement>) => this.onErrorDetailsKeyPress(event)}
>
More details
</span>
</a>
</span>
</div>
</div>

View File

@@ -1,5 +1,5 @@
import ko from "knockout";
import React, { MutableRefObject, useEffect, useRef, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import loadingIcon from "../../../images/circular_loader_black_16x16.gif";
import errorIcon from "../../../images/close-black.svg";
import { useObservable } from "../../hooks/useObservable";
@@ -32,13 +32,7 @@ export const Tabs = (): JSX.Element => {
function TabNav({ tab, active }: { tab: Tab; active: boolean }) {
const [hovering, setHovering] = useState(false);
const focusTab = useRef<HTMLLIElement>() as MutableRefObject<HTMLLIElement>;
useEffect(() => {
if (active && focusTab.current) {
focusTab.current.focus();
}
});
return (
<li
onMouseOver={() => setHovering(true)}
@@ -52,8 +46,6 @@ function TabNav({ tab, active }: { tab: Tab; active: boolean }) {
aria-controls={tab.tabId}
tabIndex={0}
role="tab"
ref={focusTab}
onFocus={() => setHovering(true)}
>
<span className="tabNavContentContainer">
<a data-toggle="tab" href={"#" + tab.tabId} tabIndex={-1}>

View File

@@ -295,6 +295,8 @@ export class TriggerTabContent extends Component<TriggerTab, ITriggerTabContentS
className="trigger-field"
label="Trigger Id"
id="entityTimeId"
autoFocus
required
type="text"
pattern="[^/?#\\]*[^/?# \\]"
placeholder="Enter the new trigger id"

View File

@@ -276,6 +276,7 @@ export default class UserDefinedFunctionTabContent extends Component<
className="trigger-field"
label="User Defined Function Id"
id="entityTimeId"
autoFocus
required
readOnly={!isUdfIdEditable}
type="text"
@@ -290,7 +291,7 @@ export default class UserDefinedFunctionTabContent extends Component<
language={"javascript"}
content={udfBody}
isReadOnly={false}
ariaLabel={"User defined function body"}
ariaLabel={"Graph JSON"}
onContentChanged={this.handleUdfBodyChange}
/>
</div>

View File

@@ -89,8 +89,6 @@ const App: React.FunctionComponent = () => {
onClick={() => window.open("https://portal.azure.com", "_blank")}
tabIndex={0}
title="Go to Azure Portal"
role="button"
onKeyDown={() => window.open("https://portal.azure.com", "_blank")}
>
Microsoft Azure
</span>

View File

@@ -33,23 +33,13 @@ const Index = (): JSX.Element => {
<div
id="Quickstart"
onClick={quickstart_click}
onKeyPress={quickstart_click}
role="button"
tabIndex={0}
className={navigationSelection === "quickstart" ? "topSelected" : ""}
>
<img id="imgiconwidth1" src={Quickstart} alt="Open Quick Start" />
<span className="menuQuickStart">Quickstart</span>
</div>
<div
id="Explorer"
onClick={explorer_click}
className={navigationSelection === "explorer" ? "topSelected" : ""}
role="button"
tabIndex={0}
onKeyPress={explorer_click}
>
<div id="Explorer" onClick={explorer_click} className={navigationSelection === "explorer" ? "topSelected" : ""}>
<img id="imgiconwidth1" src={Explorer} alt="Open Data Explorer" />
<span className="menuExplorer">Explorer</span>
</div>
@@ -63,11 +53,11 @@ const Index = (): JSX.Element => {
</nav>
{navigationSelection === "quickstart" && (
<iframe name="quickstart" className="iframe" src="quickstart.html" title="Quick Start"></iframe>
<iframe name="quickstart" className="iframe" src="quickstart.html"></iframe>
)}
{navigationSelection === "explorer" && (
<iframe name="explorer" className="iframe" src="explorer.html?platform=Emulator" title="Explorer"></iframe>
<iframe name="explorer" className="iframe" src="explorer.html?platform=Emulator"></iframe>
)}
</React.Fragment>
);

View File

@@ -77,16 +77,16 @@ export const ConnectExplorer: React.FunctionComponent<Props> = ({
<p className="connectExplorerContent">
<input className="filterbtnstyle" type="submit" value="Connect" />
</p>
<div className="switchConnectTypeText" onClick={login} onKeyDown={login} role="button" tabIndex={0}>
<p className="switchConnectTypeText" onClick={login}>
Sign In with Azure Account
</div>
</p>
</form>
) : (
<div id="connectWithAad">
<input className="filterbtnstyle" type="button" value="Sign In" onClick={login} />
<div className="switchConnectTypeText" onClick={showForm} onKeyDown={showForm} role="button" tabIndex={0}>
<p className="switchConnectTypeText" onClick={showForm}>
Connect to your account with connection string
</div>
</p>
</div>
)}
</div>

View File

@@ -85,7 +85,7 @@ export function extractFeatures(given = new URLSearchParams(window.location.sear
};
}
export function hasFlag(flags: string | undefined, desiredFlag: string | undefined): boolean {
export function hasFlag(flags: string, desiredFlag: string): boolean {
if (!flags || !desiredFlag) {
return false;
}

View File

@@ -151,10 +151,10 @@ export const getReadRegions = async (): Promise<Array<string>> => {
});
if (response.result.location !== undefined) {
readRegions.push(response.result.location.split(" ").join("").toLowerCase());
readRegions.push(response.result.location.replace(" ", "").toLowerCase());
} else {
for (const location of response.result.locations) {
readRegions.push(location.locationName.split(" ").join("").toLowerCase());
readRegions.push(location.locationName.replace(" ", "").toLowerCase());
}
}
return readRegions;

View File

@@ -139,14 +139,6 @@ const getGeneralPath = (subscriptionId: string, resourceGroup: string, name: str
};
export const getRegions = async (): Promise<Array<string>> => {
const telemetryData = {
feature: "Calculate approximate cost",
function: "getRegions",
description: "",
selfServeClassName: SqlX.name,
};
const getRegionsTimestamp = selfServeTraceStart(telemetryData);
try {
const regions = new Array<string>();
@@ -164,12 +156,8 @@ export const getRegions = async (): Promise<Array<string>> => {
regions.push(location.locationName.split(" ").join("").toLowerCase());
}
}
selfServeTraceSuccess(telemetryData, getRegionsTimestamp);
return regions;
} catch (err) {
const failureTelemetry = { err, selfServeClassName: SqlX.name };
selfServeTraceFailure(failureTelemetry, getRegionsTimestamp);
return new Array<string>();
}
};
@@ -179,14 +167,6 @@ const getFetchPricesPathForRegion = (subscriptionId: string): string => {
};
export const getPriceMap = async (regions: Array<string>): Promise<Map<string, Map<string, number>>> => {
const telemetryData = {
feature: "Calculate approximate cost",
function: "getPriceMap",
description: "fetch prices API call",
selfServeClassName: SqlX.name,
};
const getPriceMapTimestamp = selfServeTraceStart(telemetryData);
try {
const priceMap = new Map<string, Map<string, number>>();
@@ -212,12 +192,8 @@ export const getPriceMap = async (regions: Array<string>): Promise<Map<string, M
priceMap.set(region, regionPriceMap);
}
selfServeTraceSuccess(telemetryData, getPriceMapTimestamp);
return priceMap;
} catch (err) {
const failureTelemetry = { err, selfServeClassName: SqlX.name };
selfServeTraceFailure(failureTelemetry, getPriceMapTimestamp);
return undefined;
}
};

View File

@@ -1,10 +1,5 @@
import { IsDisplayable, OnChange, PropertyInfo, RefreshOptions, Values } from "../Decorators";
import {
selfServeTrace,
selfServeTraceFailure,
selfServeTraceStart,
selfServeTraceSuccess,
} from "../SelfServeTelemetryProcessor";
import { selfServeTrace } from "../SelfServeTelemetryProcessor";
import {
ChoiceItem,
Description,
@@ -210,14 +205,6 @@ let priceMap: Map<string, Map<string, number>>;
let regions: Array<string>;
const calculateCost = (skuName: string, instanceCount: number): Description => {
const telemetryData = {
feature: "Calculate approximate cost",
function: "calculateCost",
description: "performs final calculation",
selfServeClassName: SqlX.name,
};
const calculateCostTimestamp = selfServeTraceStart(telemetryData);
try {
let costPerHour = 0;
for (const region of regions) {
@@ -228,22 +215,14 @@ const calculateCost = (skuName: string, instanceCount: number): Description => {
costPerHour += incrementalCost;
}
if (costPerHour === 0) {
throw new Error("Cost per hour = 0");
}
costPerHour *= instanceCount;
costPerHour = Math.round(costPerHour * 100) / 100;
selfServeTraceSuccess(telemetryData, calculateCostTimestamp);
return {
textTKey: `${costPerHour} USD`,
type: DescriptionType.Text,
};
} catch (err) {
const failureTelemetry = { err, regions, priceMap, selfServeClassName: SqlX.name };
selfServeTraceFailure(failureTelemetry, calculateCostTimestamp);
return costPerHourDefaultValue;
}
};

View File

@@ -1,3 +1,7 @@
import * as Constants from "../Common/Constants";
export const manualToAutoscaleDisclaimer = `The starting autoscale max RU/s will be determined by the system, based on the current manual throughput settings and storage of your resource. After autoscale has been enabled, you can change the max RU/s. <a href="${Constants.Urls.autoscaleMigration}">Learn more</a>.`;
export const minAutoPilotThroughput = 4000;
export const autoPilotIncrementStep = 1000;

View File

@@ -8,7 +8,6 @@
"noUnusedParameters": true
},
"files": [
"./src/SelfServe/GraphAPICompute/GraphAPICompute.types.ts",
"./src/AuthType.ts",
"./src/Bindings/ReactBindingHandler.ts",
"./src/Common/ArrayHashMap.ts",
@@ -166,4 +165,4 @@
"src/Terminal/**/*",
"src/Utils/arm/**/*"
]
}
}