Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dashboard: microapp v2 #999

Merged
merged 32 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
c781ae7
reactive rmf api
koonpeng Aug 13, 2024
64925ce
first test of new micro app architecture
koonpeng Aug 15, 2024
8e703dd
migrate robots tab
koonpeng Aug 16, 2024
0c31f4e
Merge remote-tracking branch 'origin/main' into koonpeng/microapp-v2
koonpeng Aug 16, 2024
c95b5ff
add container
koonpeng Aug 16, 2024
2ed3ef4
docs
koonpeng Aug 16, 2024
d65ccaa
port tasks app
koonpeng Aug 19, 2024
c68874b
implement login route
koonpeng Aug 19, 2024
41f216c
fix routes
koonpeng Aug 19, 2024
eaf6d54
cleanup
koonpeng Aug 19, 2024
d0dd12a
unload current tab when pending transition
koonpeng Aug 19, 2024
3dcef2f
migrated app-base
koonpeng Aug 20, 2024
2ed8628
managed to mock everything needed for appbar tests
koonpeng Aug 20, 2024
b046ada
hacky workaround for react-three-fiber and material conflict
koonpeng Aug 21, 2024
23c1185
test passes
koonpeng Aug 21, 2024
ee58469
Merge remote-tracking branch 'origin/main' into koonpeng/microapp-v2
koonpeng Aug 21, 2024
d4dba00
add AlertManager and DeliveryAlertStore
koonpeng Aug 21, 2024
9910a02
update schema
koonpeng Aug 21, 2024
09dbfcc
Merge remote-tracking branch 'origin/main' into koonpeng/microapp-v2
koonpeng Aug 22, 2024
932b04b
fix design mode
koonpeng Aug 22, 2024
cf84011
ported custom tabs
koonpeng Aug 22, 2024
2421e0b
add key for micro app settings
koonpeng Aug 22, 2024
e432b93
fix onclose
koonpeng Aug 23, 2024
6e3b5aa
fix tasks window
koonpeng Aug 23, 2024
f6d6f7c
fix importing app-config
koonpeng Aug 23, 2024
1a7bf2d
add example
koonpeng Aug 23, 2024
1d6fec8
add custom theme example
koonpeng Aug 26, 2024
7d50262
some fixes to the theme
koonpeng Aug 26, 2024
60fe3b9
add support for toggling dark mode
koonpeng Aug 26, 2024
c61a105
fix tests
koonpeng Aug 26, 2024
d371666
fix alert manager not getting some context
koonpeng Aug 30, 2024
2bc496e
enable admin actions button
koonpeng Sep 3, 2024
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
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"lint-staged": "^15.2.2",
"prettier": "^3.2.5",
"pyright": "1.1.369",
"typescript": "~5.4.3",
"typescript": "~5.5.4",
"typescript-eslint": "^7.5.0"
},
"lint-staged": {
Expand All @@ -34,6 +34,9 @@
"pnpm": {
"overrides": {
"typescript-json-schema>@types/node": "*"
},
"patchedDependencies": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this in, should we add some comments about this patch as well?

I'm not very familiar with patches in this manner, the .patch file was written by you manually, is that right? Or was it recommended somewhere?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was a known problem with mui and three-fiber, the only solution I found is to do a hacky patch.

"@react-three/fiber": "patches/@react-three__fiber.patch"
}
},
"overrides": {
Expand Down
2 changes: 1 addition & 1 deletion packages/api-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"@typescript-eslint/parser": "^7.5.0",
"axios": "1.7.4",
"eslint": "^8.57.0",
"typescript": "~5.4.3",
"typescript": "~5.5.4",
"vitest": "^2.0.4"
},
"files": [
Expand Down
2 changes: 1 addition & 1 deletion packages/dashboard-e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@
"rmf-dashboard": "workspace:*",
"serve": "^11.3.2",
"ts-node": "^9.1.1",
"typescript": "~5.4.3"
"typescript": "~5.5.4"
}
}
55 changes: 27 additions & 28 deletions packages/dashboard/app-config.schema.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AllowedTask": {
"properties": {
"displayName": {
"description": "Configure the display name for the task definition.",
"type": "string"
},
"scheduleEventColor": {
"description": "The color of the event when rendered on the task scheduler in the form of a CSS color string.",
"type": "string"
},
"taskDefinitionId": {
"description": "The task definition to configure.",
"enum": [
"compose-clean",
"custom_compose",
"delivery",
"patrol"
],
"type": "string"
}
},
"required": [
"taskDefinitionId"
],
"type": "object"
},
"BuildConfig": {
"description": "These will be injected at build time, they CANNOT be changed after the bundle is built.",
"properties": {
Expand Down Expand Up @@ -105,33 +131,6 @@
},
"StubAuthConfig": {
"type": "object"
},
"TaskResource": {
"description": "Configuration for task definitions.",
"properties": {
"displayName": {
"description": "Configure the display name for the task definition.",
"type": "string"
},
"scheduleEventColor": {
"description": "The color of the event when rendered on the task scheduler in the form of a CSS color string.",
"type": "string"
},
"taskDefinitionId": {
"description": "The task definition to configure.",
"enum": [
"compose-clean",
"custom_compose",
"delivery",
"patrol"
],
"type": "string"
}
},
"required": [
"taskDefinitionId"
],
"type": "object"
}
},
"properties": {
Expand All @@ -142,7 +141,7 @@
"allowedTasks": {
"description": "List of allowed tasks that can be requested",
"items": {
"$ref": "#/definitions/TaskResource"
"$ref": "#/definitions/AllowedTask"
},
"type": "array"
},
Expand Down
18 changes: 18 additions & 0 deletions packages/dashboard/examples/custom-theme/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%BASE_URL%favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="description"
content="Web application that provides overall visualization and control over the RMF system"
/>
<link rel="shortcut icon" type="image/x-icon" href="%BASE_URL%favicon.ico" />
<title>RMF Dashboard</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/index.tsx"></script>
</body>
</html>
127 changes: 127 additions & 0 deletions packages/dashboard/examples/custom-theme/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import '@fontsource/roboto/300.css';
import '@fontsource/roboto/400.css';
import '@fontsource/roboto/500.css';
import '@fontsource/roboto/700.css';

import { createTheme } from '@mui/material';
import ReactDOM from 'react-dom/client';
import { LocallyPersistentWorkspace, RmfDashboard } from 'rmf-dashboard/components';
import { MicroAppManifest } from 'rmf-dashboard/components/micro-app';
import doorsApp from 'rmf-dashboard/micro-apps/doors-app';
import liftsApp from 'rmf-dashboard/micro-apps/lifts-app';
import createMapApp from 'rmf-dashboard/micro-apps/map-app';
import robotMutexGroupsApp from 'rmf-dashboard/micro-apps/robot-mutex-groups-app';
import robotsApp from 'rmf-dashboard/micro-apps/robots-app';
import tasksApp from 'rmf-dashboard/micro-apps/tasks-app';
import StubAuthenticator from 'rmf-dashboard/services/stub-authenticator';

/* eslint-disable @typescript-eslint/no-unused-vars,@typescript-eslint/ban-ts-comment */
// Polar Night
const nord0 = '#2e3440'; // @ts-ignore
const nord1 = '#3b4252'; // @ts-ignore
const nord2 = '#434c5e'; // @ts-ignore
const nord3 = '#4c566a'; // @ts-ignore

// Snow Storm
const nord4 = '#d8dee9'; // @ts-ignore
const nord5 = '#e5e9f0'; // @ts-ignore
const nord6 = '#eceff4'; // @ts-ignore

// Frost
const nord7 = '#8fbcbb'; // @ts-ignore
const nord8 = '#88c0d0'; // @ts-ignore
const nord9 = '#81a1c1'; // @ts-ignore
const nord10 = '#5e81ac'; // @ts-ignore

// Aurora
const nord11 = '#bf616a'; // @ts-ignore
const nord12 = '#d08770'; // @ts-ignore
const nord13 = '#ebcb8b'; // @ts-ignore
const nord14 = '#a3be8c'; // @ts-ignore
const nord15 = '#b48ead'; // @ts-ignore
/* eslint-enable @typescript-eslint/no-unused-vars,@typescript-eslint/ban-ts-comment */

const nordTheme = createTheme({
palette: {
mode: 'dark',
primary: {
main: nord8,
contrastText: nord1,
},
secondary: {
main: nord9,
},
text: {
primary: nord4,
secondary: nord6,
disabled: nord5,
},
error: {
main: nord11,
},
warning: {
main: nord13,
},
success: {
main: nord14,
},
background: { default: nord0, paper: nord1 },
},
});

const mapApp = createMapApp({
attributionPrefix: 'Open-RMF',
defaultMapLevel: 'L1',
defaultRobotZoom: 20,
defaultZoom: 6,
});

const appRegistry: MicroAppManifest[] = [
mapApp,
doorsApp,
liftsApp,
robotsApp,
robotMutexGroupsApp,
tasksApp,
];

export default function App() {
return (
<RmfDashboard
apiServerUrl="http://localhost:8000"
trajectoryServerUrl="http://localhost:8006"
authenticator={new StubAuthenticator()}
helpLink="https://osrf.github.io/ros2multirobotbook/rmf-core.html"
reportIssueLink="https://github.com/open-rmf/rmf-web/issues"
themes={{ default: createTheme(), dark: nordTheme }}
resources={{ fleets: {}, logos: { header: '/resources/defaultLogo.png' } }}
tasks={{
allowedTasks: [
{ taskDefinitionId: 'patrol' },
{ taskDefinitionId: 'delivery' },
{ taskDefinitionId: 'compose-clean' },
{ taskDefinitionId: 'custom_compose' },
],
pickupZones: [],
cartIds: [],
}}
tabs={[
{
name: 'Example',
route: '',
element: (
<LocallyPersistentWorkspace
defaultWindows={[]}
allowDesignMode
appRegistry={appRegistry}
storageKey="custom-workspace"
/>
),
},
]}
/>
);
}

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(<App />);
18 changes: 18 additions & 0 deletions packages/dashboard/examples/demo/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%BASE_URL%favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="description"
content="Web application that provides overall visualization and control over the RMF system"
/>
<link rel="shortcut icon" type="image/x-icon" href="%BASE_URL%favicon.ico" />
<title>RMF Dashboard</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/index.tsx"></script>
</body>
</html>
114 changes: 114 additions & 0 deletions packages/dashboard/examples/demo/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import '@fontsource/roboto/300.css';
import '@fontsource/roboto/400.css';
import '@fontsource/roboto/500.css';
import '@fontsource/roboto/700.css';

import ReactDOM from 'react-dom/client';
import {
InitialWindow,
LocallyPersistentWorkspace,
RmfDashboard,
Workspace,
} from 'rmf-dashboard/components';
import { MicroAppManifest } from 'rmf-dashboard/components/micro-app';
import doorsApp from 'rmf-dashboard/micro-apps/doors-app';
import liftsApp from 'rmf-dashboard/micro-apps/lifts-app';
import createMapApp from 'rmf-dashboard/micro-apps/map-app';
import robotMutexGroupsApp from 'rmf-dashboard/micro-apps/robot-mutex-groups-app';
import robotsApp from 'rmf-dashboard/micro-apps/robots-app';
import tasksApp from 'rmf-dashboard/micro-apps/tasks-app';
import StubAuthenticator from 'rmf-dashboard/services/stub-authenticator';

const mapApp = createMapApp({
attributionPrefix: 'Open-RMF',
defaultMapLevel: 'L1',
defaultRobotZoom: 20,
defaultZoom: 6,
});

const appRegistry: MicroAppManifest[] = [
mapApp,
doorsApp,
liftsApp,
robotsApp,
robotMutexGroupsApp,
tasksApp,
];

const homeWorkspace: InitialWindow[] = [
{
layout: { x: 0, y: 0, w: 12, h: 6 },
microApp: mapApp,
},
];

const robotsWorkspace: InitialWindow[] = [
{
layout: { x: 0, y: 0, w: 7, h: 4 },
microApp: robotsApp,
},
{ layout: { x: 8, y: 0, w: 5, h: 8 }, microApp: mapApp },
{ layout: { x: 0, y: 0, w: 7, h: 4 }, microApp: doorsApp },
{ layout: { x: 0, y: 0, w: 7, h: 4 }, microApp: liftsApp },
{ layout: { x: 8, y: 0, w: 5, h: 4 }, microApp: robotMutexGroupsApp },
];

const tasksWorkspace: InitialWindow[] = [
{ layout: { x: 0, y: 0, w: 7, h: 8 }, microApp: tasksApp },
{ layout: { x: 8, y: 0, w: 5, h: 8 }, microApp: mapApp },
];

export default function App() {
return (
<RmfDashboard
apiServerUrl="http://localhost:8000"
trajectoryServerUrl="http://localhost:8006"
authenticator={new StubAuthenticator()}
helpLink="https://osrf.github.io/ros2multirobotbook/rmf-core.html"
reportIssueLink="https://github.com/open-rmf/rmf-web/issues"
resources={{ fleets: {}, logos: { header: '/resources/defaultLogo.png' } }}
tasks={{
allowedTasks: [
{ taskDefinitionId: 'patrol' },
{ taskDefinitionId: 'delivery' },
{ taskDefinitionId: 'compose-clean' },
{ taskDefinitionId: 'custom_compose' },
],
pickupZones: [],
cartIds: [],
}}
tabs={[
{
name: 'Map',
route: '',
element: <Workspace initialWindows={homeWorkspace} />,
},
{
name: 'Robots',
route: 'robots',
element: <Workspace initialWindows={robotsWorkspace} />,
},
{
name: 'Tasks',
route: 'tasks',
element: <Workspace initialWindows={tasksWorkspace} />,
},
{
name: 'Custom',
route: 'custom',
element: (
<LocallyPersistentWorkspace
defaultWindows={[]}
allowDesignMode
appRegistry={appRegistry}
storageKey="custom-workspace"
/>
),
},
]}
/>
);
}

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(<App />);
Loading
Loading