# @rdi-ui/pipeline

Shared pipeline management UI package for RDI.

## Usage

The package uses a flat props API with a discriminated union based on `clientType`:

### Cloud Consumer

```tsx
import { PipelineManagement } from '@rdi-ui/pipeline';

<PipelineManagement
  clientType="cloud"
  basePath="pipeline"
  navigation={navigationService}
  i18n={i18n}
  draft={{
    getDraft: () => api.getDraft(),
    saveDraft: (data) => api.saveDraft(data)
  }}
  getWorkspace={() => api.getWorkspace()}
  getTargetDatabases={() => api.getTargetDatabases()}
/>
```

### Direct Consumer

```tsx
import { PipelineManagement } from '@rdi-ui/pipeline';

<PipelineManagement
  clientType="direct"
  basePath="pipeline"
  navigation={navigationService}
  draft={{
    getDraft: () => api.getDraft(),
    saveDraft: (data) => api.saveDraft(data)
  }}
/>
```

## Props

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `clientType` | `'cloud' \| 'direct'` | ✓ | Determines available features |
| `basePath` | `string` | ✓ | Base path for routing (e.g., `"pipeline"`) |
| `navigation` | `NavigationService` | ✓ | Navigation service implementation |
| `i18n` | `i18n` | | i18next instance (falls back to internal) |
| `analytics` | `AnalyticsCapabilityConfig` | | Analytics hooks for UI events (`track`) |
| `draft` | `DraftCapabilityConfig` | | Draft persistence (getDraft / saveDraft / deleteDraft) |
| `getWorkspace` | `() => Promise<Workspace>` | Cloud only | Fetch workspace status |
| `getTargetDatabases` | `() => Promise<TargetDatabase[]>` | Cloud only | Fetch target databases |

## Stability

Function props should be memoized if created inline to prevent unnecessary re-renders:

```tsx
const getWorkspace = useCallback(() => api.getWorkspace(), [api]);
```

## Analytics capability

`analytics` is an optional capability. The package currently uses only `track(event, properties?)`.

```tsx
import { PipelineManagement } from '@rdi-ui/pipeline';

const analytics = {
  track: (event: string, properties?: Record<string, unknown>) => {
    // Host can enrich all events before forwarding to real analytics SDK.
    hostAnalytics.track(event, {
      ...properties,
      newUi: true
    });
  }
};

<PipelineManagement
  basePath="pipeline"
  navigation={navigationService}
  analytics={analytics}
  // ...other required capabilities
/>;
```

Playground contains a mock example at `playground/src/components/PipelineWrapper/PipelineWrapper.tsx`.

## NavigationService

Consumers must provide a `NavigationService` implementation:

```ts
interface NavigationOptions {
  replace?: boolean;
}

interface NavigationService {
  navigate: (path: string, options?: NavigationOptions) => void;
  getPath: () => string;
  subscribe: (callback: () => void) => () => void;
  exit: () => void;
}
```

See `src/services/navigation/README.md` for integration examples.

## Internationalization (i18n)

The package supports i18n via an optional `i18next` instance. If not provided, an internal fallback is used. Translations are auto-registered under the `rdiPipeline` namespace.

See [`src/i18n/README.md`](./src/i18n/README.md) for full documentation.

## Toast notifications

Mount Redis UI `<Toaster />` **once** under `ThemeProvider` at application root, above `PipelineManagement`, so success toasts can appear after activating pipeline updates (`active: true`). If your app already renders a global Toaster for other features, reuse that instance instead of adding a second container.

```tsx
import { Toaster, toast } from '@redis-ui/components';
import { ThemeProvider } from 'styled-components';
import { themes } from '@redis-ui/styles';
import { PipelineManagement } from '@rdi-ui/pipeline';

<ThemeProvider theme={themes.light}>
  <Toaster position={toast.Position.TopCenter} />
  <PipelineManagement {...pipelineProps} />
</ThemeProvider>
```

## Development

The playground requires the RDI mock server to serve API responses:

```bash
npm run mock-server -w @rdi-ui/pipeline   # start mock server (port 4400)
npm start -w packages/pipeline         # start playground (port 5173)
```

Run both in separate terminals, or use E2E tests which start them automatically.

The transformation playground uses in-browser mocks by default. To exercise the local AI and Java dry-run services through Vite's development-only proxies, start the AI service on `8090`, start `transform-playground-api` on `8092`, then run:

```bash
USE_LIVE_TRANSFORMATION_SERVICES=true npm start -w packages/pipeline
```

Override the defaults with `TRANSFORMATION_AI_TARGET` and `TRANSFORMATION_DRY_RUN_TARGET`. Vite adds the local internal identity headers; this direct integration is not part of the published package. Production consumers continue to provide the transformation AI and dry-run capabilities through their host boundary.

From the repository root, the complete setup can be started with one command:

```bash
scripts/start-transformation-playground.sh
```

This starts the mock server, local AI service, dry-run API, and playground and
stops all four when you press `Ctrl-C`. It uses the documented default ports,
but automatically moves each service to the next available port when needed.
It uses existing service artifacts for fast startup; pass `--build` to rebuild
the UI and both local services first.

Stop the setup from another terminal with:

```bash
scripts/stop-transformation-playground.sh
```

The service repositories default to adjacent checkouts and can be overridden
with `RDI_AI_SERVICE_REPO` and `RDI_TRANSFORM_PLAYGROUND_REPO`.

```bash
npm test -w packages/pipeline     # unit tests
npm run lint -w packages/pipeline # eslint
```
