Basic select api changes and adjustments ready

Signed-off-by: lukzerom <lukzerom@gmail.com>
This commit is contained in:
lukzerom
2021-12-11 00:35:19 +01:00
parent 3e70c671a1
commit 90fbd943de
3 changed files with 96 additions and 59 deletions
@@ -21,13 +21,13 @@ import FormControl from '@material-ui/core/FormControl';
import InputBase from '@material-ui/core/InputBase';
import MenuItem from '@material-ui/core/MenuItem';
import Select from '@material-ui/core/Select';
import Typography from '@material-ui/core/Typography';
import {
createStyles,
makeStyles,
Theme,
withStyles,
} from '@material-ui/core/styles';
import Typography from '@material-ui/core/Typography';
import React, { useEffect, useState } from 'react';
import ClosedDropdown from './static/ClosedDropdown';
import OpenedDropdown from './static/OpenedDropdown';
@@ -92,7 +92,14 @@ const useStyles = makeStyles(
chip: {
margin: 2,
},
checkbox: {},
select: {
'&:hover': {
cursor: 'not-allowed',
},
},
root: {
display: 'flex',
flexDirection: 'column',
@@ -101,12 +108,12 @@ const useStyles = makeStyles(
{ name: 'BackstageSelect' },
);
type Item = {
export type Item = {
label: string;
value: string | number;
};
type Selection = string | string[] | number | number[];
export type Selection = string | string[] | number | number[];
export type SelectProps = {
multiple?: boolean;
@@ -116,6 +123,8 @@ export type SelectProps = {
selected?: Selection;
onChange: (arg: Selection) => void;
triggerReset?: boolean;
native?: boolean;
disabled?: boolean;
};
export function SelectComponent(props: SelectProps) {
@@ -127,6 +136,8 @@ export function SelectComponent(props: SelectProps) {
selected,
onChange,
triggerReset,
native = false,
disabled = false,
} = props;
const classes = useStyles();
const [value, setValue] = useState<Selection>(
@@ -150,6 +161,9 @@ export function SelectComponent(props: SelectProps) {
};
const handleClick = (event: React.ChangeEvent<any>) => {
// if (disabled) {
// return event.preventDefault();
// }
setOpen(previous => {
if (multiple && !(event.target instanceof HTMLElement)) {
return true;
@@ -175,6 +189,8 @@ export function SelectComponent(props: SelectProps) {
<FormControl className={classes.formControl}>
<Select
value={value}
native={native}
disabled={disabled}
data-testid="select"
displayEmpty
multiple={multiple}
@@ -223,19 +239,26 @@ export function SelectComponent(props: SelectProps) {
{placeholder && !multiple && (
<MenuItem value={[]}>{placeholder}</MenuItem>
)}
{items &&
items.map(item => (
<MenuItem key={item.value} value={item.value}>
{multiple && (
<Checkbox
color="primary"
checked={(value as any[]).includes(item.value) || false}
className={classes.checkbox}
/>
)}
{item.label}
</MenuItem>
))}
{native
? items &&
items.map(item => (
<option value={item.value} key={item.value}>
{item.label}
</option>
))
: items &&
items.map(item => (
<MenuItem key={item.value} value={item.value}>
{multiple && (
<Checkbox
color="primary"
checked={(value as any[]).includes(item.value) || false}
className={classes.checkbox}
/>
)}
{item.label}
</MenuItem>
))}
</Select>
</FormControl>
</ClickAwayListener>
@@ -15,6 +15,11 @@
*/
export { SelectComponent as Select } from './Select';
export type { SelectClassKey, SelectInputBaseClassKey } from './Select';
export type {
Item,
SelectClassKey,
SelectInputBaseClassKey,
Selection,
} from './Select';
export type { ClosedDropdownClassKey } from './static/ClosedDropdown';
export type { OpenedDropdownClassKey } from './static/OpenedDropdown';
@@ -13,19 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { useCallback, useEffect } from 'react';
import { FieldProps } from '@rjsf/core';
import { scaffolderApiRef } from '../../../api';
import { Item, Progress, Select, Selection } from '@backstage/core-components';
import { useApi } from '@backstage/core-plugin-api';
import { scmIntegrationsApiRef } from '@backstage/integration-react';
import { useAsync } from 'react-use';
import Select from '@material-ui/core/Select';
import InputLabel from '@material-ui/core/InputLabel';
import Input from '@material-ui/core/Input';
import FormControl from '@material-ui/core/FormControl';
import FormHelperText from '@material-ui/core/FormHelperText';
import { useApi } from '@backstage/core-plugin-api';
import { Progress } from '@backstage/core-components';
import Input from '@material-ui/core/Input';
import InputLabel from '@material-ui/core/InputLabel';
import { FieldProps } from '@rjsf/core';
import React, { useCallback, useEffect } from 'react';
import { useAsync } from 'react-use';
import { scaffolderApiRef } from '../../../api';
function splitFormData(url: string | undefined, allowedOwners?: string[]) {
let host = undefined;
@@ -106,10 +104,10 @@ export const RepoUrlPicker = ({
allowedOwners,
);
const updateHost = useCallback(
(evt: React.ChangeEvent<{ name?: string; value: unknown }>) => {
(value: Selection) => {
onChange(
serializeFormData({
host: evt.target.value as string,
host: value as string,
owner,
repo,
organization,
@@ -121,6 +119,21 @@ export const RepoUrlPicker = ({
[onChange, owner, repo, organization, workspace, project],
);
const updateOwnerSelect = useCallback(
(value: Selection) =>
onChange(
serializeFormData({
host,
owner: value as string,
repo,
organization,
workspace,
project,
}),
),
[onChange, host, repo, organization, workspace, project],
);
const updateOwner = useCallback(
(evt: React.ChangeEvent<{ name?: string; value: unknown }>) =>
onChange(
@@ -224,6 +237,16 @@ export const RepoUrlPicker = ({
return <Progress />;
}
const hostsOptions: Item[] = integrations
? integrations
.filter(i => allowedHosts?.includes(i.host))
.map(i => ({ label: i.title, value: i.host }))
: [{ label: 'Loading...', value: 'loading' }];
const ownersOptions: Item[] = allowedOwners
? allowedOwners.map(i => ({ label: i, value: i }))
: [{ label: 'Loading...', value: 'loading' }];
return (
<>
<FormControl
@@ -231,20 +254,15 @@ export const RepoUrlPicker = ({
required
error={rawErrors?.length > 0 && !host}
>
<InputLabel htmlFor="hostInput">Host</InputLabel>
<Select native id="hostInput" onChange={updateHost} value={host}>
{integrations ? (
integrations
.filter(i => allowedHosts?.includes(i.host))
.map(i => (
<option key={i.host} value={i.host}>
{i.title}
</option>
))
) : (
<p>loading</p>
)}
</Select>
<Select
native
disabled={hostsOptions.length === 1}
label="Host"
onChange={updateHost}
selected={host}
items={hostsOptions}
/>
<FormHelperText>
The host where the repository will be created
</FormHelperText>
@@ -330,24 +348,15 @@ export const RepoUrlPicker = ({
required
error={rawErrors?.length > 0 && !owner}
>
<InputLabel htmlFor="ownerInput">Owner Available</InputLabel>
<Select
native
id="ownerInput"
onChange={updateOwner}
value={owner}
>
{allowedOwners ? (
allowedOwners.map(i => (
<option key={i} value={i}>
{i}
</option>
))
) : (
<p>loading</p>
)}
;
</Select>
label="Owner Available"
onChange={updateOwnerSelect}
disabled={ownersOptions.length === 1}
selected={owner}
items={ownersOptions}
/>
<FormHelperText>
The organization, user or project that this repo will belong to
</FormHelperText>