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( baseUrlOptions.find(o => o.key === window.location.origin + window.location.pathname) || baseUrlOptions[0] ); const [platform, setPlatform] = React.useState( 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>]; onChange?: (_?: React.FormEvent, 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.enablegallerypublish", label: "Enable Notebook Gallery Publishing", value: "true" }, { key: "feature.enablecodeofconduct", label: "Enable Code Of Conduct Acknowledgement", value: "true" }, { key: "feature.enableLinkInjection", label: "Enable Injecting Notebook Viewer Link into the first cell", value: "true" }, { key: "feature.enablesettingsv2", label: "Enable SettingsV2 Tab", 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>]; onChange?: (_: React.FormEvent, 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(urlParams.has(f.key) ? urlParams.get(f.key) === "true" : false)) ); stringFeatures.forEach( f => (f.reactState = React.useState(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, option?: IDropdownOption): void => { setBaseUrl(option); }; const onChangePlatform = (event: React.FormEvent, option?: IDropdownOption): void => { setPlatform(option); }; booleanFeatures.forEach( f => (f.onChange = (ev?: React.FormEvent, checked?: boolean): void => { f.reactState[1](checked); }) ); stringFeatures.forEach( f => (f.onChange = (event: React.FormEvent, 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]("./notebooks"); 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 = { dropdown: { width: 200 } }; const textFieldStyles: Partial = { 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 (
Notebooks on localhost Portal points to local DE Reset {leftBooleanFeatures.map(f => ( ))} {rightBooleanFeatures.map(f => ( ))} {leftStringFeatures.map(f => ( ))} {rightStringFeatures.map(f => ( ))}
); };