# ProjectList

> A list of projects as a table or cards with status, progress, members, lead, due date and tags, plus search, status and client and member and tag filters, bulk select, loading skeletons and an empty state.

Source: https://docs.nasaqui.com/components/project-list

## Install

```bash
npx shadcn@latest add https://docs.nasaqui.com/r/project-list.json
```

A portfolio of projects: status, progress, who works on it, the lead, when it is due and its tags. It is
`EntityList` with the columns, cards and filters set up, plus an overdue highlight on the due date.

## When to use

- A projects overview, portfolio or client project list.

## When not to use

- Tasks on a board: use [`KanbanBoard`](https://docs.nasaqui.com/components/kanban-board).
- Other records: build on [`EntityList`](https://docs.nasaqui.com/components/entity-list).

## Import

```tsx
import { ProjectList } from "@fadymondy/nasaq/web";
// inside this monorepo: "@nasaq/web"
```

## Quick start

```tsx
import { ProjectList, type Project } from "@fadymondy/nasaq/web";

const projects: Project[] = [
  { id: "1", name: "Website redesign", key: "WEB", client: "Acme", status: "active", progress: 62, dueDate: "2026-12-01", members: [{ name: "Sara Ali" }, { name: "Omar Nasser" }] },
];

export function Projects() {
  return <ProjectList projects={projects} />;
}
```

## Anatomy

`ProjectList` renders `EntityList`. Columns: name (logo, name, key and client), status, progress, members, lead
(hidden by default), due, tags (hidden by default), last activity. Facets: status, client, member, tag.

## API

`ProjectListProps` extends the `EntityList` props (`view`, `pageSize`, `selectable`, `toolbar`, `bulkActions`,
`rowActions`, `onRowClick`, `loading`, `error`, `onRetry`, `empty`, `defaultSort`, `className`).

| Prop | Type | Description |
| --- | --- | --- |
| `projects` | `Project[]` | `{ id, name, key?, logo?, client?, status, progress (0 to 100), members?, owner?, dueDate?, tags?, lastActivity? }`. |
| `label` | `string` | Accessible name. Default "Projects" / "المشاريع". |
| `labels` | `Partial<ProjectListLabels>` | Override any string, including `statuses`. |

`ProjectStatus` is `"planning" | "active" | "on-hold" | "completed" | "archived"`.

## Examples

**Cards only**

```tsx
<ProjectList projects={projects} defaultView="cards" views={["cards"]} />
```

## Accessibility

Inherited from `EntityList`. Each progress bar is named ("Progress: Website redesign") and reads its value; status is
text plus an icon, never colour alone. Overdue dates say "Overdue" in text.

## RTL & i18n

- English and Arabic strings ship, including status names. Percentages and dates follow the locale; project keys are set left-to-right.
- Progress bars fill from the inline start, so they run right to left in Arabic.

## Styling & tokens

- Status tones and progress tones come from `Status` and `Progress`. Overdue uses `text-nq-danger-text`.

## Do / Don't

- Do keep `progress` between 0 and 100.
- Don't use colour alone to tell statuses apart in your own cells; reuse `Status`.

## Related

- [`EntityList`](https://docs.nasaqui.com/components/entity-list)
- [`KanbanBoard`](https://docs.nasaqui.com/components/kanban-board)
- [`ExportButton`](https://docs.nasaqui.com/components/export-action)

## Lab

https://docs.nasaqui.com/?path=/docs/components-projects-work-project-list--docs

## Code

### React

```tsx
import { ProjectList, type Project } from "@fadymondy/nasaq/web";

const projects: Project[] = [
  { id: "1", name: "Website redesign", key: "WEB", client: "Acme", status: "active", progress: 62, dueDate: "2026-12-01", members: [{ name: "Sara Ali" }, { name: "Omar Nasser" }] },
];

export function Projects() {
  return <ProjectList projects={projects} />;
}
```

### shadcn

```tsx
import { ProjectList, type Project } from "@/components/ui/project-list";

const projects: Project[] = [
  { id: "1", name: "Website redesign", key: "WEB", client: "Acme", status: "active", progress: 62, dueDate: "2026-12-01", members: [{ name: "Sara Ali" }, { name: "Omar Nasser" }] },
];

export function Projects() {
  return <ProjectList projects={projects} />;
}
```

### Vue

```vue
<script setup lang="ts">
import { NqProjectList, type Project } from "@fadymondy/nasaq/vue";

const projects: Project[] = [
  { id: "1", name: "Website redesign", key: "WEB", client: "Acme", status: "active", progress: 62, dueDate: "2026-12-01", members: [{ name: "Sara Ali" }, { name: "Omar Nasser" }] },
];
</script>

<template>
  <NqProjectList :projects="projects" />
</template>
```

### Blade

```blade
<x-nq::project-list :projects="[
    ['id' => '1', 'name' => 'Website redesign', 'key' => 'WEB', 'client' => 'Acme', 'status' => 'active', 'progress' => 62, 'dueDate' => '2026-12-01', 'members' => [['name' => 'Sara Ali'], ['name' => 'Omar Nasser']]],
]" />
{{-- <x-nq::project-list :projects="$projects" /> Bubbling events: nq-entity-list-row-click { row } (row.id is the project id). See the component header for the projects shape and labels. --}}
```

### HTML + Alpine

```html
<div data-slot="project-list" class="min-w-0">
    <div data-slot="entity-list" x-data="nqEntityList(JSON.parse('[{\u0022nameCell\u0022:\u0022\\u003Cdiv data-slot=\\u0022entity-identity\\u0022 class=\\u0022flex min-w-0 items-center gap-3\\u0022\\u003E\\n    \\u003Cspan data-slot=\\u0022avatar\\u0022 x-data=\\u0022nqAvatar(0)\\u0022\\n    class=\\u0022inline-flex shrink-0 select-none items-center justify-center overflow-hidden bg-secondary align-middle font-medium text-secondary-foreground size-8 text-caption rounded-control\\u0022\\u003E\\n                    \\u003Cspan data-slot=\\u0022avatar-fallback\\u0022 class=\\u0022flex size-full items-center justify-center\\u0022 x-bind=\\u0022fallback\\u0022\\n             role=\\u0022img\\u0022 aria-label=\\u0022Website redesign\\u0022 \\u003EWR\\u003C\\\/span\\u003E\\n    \\u003C\\\/span\\u003E\\n    \\u003Cdiv class=\\u0022flex min-w-0 flex-col\\u0022\\u003E\\n        \\u003Cspan class=\\u0022truncate text-label text-foreground\\u0022\\u003EWebsite redesign\\u003C\\\/span\\u003E\\n        \\u003Cspan class=\\u0022truncate text-body-sm text-muted-foreground\\u0022\\u003E\\u003Cbdi dir=\\u0022ltr\\u0022\\u003EWEB\\u003C\\\/bdi\\u003E \\u00b7 Acme\\u003C\\\/span\\u003E    \\u003C\\\/div\\u003E\\n\\u003C\\\/div\\u003E\u0022,\u0022statusCell\u0022:\u0022\\u003Cspan data-slot=\\u0022status\\u0022 data-tone=\\u0022info\\u0022 class=\\u0022inline-flex min-w-0 items-center gap-1.5 text-body-sm text-foreground\\u0022\\u003E\\n            \\u003Csvg aria-hidden=\\u0022true\\u0022 class=\\u0022size-3.5 shrink-0 text-nq-info-text\\u0022 xmlns=\\u0022http:\\\/\\\/www.w3.org\\\/2000\\\/svg\\u0022 viewBox=\\u00220 0 24 24\\u0022 fill=\\u0022none\\u0022 stroke=\\u0022currentColor\\u0022 stroke-width=\\u00222\\u0022 stroke-linecap=\\u0022round\\u0022 stroke-linejoin=\\u0022round\\u0022\\u003E\\n  \\u003Ccircle cx=\\u002212\\u0022 cy=\\u002212\\u0022 r=\\u002210\\u0022\\\/\\u003E\\n  \\u003Ccircle cx=\\u002212\\u0022 cy=\\u002212\\u0022 r=\\u00221\\u0022\\\/\\u003E\\n\\u003C\\\/svg\\u003E        \\u003Cspan class=\\u0022truncate\\u0022  title=\\u0022Active\\u0022 \\u003EActive\\u003C\\\/span\\u003E\\n\\u003C\\\/span\\u003E\u0022,\u0022progressCell\u0022:\u0022\\u003Cspan class=\\u0022flex w-36 items-center gap-2\\u0022\\u003E\\n    \\u003Cdiv data-slot=\\u0022progress\\u0022 data-tone=\\u0022info\\u0022 role=\\u0022progressbar\\u0022     aria-valuemin=\\u00220\\u0022 aria-valuemax=\\u0022100\\u0022  aria-valuenow=\\u002262\\u0022     aria-valuetext=\\u002262%\\u0022 data-progressing\\n    aria-label=\\u0022Progress: Website redesign\\u0022 class=\\u0022flex w-full flex-col gap-1.5 flex-1\\u0022\\u003E\\n        \\u003Cdiv data-slot=\\u0022progress-track\\u0022 data-progressing class=\\u0022relative block w-full overflow-hidden rounded-full bg-nq-surface-soft h-1\\u0022\\u003E\\n        \\u003Cdiv data-slot=\\u0022progress-indicator\\u0022 data-progressing style=\\u0022inset-inline-start:0;width:62%\\u0022\\n            class=\\u0022block h-full rounded-full transition-[width] duration-300 ease-nq motion-reduce:transition-none bg-nq-info\\u0022\\u003E\\u003C\\\/div\\u003E\\n    \\u003C\\\/div\\u003E\\n\\u003C\\\/div\\u003E\\n    \\u003Cspan class=\\u0022w-9 shrink-0 text-end text-caption tabular-nums text-muted-foreground\\u0022\\u003E62%\\u003C\\\/span\\u003E\\n\\u003C\\\/span\\u003E\u0022,\u0022membersCell\u0022:\u0022\\u003Cspan data-slot=\\u0022avatar-stack\\u0022 role=\\u0022group\\u0022 aria-label=\\u0022Sara Ali, Omar Nasser\\u0022 class=\\u0022inline-flex items-center\\u0022\\u003E\\n        \\u003Cspan data-slot=\\u0022avatar\\u0022 x-data=\\u0022nqAvatar(0)\\u0022\\n    class=\\u0022inline-flex shrink-0 select-none items-center justify-center overflow-hidden bg-secondary align-middle font-medium text-secondary-foreground size-6 text-[10px] rounded-full -ms-1.5 ring-2 ring-card first:ms-0\\u0022\\u003E\\n                    \\u003Cspan data-slot=\\u0022avatar-fallback\\u0022 class=\\u0022flex size-full items-center justify-center\\u0022 x-bind=\\u0022fallback\\u0022\\n             role=\\u0022img\\u0022 aria-label=\\u0022Sara Ali\\u0022 \\u003ESA\\u003C\\\/span\\u003E\\n    \\u003C\\\/span\\u003E\\n\\u003Cspan data-slot=\\u0022avatar\\u0022 x-data=\\u0022nqAvatar(0)\\u0022\\n    class=\\u0022inline-flex shrink-0 select-none items-center justify-center overflow-hidden bg-secondary align-middle font-medium text-secondary-foreground size-6 text-[10px] rounded-full -ms-1.5 ring-2 ring-card first:ms-0\\u0022\\u003E\\n                    \\u003Cspan data-slot=\\u0022avatar-fallback\\u0022 class=\\u0022flex size-full items-center justify-center\\u0022 x-bind=\\u0022fallback\\u0022\\n             role=\\u0022img\\u0022 aria-label=\\u0022Omar Nasser\\u0022 \\u003EON\\u003C\\\/span\\u003E\\n    \\u003C\\\/span\\u003E\\n            \\u003C\\\/span\\u003E\u0022,\u0022dueCell\u0022:\u0022\\u003Cspan class=\\u0022inline-flex items-center gap-1.5 \\u0022\\u003E\\u003Ctime data-slot=\\u0022date-time\\u0022 datetime=\\u00222026-12-01T00:00:00+00:00\\u0022 dir=\\u0022auto\\u0022     class=\\u0022tabular-nums [unicode-bidi:isolate] text-body-sm\\u0022\\u003EDec 1, 2026\\u003C\\\/time\\u003E\\n\\u003C\\\/span\\u003E\u0022,\u0022activityCell\u0022:\u0022\\u003Cspan class=\\u0022text-muted-foreground\\u0022\\u003E\\u2014\\u003C\\\/span\\u003E\u0022,\u0022searchText\u0022:\u0022Website redesign WEB Acme\u0022,\u0022statusRank\u0022:1,\u0022dueTs\u0022:1796083200,\u0022activityTs\u0022:0,\u0022id\u0022:\u00221\u0022,\u0022name\u0022:\u0022Website redesign\u0022,\u0022client\u0022:\u0022Acme\u0022,\u0022status\u0022:\u0022active\u0022,\u0022statusLabel\u0022:\u0022Active\u0022,\u0022progress\u0022:62,\u0022progressText\u0022:\u002262%\u0022,\u0022members\u0022:[\u0022Sara Ali\u0022,\u0022Omar Nasser\u0022],\u0022membersText\u0022:\u0022Sara Ali, Omar Nasser\u0022,\u0022owner\u0022:\u0022\\u2014\u0022,\u0022due\u0022:\u0022Dec 1, 2026\u0022,\u0022tags\u0022:[],\u0022lastActivityText\u0022:\u0022\\u2014\u0022,\u0022card\u0022:\u0022\\u003Cdiv class=\\u0022flex min-w-0 flex-col gap-3\\u0022\\u003E\\n    \\u003Cdiv data-slot=\\u0022entity-identity\\u0022 class=\\u0022flex min-w-0 items-center gap-3 pe-(--entity-card-controls)\\u0022\\u003E\\n    \\u003Cspan data-slot=\\u0022avatar\\u0022 x-data=\\u0022nqAvatar(0)\\u0022\\n    class=\\u0022inline-flex shrink-0 select-none items-center justify-center overflow-hidden bg-secondary align-middle font-medium text-secondary-foreground size-10 text-label rounded-control\\u0022\\u003E\\n                    \\u003Cspan data-slot=\\u0022avatar-fallback\\u0022 class=\\u0022flex size-full items-center justify-center\\u0022 x-bind=\\u0022fallback\\u0022\\n             role=\\u0022img\\u0022 aria-label=\\u0022Website redesign\\u0022 \\u003EWR\\u003C\\\/span\\u003E\\n    \\u003C\\\/span\\u003E\\n    \\u003Cdiv class=\\u0022flex min-w-0 flex-col\\u0022\\u003E\\n        \\u003Cspan class=\\u0022truncate text-label text-foreground\\u0022\\u003EWebsite redesign\\u003C\\\/span\\u003E\\n        \\u003Cspan class=\\u0022truncate text-body-sm text-muted-foreground\\u0022\\u003EAcme\\u003C\\\/span\\u003E    \\u003C\\\/div\\u003E\\n\\u003C\\\/div\\u003E\\n    \\u003Cdiv class=\\u0022flex flex-col gap-1.5\\u0022\\u003E\\n        \\u003Cdiv data-slot=\\u0022card-meta\\u0022 class=\\u0022flex items-center justify-between gap-3 text-body-sm\\u0022\\u003E\\n    \\u003Cspan class=\\u0022shrink-0 text-muted-foreground\\u0022\\u003EStatus\\u003C\\\/span\\u003E\\n    \\u003Cspan class=\\u0022min-w-0 truncate text-end\\u0022\\u003E\\u003Cspan data-slot=\\u0022status\\u0022 data-tone=\\u0022info\\u0022 class=\\u0022inline-flex min-w-0 items-center gap-1.5 text-body-sm text-foreground\\u0022\\u003E\\n            \\u003Csvg aria-hidden=\\u0022true\\u0022 class=\\u0022size-3.5 shrink-0 text-nq-info-text\\u0022 xmlns=\\u0022http:\\\/\\\/www.w3.org\\\/2000\\\/svg\\u0022 viewBox=\\u00220 0 24 24\\u0022 fill=\\u0022none\\u0022 stroke=\\u0022currentColor\\u0022 stroke-width=\\u00222\\u0022 stroke-linecap=\\u0022round\\u0022 stroke-linejoin=\\u0022round\\u0022\\u003E\\n  \\u003Ccircle cx=\\u002212\\u0022 cy=\\u002212\\u0022 r=\\u002210\\u0022\\\/\\u003E\\n  \\u003Ccircle cx=\\u002212\\u0022 cy=\\u002212\\u0022 r=\\u00221\\u0022\\\/\\u003E\\n\\u003C\\\/svg\\u003E        \\u003Cspan class=\\u0022truncate\\u0022  title=\\u0022Active\\u0022 \\u003EActive\\u003C\\\/span\\u003E\\n\\u003C\\\/span\\u003E\\u003C\\\/span\\u003E\\n\\u003C\\\/div\\u003E\\n        \\u003Cdiv data-slot=\\u0022progress\\u0022 data-tone=\\u0022info\\u0022 role=\\u0022progressbar\\u0022  aria-labelledby=\\u0022nq-progress-46b5f8c5-label\\u0022     aria-valuemin=\\u00220\\u0022 aria-valuemax=\\u0022100\\u0022  aria-valuenow=\\u002262\\u0022     aria-valuetext=\\u002262%\\u0022 data-progressing\\n    aria-label=\\u0022Progress: Website redesign\\u0022 class=\\u0022flex w-full flex-col gap-1.5 py-1\\u0022\\u003E\\n            \\u003Cdiv data-slot=\\u0022progress-head\\u0022 class=\\u0022flex items-baseline justify-between gap-3 text-body-sm\\u0022\\u003E\\n            \\u003Cspan id=\\u0022nq-progress-46b5f8c5-label\\u0022 class=\\u0022text-label text-foreground\\u0022\\u003EProgress\\u003C\\\/span\\u003E            \\u003Cspan aria-hidden=\\u0022true\\u0022 class=\\u0022text-muted-foreground tabular-nums\\u0022\\u003E62%\\u003C\\\/span\\u003E        \\u003C\\\/div\\u003E\\n        \\u003Cdiv data-slot=\\u0022progress-track\\u0022 data-progressing class=\\u0022relative block w-full overflow-hidden rounded-full bg-nq-surface-soft h-1\\u0022\\u003E\\n        \\u003Cdiv data-slot=\\u0022progress-indicator\\u0022 data-progressing style=\\u0022inset-inline-start:0;width:62%\\u0022\\n            class=\\u0022block h-full rounded-full transition-[width] duration-300 ease-nq motion-reduce:transition-none bg-nq-info\\u0022\\u003E\\u003C\\\/div\\u003E\\n    \\u003C\\\/div\\u003E\\n\\u003C\\\/div\\u003E\\n        \\u003Cdiv data-slot=\\u0022card-meta\\u0022 class=\\u0022flex items-center justify-between gap-3 text-body-sm\\u0022\\u003E\\n    \\u003Cspan class=\\u0022shrink-0 text-muted-foreground\\u0022\\u003EDue\\u003C\\\/span\\u003E\\n    \\u003Cspan class=\\u0022min-w-0 truncate text-end\\u0022\\u003E\\u003Ctime data-slot=\\u0022date-time\\u0022 datetime=\\u00222026-12-01T00:00:00+00:00\\u0022 dir=\\u0022auto\\u0022     class=\\u0022tabular-nums [unicode-bidi:isolate]\\u0022\\u003EDec 1, 2026\\u003C\\\/time\\u003E\\u003C\\\/span\\u003E\\n\\u003C\\\/div\\u003E\\n        \\u003Cdiv data-slot=\\u0022card-meta\\u0022 class=\\u0022flex items-center justify-between gap-3 text-body-sm\\u0022\\u003E\\n    \\u003Cspan class=\\u0022shrink-0 text-muted-foreground\\u0022\\u003EMembers\\u003C\\\/span\\u003E\\n    \\u003Cspan class=\\u0022min-w-0 truncate text-end\\u0022\\u003E\\u003Cspan data-slot=\\u0022avatar-stack\\u0022 role=\\u0022group\\u0022 aria-label=\\u0022Sara Ali, Omar Nasser\\u0022 class=\\u0022inline-flex items-center\\u0022\\u003E\\n        \\u003Cspan data-slot=\\u0022avatar\\u0022 x-data=\\u0022nqAvatar(0)\\u0022\\n    class=\\u0022inline-flex shrink-0 select-none items-center justify-center overflow-hidden bg-secondary align-middle font-medium text-secondary-foreground size-6 text-[10px] rounded-full -ms-1.5 ring-2 ring-card first:ms-0\\u0022\\u003E\\n                    \\u003Cspan data-slot=\\u0022avatar-fallback\\u0022 class=\\u0022flex size-full items-center justify-center\\u0022 x-bind=\\u0022fallback\\u0022\\n             role=\\u0022img\\u0022 aria-label=\\u0022Sara Ali\\u0022 \\u003ESA\\u003C\\\/span\\u003E\\n    \\u003C\\\/span\\u003E\\n\\u003Cspan data-slot=\\u0022avatar\\u0022 x-data=\\u0022nqAvatar(0)\\u0022\\n    class=\\u0022inline-flex shrink-0 select-none items-center justify-center overflow-hidden bg-secondary align-middle font-medium text-secondary-foreground size-6 text-[10px] rounded-full -ms-1.5 ring-2 ring-card first:ms-0\\u0022\\u003E\\n                    \\u003Cspan data-slot=\\u0022avatar-fallback\\u0022 class=\\u0022flex size-full items-center justify-center\\u0022 x-bind=\\u0022fallback\\u0022\\n             role=\\u0022img\\u0022 aria-label=\\u0022Omar Nasser\\u0022 \\u003EON\\u003C\\\/span\\u003E\\n    \\u003C\\\/span\\u003E\\n            \\u003C\\\/span\\u003E\\u003C\\\/span\\u003E\\n\\u003C\\\/div\\u003E\\n    \\u003C\\\/div\\u003E\\n    \\u003C\\\/div\\u003E\u0022}]'), JSON.parse('[{\u0022id\u0022:\u0022name\u0022,\u0022type\u0022:\u0022html\u0022,\u0022key\u0022:\u0022nameCell\u0022,\u0022sortKey\u0022:\u0022name\u0022,\u0022searchKey\u0022:\u0022searchText\u0022,\u0022header\u0022:\u0022Project\u0022,\u0022sortable\u0022:true,\u0022searchable\u0022:true},{\u0022id\u0022:\u0022status\u0022,\u0022type\u0022:\u0022html\u0022,\u0022key\u0022:\u0022statusCell\u0022,\u0022sortKey\u0022:\u0022statusRank\u0022,\u0022header\u0022:\u0022Status\u0022,\u0022sortable\u0022:true},{\u0022id\u0022:\u0022progress\u0022,\u0022type\u0022:\u0022html\u0022,\u0022key\u0022:\u0022progressCell\u0022,\u0022sortKey\u0022:\u0022progress\u0022,\u0022header\u0022:\u0022Progress\u0022,\u0022sortable\u0022:true},{\u0022id\u0022:\u0022members\u0022,\u0022type\u0022:\u0022html\u0022,\u0022key\u0022:\u0022membersCell\u0022,\u0022header\u0022:\u0022Members\u0022},{\u0022id\u0022:\u0022due\u0022,\u0022type\u0022:\u0022html\u0022,\u0022key\u0022:\u0022dueCell\u0022,\u0022sortKey\u0022:\u0022dueTs\u0022,\u0022header\u0022:\u0022Due\u0022,\u0022sortable\u0022:true},{\u0022id\u0022:\u0022lastActivity\u0022,\u0022type\u0022:\u0022html\u0022,\u0022key\u0022:\u0022activityCell\u0022,\u0022sortKey\u0022:\u0022activityTs\u0022,\u0022header\u0022:\u0022Last activity\u0022,\u0022align\u0022:\u0022end\u0022,\u0022sortable\u0022:true}]'), JSON.parse('{\u0022view\u0022:\u0022table\u0022,\u0022views\u0022:[\u0022table\u0022,\u0022cards\u0022],\u0022facets\u0022:[{\u0022id\u0022:\u0022status\u0022,\u0022title\u0022:\u0022Status\u0022,\u0022key\u0022:\u0022status\u0022,\u0022options\u0022:[{\u0022value\u0022:\u0022planning\u0022,\u0022label\u0022:\u0022Planning\u0022},{\u0022value\u0022:\u0022active\u0022,\u0022label\u0022:\u0022Active\u0022},{\u0022value\u0022:\u0022on-hold\u0022,\u0022label\u0022:\u0022On hold\u0022},{\u0022value\u0022:\u0022completed\u0022,\u0022label\u0022:\u0022Completed\u0022},{\u0022value\u0022:\u0022archived\u0022,\u0022label\u0022:\u0022Archived\u0022}]},{\u0022id\u0022:\u0022client\u0022,\u0022title\u0022:\u0022Client\u0022,\u0022key\u0022:\u0022client\u0022,\u0022options\u0022:[{\u0022value\u0022:\u0022Acme\u0022,\u0022label\u0022:\u0022Acme\u0022}]},{\u0022id\u0022:\u0022members\u0022,\u0022title\u0022:\u0022Members\u0022,\u0022key\u0022:\u0022members\u0022,\u0022options\u0022:[{\u0022value\u0022:\u0022Omar Nasser\u0022,\u0022label\u0022:\u0022Omar Nasser\u0022},{\u0022value\u0022:\u0022Sara Ali\u0022,\u0022label\u0022:\u0022Sara Ali\u0022}]}],\u0022locale\u0022:\u0022en\u0022,\u0022labels\u0022:{\u0022selectRow\u0022:\u0022Select {name}\u0022,\u0022rowActions\u0022:\u0022Actions for {name}\u0022,\u0022selected\u0022:\u0022{n} selected\u0022,\u0022results\u0022:\u0022{n} results\u0022,\u0022resultsOne\u0022:\u00221 result\u0022}}'))" x-modelable="rows"
    x-bind:data-view="view" class="flex min-w-0 flex-col gap-3">
    <div data-slot="data-table-toolbar" class="flex flex-wrap items-center gap-2">
                    <button type="button" role="checkbox" data-slot="checkbox" aria-label="Select all on this page" x-on:click="togglePage()" x-show="view === 'cards'" style="display: none"
                x-bind:aria-checked="pageSelection() === 'all' ? 'true' : (pageSelection() === 'some' ? 'mixed' : 'false')"
                x-bind:data-checked="pageSelection() === 'all' ? '' : null" x-bind:data-indeterminate="pageSelection() === 'some' ? '' : null" aria-checked="false" class="relative inline-flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-nq-line-strong bg-card text-primary-foreground outline-none transition-colors duration-150 ease-nq data-checked:border-primary data-checked:bg-primary data-indeterminate:border-primary data-indeterminate:bg-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus after:absolute after:-inset-1 align-middle me-1">
                <span data-slot="checkbox-indicator" class="flex items-center justify-center [&_svg]:size-3 [&_svg]:stroke-3" x-show="pageSelection() !== 'none'" style="display: none">
                    <x-lucide-minus aria-hidden="true" x-show="pageSelection() === 'some'" style="display: none" />
                    <x-lucide-check aria-hidden="true" x-show="pageSelection() === 'all'" style="display: none" />
                </span>
            </button>
                            <div data-slot="data-table-search" class="relative w-full sm:w-64">
                <svg aria-hidden="true" class="pointer-events-none absolute start-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="m21 21-4.34-4.34"/>
  <circle cx="11" cy="11" r="8"/>
</svg>                <input data-slot="input" type="search"
                    x-model="query" x-on:keydown.escape="if (query) { $event.preventDefault(); query = &#039;&#039; }" placeholder="Search projects…" aria-label="Search projects…" class="w-full min-w-0 rounded-control border border-input bg-card px-3 text-foreground min-h-[var(--nq-touch-min,0px)] transition-colors duration-150 ease-nq outline-none placeholder:text-muted-foreground focus-visible:border-nq-focus focus-visible:outline-1 focus-visible:outline-nq-focus data-invalid:border-nq-danger aria-invalid:border-nq-danger disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:text-[16px] h-control-sm ps-8 pe-8 text-body-sm [&::-webkit-search-cancel-button]:hidden">
                <button type="button" x-show="query" aria-label="Clear search" x-on:click="query = ''" style="display: none"
                    class="absolute end-1.5 top-1/2 inline-flex size-5 -translate-y-1/2 items-center justify-center rounded-full text-muted-foreground outline-none hover:bg-nq-hover hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus">
                    <svg aria-hidden="true" class="size-3.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M18 6 6 18"/>
  <path d="m6 6 12 12"/>
</svg>                </button>
            </div>
                    <div data-slot="dropdown-menu" x-data="nqDropdownMenu(false)" x-modelable="open" class="contents"><button data-slot="dropdown-menu-trigger"
     type="button"                         x-bind="trigger" x-ref="trigger" x-bind:class="facetCount(&#039;status&#039;) ? &#039;&#039; : &#039;border-dashed text-muted-foreground&#039;" data-facet="status" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border-border bg-card text-foreground hover:bg-nq-hover h-control-sm px-2.5">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M2 5h20"/>
  <path d="M6 12h12"/>
  <path d="M9 19h6"/>
</svg>                    Status
                    <span data-slot="badge" x-show="facetCount('status')" x-text="facetSummary('status')" style="display: none"
                        class="-me-1 inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-[4px] border border-border px-1.5 text-caption font-medium tabular-nums text-muted-foreground"></span></button>
                <template x-teleport="body">
    <div data-slot="dropdown-menu-content" x-bind="popup" x-init="popupEl = $el" x-nq-presence="open" x-anchor.bottom-start.offset.4="$refs.trigger"
        class="z-50 overflow-hidden rounded-floating border border-border bg-popover p-1.5 text-popover-foreground shadow-floating outline-none transition-opacity duration-150 ease-nq data-starting-style:opacity-0 data-ending-style:opacity-0 max-h-80 min-w-48 overflow-y-auto"><div data-slot="dropdown-menu-group" role="group" ><div data-slot="dropdown-menu-checkbox-item" role="menuitemcheckbox" x-data="{ checked: false }" x-modelable="checked" x-bind="item"
    x-on:click="if (! $el.hasAttribute('data-disabled')) checked = ! checked"
    x-bind:aria-checked="checked ? 'true' : 'false'" x-bind:data-checked="checked ? '' : undefined" x-bind:data-unchecked="checked ? undefined : ''"
     data-keep-open         x-model="facet[&#039;status|planning&#039;]" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground ps-8">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="checked" class="contents"  style="display:none" ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    Planning
</div>
                                                    <div data-slot="dropdown-menu-checkbox-item" role="menuitemcheckbox" x-data="{ checked: false }" x-modelable="checked" x-bind="item"
    x-on:click="if (! $el.hasAttribute('data-disabled')) checked = ! checked"
    x-bind:aria-checked="checked ? 'true' : 'false'" x-bind:data-checked="checked ? '' : undefined" x-bind:data-unchecked="checked ? undefined : ''"
     data-keep-open         x-model="facet[&#039;status|active&#039;]" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground ps-8">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="checked" class="contents"  style="display:none" ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    Active
</div>
                                                    <div data-slot="dropdown-menu-checkbox-item" role="menuitemcheckbox" x-data="{ checked: false }" x-modelable="checked" x-bind="item"
    x-on:click="if (! $el.hasAttribute('data-disabled')) checked = ! checked"
    x-bind:aria-checked="checked ? 'true' : 'false'" x-bind:data-checked="checked ? '' : undefined" x-bind:data-unchecked="checked ? undefined : ''"
     data-keep-open         x-model="facet[&#039;status|on-hold&#039;]" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground ps-8">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="checked" class="contents"  style="display:none" ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    On hold
</div>
                                                    <div data-slot="dropdown-menu-checkbox-item" role="menuitemcheckbox" x-data="{ checked: false }" x-modelable="checked" x-bind="item"
    x-on:click="if (! $el.hasAttribute('data-disabled')) checked = ! checked"
    x-bind:aria-checked="checked ? 'true' : 'false'" x-bind:data-checked="checked ? '' : undefined" x-bind:data-unchecked="checked ? undefined : ''"
     data-keep-open         x-model="facet[&#039;status|completed&#039;]" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground ps-8">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="checked" class="contents"  style="display:none" ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    Completed
</div>
                                                    <div data-slot="dropdown-menu-checkbox-item" role="menuitemcheckbox" x-data="{ checked: false }" x-modelable="checked" x-bind="item"
    x-on:click="if (! $el.hasAttribute('data-disabled')) checked = ! checked"
    x-bind:aria-checked="checked ? 'true' : 'false'" x-bind:data-checked="checked ? '' : undefined" x-bind:data-unchecked="checked ? undefined : ''"
     data-keep-open         x-model="facet[&#039;status|archived&#039;]" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground ps-8">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="checked" class="contents"  style="display:none" ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    Archived
</div></div>
                    <div x-show="facetCount('status')" style="display: none">
                        <div data-slot="dropdown-menu-separator" role="separator" aria-orientation="horizontal" class="-mx-1.5 my-1.5 h-px bg-border"></div>
                        <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="resetFacet(&#039;status&#039;)" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground">Reset</div>
                    </div></div>
</template></div>
                    <div data-slot="dropdown-menu" x-data="nqDropdownMenu(false)" x-modelable="open" class="contents"><button data-slot="dropdown-menu-trigger"
     type="button"                         x-bind="trigger" x-ref="trigger" x-bind:class="facetCount(&#039;client&#039;) ? &#039;&#039; : &#039;border-dashed text-muted-foreground&#039;" data-facet="client" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border-border bg-card text-foreground hover:bg-nq-hover h-control-sm px-2.5">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M2 5h20"/>
  <path d="M6 12h12"/>
  <path d="M9 19h6"/>
</svg>                    Client
                    <span data-slot="badge" x-show="facetCount('client')" x-text="facetSummary('client')" style="display: none"
                        class="-me-1 inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-[4px] border border-border px-1.5 text-caption font-medium tabular-nums text-muted-foreground"></span></button>
                <template x-teleport="body">
    <div data-slot="dropdown-menu-content" x-bind="popup" x-init="popupEl = $el" x-nq-presence="open" x-anchor.bottom-start.offset.4="$refs.trigger"
        class="z-50 overflow-hidden rounded-floating border border-border bg-popover p-1.5 text-popover-foreground shadow-floating outline-none transition-opacity duration-150 ease-nq data-starting-style:opacity-0 data-ending-style:opacity-0 max-h-80 min-w-48 overflow-y-auto"><div data-slot="dropdown-menu-group" role="group" ><div data-slot="dropdown-menu-checkbox-item" role="menuitemcheckbox" x-data="{ checked: false }" x-modelable="checked" x-bind="item"
    x-on:click="if (! $el.hasAttribute('data-disabled')) checked = ! checked"
    x-bind:aria-checked="checked ? 'true' : 'false'" x-bind:data-checked="checked ? '' : undefined" x-bind:data-unchecked="checked ? undefined : ''"
     data-keep-open         x-model="facet[&#039;client|Acme&#039;]" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground ps-8">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="checked" class="contents"  style="display:none" ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    Acme
</div></div>
                    <div x-show="facetCount('client')" style="display: none">
                        <div data-slot="dropdown-menu-separator" role="separator" aria-orientation="horizontal" class="-mx-1.5 my-1.5 h-px bg-border"></div>
                        <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="resetFacet(&#039;client&#039;)" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground">Reset</div>
                    </div></div>
</template></div>
                    <div data-slot="dropdown-menu" x-data="nqDropdownMenu(false)" x-modelable="open" class="contents"><button data-slot="dropdown-menu-trigger"
     type="button"                         x-bind="trigger" x-ref="trigger" x-bind:class="facetCount(&#039;members&#039;) ? &#039;&#039; : &#039;border-dashed text-muted-foreground&#039;" data-facet="members" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border-border bg-card text-foreground hover:bg-nq-hover h-control-sm px-2.5">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M2 5h20"/>
  <path d="M6 12h12"/>
  <path d="M9 19h6"/>
</svg>                    Members
                    <span data-slot="badge" x-show="facetCount('members')" x-text="facetSummary('members')" style="display: none"
                        class="-me-1 inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-[4px] border border-border px-1.5 text-caption font-medium tabular-nums text-muted-foreground"></span></button>
                <template x-teleport="body">
    <div data-slot="dropdown-menu-content" x-bind="popup" x-init="popupEl = $el" x-nq-presence="open" x-anchor.bottom-start.offset.4="$refs.trigger"
        class="z-50 overflow-hidden rounded-floating border border-border bg-popover p-1.5 text-popover-foreground shadow-floating outline-none transition-opacity duration-150 ease-nq data-starting-style:opacity-0 data-ending-style:opacity-0 max-h-80 min-w-48 overflow-y-auto"><div data-slot="dropdown-menu-group" role="group" ><div data-slot="dropdown-menu-checkbox-item" role="menuitemcheckbox" x-data="{ checked: false }" x-modelable="checked" x-bind="item"
    x-on:click="if (! $el.hasAttribute('data-disabled')) checked = ! checked"
    x-bind:aria-checked="checked ? 'true' : 'false'" x-bind:data-checked="checked ? '' : undefined" x-bind:data-unchecked="checked ? undefined : ''"
     data-keep-open         x-model="facet[&#039;members|Omar Nasser&#039;]" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground ps-8">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="checked" class="contents"  style="display:none" ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    Omar Nasser
</div>
                                                    <div data-slot="dropdown-menu-checkbox-item" role="menuitemcheckbox" x-data="{ checked: false }" x-modelable="checked" x-bind="item"
    x-on:click="if (! $el.hasAttribute('data-disabled')) checked = ! checked"
    x-bind:aria-checked="checked ? 'true' : 'false'" x-bind:data-checked="checked ? '' : undefined" x-bind:data-unchecked="checked ? undefined : ''"
     data-keep-open         x-model="facet[&#039;members|Sara Ali&#039;]" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground ps-8">
    <span aria-hidden="true" class="absolute start-2.5 inline-flex size-4 items-center justify-center">
        <span x-show="checked" class="contents"  style="display:none" ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 6 9 17l-5-5"/>
</svg></span>
    </span>
    Sara Ali
</div></div>
                    <div x-show="facetCount('members')" style="display: none">
                        <div data-slot="dropdown-menu-separator" role="separator" aria-orientation="horizontal" class="-mx-1.5 my-1.5 h-px bg-border"></div>
                        <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="resetFacet(&#039;members&#039;)" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground">Reset</div>
                    </div></div>
</template></div>
        <button data-slot="entity-list-clear"
     type="button"                         x-show="isFiltered()" x-on:click="clearAll()" style="display: none" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border border-transparent font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 text-foreground hover:bg-nq-hover h-control-sm px-2.5">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M18 6 6 18"/>
  <path d="m6 6 12 12"/>
</svg>            Clear filters</button>
        <div class="ms-auto flex flex-wrap items-center gap-2">
                                                    <div x-show="view === 'cards'" style="display: none">
                    <div data-slot="dropdown-menu" x-data="nqDropdownMenu(false)" x-modelable="open" class="contents"><button data-slot="entity-list-sort"
     type="button"                         x-bind="trigger" x-ref="trigger" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border-border bg-card text-foreground hover:bg-nq-hover h-control-sm px-2.5">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="m3 16 4 4 4-4"/>
  <path d="M7 20V4"/>
  <path d="m21 8-4-4-4 4"/>
  <path d="M17 4v16"/>
</svg>                            Sort</button>
                        <template x-teleport="body">
    <div data-slot="dropdown-menu-content" x-bind="popup" x-init="popupEl = $el" x-nq-presence="open" x-anchor.bottom-end.offset.4="$refs.trigger"
        class="z-50 overflow-hidden rounded-floating border border-border bg-popover p-1.5 text-popover-foreground shadow-floating outline-none max-h-[var(--available-height)] overflow-y-auto transition-opacity duration-150 ease-nq data-starting-style:opacity-0 data-ending-style:opacity-0 min-w-44"><div data-slot="dropdown-menu-group" role="group" ><div data-slot="dropdown-menu-label" role="presentation" class="px-2.5 pt-1.5 pb-1 text-caption font-medium text-muted-foreground">Sort by</div>
                                                                                                            <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="toggleSort(&#039;name&#039;)" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground"><span class="flex-1">Project</span>
                                            <span aria-hidden="true" class="text-muted-foreground" x-text="sort?.id === 'name' ? (sort.dir === 'asc' ? '↑' : '↓') : ''"></span></div>
                                                                                                                                                <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="toggleSort(&#039;status&#039;)" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground"><span class="flex-1">Status</span>
                                            <span aria-hidden="true" class="text-muted-foreground" x-text="sort?.id === 'status' ? (sort.dir === 'asc' ? '↑' : '↓') : ''"></span></div>
                                                                                                                                                <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="toggleSort(&#039;progress&#039;)" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground"><span class="flex-1">Progress</span>
                                            <span aria-hidden="true" class="text-muted-foreground" x-text="sort?.id === 'progress' ? (sort.dir === 'asc' ? '↑' : '↓') : ''"></span></div>
                                                                                                                                                                                                                    <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="toggleSort(&#039;due&#039;)" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground"><span class="flex-1">Due</span>
                                            <span aria-hidden="true" class="text-muted-foreground" x-text="sort?.id === 'due' ? (sort.dir === 'asc' ? '↑' : '↓') : ''"></span></div>
                                                                                                                                                <div data-slot="dropdown-menu-item" role="menuitem" data-variant="default" x-bind="item"
        x-on:click="toggleSort(&#039;lastActivity&#039;)" class="relative flex h-nav-row min-h-[var(--nq-touch-min,0px)] cursor-default select-none items-center gap-2.5 rounded-control px-2.5 text-body-sm text-foreground outline-none data-highlighted:bg-nq-selected data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground"><span class="flex-1">Last activity</span>
                                            <span aria-hidden="true" class="text-muted-foreground" x-text="sort?.id === 'lastActivity' ? (sort.dir === 'asc' ? '↑' : '↓') : ''"></span></div></div></div>
</template></div>
                </div>
                                        <div role="group" data-slot="toggle-group" aria-label="Layout" class="flex w-fit max-w-full gap-0.5 rounded-control bg-secondary p-0.5">
                                            <button type="button" data-slot="toggle" aria-label="Table view" x-on:click="setView('table')" x-bind:aria-pressed="view === 'table' ? 'true' : 'false'"
                            x-bind:data-pressed="view === 'table' ? '' : null"
                            class="inline-flex h-control-sm min-w-control-sm items-center justify-center rounded-[calc(var(--radius-control)-2px)] px-2 text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus data-pressed:bg-card data-pressed:text-foreground data-pressed:shadow-sm [&_svg]:size-4">
                            <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M3 5h.01"/>
  <path d="M3 12h.01"/>
  <path d="M3 19h.01"/>
  <path d="M8 5h13"/>
  <path d="M8 12h13"/>
  <path d="M8 19h13"/>
</svg>                        </button>
                                            <button type="button" data-slot="toggle" aria-label="Card view" x-on:click="setView('cards')" x-bind:aria-pressed="view === 'cards' ? 'true' : 'false'"
                            x-bind:data-pressed="view === 'cards' ? '' : null"
                            class="inline-flex h-control-sm min-w-control-sm items-center justify-center rounded-[calc(var(--radius-control)-2px)] px-2 text-muted-foreground outline-none transition-colors duration-150 ease-nq hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus data-pressed:bg-card data-pressed:text-foreground data-pressed:shadow-sm [&_svg]:size-4">
                            <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <rect width="7" height="7" x="3" y="3" rx="1"/>
  <rect width="7" height="7" x="14" y="3" rx="1"/>
  <rect width="7" height="7" x="14" y="14" rx="1"/>
  <rect width="7" height="7" x="3" y="14" rx="1"/>
</svg>                        </button>
                                    </div>
                    </div>
    </div>
            <div data-slot="data-table-bulk-actions" role="toolbar" x-bind:aria-label="say('selected').replace('{n}', selectedCount())" x-bind:hidden="selectedCount() === 0" hidden
            class="flex flex-wrap items-center gap-2 rounded-control bg-nq-selected py-1 ps-3 pe-1">
            <span aria-live="polite" class="me-auto text-label tabular-nums text-foreground" x-text="say('selected').replace('{n}', selectedCount())"></span>
                        <button type="button" aria-label="Clear selection" x-on:click="clearSelection()" class="inline-flex size-control-sm shrink-0 items-center justify-center rounded-control text-foreground outline-none hover:bg-nq-hover focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:size-4"><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M18 6 6 18"/>
  <path d="m6 6 12 12"/>
</svg></button>
        </div>
    <span role="status" aria-live="polite" class="sr-only" x-text="status()"></span>
        <div x-show="view === 'table'" style="display: none" data-slot="table-container" role="region" tabindex="0" aria-label="Projects"
            class="relative w-full overflow-x-auto outline-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-nq-focus">
            <div data-slot="table" role="table" aria-label="Projects"  style="grid-template-columns: repeat(7, auto)" class="grid w-full min-w-max text-body-sm">
                <div data-slot="table-header" role="rowgroup" class="contents">
                    <div role="row" class="col-span-full grid grid-cols-subgrid border-b border-border">
                        <div role="columnheader" class="flex h-row w-10 items-center"><span class="sr-only">Select all on this page</span></div>                                                    <div role="columnheader" data-slot="table-head"   x-bind:aria-sort="sortState('name')"                                 class="flex h-row items-center px-4 text-caption font-medium whitespace-nowrap text-muted-foreground text-start">
                                                                    <button type="button" x-on:click="toggleSort('name')" class="inline-flex items-center gap-1.5 rounded-control outline-none hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus">
                                        Project
                                        <span aria-hidden="true" x-text="sort?.id === 'name' ? (sort.dir === 'asc' ? '↑' : '↓') : ''"></span>
                                    </button>
                                                            </div>
                                                    <div role="columnheader" data-slot="table-head"   x-bind:aria-sort="sortState('status')"                                 class="flex h-row items-center px-4 text-caption font-medium whitespace-nowrap text-muted-foreground text-start">
                                                                    <button type="button" x-on:click="toggleSort('status')" class="inline-flex items-center gap-1.5 rounded-control outline-none hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus">
                                        Status
                                        <span aria-hidden="true" x-text="sort?.id === 'status' ? (sort.dir === 'asc' ? '↑' : '↓') : ''"></span>
                                    </button>
                                                            </div>
                                                    <div role="columnheader" data-slot="table-head"   x-bind:aria-sort="sortState('progress')"                                 class="flex h-row items-center px-4 text-caption font-medium whitespace-nowrap text-muted-foreground text-start">
                                                                    <button type="button" x-on:click="toggleSort('progress')" class="inline-flex items-center gap-1.5 rounded-control outline-none hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus">
                                        Progress
                                        <span aria-hidden="true" x-text="sort?.id === 'progress' ? (sort.dir === 'asc' ? '↑' : '↓') : ''"></span>
                                    </button>
                                                            </div>
                                                    <div role="columnheader" data-slot="table-head"                                  class="flex h-row items-center px-4 text-caption font-medium whitespace-nowrap text-muted-foreground text-start">
                                                                    Members
                                                            </div>
                                                    <div role="columnheader" data-slot="table-head"   x-bind:aria-sort="sortState('due')"                                 class="flex h-row items-center px-4 text-caption font-medium whitespace-nowrap text-muted-foreground text-start">
                                                                    <button type="button" x-on:click="toggleSort('due')" class="inline-flex items-center gap-1.5 rounded-control outline-none hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus">
                                        Due
                                        <span aria-hidden="true" x-text="sort?.id === 'due' ? (sort.dir === 'asc' ? '↑' : '↓') : ''"></span>
                                    </button>
                                                            </div>
                                                    <div role="columnheader" data-slot="table-head"   x-bind:aria-sort="sortState('lastActivity')"                                 class="flex h-row items-center px-4 text-caption font-medium whitespace-nowrap text-muted-foreground justify-end text-end">
                                                                    <button type="button" x-on:click="toggleSort('lastActivity')" class="inline-flex items-center gap-1.5 rounded-control outline-none hover:text-foreground focus-visible:outline-2 focus-visible:outline-nq-focus">
                                        Last activity
                                        <span aria-hidden="true" x-text="sort?.id === 'lastActivity' ? (sort.dir === 'asc' ? '↑' : '↓') : ''"></span>
                                    </button>
                                                            </div>
                                                                    </div>
                </div>
                <div data-slot="table-body" role="rowgroup" class="contents">
                    <template x-for="(row, index) in pageRows" :key="idOf(row)">
                                                    <div role="row" data-row x-bind:data-state="isSelected(row) ? 'selected' : null" x-on:click="openRow(row, $event)"
                                class="group/row col-span-full grid grid-cols-subgrid border-b border-border transition-colors hover:bg-nq-hover data-[state=selected]:bg-nq-selected">
                                    <div role="cell" data-slot="table-cell" class="flex h-row w-10 items-center pe-0">
        <button type="button" role="checkbox" data-slot="checkbox" x-bind:aria-label="say('selectRow', row)" x-on:click="toggleRow(row)" aria-checked="false"
            x-bind:aria-checked="isSelected(row) ? 'true' : 'false'" x-bind:data-checked="isSelected(row) ? '' : null" x-bind:data-unchecked="isSelected(row) ? null : ''" class="relative inline-flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-nq-line-strong bg-card text-primary-foreground outline-none transition-colors duration-150 ease-nq data-checked:border-primary data-checked:bg-primary data-indeterminate:border-primary data-indeterminate:bg-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus after:absolute after:-inset-1 align-middle">
            <span data-slot="checkbox-indicator" class="flex items-center justify-center [&_svg]:size-3 [&_svg]:stroke-3" x-show="isSelected(row)" style="display: none"><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 6 9 17l-5-5"/>
</svg></span>
        </button>
    </div>
        <div role="cell" data-slot="table-cell" data-cell-col="name"  class="flex h-row items-center px-4 py-3 ">
        <span class="flex min-w-0 items-center gap-1.5 ">
                            <span class="min-w-0" x-html="row['nameCell'] ?? ''"></span>
                    </span>
    </div>
        <div role="cell" data-slot="table-cell" data-cell-col="status"  class="flex h-row items-center px-4 py-3 ">
        <span class="flex min-w-0 items-center gap-1.5 ">
                            <span class="min-w-0" x-html="row['statusCell'] ?? ''"></span>
                    </span>
    </div>
        <div role="cell" data-slot="table-cell" data-cell-col="progress"  class="flex h-row items-center px-4 py-3 ">
        <span class="flex min-w-0 items-center gap-1.5 ">
                            <span class="min-w-0" x-html="row['progressCell'] ?? ''"></span>
                    </span>
    </div>
        <div role="cell" data-slot="table-cell" data-cell-col="members"  class="flex h-row items-center px-4 py-3 ">
        <span class="flex min-w-0 items-center gap-1.5 ">
                            <span class="min-w-0" x-html="row['membersCell'] ?? ''"></span>
                    </span>
    </div>
        <div role="cell" data-slot="table-cell" data-cell-col="due"  class="flex h-row items-center px-4 py-3 ">
        <span class="flex min-w-0 items-center gap-1.5 ">
                            <span class="min-w-0" x-html="row['dueCell'] ?? ''"></span>
                    </span>
    </div>
        <div role="cell" data-slot="table-cell" data-cell-col="lastActivity"  class="flex h-row items-center px-4 py-3 justify-end text-end">
        <span class="flex min-w-0 items-center gap-1.5 justify-end">
                            <span class="min-w-0" x-html="row['activityCell'] ?? ''"></span>
                    </span>
    </div>
                            </div>
                                            </template>
                </div>
            </div>
        </div>
        <div x-show="view === 'cards'" style="display: none" role="list" aria-label="Projects" class="grid gap-3"
            style="grid-template-columns: repeat(auto-fill, minmax(min(100%, 272px), 1fr)); --entity-card-controls: 1.75rem">
            <template x-for="(row, index) in pageRows" :key="idOf(row)">
                                    <div role="listitem" data-card x-bind:tabindex="index === Math.min(active, pageRows.length - 1) ? 0 : -1" x-bind:data-state="isSelected(row) ? 'selected' : null"
                        x-on:keydown="cardKey($event, row, index)" x-on:click="openRow(row, $event)" x-on:focus="$event.target === $event.currentTarget ? (active = index) : null" class="group/card relative flex min-w-0 flex-col rounded-card border border-border bg-card p-4 text-card-foreground outline-none transition-colors duration-150 ease-nq hover:bg-nq-hover focus-visible:outline-2 focus-visible:outline-nq-focus data-[state=selected]:border-primary data-[state=selected]:bg-nq-selected">
                        <div class="min-w-0 flex-1"><div x-html="row.card"></div></div>
    <div class="absolute end-2 top-2 flex items-center gap-1">
                    <button type="button" role="checkbox" data-slot="checkbox" x-bind:aria-label="say('selectRow', row)" x-on:click="toggleRow(row)" aria-checked="false"
                x-bind:aria-checked="isSelected(row) ? 'true' : 'false'" x-bind:data-checked="isSelected(row) ? '' : null" x-bind:data-unchecked="isSelected(row) ? null : ''"
                x-bind:tabindex="index === Math.min(active, pageRows.length - 1) ? 0 : -1" class="relative inline-flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-nq-line-strong bg-card text-primary-foreground outline-none transition-colors duration-150 ease-nq data-checked:border-primary data-checked:bg-primary data-indeterminate:border-primary data-indeterminate:bg-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus after:absolute after:-inset-1 align-middle">
                <span data-slot="checkbox-indicator" class="flex items-center justify-center [&_svg]:size-3 [&_svg]:stroke-3" x-show="isSelected(row)" style="display: none"><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M20 6 9 17l-5-5"/>
</svg></span>
            </button>
                    </div>
                    </div>
                            </template>
        </div>
        <div x-show="! hasRows() && noMatches()" style="display: none">
            <div data-slot="empty-state" class="flex flex-col items-center justify-center gap-3 border-dashed border-border px-6 py-12 text-center rounded-card border-0">
            <span data-slot="state-icon" class="inline-flex size-10 items-center justify-center rounded-control border border-border bg-card [&amp;_svg]:size-5 text-muted-foreground">
            <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="m21 21-4.34-4.34"/>
  <circle cx="11" cy="11" r="8"/>
</svg>        </span>
        <div class="flex max-w-sm flex-col gap-1">
        <p class="text-label text-foreground">No matching results</p>
                    <p class="text-body-sm text-muted-foreground">Try a different search or clear the filters.</p>
            </div>
            <div class="mt-1 flex flex-wrap items-center justify-center gap-2"><button data-slot="button"
     type="button"                         x-on:click="clearAll()" class="inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-control border font-sans text-label transition-colors duration-150 ease-nq min-h-[var(--nq-touch-min,0px)] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-nq-focus disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border-border bg-card text-foreground hover:bg-nq-hover h-control-sm px-2.5">
        Clear filters</button></div>
    </div>
        </div>
        <div x-show="rows.length === 0" style="display: none">
            <div data-slot="empty-state" class="flex flex-col items-center justify-center gap-3 border border-dashed border-border px-6 py-12 text-center rounded-card">
            <span data-slot="state-icon" class="inline-flex size-10 items-center justify-center rounded-control border border-border bg-card [&amp;_svg]:size-5 text-muted-foreground">
            <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"/>
  <path d="M8 10v4"/>
  <path d="M12 10v2"/>
  <path d="M16 10v6"/>
</svg>        </span>
        <div class="flex max-w-sm flex-col gap-1">
        <p class="text-label text-foreground">No projects yet</p>
                    <p class="text-body-sm text-muted-foreground">Create a project to start planning work.</p>
            </div>
    </div>        </div>
    </div>
</div>
```
