123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- /*
- * Copyright 2021-2024 Avaiga Private Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
- * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
- */
- import React, { MouseEvent, ReactNode, useEffect, useMemo, useRef} from "react";
- import Chip from "@mui/material/Chip";
- import Avatar from "@mui/material/Avatar";
- import CheckCircleIcon from "@mui/icons-material/CheckCircle";
- import WarningIcon from "@mui/icons-material/Warning";
- import ErrorIcon from "@mui/icons-material/Error";
- import InfoIcon from "@mui/icons-material/Info";
- import { getInitials } from "../../utils";
- import { TaipyBaseProps } from "./utils";
- import { useClassNames } from "../../utils/hooks";
- export interface StatusType {
- status: string;
- message: string;
- }
- interface StatusProps extends TaipyBaseProps {
- value: StatusType;
- onClose?: (evt: MouseEvent) => void;
- icon?: ReactNode;
- withIcons?: boolean;
- content?: string;
- }
- const status2Color = (status: string): "error" | "info" | "success" | "warning" => {
- status = (status || "").toLowerCase();
- status = status.length == 0 ? " " : status.charAt(0);
- switch (status) {
- case "s":
- return "success";
- case "w":
- return "warning";
- case "e":
- return "error";
- }
- return "info";
- };
- // Function to get the appropriate icon based on the status
- const GetStatusIcon = (status: string, withIcons?: boolean): ReactNode => {
- // Use useMemo to memoize the iconProps as well
- const color = status2Color(status);
- // Memoize the iconProps
- const iconProps = {
- sx: { fontSize: 20, color: `${color}.main` }}
-
- if (withIcons) {
- switch (color) {
- case "success":
- return <CheckCircleIcon {...iconProps} />;
- case "warning":
- return <WarningIcon {...iconProps} />;
- case "error":
- return <ErrorIcon {...iconProps} />;
- default:
- return <InfoIcon {...iconProps} />;
- }
- } else {
- return getInitials(status);
- }
- };
- const chipSx = { alignSelf: "flex-start" };
- const defaultAvatarStyle = {
- width: '100%',
- height: '100%',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- };
- const defaultAvatarSx = {
- bgcolor: 'transparent'
- };
- const baseStyles = {
- fontSize: '1rem',
- textShadow: '1px 1px 4px black, -1px -1px 4px black',
- };
- const isSvgUrl = (content?: string) => {
- return content?.substring(content?.length - 4).toLowerCase() === ".svg"; // Check if it ends with ".svg"
- };
- const isInlineSvg = (content?: string) => {
- return content?.substring(0, 4).toLowerCase() === "<svg"; // Check if the content starts with "<svg"
- };
- const Status = (props: StatusProps) => {
- const { value, id } = props;
- const content = props.content || undefined;
- const withIcons = props.withIcons;
- const svgRef = useRef<HTMLDivElement>(null);
- const className = useClassNames(props.libClassName, props.dynamicClassName, props.className);
- useEffect(() => {
- if (content && svgRef.current) {
- svgRef.current.innerHTML = content;
- }
- }, [content]);
- const chipProps = useMemo(() => {
- const cp: Record<string, unknown> = {};
- const statusColor = status2Color(value.status);
- cp.color = statusColor;
-
- if (isSvgUrl(content)) {
- cp.avatar = (
- <Avatar src={content} data-testid="Avatar" />
- );
- }
-
- else if(content && isInlineSvg(content)){
- cp.avatar = (
- <Avatar
- sx={defaultAvatarSx}
- data-testid="Avatar"
- >
- <div
- ref={svgRef}
- style={defaultAvatarStyle}
- />
- </Avatar>
- );
- }
- else {
- cp.avatar = (
- <Avatar
- sx={{
- bgcolor: withIcons
- ? 'transparent'
- : `${statusColor}.main`,
- color: `${statusColor}.contrastText`,
- ...baseStyles
- }}
- data-testid="Avatar"
- >
- {GetStatusIcon(value.status, withIcons)}
- </Avatar>
- );
- }
- if (props.onClose) {
- cp.onDelete = props.onClose;
- }
- if (props.icon) {
- cp.deleteIcon = props.icon;
- }
- return cp;
- }, [value.status, props.onClose, props.icon, withIcons, content]);
- return <Chip id={id} variant="outlined" {...chipProps} label={value.message} sx={chipSx} className={className} />;
- };
- export default Status;
|