Skip to content

Commit

Permalink
Pull request update/250121
Browse files Browse the repository at this point in the history
fcb2b4b OS-556. Introduce CapabilityField component and enhance
CapabilityCard
45f1df4 OSN-556. Refactor CapabilityCard component
0c47662 OSN-569 Refactor URL handling in InitializeContainer to
streamline query parameter management
  • Loading branch information
tm-hystax authored Jan 21, 2025
2 parents 49b574e + fcb2b4b commit fcb54ad
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 230 deletions.
88 changes: 49 additions & 39 deletions ngui/ui/src/components/CapabilityCard/CapabilityCard.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { ChangeEvent } from "react";
import { Box, Typography, Paper, lighten } from "@mui/material";
import { useRef } from "react";
import { Box, Typography, Paper, lighten, FormControlLabel } from "@mui/material";
import { FormattedMessage } from "react-intl";
import Checkbox from "components/Checkbox";
import ContentBackdropLoader from "components/ContentBackdropLoader";

type CapabilityCardProps = {
capability: "mlops" | "finops";
checked?: boolean;
onChange: (event: ChangeEvent<HTMLInputElement>, checked: boolean) => void;
onChange: (checked: boolean) => void;
isLoading?: boolean;
disabled?: boolean;
typographyVariant?: "body1" | "body2" | "subtitle1" | "subtitle2" | "caption" | "overline";
sx?: Record<string, unknown>;
};

type FeatureListProps = {
Expand Down Expand Up @@ -60,54 +61,63 @@ const CapabilityCard = ({
checked = false,
isLoading = false,
disabled = false,
typographyVariant = "body2"
}: CapabilityCardProps) => (
<ContentBackdropLoader isLoading={isLoading} size="medium">
<Box
typographyVariant = "body2",
sx
}: CapabilityCardProps) => {
const clickTimeRef = useRef<number>(0);

return (
<Paper
elevation={0}
sx={{
height: "100%",
width: "100%"
border: (theme) => `1px solid ${lighten(theme.palette.info.main, 0.8)}`,
...sx
}}
>
<label
style={{
cursor: "pointer",
display: "flex"
}}
>
<Paper
elevation={0}
<ContentBackdropLoader isLoading={isLoading}>
<Box
sx={{
border: (theme) => `1px solid ${lighten(theme.palette.info.main, 0.8)}`,
padding: "1rem",
width: "100%",
height: "100%"
height: "100%",
cursor: disabled ? "default" : "pointer"
}}
onMouseDown={() => {
clickTimeRef.current = Date.now();
}}
onMouseUp={() => {
const timeDiff = Date.now() - clickTimeRef.current;

const textSelection = window.getSelection()?.toString();

if (timeDiff < 150) {
onChange(!checked);
} else {
if (textSelection) {
return;
}
onChange(!checked);
}
}}
>
<Box
<FormControlLabel
sx={{
padding: "1rem"
pointerEvents: "none"
}}
>
<Box
sx={{
ml: "-11px",
display: "flex",
alignItems: "center"
}}
>
<Checkbox checked={checked} onChange={onChange} disabled={disabled} />
control={<Checkbox checked={checked} disabled={disabled} onChange={(_, checked) => onChange(checked)} />}
label={
<Typography variant={typographyVariant}>
<FormattedMessage id={capabilityName[capability]} />
</Typography>
</Box>
<Box>
<FeatureList messageIds={capabilityMessages[capability]} variant={typographyVariant} />
</Box>
}
/>
<Box>
<FeatureList messageIds={capabilityMessages[capability]} variant={typographyVariant} />
</Box>
</Paper>
</label>
</Box>
</ContentBackdropLoader>
);
</Box>
</ContentBackdropLoader>
</Paper>
);
};

export default CapabilityCard;
74 changes: 74 additions & 0 deletions ngui/ui/src/components/CapabilityField/CapabilityField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { Box } from "@mui/material";
import { FormControl, FormHelperText } from "@mui/material";
import { Controller, useFormContext } from "react-hook-form";
import { useIntl } from "react-intl";
import CapabilityCard from "components/CapabilityCard";
import { SPACING_2 } from "utils/layouts";

type FieldNames = {
capability: string;
capabilityMl: string;
capabilityFin: string;
};

type CapabilityFieldProps = {
fieldNames: FieldNames;
margin?: "none" | "normal" | "dense";
fullWidth?: boolean;
};

const CapabilityField = ({ fieldNames, margin, fullWidth }: CapabilityFieldProps) => {
const intl = useIntl();
const {
control,
formState: { errors }
} = useFormContext();

return (
<FormControl margin={margin} fullWidth={fullWidth}>
<Controller
control={control}
name={fieldNames.capability}
rules={{
validate: {
atLeastOne: (value) => {
if (value[fieldNames.capabilityMl] || value[fieldNames.capabilityFin]) {
return true;
}
return intl.formatMessage({ id: "applyOptscaleCapabilityError" });
}
}
}}
render={({ field: { value, onChange } }) => (
<Box display="flex" gap={SPACING_2} flexWrap="wrap">
<CapabilityCard
capability="finops"
checked={value[fieldNames.capabilityFin]}
onChange={(checked) => {
onChange({ ...value, [fieldNames.capabilityFin]: checked });
}}
sx={{
flexGrow: 1,
flexBasis: "200px"
}}
/>
<CapabilityCard
capability="mlops"
checked={value[fieldNames.capabilityMl]}
onChange={(checked) => {
onChange({ ...value, [fieldNames.capabilityMl]: checked });
}}
sx={{
flexGrow: 1,
flexBasis: "200px"
}}
/>
</Box>
)}
/>
{!!errors[fieldNames.capability] && <FormHelperText error>{errors?.[fieldNames.capability]?.message}</FormHelperText>}
</FormControl>
);
};

export default CapabilityField;
3 changes: 3 additions & 0 deletions ngui/ui/src/components/CapabilityField/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import CapabilityField from "./CapabilityField";

export default CapabilityField;
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import { ReactNode } from "react";
import Box from "@mui/material/Box";
import CircularProgress from "@mui/material/CircularProgress";
import Backdrop from "components/Backdrop";

const ContentBackdropLoader = ({ isLoading = false, size, children }) => (
type ContentBackdropLoaderProps = {
isLoading?: boolean;
// The size of the component.
// * If using a number, the pixel unit is assumed.
// * If using a string, you need to provide the CSS unit, e.g. '3rem'.
size?: string | number;
children: ReactNode;
};

const ContentBackdropLoader = ({ isLoading = false, size, children }: ContentBackdropLoaderProps) => (
<Box height="100%" position="relative">
{isLoading && (
<Backdrop customClass="contentLoader">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,63 +1,15 @@
import { Box } from "@mui/material";
import { FormControl, FormHelperText } from "@mui/material";
import { Controller, useFormContext } from "react-hook-form";
import { useIntl } from "react-intl";
import CapabilityCard from "components/CapabilityCard";
import CapabilityFieldComponent from "components/CapabilityField";
import { FIELD_NAMES } from "../constants";
import { FormValues } from "../types";

const CapabilityField = () => {
const intl = useIntl();
const {
control,
formState: { errors }
} = useFormContext<FormValues>();

return (
<FormControl margin="none">
<Controller
control={control}
name={FIELD_NAMES.CAPABILITY}
rules={{
validate: {
atLeastOne: (value) => {
if (value[FIELD_NAMES.CAPABILITY_ML] || value[FIELD_NAMES.CAPABILITY_FIN]) {
return true;
}
return intl.formatMessage({ id: "applyOptscaleCapabilityError" });
}
}
}}
render={({ field: { value, onChange } }) => (
<Box
display="grid"
gridTemplateColumns={{
xs: "1fr",
sm: "repeat(2, 1fr)"
}}
columnGap={4}
rowGap={2}
>
<CapabilityCard
capability="finops"
checked={value[FIELD_NAMES.CAPABILITY_FIN]}
onChange={(_, checked) => {
onChange({ ...value, [FIELD_NAMES.CAPABILITY_FIN]: checked });
}}
/>
<CapabilityCard
capability="mlops"
checked={value[FIELD_NAMES.CAPABILITY_ML]}
onChange={(_, checked) => {
onChange({ ...value, [FIELD_NAMES.CAPABILITY_ML]: checked });
}}
/>
</Box>
)}
/>
{!!errors[FIELD_NAMES.CAPABILITY] && <FormHelperText error>{errors[FIELD_NAMES.CAPABILITY]?.message}</FormHelperText>}
</FormControl>
);
};
const CapabilityField = () => (
<CapabilityFieldComponent
fieldNames={{
capability: FIELD_NAMES.CAPABILITY,
capabilityMl: FIELD_NAMES.CAPABILITY_ML,
capabilityFin: FIELD_NAMES.CAPABILITY_FIN
}}
margin="none"
/>
);

export default CapabilityField;
Original file line number Diff line number Diff line change
@@ -1,62 +1,15 @@
import { Box, FormHelperText, FormControl } from "@mui/material";
import { Controller, useFormContext } from "react-hook-form";
import { useIntl } from "react-intl";
import CapabilityCard from "components/CapabilityCard";
import CapabilityFieldComponent from "components/CapabilityField";
import { FIELD_NAMES } from "../constants";
import { FormValues } from "../types";

const CapabilityField = () => {
const intl = useIntl();
const {
control,
formState: { errors }
} = useFormContext<FormValues>();

return (
<FormControl fullWidth>
<Controller
control={control}
name={FIELD_NAMES.CAPABILITY}
rules={{
validate: {
atLeastOne: (value) => {
if (value[FIELD_NAMES.CAPABILITY_ML] || value[FIELD_NAMES.CAPABILITY_FIN]) {
return true;
}
return intl.formatMessage({ id: "applyOptscaleCapabilityError" });
}
}
}}
render={({ field: { value, onChange } }) => (
<Box
display="grid"
gridTemplateColumns={{
xs: "1fr",
lg: "repeat(2, 1fr)"
}}
columnGap={4}
rowGap={2}
>
<CapabilityCard
capability="finops"
checked={value[FIELD_NAMES.CAPABILITY_FIN]}
onChange={(_, checked) => {
onChange({ ...value, [FIELD_NAMES.CAPABILITY_FIN]: checked });
}}
/>
<CapabilityCard
capability="mlops"
checked={value[FIELD_NAMES.CAPABILITY_ML]}
onChange={(_, checked) => {
onChange({ ...value, [FIELD_NAMES.CAPABILITY_ML]: checked });
}}
/>
</Box>
)}
/>
{!!errors[FIELD_NAMES.CAPABILITY] && <FormHelperText error>{errors[FIELD_NAMES.CAPABILITY]?.message}</FormHelperText>}
</FormControl>
);
};
const CapabilityField = () => (
<CapabilityFieldComponent
fieldNames={{
capability: FIELD_NAMES.CAPABILITY,
capabilityMl: FIELD_NAMES.CAPABILITY_ML,
capabilityFin: FIELD_NAMES.CAPABILITY_FIN
}}
fullWidth
/>
);

export default CapabilityField;
15 changes: 10 additions & 5 deletions ngui/ui/src/containers/InitializeContainer/InitializeContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,17 @@ const getRedirectionPath = (scopeUserEmail: string) => {
return next;
};

const getSearchParams = () => {
const searchParams = [showPolicyQueryParameter ? `${SHOW_POLICY_QUERY_PARAM}=${showPolicyQueryParameter}` : ""].join("&");
return searchParams;
};
const nextPath = getNextPath();

const url = new URL(nextPath, window.location.origin);

// Add showPolicy param if needed
if (showPolicyQueryParameter) {
url.searchParams.set(SHOW_POLICY_QUERY_PARAM, showPolicyQueryParameter);
}

return `${getNextPath()}?${getSearchParams()}`;
// Return just the pathname and search parts, removing the origin
return `${url.pathname}${url.search}`;
};

const InitializeContainer = () => {
Expand Down
Loading

0 comments on commit fcb54ad

Please sign in to comment.