Files
fleet/frontend/pages/ManageControlsPage/Scripts/components/ScriptListItem/ScriptListItem.tsx
T

163 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { format } from "date-fns";
import FileSaver from "file-saver";
import React, { useContext } from "react";
import { NotificationContext } from "context/notification";
import { IScript } from "interfaces/script";
import scriptAPI from "services/entities/scripts";
import Button from "components/buttons/Button";
import Icon from "components/Icon";
import ListItem from "components/ListItem";
import { ISupportedGraphicNames } from "components/ListItem/ListItem";
import GitOpsModeTooltipWrapper from "components/GitOpsModeTooltipWrapper";
import { HumanTimeDiffWithDateTip } from "components/HumanTimeDiffWithDateTip";
import TooltipTruncatedText from "components/TooltipTruncatedText";
const baseClass = "script-list-item";
interface IScriptListItemProps {
script: IScript;
onDelete: (script: IScript) => void;
onClickScript: (script: IScript) => void;
onEdit: (script: IScript) => void;
isTechnician?: boolean;
}
// TODO - useful to have a 'platform' field from API, for use elsewhere in app as well?
const getFileRenderDetails = (
fileName: string
): { graphicName: ISupportedGraphicNames; platform: string | null } => {
const fileExtension = fileName.split(".").pop();
switch (fileExtension) {
case "py":
return { graphicName: "file-py", platform: "macOS & Linux" };
case "sh":
return { graphicName: "file-sh", platform: "macOS & Linux" };
case "ps1":
return { graphicName: "file-ps1", platform: "Windows" };
default:
return { graphicName: "file-script", platform: null };
}
};
interface IScriptListItemDetailsProps {
platform: string | null;
createdAt: string;
}
const onDownload = async (script: IScript, renderFlash: any) => {
try {
const content = await scriptAPI.downloadScript(script.id);
const formatDate = format(new Date(), "yyyy-MM-dd");
const filename = `${formatDate} ${script.name}`;
const file = new File([content], filename);
FileSaver.saveAs(file);
} catch {
renderFlash("error", "Couldnt Download. Please try again.");
}
};
const ScriptListItemDetails = ({
platform,
createdAt,
}: IScriptListItemDetailsProps) => (
<div className={`${baseClass}__details`}>
{platform && (
<>
<span>{platform}</span>
<span>&bull;</span>
</>
)}
<span>
Uploaded <HumanTimeDiffWithDateTip timeString={createdAt} />
</span>
</div>
);
const ScriptListItem = ({
script,
onDelete,
onClickScript,
onEdit,
isTechnician,
}: IScriptListItemProps) => {
const { renderFlash } = useContext(NotificationContext);
const { graphicName, platform } = getFileRenderDetails(script.name);
const onClickEdit = () => {
onEdit(script);
};
const onClickDownload = () => {
onDownload(script, renderFlash);
};
const onClickDelete = () => {
onDelete(script);
};
const actions = (
<div onClick={(evt) => evt.stopPropagation()}>
<GitOpsModeTooltipWrapper
renderChildren={(disableChildren) => (
<Button
disabled={disableChildren}
onClick={onClickEdit}
className={`${baseClass}__action-button`}
variant="icon"
ariaLabel={`Edit ${script.name}`}
>
<Icon name="pencil" />
</Button>
)}
/>
<Button
className={`${baseClass}__action-button`}
variant="icon"
onClick={onClickDownload}
ariaLabel={`Download ${script.name}`}
>
<Icon name="download" />
</Button>
<GitOpsModeTooltipWrapper
renderChildren={(disableChildren) => (
<Button
disabled={disableChildren}
onClick={onClickDelete}
className={`${baseClass}__action-button`}
variant="icon"
ariaLabel={`Delete ${script.name}`}
>
<Icon name="trash" />
</Button>
)}
/>
</div>
);
return (
<ListItem
className={baseClass}
graphic={graphicName}
title={
<Button variant="link" className={`${baseClass}__title-button`}>
<TooltipTruncatedText value={script.name} fixedPositionStrategy />
</Button>
}
details={
<ScriptListItemDetails
platform={platform}
createdAt={script.created_at}
/>
}
actions={isTechnician ? undefined : actions}
onClick={() => onClickScript(script)}
/>
);
};
export default ScriptListItem;