From 81f5f06e876d32a1ba09f15afe45444acd41aa63 Mon Sep 17 00:00:00 2001 From: John Phan Date: Fri, 3 Jan 2025 10:53:29 -0800 Subject: [PATCH] 35423 Add Results tab to Generic Molecular Analysis - Implemented Action button and column --- packages/common-ui/lib/index.ts | 1 + .../lib/settings-button/SettingsButton.css | 59 +++++++++++++++++++ .../lib/settings-button/SettingsButton.tsx | 49 +++++++++++++++ packages/common-ui/lib/table/react-table.css | 1 - .../SplitMaterialSampleDropdownButton.tsx | 8 ++- .../useMolecularAnalysisRun.tsx | 54 ++++++++++++++++- 6 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 packages/common-ui/lib/settings-button/SettingsButton.css create mode 100644 packages/common-ui/lib/settings-button/SettingsButton.tsx diff --git a/packages/common-ui/lib/index.ts b/packages/common-ui/lib/index.ts index 63c781df6d..9976e489eb 100644 --- a/packages/common-ui/lib/index.ts +++ b/packages/common-ui/lib/index.ts @@ -123,3 +123,4 @@ export * from "./instance/useInstanceContext"; export * from "./label/FieldLabel"; export * from "./visibility/useIsVisible"; export * from "./table/ScientificNameCell"; +export * from "./settings-button/SettingsButton"; diff --git a/packages/common-ui/lib/settings-button/SettingsButton.css b/packages/common-ui/lib/settings-button/SettingsButton.css new file mode 100644 index 0000000000..23a836ebea --- /dev/null +++ b/packages/common-ui/lib/settings-button/SettingsButton.css @@ -0,0 +1,59 @@ +/* SettingsButton Container */ +.settings-button-container { + position: relative; /* Make this the positioning context for the dropdown menu */ + display: flex; + justify-content: center; /* Center horizontally */ + align-items: center; /* Center vertically */ + height: 100%; /* Ensures full height for proper vertical alignment */ +} + +.settings-container { + position: relative; + display: inline-block; +} + +/* SettingsButton */ +.settings-button { + border: none; + cursor: pointer; + font-size: 20px; + background: grey; /* Grey background */ + color: white; /* White ellipsis */ + border-radius: 5px; /* Round borders */ +} + +.settings-button:focus { + outline: none; +} + +.settings-button:hover { + background: darkgray; /* Color change on hover */ +} + +/* SettingsButton menu*/ +.settings-dropdown-menu { + position: absolute; + background: white; + border: 1px solid #ccc; + border-radius: 4px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + z-index: 9500; + margin-top: 4px; /* Slight gap below the button */ + width: 12rem; +} + +/* SettingsButton dropdown item*/ +.settings-dropdown-item { + display: block; + width: 100%; + padding: 8px 16px; + text-align: left; + background: none; + border: none; + cursor: pointer; + z-index: 9500; +} + +.settings-dropdown-item:hover { + background: #f0f0f0; +} diff --git a/packages/common-ui/lib/settings-button/SettingsButton.tsx b/packages/common-ui/lib/settings-button/SettingsButton.tsx new file mode 100644 index 0000000000..a496c53214 --- /dev/null +++ b/packages/common-ui/lib/settings-button/SettingsButton.tsx @@ -0,0 +1,49 @@ +import React, { useState, useRef } from "react"; +import "./SettingsButton.css"; // For styling + +interface SettingsButtonProps { + menuItems: JSX.Element[]; +} + +export function SettingsButton({ menuItems }: SettingsButtonProps) { + const [menuOpen, setMenuOpen] = useState(false); + const menuRef = useRef(null); + + // Close the menu if clicked outside + const handleClickOutside = (event) => { + if (menuRef.current && !menuRef.current.contains(event.target)) { + setMenuOpen(false); + } + }; + + React.useEffect(() => { + document.addEventListener("mousedown", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, []); + + return ( +
+ + {menuOpen && ( +
+ {menuItems.map((element, index) => { + return ( +
+ {element} +
+ ); + })} +
+ )} +
+ ); +} + +export default SettingsButton; diff --git a/packages/common-ui/lib/table/react-table.css b/packages/common-ui/lib/table/react-table.css index f5dcff552e..e3dc2b88ef 100644 --- a/packages/common-ui/lib/table/react-table.css +++ b/packages/common-ui/lib/table/react-table.css @@ -36,7 +36,6 @@ .ReactTable td { text-overflow: ellipsis; padding: 7px 5px; - overflow: hidden; transition: 0.3s ease; transition-property: width, min-width, padding, opacity; white-space: normal; diff --git a/packages/dina-ui/components/collection/material-sample/SplitMaterialSampleDropdownButton.tsx b/packages/dina-ui/components/collection/material-sample/SplitMaterialSampleDropdownButton.tsx index af190c410e..3c0092b410 100644 --- a/packages/dina-ui/components/collection/material-sample/SplitMaterialSampleDropdownButton.tsx +++ b/packages/dina-ui/components/collection/material-sample/SplitMaterialSampleDropdownButton.tsx @@ -4,7 +4,7 @@ import { writeStorage } from "@rehooks/local-storage"; import { BULK_SPLIT_IDS, Tooltip, useAccount, useQuery } from "common-ui"; import Dropdown from "react-bootstrap/Dropdown"; import Select from "react-select"; -import React, { useState } from "react"; +import React, { CSSProperties, useState } from "react"; import Button from "react-bootstrap/Button"; import { SplitConfiguration } from "../../../types/collection-api/resources/SplitConfiguration"; @@ -26,13 +26,15 @@ interface SplitMaterialSampleDropdownButtonProps { disabled: boolean; materialSampleType?: string; className?: string; + style?: CSSProperties; } export function SplitMaterialSampleDropdownButton({ ids, disabled, materialSampleType, - className + className, + style }: SplitMaterialSampleDropdownButtonProps) { const router = useRouter(); const { groupNames, username } = useAccount(); @@ -157,7 +159,7 @@ export function SplitMaterialSampleDropdownButton({ /> ) : ( - + diff --git a/packages/dina-ui/components/molecular-analysis/useMolecularAnalysisRun.tsx b/packages/dina-ui/components/molecular-analysis/useMolecularAnalysisRun.tsx index 96eac70e8b..1f8395d7fe 100644 --- a/packages/dina-ui/components/molecular-analysis/useMolecularAnalysisRun.tsx +++ b/packages/dina-ui/components/molecular-analysis/useMolecularAnalysisRun.tsx @@ -9,9 +9,12 @@ import { } from "react"; import { BulkGetOptions, + DeleteButton, + EditButton, FieldHeader, filterBy, SaveArgs, + SettingsButton, useApiClient, useQuery, useStringComparator @@ -36,6 +39,7 @@ import { } from "./useMetagenomicsWorkflowMolecularAnalysisRun"; import { QualityControl } from "packages/dina-ui/types/seqdb-api/resources/QualityControl"; import useVocabularyOptions from "../collection/useVocabularyOptions"; +import { SplitMaterialSampleDropdownButton } from "../collection/material-sample/SplitMaterialSampleDropdownButton"; export interface UseMolecularAnalysisRunProps { seqBatchId: string; @@ -861,6 +865,7 @@ export function getMolecularAnalysisRunColumns( >, readOnly?: boolean ) { + const { save } = useApiClient(); // Table columns to display for the sequencing run. const SEQ_REACTION_COLUMNS: ColumnDef[] = [ { @@ -1195,7 +1200,54 @@ export function getMolecularAnalysisRunColumns( { id: "action", cell: ({ row: { original } }) => { - return <>; + return ( +
+ , + , + { + // Delete storageUnitUsage if there is one linked + if (original.storageUnitUsage?.id) { + await save( + [ + { + delete: { + id: original.storageUnitUsage?.id ?? null, + type: "storage-unit-usage" + } + } + ], + { + apiBaseUrl: "/collection-api" + } + ); + } + }} + /> + ]} + /> +
+ ); }, header: () => , accessorKey: "action",