diff --git a/src/components/widgets/BaseWidget.tsx b/src/components/widgets/BaseWidget.tsx new file mode 100644 index 0000000..c17ff10 --- /dev/null +++ b/src/components/widgets/BaseWidget.tsx @@ -0,0 +1,67 @@ +import { Button } from 'antd' +import { memo, ReactNode, useMemo } from 'react' +import { CloseOutlined, SettingOutlined } from '@ant-design/icons' + +import '@styles/widgets/base.less' + +export type WidgetSettings = { + id?: number, + unit?: string, + label?: string, + formatter?: ((v: T) => ReactNode) | null, + defaultValue?: ReactNode, + + labelColor?: string, + valueColor?: string, + backgroundColor?: string, + unitColor?: string, +} + +export const defaultSettings: WidgetSettings = { + unit: '----', + label: 'Виджет', + formatter: v => isNaN(v) ? v : parseFloat(v).toFixed(2), + + labelColor: '#000000', + valueColor: '#000000', + backgroundColor: '#f6f6f6', + unitColor: '#a0a0a0', +} + +export type BaseWidgetProps = WidgetSettings & { + value: T, + onRemove: (settings: WidgetSettings) => void, + onEdit: (settings: WidgetSettings) => void, +} + +export const BaseWidget = memo(({ value, onRemove, onEdit, ...settings }) => { + const sets = useMemo(() => ({ ...defaultSettings, ...settings }), [settings]) + + return ( +
+
+
+
+
+ {(sets.formatter === null ? value : sets.formatter?.(value)) ?? sets.defaultValue ?? '----'} +
+
{sets.unit}
+ + ) +}) + +export default BaseWidget diff --git a/src/components/widgets/WidgetSettingsWindow.tsx b/src/components/widgets/WidgetSettingsWindow.tsx new file mode 100644 index 0000000..16b70be --- /dev/null +++ b/src/components/widgets/WidgetSettingsWindow.tsx @@ -0,0 +1,65 @@ +import { memo, useEffect } from 'react' +import { Form, Input, Modal, ModalProps } from 'antd' + +import { WidgetSettings } from './BaseWidget' + +export type WidgetSettingsWindowProps = ModalProps & { + settings: WidgetSettings + onEdit: (settings: WidgetSettings) => void +} + +const { Item } = Form + +export const WidgetSettingsWindow = memo(({ settings, onEdit, ...other }) => { + const [form] = Form.useForm() + + useEffect(() => { + if (settings) form.setFieldsValue(settings) + }, [form, settings]) + + return ( + + Настройка виджета {settings?.label ? `"${settings?.label}"` : ''} + (id: {settings?.id}) + + )} + onOk={form.submit} + getContainer={false} + > +
+ + + + + + + + + + + + + + + + + + + +
+
+ ) +}) + +export default WidgetSettingsWindow diff --git a/src/components/widgets/index.ts b/src/components/widgets/index.ts new file mode 100644 index 0000000..c73bcc7 --- /dev/null +++ b/src/components/widgets/index.ts @@ -0,0 +1,5 @@ +export { WidgetSettingsWindow } from './WidgetSettingsWindow' +export { BaseWidget } from './BaseWidget' + +export type { WidgetSettingsWindowProps } from './WidgetSettingsWindow' +export type { WidgetSettings, BaseWidgetProps } from './BaseWidget' diff --git a/src/pages/Telemetry/DashboardNNB/AddGroupWindow.jsx b/src/pages/Telemetry/DashboardNNB/AddGroupWindow.jsx new file mode 100644 index 0000000..96ce88e --- /dev/null +++ b/src/pages/Telemetry/DashboardNNB/AddGroupWindow.jsx @@ -0,0 +1,18 @@ +import { PlusOutlined } from '@ant-design/icons' +import { Form, Input } from 'antd' +import { memo } from 'react' + +import Poprompt from '@components/selectors/Poprompt' + +const addGroupRules = [{ required: true, message: 'Пожалуйста, введите название группы' }] +const addGroupButtonProps = { type: 'link', className: 'add_group', icon: } + +export const AddGroupWindow = memo(({ addGroup, initialValue = 'Новая группа' }) => ( + + + + + +)) + +export default AddGroupWindow diff --git a/src/pages/Telemetry/DashboardNNB/AddWidgetWindow.jsx b/src/pages/Telemetry/DashboardNNB/AddWidgetWindow.jsx new file mode 100644 index 0000000..1cd15cd --- /dev/null +++ b/src/pages/Telemetry/DashboardNNB/AddWidgetWindow.jsx @@ -0,0 +1,52 @@ +import { PlusOutlined } from '@ant-design/icons' +import { Form, Select } from 'antd' +import { memo, useCallback, useMemo } from 'react' + +import Poprompt from '@components/selectors/Poprompt' + +export const createWidgetId = (witsRecord, dt = false) => `${witsRecord.recordId}_${witsRecord.itemId}` + (dt ? `_${Date.now()}` : '') + +export const makeWidgetFromWits = (witsRecord) => ({ + id: createWidgetId(witsRecord, true), + witsId: witsRecord.longMnemonic.toLowerCase(), + recordId: witsRecord.recordId, + unit: witsRecord.metricUnits, + label: witsRecord.longMnemonic, +}) + +const addWidgetRules = [{ required: true, message: 'Пожалуйста, выберите виджет' }] +const addWidgetButtonProps = { type: 'link', className: 'add_group', icon: } + +export const AddWidgetWindow = memo(({ witsInfo, onAdded }) => { + const options = useMemo(() => witsInfo?.map((witsRecord) => ({ + label: `Record #${witsRecord.recordId}: ${witsRecord.longMnemonic}`, + value: createWidgetId(witsRecord), + })) ?? [], [witsInfo]) + + const onFormFinish = useCallback((value) => { + if (!value?.widget) return + const record = witsInfo.find((witsRecord) => createWidgetId(witsRecord) === value.widget) + if (record) + onAdded?.(makeWidgetFromWits(record)) + }, [onAdded, witsInfo]) + + return ( + + +