Refactor dropdown menu components in various files to prevent event propagation, enhancing user interaction. Update CountedLineTabs component documentation with preview links for better clarity. Improve styling and layout in resource page and user columns for consistency and visual appeal.
Build and Push Telemt Panel Docker Image / build-and-push (push) Successful in 2m8s
Build and Push Telemt Panel Docker Image / create-release (push) Skipped

This commit is contained in:
Denozordec
2026-08-04 22:06:15 +07:00
parent 3c065e8de1
commit ee3e96647e
5 changed files with 115 additions and 75 deletions
+18 -3
View File
@@ -17,7 +17,11 @@ interface CountedLineTabsProps {
children?: ReactNode children?: ReactNode
} }
/** Line tabs with count pills (c-tabs-2 / data-grid-filtering-2). */ /**
* Line tabs with count pills — ReUI PRO DNA.
* Preview: https://reui.io/preview/base/components/c-tabs-2
* Lists: https://reui.io/preview/base/data-grid-filtering-2
*/
export function CountedLineTabs({ export function CountedLineTabs({
tabs, tabs,
value, value,
@@ -28,12 +32,23 @@ export function CountedLineTabs({
}: CountedLineTabsProps) { }: CountedLineTabsProps) {
return ( return (
<Tabs value={value} onValueChange={onValueChange} className={className}> <Tabs value={value} onValueChange={onValueChange} className={className}>
<TabsList variant="line" className={cn('gap-5', listClassName)}> <TabsList
variant="line"
className={cn(
'h-auto w-full justify-start gap-5 rounded-none bg-transparent p-0',
listClassName,
)}
>
{tabs.map((tab) => ( {tabs.map((tab) => (
<TabsTrigger <TabsTrigger
key={tab.id} key={tab.id}
value={tab.id} value={tab.id}
className="text-muted-foreground hover:text-foreground h-auto gap-2 px-0 pb-3 after:bottom-0" className={cn(
'text-muted-foreground hover:text-foreground h-auto flex-none gap-2 rounded-none px-0 pb-3 shadow-none',
'data-active:bg-transparent data-active:text-foreground data-active:shadow-none',
'dark:data-active:border-transparent dark:data-active:bg-transparent',
'after:bottom-0 after:bg-foreground',
)}
> >
<span>{tab.label}</span> <span>{tab.label}</span>
{tab.count !== undefined ? ( {tab.count !== undefined ? (
@@ -251,6 +251,11 @@ function RowActions({
onOpen: (row: TelemtErrorRow) => void onOpen: (row: TelemtErrorRow) => void
}) { }) {
return ( return (
<div
className="flex items-center justify-center"
onClick={(event) => event.stopPropagation()}
onPointerDown={(event) => event.stopPropagation()}
>
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger <DropdownMenuTrigger
render={ render={
@@ -271,6 +276,7 @@ function RowActions({
</DropdownMenuItem> </DropdownMenuItem>
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
</div>
) )
} }
@@ -570,14 +570,13 @@ function ResourcePageFiltered<T extends object>({
<FramePanel className="p-0 shadow-none!"> <FramePanel className="p-0 shadow-none!">
{countedTabs.length > 0 ? ( {countedTabs.length > 0 ? (
<> <>
<div className="px-(--frame-panel-header-px) pt-(--frame-panel-header-py)"> <div className="border-border flex flex-col gap-0 border-b px-(--frame-panel-header-px) pt-(--frame-panel-header-py)">
<CountedLineTabs <CountedLineTabs
tabs={countedTabs} tabs={countedTabs}
value={activeTab} value={activeTab}
onValueChange={handleTabChange} onValueChange={handleTabChange}
/> />
</div> </div>
<Separator />
</> </>
) : null} ) : null}
@@ -1269,7 +1269,21 @@ function DataGridTableBodyRow<TData>({
data-depth={row.depth || undefined} data-depth={row.depth || undefined}
data-row-pinned={isRowPinned || undefined} data-row-pinned={isRowPinned || undefined}
data-row-pinned-boundary={pinnedBoundary} data-row-pinned-boundary={pinnedBoundary}
onClick={() => props.onRowClick && props.onRowClick(row.original)} onClick={(event) => {
if (!props.onRowClick) return
// Interactive controls (actions menu, pin, checkbox, links) must not
// open the row detail — same contract as DataGridTableRowPin/Select.
const target = event.target
if (
target instanceof Element &&
target.closest(
'button, a, input, textarea, select, [role="button"], [role="menuitem"], [role="checkbox"], [data-slot="dropdown-menu-trigger"], [data-slot="checkbox"]'
)
) {
return
}
props.onRowClick(row.original)
}}
className={cn( className={cn(
"hover:bg-muted/40 data-[state=selected]:bg-muted/50", "hover:bg-muted/40 data-[state=selected]:bg-muted/50",
props.onRowClick && "cursor-pointer", props.onRowClick && "cursor-pointer",
@@ -199,6 +199,11 @@ export function ActionsCell({
return ( return (
<> <>
<div
className="flex items-center justify-center"
onClick={(event) => event.stopPropagation()}
onPointerDown={(event) => event.stopPropagation()}
>
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger <DropdownMenuTrigger
render={ render={
@@ -248,6 +253,7 @@ export function ActionsCell({
</DropdownMenuGroup> </DropdownMenuGroup>
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
</div>
<AlertDialog open={deleteOpen} onOpenChange={setDeleteOpen}> <AlertDialog open={deleteOpen} onOpenChange={setDeleteOpen}>
<AlertDialogContent size="sm"> <AlertDialogContent size="sm">