From 9ccf7faa2f0a79443fbc8fc6b34f2a80be209651 Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Sun, 29 Jun 2025 22:38:11 +0100 Subject: [PATCH] Added dayjs dependency for date manipulation and refactored components to replace IdText with IdDisplay for consistent ID representation. Updated logging to use loglevel for improved debugging and removed console logs for cleaner code. --- package-lock.json | 1 + package.json | 1 + src/App.css | 2 +- src/assets/icons/eyeicon.afdesign | Bin 0 -> 45463 bytes src/assets/icons/eyeicon.min.svg | 1 + src/assets/icons/eyeicon.svg | 7 + src/assets/icons/eyeslashicon.afdesign | Bin 0 -> 52802 bytes src/assets/icons/eyeslashicon.min.svg | 1 + src/assets/icons/eyeslashicon.svg | 8 + src/assets/icons/linkicon.afdesign | Bin 0 -> 48418 bytes src/assets/icons/linkicon.min.svg | 1 + src/assets/icons/linkicon.svg | 7 + src/assets/icons/newmailicon.afdesign | Bin 0 -> 36529 bytes src/assets/icons/newmailicon.min.svg | 1 + src/assets/icons/newmailicon.svg | 8 + src/components/App/AppParticles.jsx | 4 +- .../Dashboard/Inventory/FilamentStocks.jsx | 6 +- .../FilamentStocks/FilamentStockInfo.jsx | 8 +- .../FilamentStocks/LoadFilamentStock.jsx | 2 +- .../Dashboard/Inventory/PartStocks.jsx | 6 +- .../Dashboard/Inventory/StockAudits.jsx | 8 +- .../Inventory/StockAudits/StockAuditInfo.jsx | 10 +- .../Dashboard/Inventory/StockEvents.jsx | 14 +- .../Dashboard/Management/AuditLogs.jsx | 12 +- .../Dashboard/Management/Filaments.jsx | 6 +- .../Management/Filaments/FilamentInfo.jsx | 841 +++++------------ .../Management/Filaments/LockIndicator.jsx | 28 + .../Management/Filaments/NewFilament.jsx | 1 - .../Dashboard/Management/Materials.jsx | 4 +- .../Dashboard/Management/NoteTypes.jsx | 6 +- .../Management/NoteTypes/NoteTypeInfo.jsx | 520 +++-------- src/components/Dashboard/Management/Parts.jsx | 6 +- .../Dashboard/Management/Parts/PartInfo.jsx | 13 +- .../Dashboard/Management/Products.jsx | 4 +- .../Management/Products/ProductInfo.jsx | 816 ++++------------ src/components/Dashboard/Management/Users.jsx | 4 +- .../Dashboard/Management/Users/UserInfo.jsx | 644 ++++--------- .../Dashboard/Management/Vendors.jsx | 4 +- .../Management/Vendors/VendorInfo.jsx | 683 ++++---------- .../Dashboard/Production/GCodeFiles.jsx | 6 +- .../Production/GCodeFiles/GCodeFileInfo.jsx | 819 ++++++---------- .../Production/GCodeFiles/NewGCodeFile.jsx | 4 - src/components/Dashboard/Production/Jobs.jsx | 4 +- .../Dashboard/Production/Jobs/JobInfo.jsx | 561 ++++------- .../Dashboard/Production/Printers.jsx | 6 +- .../Production/Printers/ControlPrinter.jsx | 18 +- .../Production/Printers/PrinterInfo.jsx | 879 +++++------------- .../Production/ProductionOverview.jsx | 2 - .../Dashboard/common/AuditLogTable.jsx | 12 +- .../Dashboard/common/ColorSelector.jsx | 55 ++ .../Dashboard/common/CopyButton.jsx | 73 ++ .../Dashboard/common/DashboardNotes.jsx | 4 +- .../Dashboard/common/DashboardTable.jsx | 14 +- .../Dashboard/common/EditButtons.jsx | 52 ++ .../Dashboard/common/EditObjectForm.jsx | 182 ++++ .../Dashboard/common/FilamentStockDisplay.jsx | 4 +- .../common/{IdText.jsx => IdDisplay.jsx} | 83 +- src/components/Dashboard/common/JobState.jsx | 4 +- .../Dashboard/common/ObjectInfo.jsx | 50 + .../Dashboard/common/ObjectProperty.jsx | 465 +++++++++ .../Dashboard/common/ObjectSelect.jsx | 29 +- .../Dashboard/common/PartsTable.jsx | 6 +- .../Dashboard/common/PrinterMovementPanel.jsx | 4 +- .../Dashboard/common/PrinterState.jsx | 6 +- .../common/PrinterTemperaturePanel.jsx | 3 - .../Dashboard/common/SecretDisplay.jsx | 50 + .../Dashboard/common/SpotlightTooltip.jsx | 6 +- .../Dashboard/common/StockEventTable.jsx | 10 +- .../Dashboard/common/SubJobCounter.jsx | 3 - .../Dashboard/common/SubJobState.jsx | 21 +- .../Dashboard/common/SubJobsTree.jsx | 4 +- .../Dashboard/common/TagsDisplay.jsx | 28 + src/components/Dashboard/common/TagsInput.jsx | 56 ++ .../Dashboard/common/TimeDisplay.jsx | 4 + .../Dashboard/common/ViewButton.jsx | 55 ++ .../Dashboard/context/ApiServerContext.js | 59 +- .../Dashboard/context/AuthContext.js | 7 +- .../Dashboard/context/SpotlightContext.js | 9 +- .../Dashboard/hooks/useTableScroll.js | 10 +- src/components/Dashboard/utils/Utils.js | 35 +- src/components/Icons/EmailDisplay.jsx | 55 ++ src/components/Icons/EyeIcon.jsx | 7 + src/components/Icons/EyeSlashIcon.jsx | 7 + src/components/Icons/LinkIcon.jsx | 7 + src/components/Icons/NewMailIcon.jsx | 7 + src/components/Icons/UrlDisplay.jsx | 59 ++ src/index.js | 2 +- 87 files changed, 3109 insertions(+), 4425 deletions(-) create mode 100644 src/assets/icons/eyeicon.afdesign create mode 100644 src/assets/icons/eyeicon.min.svg create mode 100644 src/assets/icons/eyeicon.svg create mode 100644 src/assets/icons/eyeslashicon.afdesign create mode 100644 src/assets/icons/eyeslashicon.min.svg create mode 100644 src/assets/icons/eyeslashicon.svg create mode 100644 src/assets/icons/linkicon.afdesign create mode 100644 src/assets/icons/linkicon.min.svg create mode 100644 src/assets/icons/linkicon.svg create mode 100644 src/assets/icons/newmailicon.afdesign create mode 100644 src/assets/icons/newmailicon.min.svg create mode 100644 src/assets/icons/newmailicon.svg create mode 100644 src/components/Dashboard/Management/Filaments/LockIndicator.jsx create mode 100644 src/components/Dashboard/common/ColorSelector.jsx create mode 100644 src/components/Dashboard/common/CopyButton.jsx create mode 100644 src/components/Dashboard/common/EditButtons.jsx create mode 100644 src/components/Dashboard/common/EditObjectForm.jsx rename src/components/Dashboard/common/{IdText.jsx => IdDisplay.jsx} (57%) create mode 100644 src/components/Dashboard/common/ObjectInfo.jsx create mode 100644 src/components/Dashboard/common/ObjectProperty.jsx create mode 100644 src/components/Dashboard/common/SecretDisplay.jsx create mode 100644 src/components/Dashboard/common/TagsDisplay.jsx create mode 100644 src/components/Dashboard/common/TagsInput.jsx create mode 100644 src/components/Dashboard/common/ViewButton.jsx create mode 100644 src/components/Icons/EmailDisplay.jsx create mode 100644 src/components/Icons/EyeIcon.jsx create mode 100644 src/components/Icons/EyeSlashIcon.jsx create mode 100644 src/components/Icons/LinkIcon.jsx create mode 100644 src/components/Icons/NewMailIcon.jsx create mode 100644 src/components/Icons/UrlDisplay.jsx diff --git a/package-lock.json b/package-lock.json index 005bd84..9244c2b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "antd-style": "^3.7.1", "axios": "^1.9.0", "country-list": "^2.3.0", + "dayjs": "^1.11.13", "dotenv": "^16.5.0", "eslint": "^8.57.0", "eslint-config-prettier": "^10.1.5", diff --git a/package.json b/package.json index f7b0ca1..5f94f7c 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "antd-style": "^3.7.1", "axios": "^1.9.0", "country-list": "^2.3.0", + "dayjs": "^1.11.13", "dotenv": "^16.5.0", "eslint": "^8.57.0", "eslint-config-prettier": "^10.1.5", diff --git a/src/App.css b/src/App.css index 8c52b6d..c35bfdb 100644 --- a/src/App.css +++ b/src/App.css @@ -110,7 +110,7 @@ code { margin-bottom: 0.15em; } -.idtext .ant-popover-inner { +.iddisplay .ant-popover-inner { padding: 0 !important; } diff --git a/src/assets/icons/eyeicon.afdesign b/src/assets/icons/eyeicon.afdesign new file mode 100644 index 0000000000000000000000000000000000000000..ee04223f514cc13087465602adf87a9c2999007b GIT binary patch literal 45463 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 \ No newline at end of file diff --git a/src/assets/icons/eyeicon.svg b/src/assets/icons/eyeicon.svg new file mode 100644 index 0000000..bc9d2f6 --- /dev/null +++ b/src/assets/icons/eyeicon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/assets/icons/eyeslashicon.afdesign b/src/assets/icons/eyeslashicon.afdesign new file mode 100644 index 0000000000000000000000000000000000000000..ddb19ebbbc7ab828284f39e318b4391efb82f279 GIT binary patch literal 52802 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 literal 0 HcmV?d00001 diff --git a/src/assets/icons/eyeslashicon.min.svg b/src/assets/icons/eyeslashicon.min.svg new file mode 100644 index 0000000..790ae6c --- /dev/null +++ b/src/assets/icons/eyeslashicon.min.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/eyeslashicon.svg b/src/assets/icons/eyeslashicon.svg new file mode 100644 index 0000000..f59e1ec --- /dev/null +++ b/src/assets/icons/eyeslashicon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/icons/linkicon.afdesign b/src/assets/icons/linkicon.afdesign new file mode 100644 index 0000000000000000000000000000000000000000..a1dc0ec0914811c4132e0900c478168312290583 GIT binary patch literal 48418 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 Teju6+K{v1IYn5KLfBb&{ibTl! literal 0 HcmV?d00001 diff --git a/src/assets/icons/linkicon.min.svg b/src/assets/icons/linkicon.min.svg new file mode 100644 index 0000000..737619a --- /dev/null +++ b/src/assets/icons/linkicon.min.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/linkicon.svg b/src/assets/icons/linkicon.svg new file mode 100644 index 0000000..ce2b1a1 --- /dev/null +++ b/src/assets/icons/linkicon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/assets/icons/newmailicon.afdesign b/src/assets/icons/newmailicon.afdesign new file mode 100644 index 0000000000000000000000000000000000000000..8863f1dcd2cda7a03714433cbd20d423e843190d GIT binary patch literal 36529 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 literal 0 HcmV?d00001 diff --git a/src/assets/icons/newmailicon.min.svg b/src/assets/icons/newmailicon.min.svg new file mode 100644 index 0000000..7d8a94c --- /dev/null +++ b/src/assets/icons/newmailicon.min.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/newmailicon.svg b/src/assets/icons/newmailicon.svg new file mode 100644 index 0000000..d570f57 --- /dev/null +++ b/src/assets/icons/newmailicon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/components/App/AppParticles.jsx b/src/components/App/AppParticles.jsx index a6acb57..5aa190e 100644 --- a/src/components/App/AppParticles.jsx +++ b/src/components/App/AppParticles.jsx @@ -29,9 +29,7 @@ const AppParticles = () => { }) }, []) - const particlesLoaded = useCallback(() => { - console.log('Particles Loaded!') - }, []) + const particlesLoaded = useCallback(() => {}, []) const options = useMemo( () => ({ diff --git a/src/components/Dashboard/Inventory/FilamentStocks.jsx b/src/components/Dashboard/Inventory/FilamentStocks.jsx index c9275a6..de83cc2 100644 --- a/src/components/Dashboard/Inventory/FilamentStocks.jsx +++ b/src/components/Dashboard/Inventory/FilamentStocks.jsx @@ -19,7 +19,7 @@ import { AuthContext } from '../context/AuthContext' import { PrintServerContext } from '../context/PrintServerContext' import NewFilamentStock from './FilamentStocks/NewFilamentStock' -import IdText from '../common/IdText' +import IdDisplay from '../common/IdDisplay' import FilamentStockIcon from '../../Icons/FilamentStockIcon' import InfoCircleIcon from '../../Icons/InfoCircleIcon' import PlusIcon from '../../Icons/PlusIcon' @@ -124,7 +124,7 @@ const FilamentStocks = () => { key: 'id', width: 180, render: (text) => ( - + ) }, { @@ -216,7 +216,6 @@ const FilamentStocks = () => { if (printServer && !initialized) { setInitialized(true) printServer.on('notify_filamentstock_update', (updateData) => { - console.log('Received filament stock update:', updateData) if (tableRef.current) { tableRef.current.updateData(updateData._id, updateData) } @@ -225,7 +224,6 @@ const FilamentStocks = () => { return () => { if (printServer && initialized) { - console.log('Deregistering filament stock update listener') printServer.off('notify_filamentstock_update') } } diff --git a/src/components/Dashboard/Inventory/FilamentStocks/FilamentStockInfo.jsx b/src/components/Dashboard/Inventory/FilamentStocks/FilamentStockInfo.jsx index 2f59597..b2767ed 100644 --- a/src/components/Dashboard/Inventory/FilamentStocks/FilamentStockInfo.jsx +++ b/src/components/Dashboard/Inventory/FilamentStocks/FilamentStockInfo.jsx @@ -18,7 +18,7 @@ import { Checkbox } from 'antd' import { LoadingOutlined, CaretLeftOutlined } from '@ant-design/icons' -import IdText from '../../common/IdText' +import IdDisplay from '../../common/IdDisplay' import { PrintServerContext } from '../../context/PrintServerContext' import FilamentStockState from '../../common/FilamentStockState' import StockEventTable from '../../common/StockEventTable' @@ -78,7 +78,6 @@ const FilamentStockInfo = () => { if (printServer && !initialized && filamentStockId) { setInitialized(true) printServer.on('notify_filamentstock_update', (statusUpdate) => { - console.log('GOT FILAMENT STOCK UPDATE', statusUpdate) setFilamentStockData((prevData) => { if (statusUpdate?._id === filamentStockId) { return { @@ -92,7 +91,6 @@ const FilamentStockInfo = () => { } return () => { if (printServer && initialized) { - console.log('Deregistering filament stock update listener') printServer.off('notify_filamentstock_update') } } @@ -260,7 +258,7 @@ const FilamentStockInfo = () => { {/* Read-only fields */} {filamentStockData?.id ? ( - @@ -316,7 +314,7 @@ const FilamentStockInfo = () => { {filamentStockData?.filament ? ( - { dataIndex: '_id', key: 'id', width: 180, - render: (text) => + render: (text) => ( + + ) }, { title: 'State', diff --git a/src/components/Dashboard/Inventory/StockAudits.jsx b/src/components/Dashboard/Inventory/StockAudits.jsx index 28f0272..8dcc5e1 100644 --- a/src/components/Dashboard/Inventory/StockAudits.jsx +++ b/src/components/Dashboard/Inventory/StockAudits.jsx @@ -5,7 +5,7 @@ import { Button, Flex, Space, message, Dropdown, Typography } from 'antd' import { AuthContext } from '../context/AuthContext' import { PrintServerContext } from '../context/PrintServerContext' -import IdText from '../common/IdText' +import IdDisplay from '../common/IdDisplay' import StockAuditIcon from '../../Icons/StockAuditIcon' import InfoCircleIcon from '../../Icons/InfoCircleIcon' import PlusIcon from '../../Icons/PlusIcon' @@ -30,7 +30,6 @@ const StockAudits = () => { if (printServer && !initialized) { setInitialized(true) printServer.on('notify_stockaudit_update', (updateData) => { - console.log('Received stock audit update:', updateData) if (tableRef.current) { tableRef.current.updateData(updateData._id, updateData) } @@ -39,7 +38,6 @@ const StockAudits = () => { return () => { if (printServer && initialized) { - console.log('Deregistering stock audit update listener') printServer.off('notify_stockaudit_update') } } @@ -76,7 +74,9 @@ const StockAudits = () => { dataIndex: '_id', key: 'id', width: 180, - render: (text) => + render: (text) => ( + + ) }, { title: 'Status', diff --git a/src/components/Dashboard/Inventory/StockAudits/StockAuditInfo.jsx b/src/components/Dashboard/Inventory/StockAudits/StockAuditInfo.jsx index eada020..68ddf2f 100644 --- a/src/components/Dashboard/Inventory/StockAudits/StockAuditInfo.jsx +++ b/src/components/Dashboard/Inventory/StockAudits/StockAuditInfo.jsx @@ -18,7 +18,7 @@ import { } from '@ant-design/icons' import { AuthContext } from '../../context/AuthContext' -import IdText from '../../common/IdText' +import IdDisplay from '../../common/IdDisplay' import TimeDisplay from '../../common/TimeDisplay' import config from '../../../../config' @@ -105,7 +105,7 @@ const StockAuditInfo = () => { key: 'id', width: 180, render: (text) => ( - + ) }, { @@ -180,7 +180,11 @@ const StockAuditInfo = () => { Stock Audit Details - + {getStatusTag(stockAudit.status)} diff --git a/src/components/Dashboard/Inventory/StockEvents.jsx b/src/components/Dashboard/Inventory/StockEvents.jsx index ce14d3a..931499a 100644 --- a/src/components/Dashboard/Inventory/StockEvents.jsx +++ b/src/components/Dashboard/Inventory/StockEvents.jsx @@ -12,7 +12,7 @@ import { import { AuthContext } from '../context/AuthContext' import { PrintServerContext } from '../context/PrintServerContext' -import IdText from '../common/IdText' +import IdDisplay from '../common/IdDisplay' import TimeDisplay from '../common/TimeDisplay' import ReloadIcon from '../../Icons/ReloadIcon' import PlusMinusIcon from '../../Icons/PlusMinusIcon' @@ -75,7 +75,7 @@ const StockEvents = () => { dataIndex: '_id', width: 170, render: (id) => { - return + return } }, { @@ -100,7 +100,7 @@ const StockEvents = () => { render: (record) => { if (record.filamentStock?._id) { return ( - { const ids = ( {record.job ? ( - { /> ) : null} {record.subJob?.number ? ( - ) : null} {record.stockAudit ? ( - { if (printServer && !initialized) { setInitialized(true) printServer.on('notify_stockevent_update', (updateData) => { - console.log('Received stock event update:', updateData) if (tableRef.current) { tableRef.current.updateData(updateData._id, updateData) } @@ -237,7 +236,6 @@ const StockEvents = () => { return () => { if (printServer && initialized) { - console.log('Deregistering stock event update listener') printServer.off('notify_stockevent_update') } } diff --git a/src/components/Dashboard/Management/AuditLogs.jsx b/src/components/Dashboard/Management/AuditLogs.jsx index 96a92f2..22d628d 100644 --- a/src/components/Dashboard/Management/AuditLogs.jsx +++ b/src/components/Dashboard/Management/AuditLogs.jsx @@ -13,7 +13,7 @@ import { } from 'antd' import { AuthContext } from '../context/AuthContext' -import IdText from '../common/IdText' +import IdDisplay from '../common/IdDisplay' import ReloadIcon from '../../Icons/ReloadIcon' import useColumnVisibility from '../hooks/useColumnVisibility' import TimeDisplay from '../common/TimeDisplay' @@ -66,7 +66,7 @@ const formatValue = (value, propertyName) => { if (isObjectId(value)) { return ( - { key: 'id', fixed: 'left', width: 180, - render: (text) => , + render: (text) => ( + + ), filterDropdown: ({ setSelectedKeys, selectedKeys, @@ -147,7 +149,7 @@ const AuditLogs = () => { key: 'owner', width: 180, render: (record) => ( - { key: 'target', width: 180, render: (record) => ( - { dataIndex: '_id', key: 'id', width: 180, - render: (text) => , + render: (text) => ( + + ), filterDropdown: ({ setSelectedKeys, selectedKeys, diff --git a/src/components/Dashboard/Management/Filaments/FilamentInfo.jsx b/src/components/Dashboard/Management/Filaments/FilamentInfo.jsx index adf0696..2dd4171 100644 --- a/src/components/Dashboard/Management/Filaments/FilamentInfo.jsx +++ b/src/components/Dashboard/Management/Filaments/FilamentInfo.jsx @@ -1,62 +1,30 @@ -import React, { useState, useEffect, useContext, useCallback } from 'react' +import React from 'react' import { useLocation } from 'react-router-dom' -import { - Descriptions, - Spin, - Space, - Button, - message, - Badge, - Typography, - Flex, - Form, - Input, - InputNumber, - ColorPicker, - Select, - Dropdown, - Popover, - Checkbox, - Card, - Tag -} from 'antd' +import { Space, Button, Flex, Dropdown, Card } from 'antd' import { LoadingOutlined } from '@ant-design/icons' import loglevel from 'loglevel' import config from '../../../../config' -import IdText from '../../common/IdText' import ReloadIcon from '../../../Icons/ReloadIcon' -import EditIcon from '../../../Icons/EditIcon.jsx' -import XMarkIcon from '../../../Icons/XMarkIcon.jsx' -import CheckIcon from '../../../Icons/CheckIcon.jsx' -import TimeDisplay from '../../common/TimeDisplay.jsx' -import VendorSelect from '../../common/VendorSelect' import useCollapseState from '../../hooks/useCollapseState' import AuditLogTable from '../../common/AuditLogTable' import DashboardNotes from '../../common/DashboardNotes' import InfoCollapse from '../../common/InfoCollapse' +import ObjectInfo from '../../common/ObjectInfo' +import ViewButton from '../../common/ViewButton' import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx' import NoteIcon from '../../../Icons/NoteIcon.jsx' import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx' -import LockIcon from '../../../Icons/LockIcon.jsx' -import { ApiServerContext } from '../../context/ApiServerContext' +import EditObjectForm from '../../common/EditObjectForm' +import EditButtons from '../../common/EditButtons' +import LockIndicator from './LockIndicator' const log = loglevel.getLogger('FilamentInfo') log.setLevel(config.logLevel) -const { Link, Text } = Typography - const FilamentInfo = () => { - const [filamentData, setFilamentData] = useState(null) - const [fetchLoading, setFetchLoading] = useState(true) - const [editLoading, setEditLoading] = useState(false) - const [lockUser, setLockUser] = useState(null) - const [initialized, setInitialized] = useState(false) const location = useLocation() - const [messageApi, contextHolder] = message.useMessage() const filamentId = new URLSearchParams(location.search).get('filamentId') - const [isEditing, setIsEditing] = useState(false) - const [form] = Form.useForm() const [collapseState, updateCollapseState] = useCollapseState( 'FilamentInfo', { @@ -66,600 +34,217 @@ const FilamentInfo = () => { auditLogs: true } ) - const { - apiServer, - fetchObjectInfo, - updateObjectInfo, - lockObject, - unlockObject, - onLockEvent, - onUpdateEvent, - fetchObjectLock, - showError - } = useContext(ApiServerContext) - - // Define the event handler function - const lockEventHandler = useCallback((lockEvent) => { - if (lockEvent.locked === true) { - setLockUser(lockEvent.user) - } else { - setLockUser(null) - } - }, []) - - // Cleanup effect for component unmount - useEffect(() => { - return () => { - if (filamentId) { - // Ensure any remaining locks are released when component unmounts - unlockObject(filamentId, 'filament') - } - } - }, [filamentId, unlockObject]) - - useEffect(() => { - if (filamentData) { - form.setFieldsValue({ - name: filamentData.name || '', - brand: filamentData.brand || '', - type: filamentData.type || '', - cost: filamentData.cost || null, - color: filamentData.color || '#000000', - diameter: filamentData.diameter || null, - density: filamentData.density || null, - url: filamentData.url || '', - barcode: filamentData.barcode || '', - emptySpoolWeight: filamentData.emptySpoolWeight || '' - }) - } - }, [filamentData, form]) - - const fetchFilamentInfo = useCallback(async () => { - try { - setFetchLoading(true) - const data = await fetchObjectInfo(filamentId, 'filament') - const lockEvent = await fetchObjectLock(filamentId, 'filament') - setLockUser(lockEvent?.user || null) - setFilamentData(data) - form.setFieldsValue(data) - setFetchLoading(false) - } catch (err) { - messageApi.error('Failed to fetch filament info') - // Show error modal with retry functionality - showError( - `Failed to fetch filament information. Message: ${err.message}. Code: ${err.code}`, - fetchFilamentInfo - ) - } - }, [ - fetchObjectInfo, - fetchObjectLock, - filamentId, - form, - messageApi, - showError - ]) - - const updateFilamentInfo = async () => { - const values = form.getFieldsValue() - const updateValue = { - name: values.name, - vendor: values.vendor, - type: values.type, - cost: values.cost, - color: values.color, - diameter: values.diameter, - density: values.density, - url: values.url, - barcode: values.barcode, - emptySpoolWeight: values.emptySpoolWeight - } - await updateObjectInfo(filamentId, 'filament', updateValue) - } - - // Define the update event handler function - const updateEventHandler = useCallback( - (updateEvent) => { - log.debug('Update event received for filament:', updateEvent) - // Refresh the filament data when an update is received - fetchFilamentInfo() - }, - [fetchFilamentInfo] - ) - - useEffect(() => { - if (initialized == false && filamentId && apiServer?.connected === true) { - setInitialized(true) - fetchFilamentInfo() - } - }, [filamentId, apiServer?.connected, initialized, fetchFilamentInfo]) - - useEffect(() => { - if (filamentId) { - const cleanup = onLockEvent(filamentId, lockEventHandler) - return cleanup - } - }, [filamentId, onLockEvent, lockEventHandler]) - - useEffect(() => { - if (filamentId) { - const cleanup = onUpdateEvent(filamentId, updateEventHandler) - return cleanup - } - }, [filamentId, onUpdateEvent, updateEventHandler]) - - const startEditing = () => { - updateCollapseState('info', true) - setIsEditing(true) - lockObject(filamentId, 'filament') - } - - const cancelEditing = () => { - // Reset form values to original data - if (filamentData) { - form.setFieldsValue({ - name: filamentData.name || '', - brand: filamentData.brand || '', - type: filamentData.type || '', - cost: filamentData.cost || null, - color: filamentData.color || '#000000', - diameter: filamentData.diameter || null, - density: filamentData.density || null, - url: filamentData.url || '', - barcode: filamentData.barcode || '', - emptySpoolWeight: filamentData.emptySpoolWeight || '' - }) - } - setIsEditing(false) - unlockObject(filamentId, 'filament') - } - - const handleUpdateFilamentInfo = async () => { - try { - const values = await form.validateFields() - setEditLoading(true) - - await updateFilamentInfo() - - // Update the local state with the new values - setFilamentData({ ...filamentData, ...values }) - setIsEditing(false) - messageApi.success('Filament information updated successfully') - } catch (err) { - if (err.errorFields) { - // This is a form validation error - return - } - console.error('Failed to update filament information:', err) - messageApi.error('Failed to update filament information') - // Show error modal with retry functionality - showError( - `Failed to update filament information. Message: ${err.message}. Code: ${err.code}`, - () => handleUpdateFilamentInfo() - ) - } finally { - fetchFilamentInfo() - setEditLoading(false) - } - } - - const actionItems = { - items: [ - { - label: 'Reload Filament', - key: 'reload', - icon: - } - ], - onClick: ({ key }) => { - if (key === 'reload') { - fetchFilamentInfo() - } - } - } - - const getViewDropdownItems = () => { - const sections = [ - { key: 'info', label: 'Filament Information' }, - { key: 'notes', label: 'Notes' }, - { key: 'auditLogs', label: 'Audit Logs' } - ] - - return ( - - - {sections.map((section) => ( - { - updateCollapseState(section.key, e.target.checked) - }} - > - {section.label} - - ))} - - - ) - } return ( - <> - {contextHolder} - - - - - - - - - - + + {({ + loading, + isEditing, + startEditing, + cancelEditing, + handleUpdate, + formValid, + objectData, + editLoading, + lock, + fetchObject + }) => ( + + + + + + } + ], + onClick: ({ key }) => { + if (key === 'reload') { + fetchObject() + } + } + }} + > + + + + + - {lockUser && ( - - } - style={{ margin: 0 }} - color={'orange'} - /> - - - )} - - - {isEditing ? ( - <> - - - - - - - - {isEditing ? ( - <> - - - ) : ( -

- {contextHolder} - - updateCollapseState('info', keys.length > 0)} - expandIcon={({ isActive }) => ( - + + + + } + ], + onClick: ({ key }) => { + if (key === 'reload') { + fetchObject() + } + } + }} + > + + + - )} - className='no-h-padding-collapse no-t-padding-collapse' - > - - - - Note Type Information - - - } - key='1' + + + + + + + + +
+ + } + active={collapseState.info} + onToggle={(expanded) => updateCollapseState('info', expanded)} + key='info' > - }> -
- - - - - - - - - - {isEditing ? ( - - - - ) : ( - noteTypeData?.name - )} - - - - - - - {isEditing ? ( - - { - if (color != null) { - return '#' + color.toHex() - } - return null - }} - > - - - { - setColorEnabled(e.target.checked) - if (!e.target.checked) { - form.setFieldValue('color', null) - } else if (e.target.checked) { - form.setFieldValue('color', '#000000') - } - }} - /> - - ) : noteTypeData?.color ? ( - - ) : ( - n/a - )} - - - - {isEditing ? ( - - - - ) : noteTypeData ? ( - - ) : ( - n/a - )} - - -
-
- - - - - updateCollapseState('auditLogs', keys.length > 0) - } - expandIcon={({ isActive }) => ( - } + isEditing={isEditing} + type='notetype' + items={[ + { + name: 'id', + label: 'ID', + value: objectData?._id, + type: 'id', + objectType: 'notetype', + showCopy: true + }, + { + name: 'createdAt', + label: 'Created At', + value: objectData?.createdAt, + type: 'dateTime', + readOnly: true + }, + { + name: 'name', + label: 'Name', + value: objectData?.name, + required: true, + type: 'text' + }, + { + name: 'updatedAt', + label: 'Updated At', + value: objectData?.updatedAt, + type: 'dateTime', + readOnly: true + }, + { + name: 'color', + label: 'Color', + value: objectData?.color, + type: 'color' + }, + { + name: 'active', + label: 'Active', + value: objectData?.active, + type: 'bool' + } + ]} /> - )} - className='no-h-padding-collapse' - > - - - - Audit Logs - -
+ + + } + active={collapseState.auditLogs} + onToggle={(expanded) => + updateCollapseState('auditLogs', expanded) } - key='2' + key='auditLogs' > - - - -
+ + +
+ )} - + ) } diff --git a/src/components/Dashboard/Management/Parts.jsx b/src/components/Dashboard/Management/Parts.jsx index 8d58126..969cd7d 100644 --- a/src/components/Dashboard/Management/Parts.jsx +++ b/src/components/Dashboard/Management/Parts.jsx @@ -17,7 +17,7 @@ import { import { DownloadOutlined } from '@ant-design/icons' import { AuthContext } from '../context/AuthContext' -import IdText from '../common/IdText' +import IdDisplay from '../common/IdDisplay' import DashboardTable from '../common/DashboardTable' import NewProduct from './Products/NewProduct' import PartIcon from '../../Icons/PartIcon' @@ -81,7 +81,7 @@ const Parts = () => { dataIndex: '_id', key: 'id', width: 180, - render: (text) => + render: (text) => }, { title: 'Product Name', @@ -109,7 +109,7 @@ const Parts = () => { key: 'productId', width: 180, render: (record) => ( - { setError(null) } catch (err) { setError('Failed to fetch part details') - console.log(err) + logger.debug(err) messageApi.error('Failed to fetch part details') } finally { setFetchLoading(false) @@ -176,7 +179,7 @@ const PartInfo = () => { } } catch (err) { setError('Failed to fetch part content') - console.log(err) + logger.debug(err) messageApi.error('Failed to fetch part content') } finally { setFetchLoading(false) @@ -398,7 +401,7 @@ const PartInfo = () => { > {partData?.id ? ( - + ) : ( n/a )} @@ -459,7 +462,7 @@ const PartInfo = () => { {partData?.product?._id ? ( - { key: 'id', fixed: 'left', width: 180, - render: (text) => , + render: (text) => , filterDropdown: ({ setSelectedKeys, selectedKeys, diff --git a/src/components/Dashboard/Management/Products/ProductInfo.jsx b/src/components/Dashboard/Management/Products/ProductInfo.jsx index a127def..d43d4af 100644 --- a/src/components/Dashboard/Management/Products/ProductInfo.jsx +++ b/src/components/Dashboard/Management/Products/ProductInfo.jsx @@ -1,56 +1,25 @@ -import React, { useState, useEffect } from 'react' +import React from 'react' import { useLocation } from 'react-router-dom' -import axios from 'axios' -import { - Descriptions, - Spin, - Space, - Button, - message, - Typography, - Flex, - Form, - Input, - Tag, - Checkbox, - InputNumber, - Collapse, - Dropdown, - Popover, - Card -} from 'antd' -import { LoadingOutlined, CaretLeftOutlined } from '@ant-design/icons' -import IdText from '../../common/IdText.jsx' -import VendorSelect from '../../common/VendorSelect.jsx' -import PartsTable from '../../common/PartsTable.jsx' -import useCollapseState from '../../hooks/useCollapseState' -import PlusIcon from '../../../Icons/PlusIcon' +import { Space, Button, Flex, Dropdown, Card } from 'antd' import ReloadIcon from '../../../Icons/ReloadIcon' -import EditIcon from '../../../Icons/EditIcon.jsx' -import XMarkIcon from '../../../Icons/XMarkIcon.jsx' -import CheckIcon from '../../../Icons/CheckIcon.jsx' -import TimeDisplay from '../../common/TimeDisplay.jsx' +import useCollapseState from '../../hooks/useCollapseState' import AuditLogTable from '../../common/AuditLogTable' import DashboardNotes from '../../common/DashboardNotes' - -import config from '../../../../config.js' +import InfoCollapse from '../../common/InfoCollapse' +import ObjectInfo from '../../common/ObjectInfo' +import ViewButton from '../../common/ViewButton' +import EditObjectForm from '../../common/EditObjectForm' +import EditButtons from '../../common/EditButtons' +import LockIndicator from '../Filaments/LockIndicator' +import PartsTable from '../../common/PartsTable' import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx' +import NoteIcon from '../../../Icons/NoteIcon.jsx' import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx' import ProductIcon from '../../../Icons/ProductIcon.jsx' -import NoteIcon from '../../../Icons/NoteIcon.jsx' - -const { Title, Text } = Typography const ProductInfo = () => { - const [productData, setProductData] = useState(null) - const [loading, setLoading] = useState(false) - const [error, setError] = useState(null) const location = useLocation() - const [messageApi, contextHolder] = message.useMessage() const productId = new URLSearchParams(location.search).get('productId') - const [isEditing, setIsEditing] = useState(false) - const [fetchLoading, setFetchLoading] = useState(true) - const [marginOrPrice, setMarginOrPrice] = useState(false) const [collapseState, updateCollapseState] = useCollapseState('ProductInfo', { info: true, parts: true, @@ -58,600 +27,209 @@ const ProductInfo = () => { auditLogs: true }) - const [productForm] = Form.useForm() - const [productFormValues, setProductFormValues] = useState({}) - - const handleTagClose = (removedTag) => { - const newTags = productData.tags.filter((tag) => tag !== removedTag) - setProductData((prev) => ({ ...prev, tags: newTags })) - } - - const handleTagAdd = () => { - const input = productForm.getFieldValue('newTag') - if (input) { - const newTag = input.trim() - if (newTag && !productData.tags.includes(newTag)) { - setProductData((prev) => ({ ...prev, tags: [...prev.tags, newTag] })) - productForm.setFieldValue('newTag', '') - } - } - } - - useEffect(() => { - setMarginOrPrice(productFormValues.marginOrPrice) - }, [productFormValues]) - - useEffect(() => { - async function fetchData() { - console.log('hello') - await fetchProductDetails() - } - if (productId) { - fetchData() - } - }, [productId]) - - useEffect(() => { - if (productData) { - productForm.setFieldsValue({ - name: productData.name || '', - vendor: productData.vendor || null, - version: productData.version || '', - tags: productData.tags || [], - price: productData.price || null, - margin: productData.margin || null, - marginOrPrice: productData.marginOrPrice || false - }) - setProductFormValues(productData) - setMarginOrPrice(productData.marginOrPrice) - } - }, [productData, productForm]) - - const fetchProductDetails = async () => { - try { - setFetchLoading(true) - const response = await axios.get( - `${config.backendUrl}/products/${productId}`, - { - headers: { - Accept: 'application/json' - }, - withCredentials: true - } - ) - setProductData(response.data) - setError(null) - } catch (err) { - setError('Failed to fetch product details') - console.log(err) - messageApi.error('Failed to fetch product details') - } finally { - setFetchLoading(false) - } - } - - const startEditing = () => { - updateCollapseState('info', true) - setIsEditing(true) - } - - const cancelEditing = () => { - // Reset form values to original data - if (productData) { - productForm.setFieldsValue({ - name: productData.name || '', - vendor: productData.vendor || { id: null, name: '' }, - version: productData.version || '', - tags: productData.tags || [], - cost: productData.cost || null, - price: productData.price || null, - margin: productData.margin || null, - marginOrPrice: productData.marginOrPrice || null - }) - setMarginOrPrice(productData.marginOrPrice) - } - setIsEditing(false) - } - - const updateInfo = async () => { - try { - const values = await productForm.validateFields() - setLoading(true) - - await axios.put(`${config.backendUrl}/products/${productId}`, values, { - headers: { - 'Content-Type': 'application/json' - }, - withCredentials: true - }) - - setProductData({ - ...productData, - ...values - }) - setIsEditing(false) - messageApi.success('Product information updated successfully') - } catch (err) { - if (err.errorFields) { - return - } - console.error('Failed to update product information:', err) - messageApi.error('Failed to update product information') - } finally { - await fetchProductDetails() - setLoading(false) - } - } - - const actionItems = { - items: [ - { - label: 'Reload Product', - key: 'reload', - icon: - } - ], - onClick: ({ key }) => { - if (key === 'reload') { - fetchProductDetails() - } - } - } - - const getViewDropdownItems = () => { - const sections = [ - { key: 'info', label: 'Product Information' }, - { key: 'parts', label: 'Product Parts' }, - { key: 'notes', label: 'Notes' }, - { key: 'auditLogs', label: 'Audit Logs' } - ] - - return ( - - - {sections.map((section) => ( - { - updateCollapseState(section.key, e.target.checked) - }} - > - {section.label} - - ))} - - - ) - } - - if (error) { - return ( - -

{error || 'Product not found'}

- -
- ) - } - return ( - <> - {contextHolder} - - - - - - - - - - - - {isEditing ? ( - <> - + + - - - ) : (
- - updateCollapseState('info', keys.length > 0) - } - expandIcon={({ isActive }) => ( - - )} - className='no-h-padding-collapse no-t-padding-collapse' + } + active={collapseState.info} + onToggle={(expanded) => updateCollapseState('info', expanded)} + key='info' > - - - - Product Information - - - } - key='1' - > -
- setProductFormValues((prevValues) => ({ - ...prevValues, - ...changedValues - })) + - } - spinning={fetchLoading} - > - - - {productData?.id ? ( - - ) : ( - n/a - )} - + ]} + /> + - - {productData?.createdAt ? ( - - ) : ( - n/a - )} - - - - {isEditing ? ( - - - - ) : productData?.name ? ( - {productData.name} - ) : ( - n/a - )} - - - - {productData?.updatedAt ? ( - - ) : ( - n/a - )} - - - - {isEditing ? ( - - - - ) : productData?.vendor?.name ? ( - {productData.vendor.name} - ) : ( - n/a - )} - - - - {productData?.vendor?.id ? ( - - ) : ( - n/a - )} - - - - {isEditing ? ( - - {marginOrPrice == false ? ( - - - - ) : ( - - - - )} - - Price - - - ) : productData?.margin && marginOrPrice == false ? ( - {productData.margin + '%'} - ) : productData?.price && marginOrPrice == true ? ( - {'£' + productData.price} - ) : ( - n/a - )} - - - - {isEditing ? ( - - - - ) : productData?.version ? ( - {productData.version} - ) : ( - n/a - )} - - - - {isEditing ? ( - - - {productData?.tags?.map((tag) => ( - handleTagClose(tag)} - style={{ marginBottom: 12 }} - > - {tag} - - ))} - - - - - -
- )} -
- +
+ )} + ) } diff --git a/src/components/Dashboard/Management/Users.jsx b/src/components/Dashboard/Management/Users.jsx index b148e46..5c83815 100644 --- a/src/components/Dashboard/Management/Users.jsx +++ b/src/components/Dashboard/Management/Users.jsx @@ -12,7 +12,7 @@ import { } from 'antd' import { ExportOutlined } from '@ant-design/icons' import { AuthContext } from '../context/AuthContext' -import IdText from '../common/IdText' +import IdDisplay from '../common/IdDisplay' import TimeDisplay from '../common/TimeDisplay' import DashboardTable from '../common/DashboardTable' import PersonIcon from '../../Icons/PersonIcon' @@ -248,7 +248,7 @@ const Users = () => { dataIndex: '_id', key: 'id', width: 180, - render: (text) => , + render: (text) => , filterDropdown: ({ setSelectedKeys, selectedKeys, diff --git a/src/components/Dashboard/Management/Users/UserInfo.jsx b/src/components/Dashboard/Management/Users/UserInfo.jsx index f35daa4..d903a9f 100644 --- a/src/components/Dashboard/Management/Users/UserInfo.jsx +++ b/src/components/Dashboard/Management/Users/UserInfo.jsx @@ -1,509 +1,207 @@ -import React, { useState, useEffect } from 'react' +import React from 'react' import { useLocation } from 'react-router-dom' -import axios from 'axios' -import { - Descriptions, - Spin, - Space, - Button, - message, - Typography, - Flex, - Form, - Input, - Collapse, - Dropdown, - Popover, - Card, - Checkbox -} from 'antd' -import { - LoadingOutlined, - ExportOutlined, - CaretLeftOutlined -} from '@ant-design/icons' -import IdText from '../../common/IdText' -import TimeDisplay from '../../common/TimeDisplay' +import { Space, Button, Flex, Dropdown, Card } from 'antd' +import { LoadingOutlined } from '@ant-design/icons' import ReloadIcon from '../../../Icons/ReloadIcon' -import EditIcon from '../../../Icons/EditIcon.jsx' -import XMarkIcon from '../../../Icons/XMarkIcon.jsx' -import CheckIcon from '../../../Icons/CheckIcon.jsx' import useCollapseState from '../../hooks/useCollapseState' import AuditLogTable from '../../common/AuditLogTable' import DashboardNotes from '../../common/DashboardNotes' +import InfoCollapse from '../../common/InfoCollapse' +import ObjectInfo from '../../common/ObjectInfo' +import ViewButton from '../../common/ViewButton' import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx' import NoteIcon from '../../../Icons/NoteIcon.jsx' import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx' - -import config from '../../../../config.js' - -const { Title, Link, Text } = Typography +import EditObjectForm from '../../common/EditObjectForm' +import EditButtons from '../../common/EditButtons' +import LockIndicator from '../Filaments/LockIndicator' const UserInfo = () => { - const [userData, setUserData] = useState(null) - const [loading, setLoading] = useState(false) - const [error, setError] = useState(null) const location = useLocation() - const [messageApi, contextHolder] = message.useMessage() const userId = new URLSearchParams(location.search).get('userId') - const [isEditing, setIsEditing] = useState(false) - const [form] = Form.useForm() - const [fetchLoading, setFetchLoading] = useState(true) const [collapseState, updateCollapseState] = useCollapseState('UserInfo', { info: true, notes: true, auditLogs: true }) - useEffect(() => { - if (userId) { - fetchUserDetails() - } - }, [userId]) - - useEffect(() => { - if (userData) { - form.setFieldsValue({ - username: userData.username || '', - name: userData.name || '', - firstName: userData.firstName || '', - lastName: userData.lastName || '', - email: userData.email || '' - }) - } - }, [userData, form]) - - const fetchUserDetails = async () => { - try { - setFetchLoading(true) - const response = await axios.get(`${config.backendUrl}/users/${userId}`, { - headers: { - Accept: 'application/json' - }, - withCredentials: true - }) - setUserData(response.data) - setError(null) - } catch (err) { - setError('Failed to fetch user details') - messageApi.error('Failed to fetch user details') - } finally { - setFetchLoading(false) - } - } - - const startEditing = () => { - updateCollapseState('info', true) - setIsEditing(true) - } - - const cancelEditing = () => { - // Reset form values to original data - if (userData) { - form.setFieldsValue({ - username: userData.username || '', - name: userData.name || '', - firstName: userData.firstName || '', - lastName: userData.lastName || '', - email: userData.email || '' - }) - } - setIsEditing(false) - } - - const updateInfo = async () => { - try { - const values = await form.validateFields() - setLoading(true) - - await axios.put(`${config.backendUrl}/users/${userId}`, values, { - headers: { - 'Content-Type': 'application/json' - }, - withCredentials: true - }) - - setUserData({ ...userData, ...values }) - setIsEditing(false) - messageApi.success('User information updated successfully') - } catch (err) { - if (err.errorFields) { - return - } - console.error('Failed to update user information:', err) - messageApi.error('Failed to update user information') - } finally { - fetchUserDetails() - setLoading(false) - } - } - - const actionItems = { - items: [ - { - label: 'Reload User', - key: 'reload', - icon: - } - ], - onClick: ({ key }) => { - if (key === 'reload') { - fetchUserDetails() - } - } - } - - const getViewDropdownItems = () => { - const sections = [ - { key: 'info', label: 'User Information' }, - { key: 'notes', label: 'Notes' }, - { key: 'auditLogs', label: 'Audit Logs' } - ] - - return ( - - - {sections.map((section) => ( - { - updateCollapseState(section.key, e.target.checked) - }} - > - {section.label} - - ))} - - - ) - } - - if (error) { - return ( - -

{error || 'User not found'}

- -
- ) - } - return ( - <> - {contextHolder} - - - - - - - - - - - - {isEditing ? ( - <> - + + - - - ) : (
- - updateCollapseState('info', keys.length > 0) - } - expandIcon={({ isActive }) => ( - - )} - className='no-h-padding-collapse no-t-padding-collapse' + } + active={collapseState.info} + onToggle={(expanded) => updateCollapseState('info', expanded)} + key='info' > - - - - User Information - - - } - key='1' - > -
- } - spinning={fetchLoading} - > - - - {userData?._id ? ( - - ) : ( - n/a - )} - + } + isEditing={isEditing} + type='user' + items={[ + { + name: '_id', + label: 'ID', + value: objectData?._id, + type: 'id', + objectType: 'user', + showCopy: true + }, + { + name: 'createdAt', + label: 'Created At', + value: objectData?.createdAt, + type: 'dateTime', + readOnly: true + }, + { + name: 'name', + label: 'Name', + value: objectData?.name, + required: true, + type: 'text' + }, + { + name: 'updatedAt', + label: 'Updated At', + value: objectData?.updatedAt, + type: 'dateTime', + readOnly: true + }, - - {userData?.createdAt ? ( - - ) : ( - n/a - )} - + { + name: 'firstName', + label: 'First Name', + value: objectData?.firstName, + type: 'text' + }, + { + name: 'username', + label: 'Username', + value: objectData?.username, + required: true, + type: 'text' + }, + { + name: 'lastName', + label: 'Last Name', + value: objectData?.lastName, + type: 'text' + }, + { + name: 'email', + label: 'Email', + value: objectData?.email, + type: 'email' + } + ]} + /> + - - {isEditing ? ( - - - - ) : userData?.name ? ( - {userData.name} - ) : ( - n/a - )} - - - - {userData?.updatedAt ? ( - - ) : ( - n/a - )} - - - - {isEditing ? ( - - - - ) : userData?.username ? ( - {userData.username} - ) : ( - n/a - )} - - - - {isEditing ? ( - - - - ) : userData?.firstName ? ( - {userData.firstName} - ) : ( - n/a - )} - - - - {isEditing ? ( - - - - ) : userData?.email ? ( - - {userData.email + ' '} - - - ) : ( - n/a - )} - - - {isEditing ? ( - - - - ) : userData?.lastName ? ( - {userData.lastName} - ) : ( - n/a - )} - - - -
- - - - - updateCollapseState('notes', keys.length > 0) - } - expandIcon={({ isActive }) => ( - - )} - className='no-h-padding-collapse' + } + active={collapseState.notes} + onToggle={(expanded) => updateCollapseState('notes', expanded)} + key='notes' > - - - - Notes - - - } - key='notes' - > - - - - - + + + + - - updateCollapseState('auditLogs', keys.length > 0) + } + active={collapseState.auditLogs} + onToggle={(expanded) => + updateCollapseState('auditLogs', expanded) } - expandIcon={({ isActive }) => ( - - )} - className='no-h-padding-collapse' + key='auditLogs' > - - - - Audit Logs - - - } - key='auditLogs' - > - - - + +
- )} -
- +
+ )} + ) } diff --git a/src/components/Dashboard/Management/Vendors.jsx b/src/components/Dashboard/Management/Vendors.jsx index 2c4fa61..4c99876 100644 --- a/src/components/Dashboard/Management/Vendors.jsx +++ b/src/components/Dashboard/Management/Vendors.jsx @@ -14,7 +14,7 @@ import { } from 'antd' import { ExportOutlined } from '@ant-design/icons' import { AuthContext } from '../context/AuthContext' -import IdText from '../common/IdText' +import IdDisplay from '../common/IdDisplay' import NewVendor from './Vendors/NewVendor' import CountryDisplay from '../common/CountryDisplay' import TimeDisplay from '../common/TimeDisplay' @@ -155,7 +155,7 @@ const Vendors = () => { dataIndex: '_id', key: 'id', width: 180, - render: (text) => , + render: (text) => , filterDropdown: ({ setSelectedKeys, selectedKeys, diff --git a/src/components/Dashboard/Management/Vendors/VendorInfo.jsx b/src/components/Dashboard/Management/Vendors/VendorInfo.jsx index 9868486..104ccb1 100644 --- a/src/components/Dashboard/Management/Vendors/VendorInfo.jsx +++ b/src/components/Dashboard/Management/Vendors/VendorInfo.jsx @@ -1,539 +1,216 @@ -import React, { useState, useEffect, useCallback } from 'react' +import React from 'react' import { useLocation } from 'react-router-dom' -import axios from 'axios' -import { - Descriptions, - Spin, - Space, - Button, - message, - Typography, - Flex, - Form, - Input, - Collapse, - Dropdown, - Popover, - Card, - Checkbox -} from 'antd' -import { - LoadingOutlined, - ExportOutlined, - CaretLeftOutlined -} from '@ant-design/icons' -import IdText from '../../common/IdText' -import CountrySelect from '../../common/CountrySelect' -import CountryDisplay from '../../common/CountryDisplay' -import TimeDisplay from '../../common/TimeDisplay' +import { Space, Button, Flex, Dropdown, Card } from 'antd' +import { LoadingOutlined } from '@ant-design/icons' +import loglevel from 'loglevel' +import config from '../../../../config' import ReloadIcon from '../../../Icons/ReloadIcon' -import EditIcon from '../../../Icons/EditIcon.jsx' -import XMarkIcon from '../../../Icons/XMarkIcon.jsx' -import CheckIcon from '../../../Icons/CheckIcon.jsx' import useCollapseState from '../../hooks/useCollapseState' import AuditLogTable from '../../common/AuditLogTable' import DashboardNotes from '../../common/DashboardNotes' +import InfoCollapse from '../../common/InfoCollapse' +import ObjectInfo from '../../common/ObjectInfo' +import ViewButton from '../../common/ViewButton' + import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx' import NoteIcon from '../../../Icons/NoteIcon.jsx' import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx' +import EditObjectForm from '../../common/EditObjectForm' +import EditButtons from '../../common/EditButtons' +import LockIndicator from '../Filaments/LockIndicator' -import config from '../../../../config.js' - -const { Title, Link, Text } = Typography +const log = loglevel.getLogger('VendorInfo') +log.setLevel(config.logLevel) const VendorInfo = () => { - const [vendorData, setVendorData] = useState(null) - const [loading, setLoading] = useState(false) - const [error, setError] = useState(null) const location = useLocation() - const [messageApi, contextHolder] = message.useMessage() const vendorId = new URLSearchParams(location.search).get('vendorId') - const [isEditing, setIsEditing] = useState(false) - const [form] = Form.useForm() - const [fetchLoading, setFetchLoading] = useState(true) const [collapseState, updateCollapseState] = useCollapseState('VendorInfo', { info: true, notes: true, auditLogs: true }) - useEffect(() => { - if (vendorId) { - fetchVendorDetails() - } - }, [vendorId, fetchVendorDetails]) - - useEffect(() => { - if (vendorData) { - form.setFieldsValue({ - name: vendorData.name || '', - website: vendorData.website || '', - contact: vendorData.contact || '', - country: vendorData.country || '', - phone: vendorData.phone || '', - email: vendorData.email || '' - }) - } - }, [vendorData, form]) - - const fetchVendorDetails = useCallback(async () => { - try { - setFetchLoading(true) - const response = await axios.get( - `${config.backendUrl}/vendors/${vendorId}`, - { - headers: { - Accept: 'application/json' - }, - withCredentials: true - } - ) - setVendorData(response.data) - setError(null) - } catch (err) { - setError('Failed to fetch vendor details') - messageApi.error('Failed to fetch vendor details') - } finally { - setFetchLoading(false) - } - }, [messageApi, vendorId]) - - const startEditing = () => { - updateCollapseState('info', true) - setIsEditing(true) - } - - const cancelEditing = () => { - // Reset form values to original data - if (vendorData) { - form.setFieldsValue({ - name: vendorData.name || '', - website: vendorData.website || '', - contact: vendorData.contact || '', - country: vendorData.country || '', - phone: vendorData.phone || '', - email: vendorData.email || '' - }) - } - setIsEditing(false) - } - - const updateInfo = async () => { - try { - const values = await form.validateFields() - setLoading(true) - - await axios.put(`${config.backendUrl}/vendors/${vendorId}`, values, { - headers: { - 'Content-Type': 'application/json' - }, - withCredentials: true - }) - - setVendorData({ ...vendorData, ...values }) - setIsEditing(false) - messageApi.success('Vendor information updated successfully') - } catch (err) { - if (err.errorFields) { - return - } - messageApi.error('Failed to update vendor information') - } finally { - fetchVendorDetails() - setLoading(false) - } - } - - const actionItems = { - items: [ - { - label: 'Reload Vendor', - key: 'reload', - icon: - } - ], - onClick: ({ key }) => { - if (key === 'reload') { - fetchVendorDetails() - } - } - } - - const getViewDropdownItems = () => { - const sections = [ - { key: 'info', label: 'Vendor Information' }, - { key: 'notes', label: 'Notes' }, - { key: 'auditLogs', label: 'Audit Logs' } - ] - - return ( - - - {sections.map((section) => ( - { - updateCollapseState(section.key, e.target.checked) - }} - > - {section.label} - - ))} - - - ) - } - - if (error) { - return ( - -

{error || 'Vendor not found'}

- -
- ) - } - return ( - <> - {contextHolder} - - - - - - - - - - - - {isEditing ? ( - <> - + + - - - ) : (
- - updateCollapseState('info', keys.length > 0) - } - expandIcon={({ isActive }) => ( - - )} - className='no-h-padding-collapse no-t-padding-collapse' + } + active={collapseState.info} + onToggle={(expanded) => updateCollapseState('info', expanded)} + key='info' > - - - - Vendor Information - - - } - key='1' - > -
- } - spinning={fetchLoading} - > - - - {vendorData?._id ? ( - - ) : ( - n/a - )} - - - {vendorData?.createdAt ? ( - - ) : ( - n/a - )} - + } + isEditing={isEditing} + items={[ + { + name: 'id', + label: 'ID', + value: objectData?._id, + type: 'id', + objectType: 'vendor', + showCopy: true + }, + { + name: 'createdAt', + label: 'Created At', + value: objectData?.createdAt, + type: 'dateTime', + readOnly: true + }, + { + name: 'name', + label: 'Name', + value: objectData?.name, + required: true, + type: 'text' + }, + { + name: 'updatedAt', + label: 'Updated At', + value: objectData?.updatedAt, + type: 'dateTime', + readOnly: true + }, + { + name: 'website', + label: 'Website', + value: objectData?.website, + type: 'url' + }, + { + name: 'country', + label: 'Country', + value: objectData?.country, + type: 'country' + }, + { + name: 'contact', + label: 'Contact', + value: objectData?.contact, + type: 'text' + }, + { + name: 'phone', + label: 'Phone', + value: objectData?.phone, + type: 'text' + }, + { + name: 'email', + label: 'Email', + value: objectData?.email, + type: 'email' + } + ]} + /> + - - {isEditing ? ( - - - - ) : vendorData?.name ? ( - {vendorData.name} - ) : ( - n/a - )} - - - - {vendorData?.updatedAt ? ( - - ) : ( - n/a - )} - - - - {isEditing ? ( - - - - ) : vendorData?.website ? ( - - {new URL(vendorData.website).hostname + ' '} - - - ) : ( - n/a - )} - - - - {isEditing ? ( - - - - ) : vendorData?.country ? ( - - ) : ( - n/a - )} - - - - {isEditing ? ( - - - - ) : vendorData?.contact ? ( - {vendorData.contact} - ) : ( - n/a - )} - - - - {isEditing ? ( - - - - ) : vendorData?.phone ? ( - {vendorData.phone} - ) : ( - n/a - )} - - - - {isEditing ? ( - - - - ) : vendorData?.email ? ( - - {vendorData.email + ' '} - - - ) : ( - n/a - )} - - - -
- - - - - updateCollapseState('notes', keys.length > 0) - } - expandIcon={({ isActive }) => ( - - )} - className='no-h-padding-collapse' + } + active={collapseState.notes} + onToggle={(expanded) => updateCollapseState('notes', expanded)} + key='notes' > - - - - Notes - - - } - key='notes' - > - - - - - + + + + - - updateCollapseState('auditLogs', keys.length > 0) + } + active={collapseState.auditLogs} + onToggle={(expanded) => + updateCollapseState('auditLogs', expanded) } - expandIcon={({ isActive }) => ( - - )} - className='no-h-padding-collapse' + key='auditLogs' > - - - - Audit Logs - - - } - key='auditLogs' - > - - - + +
- )} -
- +
+ )} + ) } diff --git a/src/components/Dashboard/Production/GCodeFiles.jsx b/src/components/Dashboard/Production/GCodeFiles.jsx index c6287c9..090a542 100644 --- a/src/components/Dashboard/Production/GCodeFiles.jsx +++ b/src/components/Dashboard/Production/GCodeFiles.jsx @@ -21,7 +21,7 @@ import { DownloadOutlined } from '@ant-design/icons' import { AuthContext } from '../context/AuthContext' import NewGCodeFile from './GCodeFiles/NewGCodeFile' -import IdText from '../common/IdText' +import IdDisplay from '../common/IdDisplay' import GCodeFileIcon from '../../Icons/GCodeFileIcon' import InfoCircleIcon from '../../Icons/InfoCircleIcon' import useColumnVisibility from '../hooks/useColumnVisibility' @@ -120,7 +120,9 @@ const GCodeFiles = () => { dataIndex: '_id', key: 'id', width: 180, - render: (text) => + render: (text) => ( + + ) }, { title: 'Filament', diff --git a/src/components/Dashboard/Production/GCodeFiles/GCodeFileInfo.jsx b/src/components/Dashboard/Production/GCodeFiles/GCodeFileInfo.jsx index 9af6e66..508c171 100644 --- a/src/components/Dashboard/Production/GCodeFiles/GCodeFileInfo.jsx +++ b/src/components/Dashboard/Production/GCodeFiles/GCodeFileInfo.jsx @@ -1,596 +1,295 @@ -import React, { useState, useEffect } from 'react' +import React from 'react' import { useLocation } from 'react-router-dom' -import axios from 'axios' -import { - Descriptions, - Spin, - Space, - Button, - message, - Badge, - Form, - Typography, - Flex, - Input, - Card, - Collapse, - Dropdown, - Popover, - Checkbox -} from 'antd' -import { LoadingOutlined, CaretLeftOutlined } from '@ant-design/icons' -import IdText from '../../common/IdText.jsx' -import { capitalizeFirstLetter } from '../../utils/Utils.js' -import FilamentSelect from '../../common/FilamentSelect' -import useCollapseState from '../../hooks/useCollapseState' -import FilamentIcon from '../../../Icons/FilamentIcon' -import TimeDisplay from '../../common/TimeDisplay.jsx' +import { Space, Button, Flex, Dropdown, Card, Typography } from 'antd' +import { LoadingOutlined } from '@ant-design/icons' import ReloadIcon from '../../../Icons/ReloadIcon' -import EditIcon from '../../../Icons/EditIcon.jsx' -import XMarkIcon from '../../../Icons/XMarkIcon.jsx' -import CheckIcon from '../../../Icons/CheckIcon.jsx' - -import config from '../../../../config.js' -import AuditLogTable from '../../common/AuditLogTable.jsx' -import DashboardNotes from '../../common/DashboardNotes.jsx' -import BinIcon from '../../../Icons/BinIcon.jsx' +import useCollapseState from '../../hooks/useCollapseState' +import AuditLogTable from '../../common/AuditLogTable' +import DashboardNotes from '../../common/DashboardNotes' +import InfoCollapse from '../../common/InfoCollapse' +import ObjectInfo from '../../common/ObjectInfo' +import ViewButton from '../../common/ViewButton' +import EditObjectForm from '../../common/EditObjectForm' +import EditButtons from '../../common/EditButtons' +import LockIndicator from '../../Management/Filaments/LockIndicator' import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx' -import GCodeFileIcon from '../../../Icons/GCodeFileIcon.jsx' import NoteIcon from '../../../Icons/NoteIcon.jsx' import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx' +import GCodeFileIcon from '../../../Icons/GCodeFileIcon.jsx' -const { Title, Text } = Typography +const { Text } = Typography const GCodeFileInfo = () => { - const [gcodeFileData, setGCodeFileData] = useState(null) - const [editLoading, setLoading] = useState(false) - const [error, setError] = useState(null) const location = useLocation() - const [messageApi, contextHolder] = message.useMessage() const gcodeFileId = new URLSearchParams(location.search).get('gcodeFileId') - const [isEditing, setIsEditing] = useState(false) - const [form] = Form.useForm() - const [fetchLoading, setFetchLoading] = useState(true) const [collapseState, updateCollapseState] = useCollapseState( 'GCodeFileInfo', { info: true, - preview: true + preview: true, + notes: true, + auditLogs: true } ) - useEffect(() => { - if (gcodeFileId) { - fetchGCodeFileDetails() - } - }, [gcodeFileId]) - - useEffect(() => { - if (gcodeFileData) { - form.setFieldsValue({ - name: gcodeFileData.name || '', - filament: gcodeFileData.filament || { id: null, name: '' } - }) - } - }, [gcodeFileData, form]) - - const fetchGCodeFileDetails = async () => { - try { - setFetchLoading(true) - const response = await axios.get( - `${config.backendUrl}/gcodefiles/${gcodeFileId}`, - { - headers: { - Accept: 'application/json' - }, - withCredentials: true - } - ) - setGCodeFileData(response.data) - setError(null) - } catch (err) { - setError('Failed to fetch GCodeFile details') - messageApi.error('Failed to fetch GCodeFile details') - } finally { - setFetchLoading(false) - } - } - - const startEditing = () => { - setIsEditing(true) - updateCollapseState('info', true) - } - - const cancelEditing = () => { - form.setFieldsValue({ - name: gcodeFileData?.name || '', - filament: gcodeFileData?.filament || { id: null, name: '' } - }) - setIsEditing(false) - } - - const updateGCodeFileInfo = async () => { - try { - const values = await form.validateFields() - setLoading(true) - - await axios.put( - `${config.backendUrl}/gcodefiles/${gcodeFileId}`, - values, - { - headers: { - 'Content-Type': 'application/json' - }, - withCredentials: true - } - ) - - setGCodeFileData({ ...gcodeFileData, ...values }) - setIsEditing(false) - messageApi.success('GCode File information updated successfully') - } catch (err) { - if (err.errorFields) { - return - } - console.error('Failed to update gcode file information:', err) - messageApi.error('Failed to update gcode file information') - } finally { - fetchGCodeFileDetails() - setLoading(false) - } - } - - const actionItems = { - items: [ - { - label: 'Edit GCode File', - key: 'edit', - icon: - }, - { - label: 'Delete GCode File', - key: 'delete', - icon: , - danger: true - }, - { type: 'divider' }, - { - label: 'Reload GCode File', - key: 'reload', - icon: - } - ], - onClick: ({ key }) => { - if (key === 'reload') { - fetchGCodeFileDetails() - } - } - } - - const getViewDropdownItems = () => { - const sections = [ - { key: 'info', label: 'GCode File Information' }, - { key: 'preview', label: 'GCode File Preview' }, - { key: 'notes', label: 'Notes' }, - { key: 'auditLogs', label: 'Audit Logs' } - ] - - return ( - - - {sections.map((section) => ( - { - updateCollapseState(section.key, e.target.checked) - }} - > - {section.label} - - ))} - - - ) - } - return ( - <> - {contextHolder} - - - - - - - - - - - - {isEditing ? ( - <> - + + - - - ) : (
- - updateCollapseState('info', keys.length > 0) - } - expandIcon={({ isActive }) => ( - - )} - className='no-h-padding-collapse no-t-padding-collapse' + } + active={collapseState.info} + onToggle={(expanded) => updateCollapseState('info', expanded)} + key='info' > - - - - GCode File Information - - - } - key='info' - > -
- } - > - - - {gcodeFileData?._id ? ( - - ) : ( - n/a - )} - - - {gcodeFileData?.createdAt ? ( - - ) : ( - n/a - )} - + } + isEditing={isEditing} + items={[ + { + name: '_id', + label: 'ID', + type: 'id', + objectType: 'gcodefile', + value: objectData?._id, + showCopy: true + }, + { + name: 'createdAt', + label: 'Created At', + type: 'dateTime', + value: objectData?.createdAt, + readOnly: true + }, + { + name: 'name', + label: 'Name', + type: 'text', + value: objectData?.name, + required: true + }, + { + name: 'updatedAt', + label: 'Updated At', + type: 'dateTime', + value: objectData?.updatedAt, + readOnly: true + }, + { + name: 'filament', + label: 'Filament', + type: 'object', + value: objectData?.filament, + objectType: 'filament', + required: true + }, + { + name: 'cost', + label: 'Cost', + type: 'currency', + value: objectData?.cost, + readOnly: true + }, + { + name: [ + 'gcodeFileInfo', + 'estimatedPrintingTimeNormalMode' + ], + label: 'Est Print Time', + value: + objectData?.gcodeFileInfo + ?.estimatedPrintingTimeNormalMode, + type: 'text', + readOnly: true + }, + { + name: ['gcodeFileInfo', 'sparseInfillDensity'], + label: 'Infill Density', + value: objectData?.gcodeFileInfo?.sparseInfillDensity, + type: 'number', + readOnly: true + }, + { + name: ['gcodeFileInfo', 'sparseInfillPattern'], + label: 'Infill Pattern', + value: objectData?.gcodeFileInfo?.sparseInfillPattern, + type: 'text', + readOnly: true + }, + { + name: ['gcodeFileInfo', 'filamentUsedMm'], + label: 'Filament Used (mm)', + value: objectData?.gcodeFileInfo?.filamentUsedMm, + type: 'mm', + readOnly: true + }, + { + name: ['gcodeFileInfo', 'filamentUsedG'], + label: 'Filament Used (g)', + value: objectData?.gcodeFileInfo?.filamentUsedG, + type: 'weight', + readOnly: true + }, + { + name: ['gcodeFileInfo', 'nozzleTemperature'], + label: 'Hotend Temperature', + value: objectData?.gcodeFileInfo?.nozzleTemperature, + type: 'number', + readOnly: true + }, + { + name: ['gcodeFileInfo', 'hotPlateTemp'], + label: 'Bed Temperature', + value: objectData?.gcodeFileInfo?.hotPlateTemp, + type: 'number', + readOnly: true + }, + { + name: ['gcodeFileInfo', 'filamentSettingsId'], + label: 'Filament Profile', + value: objectData?.gcodeFileInfo?.filamentSettingsId, + type: 'text', + readOnly: true + }, + { + name: ['gcodeFileInfo', 'printSettingsId'], + label: 'Print Profile', + value: objectData?.gcodeFileInfo?.printSettingsId, + type: 'text', + readOnly: true + } + ]} + objectData={objectData} + type='gcodefile' + /> + - - {isEditing ? ( - - - - ) : gcodeFileData?.name ? ( - {gcodeFileData.name} - ) : ( - n/a - )} - - - - {gcodeFileData?.updatedAt ? ( - - ) : ( - n/a - )} - - - {isEditing ? ( - - - - ) : gcodeFileData?.filament ? ( - - - - - ) : ( - n/a - )} - - - {gcodeFileData?.filament ? ( - - ) : ( - n/a - )} - - - {gcodeFileData?.gcodeFileInfo - ?.estimatedPrintingTimeNormalMode ? ( - - { - gcodeFileData.gcodeFileInfo - .estimatedPrintingTimeNormalMode - } - - ) : ( - n/a - )} - - - {gcodeFileData?.cost ? ( - {'£' + gcodeFileData.cost.toFixed(2)} - ) : ( - n/a - )} - - - {gcodeFileData?.gcodeFileInfo?.sparseInfillDensity ? ( - - {gcodeFileData.gcodeFileInfo.sparseInfillDensity} - - ) : ( - n/a - )} - - - {gcodeFileData?.gcodeFileInfo?.sparseInfillPattern ? ( - - {capitalizeFirstLetter( - gcodeFileData.gcodeFileInfo.sparseInfillPattern - )} - - ) : ( - n/a - )} - - - {gcodeFileData?.gcodeFileInfo?.filamentUsedMm ? ( - - {gcodeFileData.gcodeFileInfo.filamentUsedMm}mm - - ) : ( - n/a - )} - - - {gcodeFileData?.gcodeFileInfo?.filamentUsedG ? ( - - {gcodeFileData.gcodeFileInfo.filamentUsedG}g - - ) : ( - n/a - )} - - - {gcodeFileData?.gcodeFileInfo?.nozzleTemperature ? ( - - {gcodeFileData.gcodeFileInfo.nozzleTemperature}° - - ) : ( - n/a - )} - - - {gcodeFileData?.gcodeFileInfo?.hotPlateTemp ? ( - - {gcodeFileData.gcodeFileInfo.hotPlateTemp}° - - ) : ( - n/a - )} - - - {gcodeFileData?.gcodeFileInfo?.filamentSettingsId ? ( - - {gcodeFileData.gcodeFileInfo.filamentSettingsId.replaceAll( - '"', - '' - )} - - ) : ( - n/a - )} - - - {gcodeFileData?.gcodeFileInfo?.printSettingsId ? ( - - {gcodeFileData.gcodeFileInfo.printSettingsId.replaceAll( - '"', - '' - )} - - ) : ( - n/a - )} - - - -
- - - - - updateCollapseState('preview', keys.length > 0) + } + active={collapseState.preview} + onToggle={(expanded) => + updateCollapseState('preview', expanded) } - expandIcon={({ isActive }) => ( - - )} - className='no-h-padding-collapse' + key='preview' > - - - - GCode File Preview - - - } - key='preview' - > - }> - - {gcodeFileData?.gcodeFileInfo?.thumbnail ? ( - GCodeFile - ) : ( - n/a - )} - - - - + + {objectData?.gcodeFileInfo?.thumbnail ? ( + GCodeFile + ) : ( + n/a + )} + + - - updateCollapseState('notes', keys.length > 0) - } - expandIcon={({ isActive }) => ( - - )} - className='no-h-padding-collapse' + } + active={collapseState.notes} + onToggle={(expanded) => updateCollapseState('notes', expanded)} + key='notes' > - - - - Notes - - - } - key='notes' - > - - - - - + + + + - - updateCollapseState('auditLogs', keys.length > 0) + } + active={collapseState.auditLogs} + onToggle={(expanded) => + updateCollapseState('auditLogs', expanded) } - expandIcon={({ isActive }) => ( - - )} - className='no-h-padding-collapse' + key='auditLogs' > - - - - Audit Log - - - } - key='auditLogs' - > - - - + +
- )} -
- +
+ )} + ) } diff --git a/src/components/Dashboard/Production/GCodeFiles/NewGCodeFile.jsx b/src/components/Dashboard/Production/GCodeFiles/NewGCodeFile.jsx index 5474888..9c0ab19 100644 --- a/src/components/Dashboard/Production/GCodeFiles/NewGCodeFile.jsx +++ b/src/components/Dashboard/Production/GCodeFiles/NewGCodeFile.jsx @@ -218,7 +218,6 @@ const NewGCodeFile = ({ onOk, reset }) => { newGCodeFileFormValues?.gcodeFileInfo?.filamentUsedG if (filamentCost && gcodeFilamentUsed) { const cost = (filamentCost / 1000) * gcodeFilamentUsed - console.log('Setting cost') setNewGCodeFileFormValues((prev) => ({ ...prev, cost: cost.toFixed(2) })) newGCodeFileForm.setFieldValue('cost', cost.toFixed(2)) } @@ -304,8 +303,6 @@ const NewGCodeFile = ({ onOk, reset }) => { gcodeFileInfo: parsedConfig }) - console.log(parsedConfig) - // Update filter settings if filament info is available if (parsedConfig.filament_type && parsedConfig.filament_diameter) { setFilamentSelectFilter({ @@ -525,7 +522,6 @@ const NewGCodeFile = ({ onOk, reset }) => { onClick={() => { setCurrentStep(currentStep + 1) setNextEnabled(false) - console.log(newGCodeFileFormValues) }} > Next diff --git a/src/components/Dashboard/Production/Jobs.jsx b/src/components/Dashboard/Production/Jobs.jsx index e8ca155..5254c3e 100644 --- a/src/components/Dashboard/Production/Jobs.jsx +++ b/src/components/Dashboard/Production/Jobs.jsx @@ -22,7 +22,7 @@ import NewJob from './Jobs/NewJob.jsx' import JobState from '../common/JobState.jsx' import SubJobCounter from '../common/SubJobCounter.jsx' import TimeDisplay from '../common/TimeDisplay.jsx' -import IdText from '../common/IdText.jsx' +import IdDisplay from '../common/IdDisplay.jsx' import useColumnVisibility from '../hooks/useColumnVisibility.js' import JobIcon from '../../Icons/JobIcon.jsx' import InfoCircleIcon from '../../Icons/InfoCircleIcon.jsx' @@ -126,7 +126,7 @@ const Jobs = () => { dataIndex: 'id', key: 'id', width: 180, - render: (text) => , + render: (text) => , filterDropdown: ({ setSelectedKeys, selectedKeys, diff --git a/src/components/Dashboard/Production/Jobs/JobInfo.jsx b/src/components/Dashboard/Production/Jobs/JobInfo.jsx index 0aed559..1234921 100644 --- a/src/components/Dashboard/Production/Jobs/JobInfo.jsx +++ b/src/components/Dashboard/Production/Jobs/JobInfo.jsx @@ -1,48 +1,26 @@ -import React, { useState, useEffect, useContext } from 'react' +import React from 'react' import { useLocation } from 'react-router-dom' -import axios from 'axios' -import { - Descriptions, - Spin, - Space, - Button, - message, - Progress, - Typography, - Collapse, - Flex, - Dropdown, - Popover, - Checkbox, - Card -} from 'antd' -import { LoadingOutlined, CaretLeftOutlined } from '@ant-design/icons' -import TimeDisplay from '../../common/TimeDisplay' -import JobState from '../../common/JobState' -import IdText from '../../common/IdText' -import SubJobsTree from '../../common/SubJobsTree' -import { PrintServerContext } from '../../context/PrintServerContext' -import GCodeFileIcon from '../../../Icons/GCodeFileIcon' -import ReloadIcon from '../../../Icons/ReloadIcon' +import { Space, Button, Flex, Dropdown, Card } from 'antd' +import { LoadingOutlined } from '@ant-design/icons' import useCollapseState from '../../hooks/useCollapseState' -import config from '../../../../config' import AuditLogTable from '../../common/AuditLogTable' import DashboardNotes from '../../common/DashboardNotes' +import InfoCollapse from '../../common/InfoCollapse' +import ObjectInfo from '../../common/ObjectInfo' +import ViewButton from '../../common/ViewButton' +import EditObjectForm from '../../common/EditObjectForm' +import EditButtons from '../../common/EditButtons' +import LockIndicator from '../../Management/Filaments/LockIndicator' +import SubJobsTree from '../../common/SubJobsTree' import InfoCircleIcon from '../../../Icons/InfoCircleIcon' import JobIcon from '../../../Icons/JobIcon' import AuditLogIcon from '../../../Icons/AuditLogIcon' import NoteIcon from '../../../Icons/NoteIcon' - -const { Title, Text } = Typography +import GCodeFileIcon from '../../../Icons/GCodeFileIcon' const JobInfo = () => { - const [jobData, setJobData] = useState(null) - const [fetchLoading, setFetchLoading] = useState(true) - const [error, setError] = useState(null) const location = useLocation() - const [messageApi] = message.useMessage() const jobId = new URLSearchParams(location.search).get('jobId') - const { printServer } = useContext(PrintServerContext) const [collapseState, updateCollapseState] = useCollapseState('JobInfo', { info: true, subJobs: true, @@ -50,352 +28,205 @@ const JobInfo = () => { auditLogs: true }) - useEffect(() => { - if (jobId) { - fetchJobDetails() - } - }, [jobId]) - - useEffect(() => { - if (printServer && jobId) { - printServer.on('notify_job_update', (updateData) => { - if (updateData._id === jobId) { - setJobData((prevData) => { - if (!prevData) return prevData - return { - ...prevData, - state: updateData.state, - ...updateData - } - }) - } - }) - } - - return () => { - if (printServer) { - printServer.off('notify_job_update') - } - } - }, [printServer, jobId]) - - const fetchJobDetails = async () => { - try { - setFetchLoading(true) - const response = await axios.get(`${config.backendUrl}/jobs/${jobId}`, { - headers: { - Accept: 'application/json' - }, - withCredentials: true // Important for including cookies - }) - setJobData(response.data) - setError(null) - } catch (err) { - setError('Failed to fetch print job details') - messageApi.error('Failed to fetch print job details') - } finally { - setFetchLoading(false) - } - } - - const getViewDropdownItems = () => { - const sections = [ - { key: 'info', label: 'Job Information' }, - { key: 'subJobs', label: 'Sub Jobs' }, - { key: 'notes', label: 'Notes' }, - { key: 'auditLogs', label: 'Audit Logs' } - ] - - return ( - - - {sections.map((section) => ( - { - updateCollapseState(section.key, e.target.checked) - }} - > - {section.label} - - ))} - - - ) - } - - const actionItems = { - items: [ - { - label: 'Reload Job', - key: 'reload', - icon: - } - ], - onClick: ({ key }) => { - if (key === 'edit') { - // TODO: Implement edit functionality - messageApi.info('Edit functionality coming soon') - } else if (key === 'reload') { - fetchJobDetails() - } - } - } - return ( - <> - - - - - - - - - - - + + {({ + loading, + isEditing, + startEditing, + cancelEditing, + handleUpdate, + formValid, + objectData, + editLoading, + lock, + fetchObject + }) => ( + + + + + + } + ], + onClick: ({ key }) => { + if (key === 'reload') { + fetchObject() + } + } + }} + > + + + + + + + + + + - {error ? ( - -

{error || 'Print job not found'}

- -
- ) : (
- - - updateCollapseState('info', keys.length > 0) - } - expandIcon={({ isActive }) => ( - - )} - className='no-h-padding-collapse no-t-padding-collapse' + + } + active={collapseState.info} + onToggle={(expanded) => updateCollapseState('info', expanded)} + key='info' > - - - - Job Information - - - } - key='info' - > - }> - - - {jobData?._id ? ( - - ) : ( - n/a - )} - - - {jobData?.state ? ( - - ) : ( - n/a - )} - - - {jobData?.gcodeFile ? ( - - - - {jobData.gcodeFile.name || 'Not specified'} - - - ) : ( - n/a - )} - - - {jobData?.gcodeFile?._id ? ( - - ) : ( - n/a - )} - - - {jobData?.quantity ? ( - {jobData.quantity} - ) : ( - n/a - )} - - - {jobData?.createdAt ? ( - - ) : ( - n/a - )} - - - {jobData?.startedAt ? ( - - ) : ( - n/a - )} - - {jobData?.state?.type === 'printing' && ( - - - - )} - - {jobData?.printers ? ( - - {jobData.printers.length} printers assigned - - ) : ( - n/a - )} - - - - - + } + isEditing={isEditing} + type='job' + items={[ + { + name: '_id', + label: 'ID', + value: objectData?._id, + type: 'id', + objectType: 'job', + showCopy: true + }, + { + name: 'state', + label: 'Status', + value: objectData, + type: 'state', + objectType: 'job', + showStatus: true, + showProgress: true, + showId: false, + showQuantity: false, + readOnly: true + }, + { + name: 'gcodeFile', + label: 'GCode File', + value: objectData?.gcodeFile, + type: 'object', + objectType: 'gcodeFile', + readOnly: true + }, + { + name: 'gcodeFileId', + label: 'GCode File ID', + value: objectData?.gcodeFile?._id, + type: 'id', + objectType: 'gcodefile', + showHyperlink: true + }, + { + name: 'quantity', + label: 'Quantity', + value: objectData?.quantity, + type: 'number', + readOnly: true + }, + { + name: 'createdAt', + label: 'Created At', + value: objectData?.createdAt, + type: 'dateTime', + readOnly: true + }, + { + name: 'startedAt', + label: 'Started At', + value: objectData?.startedAt, + type: 'dateTime', + readOnly: true + }, + { + name: 'assignedPrinters', + label: 'Assigned Printers', + value: objectData?.printers?.length, + type: 'number', + readOnly: true + } + ]} + /> + - - updateCollapseState('subJobs', keys.length > 0) + } + active={collapseState.subJobs} + onToggle={(expanded) => + updateCollapseState('subJobs', expanded) } - expandIcon={({ isActive }) => ( - - )} - className='no-h-padding-collapse' + key='subJobs' > - - - - Sub Job Information - - - } - key='2' - > - - - + + - - updateCollapseState('notes', keys.length > 0) - } - expandIcon={({ isActive }) => ( - - )} - className='no-h-padding-collapse' + } + active={collapseState.notes} + onToggle={(expanded) => updateCollapseState('notes', expanded)} + key='notes' > - - - - Notes - - - } - key='notes' - > - - - - - + + + + - - updateCollapseState('auditLogs', keys.length > 0) + } + active={collapseState.auditLogs} + onToggle={(expanded) => + updateCollapseState('auditLogs', expanded) } - expandIcon={({ isActive }) => ( - - )} - className='no-h-padding-collapse' + key='auditLogs' > - - - - Audit Logs - - - } - key='auditLogs' - > - - - + +
- )} -
- +
+ )} + ) } diff --git a/src/components/Dashboard/Production/Printers.jsx b/src/components/Dashboard/Production/Printers.jsx index fa011ee..674197a 100644 --- a/src/components/Dashboard/Production/Printers.jsx +++ b/src/components/Dashboard/Production/Printers.jsx @@ -18,7 +18,7 @@ import { import { AuthContext } from '../context/AuthContext' import PrinterState from '../common/PrinterState' import NewPrinter from './Printers/NewPrinter' -import IdText from '../common/IdText' +import IdDisplay from '../common/IdDisplay' import PrinterIcon from '../../Icons/PrinterIcon' import InfoCircleIcon from '../../Icons/InfoCircleIcon' import ControlIcon from '../../Icons/ControlIcon' @@ -79,7 +79,7 @@ const Printers = () => { dataIndex: '_id', key: 'id', width: 180, - render: (text) => + render: (text) => }, { title: 'State', @@ -89,7 +89,7 @@ const Printers = () => { return ( ) diff --git a/src/components/Dashboard/Production/Printers/ControlPrinter.jsx b/src/components/Dashboard/Production/Printers/ControlPrinter.jsx index 8f8c689..ac82778 100644 --- a/src/components/Dashboard/Production/Printers/ControlPrinter.jsx +++ b/src/components/Dashboard/Production/Printers/ControlPrinter.jsx @@ -31,7 +31,7 @@ import PrinterMiscPanel from '../../common/PrinterMiscPanel' import PrinterState from '../../common/PrinterState' import { AuthContext } from '../../context/AuthContext' import PrinterSubJobsTree from '../../common/PrinterJobsTree' -import IdText from '../../common/IdText' +import IdDisplay from '../../common/IdDisplay' import FilamentIcon from '../../../Icons/FilamentIcon' import FilamentStockIcon from '../../../Icons/FilamentStockIcon' @@ -179,7 +179,6 @@ const ControlPrinter = () => { } return () => { if (printServer && initialized) { - console.log('Deregistering') printServer.off('notify_printer_update') printServer.off('notify_filamentstock_update') } @@ -187,7 +186,6 @@ const ControlPrinter = () => { }, [printServer, initialized, printerId]) function handleEmergencyStop() { - console.log('Emergency stop button clicked') printServer.emit('printer.emergency_stop', { printerId }) } @@ -438,7 +436,7 @@ const ControlPrinter = () => { ) : ( @@ -548,7 +546,7 @@ const ControlPrinter = () => { {printerData?._id ? ( - { {printerData?.currentJob?.gcodeFile ? ( - { {printerData?.currentJob?.id ? ( - { {printerData?.currentSubJob?.id ? ( - { {printerData?.currentFilamentStock?._id ? ( - { {printerData?.currentFilamentStock?.filament ? ( - { - const [printerData, setPrinterData] = useState(null) - const [fetchLoading, setFetchLoading] = useState(true) - const [editLoading, setEditLoading] = useState(false) - const [error, setError] = useState(null) const location = useLocation() const printerId = new URLSearchParams(location.search).get('printerId') - const [messageApi, contextHolder] = message.useMessage() - const [isEditing, setIsEditing] = useState(false) - const [form] = Form.useForm() const [collapseState, updateCollapseState] = useCollapseState('PrinterInfo', { info: true, jobs: true, + notes: true, auditLogs: true }) - useEffect(() => { - if (printerId) { - fetchPrinterDetails() - } - }, [printerId]) - - useEffect(() => { - if (printerData) { - form.setFieldsValue({ - name: printerData.name || '', - vendor: printerData.vendor || { id: null, name: '' }, - moonraker: { - host: printerData.moonraker?.host || '', - port: printerData.moonraker?.port || null, - protocol: printerData.moonraker?.protocol || 'ws', - apiKey: printerData.moonraker?.apiKey || '' - }, - tags: printerData.tags || [] - }) - } - }, [printerData, form]) - - const fetchPrinterDetails = async () => { - try { - setFetchLoading(true) - const response = await axios.get( - `${config.backendUrl}/printers/${printerId}`, - { - headers: { - Accept: 'application/json' - }, - withCredentials: true - } - ) - setPrinterData(response.data) - setError(null) - } catch (err) { - setError('Failed to fetch printer details') - messageApi.error('Failed to fetch printer details') - } finally { - setFetchLoading(false) - } - } - - const startEditing = () => { - updateCollapseState('info', true) - setIsEditing(true) - } - - const cancelEditing = () => { - // Reset form values to original data - if (printerData) { - form.setFieldsValue({ - name: printerData.name || '', - vendor: printerData.vendor || { id: null, name: '' }, - moonraker: { - host: printerData.moonraker?.host || '', - port: printerData.moonraker?.port || null, - protocol: printerData.moonraker?.protocol || 'ws', - apiKey: printerData.moonraker?.apiKey || '' - }, - tags: printerData.tags || [] - }) - } - setIsEditing(false) - } - - const updatePrinterInfo = async () => { - try { - const values = await form.validateFields() - setEditLoading(true) - - await axios.put( - `${config.backendUrl}/printers/${printerId}`, - { - name: values.name, - vendor: values.vendor, - moonraker: { - host: values.moonraker.host, - port: values.moonraker.port, - protocol: values.moonraker.protocol, - apiKey: values.moonraker.apiKey - }, - tags: values.tags - }, - { - headers: { - 'Content-Type': 'application/json' - }, - withCredentials: true - } - ) - - // Update the local state with the new values - setPrinterData({ ...printerData, ...values }) - setIsEditing(false) - messageApi.success('Printer information updated successfully') - } catch (err) { - if (err.errorFields) { - // This is a form validation error - return - } - console.error('Failed to update printer information:', err) - messageApi.error('Failed to update printer information') - } finally { - setEditLoading(false) - } - } - - const handleTagClose = (removedTag) => { - const newTags = printerData.tags.filter((tag) => tag !== removedTag) - setPrinterData((prev) => ({ ...prev, tags: newTags })) - } - - const handleTagAdd = () => { - const input = form.getFieldValue('newTag') - if (input) { - const newTag = input.trim() - if (newTag && !printerData.tags.includes(newTag)) { - setPrinterData((prev) => ({ ...prev, tags: [...prev.tags, newTag] })) - form.setFieldValue('newTag', '') - } - } - } - - const actionItems = { - items: [ - { - label: 'Reload Printer', - key: 'reload', - icon: - } - ], - onClick: ({ key }) => { - if (key === 'reload') { - fetchPrinterDetails() - } - } - } - - const getViewDropdownItems = () => { - const sections = [ - { key: 'info', label: 'Printer Information' }, - { key: 'jobs', label: 'Printer Jobs' }, - { key: 'notes', label: 'Notes' }, - { key: 'auditLogs', label: 'Audit Logs' } - ] - - return ( - - - {sections.map((section) => ( - { - updateCollapseState(section.key, e.target.checked) - }} - > - {section.label} - - ))} - - - ) - } - return ( - <> - {contextHolder} - - - - - - - - - - - - {isEditing ? ( - <> - + + - - - ) : (
- - updateCollapseState('info', keys.length > 0) - } - expandIcon={({ isActive }) => ( - - )} - className='no-h-padding-collapse no-t-padding-collapse' + } + active={collapseState.info} + onToggle={(expanded) => updateCollapseState('info', expanded)} + key='info' > - - - - Printer Information - - - } - key='info' - > -
- } - > - - {/* Read-only fields */} - - {printerData?._id ? ( - - ) : ( - n/a - )} - - - {printerData?.connectedAt ? ( - - ) : ( - n/a - )} - + } + isEditing={isEditing} + type='printer' + items={[ + { + name: '_id', + label: 'ID', + value: objectData?._id, + type: 'id', + objectType: 'printer', + showCopy: true + }, + { + name: 'connectedAt', + label: 'Connected At', + value: objectData?.connectedAt, + type: 'dateTime', + readOnly: true + }, + { + name: 'name', + label: 'Name', + value: objectData?.name, + required: true, + type: 'text' + }, + { + name: 'state', + label: 'Status', + value: objectData, + type: 'state', + objectType: 'printer', + showName: false, + readOnly: true + }, + { + name: 'vendor', + label: 'Vendor', + value: objectData?.vendor, + type: 'object', + objectType: 'vendor', + required: true + }, + { + name: ['moonraker', 'host'], + label: 'Host', + value: objectData?.moonraker?.host, + type: 'text', + required: true + }, + { + name: 'vendorId', + label: 'Vendor ID', + value: objectData?.vendor?.id, + type: 'id', + objectType: 'vendor', + showHyperlink: true, + readOnly: true + }, - {/* Editable fields */} - - {isEditing ? ( - - - - ) : printerData?.name ? ( - {printerData.name} - ) : ( - n/a - )} - + { + name: ['moonraker', 'port'], + label: 'Port', + value: objectData?.moonraker?.port, + type: 'number', + required: true + }, + { + name: ['moonraker', 'apiKey'], + label: 'API Key', + value: objectData?.moonraker?.apiKey, + type: 'secret', + reveal: true, + required: false + }, + { + name: ['moonraker', 'protocol'], + label: 'Protocol', + value: objectData?.moonraker?.protocol, + type: 'wsprotocol', + required: true + }, - - {isEditing ? ( - - - - ) : printerData?.moonraker?.host ? ( - {printerData.moonraker.host} - ) : ( - n/a - )} - + { + name: 'tags', + label: 'Tags', + value: objectData?.tags, + type: 'tags', + required: false + }, + { + name: 'firmware', + label: 'Firmware Version', + value: objectData?.firmware, + type: 'text', + required: false, + readOnly: true + } + ]} + /> + - - {isEditing ? ( - - - - ) : printerData?.vendor?.name ? ( - - - {printerData?.vendor?.name || 'n/a'} - - ) : ( - n/a - )} - - - - {printerData?.vendor ? ( - - ) : ( - n/a - )} - - - - {isEditing ? ( - - - - ) : printerData?.moonraker?.port ? ( - {printerData.moonraker.port} - ) : ( - n/a - )} - - - - {isEditing ? ( - - - -
- )} -
- +
+ )} + ) } diff --git a/src/components/Dashboard/Production/ProductionOverview.jsx b/src/components/Dashboard/Production/ProductionOverview.jsx index 4c32241..807d243 100644 --- a/src/components/Dashboard/Production/ProductionOverview.jsx +++ b/src/components/Dashboard/Production/ProductionOverview.jsx @@ -61,7 +61,6 @@ const ProductionOverview = () => { await fetchPrinterStats() await fetchJobstats() await fetchChartData() - console.log(stats) }, []) const fetchPrinterStats = async () => { @@ -74,7 +73,6 @@ const ProductionOverview = () => { withCredentials: true }) const printStats = response.data - console.log(printStats) setStats((prev) => ({ ...prev, printers: printStats })) setError(null) } catch (err) { diff --git a/src/components/Dashboard/common/AuditLogTable.jsx b/src/components/Dashboard/common/AuditLogTable.jsx index a486286..d8f670e 100644 --- a/src/components/Dashboard/common/AuditLogTable.jsx +++ b/src/components/Dashboard/common/AuditLogTable.jsx @@ -1,7 +1,7 @@ import React, { forwardRef, useState } from 'react' import { Typography, Space, Descriptions, Badge, Table } from 'antd' import PropTypes from 'prop-types' -import IdText from './IdText' +import IdDisplay from './IdDisplay' import { AuditOutlined, LoadingOutlined } from '@ant-design/icons' import TimeDisplay from '../common/TimeDisplay' import BoolDisplay from './BoolDisplay' @@ -51,7 +51,7 @@ const formatValue = (value, propertyName) => { if (isObjectId(value)) { return ( - , + render: (text) => ( + + ), sorter: (a, b) => a._id.localeCompare(b._id) } ] @@ -110,7 +112,7 @@ const AuditLogTable = forwardRef( key: 'owner', width: 180, render: (record) => ( - ( - { + // Determine initial enabled state based on value + const [colorEnabled, setColorEnabled] = useState(!!value) + + useEffect(() => { + setColorEnabled(!!value) + }, [value]) + + const handleCheckboxChange = (e) => { + const checked = e.target.checked + setColorEnabled(checked) + if (!checked) { + onChange(null) + } else if (checked && !value) { + onChange('#000000') + } + } + + const handleColorChange = (color) => { + onChange('#' + color.toHex()) + } + + return ( + + + {!required && ( + + )} + + ) +} + +ColorSelector.propTypes = { + value: PropTypes.string, + onChange: PropTypes.func.isRequired, + disabled: PropTypes.bool, + required: PropTypes.bool +} + +export default ColorSelector diff --git a/src/components/Dashboard/common/CopyButton.jsx b/src/components/Dashboard/common/CopyButton.jsx new file mode 100644 index 0000000..d8e745f --- /dev/null +++ b/src/components/Dashboard/common/CopyButton.jsx @@ -0,0 +1,73 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Button, Tooltip, message } from 'antd' +import CopyIcon from '../../Icons/CopyIcon' + +const CopyButton = ({ + text, + style = {}, + iconStyle = {}, + tooltip = 'Copy', + size = 'small' +}) => { + const [messageApi, contextHolder] = message.useMessage() + + const doCopy = (copyText) => { + if (navigator && navigator.clipboard && navigator.clipboard.writeText) { + navigator.clipboard + .writeText(copyText) + .then(() => { + messageApi.success('Copied to clipboard') + }) + .catch(() => { + messageApi.error('Failed to copy') + }) + } else if ( + document.queryCommandSupported && + document.queryCommandSupported('copy') + ) { + // Legacy fallback + const textarea = document.createElement('textarea') + textarea.value = copyText + textarea.setAttribute('readonly', '') + textarea.style.position = 'absolute' + textarea.style.left = '-9999px' + document.body.appendChild(textarea) + textarea.select() + try { + document.execCommand('copy') + messageApi.success('Copied to clipboard') + } catch (err) { + messageApi.error('Failed to copy') + } + document.body.removeChild(textarea) + } else { + messageApi.error('Copy not supported in this browser') + } + } + + return ( + <> + {contextHolder} + + - + danger + /> + ) : ( { dataIndex: '_id', key: 'id', width: 180, - render: (text) => + render: (text) => ( + + ) } ] diff --git a/src/components/Dashboard/common/PrinterMovementPanel.jsx b/src/components/Dashboard/common/PrinterMovementPanel.jsx index 0e35f5f..1b41daa 100644 --- a/src/components/Dashboard/common/PrinterMovementPanel.jsx +++ b/src/components/Dashboard/common/PrinterMovementPanel.jsx @@ -41,7 +41,7 @@ const PrinterMovementPanel = ({ printerId }) => { const handleHomeAxisClick = (axis) => { if (printServer) { - console.log('Homeing Axis:', axis) + logger.debug('Homeing Axis:', axis) printServer.emit('printer.gcode.script', { printerId, script: `G28 ${axis}` @@ -52,7 +52,7 @@ const PrinterMovementPanel = ({ printerId }) => { const handleMoveAxisClick = (axis, minus) => { const distanceValue = !minus ? posValue * -1 : posValue if (printServer) { - console.log('Moving Axis:', axis, distanceValue) + logger.debug('Moving Axis:', axis, distanceValue) printServer.emit('printer.gcode.script', { printerId, script: `_CLIENT_LINEAR_MOVE ${axis}=${distanceValue} F=${rateValue}` diff --git a/src/components/Dashboard/common/PrinterState.jsx b/src/components/Dashboard/common/PrinterState.jsx index 6bbc0b0..2e4ae50 100644 --- a/src/components/Dashboard/common/PrinterState.jsx +++ b/src/components/Dashboard/common/PrinterState.jsx @@ -12,7 +12,7 @@ const PrinterState = ({ printer, showProgress = true, showStatus = true, - showPrinterName = true, + showName = true, showControls = true }) => { const { printServer } = useContext(PrintServerContext) @@ -43,7 +43,7 @@ const PrinterState = ({ return ( - {showPrinterName && {printer.name}} + {showName && {printer.name}} {showStatus && ( @@ -122,7 +122,7 @@ PrinterState.propTypes = { }), showProgress: PropTypes.bool, showStatus: PropTypes.bool, - showPrinterName: PropTypes.bool, + showName: PropTypes.bool, showControls: PropTypes.bool } diff --git a/src/components/Dashboard/common/PrinterTemperaturePanel.jsx b/src/components/Dashboard/common/PrinterTemperaturePanel.jsx index 0924a1c..a60191d 100644 --- a/src/components/Dashboard/common/PrinterTemperaturePanel.jsx +++ b/src/components/Dashboard/common/PrinterTemperaturePanel.jsx @@ -97,14 +97,12 @@ const PrinterTemperaturePanel = ({ } } if (printServer?.connected == true) { - console.log('Printer Temperature Panel is subscribing...') printServer.emit('printer.objects.subscribe', params) printServer.emit('printer.objects.query', params) printServer.on('notify_status_update', notifyTemperatureStatusUpdate) } return () => { if (printServer && shouldUnsubscribe == true) { - console.log('Printer Temperature Panel is unsubscribing...') printServer.off('notify_status_update', notifyTemperatureStatusUpdate) printServer.emit('printer.objects.unsubscribe', params) } @@ -113,7 +111,6 @@ const PrinterTemperaturePanel = ({ const handleSetTemperatureClick = (target, value) => { if (printServer) { - console.log('printer.gcode.script', target, value) printServer.emit('printer.gcode.script', { printerId, script: `SET_HEATER_TEMPERATURE HEATER=${target} TARGET=${value}` diff --git a/src/components/Dashboard/common/SecretDisplay.jsx b/src/components/Dashboard/common/SecretDisplay.jsx new file mode 100644 index 0000000..ac61b99 --- /dev/null +++ b/src/components/Dashboard/common/SecretDisplay.jsx @@ -0,0 +1,50 @@ +import React, { useState } from 'react' +import PropTypes from 'prop-types' +import { Typography, Tooltip, Button } from 'antd' +import CopyButton from './CopyButton' +import EyeIcon from '../../Icons/EyeIcon' +import EyeSlashIcon from '../../Icons/EyeSlashIcon' + +const { Text } = Typography + +const SecretDisplay = ({ value, reveal = false }) => { + const [visible, setVisible] = useState(false) + + if (!value) { + return n/a + } + + const masked = '•'.repeat(Math.max(8, value.length)) + + return ( + + {reveal && visible ? value : masked} + {reveal && ( + + + + ) +} + +ViewButton.propTypes = { + loading: PropTypes.bool, + sections: PropTypes.arrayOf( + PropTypes.shape({ + key: PropTypes.string.isRequired, + label: PropTypes.string.isRequired + }) + ), + collapseState: PropTypes.object, + updateCollapseState: PropTypes.func +} + +export default ViewButton diff --git a/src/components/Dashboard/context/ApiServerContext.js b/src/components/Dashboard/context/ApiServerContext.js index 519373b..cbcc39d 100644 --- a/src/components/Dashboard/context/ApiServerContext.js +++ b/src/components/Dashboard/context/ApiServerContext.js @@ -10,13 +10,14 @@ import io from 'socket.io-client' import { message, notification, Modal, Space, Button } from 'antd' import PropTypes from 'prop-types' import { AuthContext } from './AuthContext' -import config from '../../../config' -import loglevel from 'loglevel' + import axios from 'axios' import ExclamationOctagonIcon from '../../Icons/ExclamationOctagonIcon' import ReloadIcon from '../../Icons/ReloadIcon' -const log = loglevel.getLogger('Api Server') -log.setLevel(config.logLevel) +import config from '../../../config' +import loglevel from 'loglevel' +const logger = loglevel.getLogger('ApiServerContext') +logger.setLevel(config.logLevel) const ApiServerContext = createContext() @@ -34,7 +35,7 @@ const ApiServerProvider = ({ children }) => { useEffect(() => { if (token) { - log.debug('Token is available, connecting to api server...') + logger.debug('Token is available, connecting to api server...') const newSocket = io(config.apiServerUrl, { reconnectionAttempts: 3, @@ -45,18 +46,18 @@ const ApiServerProvider = ({ children }) => { setConnecting(true) newSocket.on('connect', () => { - log.debug('Api Server connected') + logger.debug('Api Server connected') setConnecting(false) setError(null) }) newSocket.on('disconnect', () => { - log.debug('Api Server disconnected') + logger.debug('Api Server disconnected') setError('Api Server disconnected') }) newSocket.on('connect_error', (err) => { - log.error('Api Server connection error:', err) + logger.error('Api Server connection error:', err) messageApi.error('Api Server connection error: ' + err.message) setError('Api Server connection error') }) @@ -69,7 +70,7 @@ const ApiServerProvider = ({ children }) => { }) newSocket.on('error', (err) => { - log.error('Api Server error:', err) + logger.error('Api Server error:', err) setError('Api Server error') }) @@ -78,37 +79,37 @@ const ApiServerProvider = ({ children }) => { // Clean up function return () => { if (socketRef.current) { - log.debug('Cleaning up api server connection...') + logger.debug('Cleaning up api server connection...') socketRef.current.disconnect() socketRef.current = null } } } else if (!token && socketRef.current) { - log.debug('Token not available, disconnecting api server...') + logger.debug('Token not available, disconnecting api server...') socketRef.current.disconnect() socketRef.current = null } }, [token, messageApi]) const lockObject = (id, type) => { - log.debug('Locking ' + id) + logger.debug('Locking ' + id) if (socketRef.current && socketRef.current.connected) { socketRef.current.emit('lock', { _id: id, type: type }) - log.debug('Sent lock command for object:', id) + logger.debug('Sent lock command for object:', id) } } const unlockObject = (id, type) => { - log.debug('Unlocking ' + id) + logger.debug('Unlocking ' + id) if (socketRef.current && socketRef.current.connected == true) { socketRef.current.emit('unlock', { _id: id, type: type }) - log.debug('Sent unlock command for object:', id) + logger.debug('Sent unlock command for object:', id) } } const fetchObjectLock = async (id, type) => { if (socketRef.current && socketRef.current.connected == true) { - log.debug('Fetching lock status for ' + id) + logger.debug('Fetching lock status for ' + id) return new Promise((resolve) => { socketRef.current.emit( 'getLock', @@ -117,11 +118,11 @@ const ApiServerProvider = ({ children }) => { type: type }, (lockEvent) => { - log.debug('Received lock event for object:', id, lockEvent) + logger.debug('Received lock event for object:', id, lockEvent) resolve(lockEvent) } ) - log.debug('Sent fetch lock command for object:', id) + logger.debug('Sent fetch lock command for object:', id) }) } } @@ -130,7 +131,7 @@ const ApiServerProvider = ({ children }) => { if (socketRef.current && socketRef.current.connected == true) { const eventHandler = (data) => { if (data._id === id && data?.user !== userProfile._id) { - log.debug( + logger.debug( 'Lock update received for object:', id, 'locked:', @@ -141,7 +142,7 @@ const ApiServerProvider = ({ children }) => { } socketRef.current.on('notify_lock_update', eventHandler) - log.debug('Registered lock event listener for object:', id) + logger.debug('Registered lock event listener for object:', id) // Return cleanup function return () => offLockEvent(id, eventHandler) @@ -151,7 +152,7 @@ const ApiServerProvider = ({ children }) => { const offLockEvent = (id, eventHandler) => { if (socketRef.current && socketRef.current.connected == true) { socketRef.current.off('notify_lock_update', eventHandler) - log.debug('Removed lock event listener for object:', id) + logger.debug('Removed lock event listener for object:', id) } } @@ -159,7 +160,7 @@ const ApiServerProvider = ({ children }) => { if (socketRef.current && socketRef.current.connected == true) { const eventHandler = (data) => { if (data._id === id && data?.user !== userProfile._id) { - log.debug( + logger.debug( 'Update event received for object:', id, 'updatedAt:', @@ -170,7 +171,7 @@ const ApiServerProvider = ({ children }) => { } socketRef.current.on('notify_object_update', eventHandler) - log.debug('Registered update event listener for object:', id) + logger.debug('Registered update event listener for object:', id) // Return cleanup function return () => offUpdateEvent(id, eventHandler) @@ -180,7 +181,7 @@ const ApiServerProvider = ({ children }) => { const offUpdateEvent = (id, eventHandler) => { if (socketRef.current && socketRef.current.connected == true) { socketRef.current.off('notify_update', eventHandler) - log.debug('Removed update event listener for object:', id) + logger.debug('Removed update event listener for object:', id) } } @@ -203,7 +204,7 @@ const ApiServerProvider = ({ children }) => { const fetchObjectInfo = async (id, type) => { const fetchUrl = `${config.backendUrl}/${type}s/${id}` setFetchLoading(true) - log.debug('Fetching from ' + fetchUrl) + logger.debug('Fetching from ' + fetchUrl) try { const response = await axios.get(fetchUrl, { headers: { @@ -213,7 +214,7 @@ const ApiServerProvider = ({ children }) => { }) return response.data } catch (err) { - log.error('Failed to fetch object information:', err) + logger.error('Failed to fetch object information:', err) // Don't automatically show error - let the component handle it throw err } finally { @@ -224,7 +225,7 @@ const ApiServerProvider = ({ children }) => { // Update filament information const updateObjectInfo = async (id, type, value) => { const updateUrl = `${config.backendUrl}/${type}s/${id}` - log.debug('Updating info for ' + id) + logger.debug('Updating info for ' + id) try { const response = await axios.put(updateUrl, value, { headers: { @@ -232,7 +233,7 @@ const ApiServerProvider = ({ children }) => { }, withCredentials: true }) - log.debug('Filament updated successfully') + logger.debug('Filament updated successfully') if (socketRef.current && socketRef.current.connected == true) { await socketRef.current.emit('update', { _id: id, @@ -242,7 +243,7 @@ const ApiServerProvider = ({ children }) => { } return response.data } catch (err) { - log.error('Failed to update filament information:', err) + logger.error('Failed to update filament information:', err) // Don't automatically show error - let the component handle it throw err } diff --git a/src/components/Dashboard/context/AuthContext.js b/src/components/Dashboard/context/AuthContext.js index b9bf589..41f4f6f 100644 --- a/src/components/Dashboard/context/AuthContext.js +++ b/src/components/Dashboard/context/AuthContext.js @@ -7,6 +7,9 @@ import ExclamationOctogonIcon from '../../Icons/ExclamationOctagonIcon' import InfoCircleIcon from '../../Icons/InfoCircleIcon' import config from '../../../config' import AppError from '../../App/AppError' +import loglevel from 'loglevel' +const logger = loglevel.getLogger('ApiServerContext') +logger.setLevel(config.logLevel) const AuthContext = createContext() @@ -50,7 +53,7 @@ const AuthProvider = ({ children }) => { }) if (response.status === 200 && response.data) { - console.log('User is authenticated!') + logger.debug('User is authenticated!') setAuthenticated(true) setToken(response.data.access_token) setExpiresAt(response.data.expires_at) @@ -60,7 +63,7 @@ const AuthProvider = ({ children }) => { setAuthError('Failed to authenticate user.') } } catch (error) { - console.log('Auth check failed', error) + logger.debug('Auth check failed', error) if (error.response?.status === 401) { setShowUnauthorizedModal(true) } else { diff --git a/src/components/Dashboard/context/SpotlightContext.js b/src/components/Dashboard/context/SpotlightContext.js index d53090b..ebd5843 100644 --- a/src/components/Dashboard/context/SpotlightContext.js +++ b/src/components/Dashboard/context/SpotlightContext.js @@ -16,7 +16,7 @@ import PropTypes from 'prop-types' import { useNavigate } from 'react-router-dom' import PrinterState from '../common/PrinterState' import JobState from '../common/JobState' -import IdText from '../common/IdText' +import IdDisplay from '../common/IdDisplay' import config from '../../../config' import { getTypeMeta, getPrefixMeta } from '../utils/Utils' @@ -243,7 +243,6 @@ const SpotlightProvider = ({ children }) => { if (!value || value.trim() === '') { // Only clear the prefix if the input is completely empty if (value === '') { - console.log('Clearing prefix') setInputPrefix(null) } if (formRef.current) { @@ -278,7 +277,6 @@ const SpotlightProvider = ({ children }) => { const handleKeyDown = (e) => { // If backspace is pressed and there's a prefix but the input is empty if (e.key === 'Backspace' && inputPrefix && query === '') { - console.log('Clearing prefix on backspace') // Clear the prefix setInputPrefix(null) // Prevent the default backspace behavior in this case @@ -462,7 +460,6 @@ const SpotlightProvider = ({ children }) => { // Add more inference as needed } const meta = getTypeMeta(type) - console.log('meta', inputPrefix?.type) const Icon = meta.icon // Determine shortcut text @@ -489,7 +486,7 @@ const SpotlightProvider = ({ children }) => { {meta.type == 'printer' ? ( @@ -520,7 +517,7 @@ const SpotlightProvider = ({ children }) => { /> ) : null} - !item.isSkeleton) })) const relevantPages = filteredPages.slice(-2) - console.log('Pages after scroll down:', { + logger.debug('Pages after scroll down:', { current: currentLoadedPageNumber, next: nextPage, keeping: relevantPages.map((p) => p.pageNum) @@ -78,7 +82,7 @@ export const useTableScroll = ({ items: page.items.filter((item) => !item.isSkeleton) })) - console.log('Pages after scroll up:', { + logger.debug('Pages after scroll up:', { current: currentLoadedPageNumber, prev: prevPage, keeping: relevantPages.map((p) => p.pageNum) diff --git a/src/components/Dashboard/utils/Utils.js b/src/components/Dashboard/utils/Utils.js index bb9fe67..c3a21bc 100644 --- a/src/components/Dashboard/utils/Utils.js +++ b/src/components/Dashboard/utils/Utils.js @@ -55,14 +55,32 @@ export const TYPE_META = [ title: 'Printer', prefix: 'PRN', icon: PrinterIcon, - url: (id) => `/dashboard/production/printers/info?printerId=${id}` + url: (id) => `/dashboard/production/printers/info?printerId=${id}`, + properties: { + name: 'text' + } }, { type: 'filament', title: 'Filament', prefix: 'FIL', icon: FilamentIcon, - url: (id) => `/dashboard/management/filaments/info?filamentId=${id}` + url: (id) => `/dashboard/management/filaments/info?filamentId=${id}`, + properties: { + id: 'id', + createdAt: 'dateTime', + name: 'text', + updatedAt: 'dateTime', + vendor: 'object', // objectType: vendor + vendorId: 'id', // objectType: vendor + type: 'material', + cost: 'currency', + color: 'color', + diameter: 'mm', + density: 'density', + url: 'text', + barcode: 'text' + } }, { type: 'spool', @@ -104,7 +122,18 @@ export const TYPE_META = [ title: 'Vendor', prefix: 'VEN', icon: VendorIcon, - url: (id) => `/dashboard/management/vendors/info?vendorId=${id}` + url: (id) => `/dashboard/management/vendors/info?vendorId=${id}`, + properties: { + id: 'id', // objectType: vendor + createdAt: 'dateTime', + name: 'text', + updatedAt: 'dateTime', + website: 'url', + country: 'country', + contact: 'text', + phone: 'text', + email: 'email' + } }, { type: 'subjob', diff --git a/src/components/Icons/EmailDisplay.jsx b/src/components/Icons/EmailDisplay.jsx new file mode 100644 index 0000000..2d4a950 --- /dev/null +++ b/src/components/Icons/EmailDisplay.jsx @@ -0,0 +1,55 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Typography, Flex, Button, Tooltip } from 'antd' +import NewMailIcon from './NewMailIcon' +// import CopyIcon from './CopyIcon' +import CopyButton from '../Dashboard/common/CopyButton' + +const { Text, Link } = Typography + +const EmailDisplay = ({ email, showCopy = true, showLink = false }) => { + if (!email) return n/a + + return ( + <> + + {showLink ? ( + + {email} + + ) : ( + <> + {email} + +