Skip to content
Merged
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
3 changes: 3 additions & 0 deletions messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,9 @@
"devices_device_type_placeholder": "Select a device type...",
"devices_device_type_required": "Device type id is required.",
"devices_download_pdf": "Download PDF",
"devices_error_status_body": "This sensor has reported an error and may need to be replaced. Please contact support so we can help get it back online.",
"devices_error_status_detail": "Reported status: {status}",
"devices_error_status_title": "Sensor error detected",
"devices_export_dialog_title": "Export Telemetry Data",
"devices_export_failed": "Unable to export telemetry for the selected range.",
"devices_export_no_data": "No telemetry was found for the selected date range.",
Expand Down
3 changes: 3 additions & 0 deletions messages/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,9 @@
"devices_device_type_placeholder": "デバイスタイプを選択してください...",
"devices_device_type_required": "デバイスタイプ ID は必須です。",
"devices_download_pdf": "PDF をダウンロード",
"devices_error_status_body": "このセンサーはエラーを報告しており、交換が必要な可能性があります。オンラインに復旧できるよう、サポートまでお問い合わせください。",
"devices_error_status_detail": "報告されたステータス: {status}",
"devices_error_status_title": "センサーエラーが検出されました",
"devices_export_dialog_title": "テレメトリデータをエクスポート",
"devices_export_failed": "選択した範囲のテレメトリをエクスポートできませんでした。",
"devices_export_no_data": "選択した日付範囲にテレメトリが見つかりませんでした。",
Expand Down
1 change: 1 addition & 0 deletions src/lib/interfaces/CwDevice.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface CwDevice {
primary_data?: string | null;
secondary_data?: string | null;
group?: string | null;
error_status?: string | null;
created_at?: string | null;
location_name?: string;
has_primary_data?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@
} from '$lib/devices/relay-control';
import { type RelayNumber, type RelayTargetState } from '$lib/devices/relay-types';
import { m } from '$lib/paraglide/messages.js';
import { CwCard, CwResponsiveLineChart, useCwToast } from '@cropwatchdevelopment/cwui';
import {
CwButton,
CwCard,
CwDialog,
CwResponsiveLineChart,
useCwToast
} from '@cropwatchdevelopment/cwui';
import { cwResponsiveLineChartLabels } from '$lib/i18n/cwuiLabels';
import { appTheme } from '$lib/theme/appTheme.svelte';
import { resolveExportTimeZone } from './csvExport';
Expand Down Expand Up @@ -137,6 +143,24 @@
displayHistoricalData.length === 0
);

// A non-empty `error_status` on the device row means the sensor has reported a
// fault and likely needs replacing. Surface it in an auto-opening dialog.
let deviceErrorStatus = $derived(
typeof data.device?.error_status === 'string' ? data.device.error_status.trim() : ''
);
let errorDialogOpen = $state(false);
let errorDialogRouteKey = '';

// Auto-open the error dialog whenever we land on a device that has an error
// status set. Keyed on `routeKey` so it re-opens when navigating between
// devices, but stays closed once the user dismisses it for the current one.
$effect(() => {
if (deviceErrorStatus && errorDialogRouteKey !== routeKey) {
errorDialogRouteKey = routeKey;
errorDialogOpen = true;
}
});

afterNavigate(() => {
const key = routeKey;
if (isRelayDevice && authToken) {
Expand Down Expand Up @@ -398,6 +422,20 @@
</svelte:head>

<AppPage>
{#if deviceErrorStatus}
<CwDialog bind:open={errorDialogOpen} title={m.devices_error_status_title()}>
<p class="device-page__error-body">{m.devices_error_status_body()}</p>
<p class="device-page__error-detail">
{m.devices_error_status_detail({ status: deviceErrorStatus })}
</p>
{#snippet actions()}
<CwButton variant="primary" onclick={() => (errorDialogOpen = false)}>
{m.action_close()}
</CwButton>
{/snippet}
</CwDialog>
{/if}

<div class="device-page">
<DeviceDashboardHeader
{activeRange}
Expand Down Expand Up @@ -475,6 +513,17 @@
color: var(--cw-text-muted, #475467);
}

.device-page__error-body {
margin: 0;
color: var(--cw-text-primary, #101828);
}

.device-page__error-detail {
margin: 0.75rem 0 0;
font-size: var(--cw-text-sm, 0.875rem);
color: var(--cw-text-muted, #475467);
}

@media (max-width: 720px) {
.device-page {
padding-right: 0;
Expand Down