mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2024-11-25 15:06:55 +00:00
Added localization for the Self Serve Model (#406)
* added localization for selfserve model * added comment * addressed PR comments * fixed format errors * Addressed PR comments
This commit is contained in:
parent
f8ede0cc1e
commit
6aaddd9c60
46
package-lock.json
generated
46
package-lock.json
generated
@ -11665,6 +11665,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"html-parse-stringify2": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz",
|
||||||
|
"integrity": "sha1-3FZwtyksoVi3vJFsmmc1rIhyg0o=",
|
||||||
|
"requires": {
|
||||||
|
"void-elements": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"html-to-react": {
|
"html-to-react": {
|
||||||
"version": "1.4.5",
|
"version": "1.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/html-to-react/-/html-to-react-1.4.5.tgz",
|
"resolved": "https://registry.npmjs.org/html-to-react/-/html-to-react-1.4.5.tgz",
|
||||||
@ -11850,6 +11858,30 @@
|
|||||||
"integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
|
"integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"i18next": {
|
||||||
|
"version": "19.8.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18next/-/i18next-19.8.4.tgz",
|
||||||
|
"integrity": "sha512-FfVPNWv+felJObeZ6DSXZkj9QM1Ivvh7NcFCgA8XPtJWHz0iXVa9BUy+QY8EPrCLE+vWgDfV/sc96BgXVo6HAA==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"i18next-browser-languagedetector": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-3H+OsNQn3FciomUU0d4zPFHsvJv4X66lBelXk9hnIDYDsveIgT7dWZ3/VvcSlpKk9lvCK770blRZ/CwHMXZqWw==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.5.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"i18next-http-backend": {
|
||||||
|
"version": "1.0.23",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-1.0.23.tgz",
|
||||||
|
"integrity": "sha512-2iXwUmawM4kozvGN+k7G9u/bYQdgqtTXVK0cWvLSOpUCTaW30ZzRhgu0FBfinb71XjwUEvdqb95jNrEFjrwGKw==",
|
||||||
|
"requires": {
|
||||||
|
"node-fetch": "2.6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"iconv-lite": {
|
"iconv-lite": {
|
||||||
"version": "0.4.24",
|
"version": "0.4.24",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
@ -17900,6 +17932,15 @@
|
|||||||
"prop-types": "^15.6.1"
|
"prop-types": "^15.6.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-i18next": {
|
||||||
|
"version": "11.8.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.8.5.tgz",
|
||||||
|
"integrity": "sha512-2jY/8NkhNv2KWBnZuhHxTn13aMxAbvhiDUNskm+1xVVnrPId78l8fA7fCyVeO3XU1kptM0t4MtvxV1Nu08cjLw==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.3.1",
|
||||||
|
"html-parse-stringify2": "2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-is": {
|
"react-is": {
|
||||||
"version": "16.13.1",
|
"version": "16.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
@ -21373,6 +21414,11 @@
|
|||||||
"integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
|
"integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"void-elements": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
|
||||||
|
"integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w="
|
||||||
|
},
|
||||||
"w3c-hr-time": {
|
"w3c-hr-time": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
|
||||||
|
@ -64,6 +64,9 @@
|
|||||||
"eslint-plugin-react": "7.20.0",
|
"eslint-plugin-react": "7.20.0",
|
||||||
"hasher": "1.2.0",
|
"hasher": "1.2.0",
|
||||||
"html2canvas": "1.0.0-rc.5",
|
"html2canvas": "1.0.0-rc.5",
|
||||||
|
"i18next": "19.8.4",
|
||||||
|
"i18next-browser-languagedetector": "6.0.1",
|
||||||
|
"i18next-http-backend": "1.0.23",
|
||||||
"immutable": "4.0.0-rc.12",
|
"immutable": "4.0.0-rc.12",
|
||||||
"is-ci": "2.0.0",
|
"is-ci": "2.0.0",
|
||||||
"jquery": "3.5.1",
|
"jquery": "3.5.1",
|
||||||
@ -86,6 +89,7 @@
|
|||||||
"react-dnd-html5-backend": "9.4.0",
|
"react-dnd-html5-backend": "9.4.0",
|
||||||
"react-dom": "16.13.1",
|
"react-dom": "16.13.1",
|
||||||
"react-hotkeys": "2.0.0",
|
"react-hotkeys": "2.0.0",
|
||||||
|
"react-i18next": "11.8.5",
|
||||||
"react-notification-system": "0.2.17",
|
"react-notification-system": "0.2.17",
|
||||||
"react-redux": "7.1.3",
|
"react-redux": "7.1.3",
|
||||||
"redux": "4.0.4",
|
"redux": "4.0.4",
|
||||||
|
@ -8,10 +8,10 @@ describe("SmartUiComponent", () => {
|
|||||||
root: {
|
root: {
|
||||||
id: "root",
|
id: "root",
|
||||||
info: {
|
info: {
|
||||||
message: "Start at $24/mo per database",
|
messageTKey: "Start at $24/mo per database",
|
||||||
link: {
|
link: {
|
||||||
href: "https://aka.ms/azure-cosmos-db-pricing",
|
href: "https://aka.ms/azure-cosmos-db-pricing",
|
||||||
text: "More Details",
|
textTKey: "More Details",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
@ -21,10 +21,10 @@ describe("SmartUiComponent", () => {
|
|||||||
dataFieldName: "description",
|
dataFieldName: "description",
|
||||||
type: "string",
|
type: "string",
|
||||||
description: {
|
description: {
|
||||||
text: "this is an example description text.",
|
textTKey: "this is an example description text.",
|
||||||
link: {
|
link: {
|
||||||
href: "https://docs.microsoft.com/en-us/azure/cosmos-db/introduction",
|
href: "https://docs.microsoft.com/en-us/azure/cosmos-db/introduction",
|
||||||
text: "Click here for more information.",
|
textTKey: "Click here for more information.",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -32,7 +32,7 @@ describe("SmartUiComponent", () => {
|
|||||||
{
|
{
|
||||||
id: "throughput",
|
id: "throughput",
|
||||||
input: {
|
input: {
|
||||||
label: "Throughput (input)",
|
labelTKey: "Throughput (input)",
|
||||||
dataFieldName: "throughput",
|
dataFieldName: "throughput",
|
||||||
type: "number",
|
type: "number",
|
||||||
min: 400,
|
min: 400,
|
||||||
@ -45,7 +45,7 @@ describe("SmartUiComponent", () => {
|
|||||||
{
|
{
|
||||||
id: "throughput2",
|
id: "throughput2",
|
||||||
input: {
|
input: {
|
||||||
label: "Throughput (Slider)",
|
labelTKey: "Throughput (Slider)",
|
||||||
dataFieldName: "throughput2",
|
dataFieldName: "throughput2",
|
||||||
type: "number",
|
type: "number",
|
||||||
min: 400,
|
min: 400,
|
||||||
@ -58,7 +58,7 @@ describe("SmartUiComponent", () => {
|
|||||||
{
|
{
|
||||||
id: "throughput3",
|
id: "throughput3",
|
||||||
input: {
|
input: {
|
||||||
label: "Throughput (invalid)",
|
labelTKey: "Throughput (invalid)",
|
||||||
dataFieldName: "throughput3",
|
dataFieldName: "throughput3",
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
min: 400,
|
min: 400,
|
||||||
@ -72,7 +72,7 @@ describe("SmartUiComponent", () => {
|
|||||||
{
|
{
|
||||||
id: "containerId",
|
id: "containerId",
|
||||||
input: {
|
input: {
|
||||||
label: "Container id",
|
labelTKey: "Container id",
|
||||||
dataFieldName: "containerId",
|
dataFieldName: "containerId",
|
||||||
type: "string",
|
type: "string",
|
||||||
},
|
},
|
||||||
@ -80,9 +80,9 @@ describe("SmartUiComponent", () => {
|
|||||||
{
|
{
|
||||||
id: "analyticalStore",
|
id: "analyticalStore",
|
||||||
input: {
|
input: {
|
||||||
label: "Analytical Store",
|
labelTKey: "Analytical Store",
|
||||||
trueLabel: "Enabled",
|
trueLabelTKey: "Enabled",
|
||||||
falseLabel: "Disabled",
|
falseLabelTKey: "Disabled",
|
||||||
defaultValue: true,
|
defaultValue: true,
|
||||||
dataFieldName: "analyticalStore",
|
dataFieldName: "analyticalStore",
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
@ -91,7 +91,7 @@ describe("SmartUiComponent", () => {
|
|||||||
{
|
{
|
||||||
id: "database",
|
id: "database",
|
||||||
input: {
|
input: {
|
||||||
label: "Database",
|
labelTKey: "Database",
|
||||||
dataFieldName: "database",
|
dataFieldName: "database",
|
||||||
type: "object",
|
type: "object",
|
||||||
choices: [
|
choices: [
|
||||||
@ -117,6 +117,9 @@ describe("SmartUiComponent", () => {
|
|||||||
onError={() => {
|
onError={() => {
|
||||||
return;
|
return;
|
||||||
}}
|
}}
|
||||||
|
getTranslation={(key: string) => {
|
||||||
|
return key;
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||||
@ -145,6 +148,9 @@ describe("SmartUiComponent", () => {
|
|||||||
onError={() => {
|
onError={() => {
|
||||||
return;
|
return;
|
||||||
}}
|
}}
|
||||||
|
getTranslation={(key: string) => {
|
||||||
|
return key;
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
NumberUiType,
|
NumberUiType,
|
||||||
SmartUiInput,
|
SmartUiInput,
|
||||||
} from "../../../SelfServe/SelfServeTypes";
|
} from "../../../SelfServe/SelfServeTypes";
|
||||||
|
import { TFunction } from "i18next";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic UX renderer
|
* Generic UX renderer
|
||||||
@ -34,8 +35,8 @@ interface BaseDisplay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface BaseInput extends BaseDisplay {
|
interface BaseInput extends BaseDisplay {
|
||||||
label: string;
|
labelTKey: string;
|
||||||
placeholder?: string;
|
placeholderTKey?: string;
|
||||||
errorMessage?: string;
|
errorMessage?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,8 +52,8 @@ interface NumberInput extends BaseInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface BooleanInput extends BaseInput {
|
interface BooleanInput extends BaseInput {
|
||||||
trueLabel: string;
|
trueLabelTKey: string;
|
||||||
falseLabel: string;
|
falseLabelTKey: string;
|
||||||
defaultValue?: boolean;
|
defaultValue?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,6 +90,7 @@ export interface SmartUiComponentProps {
|
|||||||
onInputChange: (input: AnyDisplay, newValue: InputType) => void;
|
onInputChange: (input: AnyDisplay, newValue: InputType) => void;
|
||||||
onError: (hasError: boolean) => void;
|
onError: (hasError: boolean) => void;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
|
getTranslation: TFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SmartUiComponentState {
|
interface SmartUiComponentState {
|
||||||
@ -122,10 +124,10 @@ export class SmartUiComponent extends React.Component<SmartUiComponentProps, Sma
|
|||||||
private renderInfo(info: Info): JSX.Element {
|
private renderInfo(info: Info): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<MessageBar styles={{ root: { width: 400 } }}>
|
<MessageBar styles={{ root: { width: 400 } }}>
|
||||||
{info.message}
|
{this.props.getTranslation(info.messageTKey)}
|
||||||
{info.link && (
|
{info.link && (
|
||||||
<Link href={info.link.href} target="_blank">
|
<Link href={info.link.href} target="_blank">
|
||||||
{info.link.text}
|
{this.props.getTranslation(info.link.textTKey)}
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
</MessageBar>
|
</MessageBar>
|
||||||
@ -139,10 +141,10 @@ export class SmartUiComponent extends React.Component<SmartUiComponentProps, Sma
|
|||||||
<div className="stringInputContainer">
|
<div className="stringInputContainer">
|
||||||
<TextField
|
<TextField
|
||||||
id={`${input.dataFieldName}-textField-input`}
|
id={`${input.dataFieldName}-textField-input`}
|
||||||
label={input.label}
|
label={this.props.getTranslation(input.labelTKey)}
|
||||||
type="text"
|
type="text"
|
||||||
value={value || ""}
|
value={value || ""}
|
||||||
placeholder={input.placeholder}
|
placeholder={this.props.getTranslation(input.placeholderTKey)}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onChange={(_, newValue) => this.props.onInputChange(input, newValue)}
|
onChange={(_, newValue) => this.props.onInputChange(input, newValue)}
|
||||||
styles={{
|
styles={{
|
||||||
@ -165,10 +167,10 @@ export class SmartUiComponent extends React.Component<SmartUiComponentProps, Sma
|
|||||||
const description = input.description;
|
const description = input.description;
|
||||||
return (
|
return (
|
||||||
<Text id={`${input.dataFieldName}-text-display`}>
|
<Text id={`${input.dataFieldName}-text-display`}>
|
||||||
{input.description.text}{" "}
|
{this.props.getTranslation(input.description.textTKey)}{" "}
|
||||||
{description.link && (
|
{description.link && (
|
||||||
<Link target="_blank" href={input.description.link.href}>
|
<Link target="_blank" href={input.description.link.href}>
|
||||||
{input.description.link.text}
|
{this.props.getTranslation(input.description.link.textTKey)}
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
@ -219,12 +221,12 @@ export class SmartUiComponent extends React.Component<SmartUiComponentProps, Sma
|
|||||||
};
|
};
|
||||||
|
|
||||||
private renderNumberInput(input: NumberInput): JSX.Element {
|
private renderNumberInput(input: NumberInput): JSX.Element {
|
||||||
const { label, min, max, dataFieldName, step } = input;
|
const { labelTKey, min, max, dataFieldName, step } = input;
|
||||||
const props = {
|
const props = {
|
||||||
label: label,
|
label: this.props.getTranslation(labelTKey),
|
||||||
min: min,
|
min: min,
|
||||||
max: max,
|
max: max,
|
||||||
ariaLabel: label,
|
ariaLabel: labelTKey,
|
||||||
step: step,
|
step: step,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -284,10 +286,10 @@ export class SmartUiComponent extends React.Component<SmartUiComponentProps, Sma
|
|||||||
return (
|
return (
|
||||||
<Toggle
|
<Toggle
|
||||||
id={`${input.dataFieldName}-toggle-input`}
|
id={`${input.dataFieldName}-toggle-input`}
|
||||||
label={input.label}
|
label={this.props.getTranslation(input.labelTKey)}
|
||||||
checked={value || false}
|
checked={value || false}
|
||||||
onText={input.trueLabel}
|
onText={this.props.getTranslation(input.trueLabelTKey)}
|
||||||
offText={input.falseLabel}
|
offText={this.props.getTranslation(input.falseLabelTKey)}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onChange={(event, checked: boolean) => this.props.onInputChange(input, checked)}
|
onChange={(event, checked: boolean) => this.props.onInputChange(input, checked)}
|
||||||
styles={{ root: { width: 400 } }}
|
styles={{ root: { width: 400 } }}
|
||||||
@ -296,7 +298,7 @@ export class SmartUiComponent extends React.Component<SmartUiComponentProps, Sma
|
|||||||
}
|
}
|
||||||
|
|
||||||
private renderChoiceInput(input: ChoiceInput): JSX.Element {
|
private renderChoiceInput(input: ChoiceInput): JSX.Element {
|
||||||
const { label, defaultKey: defaultKey, dataFieldName, choices, placeholder } = input;
|
const { labelTKey, defaultKey, dataFieldName, choices, placeholderTKey } = input;
|
||||||
const value = this.props.currentValues.get(dataFieldName)?.value as string;
|
const value = this.props.currentValues.get(dataFieldName)?.value as string;
|
||||||
const disabled = this.props.disabled || this.props.currentValues.get(dataFieldName)?.disabled;
|
const disabled = this.props.disabled || this.props.currentValues.get(dataFieldName)?.disabled;
|
||||||
let selectedKey = value ? value : defaultKey;
|
let selectedKey = value ? value : defaultKey;
|
||||||
@ -306,14 +308,14 @@ export class SmartUiComponent extends React.Component<SmartUiComponentProps, Sma
|
|||||||
return (
|
return (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
id={`${input.dataFieldName}-dropdown-input`}
|
id={`${input.dataFieldName}-dropdown-input`}
|
||||||
label={label}
|
label={this.props.getTranslation(labelTKey)}
|
||||||
selectedKey={selectedKey}
|
selectedKey={selectedKey}
|
||||||
onChange={(_, item: IDropdownOption) => this.props.onInputChange(input, item.key.toString())}
|
onChange={(_, item: IDropdownOption) => this.props.onInputChange(input, item.key.toString())}
|
||||||
placeholder={placeholder}
|
placeholder={this.props.getTranslation(placeholderTKey)}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
options={choices.map((c) => ({
|
options={choices.map((c) => ({
|
||||||
key: c.key,
|
key: c.key,
|
||||||
text: c.label,
|
text: this.props.getTranslation(c.label),
|
||||||
}))}
|
}))}
|
||||||
styles={{
|
styles={{
|
||||||
root: { width: 400 },
|
root: { width: 400 },
|
||||||
|
33
src/Localization/en/translations.json
Normal file
33
src/Localization/en/translations.json
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"translations": {
|
||||||
|
"Common": {
|
||||||
|
"Save": "Save",
|
||||||
|
"Discard": "Discard",
|
||||||
|
"Refresh": "Refesh"
|
||||||
|
},
|
||||||
|
"SelfServeExample": {
|
||||||
|
"North Central US": "North Central US",
|
||||||
|
"West US": "West US",
|
||||||
|
"East US 2": "East US 2",
|
||||||
|
"ClassInfo": "This is a self serve class",
|
||||||
|
"RegionDropdownInfo": "More regions can be added in the future.",
|
||||||
|
"ValidationError": "Regions and AccountName should not be empty.",
|
||||||
|
"DescriptionText": "This class sets collection and database throughput.",
|
||||||
|
"DecriptionLinkText": "Click here for more information",
|
||||||
|
"Regions": "Regions",
|
||||||
|
"RegionsPlaceholder": "Select a region",
|
||||||
|
"Enable Logging": "Enable Logging",
|
||||||
|
"Enable": "Enable",
|
||||||
|
"Disable": "Disable",
|
||||||
|
"Account Name": "Account Name",
|
||||||
|
"AccountNamePlaceHolder": "Enter the account name",
|
||||||
|
"Collection Throughput": "Collection Throughput",
|
||||||
|
"Enable DB level throughput": "Enable DB level throughput",
|
||||||
|
"Database Throughput": "Database Throughput",
|
||||||
|
"RefreshMessage": "Self Serve Example successfully refreshing",
|
||||||
|
"SubmissionMessage": "Submitted successfully"
|
||||||
|
},
|
||||||
|
"SqlX": {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,7 @@ interface Decorator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface InputOptionsBase {
|
interface InputOptionsBase {
|
||||||
label: string;
|
labelTKey: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NumberInputOptions extends InputOptionsBase {
|
export interface NumberInputOptions extends InputOptionsBase {
|
||||||
@ -19,17 +19,17 @@ export interface NumberInputOptions extends InputOptionsBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface StringInputOptions extends InputOptionsBase {
|
export interface StringInputOptions extends InputOptionsBase {
|
||||||
placeholder?: (() => Promise<string>) | string;
|
placeholderTKey?: (() => Promise<string>) | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BooleanInputOptions extends InputOptionsBase {
|
export interface BooleanInputOptions extends InputOptionsBase {
|
||||||
trueLabel: (() => Promise<string>) | string;
|
trueLabelTKey: (() => Promise<string>) | string;
|
||||||
falseLabel: (() => Promise<string>) | string;
|
falseLabelTKey: (() => Promise<string>) | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ChoiceInputOptions extends InputOptionsBase {
|
export interface ChoiceInputOptions extends InputOptionsBase {
|
||||||
choices: (() => Promise<ChoiceItem[]>) | ChoiceItem[];
|
choices: (() => Promise<ChoiceItem[]>) | ChoiceItem[];
|
||||||
placeholder?: (() => Promise<string>) | string;
|
placeholderTKey?: (() => Promise<string>) | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DescriptionDisplayOptions {
|
export interface DescriptionDisplayOptions {
|
||||||
@ -48,7 +48,7 @@ const isNumberInputOptions = (inputOptions: InputOptions): inputOptions is Numbe
|
|||||||
};
|
};
|
||||||
|
|
||||||
const isBooleanInputOptions = (inputOptions: InputOptions): inputOptions is BooleanInputOptions => {
|
const isBooleanInputOptions = (inputOptions: InputOptions): inputOptions is BooleanInputOptions => {
|
||||||
return "trueLabel" in inputOptions;
|
return "trueLabelTKey" in inputOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
const isChoiceInputOptions = (inputOptions: InputOptions): inputOptions is ChoiceInputOptions => {
|
const isChoiceInputOptions = (inputOptions: InputOptions): inputOptions is ChoiceInputOptions => {
|
||||||
@ -92,7 +92,7 @@ export const PropertyInfo = (info: (() => Promise<Info>) | Info): PropertyDecora
|
|||||||
export const Values = (inputOptions: InputOptions): PropertyDecorator => {
|
export const Values = (inputOptions: InputOptions): PropertyDecorator => {
|
||||||
if (isNumberInputOptions(inputOptions)) {
|
if (isNumberInputOptions(inputOptions)) {
|
||||||
return addToMap(
|
return addToMap(
|
||||||
{ name: "label", value: inputOptions.label },
|
{ name: "labelTKey", value: inputOptions.labelTKey },
|
||||||
{ name: "min", value: inputOptions.min },
|
{ name: "min", value: inputOptions.min },
|
||||||
{ name: "max", value: inputOptions.max },
|
{ name: "max", value: inputOptions.max },
|
||||||
{ name: "step", value: inputOptions.step },
|
{ name: "step", value: inputOptions.step },
|
||||||
@ -100,22 +100,22 @@ export const Values = (inputOptions: InputOptions): PropertyDecorator => {
|
|||||||
);
|
);
|
||||||
} else if (isBooleanInputOptions(inputOptions)) {
|
} else if (isBooleanInputOptions(inputOptions)) {
|
||||||
return addToMap(
|
return addToMap(
|
||||||
{ name: "label", value: inputOptions.label },
|
{ name: "labelTKey", value: inputOptions.labelTKey },
|
||||||
{ name: "trueLabel", value: inputOptions.trueLabel },
|
{ name: "trueLabelTKey", value: inputOptions.trueLabelTKey },
|
||||||
{ name: "falseLabel", value: inputOptions.falseLabel }
|
{ name: "falseLabelTKey", value: inputOptions.falseLabelTKey }
|
||||||
);
|
);
|
||||||
} else if (isChoiceInputOptions(inputOptions)) {
|
} else if (isChoiceInputOptions(inputOptions)) {
|
||||||
return addToMap(
|
return addToMap(
|
||||||
{ name: "label", value: inputOptions.label },
|
{ name: "labelTKey", value: inputOptions.labelTKey },
|
||||||
{ name: "placeholder", value: inputOptions.placeholder },
|
{ name: "placeholderTKey", value: inputOptions.placeholderTKey },
|
||||||
{ name: "choices", value: inputOptions.choices }
|
{ name: "choices", value: inputOptions.choices }
|
||||||
);
|
);
|
||||||
} else if (isDescriptionDisplayOptions(inputOptions)) {
|
} else if (isDescriptionDisplayOptions(inputOptions)) {
|
||||||
return addToMap({ name: "description", value: inputOptions.description });
|
return addToMap({ name: "description", value: inputOptions.description });
|
||||||
} else {
|
} else {
|
||||||
return addToMap(
|
return addToMap(
|
||||||
{ name: "label", value: inputOptions.label },
|
{ name: "labelTKey", value: inputOptions.labelTKey },
|
||||||
{ name: "placeholder", value: inputOptions.placeholder }
|
{ name: "placeholderTKey", value: inputOptions.placeholderTKey }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -16,10 +16,22 @@ export interface InitializeResponse {
|
|||||||
dbThroughput: number;
|
dbThroughput: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getMaxThroughput = async (): Promise<number> => {
|
export const getMaxCollectionThroughput = async (): Promise<number> => {
|
||||||
return 10000;
|
return 10000;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getMinCollectionThroughput = async (): Promise<number> => {
|
||||||
|
return 400;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getMaxDatabaseThroughput = async (): Promise<number> => {
|
||||||
|
return 10000;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getMinDatabaseThroughput = async (): Promise<number> => {
|
||||||
|
return 400;
|
||||||
|
};
|
||||||
|
|
||||||
export const update = async (
|
export const update = async (
|
||||||
regions: Regions,
|
regions: Regions,
|
||||||
enableLogging: boolean,
|
enableLogging: boolean,
|
||||||
@ -59,6 +71,6 @@ export const onRefreshSelfServeExample = async (): Promise<RefreshResult> => {
|
|||||||
const isUpdateInProgress = databaseAccountGetResults.properties.provisioningState !== "Succeeded";
|
const isUpdateInProgress = databaseAccountGetResults.properties.provisioningState !== "Succeeded";
|
||||||
return {
|
return {
|
||||||
isUpdateInProgress: isUpdateInProgress,
|
isUpdateInProgress: isUpdateInProgress,
|
||||||
notificationMessage: "Self Serve Example successfully refreshing",
|
notificationMessage: "RefreshMessage",
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -10,7 +10,16 @@ import {
|
|||||||
SelfServeNotificationType,
|
SelfServeNotificationType,
|
||||||
SmartUiInput,
|
SmartUiInput,
|
||||||
} from "../SelfServeTypes";
|
} from "../SelfServeTypes";
|
||||||
import { onRefreshSelfServeExample, getMaxThroughput, Regions, update, initialize } from "./SelfServeExample.rp";
|
import {
|
||||||
|
onRefreshSelfServeExample,
|
||||||
|
Regions,
|
||||||
|
update,
|
||||||
|
initialize,
|
||||||
|
getMinDatabaseThroughput,
|
||||||
|
getMaxDatabaseThroughput,
|
||||||
|
getMinCollectionThroughput,
|
||||||
|
getMaxCollectionThroughput,
|
||||||
|
} from "./SelfServeExample.rp";
|
||||||
|
|
||||||
const regionDropdownItems: ChoiceItem[] = [
|
const regionDropdownItems: ChoiceItem[] = [
|
||||||
{ label: "North Central US", key: Regions.NorthCentralUS },
|
{ label: "North Central US", key: Regions.NorthCentralUS },
|
||||||
@ -19,11 +28,11 @@ const regionDropdownItems: ChoiceItem[] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const selfServeExampleInfo: Info = {
|
const selfServeExampleInfo: Info = {
|
||||||
message: "This is a self serve class",
|
messageTKey: "ClassInfo",
|
||||||
};
|
};
|
||||||
|
|
||||||
const regionDropdownInfo: Info = {
|
const regionDropdownInfo: Info = {
|
||||||
message: "More regions can be added in the future.",
|
messageTKey: "RegionDropdownInfo",
|
||||||
};
|
};
|
||||||
|
|
||||||
const onRegionsChange = (currentState: Map<string, SmartUiInput>, newValue: InputType): Map<string, SmartUiInput> => {
|
const onRegionsChange = (currentState: Map<string, SmartUiInput>, newValue: InputType): Map<string, SmartUiInput> => {
|
||||||
@ -50,7 +59,7 @@ const onEnableDbLevelThroughputChange = (
|
|||||||
|
|
||||||
const validate = (currentvalues: Map<string, SmartUiInput>): void => {
|
const validate = (currentvalues: Map<string, SmartUiInput>): void => {
|
||||||
if (!currentvalues.get("regions").value || !currentvalues.get("accountName").value) {
|
if (!currentvalues.get("regions").value || !currentvalues.get("accountName").value) {
|
||||||
throw new Error("Regions and AccountName should not be empty.");
|
throw new Error("ValidationError");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -66,6 +75,9 @@ const validate = (currentvalues: Map<string, SmartUiInput>): void => {
|
|||||||
|
|
||||||
You can test this self serve UI by using the featureflag '?feature.selfServeType=example'
|
You can test this self serve UI by using the featureflag '?feature.selfServeType=example'
|
||||||
and plumb in similar feature flags for your own self serve class.
|
and plumb in similar feature flags for your own self serve class.
|
||||||
|
|
||||||
|
All string to be used should be present in the "src/Localization" folder, in the language specific json files. The
|
||||||
|
corresponding key should be given as the value for the fields like "label", the error message etc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -117,7 +129,7 @@ export default class SelfServeExample extends SelfServeBaseClass {
|
|||||||
let dbThroughput = currentValues.get("dbThroughput")?.value as number;
|
let dbThroughput = currentValues.get("dbThroughput")?.value as number;
|
||||||
dbThroughput = enableDbLevelThroughput ? dbThroughput : undefined;
|
dbThroughput = enableDbLevelThroughput ? dbThroughput : undefined;
|
||||||
await update(regions, enableLogging, accountName, collectionThroughput, dbThroughput);
|
await update(regions, enableLogging, accountName, collectionThroughput, dbThroughput);
|
||||||
return { message: "submitted successfully", type: SelfServeNotificationType.info };
|
return { message: "SubmissionMessage", type: SelfServeNotificationType.info };
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -161,10 +173,10 @@ export default class SelfServeExample extends SelfServeBaseClass {
|
|||||||
*/
|
*/
|
||||||
@Values({
|
@Values({
|
||||||
description: {
|
description: {
|
||||||
text: "This class sets collection and database throughput.",
|
textTKey: "DescriptionText",
|
||||||
link: {
|
link: {
|
||||||
href: "https://docs.microsoft.com/en-us/azure/cosmos-db/introduction",
|
href: "https://docs.microsoft.com/en-us/azure/cosmos-db/introduction",
|
||||||
text: "Click here for more information",
|
textTKey: "DecriptionLinkText",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -193,26 +205,26 @@ export default class SelfServeExample extends SelfServeBaseClass {
|
|||||||
any other value of "regions"
|
any other value of "regions"
|
||||||
*/
|
*/
|
||||||
@OnChange(onRegionsChange)
|
@OnChange(onRegionsChange)
|
||||||
@Values({ label: "Regions", choices: regionDropdownItems, placeholder: "Select a region" })
|
@Values({ labelTKey: "Regions", choices: regionDropdownItems, placeholderTKey: "RegionsPlaceholder" })
|
||||||
regions: ChoiceItem;
|
regions: ChoiceItem;
|
||||||
|
|
||||||
@Values({
|
@Values({
|
||||||
label: "Enable Logging",
|
labelTKey: "Enable Logging",
|
||||||
trueLabel: "Enable",
|
trueLabelTKey: "Enable",
|
||||||
falseLabel: "Disable",
|
falseLabelTKey: "Disable",
|
||||||
})
|
})
|
||||||
enableLogging: boolean;
|
enableLogging: boolean;
|
||||||
|
|
||||||
@Values({
|
@Values({
|
||||||
label: "Account Name",
|
labelTKey: "Account Name",
|
||||||
placeholder: "Enter the account name",
|
placeholderTKey: "AccountNamePlaceHolder",
|
||||||
})
|
})
|
||||||
accountName: string;
|
accountName: string;
|
||||||
|
|
||||||
@Values({
|
@Values({
|
||||||
label: "Collection Throughput",
|
labelTKey: "Collection Throughput",
|
||||||
min: 400,
|
min: getMinCollectionThroughput,
|
||||||
max: getMaxThroughput,
|
max: getMaxCollectionThroughput,
|
||||||
step: 100,
|
step: 100,
|
||||||
uiType: NumberUiType.Spinner,
|
uiType: NumberUiType.Spinner,
|
||||||
})
|
})
|
||||||
@ -224,16 +236,16 @@ export default class SelfServeExample extends SelfServeBaseClass {
|
|||||||
*/
|
*/
|
||||||
@OnChange(onEnableDbLevelThroughputChange)
|
@OnChange(onEnableDbLevelThroughputChange)
|
||||||
@Values({
|
@Values({
|
||||||
label: "Enable DB level throughput",
|
labelTKey: "Enable DB level throughput",
|
||||||
trueLabel: "Enable",
|
trueLabelTKey: "Enable",
|
||||||
falseLabel: "Disable",
|
falseLabelTKey: "Disable",
|
||||||
})
|
})
|
||||||
enableDbLevelThroughput: boolean;
|
enableDbLevelThroughput: boolean;
|
||||||
|
|
||||||
@Values({
|
@Values({
|
||||||
label: "Database Throughput",
|
labelTKey: "Database Throughput",
|
||||||
min: 400,
|
min: getMinDatabaseThroughput,
|
||||||
max: getMaxThroughput,
|
max: getMaxDatabaseThroughput,
|
||||||
step: 100,
|
step: 100,
|
||||||
uiType: NumberUiType.Slider,
|
uiType: NumberUiType.Slider,
|
||||||
})
|
})
|
||||||
|
@ -34,17 +34,17 @@ describe("SelfServeComponent", () => {
|
|||||||
root: {
|
root: {
|
||||||
id: "root",
|
id: "root",
|
||||||
info: {
|
info: {
|
||||||
message: "Start at $24/mo per database",
|
messageTKey: "Start at $24/mo per database",
|
||||||
link: {
|
link: {
|
||||||
href: "https://aka.ms/azure-cosmos-db-pricing",
|
href: "https://aka.ms/azure-cosmos-db-pricing",
|
||||||
text: "More Details",
|
textTKey: "More Details",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: "throughput",
|
id: "throughput",
|
||||||
input: {
|
input: {
|
||||||
label: "Throughput (input)",
|
labelTKey: "Throughput (input)",
|
||||||
dataFieldName: "throughput",
|
dataFieldName: "throughput",
|
||||||
type: "number",
|
type: "number",
|
||||||
min: 400,
|
min: 400,
|
||||||
@ -57,7 +57,7 @@ describe("SelfServeComponent", () => {
|
|||||||
{
|
{
|
||||||
id: "containerId",
|
id: "containerId",
|
||||||
input: {
|
input: {
|
||||||
label: "Container id",
|
labelTKey: "Container id",
|
||||||
dataFieldName: "containerId",
|
dataFieldName: "containerId",
|
||||||
type: "string",
|
type: "string",
|
||||||
},
|
},
|
||||||
@ -65,9 +65,9 @@ describe("SelfServeComponent", () => {
|
|||||||
{
|
{
|
||||||
id: "analyticalStore",
|
id: "analyticalStore",
|
||||||
input: {
|
input: {
|
||||||
label: "Analytical Store",
|
labelTKey: "Analytical Store",
|
||||||
trueLabel: "Enabled",
|
trueLabelTKey: "Enabled",
|
||||||
falseLabel: "Disabled",
|
falseLabelTKey: "Disabled",
|
||||||
defaultValue: true,
|
defaultValue: true,
|
||||||
dataFieldName: "analyticalStore",
|
dataFieldName: "analyticalStore",
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
@ -76,7 +76,7 @@ describe("SelfServeComponent", () => {
|
|||||||
{
|
{
|
||||||
id: "database",
|
id: "database",
|
||||||
input: {
|
input: {
|
||||||
label: "Database",
|
labelTKey: "Database",
|
||||||
dataFieldName: "database",
|
dataFieldName: "database",
|
||||||
type: "object",
|
type: "object",
|
||||||
choices: [
|
choices: [
|
||||||
|
@ -26,6 +26,9 @@ import {
|
|||||||
} from "./SelfServeTypes";
|
} from "./SelfServeTypes";
|
||||||
import { SmartUiComponent, SmartUiDescriptor } from "../Explorer/Controls/SmartUi/SmartUiComponent";
|
import { SmartUiComponent, SmartUiDescriptor } from "../Explorer/Controls/SmartUi/SmartUiComponent";
|
||||||
import { getMessageBarType } from "./SelfServeUtils";
|
import { getMessageBarType } from "./SelfServeUtils";
|
||||||
|
import { Translation } from "react-i18next";
|
||||||
|
import { TFunction } from "i18next";
|
||||||
|
import "../i18n";
|
||||||
|
|
||||||
export interface SelfServeComponentProps {
|
export interface SelfServeComponentProps {
|
||||||
descriptor: SelfServeDescriptor;
|
descriptor: SelfServeDescriptor;
|
||||||
@ -43,6 +46,8 @@ export interface SelfServeComponentState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class SelfServeComponent extends React.Component<SelfServeComponentProps, SelfServeComponentState> {
|
export class SelfServeComponent extends React.Component<SelfServeComponentProps, SelfServeComponentState> {
|
||||||
|
private smartUiGeneratorClassName: string;
|
||||||
|
|
||||||
componentDidMount(): void {
|
componentDidMount(): void {
|
||||||
this.performRefresh();
|
this.performRefresh();
|
||||||
this.initializeSmartUiComponent();
|
this.initializeSmartUiComponent();
|
||||||
@ -60,6 +65,7 @@ export class SelfServeComponent extends React.Component<SelfServeComponentProps,
|
|||||||
notification: undefined,
|
notification: undefined,
|
||||||
refreshResult: undefined,
|
refreshResult: undefined,
|
||||||
};
|
};
|
||||||
|
this.smartUiGeneratorClassName = this.props.descriptor.root.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private onError = (hasErrors: boolean): void => {
|
private onError = (hasErrors: boolean): void => {
|
||||||
@ -147,8 +153,8 @@ export class SelfServeComponent extends React.Component<SelfServeComponentProps,
|
|||||||
currentValues: Map<string, SmartUiInput>,
|
currentValues: Map<string, SmartUiInput>,
|
||||||
baselineValues: Map<string, SmartUiInput>
|
baselineValues: Map<string, SmartUiInput>
|
||||||
): Promise<AnyDisplay> => {
|
): Promise<AnyDisplay> => {
|
||||||
input.label = await this.getResolvedValue(input.label);
|
input.labelTKey = await this.getResolvedValue(input.labelTKey);
|
||||||
input.placeholder = await this.getResolvedValue(input.placeholder);
|
input.placeholderTKey = await this.getResolvedValue(input.placeholderTKey);
|
||||||
|
|
||||||
switch (input.type) {
|
switch (input.type) {
|
||||||
case "string": {
|
case "string": {
|
||||||
@ -177,8 +183,8 @@ export class SelfServeComponent extends React.Component<SelfServeComponentProps,
|
|||||||
}
|
}
|
||||||
case "boolean": {
|
case "boolean": {
|
||||||
const booleanInput = input as BooleanInput;
|
const booleanInput = input as BooleanInput;
|
||||||
booleanInput.trueLabel = await this.getResolvedValue(booleanInput.trueLabel);
|
booleanInput.trueLabelTKey = await this.getResolvedValue(booleanInput.trueLabelTKey);
|
||||||
booleanInput.falseLabel = await this.getResolvedValue(booleanInput.falseLabel);
|
booleanInput.falseLabelTKey = await this.getResolvedValue(booleanInput.falseLabelTKey);
|
||||||
return booleanInput;
|
return booleanInput;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -214,7 +220,7 @@ export class SelfServeComponent extends React.Component<SelfServeComponentProps,
|
|||||||
onSavePromise.catch((error) => {
|
onSavePromise.catch((error) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
notification: {
|
notification: {
|
||||||
message: `Error: ${error.message}`,
|
message: `${error.message}`,
|
||||||
type: SelfServeNotificationType.error,
|
type: SelfServeNotificationType.error,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -273,11 +279,15 @@ export class SelfServeComponent extends React.Component<SelfServeComponentProps,
|
|||||||
this.setState({ isInitializing: false });
|
this.setState({ isInitializing: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
private getCommandBarItems = (): ICommandBarItemProps[] => {
|
public getCommonTranslation = (translationFunction: TFunction, key: string): string => {
|
||||||
|
return translationFunction(`Common.${key}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
private getCommandBarItems = (translate: TFunction): ICommandBarItemProps[] => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
key: "save",
|
key: "save",
|
||||||
text: "Save",
|
text: this.getCommonTranslation(translate, "Save"),
|
||||||
iconProps: { iconName: "Save" },
|
iconProps: { iconName: "Save" },
|
||||||
split: true,
|
split: true,
|
||||||
disabled: this.isSaveButtonDisabled(),
|
disabled: this.isSaveButtonDisabled(),
|
||||||
@ -285,7 +295,7 @@ export class SelfServeComponent extends React.Component<SelfServeComponentProps,
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "discard",
|
key: "discard",
|
||||||
text: "Discard",
|
text: this.getCommonTranslation(translate, "Discard"),
|
||||||
iconProps: { iconName: "Undo" },
|
iconProps: { iconName: "Undo" },
|
||||||
split: true,
|
split: true,
|
||||||
disabled: this.isDiscardButtonDisabled(),
|
disabled: this.isDiscardButtonDisabled(),
|
||||||
@ -295,7 +305,7 @@ export class SelfServeComponent extends React.Component<SelfServeComponentProps,
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "refresh",
|
key: "refresh",
|
||||||
text: "Refresh",
|
text: this.getCommonTranslation(translate, "Refresh"),
|
||||||
disabled: this.state.isInitializing,
|
disabled: this.state.isInitializing,
|
||||||
iconProps: { iconName: "Refresh" },
|
iconProps: { iconName: "Refresh" },
|
||||||
split: true,
|
split: true,
|
||||||
@ -306,15 +316,30 @@ export class SelfServeComponent extends React.Component<SelfServeComponentProps,
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private getNotificationMessageTranslation = (translationFunction: TFunction, messageKey: string): string => {
|
||||||
|
const translation = translationFunction(messageKey);
|
||||||
|
if (translation === `${this.smartUiGeneratorClassName}.${messageKey}`) {
|
||||||
|
return messageKey;
|
||||||
|
}
|
||||||
|
return translation;
|
||||||
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): JSX.Element {
|
||||||
const containerStackTokens: IStackTokens = { childrenGap: 5 };
|
const containerStackTokens: IStackTokens = { childrenGap: 5 };
|
||||||
if (this.state.compileErrorMessage) {
|
if (this.state.compileErrorMessage) {
|
||||||
return <MessageBar messageBarType={MessageBarType.error}>{this.state.compileErrorMessage}</MessageBar>;
|
return <MessageBar messageBarType={MessageBarType.error}>{this.state.compileErrorMessage}</MessageBar>;
|
||||||
}
|
}
|
||||||
|
return (
|
||||||
|
<Translation>
|
||||||
|
{(translate) => {
|
||||||
|
const getTranslation = (key: string): string => {
|
||||||
|
return translate(`${this.smartUiGeneratorClassName}.${key}`);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ overflowX: "auto" }}>
|
<div style={{ overflowX: "auto" }}>
|
||||||
<Stack tokens={containerStackTokens} styles={{ root: { padding: 10 } }}>
|
<Stack tokens={containerStackTokens} styles={{ root: { padding: 10 } }}>
|
||||||
<CommandBar styles={{ root: { paddingLeft: 0 } }} items={this.getCommandBarItems()} />
|
<CommandBar styles={{ root: { paddingLeft: 0 } }} items={this.getCommandBarItems(translate)} />
|
||||||
{this.state.isInitializing ? (
|
{this.state.isInitializing ? (
|
||||||
<Spinner
|
<Spinner
|
||||||
size={SpinnerSize.large}
|
size={SpinnerSize.large}
|
||||||
@ -324,7 +349,7 @@ export class SelfServeComponent extends React.Component<SelfServeComponentProps,
|
|||||||
<>
|
<>
|
||||||
{this.state.refreshResult?.isUpdateInProgress && (
|
{this.state.refreshResult?.isUpdateInProgress && (
|
||||||
<MessageBar messageBarType={MessageBarType.info} styles={{ root: { width: 400 } }}>
|
<MessageBar messageBarType={MessageBarType.info} styles={{ root: { width: 400 } }}>
|
||||||
{this.state.refreshResult.notificationMessage}
|
{getTranslation(this.state.refreshResult.notificationMessage)}
|
||||||
</MessageBar>
|
</MessageBar>
|
||||||
)}
|
)}
|
||||||
{this.state.notification && (
|
{this.state.notification && (
|
||||||
@ -333,7 +358,7 @@ export class SelfServeComponent extends React.Component<SelfServeComponentProps,
|
|||||||
styles={{ root: { width: 400 } }}
|
styles={{ root: { width: 400 } }}
|
||||||
onDismiss={() => this.setState({ notification: undefined })}
|
onDismiss={() => this.setState({ notification: undefined })}
|
||||||
>
|
>
|
||||||
{this.state.notification.message}
|
{this.getNotificationMessageTranslation(getTranslation, this.state.notification.message)}
|
||||||
</MessageBar>
|
</MessageBar>
|
||||||
)}
|
)}
|
||||||
<SmartUiComponent
|
<SmartUiComponent
|
||||||
@ -342,11 +367,15 @@ export class SelfServeComponent extends React.Component<SelfServeComponentProps,
|
|||||||
currentValues={this.state.currentValues}
|
currentValues={this.state.currentValues}
|
||||||
onInputChange={this.onInputChange}
|
onInputChange={this.onInputChange}
|
||||||
onError={this.onError}
|
onError={this.onError}
|
||||||
|
getTranslation={getTranslation}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
}}
|
||||||
|
</Translation>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,9 @@ interface BaseInput {
|
|||||||
dataFieldName: string;
|
dataFieldName: string;
|
||||||
errorMessage?: string;
|
errorMessage?: string;
|
||||||
type: InputTypeValue;
|
type: InputTypeValue;
|
||||||
label?: (() => Promise<string>) | string;
|
labelTKey?: (() => Promise<string>) | string;
|
||||||
onChange?: (currentState: Map<string, SmartUiInput>, newValue: InputType) => Map<string, SmartUiInput>;
|
onChange?: (currentState: Map<string, SmartUiInput>, newValue: InputType) => Map<string, SmartUiInput>;
|
||||||
placeholder?: (() => Promise<string>) | string;
|
placeholderTKey?: (() => Promise<string>) | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NumberInput extends BaseInput {
|
export interface NumberInput extends BaseInput {
|
||||||
@ -16,8 +16,8 @@ export interface NumberInput extends BaseInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface BooleanInput extends BaseInput {
|
export interface BooleanInput extends BaseInput {
|
||||||
trueLabel: (() => Promise<string>) | string;
|
trueLabelTKey: (() => Promise<string>) | string;
|
||||||
falseLabel: (() => Promise<string>) | string;
|
falseLabelTKey: (() => Promise<string>) | string;
|
||||||
defaultValue?: boolean;
|
defaultValue?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,18 +92,18 @@ export type ChoiceItem = { label: string; key: string };
|
|||||||
export type InputType = number | string | boolean | ChoiceItem;
|
export type InputType = number | string | boolean | ChoiceItem;
|
||||||
|
|
||||||
export interface Info {
|
export interface Info {
|
||||||
message: string;
|
messageTKey: string;
|
||||||
link?: {
|
link?: {
|
||||||
href: string;
|
href: string;
|
||||||
text: string;
|
textTKey: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Description {
|
export interface Description {
|
||||||
text: string;
|
textTKey: string;
|
||||||
link?: {
|
link?: {
|
||||||
href: string;
|
href: string;
|
||||||
text: string;
|
textTKey: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ describe("SelfServeUtils", () => {
|
|||||||
id: "dbThroughput",
|
id: "dbThroughput",
|
||||||
dataFieldName: "dbThroughput",
|
dataFieldName: "dbThroughput",
|
||||||
type: "number",
|
type: "number",
|
||||||
label: "Database Throughput",
|
labelTKey: "Database Throughput",
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 5,
|
max: 5,
|
||||||
step: 1,
|
step: 1,
|
||||||
@ -71,7 +71,7 @@ describe("SelfServeUtils", () => {
|
|||||||
id: "collThroughput",
|
id: "collThroughput",
|
||||||
dataFieldName: "collThroughput",
|
dataFieldName: "collThroughput",
|
||||||
type: "number",
|
type: "number",
|
||||||
label: "Coll Throughput",
|
labelTKey: "Coll Throughput",
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 5,
|
max: 5,
|
||||||
step: 1,
|
step: 1,
|
||||||
@ -84,7 +84,7 @@ describe("SelfServeUtils", () => {
|
|||||||
id: "invalidThroughput",
|
id: "invalidThroughput",
|
||||||
dataFieldName: "invalidThroughput",
|
dataFieldName: "invalidThroughput",
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
label: "Invalid Coll Throughput",
|
labelTKey: "Invalid Coll Throughput",
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 5,
|
max: 5,
|
||||||
step: 1,
|
step: 1,
|
||||||
@ -98,8 +98,8 @@ describe("SelfServeUtils", () => {
|
|||||||
id: "collName",
|
id: "collName",
|
||||||
dataFieldName: "collName",
|
dataFieldName: "collName",
|
||||||
type: "string",
|
type: "string",
|
||||||
label: "Coll Name",
|
labelTKey: "Coll Name",
|
||||||
placeholder: "placeholder text",
|
placeholderTKey: "placeholder text",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@ -108,9 +108,9 @@ describe("SelfServeUtils", () => {
|
|||||||
id: "enableLogging",
|
id: "enableLogging",
|
||||||
dataFieldName: "enableLogging",
|
dataFieldName: "enableLogging",
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
label: "Enable Logging",
|
labelTKey: "Enable Logging",
|
||||||
trueLabel: "Enable",
|
trueLabelTKey: "Enable",
|
||||||
falseLabel: "Disable",
|
falseLabelTKey: "Disable",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@ -119,8 +119,8 @@ describe("SelfServeUtils", () => {
|
|||||||
id: "invalidEnableLogging",
|
id: "invalidEnableLogging",
|
||||||
dataFieldName: "invalidEnableLogging",
|
dataFieldName: "invalidEnableLogging",
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
label: "Invalid Enable Logging",
|
labelTKey: "Invalid Enable Logging",
|
||||||
placeholder: "placeholder text",
|
placeholderTKey: "placeholder text",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@ -129,7 +129,7 @@ describe("SelfServeUtils", () => {
|
|||||||
id: "regions",
|
id: "regions",
|
||||||
dataFieldName: "regions",
|
dataFieldName: "regions",
|
||||||
type: "object",
|
type: "object",
|
||||||
label: "Regions",
|
labelTKey: "Regions",
|
||||||
choices: [
|
choices: [
|
||||||
{ label: "South West US", key: "SWUS" },
|
{ label: "South West US", key: "SWUS" },
|
||||||
{ label: "North Central US", key: "NCUS" },
|
{ label: "North Central US", key: "NCUS" },
|
||||||
@ -143,14 +143,14 @@ describe("SelfServeUtils", () => {
|
|||||||
id: "invalidRegions",
|
id: "invalidRegions",
|
||||||
dataFieldName: "invalidRegions",
|
dataFieldName: "invalidRegions",
|
||||||
type: "object",
|
type: "object",
|
||||||
label: "Invalid Regions",
|
labelTKey: "Invalid Regions",
|
||||||
placeholder: "placeholder text",
|
placeholderTKey: "placeholder text",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
const expectedDescriptor = {
|
const expectedDescriptor = {
|
||||||
root: {
|
root: {
|
||||||
id: "root",
|
id: "TestClass",
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: "dbThroughput",
|
id: "dbThroughput",
|
||||||
@ -158,7 +158,7 @@ describe("SelfServeUtils", () => {
|
|||||||
id: "dbThroughput",
|
id: "dbThroughput",
|
||||||
dataFieldName: "dbThroughput",
|
dataFieldName: "dbThroughput",
|
||||||
type: "number",
|
type: "number",
|
||||||
label: "Database Throughput",
|
labelTKey: "Database Throughput",
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 5,
|
max: 5,
|
||||||
step: 1,
|
step: 1,
|
||||||
@ -172,7 +172,7 @@ describe("SelfServeUtils", () => {
|
|||||||
id: "collThroughput",
|
id: "collThroughput",
|
||||||
dataFieldName: "collThroughput",
|
dataFieldName: "collThroughput",
|
||||||
type: "number",
|
type: "number",
|
||||||
label: "Coll Throughput",
|
labelTKey: "Coll Throughput",
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 5,
|
max: 5,
|
||||||
step: 1,
|
step: 1,
|
||||||
@ -186,7 +186,7 @@ describe("SelfServeUtils", () => {
|
|||||||
id: "invalidThroughput",
|
id: "invalidThroughput",
|
||||||
dataFieldName: "invalidThroughput",
|
dataFieldName: "invalidThroughput",
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
label: "Invalid Coll Throughput",
|
labelTKey: "Invalid Coll Throughput",
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 5,
|
max: 5,
|
||||||
step: 1,
|
step: 1,
|
||||||
@ -201,8 +201,8 @@ describe("SelfServeUtils", () => {
|
|||||||
id: "collName",
|
id: "collName",
|
||||||
dataFieldName: "collName",
|
dataFieldName: "collName",
|
||||||
type: "string",
|
type: "string",
|
||||||
label: "Coll Name",
|
labelTKey: "Coll Name",
|
||||||
placeholder: "placeholder text",
|
placeholderTKey: "placeholder text",
|
||||||
},
|
},
|
||||||
children: [] as Node[],
|
children: [] as Node[],
|
||||||
},
|
},
|
||||||
@ -212,9 +212,9 @@ describe("SelfServeUtils", () => {
|
|||||||
id: "enableLogging",
|
id: "enableLogging",
|
||||||
dataFieldName: "enableLogging",
|
dataFieldName: "enableLogging",
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
label: "Enable Logging",
|
labelTKey: "Enable Logging",
|
||||||
trueLabel: "Enable",
|
trueLabelTKey: "Enable",
|
||||||
falseLabel: "Disable",
|
falseLabelTKey: "Disable",
|
||||||
},
|
},
|
||||||
children: [] as Node[],
|
children: [] as Node[],
|
||||||
},
|
},
|
||||||
@ -224,8 +224,8 @@ describe("SelfServeUtils", () => {
|
|||||||
id: "invalidEnableLogging",
|
id: "invalidEnableLogging",
|
||||||
dataFieldName: "invalidEnableLogging",
|
dataFieldName: "invalidEnableLogging",
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
label: "Invalid Enable Logging",
|
labelTKey: "Invalid Enable Logging",
|
||||||
placeholder: "placeholder text",
|
placeholderTKey: "placeholder text",
|
||||||
errorMessage: "label, truelabel and falselabel are required for boolean input 'invalidEnableLogging'.",
|
errorMessage: "label, truelabel and falselabel are required for boolean input 'invalidEnableLogging'.",
|
||||||
},
|
},
|
||||||
children: [] as Node[],
|
children: [] as Node[],
|
||||||
@ -236,7 +236,7 @@ describe("SelfServeUtils", () => {
|
|||||||
id: "regions",
|
id: "regions",
|
||||||
dataFieldName: "regions",
|
dataFieldName: "regions",
|
||||||
type: "object",
|
type: "object",
|
||||||
label: "Regions",
|
labelTKey: "Regions",
|
||||||
choices: [
|
choices: [
|
||||||
{ label: "South West US", key: "SWUS" },
|
{ label: "South West US", key: "SWUS" },
|
||||||
{ label: "North Central US", key: "NCUS" },
|
{ label: "North Central US", key: "NCUS" },
|
||||||
@ -251,8 +251,8 @@ describe("SelfServeUtils", () => {
|
|||||||
id: "invalidRegions",
|
id: "invalidRegions",
|
||||||
dataFieldName: "invalidRegions",
|
dataFieldName: "invalidRegions",
|
||||||
type: "object",
|
type: "object",
|
||||||
label: "Invalid Regions",
|
labelTKey: "Invalid Regions",
|
||||||
placeholder: "placeholder text",
|
placeholderTKey: "placeholder text",
|
||||||
errorMessage: "label and choices are required for Choice input 'invalidRegions'.",
|
errorMessage: "label and choices are required for Choice input 'invalidRegions'.",
|
||||||
},
|
},
|
||||||
children: [] as Node[],
|
children: [] as Node[],
|
||||||
@ -270,7 +270,7 @@ describe("SelfServeUtils", () => {
|
|||||||
"invalidRegions",
|
"invalidRegions",
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
const descriptor = mapToSmartUiDescriptor(context);
|
const descriptor = mapToSmartUiDescriptor("TestClass", context);
|
||||||
expect(descriptor).toEqual(expectedDescriptor);
|
expect(descriptor).toEqual(expectedDescriptor);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -32,14 +32,14 @@ export interface DecoratorProperties {
|
|||||||
id: string;
|
id: string;
|
||||||
info?: (() => Promise<Info>) | Info;
|
info?: (() => Promise<Info>) | Info;
|
||||||
type?: InputTypeValue;
|
type?: InputTypeValue;
|
||||||
label?: (() => Promise<string>) | string;
|
labelTKey?: (() => Promise<string>) | string;
|
||||||
placeholder?: (() => Promise<string>) | string;
|
placeholderTKey?: (() => Promise<string>) | string;
|
||||||
dataFieldName?: string;
|
dataFieldName?: string;
|
||||||
min?: (() => Promise<number>) | number;
|
min?: (() => Promise<number>) | number;
|
||||||
max?: (() => Promise<number>) | number;
|
max?: (() => Promise<number>) | number;
|
||||||
step?: (() => Promise<number>) | number;
|
step?: (() => Promise<number>) | number;
|
||||||
trueLabel?: (() => Promise<string>) | string;
|
trueLabelTKey?: (() => Promise<string>) | string;
|
||||||
falseLabel?: (() => Promise<string>) | string;
|
falseLabelTKey?: (() => Promise<string>) | string;
|
||||||
choices?: (() => Promise<ChoiceItem[]>) | ChoiceItem[];
|
choices?: (() => Promise<ChoiceItem[]>) | ChoiceItem[];
|
||||||
uiType?: string;
|
uiType?: string;
|
||||||
errorMessage?: string;
|
errorMessage?: string;
|
||||||
@ -100,18 +100,21 @@ export const updateContextWithDecorator = <T extends keyof DecoratorProperties,
|
|||||||
|
|
||||||
export const buildSmartUiDescriptor = (className: string, target: unknown): void => {
|
export const buildSmartUiDescriptor = (className: string, target: unknown): void => {
|
||||||
const context = Reflect.getMetadata(className, target) as Map<string, DecoratorProperties>;
|
const context = Reflect.getMetadata(className, target) as Map<string, DecoratorProperties>;
|
||||||
const smartUiDescriptor = mapToSmartUiDescriptor(context);
|
const smartUiDescriptor = mapToSmartUiDescriptor(className, context);
|
||||||
Reflect.defineMetadata(className, smartUiDescriptor, target);
|
Reflect.defineMetadata(className, smartUiDescriptor, target);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mapToSmartUiDescriptor = (context: Map<string, DecoratorProperties>): SelfServeDescriptor => {
|
export const mapToSmartUiDescriptor = (
|
||||||
|
className: string,
|
||||||
|
context: Map<string, DecoratorProperties>
|
||||||
|
): SelfServeDescriptor => {
|
||||||
const root = context.get("root");
|
const root = context.get("root");
|
||||||
context.delete("root");
|
context.delete("root");
|
||||||
const inputNames: string[] = [];
|
const inputNames: string[] = [];
|
||||||
|
|
||||||
const smartUiDescriptor: SelfServeDescriptor = {
|
const smartUiDescriptor: SelfServeDescriptor = {
|
||||||
root: {
|
root: {
|
||||||
id: "root",
|
id: className,
|
||||||
info: root?.info,
|
info: root?.info,
|
||||||
children: [],
|
children: [],
|
||||||
},
|
},
|
||||||
@ -147,7 +150,7 @@ const addToDescriptor = (
|
|||||||
const getInput = (value: DecoratorProperties): AnyDisplay => {
|
const getInput = (value: DecoratorProperties): AnyDisplay => {
|
||||||
switch (value.type) {
|
switch (value.type) {
|
||||||
case "number":
|
case "number":
|
||||||
if (!value.label || !value.step || !value.uiType || !value.min || !value.max) {
|
if (!value.labelTKey || !value.step || !value.uiType || !value.min || !value.max) {
|
||||||
value.errorMessage = `label, step, min, max and uiType are required for number input '${value.id}'.`;
|
value.errorMessage = `label, step, min, max and uiType are required for number input '${value.id}'.`;
|
||||||
}
|
}
|
||||||
return value as NumberInput;
|
return value as NumberInput;
|
||||||
@ -155,17 +158,17 @@ const getInput = (value: DecoratorProperties): AnyDisplay => {
|
|||||||
if (value.description) {
|
if (value.description) {
|
||||||
return value as DescriptionDisplay;
|
return value as DescriptionDisplay;
|
||||||
}
|
}
|
||||||
if (!value.label) {
|
if (!value.labelTKey) {
|
||||||
value.errorMessage = `label is required for string input '${value.id}'.`;
|
value.errorMessage = `label is required for string input '${value.id}'.`;
|
||||||
}
|
}
|
||||||
return value as StringInput;
|
return value as StringInput;
|
||||||
case "boolean":
|
case "boolean":
|
||||||
if (!value.label || !value.trueLabel || !value.falseLabel) {
|
if (!value.labelTKey || !value.trueLabelTKey || !value.falseLabelTKey) {
|
||||||
value.errorMessage = `label, truelabel and falselabel are required for boolean input '${value.id}'.`;
|
value.errorMessage = `label, truelabel and falselabel are required for boolean input '${value.id}'.`;
|
||||||
}
|
}
|
||||||
return value as BooleanInput;
|
return value as BooleanInput;
|
||||||
default:
|
default:
|
||||||
if (!value.label || !value.choices) {
|
if (!value.labelTKey || !value.choices) {
|
||||||
value.errorMessage = `label and choices are required for Choice input '${value.id}'.`;
|
value.errorMessage = `label and choices are required for Choice input '${value.id}'.`;
|
||||||
}
|
}
|
||||||
return value as ChoiceInput;
|
return value as ChoiceInput;
|
||||||
|
@ -62,10 +62,10 @@ export default class SqlX extends SelfServeBaseClass {
|
|||||||
|
|
||||||
@Values({
|
@Values({
|
||||||
description: {
|
description: {
|
||||||
text: "Provisioning dedicated gateways for SqlX accounts.",
|
textTKey: "Provisioning dedicated gateways for SqlX accounts.",
|
||||||
link: {
|
link: {
|
||||||
href: "https://docs.microsoft.com/en-us/azure/cosmos-db/introduction",
|
href: "https://docs.microsoft.com/en-us/azure/cosmos-db/introduction",
|
||||||
text: "Learn more about dedicated gateway.",
|
textTKey: "Learn more about dedicated gateway.",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -73,21 +73,21 @@ export default class SqlX extends SelfServeBaseClass {
|
|||||||
|
|
||||||
@OnChange(onEnableDedicatedGatewayChange)
|
@OnChange(onEnableDedicatedGatewayChange)
|
||||||
@Values({
|
@Values({
|
||||||
label: "Dedicated Gateway",
|
labelTKey: "Dedicated Gateway",
|
||||||
trueLabel: "Enable",
|
trueLabelTKey: "Enable",
|
||||||
falseLabel: "Disable",
|
falseLabelTKey: "Disable",
|
||||||
})
|
})
|
||||||
enableDedicatedGateway: boolean;
|
enableDedicatedGateway: boolean;
|
||||||
|
|
||||||
@Values({
|
@Values({
|
||||||
label: "SKUs",
|
labelTKey: "SKUs",
|
||||||
choices: getSkus,
|
choices: getSkus,
|
||||||
placeholder: "Select SKUs",
|
placeholderTKey: "Select SKUs",
|
||||||
})
|
})
|
||||||
sku: ChoiceItem;
|
sku: ChoiceItem;
|
||||||
|
|
||||||
@Values({
|
@Values({
|
||||||
label: "Number of instances",
|
labelTKey: "Number of instances",
|
||||||
min: getInstancesMin,
|
min: getInstancesMin,
|
||||||
max: getInstancesMax,
|
max: getInstancesMax,
|
||||||
step: 1,
|
step: 1,
|
||||||
|
@ -1,686 +1,21 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`SelfServeComponent message bar and spinner snapshots 1`] = `
|
exports[`SelfServeComponent message bar and spinner snapshots 1`] = `
|
||||||
<div
|
<Translation>
|
||||||
style={
|
<Component />
|
||||||
Object {
|
</Translation>
|
||||||
"overflowX": "auto",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Stack
|
|
||||||
styles={
|
|
||||||
Object {
|
|
||||||
"root": Object {
|
|
||||||
"padding": 10,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tokens={
|
|
||||||
Object {
|
|
||||||
"childrenGap": 5,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<StyledCommandBarBase
|
|
||||||
items={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"disabled": true,
|
|
||||||
"iconProps": Object {
|
|
||||||
"iconName": "Save",
|
|
||||||
},
|
|
||||||
"key": "save",
|
|
||||||
"onClick": [Function],
|
|
||||||
"split": true,
|
|
||||||
"text": "Save",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"disabled": true,
|
|
||||||
"iconProps": Object {
|
|
||||||
"iconName": "Undo",
|
|
||||||
},
|
|
||||||
"key": "discard",
|
|
||||||
"onClick": [Function],
|
|
||||||
"split": true,
|
|
||||||
"text": "Discard",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"disabled": false,
|
|
||||||
"iconProps": Object {
|
|
||||||
"iconName": "Refresh",
|
|
||||||
},
|
|
||||||
"key": "refresh",
|
|
||||||
"onClick": [Function],
|
|
||||||
"split": true,
|
|
||||||
"text": "Refresh",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
styles={
|
|
||||||
Object {
|
|
||||||
"root": Object {
|
|
||||||
"paddingLeft": 0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<StyledMessageBarBase
|
|
||||||
messageBarType={0}
|
|
||||||
styles={
|
|
||||||
Object {
|
|
||||||
"root": Object {
|
|
||||||
"width": 400,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
refresh performed successfully
|
|
||||||
</StyledMessageBarBase>
|
|
||||||
<StyledMessageBarBase
|
|
||||||
messageBarType={0}
|
|
||||||
onDismiss={[Function]}
|
|
||||||
styles={
|
|
||||||
Object {
|
|
||||||
"root": Object {
|
|
||||||
"width": 400,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
submitted successfully
|
|
||||||
</StyledMessageBarBase>
|
|
||||||
<SmartUiComponent
|
|
||||||
currentValues={
|
|
||||||
Map {
|
|
||||||
"throughput" => Object {
|
|
||||||
"value": 450,
|
|
||||||
},
|
|
||||||
"analyticalStore" => Object {
|
|
||||||
"value": false,
|
|
||||||
},
|
|
||||||
"database" => Object {
|
|
||||||
"value": "db2",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
descriptor={
|
|
||||||
Object {
|
|
||||||
"initialize": [MockFunction] {
|
|
||||||
"calls": Array [
|
|
||||||
Array [],
|
|
||||||
Array [],
|
|
||||||
Array [],
|
|
||||||
Array [],
|
|
||||||
Array [],
|
|
||||||
],
|
|
||||||
"results": Array [
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
"inputNames": Array [
|
|
||||||
"throughput",
|
|
||||||
"analyticalStore",
|
|
||||||
"database",
|
|
||||||
],
|
|
||||||
"onRefresh": [MockFunction] {
|
|
||||||
"calls": Array [
|
|
||||||
Array [],
|
|
||||||
Array [],
|
|
||||||
],
|
|
||||||
"results": Array [
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
"onSave": [MockFunction] {
|
|
||||||
"calls": Array [
|
|
||||||
Array [
|
|
||||||
Map {
|
|
||||||
"throughput" => Object {
|
|
||||||
"value": 450,
|
|
||||||
},
|
|
||||||
"analyticalStore" => Object {
|
|
||||||
"value": false,
|
|
||||||
},
|
|
||||||
"database" => Object {
|
|
||||||
"value": "db2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
Array [
|
|
||||||
Map {
|
|
||||||
"throughput" => Object {
|
|
||||||
"value": 450,
|
|
||||||
},
|
|
||||||
"analyticalStore" => Object {
|
|
||||||
"value": false,
|
|
||||||
},
|
|
||||||
"database" => Object {
|
|
||||||
"value": "db2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
"results": Array [
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
"root": Object {
|
|
||||||
"children": Array [
|
|
||||||
Object {
|
|
||||||
"id": "throughput",
|
|
||||||
"info": undefined,
|
|
||||||
"input": Object {
|
|
||||||
"dataFieldName": "throughput",
|
|
||||||
"defaultValue": 400,
|
|
||||||
"label": "Throughput (input)",
|
|
||||||
"max": 500,
|
|
||||||
"min": 400,
|
|
||||||
"placeholder": undefined,
|
|
||||||
"step": 10,
|
|
||||||
"type": "number",
|
|
||||||
"uiType": "Spinner",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"id": "containerId",
|
|
||||||
"info": undefined,
|
|
||||||
"input": Object {
|
|
||||||
"dataFieldName": "containerId",
|
|
||||||
"label": "Container id",
|
|
||||||
"placeholder": undefined,
|
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"id": "analyticalStore",
|
|
||||||
"info": undefined,
|
|
||||||
"input": Object {
|
|
||||||
"dataFieldName": "analyticalStore",
|
|
||||||
"defaultValue": true,
|
|
||||||
"falseLabel": "Disabled",
|
|
||||||
"label": "Analytical Store",
|
|
||||||
"placeholder": undefined,
|
|
||||||
"trueLabel": "Enabled",
|
|
||||||
"type": "boolean",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"id": "database",
|
|
||||||
"info": undefined,
|
|
||||||
"input": Object {
|
|
||||||
"choices": Array [
|
|
||||||
Object {
|
|
||||||
"key": "db1",
|
|
||||||
"label": "Database 1",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"key": "db2",
|
|
||||||
"label": "Database 2",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"key": "db3",
|
|
||||||
"label": "Database 3",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"dataFieldName": "database",
|
|
||||||
"defaultKey": "db2",
|
|
||||||
"label": "Database",
|
|
||||||
"placeholder": undefined,
|
|
||||||
"type": "object",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"id": "root",
|
|
||||||
"info": Object {
|
|
||||||
"link": Object {
|
|
||||||
"href": "https://aka.ms/azure-cosmos-db-pricing",
|
|
||||||
"text": "More Details",
|
|
||||||
},
|
|
||||||
"message": "Start at $24/mo per database",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
disabled={true}
|
|
||||||
onError={[Function]}
|
|
||||||
onInputChange={[Function]}
|
|
||||||
/>
|
|
||||||
</Stack>
|
|
||||||
</div>
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`SelfServeComponent message bar and spinner snapshots 2`] = `
|
exports[`SelfServeComponent message bar and spinner snapshots 2`] = `
|
||||||
<div
|
<Translation>
|
||||||
style={
|
<Component />
|
||||||
Object {
|
</Translation>
|
||||||
"overflowX": "auto",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Stack
|
|
||||||
styles={
|
|
||||||
Object {
|
|
||||||
"root": Object {
|
|
||||||
"padding": 10,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tokens={
|
|
||||||
Object {
|
|
||||||
"childrenGap": 5,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<StyledCommandBarBase
|
|
||||||
items={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"disabled": true,
|
|
||||||
"iconProps": Object {
|
|
||||||
"iconName": "Save",
|
|
||||||
},
|
|
||||||
"key": "save",
|
|
||||||
"onClick": [Function],
|
|
||||||
"split": true,
|
|
||||||
"text": "Save",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"disabled": true,
|
|
||||||
"iconProps": Object {
|
|
||||||
"iconName": "Undo",
|
|
||||||
},
|
|
||||||
"key": "discard",
|
|
||||||
"onClick": [Function],
|
|
||||||
"split": true,
|
|
||||||
"text": "Discard",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"disabled": false,
|
|
||||||
"iconProps": Object {
|
|
||||||
"iconName": "Refresh",
|
|
||||||
},
|
|
||||||
"key": "refresh",
|
|
||||||
"onClick": [Function],
|
|
||||||
"split": true,
|
|
||||||
"text": "Refresh",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
styles={
|
|
||||||
Object {
|
|
||||||
"root": Object {
|
|
||||||
"paddingLeft": 0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<StyledMessageBarBase
|
|
||||||
messageBarType={0}
|
|
||||||
onDismiss={[Function]}
|
|
||||||
styles={
|
|
||||||
Object {
|
|
||||||
"root": Object {
|
|
||||||
"width": 400,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
submitted successfully
|
|
||||||
</StyledMessageBarBase>
|
|
||||||
<SmartUiComponent
|
|
||||||
currentValues={
|
|
||||||
Map {
|
|
||||||
"throughput" => Object {
|
|
||||||
"value": 450,
|
|
||||||
},
|
|
||||||
"analyticalStore" => Object {
|
|
||||||
"value": false,
|
|
||||||
},
|
|
||||||
"database" => Object {
|
|
||||||
"value": "db2",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
descriptor={
|
|
||||||
Object {
|
|
||||||
"initialize": [MockFunction] {
|
|
||||||
"calls": Array [
|
|
||||||
Array [],
|
|
||||||
Array [],
|
|
||||||
Array [],
|
|
||||||
Array [],
|
|
||||||
Array [],
|
|
||||||
Array [],
|
|
||||||
Array [],
|
|
||||||
],
|
|
||||||
"results": Array [
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
"inputNames": Array [
|
|
||||||
"throughput",
|
|
||||||
"analyticalStore",
|
|
||||||
"database",
|
|
||||||
],
|
|
||||||
"onRefresh": [MockFunction] {
|
|
||||||
"calls": Array [
|
|
||||||
Array [],
|
|
||||||
Array [],
|
|
||||||
Array [],
|
|
||||||
Array [],
|
|
||||||
Array [],
|
|
||||||
Array [],
|
|
||||||
],
|
|
||||||
"results": Array [
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
"onSave": [MockFunction] {
|
|
||||||
"calls": Array [
|
|
||||||
Array [
|
|
||||||
Map {
|
|
||||||
"throughput" => Object {
|
|
||||||
"value": 450,
|
|
||||||
},
|
|
||||||
"analyticalStore" => Object {
|
|
||||||
"value": false,
|
|
||||||
},
|
|
||||||
"database" => Object {
|
|
||||||
"value": "db2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
Array [
|
|
||||||
Map {
|
|
||||||
"throughput" => Object {
|
|
||||||
"value": 450,
|
|
||||||
},
|
|
||||||
"analyticalStore" => Object {
|
|
||||||
"value": false,
|
|
||||||
},
|
|
||||||
"database" => Object {
|
|
||||||
"value": "db2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
Array [
|
|
||||||
Map {
|
|
||||||
"throughput" => Object {
|
|
||||||
"value": 450,
|
|
||||||
},
|
|
||||||
"analyticalStore" => Object {
|
|
||||||
"value": false,
|
|
||||||
},
|
|
||||||
"database" => Object {
|
|
||||||
"value": "db2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
"results": Array [
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
"root": Object {
|
|
||||||
"children": Array [
|
|
||||||
Object {
|
|
||||||
"id": "throughput",
|
|
||||||
"info": undefined,
|
|
||||||
"input": Object {
|
|
||||||
"dataFieldName": "throughput",
|
|
||||||
"defaultValue": 400,
|
|
||||||
"label": "Throughput (input)",
|
|
||||||
"max": 500,
|
|
||||||
"min": 400,
|
|
||||||
"placeholder": undefined,
|
|
||||||
"step": 10,
|
|
||||||
"type": "number",
|
|
||||||
"uiType": "Spinner",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"id": "containerId",
|
|
||||||
"info": undefined,
|
|
||||||
"input": Object {
|
|
||||||
"dataFieldName": "containerId",
|
|
||||||
"label": "Container id",
|
|
||||||
"placeholder": undefined,
|
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"id": "analyticalStore",
|
|
||||||
"info": undefined,
|
|
||||||
"input": Object {
|
|
||||||
"dataFieldName": "analyticalStore",
|
|
||||||
"defaultValue": true,
|
|
||||||
"falseLabel": "Disabled",
|
|
||||||
"label": "Analytical Store",
|
|
||||||
"placeholder": undefined,
|
|
||||||
"trueLabel": "Enabled",
|
|
||||||
"type": "boolean",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"id": "database",
|
|
||||||
"info": undefined,
|
|
||||||
"input": Object {
|
|
||||||
"choices": Array [
|
|
||||||
Object {
|
|
||||||
"key": "db1",
|
|
||||||
"label": "Database 1",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"key": "db2",
|
|
||||||
"label": "Database 2",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"key": "db3",
|
|
||||||
"label": "Database 3",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"dataFieldName": "database",
|
|
||||||
"defaultKey": "db2",
|
|
||||||
"label": "Database",
|
|
||||||
"placeholder": undefined,
|
|
||||||
"type": "object",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"id": "root",
|
|
||||||
"info": Object {
|
|
||||||
"link": Object {
|
|
||||||
"href": "https://aka.ms/azure-cosmos-db-pricing",
|
|
||||||
"text": "More Details",
|
|
||||||
},
|
|
||||||
"message": "Start at $24/mo per database",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
disabled={false}
|
|
||||||
onError={[Function]}
|
|
||||||
onInputChange={[Function]}
|
|
||||||
/>
|
|
||||||
</Stack>
|
|
||||||
</div>
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`SelfServeComponent message bar and spinner snapshots 3`] = `
|
exports[`SelfServeComponent message bar and spinner snapshots 3`] = `
|
||||||
<div
|
<Translation>
|
||||||
style={
|
<Component />
|
||||||
Object {
|
</Translation>
|
||||||
"overflowX": "auto",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Stack
|
|
||||||
styles={
|
|
||||||
Object {
|
|
||||||
"root": Object {
|
|
||||||
"padding": 10,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tokens={
|
|
||||||
Object {
|
|
||||||
"childrenGap": 5,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<StyledCommandBarBase
|
|
||||||
items={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"disabled": true,
|
|
||||||
"iconProps": Object {
|
|
||||||
"iconName": "Save",
|
|
||||||
},
|
|
||||||
"key": "save",
|
|
||||||
"onClick": [Function],
|
|
||||||
"split": true,
|
|
||||||
"text": "Save",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"disabled": true,
|
|
||||||
"iconProps": Object {
|
|
||||||
"iconName": "Undo",
|
|
||||||
},
|
|
||||||
"key": "discard",
|
|
||||||
"onClick": [Function],
|
|
||||||
"split": true,
|
|
||||||
"text": "Discard",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"disabled": true,
|
|
||||||
"iconProps": Object {
|
|
||||||
"iconName": "Refresh",
|
|
||||||
},
|
|
||||||
"key": "refresh",
|
|
||||||
"onClick": [Function],
|
|
||||||
"split": true,
|
|
||||||
"text": "Refresh",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
styles={
|
|
||||||
Object {
|
|
||||||
"root": Object {
|
|
||||||
"paddingLeft": 0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<StyledSpinnerBase
|
|
||||||
size={3}
|
|
||||||
styles={
|
|
||||||
Object {
|
|
||||||
"root": Object {
|
|
||||||
"height": "100%",
|
|
||||||
"justifyContent": "center",
|
|
||||||
"textAlign": "center",
|
|
||||||
"width": "100%",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Stack>
|
|
||||||
</div>
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`SelfServeComponent message bar and spinner snapshots 4`] = `
|
exports[`SelfServeComponent message bar and spinner snapshots 4`] = `
|
||||||
@ -692,195 +27,7 @@ exports[`SelfServeComponent message bar and spinner snapshots 4`] = `
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`SelfServeComponent should render and honor save, discard, refresh actions 1`] = `
|
exports[`SelfServeComponent should render and honor save, discard, refresh actions 1`] = `
|
||||||
<div
|
<Translation>
|
||||||
style={
|
<Component />
|
||||||
Object {
|
</Translation>
|
||||||
"overflowX": "auto",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Stack
|
|
||||||
styles={
|
|
||||||
Object {
|
|
||||||
"root": Object {
|
|
||||||
"padding": 10,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tokens={
|
|
||||||
Object {
|
|
||||||
"childrenGap": 5,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<StyledCommandBarBase
|
|
||||||
items={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"disabled": true,
|
|
||||||
"iconProps": Object {
|
|
||||||
"iconName": "Save",
|
|
||||||
},
|
|
||||||
"key": "save",
|
|
||||||
"onClick": [Function],
|
|
||||||
"split": true,
|
|
||||||
"text": "Save",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"disabled": true,
|
|
||||||
"iconProps": Object {
|
|
||||||
"iconName": "Undo",
|
|
||||||
},
|
|
||||||
"key": "discard",
|
|
||||||
"onClick": [Function],
|
|
||||||
"split": true,
|
|
||||||
"text": "Discard",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"disabled": false,
|
|
||||||
"iconProps": Object {
|
|
||||||
"iconName": "Refresh",
|
|
||||||
},
|
|
||||||
"key": "refresh",
|
|
||||||
"onClick": [Function],
|
|
||||||
"split": true,
|
|
||||||
"text": "Refresh",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
styles={
|
|
||||||
Object {
|
|
||||||
"root": Object {
|
|
||||||
"paddingLeft": 0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<SmartUiComponent
|
|
||||||
currentValues={
|
|
||||||
Map {
|
|
||||||
"throughput" => Object {
|
|
||||||
"value": 450,
|
|
||||||
},
|
|
||||||
"analyticalStore" => Object {
|
|
||||||
"value": false,
|
|
||||||
},
|
|
||||||
"database" => Object {
|
|
||||||
"value": "db2",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
descriptor={
|
|
||||||
Object {
|
|
||||||
"initialize": [MockFunction] {
|
|
||||||
"calls": Array [
|
|
||||||
Array [],
|
|
||||||
],
|
|
||||||
"results": Array [
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
"inputNames": Array [
|
|
||||||
"throughput",
|
|
||||||
"analyticalStore",
|
|
||||||
"database",
|
|
||||||
],
|
|
||||||
"onRefresh": [MockFunction] {
|
|
||||||
"calls": Array [
|
|
||||||
Array [],
|
|
||||||
],
|
|
||||||
"results": Array [
|
|
||||||
Object {
|
|
||||||
"type": "return",
|
|
||||||
"value": Promise {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
"onSave": [MockFunction],
|
|
||||||
"root": Object {
|
|
||||||
"children": Array [
|
|
||||||
Object {
|
|
||||||
"id": "throughput",
|
|
||||||
"info": undefined,
|
|
||||||
"input": Object {
|
|
||||||
"dataFieldName": "throughput",
|
|
||||||
"defaultValue": 400,
|
|
||||||
"label": "Throughput (input)",
|
|
||||||
"max": 500,
|
|
||||||
"min": 400,
|
|
||||||
"placeholder": undefined,
|
|
||||||
"step": 10,
|
|
||||||
"type": "number",
|
|
||||||
"uiType": "Spinner",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"id": "containerId",
|
|
||||||
"info": undefined,
|
|
||||||
"input": Object {
|
|
||||||
"dataFieldName": "containerId",
|
|
||||||
"label": "Container id",
|
|
||||||
"placeholder": undefined,
|
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"id": "analyticalStore",
|
|
||||||
"info": undefined,
|
|
||||||
"input": Object {
|
|
||||||
"dataFieldName": "analyticalStore",
|
|
||||||
"defaultValue": true,
|
|
||||||
"falseLabel": "Disabled",
|
|
||||||
"label": "Analytical Store",
|
|
||||||
"placeholder": undefined,
|
|
||||||
"trueLabel": "Enabled",
|
|
||||||
"type": "boolean",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"id": "database",
|
|
||||||
"info": undefined,
|
|
||||||
"input": Object {
|
|
||||||
"choices": Array [
|
|
||||||
Object {
|
|
||||||
"key": "db1",
|
|
||||||
"label": "Database 1",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"key": "db2",
|
|
||||||
"label": "Database 2",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"key": "db3",
|
|
||||||
"label": "Database 3",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"dataFieldName": "database",
|
|
||||||
"defaultKey": "db2",
|
|
||||||
"label": "Database",
|
|
||||||
"placeholder": undefined,
|
|
||||||
"type": "object",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"id": "root",
|
|
||||||
"info": Object {
|
|
||||||
"link": Object {
|
|
||||||
"href": "https://aka.ms/azure-cosmos-db-pricing",
|
|
||||||
"text": "More Details",
|
|
||||||
},
|
|
||||||
"message": "Start at $24/mo per database",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
disabled={false}
|
|
||||||
onError={[Function]}
|
|
||||||
onInputChange={[Function]}
|
|
||||||
/>
|
|
||||||
</Stack>
|
|
||||||
</div>
|
|
||||||
`;
|
`;
|
||||||
|
31
src/i18n.ts
Normal file
31
src/i18n.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import i18n from "i18next";
|
||||||
|
import LanguageDetector from "i18next-browser-languagedetector";
|
||||||
|
import { initReactI18next } from "react-i18next";
|
||||||
|
import XHR from "i18next-http-backend";
|
||||||
|
import EnglishTranslations from "./Localization/en/translations.json";
|
||||||
|
|
||||||
|
i18n
|
||||||
|
.use(XHR)
|
||||||
|
.use(LanguageDetector)
|
||||||
|
.use(initReactI18next)
|
||||||
|
.init({
|
||||||
|
resources: {
|
||||||
|
en: EnglishTranslations,
|
||||||
|
},
|
||||||
|
fallbackLng: "en",
|
||||||
|
detection: { order: ["navigator", "cookie", "localStorage", "sessionStorage", "querystring", "htmlTag"] },
|
||||||
|
debug: process.env.NODE_ENV === "development",
|
||||||
|
ns: ["translations"],
|
||||||
|
defaultNS: "translations",
|
||||||
|
keySeparator: ".",
|
||||||
|
interpolation: {
|
||||||
|
formatSeparator: ",",
|
||||||
|
},
|
||||||
|
react: {
|
||||||
|
wait: true,
|
||||||
|
bindI18n: "languageChanged loaded",
|
||||||
|
bindI18nStore: "added removed",
|
||||||
|
nsMode: "default",
|
||||||
|
useSuspense: false,
|
||||||
|
},
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user