Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 7 additions & 59 deletions apps/apollo-vertex/app/api/datafabric/[...path]/route.ts
Original file line number Diff line number Diff line change
@@ -1,76 +1,24 @@
import { type NextRequest, NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { proxyToUiPath } from "@/lib/api-proxy";

function getAuthHeader(request: NextRequest) {
const authHeader = request.headers.get("authorization");
if (!authHeader) {
return null;
}
return authHeader;
}

function buildTargetUrl(path: string[], search: string) {
return `https://alpha.uipath.com/${path.join("/")}${search}`;
}
const DATAFABRIC_SEGMENT = "datafabric_";

export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ path: string[] }> },
) {
const authHeader = getAuthHeader(request);
if (!authHeader) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}

const { path } = await params;
const targetUrl = buildTargetUrl(path, request.nextUrl.search);

const response = await fetch(targetUrl, {
method: "GET",
headers: {
Authorization: authHeader,
},
signal: request.signal,
});

const text = await response.text();
return new NextResponse(text, {
status: response.status,
headers: {
"Content-Type":
response.headers.get("content-type") ?? "application/json",
},
return proxyToUiPath(request, path, {
requiredServiceSegment: DATAFABRIC_SEGMENT,
});
}

export async function POST(
request: NextRequest,
{ params }: { params: Promise<{ path: string[] }> },
) {
const authHeader = getAuthHeader(request);
if (!authHeader) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}

const { path } = await params;
const targetUrl = buildTargetUrl(path, request.nextUrl.search);
const body = await request.text();

const response = await fetch(targetUrl, {
method: "POST",
headers: {
"Content-Type": request.headers.get("content-type") ?? "application/json",
Authorization: authHeader,
},
body,
signal: request.signal,
});

const text = await response.text();
return new NextResponse(text, {
status: response.status,
headers: {
"Content-Type":
response.headers.get("content-type") ?? "application/json",
},
return proxyToUiPath(request, path, {
requiredServiceSegment: DATAFABRIC_SEGMENT,
});
}
24 changes: 24 additions & 0 deletions apps/apollo-vertex/app/api/insights/[...path]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { NextRequest } from "next/server";
import { proxyToUiPath } from "@/lib/api-proxy";

const INSIGHTS_SEGMENT = "insightsrtm_";

export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ path: string[] }> },
) {
const { path } = await params;
return proxyToUiPath(request, path, {
requiredServiceSegment: INSIGHTS_SEGMENT,
});
}

export async function POST(
request: NextRequest,
{ params }: { params: Promise<{ path: string[] }> },
) {
const { path } = await params;
return proxyToUiPath(request, path, {
requiredServiceSegment: INSIGHTS_SEGMENT,
});
}
92 changes: 92 additions & 0 deletions apps/apollo-vertex/app/components/bar-chart/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,95 @@ A metric broken down by a categorical dimension.
```bash
npx shadcn@latest add @uipath/bar-chart
```

Installs both the prop-driven `BarChart` view and the `BarChartWithAdapter` variant.

## View

`BarChart` renders pre-shaped rows. Use it when the data is already in memory.

```tsx
import { BarChart } from "@/components/ui/bar-chart";

const rows = [
{
id: "engineering",
dimensions: [{ key: "department", label: "Engineering" }],
values: { spend: 28000 },
formattedValues: { spend: "$28,000" },
formattedPercents: { spend: "32.2%" },
},
// ...
];

<BarChart
rows={rows}
series={[{ id: "spend", label: "Total spend" }]}
/>
```

### Props

- `rows: BarChartRow[]` — one row per category. Each row carries its dimensions, raw `values`, and pre-formatted `formattedValues`/`formattedPercents` for the tooltip and labels.
- `series: BarChartSeries[]` — one entry per metric. With multiple series, bars are grouped per category. Set `color` to override the palette.

## With adapter

`BarChartWithAdapter` wires the chart to a `DataAdapter`. It manages its own data fetching, Suspense, and error boundary — drop it anywhere a `QueryClientProvider` is in scope.

The chart package does not bundle an adapter. Install one of the ready-made adapters (or implement the `DataAdapter` interface yourself):

```bash
npx shadcn@latest add @uipath/data-fabric-adapter
# or
npx shadcn@latest add @uipath/insights-adapter
```

```tsx
import { BarChartWithAdapter } from "@/components/ui/bar-chart";
import { dataFabricAdapter } from "@/lib/data-fabric-adapter";

const adapter = dataFabricAdapter({
baseUrl: "/api/datafabric/.../api",
accessToken,
entityName: "Orders",
});

const dataModel = {
id: "orders-by-status",
dimensions: [
{ id: "Status", display: "Status", type: "string" as const },
],
metrics: [
{
id: "total",
display: "Total orders",
expression: {
type: "aggregate" as const,
aggregation: "COUNT" as const,
argument: { id: "Id", display: "Id", type: "numeric" as const },
},
},
],
};

const configuration = {
id: "orders-bar",
name: "Orders by status",
type: "bar" as const,
dimensions: ["Status"],
metrics: ["total"],
};

<BarChartWithAdapter
configuration={configuration}
dataModel={dataModel}
dataAdapter={adapter}
/>
```

### Props

- `configuration: BarChartConfiguration` — `dimensions`/`metrics` reference IDs that must exist in `dataModel`. Optional `filters`, `joins`, `from`, `filterTableId`.
- `dataModel: ChartDataModel<StringModelField>` — defines available dimensions (`StringModelField` only — bar charts need a categorical X axis) and metrics with `expression` shape.
- `dataAdapter: DataAdapter` — implementation that runs the query. Use `dataFabricAdapter` or `insightsAdapter` from `@uipath/data-fabric-adapter` / `@uipath/insights-adapter`, or implement the interface yourself.
96 changes: 95 additions & 1 deletion apps/apollo-vertex/app/components/distribution-chart/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { DistributionChartTemplate } from '@/templates/charts/DistributionChartT

# Distribution Chart

A histogram over a numeric or datetime dimension.
A histogram over a numeric or datetime dimension. Bins are computed by the adapter and rendered as bars.

<div className="not-prose my-8">
<DistributionChartTemplate />
Expand All @@ -13,3 +13,97 @@ A histogram over a numeric or datetime dimension.
```bash
npx shadcn@latest add @uipath/distribution-chart
```

Installs both the prop-driven `DistributionChart` view and the `DistributionChartWithAdapter` variant.

## View

`DistributionChart` plots an array of `{ x, y }` points where `x` is the bin label. Same shape as `LineChart` but rendered as bars (no curve).

```tsx
import { DistributionChart } from "@/components/ui/distribution-chart";

const data = [
{ x: "0–100", y: 12 },
{ x: "100–200", y: 28 },
{ x: "200–300", y: 19 },
// ...
];

const formatValue = (value: number) =>
new Intl.NumberFormat("en-US").format(value);

<DistributionChart
data={data}
seriesLabel="Order count"
formatValue={formatValue}
/>
```

### Props

- `data: Array<{ x: string; y: number }>` — bin label + count.
- `seriesLabel: string` — tooltip label.
- `formatValue: (value: number) => string` — formats Y values.
- `color?: string` — optional override; defaults to `var(--color-primary)`.

## With adapter

`DistributionChartWithAdapter` runs a min/max query, computes bin cutoff points, then queries the binned data — all behind Suspense + error boundary.

The chart package does not bundle an adapter. Install one of the ready-made adapters (or implement the `DataAdapter` interface yourself):

```bash
npx shadcn@latest add @uipath/data-fabric-adapter
# or
npx shadcn@latest add @uipath/insights-adapter
```

```tsx
import { DistributionChartWithAdapter } from "@/components/ui/distribution-chart";
import { dataFabricAdapter } from "@/lib/data-fabric-adapter";

const adapter = dataFabricAdapter({
baseUrl: "/api/datafabric/.../api",
accessToken,
entityName: "Orders",
});

const dataModel = {
id: "order-amount-distribution",
dimensions: [
{ id: "Amount", display: "Amount", type: "numeric" as const },
],
metrics: [
{
id: "count",
display: "Orders",
expression: {
type: "aggregate" as const,
aggregation: "COUNT" as const,
argument: { id: "Id", display: "Id", type: "numeric" as const },
},
},
],
};

const configuration = {
id: "amount-distribution",
name: "Order amount distribution",
type: "distribution" as const,
dimensions: ["Amount"],
metrics: ["count"],
};

<DistributionChartWithAdapter
configuration={configuration}
dataModel={dataModel}
dataAdapter={adapter}
/>
```

### Props

- `configuration: DistributionChartConfiguration` — single dimension + single metric.
- `dataModel: ChartDataModel<NumericOrDatetimeModelField>` — dimension must be `numeric` or `datetime`.
- `dataAdapter: DataAdapter` — implementation that runs the queries.
Loading
Loading