소스 검색

feat(frontend): show client comments on mobile cards (#5942)

* feat(frontend): show client comments on mobile cards

* fix(frontend): bound mobile comment height

---------

Co-authored-by: sanmaxdev <[email protected]>
Sangeeth Thilakarathna 8 시간 전
부모
커밋
658e6ab3d3

+ 14 - 0
frontend/src/components/clients/ClientCardComment.tsx

@@ -0,0 +1,14 @@
+type ClientCardCommentProps = {
+  comment?: string;
+  className?: string;
+};
+
+export default function ClientCardComment({ comment, className = 'client-card-comment' }: ClientCardCommentProps) {
+  if (!comment) return null;
+
+  return (
+    <span className={className} title={comment}>
+      {comment}
+    </span>
+  );
+}

+ 11 - 0
frontend/src/pages/clients/ClientsPage.css

@@ -162,6 +162,17 @@
   background: color-mix(in srgb, var(--ant-color-primary) 6%, transparent);
 }
 
+.client-card-comment {
+  display: block;
+  margin-top: 6px;
+  color: var(--ant-color-text-secondary);
+  font-size: 12px;
+  max-height: 4.5em;
+  overflow-y: auto;
+  overflow-wrap: anywhere;
+  white-space: pre-wrap;
+}
+
 .client-card-speed {
   margin-top: 6px;
   font-size: 12px;

+ 3 - 1
frontend/src/pages/clients/ClientsPage.tsx

@@ -62,6 +62,7 @@ import { useDatepicker } from '@/hooks/useDatepicker';
 import type { ClientRecord, InboundOption, ExternalLink, ExternalLinkInput } from '@/hooks/useClients';
 import ClientTrafficCell from '@/components/clients/ClientTrafficCell';
 import ClientSpeedTag, { isActiveSpeed } from '@/components/clients/ClientSpeedTag';
+import ClientCardComment from '@/components/clients/ClientCardComment';
 import AppSidebar from '@/layouts/AppSidebar';
 import { IntlUtil, SizeFormatter } from '@/utils';
 import { setMessageInstance } from '@/utils/messageBus';
@@ -818,7 +819,7 @@ export default function ClientsPage() {
         <div className="email-cell">
           <span className="email">{record.email}</span>
           {record.subId && <span className="sub" title={record.subId}>{record.subId}</span>}
-          {record.comment && <span className="sub" title={record.comment}>{record.comment}</span>}
+          <ClientCardComment comment={record.comment} className="sub" />
         </div>
       ),
     },
@@ -1433,6 +1434,7 @@ export default function ClientsPage() {
                                       </Dropdown>
                                     </div>
                                   </div>
+                                  <ClientCardComment comment={row.comment} />
                                   <ClientTrafficCell
                                     compact
                                     up={row.traffic?.up}

+ 27 - 0
frontend/src/test/client-card-comment.test.tsx

@@ -0,0 +1,27 @@
+import { render, screen } from '@testing-library/react';
+import { describe, expect, it } from 'vitest';
+
+import ClientCardComment from '@/components/clients/ClientCardComment';
+
+describe('ClientCardComment', () => {
+  it('renders a client comment in the card', () => {
+    render(<ClientCardComment comment={'Primary mobile client\nLine two'} />);
+
+    const comment = screen.getByText(/Primary mobile client/);
+    expect(comment.className).toContain('client-card-comment');
+    expect(comment.textContent).toBe('Primary mobile client\nLine two');
+    expect(comment.getAttribute('title')).toBe('Primary mobile client\nLine two');
+  });
+
+  it('supports the compact desktop style', () => {
+    render(<ClientCardComment comment="Desktop comment" className="sub" />);
+
+    expect(screen.getByText('Desktop comment').className).toBe('sub');
+  });
+
+  it('renders nothing when no comment is set', () => {
+    const { container } = render(<ClientCardComment comment="" />);
+
+    expect(container.childElementCount).toBe(0);
+  });
+});