Merge pull request #83 from madhura68/feat/product-edit-icon-on-dashboard
feat(dashboard): pencil-icoon edit-trigger op product-card
This commit is contained in:
commit
70c5be6750
2 changed files with 62 additions and 5 deletions
56
__tests__/components/dashboard/product-list.test.tsx
Normal file
56
__tests__/components/dashboard/product-list.test.tsx
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
// @vitest-environment jsdom
|
||||||
|
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||||
|
import { render, screen, fireEvent } from '@testing-library/react'
|
||||||
|
|
||||||
|
const { pushMock } = vi.hoisted(() => ({ pushMock: vi.fn() }))
|
||||||
|
vi.mock('next/navigation', () => ({ useRouter: () => ({ push: pushMock, refresh: vi.fn() }) }))
|
||||||
|
vi.mock('@/actions/products', () => ({ restoreProductAction: vi.fn() }))
|
||||||
|
vi.mock('@/actions/active-product', () => ({ setActiveProductAction: vi.fn() }))
|
||||||
|
vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } }))
|
||||||
|
vi.mock('@/components/dialogs/product-dialog', () => ({
|
||||||
|
ProductDialog: ({ open }: { open: boolean }) => (open ? <div role="dialog">ProductDialog</div> : null),
|
||||||
|
}))
|
||||||
|
|
||||||
|
import { ProductList } from '@/components/dashboard/product-list'
|
||||||
|
|
||||||
|
const PRODUCT = {
|
||||||
|
id: 'p1',
|
||||||
|
name: 'Mijn Product',
|
||||||
|
code: 'MP',
|
||||||
|
description: 'Een product',
|
||||||
|
repo_url: 'https://github.com/foo/bar',
|
||||||
|
definition_of_done: 'klaar als het werkt',
|
||||||
|
auto_pr: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
pushMock.mockClear()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('ProductList — edit-icoon (todo cmoq3ox51)', () => {
|
||||||
|
it('rendert pencil-icoon (Bewerk product) op active card, geen tekstknop "Bewerken"', () => {
|
||||||
|
render(<ProductList products={[PRODUCT]} isDemo={false} activeProductId="p1" />)
|
||||||
|
expect(screen.getByLabelText('Bewerk product')).toBeTruthy()
|
||||||
|
// Oude tekstknop is weg
|
||||||
|
expect(screen.queryByText('Bewerken')).toBeNull()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('opent ProductDialog op klik (en stopt propagation zodat card-click niet navigeert)', () => {
|
||||||
|
render(<ProductList products={[PRODUCT]} isDemo={false} activeProductId="p1" />)
|
||||||
|
expect(screen.queryByRole('dialog')).toBeNull()
|
||||||
|
fireEvent.click(screen.getByLabelText('Bewerk product'))
|
||||||
|
expect(screen.getByRole('dialog')).toBeTruthy()
|
||||||
|
expect(pushMock).not.toHaveBeenCalled() // card-navigation niet getriggerd
|
||||||
|
})
|
||||||
|
|
||||||
|
it('demo-user: knop is disabled', () => {
|
||||||
|
render(<ProductList products={[PRODUCT]} isDemo={true} activeProductId="p1" />)
|
||||||
|
const btn = screen.getByLabelText('Bewerk product') as HTMLButtonElement
|
||||||
|
expect(btn.disabled).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('toont geen edit-icoon bij gearchiveerde producten', () => {
|
||||||
|
render(<ProductList products={[PRODUCT]} isDemo={false} showArchived={true} activeProductId={null} />)
|
||||||
|
expect(screen.queryByLabelText('Bewerk product')).toBeNull()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { useRouter } from 'next/navigation'
|
import { useRouter } from 'next/navigation'
|
||||||
import { useState, useTransition } from 'react'
|
import { useState, useTransition } from 'react'
|
||||||
|
import { Pencil } from 'lucide-react'
|
||||||
import { toast } from 'sonner'
|
import { toast } from 'sonner'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { Badge } from '@/components/ui/badge'
|
import { Badge } from '@/components/ui/badge'
|
||||||
|
|
@ -106,14 +107,14 @@ export function ProductList({ products, isDemo, showArchived = false, activeProd
|
||||||
{!showArchived && (
|
{!showArchived && (
|
||||||
<>
|
<>
|
||||||
<DemoTooltip show={isDemo}>
|
<DemoTooltip show={isDemo}>
|
||||||
<Button
|
<button
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={(e) => { e.stopPropagation(); if (!isDemo) setEditingProduct(product) }}
|
onClick={(e) => { e.stopPropagation(); if (!isDemo) setEditingProduct(product) }}
|
||||||
|
className="opacity-0 group-hover:opacity-100 text-muted-foreground hover:text-foreground p-0.5 rounded disabled:opacity-40 disabled:cursor-not-allowed"
|
||||||
|
aria-label="Bewerk product"
|
||||||
disabled={isDemo}
|
disabled={isDemo}
|
||||||
>
|
>
|
||||||
Bewerken
|
<Pencil size={14} />
|
||||||
</Button>
|
</button>
|
||||||
</DemoTooltip>
|
</DemoTooltip>
|
||||||
{product.id === activeProductId
|
{product.id === activeProductId
|
||||||
? <Badge className="bg-primary-container text-primary-container-foreground text-xs px-2 py-0">Actief</Badge>
|
? <Badge className="bg-primary-container text-primary-container-foreground text-xs px-2 py-0">Actief</Badge>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue