diff --git a/platform/ui-next/src/_pages/patterns-measurements.tsx b/platform/ui-next/src/_pages/patterns-measurements.tsx new file mode 100644 index 00000000000..7aefa478bc0 --- /dev/null +++ b/platform/ui-next/src/_pages/patterns-measurements.tsx @@ -0,0 +1,165 @@ +// src/_pages/patterns.tsx + +import React, { useState } from 'react'; +import { createRoot } from 'react-dom/client'; +import '../tailwind.css'; + +import { Button } from '../components/Button'; +import { + Select, + SelectGroup, + SelectValue, + SelectTrigger, + SelectContent, + SelectLabel, + SelectItem, + SelectSeparator, + SelectScrollUpButton, + SelectScrollDownButton, +} from '../components/Select'; +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuLabel, + DropdownMenuSub, + DropdownMenuSubTrigger, + DropdownMenuSubContent, + DropdownMenuPortal, +} from '../components/DropdownMenu'; +import { Icons } from '../components/Icons/Icons'; +import DataRow from '../_prototypes/DataRow/DataRow'; +import dataList from '../_prototypes/DataRow/dataList.json'; +import actionOptionsMap from '../_prototypes/DataRow/actionOptionsMap'; +import { + Accordion, + AccordionItem, + AccordionTrigger, + AccordionContent, +} from '../components/Accordion/Accordion'; +import { Slider } from '../components/Slider'; +import { Switch } from '../components/Switch'; +import { Label } from '../components/Label'; +import { Input } from '../components/Input'; +import { Tabs, TabsList, TabsTrigger, TabsContent } from '../components/Tabs'; + +import { ChevronDownIcon } from '@radix-ui/react-icons'; // Ensure ChevronDownIcon is imported + +interface DataItem { + id: number; + title: string; + description: string; + optionalField?: string; + colorHex?: string; + details?: string; +} + +interface ListGroup { + type: string; + items: DataItem[]; +} + +function Patterns() { + // State to track the selected row ID + const [selectedRowId, setSelectedRowId] = useState(null); + + // Handle actions from DataRow + const handleAction = (id: string, action: string) => { + console.log(`Action "${action}" triggered for item with id: ${id}`); + // Implement actual action logic here + }; + + // Handle row selection + const handleRowSelect = (id: string) => { + setSelectedRowId(prevSelectedId => (prevSelectedId === id ? null : id)); + }; + + // Find the "Organ Segmentation" list group + const organSegmentationGroup = dataList.find( + (listGroup: ListGroup) => listGroup.type === 'Organ Segmentation' + ); + + // Find the "ROI Tools" list group + const roiToolsGroup = dataList.find((listGroup: ListGroup) => listGroup.type === 'ROI Tools'); + + if (!organSegmentationGroup) { + return
Organ Segmentation data not found.
; + } + + return ( +
+ {/* Simulated Panel List for "Segmentation" */} +
+ + {/* Segmentation Tools */} + + + Measurements + + +
+
+ + +
+ +
+
+ {roiToolsGroup.items.map((item, index) => { + const compositeId = `${roiToolsGroup.type}-${item.id}-panel`; // Ensure unique composite ID + return ( + handleAction(compositeId, action)} + isSelected={selectedRowId === compositeId} + onSelect={() => handleRowSelect(compositeId)} + /> + ); + })} +
+
+
+ {/* + + + Additional Findings + + +
+
+
+ */} +
+
+
+ ); +} + +const container = document.getElementById('root'); +const root = createRoot(container!); +root.render(); diff --git a/platform/ui-next/src/_pages/patterns-backup.tsx b/platform/ui-next/src/_pages/patterns-panelsplit.tsx similarity index 100% rename from platform/ui-next/src/_pages/patterns-backup.tsx rename to platform/ui-next/src/_pages/patterns-panelsplit.tsx diff --git a/platform/ui-next/src/_pages/patterns-segmentations.tsx b/platform/ui-next/src/_pages/patterns-segmentations.tsx new file mode 100644 index 00000000000..52613293ea9 --- /dev/null +++ b/platform/ui-next/src/_pages/patterns-segmentations.tsx @@ -0,0 +1,252 @@ +// src/_pages/patterns.tsx + +import React, { useState } from 'react'; +import { createRoot } from 'react-dom/client'; +import '../tailwind.css'; + +import { Button } from '../components/Button'; +import { + Select, + SelectGroup, + SelectValue, + SelectTrigger, + SelectContent, + SelectLabel, + SelectItem, + SelectSeparator, + SelectScrollUpButton, + SelectScrollDownButton, +} from '../components/Select'; +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuLabel, + DropdownMenuSub, + DropdownMenuSubTrigger, + DropdownMenuSubContent, + DropdownMenuPortal, +} from '../components/DropdownMenu'; +import { Icons } from '../components/Icons/Icons'; +import DataRow from '../_prototypes/DataRow/DataRow'; +import dataList from '../_prototypes/DataRow/dataList.json'; +import actionOptionsMap from '../_prototypes/DataRow/actionOptionsMap'; +import { + Accordion, + AccordionItem, + AccordionTrigger, + AccordionContent, +} from '../components/Accordion/Accordion'; +import { Slider } from '../components/Slider'; +import { Switch } from '../components/Switch'; +import { Label } from '../components/Label'; +import { Input } from '../components/Input'; +import { Tabs, TabsList, TabsTrigger, TabsContent } from '../components/Tabs'; + +import { ChevronDownIcon } from '@radix-ui/react-icons'; // Ensure ChevronDownIcon is imported + +interface DataItem { + id: number; + title: string; + description: string; + optionalField?: string; + colorHex?: string; + details?: string; +} + +interface ListGroup { + type: string; + items: DataItem[]; +} + +function Patterns() { + // State to track the selected row ID + const [selectedRowId, setSelectedRowId] = useState(null); + + // Handle actions from DataRow + const handleAction = (id: string, action: string) => { + console.log(`Action "${action}" triggered for item with id: ${id}`); + // Implement actual action logic here + }; + + // Handle row selection + const handleRowSelect = (id: string) => { + setSelectedRowId(prevSelectedId => (prevSelectedId === id ? null : id)); + }; + + // Find the "Organ Segmentation" list group + const organSegmentationGroup = dataList.find( + (listGroup: ListGroup) => listGroup.type === 'Organ Segmentation' + ); + + if (!organSegmentationGroup) { + return
Organ Segmentation data not found.
; + } + + return ( +
+ {/* Simulated Panel List for "Segmentation" */} +
+ + {/* Segmentation Tools */} + + + Segmentation Tools + + +
+
+
+ + + Segmentation List + + +
+
+ + + + + + Create New Segmentation + + Current Segmentation + Rename + Delete + + Export + + + Export DICOM SEG + Download DICOM SEG + Download DICOM RTSTRUCT + + + + + + + +
+ + + Appearance Settings + + +
+
+ + + +
+
+ + + +
+
+ + +
+
+ + +
+
+
+
+ +
+ + +
+
+
+ {organSegmentationGroup.items.map((item, index) => { + const compositeId = `${organSegmentationGroup.type}-${item.id}-panel`; // Ensure unique composite ID + return ( + handleAction(compositeId, action)} + isSelected={selectedRowId === compositeId} + onSelect={() => handleRowSelect(compositeId)} + /> + ); + })} +
+
+
+
+
+
+ ); +} + +const container = document.getElementById('root'); +const root = createRoot(container!); +root.render(); diff --git a/platform/ui-next/src/_pages/patterns.tsx b/platform/ui-next/src/_pages/patterns.tsx index a41482ddab9..8ff377a95b5 100644 --- a/platform/ui-next/src/_pages/patterns.tsx +++ b/platform/ui-next/src/_pages/patterns.tsx @@ -4,9 +4,48 @@ import React, { useState } from 'react'; import { createRoot } from 'react-dom/client'; import '../tailwind.css'; +import { Button } from '../components/Button'; +import { + Select, + SelectGroup, + SelectValue, + SelectTrigger, + SelectContent, + SelectLabel, + SelectItem, + SelectSeparator, + SelectScrollUpButton, + SelectScrollDownButton, +} from '../components/Select'; +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuLabel, + DropdownMenuSub, + DropdownMenuSubTrigger, + DropdownMenuSubContent, + DropdownMenuPortal, +} from '../components/DropdownMenu'; +import { Icons } from '../components/Icons/Icons'; import DataRow from '../_prototypes/DataRow/DataRow'; import dataList from '../_prototypes/DataRow/dataList.json'; import actionOptionsMap from '../_prototypes/DataRow/actionOptionsMap'; +import { + Accordion, + AccordionItem, + AccordionTrigger, + AccordionContent, +} from '../components/Accordion/Accordion'; +import { Slider } from '../components/Slider'; +import { Switch } from '../components/Switch'; +import { Label } from '../components/Label'; +import { Input } from '../components/Input'; +import { Tabs, TabsList, TabsTrigger, TabsContent } from '../components/Tabs'; + +import { ChevronDownIcon } from '@radix-ui/react-icons'; // Ensure ChevronDownIcon is imported interface DataItem { id: number; @@ -24,7 +63,7 @@ interface ListGroup { function Patterns() { // State to track the selected row ID - const [selectedRowId, setSelectedRowId] = useState(null); // Changed to string for composite ID + const [selectedRowId, setSelectedRowId] = useState(null); // Handle actions from DataRow const handleAction = (id: string, action: string) => { @@ -37,58 +76,155 @@ function Patterns() { setSelectedRowId(prevSelectedId => (prevSelectedId === id ? null : id)); }; - return ( -
-
Patterns Page
- - {/* Iterate over each list group */} - {dataList.map((listGroup: ListGroup, groupIndex: number) => ( -
- {/* List Group Title */} -

{listGroup.type}

+ // Find the "Organ Segmentation" list group + const organSegmentationGroup = dataList.find( + (listGroup: ListGroup) => listGroup.type === 'Organ Segmentation' + ); - {/* Container for DataRow components */} -
- {listGroup.items.map((item, index) => { - const compositeId = `${item.type}-${item.id}`; // Ensure 'type' is present in DataItem if needed - return ( - handleAction(compositeId, action)} - isSelected={selectedRowId === compositeId} - onSelect={() => handleRowSelect(compositeId)} - /> - ); - })} -
-
- ))} + if (!organSegmentationGroup) { + return
Organ Segmentation data not found.
; + } - {/* New 250px Wide Panel */} -
-
- {dataList.map((listGroup: ListGroup, groupIndex: number) => ( -
- {/* List Group Title */} -

{listGroup.type}

+ return ( +
+ {/* Simulated Panel List for "Segmentation" */} +
+ + {/* Segmentation Tools */} + + + Segmentation Tools + + +
+
+
+ + + Segmentation List + + +
+
+ + + + + + Create New Segmentation + + Current Segmentation + Rename + Delete + + Export + + + Export DICOM SEG + Download DICOM SEG + Download DICOM RTSTRUCT + + + + + + + +
+ + + Appearance Settings + + +
+
+ + + +
+
+ + + +
+
+ + +
+
+ + +
+
+
+
- {/* Container for DataRow components */} +
+ + +
+
- {listGroup.items.map((item, index) => { - const compositeId = `${item.type}-${item.id}-panel`; // Unique composite ID for panel + {organSegmentationGroup.items.map((item, index) => { + const compositeId = `${organSegmentationGroup.type}-${item.id}-panel`; // Ensure unique composite ID return ( handleAction(compositeId, action)} isSelected={selectedRowId === compositeId} onSelect={() => handleRowSelect(compositeId)} @@ -106,9 +242,9 @@ function Patterns() { ); })}
-
- ))} -
+ + +
); diff --git a/platform/ui-next/src/_pages/playground.tsx b/platform/ui-next/src/_pages/playground.tsx index 44c1d252e04..5cac2e10d25 100644 --- a/platform/ui-next/src/_pages/playground.tsx +++ b/platform/ui-next/src/_pages/playground.tsx @@ -374,6 +374,20 @@ export default function Playground() {
+

Accordion

+
+
+
+ +
+
+
+

Scroll Area

diff --git a/platform/ui-next/src/components/Accordion/Accordion.tsx b/platform/ui-next/src/components/Accordion/Accordion.tsx index 76a0b92b366..bc9d7c2dcfb 100644 --- a/platform/ui-next/src/components/Accordion/Accordion.tsx +++ b/platform/ui-next/src/components/Accordion/Accordion.tsx @@ -36,7 +36,7 @@ const AccordionTrigger = React.forwardRef< {...props} > {children} - + )); diff --git a/platform/ui-next/src/components/DropdownMenu/DropdownMenu.tsx b/platform/ui-next/src/components/DropdownMenu/DropdownMenu.tsx index a4f57aaceae..377c18d9080 100644 --- a/platform/ui-next/src/components/DropdownMenu/DropdownMenu.tsx +++ b/platform/ui-next/src/components/DropdownMenu/DropdownMenu.tsx @@ -142,7 +142,7 @@ const DropdownMenuLabel = React.forwardRef< >(({ className, inset, ...props }, ref) => ( )); @@ -154,7 +154,7 @@ const DropdownMenuSeparator = React.forwardRef< >(({ className, ...props }, ref) => ( )); diff --git a/platform/ui-next/src/components/Icons/Icons.tsx b/platform/ui-next/src/components/Icons/Icons.tsx index ec3aa6d6215..dec47efc56b 100644 --- a/platform/ui-next/src/components/Icons/Icons.tsx +++ b/platform/ui-next/src/components/Icons/Icons.tsx @@ -5,6 +5,51 @@ type IconProps = React.HTMLAttributes; export const Icons = { // Usage example: + Add: (props: IconProps) => ( + + + + + + + + + + ), ChevronClosed: (props: IconProps) => ( ), + Controls: (props: IconProps) => ( + + + + + + + + + + + + + + + + ), Download: (props: IconProps) => ( ), + Hide: (props: IconProps) => ( + + + + + + + + ), + Info: (props: IconProps) => ( + + + + + + + + + + ), ListView: (props: IconProps) => ( ), + Actions: (props: IconProps) => ( + + + + + + + + + + ), PinFill: (props: IconProps) => (