Compare commits

...

2 Commits

Author SHA1 Message Date
Victor Meng
aeb9c87eb2 formatting 2021-04-09 18:01:47 -07:00
Victor Meng
188d08ea7b Enable searching in account switcher 2021-04-09 17:29:02 -07:00
3 changed files with 126 additions and 41 deletions

View File

@@ -0,0 +1,87 @@
import { Callout, DefaultButton, DirectionalHint, Stack, TextField } from "office-ui-fabric-react";
import React from "react";
export interface DropdownItem {
key: string;
text: string;
}
export interface SearchableDropdownProps {
items: DropdownItem[];
onItemSelected: (selectedItem: DropdownItem) => void;
defaultSelectedItem?: DropdownItem;
placeholder?: string;
title?: string;
}
export interface SearchableDropdownState {
isDropdownExpanded: boolean;
selectedItem: DropdownItem;
filteredItems: DropdownItem[];
}
export class SearchableDropdown extends React.Component<SearchableDropdownProps, SearchableDropdownState> {
constructor(props: SearchableDropdownProps) {
super(props);
this.state = {
isDropdownExpanded: false,
selectedItem: props.defaultSelectedItem,
filteredItems: props.items,
};
}
public render(): JSX.Element {
return this.state.isDropdownExpanded ? (
<Stack>
<TextField
className="dropdownTextField"
title={this.props.title}
onChange={(event, newInput?: string) => this.onSearchInputChange(newInput)}
placeholder={this.props.placeholder}
autoFocus
/>
<Callout
isBeakVisible={false}
target=".dropdownTextField"
directionalHint={DirectionalHint.rightTopEdge}
onDismiss={() => this.setState({ isDropdownExpanded: false })}
gapSpace={0}
>
<Stack>
{this.state.filteredItems?.map((item) => (
<DefaultButton
key={item.key}
text={item.text}
style={{ border: "none", textAlign: "left" }}
styles={{ label: { fontWeight: "normal" } }}
onClick={() => this.onItemSelected(item)}
/>
))}
</Stack>
</Callout>
</Stack>
) : (
<TextField
className="dropdownTextField"
title={this.props.title}
onClick={() => this.setState({ isDropdownExpanded: true, filteredItems: this.props.items })}
value={this.state.selectedItem?.text || ""}
placeholder={this.props.placeholder}
readOnly
/>
);
}
private onSearchInputChange(newInput: string): void {
const filteredItems = this.props.items.filter((item: DropdownItem) =>
item.text.toLocaleLowerCase().includes(newInput.toLocaleLowerCase())
);
this.setState({ filteredItems });
}
private onItemSelected(item: DropdownItem): void {
this.setState({ selectedItem: item, isDropdownExpanded: false });
this.props.onItemSelected(item);
}
}

View File

@@ -1,7 +1,6 @@
import { Dropdown } from "office-ui-fabric-react/lib/Dropdown";
import * as React from "react";
import { FunctionComponent } from "react";
import React from "react";
import { DatabaseAccount } from "../../../Contracts/DataModels";
import { DropdownItem, SearchableDropdown } from "./SearchableDropdown";
interface Props {
accounts: DatabaseAccount[];
@@ -10,30 +9,32 @@ interface Props {
dismissMenu: () => void;
}
export const SwitchAccount: FunctionComponent<Props> = ({
export const SwitchAccount: React.FunctionComponent<Props> = ({
accounts,
setSelectedAccountName,
selectedAccount,
dismissMenu,
}: Props) => {
const accountItems = accounts?.map((account) => ({
key: account.name,
text: account.name,
}));
const defaultAccount = selectedAccount && {
key: selectedAccount.name,
text: selectedAccount.name,
};
return (
<Dropdown
label="Cosmos DB Account Name"
className="accountSwitchAccountDropdown"
options={accounts?.map((account) => ({
key: account.name,
text: account.name,
data: account,
}))}
onChange={(_, option) => {
setSelectedAccountName(String(option.key));
<SearchableDropdown
items={accountItems}
title="Cosmos DB Account Name"
defaultSelectedItem={defaultAccount}
placeholder={accounts?.length === 0 ? "No Accounts Found" : "Select an Account"}
onItemSelected={(accountItem: DropdownItem) => {
setSelectedAccountName(accountItem.key);
dismissMenu();
}}
defaultSelectedKey={selectedAccount?.name}
placeholder={accounts && accounts.length === 0 ? "No Accounts Found" : "Select an Account"}
styles={{
callout: "accountSwitchAccountDropdownMenu",
}}
/>
);
};

View File

@@ -1,7 +1,6 @@
import { Dropdown } from "office-ui-fabric-react/lib/Dropdown";
import * as React from "react";
import { FunctionComponent } from "react";
import React from "react";
import { Subscription } from "../../../Contracts/DataModels";
import { DropdownItem, SearchableDropdown } from "./SearchableDropdown";
interface Props {
subscriptions: Subscription[];
@@ -9,30 +8,28 @@ interface Props {
setSelectedSubscriptionId: (id: string) => void;
}
export const SwitchSubscription: FunctionComponent<Props> = ({
export const SwitchSubscription: React.FunctionComponent<Props> = ({
subscriptions,
setSelectedSubscriptionId,
selectedSubscription,
}: Props) => {
const subscriptionItems = subscriptions?.map((sub) => ({
key: sub.subscriptionId,
text: sub.displayName,
}));
const defaultSubscription = selectedSubscription && {
key: selectedSubscription.subscriptionId,
text: selectedSubscription.displayName,
};
return (
<Dropdown
label="Subscription"
className="accountSwitchSubscriptionDropdown"
options={subscriptions?.map((sub) => {
return {
key: sub.subscriptionId,
text: sub.displayName,
data: sub,
};
})}
onChange={(_, option) => {
setSelectedSubscriptionId(String(option.key));
}}
defaultSelectedKey={selectedSubscription?.subscriptionId}
placeholder={subscriptions && subscriptions.length === 0 ? "No Subscriptions Found" : "Select a Subscription"}
styles={{
callout: "accountSwitchSubscriptionDropdownMenu",
}}
<SearchableDropdown
items={subscriptionItems}
title="Subscription"
defaultSelectedItem={defaultSubscription}
placeholder={subscriptions?.length === 0 ? "No Subscriptions Found" : "Select a Subscription"}
onItemSelected={(subscriptionItem: DropdownItem) => setSelectedSubscriptionId(subscriptionItem.key)}
/>
);
};