pull/109/head
Samuel Rowe 3 years ago
parent 7879eb7fb2
commit 70e418838a

@ -1,6 +1,7 @@
import { import {
Fragment, Fragment,
FunctionComponent, FunctionComponent,
ReactNode,
useCallback, useCallback,
useMemo, useMemo,
useState useState
@ -13,6 +14,7 @@ import { ScrollView } from "./ScrollView";
import Modal from "./Modal"; import Modal from "./Modal";
import Tabs from "./Tabs"; import Tabs from "./Tabs";
import Tab from "./Tab"; import Tab from "./Tab";
import ResourceList from "./ResourceList";
export interface ITab { export interface ITab {
value: string; value: string;
@ -23,12 +25,15 @@ export interface ITab {
export interface IFormModalProps { export interface IFormModalProps {
title: string; title: string;
tabs: ITab[]; tabs: ITab[];
items: string[];
onHide: () => void; onHide: () => void;
getFinalValues: (values: any, selectedNode?: any) => any; getFinalValues: (values: any, selectedNode?: any) => any;
getInitialValues: (selectedNode?: any) => any; getInitialValues: (selectedNode?: any) => any;
getText: (item: string) => ReactNode;
validationSchema: any; validationSchema: any;
onCreate: (finalValues: any, values: any, formik: any) => void; onCreate: (finalValues: any, values: any, formik: any) => void;
selectedNode?: any; selectedNode?: any;
resourceType: string;
} }
const StyledScrollView = styled(ScrollView)` const StyledScrollView = styled(ScrollView)`
@ -40,6 +45,16 @@ const StyledScrollView = styled(ScrollView)`
flex: 1 1 auto; flex: 1 1 auto;
`; `;
const Container = styled("div")`
display: flex;
flex-direction: row;
`;
const FormContainer = styled("div")`
display: flex;
flex-direction: column;
`;
const Actions = styled("div")` const Actions = styled("div")`
display: flex; display: flex;
padding-top: 0.75rem; padding-top: 0.75rem;
@ -58,12 +73,15 @@ const FormModal = (props: IFormModalProps) => {
const { const {
title, title,
tabs, tabs,
items,
validationSchema,
getInitialValues, getInitialValues,
getFinalValues, getFinalValues,
validationSchema, getText,
onHide, onHide,
onCreate, onCreate,
selectedNode selectedNode,
resourceType
} = props; } = props;
const [openTab, setOpenTab] = useState(() => tabs[0].value); const [openTab, setOpenTab] = useState(() => tabs[0].value);
@ -89,32 +107,52 @@ const FormModal = (props: IFormModalProps) => {
); );
}; };
const handleNew = () => null;
const handleRemove = () => null;
const handleEdit = () => null;
const selectedItem = undefined as any;
return ( return (
<Modal onHide={onHide} title={title}> <Modal onHide={onHide} title={title}>
<Formik <Container>
initialValues={initialValues} {items.length > 0 && (
enableReinitialize={true} <ResourceList
onSubmit={handleCreate} items={items}
validationSchema={validationSchema} newActionText={`New ${resourceType}`}
> getText={getText}
{(formik) => ( onNew={handleNew}
<> onRemove={handleRemove}
<Tabs value={openTab} onChange={setOpenTab}> onEdit={handleEdit}
{tabs.map((tab) => ( selectedItem={selectedItem?.key}
<Tab key={tab.value} value={tab.value} title={tab.title} /> />
))}
</Tabs>
<StyledScrollView height="500px">
{tabs.map(renderTab)}
</StyledScrollView>
<Actions>
<Button onClick={reportErrorsAndSubmit(formik)}>Save</Button>
</Actions>
</>
)} )}
</Formik> <FormContainer>
<Formik
initialValues={initialValues}
enableReinitialize={true}
onSubmit={handleCreate}
validationSchema={validationSchema}
>
{(formik) => (
<>
<Tabs value={openTab} onChange={setOpenTab}>
{tabs.map((tab) => (
<Tab key={tab.value} value={tab.value} title={tab.title} />
))}
</Tabs>
<StyledScrollView height="500px">
{tabs.map(renderTab)}
</StyledScrollView>
<Actions>
<Button onClick={reportErrorsAndSubmit(formik)}>Save</Button>
</Actions>
</>
)}
</Formik>
</FormContainer>
</Container>
</Modal> </Modal>
); );
}; };

@ -1,107 +0,0 @@
import { MinusSmIcon, PlusIcon } from "@heroicons/react/outline";
import { Button, styled } from "@mui/joy";
import IconButton from "@mui/joy/IconButton";
import { FunctionComponent, ReactElement } from "react";
import { truncateStr } from "../../../../utils";
export interface INetworkListProps {
networks: Record<string, any>;
selectedUuid: string;
onEdit: (networkUuid: string) => void;
onNew: () => void;
onRemove: (networkUuid: string) => void;
}
interface IListItemProps {
selected: boolean;
}
const Root = styled("div")`
padding: ${({ theme }) => theme.spacing(0)};
display: flex;
flex-direction: column;
justify-content: space-between;
border-right: solid #eaeaea 1px;
`;
const Top = styled("div")`
display: flex;
flex-direction: column;
`;
const Bottom = styled("div")`
padding: ${({ theme }) => theme.spacing(1, 2)};
`;
const ListItem = styled("div")<IListItemProps>`
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
column-gap: ${({ theme }) => theme.spacing(1)};
padding: ${({ theme }) => theme.spacing(1, 1, 1, 2)};
cursor: pointer;
background-color: ${({ selected }) => selected && "#f5f5f5"};
&:hover {
background-color: #f5f5f5;
}
`;
const ListItemText = styled("h5")`
font-weight: 400;
font-size: 14px;
`;
const RemoveButton = styled(IconButton)`
width: 24px;
max-height: 16px;
`;
const NetworkList: FunctionComponent<INetworkListProps> = (
props: INetworkListProps
): ReactElement => {
const { onNew, onRemove, onEdit, networks, selectedUuid } = props;
const handleEdit = (networkUuid: string) => () => onEdit(networkUuid);
const handleRemove = (e: any, networkUuid: string) => {
e.stopPropagation();
onRemove(networkUuid);
};
return (
<Root>
<Top>
{Object.keys(networks).map((networkUuid: string) => (
<ListItem
key={networkUuid}
onClick={handleEdit(networkUuid)}
selected={networkUuid === selectedUuid}
>
<ListItemText>
{truncateStr(networks[networkUuid].canvasConfig.node_name, 10)}
</ListItemText>
<RemoveButton
variant="soft"
size="sm"
color="danger"
onClick={(e) => handleRemove(e, networkUuid)}
>
<MinusSmIcon className="h-4 w-4" />
</RemoveButton>
</ListItem>
))}
</Top>
<Bottom>
<Button variant="plain" size="sm" onClick={onNew}>
<PlusIcon className="h-4 w-4 mr-2" />
New network
</Button>
</Bottom>
</Root>
);
};
export default NetworkList;

@ -2,10 +2,10 @@ import { useCallback, useState } from "react";
import CreateNetworkModal from "./CreateNetworkModal"; import CreateNetworkModal from "./CreateNetworkModal";
import { CallbackFunction, IEditNetworkForm } from "../../../../types"; import { CallbackFunction, IEditNetworkForm } from "../../../../types";
import EditNetworkModal from "./EditNetworkModal"; import EditNetworkModal from "./EditNetworkModal";
import { attachUUID, toaster } from "../../../../utils"; import { attachUUID, toaster, truncateStr } from "../../../../utils";
import { getFinalValues } from "./form-utils"; import { getFinalValues } from "./form-utils";
import EmptyNetworks from "./EmptyNetworks"; import EmptyNetworks from "./EmptyNetworks";
import NetworkList from "./NetworkList"; import ResourceList from "../../../ResourceList";
import { styled } from "@mui/joy"; import { styled } from "@mui/joy";
import Modal from "../../../Modal"; import Modal from "../../../Modal";
@ -95,12 +95,16 @@ const ModalNetwork = (props: IModalNetworkProps) => {
{(networkKeys.length > 0 || showCreate) && ( {(networkKeys.length > 0 || showCreate) && (
<Container> <Container>
{networkKeys.length > 0 && ( {networkKeys.length > 0 && (
<NetworkList <ResourceList
networks={networks} items={networkKeys}
newActionText="New network"
getText={(uuid: string) =>
truncateStr(networks[uuid].canvasConfig.node_name, 10)
}
onNew={handleNew} onNew={handleNew}
onRemove={handleRemove} onRemove={handleRemove}
onEdit={handleEdit} onEdit={handleEdit}
selectedUuid={selectedNetwork?.key} selectedItem={selectedNetwork?.key}
/> />
)} )}

@ -35,10 +35,13 @@ const CreateServiceModal = (props: IModalServiceProps) => {
return ( return (
<FormModal <FormModal
title="Create service" title="Services > New"
resourceType="service"
tabs={tabs} tabs={tabs}
items={["test"]}
getInitialValues={getInitialValues} getInitialValues={getInitialValues}
getFinalValues={getFinalValues} getFinalValues={getFinalValues}
getText={() => "test"}
validationSchema={validationSchema} validationSchema={validationSchema}
onHide={onHide} onHide={onHide}
onCreate={handleCreate} onCreate={handleCreate}

@ -40,10 +40,13 @@ const ModalServiceEdit = (props: IModalServiceProps) => {
return ( return (
<FormModal <FormModal
title="Edit service" title="Services > Edit"
resourceType="service"
tabs={tabs} tabs={tabs}
items={["test"]}
getInitialValues={getInitialValues} getInitialValues={getInitialValues}
getFinalValues={getFinalValues} getFinalValues={getFinalValues}
getText={() => "test"}
validationSchema={validationSchema} validationSchema={validationSchema}
onHide={onHide} onHide={onHide}
onCreate={handleUpdate} onCreate={handleUpdate}

@ -32,10 +32,13 @@ const CreateVolumeModal = (props: ICreateVolumeModalProps) => {
return ( return (
<FormModal <FormModal
title="Add volume" title="Volumes > New"
resourceType="volume"
tabs={tabs} tabs={tabs}
items={["test"]}
getInitialValues={getInitialValues} getInitialValues={getInitialValues}
getFinalValues={getFinalValues} getFinalValues={getFinalValues}
getText={() => "test"}
validationSchema={validationSchema} validationSchema={validationSchema}
onHide={onHide} onHide={onHide}
onCreate={handleCreate} onCreate={handleCreate}

@ -39,10 +39,13 @@ const EditVolumeModal = (props: IEditVolumeModal) => {
return ( return (
<FormModal <FormModal
title="Edit volume" title="Volumes > Edit"
resourceType="volume"
tabs={tabs} tabs={tabs}
getInitialValues={getInitialValues} getInitialValues={getInitialValues}
getFinalValues={getFinalValues} getFinalValues={getFinalValues}
items={["test"]}
getText={() => "test"}
selectedNode={selectedNode} selectedNode={selectedNode}
validationSchema={validationSchema} validationSchema={validationSchema}
onHide={onHide} onHide={onHide}

Loading…
Cancel
Save