diff --git a/apps/react-starter/src/App.tsx b/apps/react-starter/src/App.tsx index a07aa1b..843aaba 100644 --- a/apps/react-starter/src/App.tsx +++ b/apps/react-starter/src/App.tsx @@ -19,7 +19,7 @@ import { useTranslation } from "react-i18next"; import { NavLink, Outlet } from "react-router-dom"; import useShowDemoMessage from "./hooks/demoMessage"; import Logo from "./Logo"; -import { useDataStore } from "./pages/store/device-store"; +import { useDataStore } from "./store/device-store"; import UserSettings from "./pages/user-settings"; registerTheme(echarts); diff --git a/apps/react-starter/src/pages/devices/components/ag-grid-table/ag-grid-table.tsx b/apps/react-starter/src/pages/devices/components/ag-grid-table/ag-grid-table.tsx index f8ff06c..1e216f4 100644 --- a/apps/react-starter/src/pages/devices/components/ag-grid-table/ag-grid-table.tsx +++ b/apps/react-starter/src/pages/devices/components/ag-grid-table/ag-grid-table.tsx @@ -13,7 +13,7 @@ import { AgGridReact } from "ag-grid-react"; import { IxEmptyState } from "@siemens/ix-react"; import QuickActionsCellRenderer from "./quick-actions-cell-renderet.tsx"; import { CellClickedEvent, ColDef, ColGroupDef, IRowNode } from "ag-grid-community"; -import { useDataStore, useFilterStore, useOverviewPaneStore } from "../../../store/device-store.ts"; +import { useDataStore, useFilterStore, useOverviewPaneStore } from "../../../../store/device-store.ts"; import { Device } from "../../../../types"; import { useCallback, useEffect, useRef, useState } from "react"; import { LogicalFilterOperator } from "@siemens/ix"; diff --git a/apps/react-starter/src/pages/devices/components/ag-grid-table/quick-actions-cell-renderet.tsx b/apps/react-starter/src/pages/devices/components/ag-grid-table/quick-actions-cell-renderet.tsx index c0267e7..884f289 100644 --- a/apps/react-starter/src/pages/devices/components/ag-grid-table/quick-actions-cell-renderet.tsx +++ b/apps/react-starter/src/pages/devices/components/ag-grid-table/quick-actions-cell-renderet.tsx @@ -19,7 +19,7 @@ import { showModal, } from "@siemens/ix-react"; import { ICellRendererParams } from "ag-grid-community"; -import { useDataStore } from "../../../store/device-store.ts"; +import { useDataStore } from "../../../../store/device-store.ts"; import { RefObject } from "react"; import { AgGridReact } from "ag-grid-react"; import { diff --git a/apps/react-starter/src/pages/devices/components/device-details/index.tsx b/apps/react-starter/src/pages/devices/components/device-details/index.tsx index 66af9dc..a170eb4 100644 --- a/apps/react-starter/src/pages/devices/components/device-details/index.tsx +++ b/apps/react-starter/src/pages/devices/components/device-details/index.tsx @@ -12,11 +12,11 @@ import { toKebabCase } from "@/util/util.ts"; import { IxButton, IxDivider, IxPane, IxTypography } from "@siemens/ix-react"; import { useLayoutEffect } from "react"; import { useTranslation } from "react-i18next"; -import { useDataStore, useOverviewPaneStore } from "../../../store/device-store.ts"; +import { useDataStore, useOverviewPaneStore } from "../../../../store/device-store.ts"; import FirmwareCard from "./firmware-card.tsx"; import styles from "./styles.module.css"; -const DeviceDetails = ({ ...props }) => { +const DeviceDetails = () => { const { editDevice } = useDataStore(); const { t } = useTranslation(); @@ -52,7 +52,6 @@ const DeviceDetails = ({ ...props }) => { setExpanded(event.detail.expanded); }} className={styles.Pane} - {...props} >
{selectedData ? ( @@ -88,7 +87,6 @@ const DeviceDetails = ({ ...props }) => { status: (selectedData!.status = "Maintenance"), }; editDevice(updatedDevice as Device); - props.api.onFilterChanged(); }} > {t("device-details-footer.maintenance")} @@ -101,7 +99,6 @@ const DeviceDetails = ({ ...props }) => { selectedData!.status === "Offline" ? "Online" : "Offline"), }; editDevice(updatedDevice as Device); - props.api.onFilterChanged(); }} > {selectedData?.status === "Offline" diff --git a/apps/react-starter/src/pages/devices/components/modal/add-device-modal.tsx b/apps/react-starter/src/pages/devices/components/modal/add-device-modal.tsx index db50730..91d5b06 100644 --- a/apps/react-starter/src/pages/devices/components/modal/add-device-modal.tsx +++ b/apps/react-starter/src/pages/devices/components/modal/add-device-modal.tsx @@ -21,7 +21,7 @@ import { useRef, useEffect } from "react"; import styles from "./styles.module.css"; import FormField from "./form-field"; import { useForm } from "react-hook-form"; -import { useDataStore } from "../../../store/device-store"; +import { useDataStore } from "../../../../store/device-store.ts"; import { Device } from "../../../../types"; import { useTranslation } from "react-i18next"; import { showSuccessToast } from "../../../../util/util.ts"; diff --git a/apps/react-starter/src/pages/devices/components/quick-actions/alert-card/alert-card.tsx b/apps/react-starter/src/pages/devices/components/quick-actions/alert-card/alert-card.tsx deleted file mode 100644 index 64bf805..0000000 --- a/apps/react-starter/src/pages/devices/components/quick-actions/alert-card/alert-card.tsx +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 Siemens AG - * - * SPDX-License-Identifier: MIT - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import { IxCard, IxCardContent, IxIcon, IxRow, IxTypography } from "@siemens/ix-react"; -import styles from "./styles.module.css"; - -type AlertCardProps = { - title: string; - value: number; - variant: string; -}; - -function AlertCard({ title, value, variant }: AlertCardProps) { - return ( - - - - - {title} - - {value} - - - ); -} - -export default AlertCard; diff --git a/apps/react-starter/src/pages/devices/components/quick-actions/alert-card/styles.module.css b/apps/react-starter/src/pages/devices/components/quick-actions/alert-card/styles.module.css deleted file mode 100644 index d252ac5..0000000 --- a/apps/react-starter/src/pages/devices/components/quick-actions/alert-card/styles.module.css +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 Siemens AG - * - * SPDX-License-Identifier: MIT - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -.AlertCardContainer { - display: flex; - flex-direction: column; - align-items: end; - flex-wrap: nowrap; -} - -.AlertCard { - width: 100%; - display: flex; - align-items: center; - gap: 0.5rem; - flex-wrap: nowrap; - - ix-typography { - font-size: 1rem; - } -} - -.CardWarning { - width: 100%; - background: #ffd73233; - - ix-icon { - color: var(--theme-color-warning); - } -} - -.CardAlert { - width: 100%; - background: #ff264033; - - ix-icon { - color: var(--theme-color-alarm); - } -} diff --git a/apps/react-starter/src/pages/devices/components/quick-actions/index.tsx b/apps/react-starter/src/pages/devices/components/quick-actions/index.tsx deleted file mode 100644 index d3299c2..0000000 --- a/apps/react-starter/src/pages/devices/components/quick-actions/index.tsx +++ /dev/null @@ -1,68 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 Siemens AG - * - * SPDX-License-Identifier: MIT - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import styles from "./styles.module.css"; - -import { IxActionCard, IxCard, IxCardContent, IxTypography } from "@siemens/ix-react"; -import AlertCard from "./alert-card/alert-card.tsx"; -import { iconAddCircle } from "@siemens/ix-icons/icons"; -import type { Device } from "../../../../types"; -import { useDataStore } from "../../../store/device-store.ts"; -import { useTranslation } from "react-i18next"; - -export type QuickActionsProps = { - show: () => void; -}; - -function QuickActions({ show }: QuickActionsProps) { - const { t } = useTranslation(); - - const { devices } = useDataStore(); - - function getDevicesCountByStatus(data: Device[], status: Device["status"]): number { - if (data) { - return data!.filter((device: Device) => device.status === status).length; - } - return 0; - } - - return ( - <> - -
- - - {t("device-quick-actions.devices")} - {devices.length} - - -
- - -
-
- - ); -} - -export default QuickActions; diff --git a/apps/react-starter/src/pages/devices/components/quick-actions/styles.module.css b/apps/react-starter/src/pages/devices/components/quick-actions/styles.module.css deleted file mode 100644 index c4b8301..0000000 --- a/apps/react-starter/src/pages/devices/components/quick-actions/styles.module.css +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 Siemens AG - * - * SPDX-License-Identifier: MIT - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -.Container { - display: grid; - grid-template-rows: auto auto; - grid-template-columns: 1fr; - gap: 0.25rem; - width: 100%; - margin-top: 1rem; -} - -.DeviceCard { - width: 100%; - grid-column: 1 / -1; - height: 8.5rem; -} - -.DeviceCard ix-typography:last-of-type { - position: absolute; - bottom: 1rem; - right: 1rem; -} - -.AlertCards { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 0.25rem; -} diff --git a/apps/react-starter/src/pages/devices/index.tsx b/apps/react-starter/src/pages/devices/index.tsx index 2a30b66..b53e992 100644 --- a/apps/react-starter/src/pages/devices/index.tsx +++ b/apps/react-starter/src/pages/devices/index.tsx @@ -20,12 +20,12 @@ import { import { IxButton, IxCategoryFilter, IxChip, IxContentHeader } from "@siemens/ix-react"; import { useCallback, useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; -import { useDataStore, useFilterStore } from "../store/device-store.ts"; +import { useDataStore, useFilterStore } from "../../store/device-store.ts"; import AgGridTable from "./components/ag-grid-table/ag-grid-table.tsx"; import DeviceDetails from "./components/device-details/index.tsx"; import show from "./components/modal/index.tsx"; import styles from "./styles.module.css"; -import { useDeviceStatus } from "../store/hooks/device.ts"; +import { useDeviceStatus } from "../../store/hooks/device.ts"; type Categories = Record< string, diff --git a/apps/react-starter/src/pages/overview/components/device-range/index.tsx b/apps/react-starter/src/pages/overview/components/device-range/index.tsx index 7839020..48cd256 100644 --- a/apps/react-starter/src/pages/overview/components/device-range/index.tsx +++ b/apps/react-starter/src/pages/overview/components/device-range/index.tsx @@ -15,75 +15,73 @@ import { BarSeriesOption } from "echarts"; import { EChartsCoreOption } from "echarts"; import { useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; -import { Device } from "../../../../types/index.tsx"; -import { useDataStore } from "../../../store/device-store.ts"; import ReactEcharts from "echarts-for-react"; import { useResizeHandler } from "@/util/util.ts"; import EChartsReact from "echarts-for-react"; import { ECBasicOption } from "echarts/types/dist/shared"; +import { getComputedCSSProperty } from "@siemens/ix-echarts"; +import { Device, DeviceState } from "@/types"; +import { useDataStore } from "@/store/device-store"; const reduceDevices = (devices: Device[]): BarSeriesOption[] => { - const onlineData: [number, string][] = []; - const offlineData: [number, string][] = []; - const maintenanceData: [number, string][] = []; - const errorData: [number, string][] = []; + const onlineData = new Map(); + const offlineData = new Map(); + const maintenanceData = new Map(); + const errorData = new Map(); - devices.forEach((device) => { + function fillData(device: Device, data: Map, state: DeviceState) { const ipSegment = device.ipAddress.split(".")[0] + ".x"; - const online = onlineData.find((data) => data[1] === ipSegment); - if (online) { - online[0]++; - } else { - onlineData.push([1, ipSegment]); - } - - const offline = offlineData.find((data) => data[1] === ipSegment); - if (offline) { - offline[0]++; - } else { - offlineData.push([1, ipSegment]); + if (device.status !== state) { + return; } - const maintenance = maintenanceData.find((data) => data[1] === ipSegment); - if (maintenance) { - maintenance[0]++; + if (data.has(ipSegment)) { + data.set(ipSegment, data.get(ipSegment)! + 1); } else { - maintenanceData.push([1, ipSegment]); + data.set(ipSegment, 1); } + } - const error = errorData.find((data) => data[1] === ipSegment); - if (error) { - error[0]++; - } else { - errorData.push([1, ipSegment]); - } + devices.forEach((device) => { + fillData(device, onlineData, "Online"); + fillData(device, maintenanceData, "Maintenance"); + fillData(device, errorData, "Error"); + fillData(device, offlineData, "Offline"); }); + function createSeries(data: Map) { + return Array.from(data).map(([name, value]) => [value, name]); + } + return [ { name: "Online", - data: onlineData, + data: createSeries(onlineData), type: "bar", stack: "x", + color: getComputedCSSProperty("color-success"), }, { name: "Maintenance", - data: maintenanceData, + data: createSeries(maintenanceData), type: "bar", stack: "x", + color: getComputedCSSProperty("color-warning"), }, { name: "Error", - data: errorData, + data: createSeries(errorData), type: "bar", stack: "x", + color: getComputedCSSProperty("color-alarm"), }, { name: "Offline", - data: offlineData, + data: createSeries(offlineData), type: "bar", stack: "x", + color: getComputedCSSProperty("color-neutral"), }, ]; }; @@ -131,7 +129,6 @@ function DeviceRange() { if (chart) { const data = reduceDevices(devices); - const option = { ...getOption(), series: data, diff --git a/apps/react-starter/src/pages/overview/components/incidents/overview/incident-cards/index.tsx b/apps/react-starter/src/pages/overview/components/incidents/overview/incident-cards/index.tsx deleted file mode 100644 index c3bafa7..0000000 --- a/apps/react-starter/src/pages/overview/components/incidents/overview/incident-cards/index.tsx +++ /dev/null @@ -1,76 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 Siemens AG - * - * SPDX-License-Identifier: MIT - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import { IxCardList, IxPushCard } from "@siemens/ix-react"; -import { Incident } from "../incident"; -import { useTranslation } from "react-i18next"; - -function IncidentCards(props: { incidents: Incident[]; search: string }) { - const { t } = useTranslation(); - - function searchArray() { - if (props.search === "") { - return props.incidents; - } - - const query = props.search.toLowerCase(); - - return props.incidents.filter((item) => - Object.values(item).some( - (value) => typeof value === "string" && value.toLowerCase().includes(query), - ), - ); - } - - function hasUpdates() { - return searchArray().some((incident) => incident.incidentName === "Update available"); - } - - function updateCount() { - return searchArray().filter((incident) => incident.incidentName === "Update available").length; - } - - for (const i in document.getElementsByTagName("ix-card-list")) { - console.log(i); - } - - return ( - - {hasUpdates() && ( - - - - - - - - - - - {searchArray().map((incident) => ( - - - - - - ))} - -
#{t("incidents.incident-cards.device")}{t("incidents.incident-cards.date")}
{incident.id}{incident.deviceName}{incident.date}
-
- )} -
- ); -} - -export default IncidentCards; diff --git a/apps/react-starter/src/pages/overview/components/incidents/overview/incident-cards/styles.module.css b/apps/react-starter/src/pages/overview/components/incidents/overview/incident-cards/styles.module.css deleted file mode 100644 index 6b23fcb..0000000 --- a/apps/react-starter/src/pages/overview/components/incidents/overview/incident-cards/styles.module.css +++ /dev/null @@ -1,8 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 Siemens AG - * - * SPDX-License-Identifier: MIT - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ diff --git a/apps/react-starter/src/pages/overview/components/incidents/overview/incident-list/index.tsx b/apps/react-starter/src/pages/overview/components/incidents/overview/incident-list/index.tsx index 4c2254b..63ef6d7 100644 --- a/apps/react-starter/src/pages/overview/components/incidents/overview/incident-list/index.tsx +++ b/apps/react-starter/src/pages/overview/components/incidents/overview/incident-list/index.tsx @@ -20,28 +20,27 @@ import { } from "@siemens/ix-react"; import { Incident } from "../incident"; import styles from "./styles.module.css"; -import { iconOpenExternal } from "@siemens/ix-icons/icons"; +import { iconOpenExternal, iconUpload } from "@siemens/ix-icons/icons"; +import useShowDemoMessage from "@/hooks/demoMessage"; function IncidentList(props: { incidents: Incident[]; search: string }) { - function searchArray() { - if (props.search === "") { - return props.incidents; + const showDemoMessage = useShowDemoMessage(); + const searchFilter = (incident: Incident) => { + if (!props.search) { + return true; } const query = props.search.toLowerCase(); - - return props.incidents.filter((item) => - Object.values(item).some( - (value) => typeof value === "string" && value.toLowerCase().includes(query), - ), + return Object.values(incident).some( + (value) => typeof value === "string" && value.toLowerCase().includes(query), ); - } + }; return (
- + Type @@ -51,12 +50,12 @@ function IncidentList(props: { incidents: Incident[]; search: string }) { - + Device - + Date @@ -64,7 +63,7 @@ function IncidentList(props: { incidents: Incident[]; search: string }) { - {searchArray().map((incident) => ( + {props.incidents.filter(searchFilter).map((incident) => ( - + {incident.incidentName} @@ -83,13 +82,21 @@ function IncidentList(props: { incidents: Incident[]; search: string }) { - {incident.deviceName} - {incident.date} - - - - Update now - + + {incident.deviceName} + + +
+ {incident.date} + + + + Update now + + +
+ +
diff --git a/apps/react-starter/src/pages/overview/components/incidents/overview/incident-list/styles.module.css b/apps/react-starter/src/pages/overview/components/incidents/overview/incident-list/styles.module.css index 4a428e2..229e1a0 100644 --- a/apps/react-starter/src/pages/overview/components/incidents/overview/incident-list/styles.module.css +++ b/apps/react-starter/src/pages/overview/components/incidents/overview/incident-list/styles.module.css @@ -27,10 +27,19 @@ padding-left: 1.125rem; } -/* .TitleOffsetDevice { - margin-left: 0.9rem; +.Desktop { + display: contents; } -.TitleOffsetDate { - margin-left: 0.5rem; -} */ +.Mobile { + display: none; +} + +@media only screen and (max-width: 48em) { + .Desktop { + display: none; + } + .Mobile { + display: block; + } +} diff --git a/apps/react-starter/src/pages/overview/components/status-history/index.tsx b/apps/react-starter/src/pages/overview/components/status-history/index.tsx index 08f018d..1c1b2da 100644 --- a/apps/react-starter/src/pages/overview/components/status-history/index.tsx +++ b/apps/react-starter/src/pages/overview/components/status-history/index.tsx @@ -76,6 +76,7 @@ function getOption(): ECBasicOption { splitLine: { show: true, }, + }, series: [ { diff --git a/apps/react-starter/src/pages/store/device-store.ts b/apps/react-starter/src/store/device-store.ts similarity index 96% rename from apps/react-starter/src/pages/store/device-store.ts rename to apps/react-starter/src/store/device-store.ts index 020c31d..32ae808 100644 --- a/apps/react-starter/src/pages/store/device-store.ts +++ b/apps/react-starter/src/store/device-store.ts @@ -8,8 +8,8 @@ */ import { create } from "zustand"; -import { fetchDataSheet } from "../../util/mock-api.ts"; -import { Device } from "../../types"; +import { fetchDataSheet } from "../util/mock-api.ts"; +import { Device } from "../types/index.tsx"; import { LogicalFilterOperator } from "@siemens/ix"; interface DataStoreState { diff --git a/apps/react-starter/src/pages/store/hooks/device.ts b/apps/react-starter/src/store/hooks/device.ts similarity index 100% rename from apps/react-starter/src/pages/store/hooks/device.ts rename to apps/react-starter/src/store/hooks/device.ts