Skip to content

Commit cca25e2

Browse files
fix(dashboard): Multiple style & functionality fixes
1 parent 17c27ff commit cca25e2

File tree

15 files changed

+683
-144
lines changed

15 files changed

+683
-144
lines changed

packages/dashboard/src/app/routes/_authenticated/_orders/components/order-history/order-history.tsx

Lines changed: 399 additions & 33 deletions
Large diffs are not rendered by default.

packages/dashboard/src/lib/components/data-input/rich-text-input.tsx

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import { BubbleMenu, Editor, EditorContent, useCurrentEditor, useEditor } from '@tiptap/react';
2-
import StarterKit from '@tiptap/starter-kit';
3-
import ListItem from '@tiptap/extension-list-item';
41
import TextStyle from '@tiptap/extension-text-style';
2+
import { BubbleMenu, Editor, EditorContent, useEditor } from '@tiptap/react';
3+
import StarterKit from '@tiptap/starter-kit';
54
import { BoldIcon, ItalicIcon, StrikethroughIcon } from 'lucide-react';
6-
import { useEffect, useLayoutEffect } from 'react';
5+
import { useLayoutEffect, useRef } from 'react';
76
import { Button } from '../ui/button.js';
87

98
// define your extension array
@@ -27,13 +26,16 @@ export interface RichTextInputProps {
2726
}
2827

2928
export function RichTextInput({ value, onChange }: Readonly<RichTextInputProps>) {
29+
const isInternalUpdate = useRef(false);
30+
3031
const editor = useEditor({
3132
parseOptions: {
3233
preserveWhitespace: 'full',
3334
},
3435
extensions: extensions,
3536
content: value,
3637
onUpdate: ({ editor }) => {
38+
isInternalUpdate.current = true;
3739
onChange(editor.getHTML());
3840
},
3941
editorProps: {
@@ -44,11 +46,15 @@ export function RichTextInput({ value, onChange }: Readonly<RichTextInputProps>)
4446
});
4547

4648
useLayoutEffect(() => {
47-
if (editor) {
48-
const { from, to } = editor.state.selection;
49-
editor.commands.setContent(value, false);
50-
editor.commands.setTextSelection({ from, to });
49+
if (editor && !isInternalUpdate.current) {
50+
const currentContent = editor.getHTML();
51+
if (currentContent !== value) {
52+
const { from, to } = editor.state.selection;
53+
editor.commands.setContent(value, false);
54+
editor.commands.setTextSelection({ from, to });
55+
}
5156
}
57+
isInternalUpdate.current = false;
5258
}, [value, editor]);
5359

5460
if (!editor) {

packages/dashboard/src/lib/components/data-table/data-table-bulk-actions.tsx

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
} from '@/vdb/components/ui/dropdown-menu.js';
1010
import { getBulkActions } from '@/vdb/framework/data-table/data-table-extensions.js';
1111
import { BulkAction } from '@/vdb/framework/extension-api/types/index.js';
12+
import { useFloatingBulkActions } from '@/vdb/hooks/use-floating-bulk-actions.js';
1213
import { usePageBlock } from '@/vdb/hooks/use-page-block.js';
1314
import { usePage } from '@/vdb/hooks/use-page.js';
1415
import { Trans } from '@/vdb/lib/trans.js';
@@ -26,7 +27,8 @@ export function DataTableBulkActions<TData>({
2627
bulkActions,
2728
}: Readonly<DataTableBulkActionsProps<TData>>) {
2829
const { pageId } = usePage();
29-
const { blockId } = usePageBlock();
30+
const pageBlock = usePageBlock();
31+
const blockId = pageBlock?.blockId;
3032

3133
// Cache to store selected items across page changes
3234
const selectedItemsCache = useRef<Map<string, TData>>(new Map());
@@ -52,7 +54,13 @@ export function DataTableBulkActions<TData>({
5254
})
5355
.filter((item): item is TData => item !== undefined);
5456

55-
if (selection.length === 0) {
57+
const { position, shouldShow } = useFloatingBulkActions({
58+
selectionCount: selection.length,
59+
containerSelector: '[data-table-root], .data-table-container, table',
60+
bottomOffset: 40,
61+
});
62+
63+
if (!shouldShow) {
5664
return null;
5765
}
5866
const extendedBulkActions = pageId ? getBulkActions(pageId, blockId) : [];
@@ -61,8 +69,13 @@ export function DataTableBulkActions<TData>({
6169

6270
return (
6371
<div
64-
className="flex items-center gap-4 px-8 py-2 animate-in fade-in duration-200 absolute bottom-10 left-1/2 transform -translate-x-1/2 bg-white shadow-2xl rounded-md border"
65-
style={{ height: 'auto', maxHeight: '60px' }}
72+
className="flex items-center gap-4 px-8 py-2 animate-in fade-in duration-200 fixed transform -translate-x-1/2 bg-white shadow-2xl rounded-md border z-50"
73+
style={{
74+
height: 'auto',
75+
maxHeight: '60px',
76+
bottom: position.bottom,
77+
left: position.left
78+
}}
6679
>
6780
<span className="text-sm text-muted-foreground">
6881
<Trans>{selection.length} selected</Trans>

packages/dashboard/src/lib/components/layout/nav-main.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ export function NavMain({ items }: Readonly<{ items: Array<NavMenuSection | NavM
150150
const renderBottomSection = (item: NavMenuSection | NavMenuItem) => {
151151
if ('url' in item) {
152152
return (
153-
<NavItemWrapper key={item.title} locationId={item.id} order={item.order}>
153+
<NavItemWrapper key={item.title} locationId={item.id} order={item.order} offset={true}>
154154
<SidebarMenuItem>
155155
<SidebarMenuButton
156156
tooltip={item.title}
@@ -167,7 +167,7 @@ export function NavMain({ items }: Readonly<{ items: Array<NavMenuSection | NavM
167167
);
168168
}
169169
return (
170-
<NavItemWrapper key={item.title} locationId={item.id} order={item.order}>
170+
<NavItemWrapper key={item.title} locationId={item.id} order={item.order} offset={true}>
171171
<Collapsible
172172
asChild
173173
open={openBottomSectionId === item.id}
@@ -218,7 +218,6 @@ export function NavMain({ items }: Readonly<{ items: Array<NavMenuSection | NavM
218218
<>
219219
{/* Top sections */}
220220
<SidebarGroup>
221-
<SidebarGroupLabel>Platform</SidebarGroupLabel>
222221
<SidebarMenu>{topSections.map(renderTopSection)}</SidebarMenu>
223222
</SidebarGroup>
224223

packages/dashboard/src/lib/components/shared/asset/asset-bulk-actions.tsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
DropdownMenuTrigger,
99
} from '@/vdb/components/ui/dropdown-menu.js';
1010
import { getBulkActions } from '@/vdb/framework/data-table/data-table-extensions.js';
11+
import { useFloatingBulkActions } from '@/vdb/hooks/use-floating-bulk-actions.js';
1112
import { usePageBlock } from '@/vdb/hooks/use-page-block.js';
1213
import { usePage } from '@/vdb/hooks/use-page.js';
1314
import { Trans } from '@/vdb/lib/trans.js';
@@ -34,9 +35,15 @@ interface AssetBulkActionsProps {
3435

3536
export function AssetBulkActions({ selection, bulkActions, refetch }: Readonly<AssetBulkActionsProps>) {
3637
const { pageId } = usePage();
37-
const { blockId } = usePageBlock();
38+
const pageBlock = usePageBlock();
39+
const blockId = pageBlock?.blockId;
40+
41+
const { position, shouldShow } = useFloatingBulkActions({
42+
selectionCount: selection.length,
43+
containerSelector: '[data-asset-gallery]'
44+
});
3845

39-
if (selection.length === 0) {
46+
if (!shouldShow) {
4047
return null;
4148
}
4249

@@ -62,13 +69,21 @@ export function AssetBulkActions({ selection, bulkActions, refetch }: Readonly<A
6269
allBulkActions.sort((a, b) => (a.order ?? 10_000) - (b.order ?? 10_000));
6370

6471
return (
65-
<div className="flex items-center gap-2 px-2 py-1 mb-2 bg-muted/50 rounded-md border">
72+
<div
73+
className="flex items-center gap-4 px-8 py-2 animate-in fade-in duration-200 fixed transform -translate-x-1/2 bg-white shadow-2xl rounded-md border z-50"
74+
style={{
75+
height: 'auto',
76+
maxHeight: '60px',
77+
bottom: position.bottom,
78+
left: position.left
79+
}}
80+
>
6681
<span className="text-sm text-muted-foreground">
6782
<Trans>{selection.length} selected</Trans>
6883
</span>
6984
<DropdownMenu>
7085
<DropdownMenuTrigger asChild>
71-
<Button variant="outline" size="sm" className="h-8">
86+
<Button variant="outline" size="sm" className="h-8 shadow-none">
7287
<Trans>With selected...</Trans>
7388
<ChevronDown className="ml-2 h-4 w-4" />
7489
</Button>

packages/dashboard/src/lib/components/shared/asset/asset-gallery.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ export function AssetGallery({
232232
};
233233

234234
return (
235-
<div className={`flex flex-col w-full ${fixedHeight ? 'h-[600px]' : ''} ${className}`}>
235+
<div className={`relative flex flex-col w-full ${fixedHeight ? 'h-[600px]' : ''} ${className}`}>
236236
{showHeader && (
237237
<div className="flex flex-col md:flex-row gap-2 mb-4 flex-shrink-0">
238238
<div className="relative flex-grow flex items-center gap-2">
@@ -291,7 +291,7 @@ export function AssetGallery({
291291
</div>
292292
)}
293293

294-
<div className="grid grid-cols-1 xs:grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-3 p-1">
294+
<div data-asset-gallery className="grid grid-cols-1 xs:grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-3 p-1">
295295
{isLoading ? (
296296
<div className="col-span-full flex justify-center py-12">
297297
<Loader2 className="h-8 w-8 animate-spin text-primary" />
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/vdb/components/ui/tooltip.js';
2+
import { useLocalFormat } from '@/vdb/hooks/use-local-format.js';
3+
4+
interface HistoryEntryDateProps {
5+
date: string;
6+
className?: string;
7+
}
8+
9+
export function HistoryEntryDate({ date, className }: Readonly<HistoryEntryDateProps>) {
10+
const { formatRelativeDate, formatDate } = useLocalFormat();
11+
12+
const formatFullDateTime = (dateString: string) => {
13+
return formatDate(dateString, {
14+
year: 'numeric',
15+
month: 'long',
16+
day: 'numeric',
17+
hour: 'numeric',
18+
minute: 'numeric',
19+
second: 'numeric',
20+
});
21+
};
22+
23+
return (
24+
<TooltipProvider>
25+
<Tooltip>
26+
<TooltipTrigger asChild>
27+
<div className={className}>
28+
{formatRelativeDate(date)}
29+
</div>
30+
</TooltipTrigger>
31+
<TooltipContent>
32+
<p>{formatFullDateTime(date)}</p>
33+
</TooltipContent>
34+
</Tooltip>
35+
</TooltipProvider>
36+
);
37+
}

0 commit comments

Comments
 (0)