Commit Graph
440 Commits
Author SHA1 Message Date
pnoker e85a8f26eb style(dialog): extract shared dialog min-height to things-dialog.scss and remove inline overrides v2026.6.2 2026-06-02 09:55:47 +08:00
pnoker b2c30f6c4a test: update tests for route rename and add Node 22 storage polyfill
- Update jumpUtil test expectations to match renamed event→alarm route
  names and add point source coverage.
- Fix thing-model-flow paths (PointAddForm→PointEditForm, etc.) after
  the form consolidation refactor.
- Exclude .spec.ts files from the focused/disabled-test guardrail since
  Playwright e2e specs use conditional first-argument-guarded skips.
- Polyfill localStorage / sessionStorage in vitest setup for Node ≥ 22
  where the native globals are gated behind --localstorage-file.
2026-05-31 23:17:03 +08:00
pnoker 81dd6a7cab feat: polish device-edit matrix tables with pagination and unified styling
- Add client-side pagination (10/20/50 per page) to Point Attributes,
  Related Commands, and Related Events tables via the matrix-toolbar
  trailing slot. Filter changes reset to page 1.
- Remove redundant descriptions from table rows: drop the defaultValue
  column in Driver Attributes (placeholder already shows the default)
  and replace two-line name+code cells with single-line names and
  hover tooltips.
- Unify table CSS class names (matrix-table, matrix-cell, matrix-cell__meta)
  across all four config tabs and let Element Plus defaults drive cell
  padding / row height instead of hard-coded overrides.
- Make input fields fill the cell width in Driver Attributes.
- Rename Profile Edit tabs (Point/Command/Event Config → Related
  Points/Commands/Events) to match the detail-page convention.
- Consolidate settings detail routes in operate.ts under a single
  /settings Layout wrapper with relative child paths so they never
  compete with the nested settings list routes.
2026-05-31 22:59:41 +08:00
pnoker f7c266e056 fix: repair settings sidebar fallback and route references after menu rename
- Add settingsAbout to SETTINGS_FALLBACK_SIDEBAR and ensureDirectItem so
  it appears even when the menu API is unreachable.
- Add ensureCommandGroup to match Alarm/Model/Event group handling.
- Fix settingsLabel insert-before references.
- PointCard now respects the embedded prop from parent context,
  hiding action buttons in detail read-only views while keeping
  them visible in edit / standalone contexts.
- Update stale event→alarm route references in Layout FALLBACK_ICON,
  Home dashboard cards, jumpUtil, Overview, and zh locale i18n keys
  that were missed in the earlier rename commits.
2026-05-31 22:59:10 +08:00
pnoker 7b96b37e35 refactor: rename navigation keys to match backend menu code changes
- Rename settingsAgentic → settingsModelConfig, settingsAgenticProvider → settingsModelProvider
- Rename settingsEventOverview → settingsAlarmOverview
- Rename settingsPointEvent → settingsPointAlarm, move to Alarm group
- Update URL paths: /settings/agentic → /settings/model/config
- Rebalance sidebar order: Model, Command, Event, Alarm
- Update detail route names and router navigation
2026-05-29 00:00:00 +08:00
pnoker f8754caedc refactor: realign navigation with Alarm/Event/Command menu restructure
- Rename routes: DeviceEvent/DriverEvent → DeviceAlarm/DriverAlarm
- Rename CommandRecord → CommandHistory, EventReport → EventHistory
- Move Overview route from Event to Alarm group
- Replace Point add dialog/edit page with inline drawer-based form
- Refactor Driver config from form layout to matrix table
- Add commandHistory i18n section with detail labels
- Remove legacy Point detail/edit routes from operate.ts
- Polish card shadows, borders, and breadcrumb spacing
2026-05-29 01:03:00 +08:00
pnoker 14e1c88e23 refactor: extract InfoCard and MatrixToolbar shared components
Replace inline config toolbars and forms in device/profile edit pages
with reusable InfoCard and MatrixToolbar components. Remove redundant
form refs and manual validation delegation to the new components.
v2026.5.28
2026-05-28 09:15:01 +08:00
pnoker 91472a9b21 fix(dialog): add spacing between form content and footer buttons 2026-05-28 01:07:57 +08:00
pnoker 4da7537103 fix(settings): fix breadcrumb position and independent sidebar/content scroll
Move breadcrumb outside el-scrollbar so it stays fixed at the top.
For settings routes, bypass the Layout-level el-scrollbar entirely and
use a fixed-viewport flex container instead, allowing the sidebar menu
and main content to scroll independently.
2026-05-28 01:07:31 +08:00
pnoker e4902522bd refactor(profile,device): replace step wizard with tab layout in edit pages
Replace the rigid el-steps sequential wizard with el-tabs, matching the
detail page pattern. Remove the "Complete" step, prev/next navigation,
and return buttons. Each tab now has its own toolbar with Reset/Save.
Device config form uses a 3-column grid layout. Use BaseCard wrapper
for consistent tab spacing with detail pages.
2026-05-28 01:06:53 +08:00
pnoker da5223a131 refactor(form): centralize validators and tighten input contracts
Extend formRuleUtil with reusable rule builders (authNameRules,
decimalRules, byteRules, requiredStringRule/requiredSelectRule,
positiveIntegerRules) plus matching patterns, and migrate every edit
form to consume them. Forms now share a consistent maxlength/show-word-
limit contract, point/device numeric attributes validate against typed
ranges with proper error messages on the offending control, and the
device edit page swaps its inline matrix status selector for the new
shared MatrixStatusSegmented component.
2026-05-27 21:43:49 +08:00
pnoker d9c14389db feat(segmented): add MatrixStatusSegmented and EnableFlagSegmented includeAll
Introduce a MatrixStatusSegmented component for the device-edit thing-model
matrices and an `includeAll` prop on EnableFlagSegmented so search/tool
panels no longer hand-roll the "All / Enable / Disable" option list.
Adopt the shared components across every Tool.vue and the alarm notify
page, dropping the redundant `enableFilterOptions` plumbing. Field-level
JSON validation in the alarm form moves into the form rules so errors
attach to the offending control instead of firing a generic toast.
2026-05-27 21:43:31 +08:00
pnoker 93f0727e8e refactor(composable): support server-paginated lists in usePagedList
Add an optional request handler so usePagedList can drive both
client-side filtering and server-paginated tables. Migrate the settings
list views (api, group, label, role, user, command, event) to consume
the composable, removing duplicated pagination/sort/search boilerplate.
2026-05-27 21:43:16 +08:00
pnoker d55e80fbd6 feat(i18n): localize clipboard/notification utils and add shared common locale keys 2026-05-27 21:43:00 +08:00
pnoker ebf157b43a fix: add missing form validation rules and centralize regex patterns
- Add required validation for command type, call type, timeout, event type/level, menu type/level, temperature range
- Add phone (11-digit) and email format validation on user form
- Centralize NAME_PATTERN, AUTH_NAME_PATTERN, PHONE_PATTERN, EMAIL_PATTERN into formRuleUtil and align with backend patterns
- Apply centralized patterns across all settings edit forms (group, label, menu, resource, role, user, command, event, model config)
2026-05-27 00:28:00 +08:00
pnoker 76bd96cf07 test: add comprehensive e2e specs for all routes and button functions
- full-flow: 57 tests covering every route in the app
- profile-edit-wizard: 5-step wizard navigation, command/event CRUD
- button-functions: toolbar buttons (search, reset, sort, refresh),
  wizard navigation (next, previous, reset), detail page edit button
- add-entity: add forms for profile, device, point, user, role, group,
  label, agentic provider
- detail-pages: tab switching on device, profile, driver, point detail
- device-edit-wizard: device edit wizard step navigation
2026-05-26 17:10:17 +08:00
pnoker 435a1a38b8 fix: prevent double-submit race and add inline param name validation
- Move `submitting = true` before `await validate()` in CommandEditForm,
  EventEditForm, ProviderEditForm, and ModelConfigEditForm to close the
  race window where two rapid clicks both pass validation and cause
  duplicate-entry R500 errors.
- Add per-row inline validation for paramName (regex: 2-32 chars) and
  paramCode (required) on command/event param tables, with red border
  and tooltip error instead of only a console toast.
2026-05-26 17:07:00 +08:00
pnoker 759d17acc9 test(views): cover every list page and the device-edit regression spot
tests/views/ goes from a single AlarmNotify file to twenty — every
route-level list page (Device / Driver / Profile / Point / PointValue
plus the eleven Settings pages) now has a smoke test that mounts the
page with mocked APIs and asserts that the canonical list endpoint
fires once on setup.

Adds device-edit.test.ts for the matrix wizard: locks in the load
chain (getDeviceById → getDriverById/getProfileById) and the
profile-driven listPoint/listCommand/listEvent triple — the regression
spot the new thing-model-flow guardrail tries to catch statically.

A `tests/views/_helpers.ts` mountListPage helper folds the shared
boilerplate (i18n, memory router, fresh Pinia, layoutStubs +
ElButton/ElForm/ElPagination + a v-loading no-op directive) so each
file can stay focused on its own apiMocks block. Bumps testTimeout
to 30s globally — list-page transforms+imports compete with the
component pool under parallel execution and were flaking the default
5s on PointValue.
2026-05-26 21:33:12 +08:00
pnoker 80d5d3c0f8 test(component): cover the twenty previously untested components
Brings tests/component/ from 4 to 24 files. Layered by complexity:

  Trivial passthroughs (slot/router-link smoke):
    BaseCard / BlankCard / DetailCard / TitleCard / SkeletonCard,
    ExternalLink, Error403/404/500.

  Logic-bearing components:
    EnableTag and DefaultTag (computed type/label),
    EnableFlagSegmented (string vs numeric value-type emit),
    ThingsCardHeader/ThingsCardActions (popconfirm + 5 emits),
    StatCard (k/M formatting, tone palette, refresh handler),
    DashboardCard (auto-refresh polling, empty placeholder, footer slot),
    RenderedAssistantMessage (markdown sanitization, chart segment count),
    MiniAreaChart (G2 mocked; height passthrough + empty-data short-circuit),
    Layout (router/menu store seeded; nav + router-view rendered),
    Particles (mount-without-error under canvas-less happy-dom).

Tests use the shared layoutStubs / createElButtonStub / createElFormStub
plumbing. The shared stub bag picks up ElResult/ElTabs/ElDropdown/ElMenu
and friends so layout-heavy components mount without the strict-warn
hook firing on unresolved Element Plus tags.
2026-05-26 21:32:48 +08:00
pnoker 292aed3ac2 test(infra): contract registry, naming guardrail, and missing util coverage
api-contracts.test.ts now covers command/event modules and routes them
through crud* shorthand mocks. sampleArgs becomes an explicit registry
(with the heuristic kept as a fallback) so newly added wrappers can pin
their argument shape without waiting for a regex collision to surface.

Adds two AI guardrails: (1) src/api/** is forbidden from declaring
`getXxxList*` collections, locking in the rename from the previous
commit; (2) toBeTruthy/toBeFalsy are flagged across `*.test.ts` and
`*.spec.ts` so the e2e suite can't silently slip in weak assertions —
destructive-delete migrates to the equivalent `not.toBe('')` form.

Picks up the previously untested `prettyJson` helper and broadens
thing-model-format-util tests to cover the new alarm formatters.
package.json gets `type-check` and `test:coverage` aliases that the
new guardrail expects.
2026-05-26 21:31:30 +08:00
pnoker 026e980c6c refactor: enforce list* prefix and consolidate alarm formatters
CLAUDE.md §"API verb convention" reserves get* for single-record fetches
and list* for collections. Renames the seven offenders that survived the
prior pass:

  getResourceListByRoleId   → listResourceByRoleId
  getResourceListByUserId   → listResourceByUserId
  getRoleListByResourceId   → listRoleByResourceId
  getRoleResourceList       → listRoleResource
  getRoleListByUserId       → listRoleByUserId
  getUserListByRoleId       → listUserByRoleId
  getRoleUserList           → listRoleUser
  getPointByIds             → listPointByIds

All eight were collection-returning under a single-record verb, which
churned every call site whenever they were touched. URLs are unchanged.

Also lifts EventTable's local alarmType / alarmLevel formatters into
thingModelFormatUtil so EventHistory and EventList can reuse them
(replacing their previous render-the-raw-flag fallback). The alarm enum
is distinct from EventType — kept under separate names per the
backend's AlarmTypeFlagEnum.
2026-05-26 21:28:46 +08:00
pnoker 52522b02a2 feat(device-edit): refresh thing model definitions from selected profile
Driver-bound device editing now refetches points/commands/events from the
profile when the user picks a different one — `listPointByDeviceId` was
returning the wrong scope, and `changeProfile()` was missing the point
sibling alongside command/event refresh. Drop the user-input commandCode /
eventCode form fields since the backend generates them from the name.

Adds a thing-model-flow guardrail that asserts the import shape (not raw
substrings) and the absence of `<el-form-item prop="*Code">` declarations,
so a future rename or refactor can't quietly bypass either constraint.
2026-05-26 21:28:25 +08:00
pnoker 1520cc6559 style: format code 2026-05-26 09:17:58 +08:00
pnoker 79193b256c style: format code 2026-05-26 00:44:59 +08:00
pnoker 9dc43265af style: format code 2026-05-26 00:40:16 +08:00
pnoker ebb229e404 feat: add alarm/command/event types, i18n entries, shared styles, and thingModel format utilities 2026-05-25 21:52:42 +08:00
pnoker 7b4f530505 feat: add command and event attribute matrix editors in device edit
- Extend inline attribute matrix pattern from points to commands and events
  with search, status filter, dirty tracking, and batch save
- Add command/event attribute and attribute-config REST API wrappers
- Introduce CommandInfoForm/EventInfoForm types and configSnapshot fields
- Replace embedded CommandList/EventList with native matrix tables in
  DeviceEdit wizard steps 3-4
- Format JSON fields in history detail drawers with styled <pre> blocks
2026-05-25 01:11:10 +08:00
pnoker 1fa8e6f80e feat: add point attribute matrix editor and refine card grid layout
- Replace point config card picker with inline editable table (matrix)
  supporting batch edit, dirty tracking, status filter, and bulk save
- Increase card grid density from 3 to 4 columns on large screens
- Refactor DriverCard status display with computed tag type and label
- Add custom icon images for command and event cards
- Hide status tag on embedded cards to reduce visual noise
v2026.5.24
2026-05-24 15:43:41 +08:00
pnoker b338c2c27c feat: restructure command/event management with card layout and inline detail
- Replace table views with CommandCard/EventCard card components and drawer-based detail panels
- Simplify navigation: merge event-definition sub-menu into event group, remove standalone detail pages
- Migrate device from multi-profile (profileIds[]) to single-profile (profileId) model
- Add command/event tabs and wizard steps to device and profile detail/edit pages
- Support pre/next navigation in embedded tool components for wizard-style editing
- Add thingModelFormatUtil utility for model value formatting
- Update flag field types to accept string|number for flexible value handling
2026-05-24 13:36:22 +08:00
pnoker ee4f2459fe refactor: normalize import order and template attribute formatting
Sort imports alphabetically across all source files, reorder Vue
template attributes for consistency, clean up markdown table alignment,
merge adjacent type-only imports, and fix HTML indentation.
2026-05-24 10:36:05 +08:00
pnoker 553bd42ffe fix: update Login view layout adjustments 2026-05-24 04:01:18 +08:00
pnoker 2ab419dea8 fix: update Login view layout adjustments 2026-05-24 01:09:48 +08:00
pnoker f30c4a2f74 feat: add command and event management views 2026-05-24 01:07:02 +08:00
pnoker 665885444c refactor(api): update point command API paths to /point_command 2026-05-22 08:57:48 +08:00
pnoker 0fc4e4386e refactor(alarm): rename eventId to alarmId; surface alarm level
Aligns with the iot-dc3 backend rename: dc3_rule_state.event_id and
dc3_notify_history.event_id now ship as alarm_id, and the corresponding
JSON keys / TypeScript types follow.

- AlarmDetail: rule-state and notify-history detail panels now show
  the field as "Alarm ID" with prop="alarmId".
- alarm.ts: RuleStateRecord.eventId / NotifyHistoryRecord.eventId →
  alarmId.
- EventTable: add a Level column rendering dc3_entity_alarm.alarm_level_flag
  (P0/P1/P2/P3) — the column already existed on the backend but the
  dashboard never surfaced it. Tag color leans danger->success as the
  level number grows so P0 lights up red.
- i18n: add settings.event.alarmLevel ("Level" / "级别") for the new column.
2026-05-21 19:09:16 +08:00
pnoker c2e3baab72 feat: add point alarm source to event dashboard and list views
Extend AlertSource from 'device' | 'driver' to 'point' | 'device' | 'driver'
across all dashboard cards, event tables, and entity name resolution. Add
settingsPointEvent route, PointEvent.vue wrapper, and i18n translations.
Replace local nameMap/resolveNames with useEntityNames composable.
2026-05-21 00:43:17 +08:00
pnoker 54285f9b67 refactor: rename alarm record view to history v2026.5.20 2026-05-20 21:26:59 +08:00
pnoker f389db5d2f refactor: eliminate any types in utils and settings, remove unused deps and duplicate scripts
- Replace `any` with proper types (unknown, string, boolean) in clipboardUtil,
  validationUtil, storageUtil, dateUtil, notificationUtil
- Rewrite dateFormat() to remove deprecated RegExp.$1 / substr usage
- Type settings module files (role, user, group, label) with specific record
  and form types instead of `any`
- Remove unused dependencies: clipboard, screenfull, @tauri-apps/api,
  @tauri-apps/plugin-shell
- Deduplicate npm scripts: remove `type-check` (→ `check`) and `test:coverage`
  (→ `test:ci`), update CI and tooling references accordingly
- Fix agentic.ts header assignment after getStorage() returns unknown
v2026.5.19
2026-05-19 23:18:49 +08:00
pnoker 860672e54a fix(auth): send MD5 password directly instead of double-hashing with salt
Remove the challenge-response double MD5 (MD5(MD5(password) + salt))
in favor of sending MD5(password) directly. The backend now verifies
with bcrypt instead of the old MD5 challenge-response protocol.
2026-05-19 23:16:08 +08:00
pnoker 365cf71c0a test: harden test infrastructure to A-grade with fixtures, stubs, guardrails, and e2e auth coverage
Adds shared fixtures/stubs/templates, 15 mechanically-enforced guardrails
(filename casing, ban wrapper.vm direct calls, double assertions, weak
matchers, tautologies, debug residue), splits grab-bag util test files
by source module, promotes Vue warnings to test failures, fills logout
and login-validation gaps in e2e, and replaces networkidle+hard-wait
recipes with web-first assertions.

Net: 355 unit/component/api/guardrail tests (+98), 36 playwright tests
(+11), 80.55% line coverage with 2-3% buffer above tightened thresholds
(65/75/78/78).
2026-05-19 19:01:15 +08:00
pnoker 20996e8578 fix(point-value): show missing latest values 2026-05-19 01:43:19 +08:00
pnoker 01edf32524 feat(agentic): replace thinking pulse dot with animated icon and shimmer text
Use Loading/CircleCheck icons instead of the pulsing dot for the
thinking state. Add a white shimmer sweep effect on the Thinking
label while streaming, which stops when the response completes.
2026-05-19 01:31:19 +08:00
pnoker 0d25294fb9 refactor: improve settings page consistency 2026-05-19 01:16:58 +08:00
pnoker cb6f0c3b03 feat: update package versions 2026-05-19 00:39:34 +08:00
pnoker 5f293ea6e7 fix: align settings ui hierarchy and spacing 2026-05-19 00:38:33 +08:00
pnoker 0b5b3689a5 feat: update package version 2026-05-18 21:08:04 +08:00
pnoker 3f9b61e93d test(component): align alarm-notify mocks with renamed alarm api functions
The component imports listRule/listNotify/listMessage/etc instead of
the old getXxxList names, but the test's hoisted vi.mock map still
declared the old function keys, so vitest auto-mock returned undefined
for every list spy. Rename the mock keys and the alarmMocks references
in expectations to match the renamed alarm.ts exports.
2026-05-18 21:01:18 +08:00
pnoker 11588a80e2 test(api): regenerate api-contracts snapshots after path rename
The contract snapshots embed the exact HTTP path each function calls.
After the get/list rename in commits cf97020 and dd13007, every
selectById -> getById and tree -> listTree path moved, so the snapshots
need a one-shot regeneration. 212 contract tests now pass.
2026-05-18 20:57:24 +08:00
pnoker 722551e557 docs(claude): document API get/list verb convention in CLAUDE.md
Pin the get/list cardinality convention so frontend changes after this
refactor stay aligned with the backend (iot-dc3 AGENTS.md). Adds the
'API verb convention' section under Project Conventions with positive
and negative examples for src/api/* function names and HTTP paths.
2026-05-18 20:17:07 +08:00
pnoker 18d1065779 fix(api): point getDeviceCountByDriverId at /get_count_by_driver_id
Match the backend rename in iot-dc3 commit 87c6a22c6: this endpoint
returns a single count, not a list, so the path is /get_count_by_driver_id.
2026-05-18 20:15:02 +08:00