add function create dashboard
Some checks failed
Test / test (push) Has been cancelled

This commit is contained in:
2026-06-17 10:19:14 +07:00
parent a2e87aeb29
commit 4054d81aaf
7 changed files with 1112 additions and 125 deletions

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>LiDAR Manager</title>
<title>Robot App</title>
<link rel="stylesheet" href="/style.css" />
</head>
<body class="auth-logged-out">
@@ -248,50 +248,94 @@
<main class="content">
<div class="page" id="pageOverview" data-page-content="dashboard" hidden>
<div class="dashboardPage">
<section class="card">
<div class="cardHeader">
<div>
<div class="cardTitle" data-i18n="dashboard.title">Dashboard</div>
<div class="cardSub" data-i18n="dashboard.subtitle">Widget mission — chạy, xếp hàng và tạm dừng giống MiR Fleet.</div>
<div class="dashboardShell">
<div class="dashboardContent">
<div id="dashboardListView" class="dashboardListView">
<header class="dashboardListHeader">
<div class="dashboardListHeaderIntro">
<h2 class="dashboardListTitle" data-i18n="dashboard.list.title">Dashboards</h2>
<p class="dashboardListSub">
<span data-i18n="dashboard.list.subtitle">Tạo và chỉnh sửa dashboard cho robot.</span>
<span class="dashboardListHelp" title="?" aria-hidden="true">?</span>
</p>
</div>
<div class="dashboardListHeaderActions">
<button id="dashboardCreateBtn" type="button" class="btn primary dashboardCreateBtn" data-i18n="dashboard.list.create">+ Tạo dashboard</button>
<button id="dashboardClearFiltersBtn" type="button" class="btn subtle dashboardClearFiltersBtn" data-i18n="dashboard.list.clearFilters">Xóa bộ lọc</button>
</div>
</header>
<div class="dashboardListBar">
<label class="dashboardFilter">
<span class="dashboardFilterLabel" data-i18n="dashboard.list.filterLabel">Lọc:</span>
<input id="dashboardFilterInput" type="search" class="dashboardFilterInput" data-i18n-placeholder="dashboard.list.filterPlaceholder" placeholder="Nhập tên để lọc…" autocomplete="off" />
</label>
<span id="dashboardListCount" class="dashboardListCount"></span>
<div class="dashboardPagination" id="dashboardPagination">
<button type="button" class="iconBtn dashboardPageBtn" data-page-action="first" title="First">«</button>
<button type="button" class="iconBtn dashboardPageBtn" data-page-action="prev" title="Previous"></button>
<span id="dashboardPageLabel" class="dashboardPageLabel"></span>
<button type="button" class="iconBtn dashboardPageBtn" data-page-action="next" title="Next"></button>
<button type="button" class="iconBtn dashboardPageBtn" data-page-action="last" title="Last">»</button>
</div>
</div>
<div class="dashboardToolbar">
<button id="dashboardAddWidgetBtn" type="button" class="btn subtle" data-i18n="dashboard.addWidget">Thêm widget</button>
<button id="dashboardEditBtn" type="button" class="btn subtle" data-i18n="dashboard.editLayout">Sửa layout</button>
<div class="dashboardTableWrap" id="dashboardTableWrap">
<table class="dashboardTable">
<thead>
<tr>
<th scope="col" class="dashboardTableStatusCol" aria-hidden="true"></th>
<th scope="col" data-i18n="dashboard.list.col.name">Tên</th>
<th scope="col" data-i18n="dashboard.list.col.createdBy">Tạo bởi</th>
<th scope="col" class="dashboardTableFuncCol" data-i18n="dashboard.list.col.functions">Chức năng</th>
</tr>
</thead>
<tbody id="dashboardTableBody"></tbody>
</table>
</div>
</div>
<div class="cardBody">
<div id="dashboardGrid" class="dashboardGrid"></div>
<p id="dashboardEmpty" class="mutedNote dashboardEmpty" hidden data-i18n="dashboard.empty">Chưa có widget. Bấm «Thêm widget» để bắt đầu.</p>
</div>
</section>
<section class="card dashboardInfoCard">
<div class="cardHeader">
<div>
<div class="cardTitle" data-i18n="dashboard.system.title">Hệ thống</div>
<div class="cardSub" data-i18n="dashboard.system.subtitle">Trạng thái backend và layout đang active.</div>
<div id="dashboardCreateView" class="dashboardCreateView" hidden>
<header class="dashboardCreateHeader">
<div class="dashboardCreateHeaderIntro">
<h2 class="dashboardCreateTitle" data-i18n="dashboard.create.title">Tạo dashboard</h2>
<p class="dashboardCreateSub">
<span data-i18n="dashboard.create.subtitle">Tạo dashboard mới trên robot.</span>
<span class="dashboardListHelp" title="?" aria-hidden="true">?</span>
</p>
</div>
<button id="dashboardCreateBackBtn" type="button" class="btn subtle dashboardCreateBackBtn" data-i18n="dashboard.create.backToList">← Quay lại danh sách</button>
</header>
<form id="dashboardCreateForm" class="dashboardCreateForm">
<div class="dashboardCreatePanel">
<div class="dashboardCreateField">
<label for="dashboardCreateName" data-i18n="dashboard.create.name">Tên</label>
<input id="dashboardCreateName" type="text" required autocomplete="off" data-i18n-placeholder="dashboard.create.namePlaceholder" placeholder="VD: John's Dashboard" />
</div>
<div class="dashboardCreateActions">
<button type="button" id="dashboardCreatePermissionsBtn" class="btn subtle dashboardMirBtn dashboardCreatePermissionsBtn" data-i18n="dashboard.create.permissionsBtn">Quyền</button>
<button type="submit" class="btn dashboardMirBtn dashboardCreateSubmitBtn">
<span class="dashboardCreateSubmitIcon" aria-hidden="true"></span>
<span data-i18n="dashboard.create.submit">Tạo dashboard</span>
</button>
<button type="button" id="dashboardCreateCancelBtn" class="btn subtle dashboardMirBtn dashboardCreateCancelBtn">
<span class="dashboardCreateCancelIcon" aria-hidden="true"></span>
<span data-i18n="dashboard.create.cancel">Hủy</span>
</button>
</div>
</div>
</form>
</div>
<div id="dashboardDesignerView" class="dashboardDesignerView" hidden>
<header class="dashboardDesignerHeader">
<button id="dashboardBackToListBtn" type="button" class="btn subtle dashboardBackBtn" data-i18n="dashboard.list.back">← Danh sách</button>
<h2 id="dashboardDesignerTitle" class="dashboardDesignerTitle"></h2>
</header>
<div class="dashboardDesignerBody">
<div id="dashboardGrid" class="dashboardGrid"></div>
<p id="dashboardDesignerEmpty" class="mutedNote dashboardDesignerEmpty" data-i18n="dashboard.designer.empty">Chưa có widget. Phase B sẽ thêm designer đầy đủ.</p>
</div>
</div>
<div class="cardBody dashboardInfoGrid">
<div class="row rowWide">
<label data-i18n="dashboard.system.backend">Backend</label>
<div id="overviewBackend" class="mutedNote"></div>
</div>
<div class="row rowWide">
<label data-i18n="dashboard.system.layout">Layout</label>
<div id="overviewActiveLayout" class="mutedNote"></div>
</div>
<div class="row rowWide">
<label data-i18n="dashboard.system.model">Model robot</label>
<div id="overviewActiveModel" class="mutedNote"></div>
</div>
<div class="row rowWide">
<label data-i18n="dashboard.system.sensors">LiDAR / IMU</label>
<div id="overviewActiveSensors" class="mutedNote"></div>
</div>
</div>
</section>
</div>
</div>
</div>
@@ -1024,6 +1068,47 @@ GET /api/v2.0.0/status</pre>
</dialog>
<dialog id="dashboardPermissionsDialog" class="missionDialog dashboardPermissionsDialog">
<form id="dashboardPermissionsForm" method="dialog" class="missionDialogForm">
<div class="missionDialogHeader">
<h3 data-i18n="dashboard.create.permissionsTitle">Quyền chỉnh sửa</h3>
<button type="button" class="iconBtn missionDialogClose" data-close-dialog="dashboardPermissionsDialog" aria-label="Đóng" data-i18n-aria="common.close">×</button>
</div>
<div class="missionDialogBody">
<p class="dashboardPermissionsIntro" data-i18n="dashboard.create.permissions">Chọn user groups được phép chỉnh sửa dashboard này.</p>
<div id="dashboardCreatePermissions" class="dashboardPermissionsList"></div>
</div>
<div class="missionDialogFooter">
<button type="button" class="btn subtle" data-close-dialog="dashboardPermissionsDialog" data-i18n="common.cancel">Hủy</button>
<button type="submit" class="btn dashboardMirBtn dashboardPermissionsApplyBtn" data-i18n="common.apply">Áp dụng</button>
</div>
</form>
</dialog>
<dialog id="dashboardEditDialog" class="missionDialog">
<form id="dashboardEditForm" method="dialog" class="missionDialogForm">
<div class="missionDialogHeader">
<h3 data-i18n="dashboard.dialog.editDashboard.title">Sửa dashboard</h3>
<button type="button" class="iconBtn missionDialogClose" data-close-dialog="dashboardEditDialog" aria-label="Đóng" data-i18n-aria="common.close">×</button>
</div>
<div class="missionDialogBody">
<input type="hidden" id="dashboardEditId" />
<div class="row rowWide">
<label for="dashboardEditName" data-i18n="dashboard.create.name">Tên</label>
<input id="dashboardEditName" type="text" required />
</div>
<div class="row rowWide">
<label data-i18n="dashboard.create.permissions">Quyền chỉnh sửa</label>
<div id="dashboardEditPermissions" class="dashboardPermissionsList"></div>
</div>
</div>
<div class="missionDialogFooter">
<button type="button" class="btn subtle" data-close-dialog="dashboardEditDialog" data-i18n="common.cancel">Hủy</button>
<button type="submit" class="btn primary" data-i18n="common.save">Lưu</button>
</div>
</form>
</dialog>
<dialog id="dashboardAddWidgetDialog" class="missionDialog">
<form id="dashboardAddWidgetForm" method="dialog" class="missionDialogForm">
<div class="missionDialogHeader">