Skip to content
Draft
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
6 changes: 3 additions & 3 deletions docs/components/custom-widgets.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Custom widgets are React components that integrate with the Widget Layout system

Widgets are loaded through a multi-step process:

1. **Widget Mapping**: The backend provides widget configuration via `/api/chrome-service/v1/dashboard-templates/widget-mapping`
1. **Widget Mapping**: The backend provides widget configuration via `/api/widget-layout/v1/widget-mapping`
2. **Module Federation**: Widgets are loaded as federated modules using ScalprumComponent (configured via `fec.config.js`)
3. **Grid Integration**: Each widget is wrapped in a GridTile that provides layout and interaction capabilities

Expand Down Expand Up @@ -129,7 +129,7 @@ npm run build

### Step 3: Configure Widget Mapping

The widget mapping must be provided by the backend API at `/api/chrome-service/v1/dashboard-templates/widget-mapping`. Example configuration:
The widget mapping must be provided by the backend API at `/api/widget-layout/v1/widget-mapping`. Example configuration:

```json
{
Expand Down Expand Up @@ -388,7 +388,7 @@ Ensure your widget is properly registered by checking the widget mapping:

```tsx
// Test if widget is available
const widgetMapping = await fetch('/api/chrome-service/v1/dashboard-templates/widget-mapping')
const widgetMapping = await fetch('/api/widget-layout/v1/widget-mapping')
.then(res => res.json());

console.log('Available widgets:', Object.keys(widgetMapping.data));
Expand Down
25 changes: 7 additions & 18 deletions docs/layout-data-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,38 +343,30 @@ export type WidgetMapping = {

## API Endpoints

### Base Templates
**Note**: The API has been migrated from `/api/chrome-service/v1/dashboard-templates` to `/api/widget-layout/v1/`. The base template fetch functions have been removed, and the delete dashboard template functionality is no longer available. They were not used in this codebase.

```bash
GET /api/chrome-service/v1/dashboard-templates/base-template
# Returns: BaseTemplate[]

GET /api/chrome-service/v1/dashboard-templates/base-template?dashboard=landingPage
# Returns: BaseTemplate
```

### User Templates
### Dashboard Templates

```bash
GET /api/chrome-service/v1/dashboard-templates
GET /api/widget-layout/v1/
# Returns: DashboardTemplate[]

GET /api/chrome-service/v1/dashboard-templates?dashboard=landingPage
GET /api/widget-layout/v1/?dashboardType=landingPage
# Returns: DashboardTemplate[]
```

### Widget Mapping

```bash
GET /api/chrome-service/v1/dashboard-templates/widget-mapping
GET /api/widget-layout/v1/widget-mapping
# Returns: WidgetMapping
```

### Template Management

```bash
# Update template configuration
PATCH /api/chrome-service/v1/dashboard-templates/{templateId}
PATCH /api/widget-layout/v1/{templateId}
Content-Type: application/json

{
Expand All @@ -387,10 +379,7 @@ Content-Type: application/json
}

# Reset template to base configuration
POST /api/chrome-service/v1/dashboard-templates/{templateId}/reset

# Delete template
DELETE /api/chrome-service/v1/dashboard-templates/{templateId}
POST /api/widget-layout/v1/{templateId}/reset
```

## Data Flow and Persistence
Expand Down
7 changes: 2 additions & 5 deletions fec.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,8 @@ module.exports = {
_unstableHotReload: process.env.HOT === 'true',
routes: {
...(process.env.CONFIG_PORT && {
'/api/chrome-service/v1/static': {
host: `http://localhost:${process.env.CONFIG_PORT}`,
},
'/api/chrome-service/v1/dashboard-templates': {
host: `http://localhost:${process.env.CONFIG_PORT}`,
'/api/widget-layout': {
target: 'http://localhost:8000',
},
}),
},
Expand Down
3 changes: 2 additions & 1 deletion src/Components/DnDLayout/GridLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const debouncedPatchDashboardTemplate = DebouncePromise(patchDashboardTemplate,
onlyResolvesLast: true,
});

const GridLayout = ({ isLayoutLocked = false, layoutType = 'landingPage' }: { isLayoutLocked?: boolean; layoutType?: LayoutTypes }) => {
const GridLayout = ({ isLayoutLocked = false, layoutType = 'landing-landingPage' }: { isLayoutLocked?: boolean; layoutType?: LayoutTypes }) => {
const [isDragging, setIsDragging] = useState(false);
const [isInitialRender, setIsInitialRender] = useState(true);
const [isLoaded, setIsLoaded] = useState(false);
Expand Down Expand Up @@ -296,6 +296,7 @@ const GridLayout = ({ isLayoutLocked = false, layoutType = 'landingPage' }: { is
// eslint-disable-next-line @typescript-eslint/no-unused-vars
.map(({ widgetType, title, ...rest }, index) => {
const widget = getWidget(widgetMapping, widgetType);
console.log({ widgetType, widgetMapping, widget });
if (!widget) {
return null;
}
Expand Down
2 changes: 2 additions & 0 deletions src/Routes/Default/Default.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ const DefaultRoute = (props: { layoutType?: LayoutTypes }) => {
const widgetConfig = value.config;
const hasPermissions = widgetConfig && widgetConfig.permissions ? await checkPermissions(widgetConfig.permissions) : true;
if (hasPermissions) {
// this key is composed on the backend side to ensure unique widget names when collect from FEO
// '<scope>-<moduleName>(-<importName>?)'
resolvedAcc[key] = value;
}
return acc;
Expand Down
39 changes: 12 additions & 27 deletions src/api/dashboard-templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const getRequestHeaders = () => ({

export const widgetIdSeparator = '#';

export type LayoutTypes = 'landingPage';
export type LayoutTypes = 'landingPage' | 'landing-landingPage';

export type Variants = 'sm' | 'md' | 'lg' | 'xl';

Expand Down Expand Up @@ -118,33 +118,27 @@ export const getWidgetIdentifier = (widgetType: string, uniqueId: string = crypt
return `${widgetType}${widgetIdSeparator}${uniqueId}`;
};

export async function getBaseDashboardTemplate(): Promise<BaseTemplate[]>;
export async function getBaseDashboardTemplate(type: LayoutTypes): Promise<BaseTemplate>;
export async function getBaseDashboardTemplate(type?: LayoutTypes): Promise<BaseTemplate | BaseTemplate[]> {
const resp = await fetch(`/api/chrome-service/v1/dashboard-templates/base-template${type ? `?dashboard=${type}` : ''}`, {
method: 'GET',
headers: getRequestHeaders(),
});
handleErrors(resp);
const json = await resp.json();
return json.data;
}

// Returns multiple templates for a user (user can have multiple template copies) - we will render the one marked default: true by default
export async function getDashboardTemplates(): Promise<DashboardTemplate[]>;
export async function getDashboardTemplates(type: LayoutTypes): Promise<DashboardTemplate[]>;
export async function getDashboardTemplates(type?: LayoutTypes): Promise<DashboardTemplate | DashboardTemplate[]> {
const resp = await fetch(`/api/chrome-service/v1/dashboard-templates${type ? `?dashboard=${type}` : ''}`, {
const searchParams = new URLSearchParams();
if (type) {
searchParams.append('dashboardType', type);
}
const url = new URL(`/api/widget-layout/v1/`, window.location.origin);
url.search = searchParams.toString();
const resp = await fetch(url.toString(), {
method: 'GET',
headers: getRequestHeaders(),
});
handleErrors(resp);
const json = await resp.json();
console.log({ json });
return json.data;
}

export async function getWidgetMapping(): Promise<WidgetMapping> {
const resp = await fetch(`/api/chrome-service/v1/dashboard-templates/widget-mapping`, {
const resp = await fetch(`/api/widget-layout/v1/widget-mapping`, {
method: 'GET',
headers: getRequestHeaders(),
});
Expand All @@ -154,7 +148,7 @@ export async function getWidgetMapping(): Promise<WidgetMapping> {
}

export const resetDashboardTemplate = async (templateId: number): Promise<DashboardTemplate> => {
const resp = await fetch(`/api/chrome-service/v1/dashboard-templates/${templateId}/reset`, {
const resp = await fetch(`/api/widget-layout/v1/${templateId}/reset`, {
method: 'POST',
headers: getRequestHeaders(),
});
Expand All @@ -167,7 +161,7 @@ export const patchDashboardTemplate = async (
templateId: DashboardTemplate['id'],
data: { templateConfig: PartialTemplateConfig }
): Promise<DashboardTemplate> => {
const resp = await fetch(`/api/chrome-service/v1/dashboard-templates/${templateId}`, {
const resp = await fetch(`/api/widget-layout/v1/${templateId}`, {
method: 'PATCH',
headers: getRequestHeaders(),
body: JSON.stringify(data),
Expand All @@ -177,15 +171,6 @@ export const patchDashboardTemplate = async (
return json.data;
};

export const deleteDashboardTemplate = async (templateId: DashboardTemplate['id']): Promise<boolean> => {
const resp = await fetch(`/api/chrome-service/v1/dashboard-templates/${templateId}`, {
method: 'DELETE',
headers: getRequestHeaders(),
});
handleErrors(resp);
return resp.status === 204;
};

export const getDefaultTemplate = (templates: DashboardTemplate[]): DashboardTemplate | undefined => {
return templates.find((itm) => itm.default === true);
};
Expand Down