Skip to content

Commit

Permalink
fix(forms) generalize config table helpers WD-7725
Browse files Browse the repository at this point in the history
Signed-off-by: David Edler <[email protected]>
  • Loading branch information
edlerd committed Jan 3, 2024
1 parent 9e8a909 commit fdd6f22
Show file tree
Hide file tree
Showing 72 changed files with 685 additions and 757 deletions.
98 changes: 63 additions & 35 deletions src/components/ConfigurationRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,29 @@ import { MainTableRow } from "@canonical/react-components/dist/components/MainTa
import classnames from "classnames";
import { FormikProps } from "formik/dist/types";
import ConfigFieldDescription from "pages/settings/ConfigFieldDescription";
import {
InstanceAndProfileFormikProps,
InstanceAndProfileFormValues,
} from "components/forms/instanceAndProfileFormValues";
import { StorageVolumeFormValues } from "pages/storage/forms/StorageVolumeForm";
import { NetworkFormValues } from "pages/networks/forms/NetworkForm";
import { ProjectFormValues } from "pages/projects/CreateProject";
import { getConfigRowMetadata } from "util/configInheritance";

export type ConfigurationRowFormikValues =
| InstanceAndProfileFormValues
| StorageVolumeFormValues
| NetworkFormValues
| ProjectFormValues;

type ConfigurationRowFormikProps =
| InstanceAndProfileFormikProps
| FormikProps<NetworkFormValues>
| FormikProps<ProjectFormValues>
| FormikProps<StorageVolumeFormValues>;

interface Props {
formik: FormikProps<unknown>;
formik: ConfigurationRowFormikProps;
name: string;
label: string | ReactNode;
children: ReactElement;
Expand All @@ -16,12 +36,7 @@ interface Props {
disabledReason?: string;
help?: string;
inputHelp?: string;
isOverridden: boolean;
inheritedValue: string | ReactNode;
inheritSource: string;
isReadOnly: boolean;
value?: string;
overrideValue: string | ReactNode;
readOnlyRenderer?: (value: unknown) => string | ReactNode;
}

export const getConfigurationRow = ({
Expand All @@ -34,13 +49,14 @@ export const getConfigurationRow = ({
disabledReason,
help,
inputHelp,
isOverridden,
inheritedValue,
inheritSource,
isReadOnly,
value,
overrideValue,
readOnlyRenderer = (value) => <>{value}</>,
}: Props): MainTableRow => {
const values = formik.values as unknown as Record<string, string | undefined>;
const value = values[name];
const isOverridden = value !== undefined;
const overrideValue = readOnlyRenderer(value === "" ? "-" : value);
const metadata = getConfigRowMetadata(formik.values, name);

const toggleDefault = () => {
if (isOverridden) {
void formik.setFieldValue(name, undefined);
Expand All @@ -64,7 +80,11 @@ export const getConfigurationRow = ({
disabled,
help: (
<ConfigFieldDescription
description={inputHelp}
description={
metadata.configField
? metadata.configField.longdesc
: inputHelp
}
className="p-form-help-text"
/>
),
Expand Down Expand Up @@ -105,12 +125,36 @@ export const getConfigurationRow = ({
return children;
};

const renderOverride = (): ReactNode => {
if (formik.values.readOnly) {
return overrideValue;
}
if (isOverridden) {
return getForm();
}
return wrapDisabledTooltip(
<Button
onClick={toggleDefault}
className="u-no-margin--bottom"
type="button"
disabled={disabled}
appearance="base"
title="Create override"
hasIcon
>
<Icon name="edit" />
</Button>,
);
};

return getConfigurationRowBase({
configuration: (
<>
{displayLabel}
<ConfigFieldDescription
description={help}
description={
metadata.configField ? metadata.configField.shortdesc : help
}
className="configuration-help"
/>
</>
Expand All @@ -123,32 +167,16 @@ export const getConfigurationRow = ({
})}
>
<div className="mono-font">
<b>{inheritedValue}</b>
<b>{readOnlyRenderer(metadata.value)}</b>
</div>
{inheritedValue && (
{metadata && (
<div className="p-text--small u-text--muted">
From: {inheritSource}
From: {metadata.source}
</div>
)}
</div>
),
override: isReadOnly
? overrideValue
: isOverridden
? getForm()
: wrapDisabledTooltip(
<Button
onClick={toggleDefault}
className="u-no-margin--bottom"
type="button"
disabled={disabled}
appearance="base"
title="Create override"
hasIcon
>
<Icon name="edit" />
</Button>,
),
override: renderOverride(),
});
};

Expand Down
2 changes: 1 addition & 1 deletion src/components/forms/CloudInitConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const CloudInitConfig: FC<Props> = ({ config, setConfig }) => {
yaml={config}
setYaml={setConfig}
autoResize={true}
isReadOnly={!setConfig}
readOnly={!setConfig}
/>
</div>
);
Expand Down
21 changes: 12 additions & 9 deletions src/components/forms/CloudInitForm.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import React, { FC } from "react";
import { Icon, Tooltip } from "@canonical/react-components";
import CloudInitConfig from "components/forms/CloudInitConfig";
import { SharedFormikTypes, SharedFormTypes } from "./sharedFormTypes";
import { getInstanceConfigurationRow } from "components/forms/InstanceConfigurationRow";
import InstanceConfigurationTable from "components/forms/InstanceConfigurationTable";
import {
InstanceAndProfileFormikProps,
InstanceAndProfileFormValues,
} from "./instanceAndProfileFormValues";
import { getConfigurationRow } from "components/ConfigurationRow";
import ScrollableConfigurationTable from "components/forms/ScrollableConfigurationTable";
import { getInstanceKey } from "util/instanceConfigFields";

export interface CloudInitFormValues {
Expand All @@ -12,7 +15,7 @@ export interface CloudInitFormValues {
cloud_init_vendor_data?: string;
}

export const cloudInitPayload = (values: SharedFormTypes) => {
export const cloudInitPayload = (values: InstanceAndProfileFormValues) => {
return {
[getInstanceKey("cloud_init_network_config")]:
values.cloud_init_network_config,
Expand All @@ -22,7 +25,7 @@ export const cloudInitPayload = (values: SharedFormTypes) => {
};

interface Props {
formik: SharedFormikTypes;
formik: InstanceAndProfileFormikProps;
}

const CloudInitForm: FC<Props> = ({ formik }) => {
Expand All @@ -35,7 +38,7 @@ const CloudInitForm: FC<Props> = ({ formik }) => {

return (
<div className="cloud-init">
<InstanceConfigurationTable
<ScrollableConfigurationTable
configurationExtra={
<Tooltip
message="Applied only to images that have the cloud-init package installed."
Expand All @@ -45,7 +48,7 @@ const CloudInitForm: FC<Props> = ({ formik }) => {
</Tooltip>
}
rows={[
getInstanceConfigurationRow({
getConfigurationRow({
formik,
label: "Network config",
name: "cloud_init_network_config",
Expand All @@ -61,7 +64,7 @@ const CloudInitForm: FC<Props> = ({ formik }) => {
),
}),

getInstanceConfigurationRow({
getConfigurationRow({
formik,
label: "User data",
name: "cloud_init_user_data",
Expand All @@ -77,7 +80,7 @@ const CloudInitForm: FC<Props> = ({ formik }) => {
),
}),

getInstanceConfigurationRow({
getConfigurationRow({
formik,
label: "Vendor data",
name: "cloud_init_vendor_data",
Expand Down
8 changes: 4 additions & 4 deletions src/components/forms/DiskDeviceForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ import { Input, useNotify } from "@canonical/react-components";
import { useQuery } from "@tanstack/react-query";
import { queryKeys } from "util/queryKeys";
import { fetchStoragePools } from "api/storage-pools";
import { SharedFormikTypes } from "./sharedFormTypes";
import { InstanceAndProfileFormikProps } from "./instanceAndProfileFormValues";
import { fetchProfiles } from "api/profiles";
import Loader from "components/Loader";
import { figureInheritedVolumes } from "util/instanceConfigInheritance";
import { getInheritedVolumes } from "util/configInheritance";
import DiskDeviceFormRoot from "./DiskDeviceFormRoot";
import DiskDeviceFormInherited from "./DiskDeviceFormInherited";
import DiskDeviceFormCustom from "./DiskDeviceFormCustom";
import classnames from "classnames";

interface Props {
formik: SharedFormikTypes;
formik: InstanceAndProfileFormikProps;
project: string;
}

Expand Down Expand Up @@ -50,7 +50,7 @@ const DiskDeviceForm: FC<Props> = ({ formik, project }) => {
return <Loader />;
}

const inheritedVolumes = figureInheritedVolumes(formik.values, profiles);
const inheritedVolumes = getInheritedVolumes(formik.values, profiles);

return (
<div
Expand Down
22 changes: 11 additions & 11 deletions src/components/forms/DiskDeviceFormCustom.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { FC } from "react";
import { Icon, Input, Label } from "@canonical/react-components";
import { SharedFormikTypes } from "./sharedFormTypes";
import { InstanceAndProfileFormikProps } from "./instanceAndProfileFormValues";
import { EditInstanceFormValues } from "pages/instances/EditInstance";
import { InheritedVolume } from "util/instanceConfigInheritance";
import { InheritedVolume } from "util/configInheritance";
import CustomVolumeSelectBtn from "pages/storage/CustomVolumeSelectBtn";
import { FormDiskDevice, removeDevice } from "util/formDevices";
import RenameDiskDeviceInput from "./RenameDiskDeviceInput";
Expand All @@ -15,7 +15,7 @@ import { LxdStorageVolume } from "types/storage";
import { isDiskDeviceMountPointMissing } from "util/instanceValidation";

interface Props {
formik: SharedFormikTypes;
formik: InstanceAndProfileFormikProps;
project: string;
inheritedVolumes: InheritedVolume[];
}
Expand All @@ -25,7 +25,7 @@ const DiskDeviceFormCustom: FC<Props> = ({
project,
inheritedVolumes,
}) => {
const isReadOnly = (formik.values as EditInstanceFormValues).readOnly;
const readOnly = (formik.values as EditInstanceFormValues).readOnly;
const customVolumes = formik.values.devices
.filter((device) => device.name !== "root" && device.type === "disk")
.map((device) => device as FormDiskDevice);
Expand Down Expand Up @@ -83,14 +83,14 @@ const DiskDeviceFormCustom: FC<Props> = ({
<RenameDiskDeviceInput
name={formVolume.name}
index={index}
isReadOnly={isReadOnly}
readOnly={readOnly}
setName={(name) =>
void formik.setFieldValue(`devices.${index}.name`, name)
}
/>
),
inherited: "",
override: !isReadOnly && (
override: !readOnly && (
<DetachDiskDeviceBtn onDetach={() => removeDevice(index, formik)} />
),
}),
Expand Down Expand Up @@ -118,7 +118,7 @@ const DiskDeviceFormCustom: FC<Props> = ({
{formVolume.pool} / {formVolume.source}
</b>
</div>
{!isReadOnly && (
{!readOnly && (
<CustomVolumeSelectBtn
project={project}
setValue={(volume) => changeVolume(volume, formVolume, index)}
Expand Down Expand Up @@ -147,7 +147,7 @@ const DiskDeviceFormCustom: FC<Props> = ({
Mount point
</Label>
),
inherited: isReadOnly ? (
inherited: readOnly ? (
<div className="mono-font">
<b>{formVolume.path}</b>
</div>
Expand Down Expand Up @@ -180,7 +180,7 @@ const DiskDeviceFormCustom: FC<Props> = ({
configuration: (
<Label forId={`devices.${index}.limits.read`}>Read limit</Label>
),
inherited: isReadOnly ? (
inherited: readOnly ? (
<div className="mono-font">
<b>
{formVolume.limits?.read
Expand Down Expand Up @@ -218,7 +218,7 @@ const DiskDeviceFormCustom: FC<Props> = ({
configuration: (
<Label forId={`devices.${index}.limits.write`}>Write limit</Label>
),
inherited: isReadOnly ? (
inherited: readOnly ? (
<div className="mono-font">
<b>
{formVolume.limits?.write
Expand Down Expand Up @@ -261,7 +261,7 @@ const DiskDeviceFormCustom: FC<Props> = ({
<ConfigurationTable rows={rows} />
</>
)}
{!isReadOnly && (
{!readOnly && (
<CustomVolumeSelectBtn project={project} setValue={addVolume}>
<Icon name="plus" />
<span>Attach disk device</span>
Expand Down
Loading

0 comments on commit fdd6f22

Please sign in to comment.