# @e-llm-studio/creative-workspace-ui-component

> Reusable React components for Creative Workspace.

Latest version **0.0.68** (published 2026-10-21) · MIT license · 0 weekly downloads

## Install

```sh
npm install @e-llm-studio/creative-workspace-ui-component
pnpm add @e-llm-studio/creative-workspace-ui-component
yarn add @e-llm-studio/creative-workspace-ui-component
bun add @e-llm-studio/creative-workspace-ui-component
```

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high maintenance score; high quality score.

Warnings: low downloads; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.0.68 |
| Published | 2026-10-21 |
| First published | 2026-05-21 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 12 |
| Unpacked size | 9.5 MB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Priyanshu Gupta |
| Maintainers | mkathyayani, viswakoduru, omkareshwar_techolution, akashmishra-dev7, yash27verma, rishabh-sonal, saurabhgathade, priyanshu-g13, bhaskar.dekaraja, amber_techo, deveshpatel, neeraj82, sabithpocker, sanket-tehco, ram_vilash, saptyadeep, hitesh_rathi_02, vikas_as, nadeenshaik, mdfaiz-tech, soubhik-techolution, mugdhatanu, techorai, sagniktecholution, ritikguptatecho, sumit.jaiswal, shivendra12131, mujtaba12131, yaksh-patel, abhay-techo |
| Keywords | bpa-ai, creative-workspace, react |

## Links

- npm: https://www.npmjs.com/package/@e-llm-studio/creative-workspace-ui-component
- Repository: https://github.com/Techolution/bpa-ai
- npm.io page: https://npm.io/package/@e-llm-studio/creative-workspace-ui-component

## Dependencies (12)

- [clsx](https://npm.io/package/clsx.md) ^2.1.1
- [uuid](https://npm.io/package/uuid.md) ^11.0.3
- [appsec-ui](https://npm.io/package/appsec-ui.md) ^1.0.9
- [style-inject](https://npm.io/package/style-inject.md) ^0.3.0
- [tailwind-merge](https://npm.io/package/tailwind-merge.md) ^2.5.4
- [fast-xml-parser](https://npm.io/package/fast-xml-parser.md) ^4.5.7
- [socket.io-client](https://npm.io/package/socket.io-client.md) ^4.8.3
- [@tanstack/react-query](https://npm.io/package/@tanstack/react-query.md) ^5.100.14
- [@radix-ui/react-tooltip](https://npm.io/package/@radix-ui/react-tooltip.md) ^1.2.8
- [@e-llm-studio/prompt-editor](https://npm.io/package/@e-llm-studio/prompt-editor.md) 0.1.0
- [@uiw/react-markdown-preview](https://npm.io/package/@uiw/react-markdown-preview.md) ^5.1.4
- [@e-llm-studio/instant-learning](https://npm.io/package/@e-llm-studio/instant-learning.md) 1.3.14

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 0.0.68 (latest) — 2026-10-21
- 0.0.45-alpha.1 (alpha) — 2026-08-24
- 0.0.17-beta.1 (beta) — 2026-07-16
- 0.0.67 — 2026-10-21
- 0.0.66 — 2026-10-16
- 0.0.65 — 2026-10-16
- 0.0.64 — 2026-10-15
- 0.0.63 — 2026-10-14
- 0.0.62 — 2026-09-28
- 0.0.61 — 2026-09-25
- 0.0.60 — 2026-09-24
- 0.0.59 — 2026-09-23
- 0.0.58 — 2026-09-22
- 0.0.57 — 2026-09-18
- 0.0.56 — 2026-09-18
- … 70 more at https://npm.io/package/@e-llm-studio/creative-workspace-ui-component/versions

## README

# TreeSidebar Component

A hierarchical tree navigation component for rendering nested scope/node structures with expandable sections, search, and configurable actions. The component is part of the `@e-llm-studio/creative-workspace-ui-component` package and can be used independently in any React application.

---

## Introduction

TreeSidebar is a standalone component from the `@e-llm-studio/creative-workspace-ui-component` package designed to provide a fully generic, hierarchical tree navigation panel. Its primary purpose is to render a tree of nodes (e.g. Global → Scope → Subscope) with expandable sections, search filtering, and optional action handlers. The consuming team controls what actions are available by passing or omitting handler props — if a handler is not passed, the corresponding button is not rendered.

---

## Features

- **Hierarchical tree rendering** — Supports unlimited nesting levels (Global → Scope → Subscope → ...)
- **Expand/collapse** — Each node is independently expandable; root node auto-expands on load
- **Section items** — Each node can show configurable section tabs (e.g. Learnings, Stations) below it when expanded
- **Search filtering** — Pass a `searchQuery` to filter nodes by name; non-matching subtrees are hidden
- **Configurable node types** — Control labels, add-child labels and child types via `nodeTypesConfig`
- **Configurable sections** — Control which sections appear per node via `sectionsConfig`
- **Conditional actions** — Add, Rename, Delete buttons only render when the corresponding handler prop is passed
- **Children count badge** — Optional badge showing number of direct children per node
- **Section badge** — Optional badge on section items showing metrics (e.g. learnings count)
- **Inline styles only** — No Tailwind or MUI dependency, works in any consuming app regardless of styling setup

---

## Installation

The TreeSidebar component is part of the `@e-llm-studio/creative-workspace-ui-component` package.

### Using npm

```bash
npm install @e-llm-studio/creative-workspace-ui-component
```

### Using yarn

```bash
yarn add @e-llm-studio/creative-workspace-ui-component
```

### Import Statement

```tsx
import { TreeSidebar } from "@e-llm-studio/creative-workspace-ui-component";
// or via subpath
import { TreeSidebar } from "@e-llm-studio/creative-workspace-ui-component/TreeSidebar";
```

---

## Usage

### Basic Example

Here's a simple example demonstrating how to use TreeSidebar with minimal props:

```tsx
import { TreeSidebar } from "@e-llm-studio/creative-workspace-ui-component";
import { BookOpen } from "lucide-react";

const treeData = {
  id: "root",
  name: "Global Scope",
  type: "GLOBAL" as const,
  metrics: { learningsCount: 10 },
  children: [
    {
      id: "scope-1",
      name: "Scope 1",
      type: "SCOPE" as const,
      metrics: { learningsCount: 5 },
      children: [],
    },
  ],
};

export default function App() {
  return (
    <TreeSidebar
      data={treeData}
      sectionsConfig={[
        {
          id: "learnings",
          label: "Learnings",
          icon: BookOpen,
          badgeKey: "learningsCount",
        },
      ]}
      nodeTypesConfig={[
        { type: "GLOBAL", label: "Global", addChildLabel: "Add Scope", addChildType: "SCOPE" },
        { type: "SCOPE", label: "Scope" },
      ]}
      onSectionSelect={(nodeId, sectionId) => console.log(nodeId, sectionId)}
    />
  );
}
```

**Key Props Explained:**
- `data`: The root node of the tree — pass `null` to render nothing
- `sectionsConfig`: Defines which section tabs appear under each expanded node
- `nodeTypesConfig`: Defines node labels and add-child behavior per depth level
- `onSectionSelect`: Fired when a section tab is clicked — returns the selected `nodeId` and `sectionId`

### Advanced Example

This example demonstrates all action handlers and badge visibility controls:

```tsx
import { TreeSidebar } from "@e-llm-studio/creative-workspace-ui-component";
import { BookOpen } from "lucide-react";

export default function AdvancedExample() {
  return (
    <TreeSidebar
      data={treeData}
      sectionsConfig={[
        {
          id: "learnings",
          label: "Learnings",
          icon: BookOpen,
          badgeKey: "learningsCount",
        },
      ]}
      nodeTypesConfig={[
        { type: "GLOBAL", label: "Global", addChildLabel: "Add Scope", addChildType: "SCOPE" },
        { type: "SCOPE", label: "Scope" },
      ]}
      onSectionSelect={(nodeId, sectionId) => handleSelect(nodeId, sectionId)}
      onAddChild={(parentId, childType, parentName) => handleAdd(parentId, childType, parentName)}
      onRenameChild={(scopeId, initialName) => handleRename(scopeId, initialName)}
      onDeleteChild={(scopeId, scopeName, learningsCount) => handleDelete(scopeId, scopeName, learningsCount)}
      showChildrenCount={true}
      showSectionBadge={true}
    />
  );
}
```

**Customization Tips:**
- Only pass the action handlers (`onAddChild`, `onRenameChild`, `onDeleteChild`) your use case needs — unneeded buttons won't render
- Use `showChildrenCount={false}` to hide the children count badge on node headers
- Use `showSectionBadge={false}` to hide the metric badge on section items
- Use `searchQuery` with `onSearchCountChange` to implement a search bar above the tree

---

## API Reference

### Props

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `data` | `ScopeTreeNode \| null` | ✅ | — | Root node of the tree. Pass `null` to render nothing. |
| `sectionsConfig` | `TreeSectionConfig[]` | ❌ | `[]` | Defines section tabs shown under each expanded node. |
| `nodeTypesConfig` | `NodeTypeConfig[]` | ❌ | `[]` | Defines node labels and add-child behavior per depth level. |
| `defaultExpandedIds` | `string[]` | ❌ | `[]` | Node IDs to expand by default on first render. |
| `searchQuery` | `string` | ❌ | `''` | Filters nodes by name. Non-matching subtrees are hidden. |
| `searchSections` | `boolean` | ❌ | `false` | Whether search query also matches section item labels alongside node names. |
| `onSearchCountChange` | `(count: number) => void` | ❌ | — | Fired when the search result count changes. |
| `onSectionSelect` | `(nodeId: string, sectionId: string) => void` | ❌ | — | Fired when a section tab is clicked. Returns the node ID and section ID. |
| `onAddChild` | `(parentId: string, childType: 'SCOPE' \| 'SUBSCOPE', parentName?: string) => void` | ❌ | — | If passed, an Add button appears in the node menu. |
| `onRenameChild` | `(scopeId: string, initialName: string) => void` | ❌ | — | If passed, a Rename button appears in the node menu. |
| `onDeleteChild` | `(scopeId: string, scopeName: string, learningsCount: number) => void` | ❌ | — | If passed, a Delete button appears in the node menu. |
| `selectedRuleSetId` | `string \| null` | ❌ | — | ID of the node to auto-select on load. |
| `activeSectionId` | `string` | ❌ | — | Section ID to auto-activate alongside `selectedRuleSetId`. |
| `isDraftMode` | `boolean` | ❌ | `false` | Whether to display the draft status chip on section items when drafts are available. |
| `enableEllipsis` | `boolean` | ❌ | `false` | Enables text truncation with ellipsis for long section labels. |
| `draftChipClassName` | `string` | ❌ | — | Custom CSS class name to style the draft chip element. |
| `draftChipDotClassName` | `string` | ❌ | — | Custom CSS class name to style the indicator dot inside the draft chip. |
| `draftChipStyle` | `React.CSSProperties` | ❌ | — | Inline style overrides for the draft chip element. |
| `showChildrenCount` | `boolean` | ❌ | `true` | Whether to show the children count badge on parent node headers (including top assistant name node). |
| `showSectionBadge` | `boolean` | ❌ | `true` | Whether to show the metric badge on section items. |
| `showNodeOptions` | `boolean` | ❌ | `true` | Whether to show the 3-dot menu options on node headers. |
| `hideEmptyNodes` | `boolean` | ❌ | `false` | If `true`, nodes with no children and no sections are hidden. |
| `showEmptyState` | `boolean` | ❌ | `false` | Whether to show an empty state UI when an expanded node has no children/sections. |
| `emptyStateText` | `string` | ❌ | `'No data present'` | Custom text to display in the empty state UI when `showEmptyState` is `true`. |

---

### `TreeSectionConfig`

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | `string` | ✅ | Unique section identifier. |
| `label` | `string` | ✅ | Display label for the section tab. |
| `icon` | `ElementType` | ✅ | Lucide icon component to show next to the label. |
| `badgeKey` | `keyof NodeMetrics` | ❌ | Maps to a key in `node.metrics` to show as a badge count. |
| `isVisible` | `(node: ScopeTreeNode, depth: number) => boolean` | ❌ | Optional visibility check per node. If omitted, section is visible for all nodes. |

---

### `NodeTypeConfig`

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `type` | `string` | ✅ | Node type identifier (e.g. `'GLOBAL'`, `'SCOPE'`, `'SUBSCOPE'`). |
| `label` | `string` | ✅ | Display label used in delete confirmation text. |
| `addChildLabel` | `string` | ❌ | Label for the add child button (e.g. `'Add Scope'`). Required if `addChildType` is set. |
| `addChildType` | `string` | ❌ | The type of child node to create. If omitted, no add button is shown for this node type. |

---

### `ScopeTreeNode`

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | `string` | ✅ | Unique identifier for the node. |
| `name` | `string` | ✅ | Display name of the node. |
| `type` | `'GLOBAL' \| 'SCOPE' \| 'SUBSCOPE' \| 'Custom'` | ✅ | Node type. |
| `metrics` | `NodeMetrics` | ✅ | Metric values used by section badges. |
| `children` | `ScopeTreeNode[]` | ✅ | Child nodes. Pass `[]` for leaf nodes. |

---

## Type Definitions

```ts
export interface TreeSidebarProps {
  data: ScopeTreeNode | null;
  defaultExpandedIds?: string[];
  onSectionSelect?: (nodeId: string, sectionId: string) => void;
  onNodeOptionsClick?: (nodeId: string) => void;
  onAddChild?: (parentId: string, childType: 'SCOPE' | 'SUBSCOPE', parentName?: string) => void;
  onRenameChild?: (scopeId: string, initialName: string) => void;
  onDeleteChild?: (scopeId: string, scopeName: string, learningsCount: number) => void;
  searchQuery?: string;
  onSearchCountChange?: (count: number) => void;
  sectionsConfig?: TreeSectionConfig[];
  nodeTypesConfig?: NodeTypeConfig[];
  selectedRuleSetId?: string | null;
  activeSectionId?: string;
  showChildrenCount?: boolean;
  showSectionBadge?: boolean;
  isDraftMode?: boolean;
  enableEllipsis?: boolean;
  draftChipClassName?: string;
  draftChipDotClassName?: string;
  draftChipStyle?: React.CSSProperties;
}

export interface TreeSectionConfig {
  id: string;
  label: string;
  icon: any;
  badgeKey?: keyof NodeMetrics;
  isVisible?: (node: ScopeTreeNode, depth: number) => boolean;
}

export interface NodeTypeConfig {
  type: string;
  label: string;
  addChildLabel?: string;
  addChildType?: string;
}

export interface ScopeTreeNode {
  id: string;
  name: string;
  type: 'GLOBAL' | 'SCOPE' | 'SUBSCOPE' | 'Custom';
  metrics: NodeMetrics;
  children: ScopeTreeNode[];
}

export interface NodeMetrics {
  learningsCount: number;
  stationsCount?: number;
}
```

---

## Examples

### With search

```tsx
const [searchQuery, setSearchQuery] = useState('');
const [searchCount, setSearchCount] = useState(0);

<>
  <input
    value={searchQuery}
    onChange={(e) => setSearchQuery(e.target.value)}
    placeholder="Search scopes..."
  />
  <span>{searchCount} results</span>
  <TreeSidebar
    data={treeData}
    sectionsConfig={sectionsConfig}
    nodeTypesConfig={nodeTypesConfig}
    searchQuery={searchQuery}
    onSearchCountChange={setSearchCount}
  />
</>
```

### With only rename and delete (no add)

```tsx
<TreeSidebar
  data={treeData}
  sectionsConfig={sectionsConfig}
  nodeTypesConfig={nodeTypesConfig}
  onRenameChild={(scopeId, name) => handleRename(scopeId, name)}
  onDeleteChild={(scopeId, name, count) => handleDelete(scopeId, name, count)}
/>
```

### With badges hidden

```tsx
<TreeSidebar
  data={treeData}
  sectionsConfig={sectionsConfig}
  nodeTypesConfig={nodeTypesConfig}
  showChildrenCount={false}
  showSectionBadge={false}
/>
```

### With auto-selected node

```tsx
<TreeSidebar
  data={treeData}
  sectionsConfig={sectionsConfig}
  nodeTypesConfig={nodeTypesConfig}
  selectedRuleSetId="scope-1"
  activeSectionId="learnings"
/>
```

### With multiple sections

```tsx
import { BookOpen, RadioTower } from 'lucide-react';

<TreeSidebar
  data={treeData}
  sectionsConfig={[
    { id: 'learnings', label: 'Learnings', icon: BookOpen, badgeKey: 'learningsCount' },
    {
      id: 'stations',
      label: 'Stations',
      icon: RadioTower,
      badgeKey: 'stationsCount',
      isVisible: (node, depth) => depth > 0, // Only show for non-root nodes
    },
  ]}
  nodeTypesConfig={nodeTypesConfig}
/>
```

---

## Notes

- `TreeSidebar` is **display-only** — no internal data fetching. All state and data management lives in the consuming app.
- Action buttons (Add, Rename, Delete) are **conditionally rendered** — only shown when the corresponding handler prop is passed.
- The `nodeTypesConfig` array maps to tree depth — index `0` applies to the root node, index `1` to its children, and so on. If the tree is deeper than the config array, the last config entry is reused.
- Delete is automatically **disabled** for nodes that have children, with a tooltip explaining why.
- The root node auto-expands on load and whenever `data` changes.
- Search expansion is automatic — all ancestor nodes of matching results are expanded.



# Assign Reminder & Approval Manager

A configurable modal workflow for assigning users to approval levels, managing
due dates and reminders, and tracking review status.

## Features

- Multi-tab interface (Assignees, Reminders, Review Status)
- Multi-level approval workflows
- Controlled and uncontrolled state support
- Async user search and assignment
- Due date management
- Final approval workflow support
- Visual approval progress tracking
- Customizable metadata, tabs, and priority badges
- Reusable UI components (Dropdowns, Date Pickers, Checkboxes)

---

## Installation

```bash
npm install @e-llm-studio/creative-workspace-ui-component
```

## Public exports

```tsx
import {
  AssignReminderWrapper,
  AssignReminderLevels,
} from "@e-llm-studio/creative-workspace-ui-component";
```

- `AssignReminderWrapper` provides the complete modal, tabs, validation,
  reminders, review status, and footer actions.
- `AssignReminderLevels` provides the controlled approval-level editor for
  applications that supply their own surrounding UI.

Internal reminder components, utilities, constants, and AssignReminders types
are not currently exported from the package root.

## Props

| Prop | Type | Description |
|--------|--------|-------------|
| `metadata` | `MetaData` | Customizes modal title, priority badge, tabs, and display settings. |
| `reviewData` | `Record<number, Record<string, boolean>>` | Approval status mapping used by Review Status. |
| `levels` | `Level[]` | Approval workflow levels. |
| `setLevels` | `Dispatch` | Controlled state setter for levels. |
| `requireFinalApproval` | `boolean` | Enables final approval step. |
| `finalApprovalStatus` | `boolean` | Status for final approval. |
| `setRequireFinalApproval` | `Dispatch` | Controlled setter for final approval state. |
| `approvalDueDate` | `Date \| null` | Final approval due date. |
| `setApprovalDueDate` | `Dispatch` | Controlled setter for approval due date. |
| `fetchUsers` | `FetchUsersFunction` | Async user lookup function. |
| `finalApprovalDueDate` | `Date \| null` | Required by `AssignReminderLevels`. Sets the final approval deadline used to constrain level due dates. |
| `onClose` | `() => void` | Called when modal closes. |
| `onSave` | `(payload) => void` | Returns configured workflow data. |
| `onValidationError` | `(message) => void` | Handles validation errors. |

---

## Core Types

### MetaData

```ts
interface MetaData {
  wrapperTitle?: string;
  wrapperSubTitle?: string;
  wrapperPriority?: string;
  wrapperPriorityStyles?: React.CSSProperties;
  tabData?: TabData[];
  showFinalApprovalDueDate?: boolean;
}
```

### Level

```ts
interface Level {
  headerName: string;
  title: string;
  isMandatory: boolean;
  hasDueDate: boolean;
  dueDate: Date | null;
  assignees: AssigneeUser[];
}
```

### AssigneeUser

```ts
interface AssigneeUser {
  id: any;
  name: string;
  email: string;
  accessLevel?: string;
}
```

### SavePayload

```ts
interface SavePayload {
  levels: Level[];
  requireFinalApproval: boolean;
  finalApprovalDueDate: Date | null;
  activeTab: "assignees" | "reminders" | "review";
}
```

---

## Included Components

### AssignReminderLevels

Manages approval levels, assignees, due dates, and final approval configuration.

### ReviewStatus

Displays approval progress and assignee review status using `reviewData`.

### LevelData

Handles assignee search, selection, and access-level assignment.

### UI Components

- `CustomDropdown`
- `CustomDatePicker`
- `AssignLevelDatePicker`
- `CustomCheckbox`

---

## Basic usage

```tsx
import { useState } from "react";
import {
  AssignReminderWrapper,
} from "@e-llm-studio/creative-workspace-ui-component";

export function ContractReview() {
  const [open, setOpen] = useState(false);

  const fetchUsers = async (query: string) => {
    const response = await fetch(
      `/api/users?query=${encodeURIComponent(query)}`,
    );
    return response.json();
  };

  return (
    <>
      <button onClick={() => setOpen(true)}>Assign reviewers</button>

      {open && (
        <AssignReminderWrapper
          fetchUsers={fetchUsers}
          requireFinalApproval
          finalApprovalStatus="approved"
          metadata={{
            wrapperTitle: "Contract Review",
            wrapperPriority: "High",
          }}
          onClose={() => setOpen(false)}
          onValidationError={(message) => console.error(message)}
          onSave={(payload) => {
            console.log(payload);
            setOpen(false);
          }}
        />
      )}
    </>
  );
}
```

`fetchUsers` is required and must return users containing `id`, `name`, and `email`.
The wrapper may be used with its local state or connected to parent state through `levels`, `requireFinalApproval`, `approvalDueDate`, and their setter props.

## Key capabilities

- Debounced asynchronous assignee search
- Sequential approval levels and access roles
- Per-level and final approval due-date validation
- Optional owner final sign-off
- Dedicated final approval status
- Manual, scheduled, and escalation reminders
- Approval and rejection progress tracking
- Configurable tabs, labels, colors, visibility, and inline style overrides
- Editing restrictions for read-only or partially locked workflows

On a valid save, `onSave` receives the normalized visible levels, final approval setting, final due date, active tab, schedules, and reminder owners.
The host application remains responsible for persistence and closing the modal.

For the complete props, validation rules, reminder configuration, styling slots, examples, and type reference, see the
[AssignReminders component guide](src/components/AssignReminders/README.md).

---
_Source: https://npm.io/package/@e-llm-studio/creative-workspace-ui-component · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
