Add data explorer launcher (#23)
* Initial migration from ADO * Bug fixes * Fix bugs. Make active area smaller and require shift + ctrl + dbl click * Add missing features * Switch from HashMap to Map as it is already polyfilled
This commit is contained in:
parent
f8f1df4183
commit
d70e30c4fc
|
@ -0,0 +1,20 @@
|
||||||
|
.featurePanelComponentContainer {
|
||||||
|
width: 800px;
|
||||||
|
|
||||||
|
.urlContainer {
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options {
|
||||||
|
padding: 10px;
|
||||||
|
overflow: auto;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkboxRow {
|
||||||
|
width: 390px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
import React from "react";
|
||||||
|
import { shallow, mount } from "enzyme";
|
||||||
|
|
||||||
|
import { FeaturePanelComponent } from "./FeaturePanelComponent";
|
||||||
|
|
||||||
|
describe("Feature panel", () => {
|
||||||
|
it("renders all flags", () => {
|
||||||
|
const wrapper = shallow(<FeaturePanelComponent />);
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,252 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import { Stack } from "office-ui-fabric-react/lib/Stack";
|
||||||
|
import { Dropdown, IDropdownOption, IDropdownStyles } from "office-ui-fabric-react/lib/Dropdown";
|
||||||
|
import { Checkbox } from "office-ui-fabric-react/lib/Checkbox";
|
||||||
|
import { TextField, ITextFieldStyles } from "office-ui-fabric-react/lib/TextField";
|
||||||
|
import { DefaultButton } from "office-ui-fabric-react";
|
||||||
|
import "./FeaturePanelComponent.less";
|
||||||
|
|
||||||
|
export const FeaturePanelComponent: React.FunctionComponent = () => {
|
||||||
|
// Initial conditions
|
||||||
|
const originalParams = new URLSearchParams(window.location.search);
|
||||||
|
const urlParams = new Map(); // Params with lowercase keys
|
||||||
|
originalParams.forEach((value: string, key: string) => urlParams.set(key.toLocaleLowerCase(), value));
|
||||||
|
|
||||||
|
const baseUrlOptions = [
|
||||||
|
{ key: "https://localhost:1234/explorer.html", text: "localhost:1234" },
|
||||||
|
{ key: "https://cosmos.azure.com/explorer.html", text: "cosmos.azure.com" },
|
||||||
|
{ key: "https://portal.azure.com", text: "portal" }
|
||||||
|
];
|
||||||
|
|
||||||
|
const platformOptions = [
|
||||||
|
{ key: "Hosted", text: "Hosted" },
|
||||||
|
{ key: "Portal", text: "Portal" },
|
||||||
|
{ key: "Emulator", text: "Emulator" },
|
||||||
|
{ key: "", text: "None" }
|
||||||
|
];
|
||||||
|
|
||||||
|
// React hooks to keep state
|
||||||
|
const [baseUrl, setBaseUrl] = React.useState<IDropdownOption>(
|
||||||
|
baseUrlOptions.find(o => o.key === window.location.origin + window.location.pathname) || baseUrlOptions[0]
|
||||||
|
);
|
||||||
|
const [platform, setPlatform] = React.useState<IDropdownOption>(
|
||||||
|
urlParams.has("platform")
|
||||||
|
? platformOptions.find(o => o.key === urlParams.get("platform")) || platformOptions[0]
|
||||||
|
: platformOptions[0]
|
||||||
|
);
|
||||||
|
|
||||||
|
const booleanFeatures: {
|
||||||
|
key: string;
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
disabled?: () => boolean;
|
||||||
|
reactState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];
|
||||||
|
onChange?: (_?: React.FormEvent<HTMLElement | HTMLInputElement>, checked?: boolean) => void;
|
||||||
|
}[] = [
|
||||||
|
{ key: "feature.enablechangefeedpolicy", label: "Enable change feed policy", value: "true" },
|
||||||
|
{ key: "feature.enablerupm", label: "Enable RUPM", value: "true" },
|
||||||
|
{ key: "feature.dataexplorerexecutesproc", label: "Execute stored procedure", value: "true" },
|
||||||
|
{ key: "feature.hosteddataexplorerenabled", label: "Hosted Data Explorer (deprecated?)", value: "true" },
|
||||||
|
{ key: "feature.enablettl", label: "Enable TTL", value: "true" },
|
||||||
|
{ key: "feature.enablegallery", label: "Enable Notebook Gallery", value: "true" },
|
||||||
|
{ key: "feature.canexceedmaximumvalue", label: "Can exceed max value", value: "true" },
|
||||||
|
{
|
||||||
|
key: "feature.enablefixedcollectionwithsharedthroughput",
|
||||||
|
label: "Enable fixed collection with shared throughput",
|
||||||
|
value: "true"
|
||||||
|
},
|
||||||
|
{ key: "feature.ttl90days", label: "TTL 90 days", value: "true" },
|
||||||
|
{ key: "feature.enablenotebooks", label: "Enable notebooks", value: "true" },
|
||||||
|
{
|
||||||
|
key: "feature.customportal",
|
||||||
|
label: "Force Production portal (portal only)",
|
||||||
|
value: "false",
|
||||||
|
disabled: (): boolean => baseUrl.key !== "https://portal.azure.com"
|
||||||
|
},
|
||||||
|
{ key: "feature.enablespark", label: "Enable Synapse", value: "true" },
|
||||||
|
{ key: "feature.enableautopilotv2", label: "Enable Auto-pilot V2", value: "true" }
|
||||||
|
];
|
||||||
|
|
||||||
|
const stringFeatures: {
|
||||||
|
key: string;
|
||||||
|
label: string;
|
||||||
|
placeholder: string;
|
||||||
|
disabled?: () => boolean;
|
||||||
|
reactState?: [string, React.Dispatch<React.SetStateAction<string>>];
|
||||||
|
onChange?: (_: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string) => void;
|
||||||
|
}[] = [
|
||||||
|
{ key: "feature.notebookserverurl", label: "Notebook server URL", placeholder: "https://notebookserver" },
|
||||||
|
{ key: "feature.notebookservertoken", label: "Notebook server token", placeholder: "" },
|
||||||
|
{ key: "feature.notebookbasepath", label: "Notebook base path", placeholder: "" },
|
||||||
|
{ key: "key", label: "Auth key", placeholder: "" },
|
||||||
|
{
|
||||||
|
key: "dataExplorerSource",
|
||||||
|
label: "Data Explorer Source (portal only)",
|
||||||
|
placeholder: "https://localhost:1234/explorer.html",
|
||||||
|
disabled: (): boolean => baseUrl.key !== "https://portal.azure.com"
|
||||||
|
},
|
||||||
|
{ key: "feature.livyendpoint", label: "Livy endpoint", placeholder: "" }
|
||||||
|
];
|
||||||
|
|
||||||
|
booleanFeatures.forEach(
|
||||||
|
f => (f.reactState = React.useState<boolean>(urlParams.has(f.key) ? urlParams.get(f.key) === "true" : false))
|
||||||
|
);
|
||||||
|
stringFeatures.forEach(
|
||||||
|
f => (f.reactState = React.useState<string>(urlParams.has(f.key) ? urlParams.get(f.key) : undefined))
|
||||||
|
);
|
||||||
|
|
||||||
|
const buildUrl = (): string => {
|
||||||
|
const fragments = (platform.key === "" ? [] : [`platform=${platform.key}`])
|
||||||
|
.concat(booleanFeatures.map(f => (f.reactState[0] ? `${f.key}=${f.value}` : "")))
|
||||||
|
.concat(stringFeatures.map(f => (f.reactState[0] ? `${f.key}=${encodeURIComponent(f.reactState[0])}` : "")))
|
||||||
|
.filter(v => v && v.length > 0);
|
||||||
|
|
||||||
|
const paramString = fragments.length < 1 ? "" : `?${fragments.join("&")}`;
|
||||||
|
return `${baseUrl.key}${paramString}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onChangeBaseUrl = (event: React.FormEvent<HTMLDivElement>, option?: IDropdownOption): void => {
|
||||||
|
setBaseUrl(option);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onChangePlatform = (event: React.FormEvent<HTMLDivElement>, option?: IDropdownOption): void => {
|
||||||
|
setPlatform(option);
|
||||||
|
};
|
||||||
|
|
||||||
|
booleanFeatures.forEach(
|
||||||
|
f =>
|
||||||
|
(f.onChange = (ev?: React.FormEvent<HTMLElement | HTMLInputElement>, checked?: boolean): void => {
|
||||||
|
f.reactState[1](checked);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
stringFeatures.forEach(
|
||||||
|
f =>
|
||||||
|
(f.onChange = (event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string): void => {
|
||||||
|
f.reactState[1](newValue);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const onNotebookShortcut = (): void => {
|
||||||
|
booleanFeatures.find(f => f.key === "feature.enablenotebooks").reactState[1](true);
|
||||||
|
stringFeatures
|
||||||
|
.find(f => f.key === "feature.notebookserverurl")
|
||||||
|
.reactState[1]("https://localhost:10001/12345/notebook/");
|
||||||
|
stringFeatures.find(f => f.key === "feature.notebookservertoken").reactState[1]("token");
|
||||||
|
stringFeatures.find(f => f.key === "feature.notebookbasepath").reactState[1](".");
|
||||||
|
setPlatform(platformOptions.find(o => o.key === "Hosted"));
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPortalLocalDEShortcut = (): void => {
|
||||||
|
setBaseUrl(baseUrlOptions.find(o => o.key === "https://portal.azure.com"));
|
||||||
|
setPlatform(platformOptions.find(o => o.key === "Portal"));
|
||||||
|
stringFeatures.find(f => f.key === "dataExplorerSource").reactState[1]("https://localhost:1234/explorer.html");
|
||||||
|
};
|
||||||
|
|
||||||
|
const onReset = (): void => {
|
||||||
|
booleanFeatures.forEach(f => f.reactState[1](false));
|
||||||
|
stringFeatures.forEach(f => f.reactState[1](""));
|
||||||
|
};
|
||||||
|
|
||||||
|
const stackTokens = { childrenGap: 10 };
|
||||||
|
const dropdownStyles: Partial<IDropdownStyles> = { dropdown: { width: 200 } };
|
||||||
|
const textFieldStyles: Partial<ITextFieldStyles> = { fieldGroup: { width: 300 } };
|
||||||
|
|
||||||
|
// Show in 2 columns to keep it compact
|
||||||
|
let halfSize = Math.ceil(booleanFeatures.length / 2);
|
||||||
|
const leftBooleanFeatures = booleanFeatures.slice(0, halfSize);
|
||||||
|
const rightBooleanFeatures = booleanFeatures.slice(halfSize, booleanFeatures.length);
|
||||||
|
|
||||||
|
halfSize = Math.ceil(stringFeatures.length / 2);
|
||||||
|
const leftStringFeatures = stringFeatures.slice(0, halfSize);
|
||||||
|
const rightStringFeatures = stringFeatures.slice(halfSize, stringFeatures.length);
|
||||||
|
|
||||||
|
const anchorOptions = {
|
||||||
|
href: buildUrl(),
|
||||||
|
target: "_blank",
|
||||||
|
rel: "noopener"
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="featurePanelComponentContainer">
|
||||||
|
<div className="urlContainer">
|
||||||
|
<a {...anchorOptions}>{buildUrl()}</a>
|
||||||
|
</div>
|
||||||
|
<Stack className="options" tokens={stackTokens}>
|
||||||
|
<Stack horizontal horizontalAlign="space-between" tokens={stackTokens}>
|
||||||
|
<DefaultButton onClick={onNotebookShortcut}>Notebooks on localhost</DefaultButton>
|
||||||
|
<DefaultButton onClick={onPortalLocalDEShortcut}>Portal points to local DE</DefaultButton>
|
||||||
|
<DefaultButton onClick={onReset}>Reset</DefaultButton>
|
||||||
|
</Stack>
|
||||||
|
<Stack horizontal horizontalAlign="start" tokens={stackTokens}>
|
||||||
|
<Dropdown
|
||||||
|
selectedKey={baseUrl.key}
|
||||||
|
options={baseUrlOptions}
|
||||||
|
onChange={onChangeBaseUrl}
|
||||||
|
label="Base Url"
|
||||||
|
styles={dropdownStyles}
|
||||||
|
/>
|
||||||
|
<Dropdown
|
||||||
|
label="Platform"
|
||||||
|
selectedKey={platform.key}
|
||||||
|
onChange={onChangePlatform}
|
||||||
|
options={platformOptions}
|
||||||
|
styles={dropdownStyles}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
<Stack horizontal>
|
||||||
|
<Stack className="checkboxRow" horizontalAlign="space-between">
|
||||||
|
{leftBooleanFeatures.map(f => (
|
||||||
|
<Checkbox
|
||||||
|
key={f.key}
|
||||||
|
label={f.label}
|
||||||
|
checked={f.reactState[0]}
|
||||||
|
onChange={f.onChange}
|
||||||
|
disabled={f.disabled && f.disabled()}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
<Stack className="checkboxRow" horizontalAlign="space-between">
|
||||||
|
{rightBooleanFeatures.map(f => (
|
||||||
|
<Checkbox
|
||||||
|
key={f.key}
|
||||||
|
label={f.label}
|
||||||
|
checked={f.reactState[0]}
|
||||||
|
onChange={f.onChange}
|
||||||
|
disabled={f.disabled && f.disabled()}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
<Stack horizontal tokens={stackTokens}>
|
||||||
|
<Stack horizontalAlign="space-between">
|
||||||
|
{leftStringFeatures.map(f => (
|
||||||
|
<TextField
|
||||||
|
key={f.key}
|
||||||
|
value={f.reactState[0]}
|
||||||
|
label={f.label}
|
||||||
|
onChange={f.onChange}
|
||||||
|
styles={textFieldStyles}
|
||||||
|
placeholder={f.placeholder}
|
||||||
|
disabled={f.disabled && f.disabled()}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
<Stack horizontalAlign="space-between">
|
||||||
|
{rightStringFeatures.map(f => (
|
||||||
|
<TextField
|
||||||
|
key={f.key}
|
||||||
|
value={f.reactState[0]}
|
||||||
|
label={f.label}
|
||||||
|
onChange={f.onChange}
|
||||||
|
styles={textFieldStyles}
|
||||||
|
placeholder={f.placeholder}
|
||||||
|
disabled={f.disabled && f.disabled()}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,18 @@
|
||||||
|
.featurePanelLauncherContainer {
|
||||||
|
.featurePanelLauncherModal {
|
||||||
|
overflow-y: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.ms-Dialog-main {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.activePatch {
|
||||||
|
position: absolute;
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
top: 20px;
|
||||||
|
left: -20px;
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import { FeaturePanelComponent } from "./FeaturePanelComponent";
|
||||||
|
import { getTheme, mergeStyleSets, FontWeights, Modal, IconButton, IIconProps } from "office-ui-fabric-react";
|
||||||
|
import "./FeaturePanelLauncher.less";
|
||||||
|
|
||||||
|
// Modal wrapper
|
||||||
|
export const FeaturePanelLauncher: React.FunctionComponent = (): JSX.Element => {
|
||||||
|
const [isModalOpen, showModal] = React.useState<boolean>(false);
|
||||||
|
|
||||||
|
const onActivate = (event: React.MouseEvent<HTMLSpanElement>): void => {
|
||||||
|
if (!event.shiftKey || !event.ctrlKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event.stopPropagation();
|
||||||
|
showModal(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const theme = getTheme();
|
||||||
|
const contentStyles = mergeStyleSets({
|
||||||
|
container: {
|
||||||
|
display: "flex",
|
||||||
|
flexFlow: "column nowrap",
|
||||||
|
alignItems: "stretch"
|
||||||
|
},
|
||||||
|
header: [
|
||||||
|
// tslint:disable-next-line:deprecation
|
||||||
|
theme.fonts.xLargePlus,
|
||||||
|
{
|
||||||
|
flex: "1 1 auto",
|
||||||
|
borderTop: `4px solid ${theme.palette.themePrimary}`,
|
||||||
|
color: theme.palette.neutralPrimary,
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
fontWeight: FontWeights.semibold,
|
||||||
|
padding: "12px 12px 14px 24px"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
body: {
|
||||||
|
flex: "4 4 auto",
|
||||||
|
overflowY: "hidden",
|
||||||
|
marginBottom: 40,
|
||||||
|
height: "100%",
|
||||||
|
display: "flex"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const iconButtonStyles = {
|
||||||
|
root: {
|
||||||
|
color: theme.palette.neutralPrimary,
|
||||||
|
marginLeft: "auto",
|
||||||
|
marginTop: "4px",
|
||||||
|
marginRight: "2px"
|
||||||
|
},
|
||||||
|
rootHovered: {
|
||||||
|
color: theme.palette.neutralDark
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const cancelIcon: IIconProps = { iconName: "Cancel" };
|
||||||
|
const hideModal = (): void => showModal(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span className="activePatch" onDoubleClick={onActivate}>
|
||||||
|
<Modal
|
||||||
|
className="featurePanelLauncherContainer"
|
||||||
|
titleAriaId="Features"
|
||||||
|
isOpen={isModalOpen}
|
||||||
|
onDismiss={hideModal}
|
||||||
|
isBlocking={false}
|
||||||
|
scrollableContentClassName="featurePanelLauncherModal"
|
||||||
|
>
|
||||||
|
<div className={contentStyles.header}>
|
||||||
|
<span>Data Explorer Launcher</span>
|
||||||
|
<IconButton
|
||||||
|
styles={iconButtonStyles}
|
||||||
|
iconProps={cancelIcon}
|
||||||
|
ariaLabel="Close popup modal"
|
||||||
|
onClick={hideModal}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className={contentStyles.body}>
|
||||||
|
<FeaturePanelComponent />
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,312 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Feature panel renders all flags 1`] = `
|
||||||
|
<div
|
||||||
|
className="featurePanelComponentContainer"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="urlContainer"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href="https://localhost:1234/explorer.html?platform=Hosted"
|
||||||
|
rel="noopener"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
https://localhost:1234/explorer.html?platform=Hosted
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<Stack
|
||||||
|
className="options"
|
||||||
|
tokens={
|
||||||
|
Object {
|
||||||
|
"childrenGap": 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Stack
|
||||||
|
horizontal={true}
|
||||||
|
horizontalAlign="space-between"
|
||||||
|
tokens={
|
||||||
|
Object {
|
||||||
|
"childrenGap": 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<CustomizedDefaultButton
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
Notebooks on localhost
|
||||||
|
</CustomizedDefaultButton>
|
||||||
|
<CustomizedDefaultButton
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
Portal points to local DE
|
||||||
|
</CustomizedDefaultButton>
|
||||||
|
<CustomizedDefaultButton
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
Reset
|
||||||
|
</CustomizedDefaultButton>
|
||||||
|
</Stack>
|
||||||
|
<Stack
|
||||||
|
horizontal={true}
|
||||||
|
horizontalAlign="start"
|
||||||
|
tokens={
|
||||||
|
Object {
|
||||||
|
"childrenGap": 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<StyledWithResponsiveMode
|
||||||
|
label="Base Url"
|
||||||
|
onChange={[Function]}
|
||||||
|
options={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"key": "https://localhost:1234/explorer.html",
|
||||||
|
"text": "localhost:1234",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"key": "https://cosmos.azure.com/explorer.html",
|
||||||
|
"text": "cosmos.azure.com",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"key": "https://portal.azure.com",
|
||||||
|
"text": "portal",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
selectedKey="https://localhost:1234/explorer.html"
|
||||||
|
styles={
|
||||||
|
Object {
|
||||||
|
"dropdown": Object {
|
||||||
|
"width": 200,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<StyledWithResponsiveMode
|
||||||
|
label="Platform"
|
||||||
|
onChange={[Function]}
|
||||||
|
options={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"key": "Hosted",
|
||||||
|
"text": "Hosted",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"key": "Portal",
|
||||||
|
"text": "Portal",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"key": "Emulator",
|
||||||
|
"text": "Emulator",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"key": "",
|
||||||
|
"text": "None",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
selectedKey="Hosted"
|
||||||
|
styles={
|
||||||
|
Object {
|
||||||
|
"dropdown": Object {
|
||||||
|
"width": 200,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
<Stack
|
||||||
|
horizontal={true}
|
||||||
|
>
|
||||||
|
<Stack
|
||||||
|
className="checkboxRow"
|
||||||
|
horizontalAlign="space-between"
|
||||||
|
>
|
||||||
|
<StyledCheckboxBase
|
||||||
|
checked={false}
|
||||||
|
key="feature.enablechangefeedpolicy"
|
||||||
|
label="Enable change feed policy"
|
||||||
|
onChange={[Function]}
|
||||||
|
/>
|
||||||
|
<StyledCheckboxBase
|
||||||
|
checked={false}
|
||||||
|
key="feature.enablerupm"
|
||||||
|
label="Enable RUPM"
|
||||||
|
onChange={[Function]}
|
||||||
|
/>
|
||||||
|
<StyledCheckboxBase
|
||||||
|
checked={false}
|
||||||
|
key="feature.dataexplorerexecutesproc"
|
||||||
|
label="Execute stored procedure"
|
||||||
|
onChange={[Function]}
|
||||||
|
/>
|
||||||
|
<StyledCheckboxBase
|
||||||
|
checked={false}
|
||||||
|
key="feature.hosteddataexplorerenabled"
|
||||||
|
label="Hosted Data Explorer (deprecated?)"
|
||||||
|
onChange={[Function]}
|
||||||
|
/>
|
||||||
|
<StyledCheckboxBase
|
||||||
|
checked={false}
|
||||||
|
key="feature.enablettl"
|
||||||
|
label="Enable TTL"
|
||||||
|
onChange={[Function]}
|
||||||
|
/>
|
||||||
|
<StyledCheckboxBase
|
||||||
|
checked={false}
|
||||||
|
key="feature.enablegallery"
|
||||||
|
label="Enable Notebook Gallery"
|
||||||
|
onChange={[Function]}
|
||||||
|
/>
|
||||||
|
<StyledCheckboxBase
|
||||||
|
checked={false}
|
||||||
|
key="feature.canexceedmaximumvalue"
|
||||||
|
label="Can exceed max value"
|
||||||
|
onChange={[Function]}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
<Stack
|
||||||
|
className="checkboxRow"
|
||||||
|
horizontalAlign="space-between"
|
||||||
|
>
|
||||||
|
<StyledCheckboxBase
|
||||||
|
checked={false}
|
||||||
|
key="feature.enablefixedcollectionwithsharedthroughput"
|
||||||
|
label="Enable fixed collection with shared throughput"
|
||||||
|
onChange={[Function]}
|
||||||
|
/>
|
||||||
|
<StyledCheckboxBase
|
||||||
|
checked={false}
|
||||||
|
key="feature.ttl90days"
|
||||||
|
label="TTL 90 days"
|
||||||
|
onChange={[Function]}
|
||||||
|
/>
|
||||||
|
<StyledCheckboxBase
|
||||||
|
checked={false}
|
||||||
|
key="feature.enablenotebooks"
|
||||||
|
label="Enable notebooks"
|
||||||
|
onChange={[Function]}
|
||||||
|
/>
|
||||||
|
<StyledCheckboxBase
|
||||||
|
checked={false}
|
||||||
|
disabled={true}
|
||||||
|
key="feature.customportal"
|
||||||
|
label="Force Production portal (portal only)"
|
||||||
|
onChange={[Function]}
|
||||||
|
/>
|
||||||
|
<StyledCheckboxBase
|
||||||
|
checked={false}
|
||||||
|
key="feature.enablespark"
|
||||||
|
label="Enable Synapse"
|
||||||
|
onChange={[Function]}
|
||||||
|
/>
|
||||||
|
<StyledCheckboxBase
|
||||||
|
checked={false}
|
||||||
|
key="feature.enableautopilotv2"
|
||||||
|
label="Enable Auto-pilot V2"
|
||||||
|
onChange={[Function]}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
<Stack
|
||||||
|
horizontal={true}
|
||||||
|
tokens={
|
||||||
|
Object {
|
||||||
|
"childrenGap": 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Stack
|
||||||
|
horizontalAlign="space-between"
|
||||||
|
>
|
||||||
|
<StyledTextFieldBase
|
||||||
|
key="feature.notebookserverurl"
|
||||||
|
label="Notebook server URL"
|
||||||
|
onChange={[Function]}
|
||||||
|
placeholder="https://notebookserver"
|
||||||
|
styles={
|
||||||
|
Object {
|
||||||
|
"fieldGroup": Object {
|
||||||
|
"width": 300,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<StyledTextFieldBase
|
||||||
|
key="feature.notebookservertoken"
|
||||||
|
label="Notebook server token"
|
||||||
|
onChange={[Function]}
|
||||||
|
placeholder=""
|
||||||
|
styles={
|
||||||
|
Object {
|
||||||
|
"fieldGroup": Object {
|
||||||
|
"width": 300,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<StyledTextFieldBase
|
||||||
|
key="feature.notebookbasepath"
|
||||||
|
label="Notebook base path"
|
||||||
|
onChange={[Function]}
|
||||||
|
placeholder=""
|
||||||
|
styles={
|
||||||
|
Object {
|
||||||
|
"fieldGroup": Object {
|
||||||
|
"width": 300,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
<Stack
|
||||||
|
horizontalAlign="space-between"
|
||||||
|
>
|
||||||
|
<StyledTextFieldBase
|
||||||
|
key="key"
|
||||||
|
label="Auth key"
|
||||||
|
onChange={[Function]}
|
||||||
|
placeholder=""
|
||||||
|
styles={
|
||||||
|
Object {
|
||||||
|
"fieldGroup": Object {
|
||||||
|
"width": 300,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<StyledTextFieldBase
|
||||||
|
disabled={true}
|
||||||
|
key="dataExplorerSource"
|
||||||
|
label="Data Explorer Source (portal only)"
|
||||||
|
onChange={[Function]}
|
||||||
|
placeholder="https://localhost:1234/explorer.html"
|
||||||
|
styles={
|
||||||
|
Object {
|
||||||
|
"fieldGroup": Object {
|
||||||
|
"width": 300,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<StyledTextFieldBase
|
||||||
|
key="feature.livyendpoint"
|
||||||
|
label="Livy endpoint"
|
||||||
|
onChange={[Function]}
|
||||||
|
placeholder=""
|
||||||
|
styles={
|
||||||
|
Object {
|
||||||
|
"fieldGroup": Object {
|
||||||
|
"width": 300,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</div>
|
||||||
|
`;
|
|
@ -19,6 +19,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
>.title {
|
>.title {
|
||||||
|
position: relative; // To attach FeaturePanelLauncher as absolute
|
||||||
color: @BaseHigh;
|
color: @BaseHigh;
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
padding-left: 0px;
|
padding-left: 0px;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import * as Constants from "../../Common/Constants";
|
import * as Constants from "../../Common/Constants";
|
||||||
import { Link } from "office-ui-fabric-react/lib/Link";
|
import { Link } from "office-ui-fabric-react/lib/Link";
|
||||||
|
import { FeaturePanelLauncher } from "../Controls/FeaturePanel/FeaturePanelLauncher";
|
||||||
|
|
||||||
export interface SplashScreenItem {
|
export interface SplashScreenItem {
|
||||||
iconSrc: string;
|
iconSrc: string;
|
||||||
|
@ -29,7 +30,10 @@ export class SplashScreenComponent extends React.Component<SplashScreenComponent
|
||||||
return (
|
return (
|
||||||
<div className="splashScreenContainer">
|
<div className="splashScreenContainer">
|
||||||
<div className="splashScreen">
|
<div className="splashScreen">
|
||||||
<div className="title">Welcome to Cosmos DB</div>
|
<div className="title">
|
||||||
|
Welcome to Cosmos DB
|
||||||
|
<FeaturePanelLauncher />
|
||||||
|
</div>
|
||||||
<div className="subtitle">Globally distributed, multi-model database service for any scale</div>
|
<div className="subtitle">Globally distributed, multi-model database service for any scale</div>
|
||||||
<div className="mainButtonsContainer">
|
<div className="mainButtonsContainer">
|
||||||
{this.props.mainItems.map((item: SplashScreenItem) => (
|
{this.props.mainItems.map((item: SplashScreenItem) => (
|
||||||
|
|
Loading…
Reference in New Issue