Skip to content

Commit

Permalink
MAT-7192 added action center and delete button to library details screen
Browse files Browse the repository at this point in the history
  • Loading branch information
sb-prateekkeerthi committed Feb 24, 2025
1 parent fc6005c commit df195da
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import React, { useState, useEffect } from "react";
import { SpeedDial, SpeedDialAction } from "@mui/material";
import DeleteOutlinedIcon from "@mui/icons-material/DeleteOutlined";
import EditCalendarOutlinedIcon from "@mui/icons-material/EditCalendarOutlined";
import AccountTreeOutlinedIcon from "@mui/icons-material/AccountTreeOutlined";
import { MadieDiscardDialog } from "@madie/madie-design-system/dist/react";
import { CqlLibrary } from "@madie/madie-models";
import { blue, red } from "@mui/material/colors";
import { RouteHandlerState, routeHandlerStore } from "@madie/madie-util";

interface PropTypes {
canEdit: boolean;
library: CqlLibrary;
}

const CqlLibraryActionCenter = (props: PropTypes) => {
const [open, setOpen] = useState(false);
const [actions, setActions] = useState<Array<any>>([]);
const [discardDialogOpen, setDiscardDialogOpen] = useState<boolean>(false);
const [eventToTrigger, setEventToTrigger] = useState<Event | null>(null);

const { updateRouteHandlerState } = routeHandlerStore;
const [routeHandlerState, setRouteHandlerState] = useState<RouteHandlerState>(
routeHandlerStore.state
);

useEffect(() => {
const subscription = routeHandlerStore.subscribe(setRouteHandlerState);
return () => {
subscription.unsubscribe();
};
}, []);

useEffect(() => {
setActions(getActionArray(props.library, props.canEdit));
}, [props, routeHandlerState]);

const onContinue = () => {
setDiscardDialogOpen(false);
if (eventToTrigger) {
window.dispatchEvent(eventToTrigger);
}
updateRouteHandlerState({
canTravel: true,
pendingRoute: "",
});
setEventToTrigger(null);
};

const onClose = () => {
setDiscardDialogOpen(false);
setEventToTrigger(null);
};

const handleActionClick = (event: Event) => {
if (routeHandlerState?.canTravel) {
window.dispatchEvent(event);
} else {
setEventToTrigger(event);
setDiscardDialogOpen(true);
}
};

const getActionArray = (library: CqlLibrary, canEdit: boolean): any[] => {
const actions = new Map<string, any>();

if (canEdit) {
if (library?.draft) {
actions.set("delete library", {
icon: <DeleteOutlinedIcon sx={{ color: red[500] }} />,
name: "Delete Library",
onClick: () => handleActionClick(new Event("delete-library")),
});
actions.set("version library", {
icon: <AccountTreeOutlinedIcon sx={{ color: blue[500] }} />,
name: "Version Library",
onClick: () => handleActionClick(new Event("version-library")),
});
}
}
// required order to display
const actionsListOrder = ["version library", "delete library"];
return actionsListOrder.map((key) => actions.get(key)).filter(Boolean);
};

return (
<div
data-testid="action-center"
style={{
display: "flex",
alignItems: "center",
height: 40,
backgroundColor: open ? "white" : "transparent",
borderRadius: 25,
}}
>
<SpeedDial
ariaLabel="Library action center"
data-testid="action-center-button"
sx={{
"& .MuiSpeedDial-fab": {
width: 40,
height: 40,
backgroundColor: "white",
color: "grey",
"&:hover": {
backgroundColor: "#f0f0f0",
},
},
}}
icon={
<div
data-testid="action-center-actual-icon"
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
transition: "transform 0.3s",
transform: open ? "rotate(90deg)" : "none",
}}
>
<div style={{ margin: "0 2px", color: "black" }}></div>
<div style={{ margin: "0 2px", color: "black" }}></div>
<div style={{ margin: "0 2px", color: "black" }}></div>
</div>
}
direction="left"
open={open}
onClick={() => setOpen((prevOpen) => !prevOpen)}
>
{actions.map((action) => (
<SpeedDialAction
key={action.name}
icon={action.icon}
tooltipTitle={action.name}
data-testid={action.name.replace(/\s/g, "")}
onClick={() => {
setOpen(false);
action.onClick();
}}
sx={{
boxShadow: "none",
transition: "opacity 0s, visibility 0s",
margin: 0,
marginRight: 1,
transitionDelay: "0s",
}}
/>
))}
</SpeedDial>
<MadieDiscardDialog
open={discardDialogOpen}
onContinue={onContinue}
onClose={onClose}
/>
</div>
);
};

export default CqlLibraryActionCenter;
23 changes: 20 additions & 3 deletions src/components/PageHeader/PageHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import "styled-components/macro";
import "./pageHeader.scss";
import axios from "../../../api/axios-instance";
import { useIsOverflow } from "./useIsOverflow";
import CqlLibraryActionCenter from "./LibraryActionCenter/CqlLibraryActionCenter";

const PageHeader = () => {
const { pathname } = useLocation();
Expand Down Expand Up @@ -77,12 +78,18 @@ const PageHeader = () => {
setWafOpen(false);
};
// dialog utilities just for delete measure
const canEdit: boolean = checkUserCanEdit(
const measureCanEdit: boolean = checkUserCanEdit(
measureState?.measureSet?.owner,
measureState?.measureSet?.acls,
true // in this context we don't care if it's not a draft; because we still have some actions we can take
);

const libraryCanEdit: boolean = checkUserCanEdit(
libraryState?.librarySet?.owner,
libraryState?.librarySet?.acls,
true
);

const makeUTCDate = (date) => {
return `${
date.getUTCMonth() + 1
Expand Down Expand Up @@ -128,7 +135,7 @@ const PageHeader = () => {
<div tw="pr-8" style={{ position: "relative" }}>
<div style={{ position: "absolute", top: 0, right: 0 }}>
<MeasureActionCenter
canEdit={canEdit}
canEdit={measureCanEdit}
measure={measureState}
/>
</div>
Expand Down Expand Up @@ -171,7 +178,7 @@ const PageHeader = () => {
<div tw="pr-8" style={{ marginLeft: "auto" }}>
<Button
style={{ border: "none" }}
disabled={!canEdit}
disabled={!measureCanEdit}
className="page-header-action-button"
variant="outline-filled"
data-testId="delete-measure-button"
Expand Down Expand Up @@ -251,6 +258,16 @@ const PageHeader = () => {
{pathname.includes("edit") && pathname.includes("cql-libraries") && (
<Fade in={libraryState?.cqlLibraryName !== undefined}>
<div className="details">
(
<div tw="pr-8" style={{ position: "relative" }}>
<div style={{ position: "absolute", top: 0, right: 0 }}>
<CqlLibraryActionCenter
canEdit={libraryCanEdit}
library={libraryState}
/>
</div>
</div>
)
<div>
<Breadcrumbs aria-label="Libraries">
<Link
Expand Down
6 changes: 3 additions & 3 deletions src/types/madie-components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@ declare module "@madie/madie-components" {
readonly lg: "lg";
readonly xl: "xl";
};
export type ButtonSize = typeof ButtonSizeDefs[keyof typeof ButtonSizeDefs];
export type ButtonSize = (typeof ButtonSizeDefs)[keyof typeof ButtonSizeDefs];

export const ButtonVariantDefs: {
readonly primary: "primary";
readonly secondary: "secondary";
readonly white: "white";
};
export type ButtonVariant =
typeof ButtonVariantDefs[keyof typeof ButtonVariantDefs];
(typeof ButtonVariantDefs)[keyof typeof ButtonVariantDefs];

export const ButtonShapeDefs: {
readonly normal: "normal";
readonly round: "round";
readonly circular: "circular";
};
export type ButtonShape =
typeof ButtonShapeDefs[keyof typeof ButtonShapeDefs];
(typeof ButtonShapeDefs)[keyof typeof ButtonShapeDefs];

export type IconType = (props: React.ComponentProps<"svg">) => JSX.Element;

Expand Down

0 comments on commit df195da

Please sign in to comment.