feature/IO-3205-Paint-Scale-Integrations: Checkpoint

This commit is contained in:
Dave Richer
2025-04-28 09:26:15 -04:00
parent 1cd0ee4f5c
commit c73db112c7
5 changed files with 276 additions and 173 deletions

View File

@@ -3,7 +3,9 @@
<component name="MaterialThemeProjectNewConfig">
<option name="metadata">
<MTProjectMetadataState>
<option name="userId" value="-70fa916f:1961b191ca1:-748b" />
<option name="migrated" value="true" />
<option name="pristineConfig" value="false" />
<option name="userId" value="-4002d172:18ee315e3ba:-7ffe" />
</MTProjectMetadataState>
</option>
</component>

View File

@@ -25,10 +25,11 @@ export const usePaintScaleConfig = (configType: ConfigType) => {
window.electron.ipcRenderer
.invoke(getConfigsMethod)
.then((configs: PaintScaleConfig[]) => {
// Ensure all configs have a pollingInterval (for backward compatibility)
// Ensure all configs have a pollingInterval and type (for backward compatibility)
const updatedConfigs = configs.map(config => ({
...config,
pollingInterval: config.pollingInterval || 60 // Default to 60 seconds if not set
pollingInterval: config.pollingInterval || 1440, // Default to 1440 seconds if not set
type: config.type || PaintScaleType.PPG, // Default type if missing
}));
setPaintScaleConfigs(updatedConfigs || []);
})
@@ -47,12 +48,12 @@ export const usePaintScaleConfig = (configType: ConfigType) => {
};
// Handle adding a new paint scale config
const handleAddConfig = () => {
const handleAddConfig = (type: PaintScaleType) => {
const newConfig: PaintScaleConfig = {
id: Date.now().toString(),
path: null,
type: PaintScaleType.PPG,
pollingInterval: 60, // Default to 60 seconds
type,
pollingInterval: 1440, // Default to 1440 seconds
};
const updatedConfigs = [...paintScaleConfigs, newConfig];
setPaintScaleConfigs(updatedConfigs);
@@ -84,15 +85,6 @@ export const usePaintScaleConfig = (configType: ConfigType) => {
});
};
// Handle type change
const handleTypeChange = (id: string, type: PaintScaleType) => {
const updatedConfigs = paintScaleConfigs.map((config) =>
config.id === id ? { ...config, type } : config,
);
setPaintScaleConfigs(updatedConfigs);
saveConfigs(updatedConfigs);
};
// Handle polling interval change
const handlePollingIntervalChange = (id: string, pollingInterval: number) => {
const updatedConfigs = paintScaleConfigs.map((config) =>
@@ -107,8 +99,6 @@ export const usePaintScaleConfig = (configType: ConfigType) => {
handleAddConfig,
handleRemoveConfig,
handlePathChange,
handleTypeChange,
handlePollingIntervalChange
handlePollingIntervalChange,
};
};

View File

@@ -1,6 +1,21 @@
import { FileAddFilled, FolderOpenFilled, CheckCircleFilled, WarningFilled } from "@ant-design/icons";
import { Button, Card, Input, Select, Space, Table, Tooltip } from "antd";
import { FC } from "react";
import {
CheckCircleFilled,
FileAddFilled,
FolderOpenFilled,
WarningFilled,
} from "@ant-design/icons";
import {
Button,
Card,
Input,
Modal,
Select,
Space,
Table,
Tag,
Tooltip,
} from "antd";
import { FC, useState } from "react";
import { useTranslation } from "react-i18next";
import {
PaintScaleConfig,
@@ -16,31 +31,55 @@ const SettingsPaintScaleInputPaths: FC = () => {
handleAddConfig,
handleRemoveConfig,
handlePathChange,
handleTypeChange,
handlePollingIntervalChange,
} = usePaintScaleConfig("input");
const [isModalVisible, setIsModalVisible] = useState(false);
const [selectedType, setSelectedType] = useState<PaintScaleType | null>(null);
// Show modal when adding a new path
const showAddPathModal = () => {
setSelectedType(null);
setIsModalVisible(true);
};
// Handle modal confirmation
const handleModalOk = () => {
if (selectedType) {
handleAddConfig(selectedType);
setIsModalVisible(false);
}
};
// Handle modal cancellation
const handleModalCancel = () => {
setIsModalVisible(false);
};
// Table columns for paint scale configs
const columns = [
{
title: t("settings.labels.paintScaleType"),
dataIndex: "type",
key: "type",
render: (type: PaintScaleType, record: PaintScaleConfig) => (
<Select
value={type}
options={paintScaleTypeOptions}
onChange={(value) => handleTypeChange(record.id, value)}
style={{ width: 120 }}
/>
),
render: (type: PaintScaleType) => {
const typeOption = paintScaleTypeOptions.find(
(option) => option.value === type,
);
const label = typeOption ? typeOption.label : type;
const colorMap: Partial<Record<PaintScaleType, string>> = {
[PaintScaleType.PPG]: "blue",
// Add other types and colors as needed
};
return <Tag color={colorMap[type] || "default"}>{label}</Tag>;
},
},
{
title: t("settings.labels.paintScalePath"),
dataIndex: "path",
key: "path",
render: (path: string | null, record: PaintScaleConfig) => {
const isValid = path && path.trim() !== ""; // Simple validity check
const isValid = path && path.trim() !== "";
return (
<Space>
<Input
@@ -48,10 +87,16 @@ const SettingsPaintScaleInputPaths: FC = () => {
placeholder={t("settings.labels.paintScalePath")}
disabled
style={{
borderColor: isValid ? "#52c41a" : "#d9d9d9", // Green for valid, default for invalid
borderColor: isValid ? "#52c41a" : "#d9d9d9",
}}
suffix={
<Tooltip title={isValid ? t("settings.labels.validPath") : t("settings.labels.invalidPath")}>
<Tooltip
title={
isValid
? t("settings.labels.validPath")
: t("settings.labels.invalidPath")
}
>
{isValid ? (
<CheckCircleFilled style={{ color: "#52c41a" }} />
) : (
@@ -96,10 +141,11 @@ const SettingsPaintScaleInputPaths: FC = () => {
];
return (
<>
<Card
title={t("settings.labels.paintScaleSettingsInput")}
extra={
<Button icon={<FileAddFilled />} onClick={handleAddConfig}>
<Button onClick={showAddPathModal} icon={<FileAddFilled />}>
{t("settings.actions.addpath")}
</Button>
}
@@ -111,6 +157,23 @@ const SettingsPaintScaleInputPaths: FC = () => {
pagination={false}
/>
</Card>
<Modal
title={t("settings.labels.selectPaintScaleType")}
open={isModalVisible}
onOk={handleModalOk}
onCancel={handleModalCancel}
okButtonProps={{ disabled: !selectedType }}
>
<Select
value={selectedType}
options={paintScaleTypeOptions}
onChange={(value) => setSelectedType(value)}
style={{ width: "100%" }}
placeholder={t("settings.labels.selectPaintScaleType")}
/>
</Modal>
</>
);
};

View File

@@ -1,6 +1,11 @@
import { FileAddFilled, FolderOpenFilled, CheckCircleFilled, WarningFilled } from "@ant-design/icons";
import { Button, Card, Input, Select, Space, Table } from "antd";
import { FC } from "react";
import {
CheckCircleFilled,
FileAddFilled,
FolderOpenFilled,
WarningFilled,
} from "@ant-design/icons";
import { Button, Card, Input, Modal, Select, Space, Table, Tag } from "antd";
import { FC, useState } from "react";
import { useTranslation } from "react-i18next";
import {
PaintScaleConfig,
@@ -16,31 +21,55 @@ const SettingsPaintScaleOutputPaths: FC = () => {
handleAddConfig,
handleRemoveConfig,
handlePathChange,
handleTypeChange,
handlePollingIntervalChange,
} = usePaintScaleConfig("output");
const [isModalVisible, setIsModalVisible] = useState(false);
const [selectedType, setSelectedType] = useState<PaintScaleType | null>(null);
// Show modal when adding a new path
const showAddPathModal = () => {
setSelectedType(null);
setIsModalVisible(true);
};
// Handle modal confirmation
const handleModalOk = () => {
if (selectedType) {
handleAddConfig(selectedType);
setIsModalVisible(false);
}
};
// Handle modal cancellation
const handleModalCancel = () => {
setIsModalVisible(false);
};
// Table columns for paint scale configs
const columns = [
{
title: t("settings.labels.paintScaleType"),
dataIndex: "type",
key: "type",
render: (type: PaintScaleType, record: PaintScaleConfig) => (
<Select
value={type}
options={paintScaleTypeOptions}
onChange={(value) => handleTypeChange(record.id, value)}
style={{ width: 120 }}
/>
),
render: (type: PaintScaleType) => {
const typeOption = paintScaleTypeOptions.find(
(option) => option.value === type,
);
const label = typeOption ? typeOption.label : type;
const colorMap: Partial<Record<PaintScaleType, string>> = {
[PaintScaleType.PPG]: "blue",
// Add other types and colors as needed
};
return <Tag color={colorMap[type] || "default"}>{label}</Tag>;
},
},
{
title: t("settings.labels.paintScalePath"),
dataIndex: "path",
key: "path",
render: (path: string | null, record: PaintScaleConfig) => {
const isValid = path && path.trim() !== ""; // Simple validity check
const isValid = path && path.trim() !== "";
return (
<Space>
<Input
@@ -48,7 +77,7 @@ const SettingsPaintScaleOutputPaths: FC = () => {
placeholder={t("settings.labels.paintScalePath")}
disabled
style={{
borderColor: isValid ? "#52c41a" : "#d9d9d9", // Green for valid, default for invalid
borderColor: isValid ? "#52c41a" : "#d9d9d9",
}}
suffix={
isValid ? (
@@ -94,10 +123,11 @@ const SettingsPaintScaleOutputPaths: FC = () => {
];
return (
<>
<Card
title={t("settings.labels.paintScaleSettingsOutput")}
extra={
<Button onClick={handleAddConfig} icon={<FileAddFilled />}>
<Button onClick={showAddPathModal} icon={<FileAddFilled />}>
{t("settings.actions.addpath")}
</Button>
}
@@ -109,6 +139,23 @@ const SettingsPaintScaleOutputPaths: FC = () => {
pagination={false}
/>
</Card>
<Modal
title={t("settings.labels.selectPaintScaleType")}
open={isModalVisible}
onOk={handleModalOk}
onCancel={handleModalCancel}
okButtonProps={{ disabled: !selectedType }}
>
<Select
value={selectedType}
options={paintScaleTypeOptions}
onChange={(value) => setSelectedType(value)}
style={{ width: "100%" }}
placeholder={t("settings.labels.selectPaintScaleType")}
/>
</Modal>
</>
);
};

View File

@@ -42,9 +42,10 @@
"addPaintScalePath": "Add Paint Scale Path",
"remove": "Remove",
"actions": "Actions",
"pollingInterval": "Polling Interval (s)",
"pollingInterval": "Polling Interval (m)",
"validPath": "Valid path",
"invalidPath": "Path not set or invalid"
"invalidPath": "Path not set or invalid",
"selectPaintScaleType": "Select Paint Scale Type"
}
},
"title": {