mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-07-15 00:14:53 +01:00
initial commit for right panel
This commit is contained in:
parent
6d46e48490
commit
09cb9c80bd
@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
Dropdown,
|
DocumentCard,
|
||||||
IDropdownOption,
|
DocumentCardDetails,
|
||||||
|
Dropdown, IDropdownOption,
|
||||||
IStackTokens,
|
IStackTokens,
|
||||||
Label,
|
Label,
|
||||||
Link,
|
Link,
|
||||||
@ -12,19 +13,19 @@ import {
|
|||||||
Stack,
|
Stack,
|
||||||
Text,
|
Text,
|
||||||
TextField,
|
TextField,
|
||||||
Toggle,
|
Toggle
|
||||||
} from "@fluentui/react";
|
} from "@fluentui/react";
|
||||||
import { TFunction } from "i18next";
|
import { TFunction } from "i18next";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {
|
import {
|
||||||
ChoiceItem,
|
ChoiceItem,
|
||||||
Description,
|
Description,
|
||||||
DescriptionType,
|
DescriptionType, Info,
|
||||||
Info,
|
|
||||||
InputType,
|
InputType,
|
||||||
InputTypeValue,
|
InputTypeValue,
|
||||||
NumberUiType,
|
NumberUiType,
|
||||||
SmartUiInput,
|
SmartUiInput,
|
||||||
|
Style
|
||||||
} from "../../../SelfServe/SelfServeTypes";
|
} from "../../../SelfServe/SelfServeTypes";
|
||||||
import { ToolTipLabelComponent } from "../Settings/SettingsSubComponents/ToolTipLabelComponent";
|
import { ToolTipLabelComponent } from "../Settings/SettingsSubComponents/ToolTipLabelComponent";
|
||||||
import * as InputUtils from "./InputUtils";
|
import * as InputUtils from "./InputUtils";
|
||||||
@ -87,6 +88,7 @@ interface Node {
|
|||||||
info?: Info;
|
info?: Info;
|
||||||
input?: AnyDisplay;
|
input?: AnyDisplay;
|
||||||
children?: Node[];
|
children?: Node[];
|
||||||
|
style?: Style
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SmartUiDescriptor {
|
export interface SmartUiDescriptor {
|
||||||
@ -194,6 +196,14 @@ export class SmartUiComponent extends React.Component<SmartUiComponentProps, Sma
|
|||||||
|
|
||||||
if (description.type === DescriptionType.Text) {
|
if (description.type === DescriptionType.Text) {
|
||||||
return descriptionElement;
|
return descriptionElement;
|
||||||
|
} else if (description.type === DescriptionType.Card) {
|
||||||
|
return (
|
||||||
|
<DocumentCard styles={{ root: { display: "inline-block", padding: 10 } }}>
|
||||||
|
<DocumentCardDetails>
|
||||||
|
{descriptionElement}
|
||||||
|
</DocumentCardDetails>
|
||||||
|
</DocumentCard>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
const messageBarType =
|
const messageBarType =
|
||||||
description.type === DescriptionType.InfoMessageBar ? MessageBarType.info : MessageBarType.warning;
|
description.type === DescriptionType.InfoMessageBar ? MessageBarType.info : MessageBarType.warning;
|
||||||
@ -396,18 +406,29 @@ export class SmartUiComponent extends React.Component<SmartUiComponentProps, Sma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderNode(node: Node): JSX.Element {
|
private renderNode(node: Node, isSectionFloatRight: boolean): JSX.Element {
|
||||||
const containerStackTokens: IStackTokens = { childrenGap: 10 };
|
const containerStackTokens: IStackTokens = { childrenGap: 10 };
|
||||||
|
const isNodeFloatRight = node.style?.isFloatRight === true;
|
||||||
|
console.log(isSectionFloatRight, isNodeFloatRight, node.id)
|
||||||
return (
|
return (
|
||||||
<Stack tokens={containerStackTokens} className="widgetRendererContainer">
|
<Stack tokens={containerStackTokens} className="widgetRendererContainer">
|
||||||
|
{isSectionFloatRight === isNodeFloatRight ?
|
||||||
|
<>
|
||||||
<Stack.Item>{node.input && this.renderElement(node.input, node.info as Info)}</Stack.Item>
|
<Stack.Item>{node.input && this.renderElement(node.input, node.info as Info)}</Stack.Item>
|
||||||
{node.children && node.children.map((child) => <div key={child.id}>{this.renderNode(child)}</div>)}
|
</>
|
||||||
|
: <></>
|
||||||
|
}
|
||||||
|
{node.children && node.children.map((child) => <div key={child.id}>{this.renderNode(child, isSectionFloatRight)}</div>)}
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
return this.renderNode(this.props.descriptor.root);
|
return (
|
||||||
|
<Stack horizontal tokens={{ childrenGap: 50 }}>
|
||||||
|
{this.renderNode(this.props.descriptor.root, false)}
|
||||||
|
{this.renderNode(this.props.descriptor.root, true)}
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @module SelfServe/Decorators
|
* @module SelfServe/Decorators
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ChoiceItem, Description, Info, NumberUiType, OnChangeCallback, RefreshParams } from "./SelfServeTypes";
|
import { ChoiceItem, Description, Info, NumberUiType, OnChangeCallback, RefreshParams, Style } from "./SelfServeTypes";
|
||||||
import { addPropertyToMap, buildSmartUiDescriptor, DecoratorProperties } from "./SelfServeUtils";
|
import { addPropertyToMap, buildSmartUiDescriptor, DecoratorProperties } from "./SelfServeUtils";
|
||||||
|
|
||||||
type ValueOf<T> = T[keyof T];
|
type ValueOf<T> = T[keyof T];
|
||||||
@ -162,6 +162,14 @@ export const PropertyInfo = (info: (() => Promise<Info>) | Info): PropertyDecora
|
|||||||
return addToMap({ name: "info", value: info });
|
return addToMap({ name: "info", value: info });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the UI element corresponding to the property should have an Info bubble. The Info
|
||||||
|
* bubble is the icon that looks like an "i" which users click on to get more information about the UI element.
|
||||||
|
*/
|
||||||
|
export const Styles = (style: (() => Promise<Style>) | Style): PropertyDecorator => {
|
||||||
|
return addToMap({ name: "style", value: style });
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that this property should correspond to a UI element with the given parameters.
|
* Indicates that this property should correspond to a UI element with the given parameters.
|
||||||
*/
|
*/
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { IsDisplayable, OnChange, PropertyInfo, RefreshOptions, Values } from "../Decorators";
|
import { IsDisplayable, OnChange, PropertyInfo, RefreshOptions, Styles, Values } from "../Decorators";
|
||||||
import { selfServeTraceStart, selfServeTraceSuccess } from "../SelfServeTelemetryProcessor";
|
import { selfServeTraceStart, selfServeTraceSuccess } from "../SelfServeTelemetryProcessor";
|
||||||
import {
|
import {
|
||||||
ChoiceItem,
|
ChoiceItem,
|
||||||
@ -10,7 +10,7 @@ import {
|
|||||||
OnSaveResult,
|
OnSaveResult,
|
||||||
RefreshResult,
|
RefreshResult,
|
||||||
SelfServeBaseClass,
|
SelfServeBaseClass,
|
||||||
SmartUiInput,
|
SmartUiInput
|
||||||
} from "../SelfServeTypes";
|
} from "../SelfServeTypes";
|
||||||
import {
|
import {
|
||||||
getMaxCollectionThroughput,
|
getMaxCollectionThroughput,
|
||||||
@ -19,7 +19,7 @@ import {
|
|||||||
getMinDatabaseThroughput,
|
getMinDatabaseThroughput,
|
||||||
initialize,
|
initialize,
|
||||||
onRefreshSelfServeExample,
|
onRefreshSelfServeExample,
|
||||||
update,
|
update
|
||||||
} from "./SelfServeExample.rp";
|
} from "./SelfServeExample.rp";
|
||||||
import { AccountProps, Regions } from "./SelfServeExample.types";
|
import { AccountProps, Regions } from "./SelfServeExample.types";
|
||||||
|
|
||||||
@ -203,6 +203,20 @@ export default class SelfServeExample extends SelfServeBaseClass {
|
|||||||
})
|
})
|
||||||
enableLogging: boolean;
|
enableLogging: boolean;
|
||||||
|
|
||||||
|
@Styles({ isFloatRight: true })
|
||||||
|
@Values({
|
||||||
|
labelTKey: "DescriptionLabel",
|
||||||
|
description: {
|
||||||
|
textTKey: "DescriptionText",
|
||||||
|
type: DescriptionType.Card,
|
||||||
|
link: {
|
||||||
|
href: "https://aka.ms/cosmos-create-account-portal",
|
||||||
|
textTKey: "DecriptionLinkText",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
rightDescription: string;
|
||||||
|
|
||||||
@Values({
|
@Values({
|
||||||
labelTKey: "Account Name",
|
labelTKey: "Account Name",
|
||||||
placeholderTKey: "AccountNamePlaceHolder",
|
placeholderTKey: "AccountNamePlaceHolder",
|
||||||
|
@ -7,7 +7,7 @@ import {
|
|||||||
Spinner,
|
Spinner,
|
||||||
SpinnerSize,
|
SpinnerSize,
|
||||||
Stack,
|
Stack,
|
||||||
Text,
|
Text
|
||||||
} from "@fluentui/react";
|
} from "@fluentui/react";
|
||||||
import { TFunction } from "i18next";
|
import { TFunction } from "i18next";
|
||||||
import promiseRetry, { AbortError } from "p-retry";
|
import promiseRetry, { AbortError } from "p-retry";
|
||||||
@ -32,7 +32,7 @@ import {
|
|||||||
SelfServeComponentTelemetryType,
|
SelfServeComponentTelemetryType,
|
||||||
SelfServeDescriptor,
|
SelfServeDescriptor,
|
||||||
SmartUiInput,
|
SmartUiInput,
|
||||||
StringInput,
|
StringInput
|
||||||
} from "./SelfServeTypes";
|
} from "./SelfServeTypes";
|
||||||
|
|
||||||
interface SelfServeNotification {
|
interface SelfServeNotification {
|
||||||
@ -186,6 +186,7 @@ export class SelfServeComponent extends React.Component<SelfServeComponentProps,
|
|||||||
baselineValues: Map<string, SmartUiInput>
|
baselineValues: Map<string, SmartUiInput>
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
currentNode.info = await this.getResolvedValue(currentNode.info);
|
currentNode.info = await this.getResolvedValue(currentNode.info);
|
||||||
|
currentNode.style = await this.getResolvedValue(currentNode.style);
|
||||||
|
|
||||||
if (currentNode.input) {
|
if (currentNode.input) {
|
||||||
currentNode.input = await this.getResolvedInput(currentNode.input, currentValues, baselineValues);
|
currentNode.input = await this.getResolvedInput(currentNode.input, currentValues, baselineValues);
|
||||||
|
@ -55,6 +55,7 @@ export interface Node {
|
|||||||
info?: (() => Promise<Info>) | Info;
|
info?: (() => Promise<Info>) | Info;
|
||||||
input?: AnyDisplay;
|
input?: AnyDisplay;
|
||||||
children?: Node[];
|
children?: Node[];
|
||||||
|
style?: (() => Promise<Style>) | Style;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**@internal */
|
/**@internal */
|
||||||
@ -82,6 +83,13 @@ export type AnyDisplay = NumberInput | BooleanInput | StringInput | ChoiceInput
|
|||||||
/**@internal */
|
/**@internal */
|
||||||
export type InputTypeValue = "number" | "string" | "boolean" | "object";
|
export type InputTypeValue = "number" | "string" | "boolean" | "object";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the styling of the UI element.
|
||||||
|
*/
|
||||||
|
export interface Style {
|
||||||
|
isFloatRight: boolean
|
||||||
|
}
|
||||||
|
|
||||||
export type initializeCallback =
|
export type initializeCallback =
|
||||||
/**
|
/**
|
||||||
* @returns Promise of Map of propertyName => {@linkcode SmartUiInput} which will become the current state of the UI.
|
* @returns Promise of Map of propertyName => {@linkcode SmartUiInput} which will become the current state of the UI.
|
||||||
@ -228,6 +236,7 @@ export enum DescriptionType {
|
|||||||
* Show the description as a Warning Message bar.
|
* Show the description as a Warning Message bar.
|
||||||
*/
|
*/
|
||||||
WarningMessageBar,
|
WarningMessageBar,
|
||||||
|
Card
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,6 +20,7 @@ import {
|
|||||||
SelfServeDescriptor,
|
SelfServeDescriptor,
|
||||||
SmartUiInput,
|
SmartUiInput,
|
||||||
StringInput,
|
StringInput,
|
||||||
|
Style
|
||||||
} from "./SelfServeTypes";
|
} from "./SelfServeTypes";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,6 +93,7 @@ export interface DecoratorProperties {
|
|||||||
description?: (() => Promise<Description>) | Description;
|
description?: (() => Promise<Description>) | Description;
|
||||||
isDynamicDescription?: boolean;
|
isDynamicDescription?: boolean;
|
||||||
refreshParams?: RefreshParams;
|
refreshParams?: RefreshParams;
|
||||||
|
style?: (() => Promise<Style>) | Style;
|
||||||
onChange?: (
|
onChange?: (
|
||||||
newValue: InputType,
|
newValue: InputType,
|
||||||
currentState: Map<string, SmartUiInput>,
|
currentState: Map<string, SmartUiInput>,
|
||||||
@ -197,6 +199,7 @@ const addToDescriptor = (
|
|||||||
info: value.info,
|
info: value.info,
|
||||||
input: getInput(value),
|
input: getInput(value),
|
||||||
children: [],
|
children: [],
|
||||||
|
style: value.style
|
||||||
} as Node;
|
} as Node;
|
||||||
context.delete(key);
|
context.delete(key);
|
||||||
root.children.push(element);
|
root.children.push(element);
|
||||||
|
@ -1,28 +1,27 @@
|
|||||||
import { IsDisplayable, OnChange, PropertyInfo, RefreshOptions, Values } from "../Decorators";
|
import { IsDisplayable, OnChange, PropertyInfo, RefreshOptions, Styles, Values } from "../Decorators";
|
||||||
import { selfServeTrace } from "../SelfServeTelemetryProcessor";
|
import { selfServeTrace } from "../SelfServeTelemetryProcessor";
|
||||||
import {
|
import {
|
||||||
ChoiceItem,
|
ChoiceItem,
|
||||||
Description,
|
Description,
|
||||||
DescriptionType,
|
DescriptionType, Info,
|
||||||
Info,
|
|
||||||
InputType,
|
InputType,
|
||||||
NumberUiType,
|
NumberUiType,
|
||||||
OnSaveResult,
|
OnSaveResult,
|
||||||
RefreshResult,
|
RefreshResult,
|
||||||
SelfServeBaseClass,
|
SelfServeBaseClass,
|
||||||
SmartUiInput,
|
SmartUiInput
|
||||||
} from "../SelfServeTypes";
|
} from "../SelfServeTypes";
|
||||||
import { BladeType, generateBladeLink } from "../SelfServeUtils";
|
import { BladeType, generateBladeLink } from "../SelfServeUtils";
|
||||||
import {
|
import {
|
||||||
deleteDedicatedGatewayResource,
|
deleteDedicatedGatewayResource,
|
||||||
getCurrentProvisioningState,
|
getCurrentProvisioningState,
|
||||||
refreshDedicatedGatewayProvisioning,
|
refreshDedicatedGatewayProvisioning,
|
||||||
updateDedicatedGatewayResource,
|
updateDedicatedGatewayResource
|
||||||
} from "./SqlX.rp";
|
} from "./SqlX.rp";
|
||||||
|
|
||||||
const costPerHourValue: Description = {
|
const costPerHourValue: Description = {
|
||||||
textTKey: "CostText",
|
textTKey: "CostText",
|
||||||
type: DescriptionType.Text,
|
type: DescriptionType.Card,
|
||||||
link: {
|
link: {
|
||||||
href: "https://aka.ms/cosmos-db-dedicated-gateway-pricing",
|
href: "https://aka.ms/cosmos-db-dedicated-gateway-pricing",
|
||||||
textTKey: "DedicatedGatewayPricing",
|
textTKey: "DedicatedGatewayPricing",
|
||||||
@ -338,6 +337,7 @@ export default class SqlX extends SelfServeBaseClass {
|
|||||||
})
|
})
|
||||||
instances: number;
|
instances: number;
|
||||||
|
|
||||||
|
@Styles({ isFloatRight: true })
|
||||||
@Values({
|
@Values({
|
||||||
labelTKey: "Cost",
|
labelTKey: "Cost",
|
||||||
isDynamicDescription: true,
|
isDynamicDescription: true,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user