Compare commits

..

No commits in common. "f4635d918853eb3f418ba9150b6adee574bc1310" and "c3cfd0a55e4364b684976f5685fa2dd54a4f3905" have entirely different histories.

115 changed files with 2789 additions and 2841 deletions

View File

@ -18,7 +18,6 @@ import {
ElectronSpotlightContentPage
} from './components/Dashboard/context/SpotlightContext.jsx'
import { ActionsModalProvider } from './components/Dashboard/context/ActionsModalContext.jsx'
import { ActionsProvider } from './components/Dashboard/context/ActionsContext.jsx'
import MissingPlaceholder from './components/Dashboard/common/MissingPlaceholder.jsx'
import {
@ -47,8 +46,7 @@ import {
FinanceRoutes,
SalesRoutes,
ManagementRoutes,
DeveloperRoutes,
ModelRoutes
DeveloperRoutes
} from './routes'
const getRouter = () => {
@ -85,89 +83,86 @@ const AppContent = () => {
<PrintServerProvider>
<ApiServerProvider>
<MessageProvider>
<TableStateProvider>
<AppUpdateProvider>
<NotificationProvider>
<SpotlightProvider>
<ActionsModalProvider>
<ActionsProvider>
<Routes>
<Route
path='/applaunch'
element={<AuthLaunch />}
/>
<Route
path='/dashboard/electron/spotlightcontent'
element={
<PrivateRoute
component={() => (
<ElectronSpotlightContentPage />
)}
/>
}
/>
<Route
path='/'
element={
<PrivateRoute
component={() => (
<Navigate
to='/dashboard/production/overview'
replace
/>
)}
/>
}
/>
<Route
path='/auth/callback'
element={<AuthCallback />}
/>
<Route
path='/auth/marketplace/callback'
element={<MarketplaceAuthCallback />}
/>
<Route
path='/email/notification'
element={<EmailNotificationTemplate />}
/>
<Route
path='/slicer'
element={<SlicerIntegration />}
/>
<AppUpdateProvider>
<NotificationProvider>
<SpotlightProvider>
<ActionsModalProvider>
<TableStateProvider>
<Routes>
<Route
path='/applaunch'
element={<AuthLaunch />}
/>
<Route
path='/dashboard/electron/spotlightcontent'
element={
<PrivateRoute
component={() => (
<ElectronSpotlightContentPage />
)}
/>
}
/>
<Route
path='/'
element={
<PrivateRoute
component={() => (
<Navigate
to='/dashboard/production/overview'
replace
/>
)}
/>
}
/>
<Route
path='/auth/callback'
element={<AuthCallback />}
/>
<Route
path='/auth/marketplace/callback'
element={<MarketplaceAuthCallback />}
/>
<Route
path='/email/notification'
element={<EmailNotificationTemplate />}
/>
<Route
path='/slicer'
element={<SlicerIntegration />}
/>
<Route
path='/dashboard'
element={
<PrivateRoute
component={() => <Dashboard />}
/>
}
>
{ProductionRoutes}
{InventoryRoutes}
{FinanceRoutes}
{SalesRoutes}
{ManagementRoutes}
{ModelRoutes}
{DeveloperRoutes}
</Route>
<Route
path='*'
element={
<AppError
message='Error 404. Page not found.'
showRefresh={false}
/>
}
/>
</Routes>
</ActionsProvider>
</ActionsModalProvider>
</SpotlightProvider>
</NotificationProvider>
</AppUpdateProvider>
</TableStateProvider>
<Route
path='/dashboard'
element={
<PrivateRoute
component={() => <Dashboard />}
/>
}
>
{ProductionRoutes}
{InventoryRoutes}
{FinanceRoutes}
{SalesRoutes}
{ManagementRoutes}
{DeveloperRoutes}
</Route>
<Route
path='*'
element={
<AppError
message='Error 404. Page not found.'
showRefresh={false}
/>
}
/>
</Routes>
</TableStateProvider>
</ActionsModalProvider>
</SpotlightProvider>
</NotificationProvider>
</AppUpdateProvider>
</MessageProvider>
</ApiServerProvider>
</PrintServerProvider>

View File

@ -1,6 +1,6 @@
import { useRef, useState, useEffect } from 'react'
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, Space } from 'antd'
import { Card, Flex, Modal, Space } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import loglevel from 'loglevel'
import config from '../../../../config.js'
@ -19,7 +19,6 @@ import EditButtons from '../../common/EditButtons.jsx'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
@ -32,6 +31,9 @@ import {
} from '../../../../database/ObjectModels.js'
import OrderItemIcon from '../../../Icons/OrderItemIcon.jsx'
import ShipmentIcon from '../../../Icons/ShipmentIcon.jsx'
import PostInvoice from './PostInvoice.jsx'
import AcknowledgeInvoice from './AcknowledgeInvoice.jsx'
import NewPayment from '../Payments/NewPayment.jsx'
const log = loglevel.getLogger('InvoiceInfo')
log.setLevel(config.logLevel)
@ -40,15 +42,6 @@ const InvoiceInfo = () => {
const location = useLocation()
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
objectFormRef.current?.handleFetchObject?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const invoiceId = new URLSearchParams(location.search).get('invoiceId')
const [collapseState, updateCollapseState] = useCollapseState('InvoiceInfo', {
info: true,
@ -67,6 +60,9 @@ const InvoiceInfo = () => {
loading: false,
objectData: {}
})
const [postInvoiceOpen, setPostInvoiceOpen] = useState(false)
const [acknowledgeInvoiceOpen, setAcknowledgeInvoiceOpen] = useState(false)
const [newPaymentOpen, setNewPaymentOpen] = useState(false)
const actions = {
edit: () => {
@ -85,6 +81,18 @@ const InvoiceInfo = () => {
objectFormRef?.current?.handleDelete?.()
return true
},
post: () => {
setPostInvoiceOpen(true)
return true
},
acknowledge: () => {
setAcknowledgeInvoiceOpen(true)
return true
},
newPayment: () => {
setNewPaymentOpen(true)
return true
}
}
const editDisabled =
@ -93,6 +101,7 @@ const InvoiceInfo = () => {
?.disabled(objectFormState.objectData) ?? false
return (
<>
<Flex
gap='large'
vertical='true'
@ -181,7 +190,6 @@ const InvoiceInfo = () => {
type='invoice'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -298,6 +306,65 @@ const InvoiceInfo = () => {
</Flex>
</ScrollBox>
</Flex>
<Modal
open={postInvoiceOpen}
onCancel={() => {
setPostInvoiceOpen(false)
}}
width={500}
footer={null}
destroyOnHidden={true}
centered={true}
>
<PostInvoice
onOk={() => {
setPostInvoiceOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
<Modal
open={acknowledgeInvoiceOpen}
onCancel={() => {
setAcknowledgeInvoiceOpen(false)
}}
width={515}
footer={null}
destroyOnHidden={true}
centered={true}
>
<AcknowledgeInvoice
onOk={() => {
setAcknowledgeInvoiceOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
<Modal
open={newPaymentOpen}
styles={{ content: { paddingBottom: '24px' } }}
footer={null}
width={800}
onCancel={() => {
setNewPaymentOpen(false)
}}
destroyOnHidden={true}
>
<NewPayment
onOk={() => {
setNewPaymentOpen(false)
objectFormRef?.current.handleFetchObject()
}}
reset={newPaymentOpen}
defaultValues={{
invoice: { ...objectFormState.objectData },
amount: objectFormState.objectData?.grandTotalAmount
}}
/>
</Modal>
</>
)
}

View File

@ -1,6 +1,6 @@
import { useRef, useState, useEffect } from 'react'
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, Space } from 'antd'
import { Card, Flex, Modal, Space } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import loglevel from 'loglevel'
import config from '../../../../config.js'
@ -17,7 +17,6 @@ import EditButtons from '../../common/EditButtons.jsx'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
@ -25,6 +24,10 @@ import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import PostPayment from './PostPayment.jsx'
import AuthorisePayment from './AuthorisePayment.jsx'
import DeclinePayment from './DeclinePayment.jsx'
import CancelPayment from './CancelPayment.jsx'
const log = loglevel.getLogger('PaymentInfo')
log.setLevel(config.logLevel)
@ -33,15 +36,6 @@ const PaymentInfo = () => {
const location = useLocation()
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
objectFormRef.current?.handleFetchObject?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const paymentId = new URLSearchParams(location.search).get('paymentId')
const [collapseState, updateCollapseState] = useCollapseState('PaymentInfo', {
info: true,
@ -57,6 +51,10 @@ const PaymentInfo = () => {
loading: false,
objectData: {}
})
const [postPaymentOpen, setPostPaymentOpen] = useState(false)
const [authorisePaymentOpen, setAuthorisePaymentOpen] = useState(false)
const [declinePaymentOpen, setDeclinePaymentOpen] = useState(false)
const [cancelPaymentOpen, setCancelPaymentOpen] = useState(false)
const actions = {
edit: () => {
@ -75,6 +73,22 @@ const PaymentInfo = () => {
objectFormRef?.current?.handleDelete?.()
return true
},
post: () => {
setPostPaymentOpen(true)
return true
},
authorise: () => {
setAuthorisePaymentOpen(true)
return true
},
decline: () => {
setDeclinePaymentOpen(true)
return true
},
cancel: () => {
setCancelPaymentOpen(true)
return true
}
}
const editDisabled =
@ -83,6 +97,7 @@ const PaymentInfo = () => {
?.disabled(objectFormState.objectData) ?? false
return (
<>
<Flex
gap='large'
vertical='true'
@ -168,7 +183,6 @@ const PaymentInfo = () => {
type='payment'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -230,6 +244,79 @@ const PaymentInfo = () => {
</Flex>
</ScrollBox>
</Flex>
<Modal
open={postPaymentOpen}
onCancel={() => {
setPostPaymentOpen(false)
}}
width={500}
footer={null}
destroyOnHidden={true}
centered={true}
>
<PostPayment
onOk={() => {
setPostPaymentOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
<Modal
open={authorisePaymentOpen}
onCancel={() => {
setAuthorisePaymentOpen(false)
}}
width={515}
footer={null}
destroyOnHidden={true}
centered={true}
>
<AuthorisePayment
onOk={() => {
setAuthorisePaymentOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
<Modal
open={declinePaymentOpen}
onCancel={() => {
setDeclinePaymentOpen(false)
}}
width={515}
footer={null}
destroyOnHidden={true}
centered={true}
>
<DeclinePayment
onOk={() => {
setDeclinePaymentOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
<Modal
open={cancelPaymentOpen}
onCancel={() => {
setCancelPaymentOpen(false)
}}
width={515}
footer={null}
destroyOnHidden={true}
centered={true}
>
<CancelPayment
onOk={() => {
setCancelPaymentOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
</>
)
}

View File

@ -155,7 +155,6 @@ const TaxRecordInfo = () => {
type='taxRecord'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -153,7 +153,6 @@ const FilamentStockInfo = () => {
type='filamentStock'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -215,7 +215,6 @@ const LoadFilamentStock = ({
showBed={false}
showMoreInfo={false}
id={loadFilamentStockFormValues.printer._id}
offline={!connected}
/>
) : null}
</Flex>

View File

@ -175,7 +175,6 @@ const UnloadFilamentStock = ({ onOk, reset, printer = null }) => {
showBed={false}
showMoreInfo={false}
id={unloadFilamentStockFormValues.printer._id}
offline={!connected}
/>
) : null}
</Flex>

View File

@ -148,7 +148,6 @@ const OrderItemInfo = () => {
type='orderItem'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -164,7 +164,6 @@ const PartStockInfo = () => {
type='partStock'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -1,6 +1,6 @@
import { useRef, useState, useEffect } from 'react'
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, Space } from 'antd'
import { Card, Flex, Modal, Space } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import loglevel from 'loglevel'
import config from '../../../../config.js'
@ -14,6 +14,7 @@ import {
getModelProperty,
getModelByName
} from '../../../../database/ObjectModels.js'
import PostProductStock from './PostProductStock.jsx'
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
import NoteIcon from '../../../Icons/NoteIcon.jsx'
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
@ -25,7 +26,6 @@ import EditButtons from '../../common/EditButtons.jsx'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
@ -41,18 +41,10 @@ const ProductStockInfo = () => {
const location = useLocation()
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
objectFormRef.current?.handleFetchObject?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const productStockId = new URLSearchParams(location.search).get(
'productStockId'
)
const [postProductStockOpen, setPostProductStockOpen] = useState(false)
const [collapseState, updateCollapseState] = useCollapseState(
'ProductStockInfo',
{
@ -91,6 +83,10 @@ const ProductStockInfo = () => {
objectFormRef?.current.handleDelete?.()
return true
},
post: () => {
setPostProductStockOpen(true)
return true
}
}
const editDisabled =
@ -99,6 +95,7 @@ const ProductStockInfo = () => {
?.disabled(objectFormState.objectData) ?? false
return (
<>
<Flex
gap='large'
vertical='true'
@ -187,7 +184,6 @@ const ProductStockInfo = () => {
type='productStock'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -306,6 +302,25 @@ const ProductStockInfo = () => {
</Flex>
</ScrollBox>
</Flex>
<Modal
open={postProductStockOpen}
onCancel={() => {
setPostProductStockOpen(false)
}}
width={500}
footer={null}
destroyOnHidden={true}
centered={true}
>
<PostProductStock
onOk={() => {
setPostProductStockOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
</>
)
}

View File

@ -1,6 +1,6 @@
import { useRef, useState, useEffect } from 'react'
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, Space } from 'antd'
import { Card, Flex, Modal, Space } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import loglevel from 'loglevel'
import config from '../../../../config.js'
@ -17,7 +17,6 @@ import EditButtons from '../../common/EditButtons.jsx'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
@ -25,10 +24,16 @@ import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import OrderItemsIcon from '../../../Icons/OrderItemIcon.jsx'
import NewOrderItem from '../OrderItems/NewOrderItem.jsx'
import NewShipment from '../Shipments/NewShipment.jsx'
import PostPurchaseOrder from './PostPurchaseOrder.jsx'
import AcknowledgePurchaseOrder from './AcknowledgePurchaseOrder.jsx'
import CancelPurchaseOrder from './CancelPurchaseOrder.jsx'
import ShipmentIcon from '../../../Icons/ShipmentIcon.jsx'
import InvoiceIcon from '../../../Icons/InvoiceIcon.jsx'
import StockEventIcon from '../../../Icons/StockEventIcon.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import NewInvoice from '../../Finance/Invoices/NewInvoice.jsx'
const log = loglevel.getLogger('PurchaseOrderInfo')
log.setLevel(config.logLevel)
@ -39,15 +44,13 @@ const PurchaseOrderInfo = () => {
const orderItemsTableRef = useRef(null)
const shipmentsTableRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
objectFormRef.current?.handleFetchObject?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const [newOrderItemOpen, setNewOrderItemOpen] = useState(false)
const [newShipmentOpen, setNewShipmentOpen] = useState(false)
const [postPurchaseOrderOpen, setPostPurchaseOrderOpen] = useState(false)
const [acknowledgePurchaseOrderOpen, setAcknowledgePurchaseOrderOpen] =
useState(false)
const [cancelPurchaseOrderOpen, setCancelPurchaseOrderOpen] = useState(false)
const [newInvoiceOpen, setNewInvoiceOpen] = useState(false)
const purchaseOrderId = new URLSearchParams(location.search).get(
'purchaseOrderId'
)
@ -93,6 +96,30 @@ const PurchaseOrderInfo = () => {
objectFormRef?.current?.handleDelete?.()
return true
},
newOrderItem: () => {
setNewOrderItemOpen(true)
return true
},
newShipment: () => {
setNewShipmentOpen(true)
return true
},
newInvoice: () => {
setNewInvoiceOpen(true)
return true
},
post: () => {
setPostPurchaseOrderOpen(true)
return true
},
acknowledge: () => {
setAcknowledgePurchaseOrderOpen(true)
return true
},
cancel: () => {
setCancelPurchaseOrderOpen(true)
return true
}
}
const editDisabled = getModelByName('purchaseOrder')
@ -100,6 +127,7 @@ const PurchaseOrderInfo = () => {
.disabled(objectFormState.objectData)
return (
<>
<Flex
gap='large'
vertical='true'
@ -189,7 +217,6 @@ const PurchaseOrderInfo = () => {
type='purchaseOrder'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -334,6 +361,122 @@ const PurchaseOrderInfo = () => {
</Flex>
</ScrollBox>
</Flex>
<Modal
open={newOrderItemOpen}
onCancel={() => {
setNewOrderItemOpen(false)
}}
width={800}
footer={null}
destroyOnHidden={true}
>
<NewOrderItem
onOk={() => {
setNewOrderItemOpen(false)
}}
reset={newOrderItemOpen}
defaultValues={{
order: { _id: purchaseOrderId },
orderType: 'purchaseOrder',
syncAmount: 'itemCost'
}}
/>
</Modal>
<Modal
open={newShipmentOpen}
onCancel={() => {
setNewShipmentOpen(false)
}}
width={800}
footer={null}
destroyOnHidden={true}
>
<NewShipment
onOk={() => {
setNewShipmentOpen(false)
}}
reset={newShipmentOpen}
defaultValues={{
orderType: 'purchaseOrder',
order: { _id: purchaseOrderId }
}}
/>
</Modal>
<Modal
open={newInvoiceOpen}
onCancel={() => {
setNewInvoiceOpen(false)
}}
width={800}
footer={null}
destroyOnHidden={true}
>
<NewInvoice
onOk={() => {
setNewInvoiceOpen(false)
}}
reset={newInvoiceOpen}
defaultValues={{
orderType: 'purchaseOrder',
order: { ...objectFormState.objectData }
}}
/>
</Modal>
<Modal
open={postPurchaseOrderOpen}
onCancel={() => {
setPostPurchaseOrderOpen(false)
}}
width={500}
footer={null}
destroyOnHidden={true}
centered={true}
>
<PostPurchaseOrder
onOk={() => {
setPostPurchaseOrderOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
<Modal
open={acknowledgePurchaseOrderOpen}
onCancel={() => {
setAcknowledgePurchaseOrderOpen(false)
}}
width={515}
footer={null}
destroyOnHidden={true}
centered={true}
>
<AcknowledgePurchaseOrder
onOk={() => {
setAcknowledgePurchaseOrderOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
<Modal
open={cancelPurchaseOrderOpen}
onCancel={() => {
setCancelPurchaseOrderOpen(false)
}}
width={515}
footer={null}
destroyOnHidden={true}
centered={true}
>
<CancelPurchaseOrder
onOk={() => {
setCancelPurchaseOrderOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
</>
)
}

View File

@ -184,7 +184,6 @@ const PurchaseOrderInfo = () => {
type='purchaseOrder'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -1,6 +1,6 @@
import { useRef, useState, useEffect } from 'react'
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, Space } from 'antd'
import { Card, Flex, Modal, Space } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import loglevel from 'loglevel'
import config from '../../../../config.js'
@ -17,7 +17,6 @@ import EditButtons from '../../common/EditButtons.jsx'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
@ -25,6 +24,9 @@ import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import OrderItemIcon from '../../../Icons/OrderItemIcon.jsx'
import ShipShipment from './ShipShipment.jsx'
import ReceiveShipment from './ReceiveShipment.jsx'
import CancelShipment from './CancelShipment.jsx'
const log = loglevel.getLogger('ShipmentInfo')
log.setLevel(config.logLevel)
@ -33,15 +35,6 @@ const ShipmentInfo = () => {
const location = useLocation()
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
objectFormRef.current?.handleFetchObject?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const shipmentId = new URLSearchParams(location.search).get('shipmentId')
const [collapseState, updateCollapseState] = useCollapseState(
'ShipmentInfo',
@ -60,6 +53,10 @@ const ShipmentInfo = () => {
loading: false,
objectData: {}
})
const [shipShipmentOpen, setShipShipmentOpen] = useState(false)
const [receiveShipmentOpen, setReceiveShipmentOpen] = useState(false)
const [cancelShipmentOpen, setCancelShipmentOpen] = useState(false)
const actions = {
edit: () => {
objectFormRef?.current?.startEditing?.()
@ -77,9 +74,22 @@ const ShipmentInfo = () => {
objectFormRef?.current?.handleDelete?.()
return true
},
ship: () => {
setShipShipmentOpen(true)
return true
},
receive: () => {
setReceiveShipmentOpen(true)
return true
},
cancel: () => {
setCancelShipmentOpen(true)
return true
}
}
return (
<>
<Flex
gap='large'
vertical='true'
@ -163,7 +173,6 @@ const ShipmentInfo = () => {
type='shipment'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -247,6 +256,61 @@ const ShipmentInfo = () => {
</Flex>
</ScrollBox>
</Flex>
<Modal
open={shipShipmentOpen}
onCancel={() => {
setShipShipmentOpen(false)
}}
width={515}
footer={null}
destroyOnHidden={true}
centered={true}
>
<ShipShipment
onOk={() => {
setShipShipmentOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
<Modal
open={receiveShipmentOpen}
onCancel={() => {
setReceiveShipmentOpen(false)
}}
width={515}
footer={null}
destroyOnHidden={true}
centered={true}
>
<ReceiveShipment
onOk={() => {
setReceiveShipmentOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
<Modal
open={cancelShipmentOpen}
onCancel={() => {
setCancelShipmentOpen(false)
}}
width={515}
footer={null}
destroyOnHidden={true}
centered={true}
>
<CancelShipment
onOk={() => {
setCancelShipmentOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
</>
)
}

View File

@ -158,7 +158,6 @@ const StockAuditInfo = () => {
type='stockAudit'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -159,7 +159,6 @@ const StockLocationInfo = () => {
type='stockLocation'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -1,6 +1,6 @@
import { useRef, useState, useEffect } from 'react'
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, Space } from 'antd'
import { Card, Flex, Modal, Space } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import useCollapseState from '../../hooks/useCollapseState.jsx'
import NotesPanel from '../../common/NotesPanel.jsx'
@ -12,6 +12,7 @@ import {
getModelProperty,
getModelByName
} from '../../../../database/ObjectModels.js'
import PostStockTransfer from './PostStockTransfer.jsx'
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
import NoteIcon from '../../../Icons/NoteIcon.jsx'
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
@ -21,7 +22,6 @@ import EditButtons from '../../common/EditButtons.jsx'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
@ -33,18 +33,10 @@ const StockTransferInfo = () => {
const location = useLocation()
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
objectFormRef.current?.handleFetchObject?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const stockTransferId = new URLSearchParams(location.search).get(
'stockTransferId'
)
const [postOpen, setPostOpen] = useState(false)
const [collapseState, updateCollapseState] = useCollapseState(
'StockTransferInfo',
{
@ -81,6 +73,10 @@ const StockTransferInfo = () => {
objectFormRef?.current.handleDelete?.()
return true
},
post: () => {
setPostOpen(true)
return true
}
}
const editDisabled =
@ -89,6 +85,7 @@ const StockTransferInfo = () => {
?.disabled(objectFormState.objectData) ?? false
return (
<>
<Flex
gap='large'
vertical='true'
@ -175,7 +172,6 @@ const StockTransferInfo = () => {
type='stockTransfer'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -257,6 +253,25 @@ const StockTransferInfo = () => {
</Flex>
</ScrollBox>
</Flex>
<Modal
open={postOpen}
onCancel={() => {
setPostOpen(false)
}}
width={520}
footer={null}
destroyOnHidden={true}
centered={true}
>
<PostStockTransfer
onOk={() => {
setPostOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
</>
)
}

View File

@ -1,6 +1,6 @@
import { useRef, useState, useEffect, useContext } from 'react'
import { useRef, useState, useContext } from 'react'
import { useLocation } from 'react-router-dom'
import { Flex, Space } from 'antd'
import { Flex, Modal, Space } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import useCollapseState from '../../hooks/useCollapseState'
import InfoCollapse from '../../common/InfoCollapse'
@ -13,13 +13,13 @@ import EditButtons from '../../common/EditButtons'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import RegenerateAppPasswordSecret from './RegenerateAppPasswordSecret.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import { AuthContext } from '../../context/AuthContext.jsx'
@ -27,19 +27,11 @@ const AppPasswordInfo = () => {
const location = useLocation()
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
objectFormRef.current?.handleFetchObject?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const { userProfile } = useContext(AuthContext)
const appPasswordId = new URLSearchParams(location.search).get(
'appPasswordId'
)
const [regenerateSecretOpen, setRegenerateSecretOpen] = useState(false)
const [collapseState, updateCollapseState] = useCollapseState(
'AppPasswordInfo',
{
@ -57,6 +49,10 @@ const AppPasswordInfo = () => {
})
const actions = {
regenerateSecret: () => {
setRegenerateSecretOpen(true)
return false
},
edit: () => {
objectFormRef?.current?.startEditing?.()
return false
@ -76,6 +72,7 @@ const AppPasswordInfo = () => {
.disabled({ ...objectFormState.objectData, _user: userProfile })
return (
<>
<Flex
gap='large'
vertical='true'
@ -163,7 +160,6 @@ const AppPasswordInfo = () => {
type='appPassword'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -202,6 +198,20 @@ const AppPasswordInfo = () => {
</Flex>
</ScrollBox>
</Flex>
<Modal
open={regenerateSecretOpen}
destroyOnHidden={true}
width={650}
onCancel={() => {
actionHandlerRef.current?.clearAction?.()
setRegenerateSecretOpen(false)
}}
footer={null}
>
<RegenerateAppPasswordSecret id={appPasswordId} />
</Modal>
</>
)
}

View File

@ -157,7 +157,6 @@ const CourierServiceInfo = () => {
type='courierService'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -153,7 +153,6 @@ const CourierInfo = () => {
type='courier'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -154,7 +154,6 @@ const DocumentJobInfo = () => {
type='documentJob'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -163,7 +163,6 @@ const DocumentPrinterInfo = () => {
type='documentPrinter'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -154,7 +154,6 @@ const DocumentSizeInfo = () => {
type='documentSize'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -160,7 +160,6 @@ const DocumentTemplateInfo = () => {
type='documentTemplate'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -152,7 +152,6 @@ const FilamentSkuInfo = () => {
type='filamentSku'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -15,7 +15,6 @@ const NewFilamentSku = ({ onOk, reset, defaultValues }) => {
}}
>
{({ handleSubmit, submitLoading, objectData, formValid }) => {
console.log('objectData', objectData)
const steps = [
{
title: 'Required',

View File

@ -1,6 +1,6 @@
import { useRef, useState, useEffect } from 'react'
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, Space } from 'antd'
import { Card, Flex, Modal, Space } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import loglevel from 'loglevel'
import config from '../../../../config'
@ -17,7 +17,6 @@ import EditButtons from '../../common/EditButtons'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
import ActionHandler from '../../common/ActionHandler'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
@ -26,6 +25,7 @@ import FilamentSkuIcon from '../../../Icons/FilamentSkuIcon.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import NewFilamentSku from '../FilamentSkus/NewFilamentSku'
const log = loglevel.getLogger('FilamentInfo')
log.setLevel(config.logLevel)
@ -35,15 +35,8 @@ const FilamentInfo = () => {
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const filamentId = new URLSearchParams(location.search).get('filamentId')
const [newFilamentSkuOpen, setNewFilamentSkuOpen] = useState(false)
const filamentSkusTableRef = useRef()
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
filamentSkusTableRef.current?.reload?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const [collapseState, updateCollapseState] = useCollapseState(
'FilamentInfo',
{
@ -65,6 +58,10 @@ const FilamentInfo = () => {
})
const actions = {
newFilamentSku: () => {
setNewFilamentSkuOpen(true)
return true
},
edit: () => {
objectFormRef?.current?.startEditing?.()
return false
@ -84,192 +81,215 @@ const FilamentInfo = () => {
}
return (
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Space size='small'>
<>
<Flex
gap='large'
vertical='true'
style={{
maxHeight: '100%',
minHeight: 0
}}
>
<Flex justify={'space-between'}>
<Space size='small'>
<ObjectActions
type='filament'
id={filamentId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Filament Information' },
{ key: 'filamentSkus', label: 'Filament SKUs' },
{ key: 'stocks', label: 'Filament Stocks' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='filament'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='filament'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
<Space size='small'>
<ObjectActions
type='filament'
id={filamentId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'Filament Information' },
{ key: 'filamentSkus', label: 'Filament SKUs' },
{ key: 'stocks', label: 'Filament Stocks' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='filament'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='filament'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</Space>
<Space>
<EditButtons
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
cancelEditing={() => {
actionHandlerRef.current.callAction('cancelEdit')
}}
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={
objectFormState.beingEditedByOther || objectFormState.loading
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={filamentId}
objectType='filament'
showEndingDivider={true}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</Space>
<Space>
<EditButtons
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
cancelEditing={() => {
actionHandlerRef.current.callAction('cancelEdit')
}}
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={
objectFormState.beingEditedByOther || objectFormState.loading
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={filamentId}
objectType='filament'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
title='Filament Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) => updateCollapseState('info', expanded)}
collapseKey='info'
>
<ObjectForm
id={filamentId}
type='filament'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => {
return (
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='filament'
objectData={objectData}
/>
)
}}
</ObjectForm>
</InfoCollapse>
</ActionHandler>
<InfoCollapse
title='Filament SKUs'
icon={<FilamentSkuIcon />}
active={collapseState.filamentSkus}
onToggle={(expanded) =>
updateCollapseState('filamentSkus', expanded)
}
collapseKey='filamentSkus'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
ref={filamentSkusTableRef}
type='filamentSku'
masterFilter={{ filament: filamentId }}
visibleColumns={{ filament: false }}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Filament Stocks'
icon={<FilamentIcon />}
active={collapseState.stocks}
onToggle={(expanded) => updateCollapseState('stocks', expanded)}
collapseKey='stocks'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='filamentStock'
masterFilter={{ filament: filamentId }}
visibleColumns={{
filament: false,
startingWeight: false
}}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={filamentId} type='filament' />
</Card>
</InfoCollapse>
<InfoCollapse
title='Audit Logs'
icon={<AuditLogIcon />}
active={collapseState.auditLogs}
onToggle={(expanded) => updateCollapseState('auditLogs', expanded)}
collapseKey='auditLogs'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': filamentId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
title='Filament Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) => updateCollapseState('info', expanded)}
collapseKey='info'
>
<ObjectForm
id={filamentId}
type='filament'
style={{ height: '100%' }}
ref={objectFormRef}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => {
return (
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='filament'
objectData={objectData}
/>
)
}}
</ObjectForm>
</InfoCollapse>
</ActionHandler>
<InfoCollapse
title='Filament SKUs'
icon={<FilamentSkuIcon />}
active={collapseState.filamentSkus}
onToggle={(expanded) =>
updateCollapseState('filamentSkus', expanded)
}
collapseKey='filamentSkus'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
ref={filamentSkusTableRef}
type='filamentSku'
masterFilter={{ filament: filamentId }}
visibleColumns={{ filament: false }}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Filament Stocks'
icon={<FilamentIcon />}
active={collapseState.stocks}
onToggle={(expanded) => updateCollapseState('stocks', expanded)}
collapseKey='stocks'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='filamentStock'
masterFilter={{ filament: filamentId }}
visibleColumns={{
filament: false,
startingWeight: false
}}
/>
)}
</InfoCollapse>
<Modal
open={newFilamentSkuOpen}
styles={{ content: { paddingBottom: '24px' } }}
footer={null}
width={700}
onCancel={() => setNewFilamentSkuOpen(false)}
destroyOnHidden={true}
>
<NewFilamentSku
onOk={() => {
setNewFilamentSkuOpen(false)
filamentSkusTableRef.current?.reload?.()
}}
reset={newFilamentSkuOpen}
defaultValues={{
filament: objectFormState?.objectData || undefined
}}
/>
</Modal>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={filamentId} type='filament' />
</Card>
</InfoCollapse>
<InfoCollapse
title='Audit Logs'
icon={<AuditLogIcon />}
active={collapseState.auditLogs}
onToggle={(expanded) =>
updateCollapseState('auditLogs', expanded)
}
collapseKey='auditLogs'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': filamentId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
</>
)
}

View File

@ -168,7 +168,6 @@ const FileInfo = () => {
type='file'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -1,6 +1,6 @@
import { useRef, useState, useEffect } from 'react'
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, Space } from 'antd'
import { Card, Flex, Modal, Space } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import loglevel from 'loglevel'
import config from '../../../../config.js'
@ -17,10 +17,10 @@ import EditButtons from '../../common/EditButtons.jsx'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import HostOTP from './HostOtp.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import PrinterIcon from '../../../Icons/PrinterIcon.jsx'
@ -34,15 +34,6 @@ const HostInfo = () => {
const location = useLocation()
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
objectFormRef.current?.handleFetchObject?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const hostId = new URLSearchParams(location.search).get('hostId')
const [collapseState, updateCollapseState] = useCollapseState('HostInfo', {
info: true,
@ -51,6 +42,8 @@ const HostInfo = () => {
notes: true,
auditLogs: false
})
const [hostOTPOpen, setHostOTPOpen] = useState(false)
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
@ -61,6 +54,10 @@ const HostInfo = () => {
})
const actions = {
hostOTP: () => {
setHostOTPOpen(true)
return false
},
edit: () => {
objectFormRef?.current.startEditing()
return false
@ -80,6 +77,7 @@ const HostInfo = () => {
}
return (
<>
<Flex
gap='large'
vertical='true'
@ -172,7 +170,6 @@ const HostInfo = () => {
type='host'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -270,6 +267,20 @@ const HostInfo = () => {
</Flex>
</ScrollBox>
</Flex>
<Modal
open={hostOTPOpen}
destroyOnHidden={true}
width={650}
onCancel={() => {
actionHandlerRef.current.clearAction()
setHostOTPOpen(false)
}}
footer={false}
>
<HostOTP id={hostId} />
</Modal>
</>
)
}

View File

@ -155,7 +155,6 @@ const MaterialInfo = () => {
type='material'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -143,7 +143,6 @@ const NoteTypeInfo = () => {
type='noteType'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -151,7 +151,6 @@ const NoteInfo = () => {
type='note'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -147,7 +147,6 @@ const PartSkuInfo = () => {
type='partSku'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -1,6 +1,6 @@
import { useRef, useState, useEffect } from 'react'
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, Space } from 'antd'
import { Card, Flex, Modal, Space } from 'antd'
import useCollapseState from '../../hooks/useCollapseState'
import NotesPanel from '../../common/NotesPanel'
import InfoCollapse from '../../common/InfoCollapse'
@ -14,7 +14,6 @@ import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
import NoteIcon from '../../../Icons/NoteIcon.jsx'
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
@ -22,22 +21,15 @@ import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import PartSkuIcon from '../../../Icons/PartSkuIcon.jsx'
import NewPartSku from '../PartSkus/NewPartSku'
const PartInfo = () => {
const location = useLocation()
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const partId = new URLSearchParams(location.search).get('partId')
const [newPartSkuOpen, setNewPartSkuOpen] = useState(false)
const partSkusTableRef = useRef()
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
partSkusTableRef.current?.reload?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const [collapseState, updateCollapseState] = useCollapseState('PartInfo', {
info: true,
partSkus: true,
@ -54,6 +46,10 @@ const PartInfo = () => {
})
const actions = {
newPartSku: () => {
setNewPartSkuOpen(true)
return true
},
edit: () => {
objectFormRef?.current?.startEditing?.()
return false
@ -69,6 +65,7 @@ const PartInfo = () => {
}
return (
<>
<Flex
gap='large'
vertical='true'
@ -149,7 +146,6 @@ const PartInfo = () => {
type='part'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -194,6 +190,25 @@ const PartInfo = () => {
)}
</InfoCollapse>
</ActionHandler>
<Modal
open={newPartSkuOpen}
styles={{ content: { paddingBottom: '24px' } }}
footer={null}
width={700}
onCancel={() => setNewPartSkuOpen(false)}
destroyOnHidden={true}
>
<NewPartSku
onOk={() => {
setNewPartSkuOpen(false)
partSkusTableRef.current?.reload?.()
}}
reset={newPartSkuOpen}
defaultValues={{
part: objectFormState?.objectData || undefined
}}
/>
</Modal>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
@ -227,6 +242,7 @@ const PartInfo = () => {
</Flex>
</ScrollBox>
</Flex>
</>
)
}

View File

@ -152,7 +152,6 @@ const ProductCategoryInfo = () => {
type='productCategory'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -148,7 +148,6 @@ const ProductSkuInfo = () => {
type='productSku'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -1,6 +1,6 @@
import { useRef, useState, useEffect } from 'react'
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, Space } from 'antd'
import { Card, Flex, Modal, Space } from 'antd'
import useCollapseState from '../../hooks/useCollapseState'
import NotesPanel from '../../common/NotesPanel'
import InfoCollapse from '../../common/InfoCollapse'
@ -15,13 +15,13 @@ import NoteIcon from '../../../Icons/NoteIcon.jsx'
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import ProductSkuIcon from '../../../Icons/ProductSkuIcon.jsx'
import NewProductSku from '../ProductSkus/NewProductSku'
const ProductInfo = () => {
const location = useLocation()
@ -34,16 +34,8 @@ const ProductInfo = () => {
notes: true,
auditLogs: false
})
const [newProductSkuOpen, setNewProductSkuOpen] = useState(false)
const productSkusTableRef = useRef()
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
productSkusTableRef.current?.reload?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
@ -54,6 +46,10 @@ const ProductInfo = () => {
})
const actions = {
newProductSku: () => {
setNewProductSkuOpen(true)
return true
},
edit: () => {
objectFormRef?.current?.startEditing?.()
return false
@ -69,6 +65,7 @@ const ProductInfo = () => {
}
return (
<>
<Flex
gap='large'
vertical='true'
@ -149,7 +146,6 @@ const ProductInfo = () => {
type='product'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -197,6 +193,26 @@ const ProductInfo = () => {
</ObjectForm>
</ActionHandler>
<Modal
open={newProductSkuOpen}
styles={{ content: { paddingBottom: '24px' } }}
footer={null}
width={700}
onCancel={() => setNewProductSkuOpen(false)}
destroyOnHidden={true}
>
<NewProductSku
onOk={() => {
setNewProductSkuOpen(false)
productSkusTableRef.current?.reload?.()
}}
reset={newProductSkuOpen}
defaultValues={{
product: objectFormState?.objectData || undefined
}}
/>
</Modal>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
@ -230,6 +246,7 @@ const ProductInfo = () => {
</Flex>
</ScrollBox>
</Flex>
</>
)
}

View File

@ -152,7 +152,6 @@ const TaxRateInfo = () => {
type='taxRate'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -1,6 +1,6 @@
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, Space } from 'antd'
import { Card, Flex, Modal, Space } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import useCollapseState from '../../hooks/useCollapseState'
import NotesPanel from '../../common/NotesPanel'
@ -22,6 +22,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import NewAppPassword from '../AppPasswords/NewAppPassword.jsx'
import ObjectProperty from '../../common/ObjectProperty.jsx'
import { getModelProperty } from '../../../../database/ObjectModels.js'
import { useMediaQuery } from 'react-responsive'
@ -32,6 +33,7 @@ const UserInfo = () => {
const appPasswordsTableRef = useRef(null)
const actionHandlerRef = useRef(null)
const userId = new URLSearchParams(location.search).get('userId')
const [newAppPasswordOpen, setNewAppPasswordOpen] = useState(false)
const [collapseState, updateCollapseState] = useCollapseState('UserInfo', {
info: true,
appPasswords: true,
@ -49,6 +51,10 @@ const UserInfo = () => {
const isMobile = useMediaQuery({ maxWidth: 768 })
const actions = {
newAppPassword: () => {
setNewAppPasswordOpen(true)
return false
},
edit: () => {
objectFormRef?.current?.startEditing?.()
return false
@ -64,184 +70,205 @@ const UserInfo = () => {
}
return (
<Flex
gap='large'
vertical='true'
style={{ maxHeight: '100%', minHeight: 0 }}
>
<Flex justify={'space-between'}>
<Space size='small'>
<>
<Flex
gap='large'
vertical='true'
style={{ maxHeight: '100%', minHeight: 0 }}
>
<Flex justify={'space-between'}>
<Space size='small'>
<ObjectActions
type='user'
id={userId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'User Information' },
{ key: 'appPasswords', label: 'App Passwords' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='user'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='user'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
<Space size='small'>
<ObjectActions
type='user'
id={userId}
disabled={objectFormState.loading}
objectData={objectFormState.objectData}
/>
<ViewButton
disabled={objectFormState.loading}
items={[
{ key: 'info', label: 'User Information' },
{ key: 'appPasswords', label: 'App Passwords' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
visibleState={collapseState}
updateVisibleState={updateCollapseState}
/>
<UserNotifierToggle
type='user'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
<DocumentPrintButton
type='user'
objectData={objectFormState.objectData}
disabled={objectFormState.loading}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</Space>
<Space>
<EditButtons
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
cancelEditing={() => {
actionHandlerRef.current.callAction('cancelEdit')
}}
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={
objectFormState.beingEditedByOther || objectFormState.loading
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={userId}
objectType='user'
showEndingDivider={true}
/>
</Space>
<ActivityIndicator
activities={objectFormState.activities}
showStartingDivider={true}
/>
</Space>
<Space>
<EditButtons
isEditing={objectFormState.isEditing}
handleUpdate={() => {
actionHandlerRef.current.callAction('finishEdit')
}}
cancelEditing={() => {
actionHandlerRef.current.callAction('cancelEdit')
}}
startEditing={() => {
actionHandlerRef.current.callAction('edit')
}}
editLoading={objectFormState.editLoading}
formValid={objectFormState.formValid}
disabled={
objectFormState.beingEditedByOther || objectFormState.loading
}
loading={objectFormState.editLoading}
/>
<ObjectTableNavigationButtons
disabled={objectFormState.loading || objectFormState.isEditing}
_id={userId}
objectType='user'
showEndingDivider={true}
/>
</Space>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
title='User Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) => updateCollapseState('info', expanded)}
collapseKey='info'
>
<ObjectForm
id={userId}
type='user'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex gap='large' vertical={isMobile}>
<div
style={
isMobile
? { width: '100%' }
: { width: '20%', maxWidth: '238px' }
}
>
<Card styles={{ body: { padding: 18 } }}>
<ObjectProperty
{...getModelProperty('user', 'profileImage')}
isEditing={isEditing}
objectData={objectData}
loading={loading}
/>
</Card>
</div>
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='user'
objectData={objectData}
visibleProperties={{
profileImage: false
}}
/>
</Flex>
)}
</ObjectForm>
</InfoCollapse>
</ActionHandler>
<InfoCollapse
title='App Passwords'
icon={<AppPasswordIcon />}
active={collapseState.appPasswords}
onToggle={(expanded) =>
updateCollapseState('appPasswords', expanded)
}
collapseKey='appPasswords'
>
{!userId ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='appPassword'
masterFilter={{ user: userId }}
visibleColumns={{ user: false }}
ref={appPasswordsTableRef}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={userId} type='user' />
</Card>
</InfoCollapse>
<InfoCollapse
title='Audit Logs'
icon={<AuditLogIcon />}
active={collapseState.auditLogs}
onToggle={(expanded) =>
updateCollapseState('auditLogs', expanded)
}
collapseKey='auditLogs'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': userId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
<ScrollBox>
<Flex vertical gap={'large'}>
<ActionHandler
actions={actions}
loading={objectFormState.loading}
ref={actionHandlerRef}
>
<InfoCollapse
title='User Information'
icon={<InfoCircleIcon />}
active={collapseState.info}
onToggle={(expanded) => updateCollapseState('info', expanded)}
collapseKey='info'
>
<ObjectForm
id={userId}
type='user'
style={{ height: '100%' }}
ref={objectFormRef}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
>
{({ loading, isEditing, objectData }) => (
<Flex gap='large' vertical={isMobile}>
<div
style={
isMobile
? { width: '100%' }
: { width: '20%', maxWidth: '238px' }
}
>
<Card styles={{ body: { padding: 18 } }}>
<ObjectProperty
{...getModelProperty('user', 'profileImage')}
isEditing={isEditing}
objectData={objectData}
loading={loading}
/>
</Card>
</div>
<ObjectInfo
loading={loading}
indicator={<LoadingOutlined />}
isEditing={isEditing}
type='user'
objectData={objectData}
visibleProperties={{
profileImage: false
}}
/>
</Flex>
)}
</ObjectForm>
</InfoCollapse>
</ActionHandler>
<InfoCollapse
title='App Passwords'
icon={<AppPasswordIcon />}
active={collapseState.appPasswords}
onToggle={(expanded) =>
updateCollapseState('appPasswords', expanded)
}
collapseKey='appPasswords'
>
{!userId ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='appPassword'
masterFilter={{ user: userId }}
visibleColumns={{ user: false }}
ref={appPasswordsTableRef}
/>
)}
</InfoCollapse>
<InfoCollapse
title='Notes'
icon={<NoteIcon />}
active={collapseState.notes}
onToggle={(expanded) => updateCollapseState('notes', expanded)}
collapseKey='notes'
>
<Card>
<NotesPanel _id={userId} type='user' />
</Card>
</InfoCollapse>
<InfoCollapse
title='Audit Logs'
icon={<AuditLogIcon />}
active={collapseState.auditLogs}
onToggle={(expanded) =>
updateCollapseState('auditLogs', expanded)
}
collapseKey='auditLogs'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': userId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex>
</ScrollBox>
</Flex>
<Modal
open={newAppPasswordOpen}
destroyOnHidden={true}
width={700}
onCancel={() => {
actionHandlerRef.current?.clearAction?.()
setNewAppPasswordOpen(false)
}}
footer={null}
>
<NewAppPassword
onOk={() => {
setNewAppPasswordOpen(false)
appPasswordsTableRef.current?.reload?.()
}}
reset={newAppPasswordOpen}
defaultValues={{ user: { ...objectFormState.objectData } }}
/>
</Modal>
</>
)
}

View File

@ -152,7 +152,6 @@ const VendorInfo = () => {
type='vendor'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -189,7 +189,6 @@ const FilamentProfileInfo = () => {
id={filamentProfileId}
type='filamentProfile'
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) =>
setObjectFormState((current) => ({ ...current, ...state }))
}

View File

@ -155,7 +155,6 @@ const GCodeFileInfo = () => {
type='gcodeFile'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -1,6 +1,6 @@
import { useRef, useState, useEffect } from 'react'
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, Space } from 'antd'
import { Card, Flex, Modal, Space } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import loglevel from 'loglevel'
import config from '../../../../config.js'
@ -17,13 +17,13 @@ import EditButtons from '../../common/EditButtons.jsx'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import JobIcon from '../../../Icons/JobIcon.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import DeployJob from './DeployJob.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
@ -34,16 +34,9 @@ const JobInfo = () => {
const location = useLocation()
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
objectFormRef.current?.handleFetchObject?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const jobId = new URLSearchParams(location.search).get('jobId')
const [deployJobOpen, setDeployJobOpen] = useState(false)
const [collapseState, updateCollapseState] = useCollapseState('JobInfo', {
info: true,
subJobs: true,
@ -80,9 +73,14 @@ const JobInfo = () => {
objectFormRef?.current.handleUpdate()
return true
},
deploy: () => {
setDeployJobOpen(true)
return false
}
}
return (
<>
<Flex
gap='large'
vertical='true'
@ -176,7 +174,6 @@ const JobInfo = () => {
type='job'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -242,6 +239,25 @@ const JobInfo = () => {
</Flex>
</ScrollBox>
</Flex>
<Modal
destroyOnHidden
footer={null}
open={deployJobOpen}
width={700}
onCancel={() => {
actionHandlerRef.current.clearAction()
setDeployJobOpen(false)
}}
>
<DeployJob
objectData={{ ...objectFormState.objectData }}
onOk={() => {
actionHandlerRef.current.clearAction()
setDeployJobOpen(false)
}}
/>
</Modal>
</>
)
}

View File

@ -162,7 +162,6 @@ const PrinterProfileInfo = () => {
id={printerProfileId}
type='printerProfile'
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) =>
setObjectFormState((current) => ({ ...current, ...state }))
}

View File

@ -1,6 +1,6 @@
import { useState, useRef, useEffect, useContext } from 'react'
import { useLocation } from 'react-router-dom'
import { Space, Flex, Card, Splitter, Divider } from 'antd'
import { Space, Flex, Card, Splitter, Divider, Modal } from 'antd'
import loglevel from 'loglevel'
import config from '../../../../config.js'
import useCollapseState from '../../hooks/useCollapseState.jsx'
@ -11,7 +11,6 @@ import NoteIcon from '../../../Icons/NoteIcon.jsx'
import ObjectForm from '../../common/ObjectForm.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import ObjectActions from '../../common/ObjectActions.jsx'
import { useActions } from '../../context/ActionsContext'
import PropTypes from 'prop-types'
import ObjectInfo from '../../common/ObjectInfo.jsx'
@ -30,6 +29,8 @@ import MissingPlaceholder from '../../common/MissingPlaceholder.jsx'
import { useMediaQuery } from 'react-responsive'
import AlertsDisplay from '../../common/AlertsDisplay.jsx'
import { ApiServerContext } from '../../context/ApiServerContext.jsx'
import LoadFilamentStock from '../../Inventory/FilamentStocks/LoadFilamentStock.jsx'
import UnloadFilamentStock from '../../Inventory/FilamentStocks/UnloadFilamentStock.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
import PrinterControlButtons from '../../common/PrinterControlButtons.jsx'
@ -58,7 +59,6 @@ const ControlPrinter = ({ slicerIntegration = false }) => {
)
const { connected, sendObjectAction } = useContext(ApiServerContext)
const { setCurrentObject, setCurrentObjectType, setOnModalOk } = useActions()
const [sideBarVisible, setSideBarVisible] = useState(
collapseState.temperature ||
collapseState.position ||
@ -66,14 +66,8 @@ const ControlPrinter = ({ slicerIntegration = false }) => {
collapseState.misc
)
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
activities: [],
loading: false,
objectData: {}
})
const [loadFilamentStockOpen, setLoadFilamentStockOpen] = useState(false)
const [unloadFilamentStockOpen, setUnloadFilamentStockOpen] = useState(false)
useEffect(() => {
setSideBarVisible(
@ -84,26 +78,14 @@ const ControlPrinter = ({ slicerIntegration = false }) => {
)
}, [collapseState])
useEffect(() => {
setCurrentObjectType('printer')
return () => {
setCurrentObject(null)
setCurrentObjectType(null)
}
}, [setCurrentObject, setCurrentObjectType])
useEffect(() => {
if (objectFormState.objectData?._id) {
setCurrentObject(objectFormState.objectData)
}
}, [objectFormState.objectData, setCurrentObject])
useEffect(() => {
setOnModalOk(() => () => {
objectFormRef.current?.handleFetchObject?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const [objectFormState, setEditFormState] = useState({
isEditing: false,
editLoading: false,
formValid: false,
activities: [],
loading: false,
objectData: {}
})
const actions = {
edit: () => {
@ -174,6 +156,14 @@ const ControlPrinter = ({ slicerIntegration = false }) => {
})
}
return true
},
loadFilamentStock: () => {
setLoadFilamentStockOpen(true)
return true
},
unloadFilamentStock: () => {
setUnloadFilamentStockOpen(true)
return true
}
}
@ -383,7 +373,6 @@ const ControlPrinter = ({ slicerIntegration = false }) => {
id={printerId}
type='printer'
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -606,6 +595,34 @@ const ControlPrinter = ({ slicerIntegration = false }) => {
</Flex>
</ScrollBox>
</Flex>
<Modal
open={loadFilamentStockOpen}
onCancel={() => setLoadFilamentStockOpen(false)}
footer={null}
width='700px'
destroyOnHidden={true}
>
<LoadFilamentStock
printer={objectFormState.objectData}
onOk={() => setLoadFilamentStockOpen(false)}
reset={false}
filamentStockLoaded={false}
/>
</Modal>
<Modal
open={unloadFilamentStockOpen}
onCancel={() => setUnloadFilamentStockOpen(false)}
footer={null}
width='700px'
destroyOnHidden={true}
>
<UnloadFilamentStock
printer={objectFormState.objectData}
onOk={() => setUnloadFilamentStockOpen(false)}
reset={false}
filamentStockLoaded={false}
/>
</Modal>
</>
)
}

View File

@ -1,6 +1,7 @@
import { useRef, useState, useEffect } from 'react'
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, Space } from 'antd'
import { Card, Flex, Modal, Space } from 'antd'
import NewPrinterProfile from '../PrinterProfiles/NewPrinterProfile'
import { LoadingOutlined } from '@ant-design/icons'
import loglevel from 'loglevel'
import config from '../../../../config.js'
@ -16,7 +17,6 @@ import ObjectForm from '../../common/ObjectForm.jsx'
import EditButtons from '../../common/EditButtons.jsx'
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
@ -33,9 +33,6 @@ const PrinterInfo = () => {
const objectFormRef = useRef(null)
const profilesTableRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
const printerId = new URLSearchParams(location.search).get('printerId')
const [collapseState, updateCollapseState] = useCollapseState('PrinterInfo', {
info: true,
@ -53,14 +50,7 @@ const PrinterInfo = () => {
loading: false,
objectData: {}
})
useEffect(() => {
setOnModalOk(() => () => {
profilesTableRef.current?.reload?.()
objectFormRef.current?.handleFetchObject?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const [newPrinterProfileOpen, setNewPrinterProfileOpen] = useState(false)
const actions = {
edit: () => {
@ -75,9 +65,14 @@ const PrinterInfo = () => {
objectFormRef?.current.handleUpdate()
return true
},
newPrinterProfile: () => {
setNewPrinterProfileOpen(true)
return true
}
}
return (
<>
<Flex
gap='large'
vertical='true'
@ -169,7 +164,6 @@ const PrinterInfo = () => {
type='printer'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -254,6 +248,28 @@ const PrinterInfo = () => {
</Flex>
</ScrollBox>
</Flex>
<Modal
open={newPrinterProfileOpen}
styles={{ content: { paddingBottom: '24px' } }}
footer={null}
width={800}
onCancel={() => {
setNewPrinterProfileOpen(false)
}}
destroyOnHidden={true}
>
<NewPrinterProfile
onOk={() => {
setNewPrinterProfileOpen(false)
profilesTableRef.current?.reload()
}}
reset={newPrinterProfileOpen}
defaultValues={{
printer: { ...objectFormState.objectData }
}}
/>
</Modal>
</>
)
}

View File

@ -143,7 +143,6 @@ const SubJobInfo = () => {
type='subJob'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -152,7 +152,6 @@ const ClientInfo = () => {
type='client'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}

View File

@ -1,6 +1,6 @@
import { useRef, useState, useEffect } from 'react'
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, Space } from 'antd'
import { Card, Flex, Modal, Space } from 'antd'
import loglevel from 'loglevel'
import config from '../../../../config'
import useCollapseState from '../../hooks/useCollapseState'
@ -16,13 +16,14 @@ import EditButtons from '../../common/EditButtons'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import PublishListingVarient from './PublishListingVarient.jsx'
import UnpublishListingVarient from './UnpublishListingVarient.jsx'
const log = loglevel.getLogger('ListingVarientInfo')
log.setLevel(config.logLevel)
@ -31,18 +32,11 @@ const ListingVarientInfo = () => {
const location = useLocation()
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
objectFormRef.current?.handleFetchObject?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const listingVarientId = new URLSearchParams(location.search).get(
'listingVarientId'
)
const [publishOpen, setPublishOpen] = useState(false)
const [unpublishOpen, setUnpublishOpen] = useState(false)
const [collapseState, updateCollapseState] = useCollapseState(
'ListingVarientInfo',
{
@ -77,9 +71,18 @@ const ListingVarientInfo = () => {
objectFormRef?.current?.handleDelete?.()
return true
},
publish: () => {
setPublishOpen(true)
return true
},
unpublish: () => {
setUnpublishOpen(true)
return true
}
}
return (
<>
<Flex
gap='large'
vertical='true'
@ -159,7 +162,6 @@ const ListingVarientInfo = () => {
type='listingVarient'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -219,6 +221,39 @@ const ListingVarientInfo = () => {
</Flex>
</ScrollBox>
</Flex>
<Modal
open={publishOpen}
onCancel={() => setPublishOpen(false)}
width={515}
footer={null}
destroyOnHidden={true}
centered={true}
>
<PublishListingVarient
objectData={objectFormState.objectData}
onOk={() => {
setPublishOpen(false)
objectFormRef?.current.handleFetchObject()
}}
/>
</Modal>
<Modal
open={unpublishOpen}
onCancel={() => setUnpublishOpen(false)}
width={515}
footer={null}
destroyOnHidden={true}
centered={true}
>
<UnpublishListingVarient
objectData={objectFormState.objectData}
onOk={() => {
setUnpublishOpen(false)
objectFormRef?.current.handleFetchObject()
}}
/>
</Modal>
</>
)
}

View File

@ -1,6 +1,6 @@
import { useRef, useState, useEffect } from 'react'
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, Space } from 'antd'
import { Card, Flex, Modal, Space } from 'antd'
import loglevel from 'loglevel'
import config from '../../../../config'
import useCollapseState from '../../hooks/useCollapseState'
@ -17,13 +17,15 @@ import EditButtons from '../../common/EditButtons'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import NewListingVarient from '../ListingVarients/NewListingVarient.jsx'
import PublishListing from './PublishListing.jsx'
import UnpublishListing from './UnpublishListing.jsx'
const log = loglevel.getLogger('ListingInfo')
log.setLevel(config.logLevel)
@ -33,16 +35,10 @@ const ListingInfo = () => {
const objectFormRef = useRef(null)
const listingVarientsTableRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
listingVarientsTableRef.current?.reload?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const listingId = new URLSearchParams(location.search).get('listingId')
const [newListingVarientOpen, setNewListingVarientOpen] = useState(false)
const [publishListingOpen, setPublishListingOpen] = useState(false)
const [unpublishListingOpen, setUnpublishListingOpen] = useState(false)
const [collapseState, updateCollapseState] = useCollapseState('ListingInfo', {
info: true,
listingVarients: true,
@ -75,9 +71,22 @@ const ListingInfo = () => {
objectFormRef?.current?.handleDelete?.()
return true
},
newListingVarient: () => {
setNewListingVarientOpen(true)
return true
},
publish: () => {
setPublishListingOpen(true)
return true
},
unpublish: () => {
setUnpublishListingOpen(true)
return true
}
}
return (
<>
<Flex
gap='large'
vertical='true'
@ -158,7 +167,6 @@ const ListingInfo = () => {
type='listing'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -237,6 +245,61 @@ const ListingInfo = () => {
</Flex>
</ScrollBox>
</Flex>
<Modal
open={newListingVarientOpen}
onCancel={() => {
setNewListingVarientOpen(false)
}}
width={800}
footer={null}
destroyOnHidden={true}
>
<NewListingVarient
onOk={() => {
setNewListingVarientOpen(false)
listingVarientsTableRef.current?.reload()
}}
reset={newListingVarientOpen}
defaultValues={{
listing: objectFormState.objectData
}}
/>
</Modal>
<Modal
open={publishListingOpen}
onCancel={() => setPublishListingOpen(false)}
width={515}
footer={null}
destroyOnHidden={true}
centered={true}
>
<PublishListing
objectData={objectFormState.objectData}
onOk={() => {
setPublishListingOpen(false)
objectFormRef?.current.handleFetchObject()
listingVarientsTableRef.current?.reload?.()
}}
/>
</Modal>
<Modal
open={unpublishListingOpen}
onCancel={() => setUnpublishListingOpen(false)}
width={515}
footer={null}
destroyOnHidden={true}
centered={true}
>
<UnpublishListing
objectData={objectFormState.objectData}
onOk={() => {
setUnpublishListingOpen(false)
objectFormRef?.current.handleFetchObject()
listingVarientsTableRef.current?.reload?.()
}}
/>
</Modal>
</>
)
}

View File

@ -1,6 +1,6 @@
import { useContext, useRef, useState , useEffect} from 'react'
import { useContext, useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Card, Flex, message, Space } from 'antd'
import { Card, Flex, message, Modal, Space } from 'antd'
import loglevel from 'loglevel'
import config from '../../../../config'
import useCollapseState from '../../hooks/useCollapseState'
@ -16,13 +16,15 @@ import EditButtons from '../../common/EditButtons'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import SyncListings from './SyncListings.jsx'
import SyncOrders from './SyncOrders.jsx'
import ConfigureMarketplace from './ConfigureMarketplace.jsx'
import { ApiServerContext } from '../../context/ApiServerContext.jsx'
import { ElectronContext } from '../../context/ElectronContext.jsx'
import {
@ -37,15 +39,6 @@ const MarketplaceInfo = () => {
const location = useLocation()
const objectFormRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
objectFormRef.current?.handleFetchObject?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const { getMarketplaceAuthUrl, refreshMarketplaceAuth } =
useContext(ApiServerContext)
const { openExternalUrl } = useContext(ElectronContext)
@ -68,6 +61,9 @@ const MarketplaceInfo = () => {
loading: false,
objectData: {}
})
const [syncListingsOpen, setSyncListingsOpen] = useState(false)
const [syncOrdersOpen, setSyncOrdersOpen] = useState(false)
const [configureModalOpen, setConfigureModalOpen] = useState(false)
const startAuthorization = async () => {
const objectData = objectFormState.objectData
@ -132,6 +128,18 @@ const MarketplaceInfo = () => {
objectFormRef?.current?.handleDelete?.()
return true
},
syncListings: () => {
setSyncListingsOpen(true)
return true
},
syncOrders: () => {
setSyncOrdersOpen(true)
return true
},
configure: () => {
setConfigureModalOpen(true)
return true
},
connect: () => {
startAuthorization()
return true
@ -147,6 +155,7 @@ const MarketplaceInfo = () => {
}
return (
<>
<Flex
gap='large'
vertical='true'
@ -233,7 +242,6 @@ const MarketplaceInfo = () => {
type='marketplace'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -283,6 +291,63 @@ const MarketplaceInfo = () => {
</Flex>
</ScrollBox>
</Flex>
<Modal
open={syncListingsOpen}
onCancel={() => setSyncListingsOpen(false)}
width={500}
footer={null}
destroyOnHidden={true}
centered
>
<SyncListings
onOk={() => {
setSyncListingsOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
<Modal
open={syncOrdersOpen}
onCancel={() => setSyncOrdersOpen(false)}
width={500}
footer={null}
destroyOnHidden={true}
centered
>
<SyncOrders
onOk={() => {
setSyncOrdersOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
<Modal
open={configureModalOpen}
onCancel={() => setConfigureModalOpen(false)}
width={650}
footer={null}
destroyOnHidden={true}
centered
>
<ConfigureMarketplace
onConnect={() => {
startAuthorization()
setConfigureModalOpen(false)
}}
isConnected={
!!(
objectFormState.objectData?.config?.refreshToken ||
objectFormState.objectData?.config?.accessToken ||
objectFormState.objectData?.config?.shopCipher
)
}
loading={objectFormState.loading}
disabled={objectFormState.isEditing}
/>
</Modal>
</>
)
}

View File

@ -1,6 +1,6 @@
import { useRef, useState, useEffect } from 'react'
import { useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Space, Flex, Card } from 'antd'
import { Space, Flex, Card, Modal } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import loglevel from 'loglevel'
import config from '../../../../config.js'
@ -17,7 +17,6 @@ import EditButtons from '../../common/EditButtons.jsx'
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import { useActions } from '../../context/ActionsContext'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
@ -25,10 +24,16 @@ import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'
import OrderItemsIcon from '../../../Icons/OrderItemIcon.jsx'
import NewOrderItem from '../../Inventory/OrderItems/NewOrderItem.jsx'
import NewShipment from '../../Inventory/Shipments/NewShipment.jsx'
import PostSalesOrder from './PostSalesOrder.jsx'
import ConfirmSalesOrder from './ConfirmSalesOrder.jsx'
import CancelSalesOrder from './CancelSalesOrder.jsx'
import ShipmentIcon from '../../../Icons/ShipmentIcon.jsx'
import InvoiceIcon from '../../../Icons/InvoiceIcon.jsx'
import StockEventIcon from '../../../Icons/StockEventIcon.jsx'
import { getModelByName } from '../../../../database/ObjectModels.js'
import NewInvoice from '../../Finance/Invoices/NewInvoice.jsx'
const log = loglevel.getLogger('SalesOrderInfo')
log.setLevel(config.logLevel)
@ -39,15 +44,12 @@ const SalesOrderInfo = () => {
const orderItemsTableRef = useRef(null)
const shipmentsTableRef = useRef(null)
const actionHandlerRef = useRef(null)
const { setOnModalOk } = useActions()
useEffect(() => {
setOnModalOk(() => () => {
objectFormRef.current?.handleFetchObject?.()
})
return () => setOnModalOk(null)
}, [setOnModalOk])
const [newOrderItemOpen, setNewOrderItemOpen] = useState(false)
const [newShipmentOpen, setNewShipmentOpen] = useState(false)
const [postSalesOrderOpen, setPostSalesOrderOpen] = useState(false)
const [confirmSalesOrderOpen, setConfirmSalesOrderOpen] = useState(false)
const [cancelSalesOrderOpen, setCancelSalesOrderOpen] = useState(false)
const [newInvoiceOpen, setNewInvoiceOpen] = useState(false)
const salesOrderId = new URLSearchParams(location.search).get('salesOrderId')
const [collapseState, updateCollapseState] = useCollapseState(
'SalesOrderInfo',
@ -91,6 +93,30 @@ const SalesOrderInfo = () => {
objectFormRef?.current?.handleDelete?.()
return true
},
newOrderItem: () => {
setNewOrderItemOpen(true)
return true
},
newShipment: () => {
setNewShipmentOpen(true)
return true
},
newInvoice: () => {
setNewInvoiceOpen(true)
return true
},
post: () => {
setPostSalesOrderOpen(true)
return true
},
confirm: () => {
setConfirmSalesOrderOpen(true)
return true
},
cancel: () => {
setCancelSalesOrderOpen(true)
return true
}
}
const editDisabled = getModelByName('salesOrder')
@ -98,6 +124,7 @@ const SalesOrderInfo = () => {
.disabled(objectFormState.objectData)
return (
<>
<Flex
gap='large'
vertical='true'
@ -187,7 +214,6 @@ const SalesOrderInfo = () => {
type='salesOrder'
style={{ height: '100%' }}
ref={objectFormRef}
setCurrentObject={true}
onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
@ -332,6 +358,122 @@ const SalesOrderInfo = () => {
</Flex>
</ScrollBox>
</Flex>
<Modal
open={newOrderItemOpen}
onCancel={() => {
setNewOrderItemOpen(false)
}}
width={800}
footer={null}
destroyOnHidden={true}
>
<NewOrderItem
onOk={() => {
setNewOrderItemOpen(false)
}}
reset={newOrderItemOpen}
defaultValues={{
order: { _id: salesOrderId },
orderType: 'salesOrder',
syncAmount: 'itemPrice'
}}
/>
</Modal>
<Modal
open={newShipmentOpen}
onCancel={() => {
setNewShipmentOpen(false)
}}
width={800}
footer={null}
destroyOnHidden={true}
>
<NewShipment
onOk={() => {
setNewShipmentOpen(false)
}}
reset={newShipmentOpen}
defaultValues={{
orderType: 'salesOrder',
order: { _id: salesOrderId }
}}
/>
</Modal>
<Modal
open={newInvoiceOpen}
onCancel={() => {
setNewInvoiceOpen(false)
}}
width={800}
footer={null}
destroyOnHidden={true}
>
<NewInvoice
onOk={() => {
setNewInvoiceOpen(false)
}}
reset={newInvoiceOpen}
defaultValues={{
orderType: 'salesOrder',
order: { ...objectFormState.objectData }
}}
/>
</Modal>
<Modal
open={postSalesOrderOpen}
onCancel={() => {
setPostSalesOrderOpen(false)
}}
width={500}
footer={null}
destroyOnHidden={true}
centered={true}
>
<PostSalesOrder
onOk={() => {
setPostSalesOrderOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
<Modal
open={confirmSalesOrderOpen}
onCancel={() => {
setConfirmSalesOrderOpen(false)
}}
width={515}
footer={null}
destroyOnHidden={true}
centered={true}
>
<ConfirmSalesOrder
onOk={() => {
setConfirmSalesOrderOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
<Modal
open={cancelSalesOrderOpen}
onCancel={() => {
setCancelSalesOrderOpen(false)
}}
width={515}
footer={null}
destroyOnHidden={true}
centered={true}
>
<CancelSalesOrder
onOk={() => {
setCancelSalesOrderOpen(false)
objectFormRef?.current.handleFetchObject()
}}
objectData={objectFormState.objectData}
/>
</Modal>
</>
)
}

View File

@ -8,7 +8,6 @@ import SpotlightTooltip from './SpotlightTooltip'
import Thumbnail from './Thumbnail'
import { useNavigate } from 'react-router-dom'
import { getModelByName } from '../../../database/ObjectModels'
import { buildActionUrl } from '../../../utils/modelActions'
const getUserId = (user) => user?._id || user
@ -91,13 +90,7 @@ const UserActivityAvatar = memo(
model.actions?.filter((action) => action.default == true) || []
if (defaultModelActions.length >= 1 && getUserId(user)) {
hyperlink = buildActionUrl(
model,
defaultModelActions[0],
getUserId(user),
'',
''
)
hyperlink = defaultModelActions[0].url(getUserId(user))
}
return (

View File

@ -5,7 +5,6 @@ import ExclamationOctagonIcon from '../../Icons/ExclamationOctagonIcon'
import InfoCircleIcon from '../../Icons/InfoCircleIcon'
import XMarkIcon from '../../Icons/XMarkIcon'
import { getModelByName } from '../../../database/ObjectModels'
import { buildActionUrl } from '../../../utils/modelActions'
import { useNavigate } from 'react-router-dom'
import ActionsIcon from '../../Icons/ActionsIcon'
import { ApiServerContext } from '../context/ApiServerContext'
@ -153,16 +152,8 @@ const AlertsDisplay = ({
onClick: ({ key }) => {
const action = findActionByKey(filteredActions, key)
if (action) {
navigate(
buildActionUrl(
getModelByName(objectType),
action,
objectId,
'',
''
)
)
if (action?.url) {
navigate(action.url(objectId))
} else {
console.warn('No action found for key:', key)
}

View File

@ -6,7 +6,6 @@ import { useMediaQuery } from 'react-responsive'
import CopyButton from './CopyButton'
import SpotlightTooltip from './SpotlightTooltip'
import { getModelByName } from '../../../database/ObjectModels'
import { buildActionUrl } from '../../../utils/modelActions'
const { Text, Link } = Typography
@ -32,7 +31,7 @@ const IdDisplay = ({
model.actions?.filter((action) => action.default == true) || []
if (defaultModelActions.length >= 1) {
hyperlink = buildActionUrl(model, defaultModelActions[0], id, '', '')
hyperlink = defaultModelActions[0].url(id)
}
if (!id) {

View File

@ -1,56 +0,0 @@
import { Suspense, useContext, useEffect } from 'react'
import { useLocation } from 'react-router-dom'
import { Flex, Spin } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import PropTypes from 'prop-types'
import { getModelByName } from '../../../database/ObjectModels'
import { getObjectIdFromSearch } from '../../../utils/modelActions'
import { useActions } from '../context/ActionsContext'
import { AuthContext } from '../context/AuthContext'
const ModelPage = ({ modelName, pageName }) => {
const model = getModelByName(modelName)
const page = model.pages?.find((p) => p.name === pageName)
const location = useLocation()
const { setCurrentObject, setCurrentObjectType } = useActions()
const { userProfile } = useContext(AuthContext)
const objectId = getObjectIdFromSearch(modelName, location.search)
useEffect(() => {
setCurrentObjectType(modelName)
if (objectId) {
setCurrentObject({ _id: objectId, _user: userProfile })
}
return () => {
setCurrentObject(null)
setCurrentObjectType(null)
}
}, [modelName, objectId, setCurrentObject, setCurrentObjectType, userProfile])
if (!page?.content) {
return null
}
return (
<Suspense
fallback={
<Flex
justify='center'
align='center'
style={{ width: '100%', height: '100%' }}
>
<Spin indicator={<LoadingOutlined spin />} />
</Flex>
}
>
{page.content()}
</Suspense>
)
}
ModelPage.propTypes = {
modelName: PropTypes.string.isRequired,
pageName: PropTypes.string.isRequired
}
export default ModelPage

View File

@ -6,7 +6,6 @@ import { useNavigate, useLocation } from 'react-router-dom'
import { useActionsModal } from '../context/ActionsModalContext'
import KeyboardShortcut from './KeyboardShortcut'
import { AuthContext } from '../context/AuthContext'
import { buildActionUrl, stripPageActionParams } from '../../../utils/modelActions'
// Recursively filter actions based on visibleActions
function filterActionsByVisibility(actions, visibleActions) {
@ -70,43 +69,22 @@ function cleanDividers(items) {
return cleaned
}
function isSameActionUrl(action, actionUrl, currentUrl, pathname, search) {
if (action.type === 'modal') {
return actionUrl === currentUrl
}
return (
stripPageActionParams(
actionUrl.split('?')[0],
actionUrl.includes('?') ? actionUrl.split('?')[1] : ''
) === stripPageActionParams(pathname, search)
)
}
// Recursively map actions to AntD Dropdown items
function mapActionsToMenuItems(
actions,
currentUrlWithActions,
id,
objectData,
userProfile,
model,
pathname,
search
userProfile
) {
return cleanDividers(
actions.map((action) => {
if (action.type === 'divider') {
return { type: 'divider' }
}
const actionUrl = buildActionUrl(model, action, id, pathname, search)
const actionUrl = action.url ? action.url(id) : undefined
var disabled = isSameActionUrl(
action,
actionUrl,
currentUrlWithActions,
pathname,
search
)
var disabled = actionUrl && actionUrl === currentUrlWithActions
var visible = true
if (action.disabled) {
@ -142,10 +120,7 @@ function mapActionsToMenuItems(
currentUrlWithActions,
id,
objectData,
userProfile,
model,
pathname,
search
userProfile
)
}
return item
@ -153,6 +128,13 @@ function mapActionsToMenuItems(
)
}
const stripActionParam = (pathname, search) => {
const params = new URLSearchParams(search)
params.delete('action')
const query = params.toString()
return pathname + (query ? `?${query}` : '')
}
const ObjectActions = ({
type,
id,
@ -168,6 +150,11 @@ const ObjectActions = ({
const location = useLocation()
const { showActionsModal } = useActionsModal()
const { userProfile } = useContext(AuthContext)
// Get current url without 'action' param
const currentUrlWithoutActions = stripActionParam(
location.pathname,
location.search
)
// First filter by visibility, then by current URL
const visibilityFilteredActions = filterActionsByVisibility(
@ -176,23 +163,12 @@ const ObjectActions = ({
)
const filteredActions = cleanDividers(
visibilityFilteredActions.filter((action) => {
if (action.type === 'divider') return true
const actionUrl = buildActionUrl(
model,
action,
id,
location.pathname,
location.search
)
return !isSameActionUrl(
action,
actionUrl,
location.pathname + location.search,
location.pathname,
location.search
)
})
visibilityFilteredActions.filter(
(action) =>
action.type === 'divider' ||
typeof action.url !== 'function' ||
action.url(id) !== currentUrlWithoutActions
)
)
const currentUrlWithActions = location.pathname + location.search
@ -204,10 +180,7 @@ const ObjectActions = ({
currentUrlWithActions,
id,
objectData,
userProfile,
model,
location.pathname,
location.search
userProfile
),
onClick: (info) => {
// Find the action by key
@ -222,10 +195,8 @@ const ObjectActions = ({
return null
}
const action = findAction(filteredActions, info.key)
if (action) {
navigate(
buildActionUrl(model, action, id, location.pathname, location.search)
)
if (action && action.url) {
navigate(action.url(id))
}
}
}

View File

@ -4,7 +4,6 @@ import { LoadingOutlined } from '@ant-design/icons'
import { useState, useEffect, useContext, useCallback, useRef } from 'react'
import { useNavigate } from 'react-router-dom'
import { getModelByName } from '../../../database/ObjectModels'
import { buildActionUrl } from '../../../utils/modelActions'
import { ApiServerContext } from '../context/ApiServerContext'
import { AuthContext } from '../context/AuthContext'
import merge from 'lodash/merge'
@ -183,13 +182,7 @@ const ObjectDisplay = ({
const objectId = getStringId(objectData)
if (defaultModelActions.length >= 1 && objectId) {
hyperlink = buildActionUrl(
model,
defaultModelActions[0],
objectId,
'',
''
)
hyperlink = defaultModelActions[0].url(objectId)
}
// Render name with hyperlink/spotlight support

View File

@ -18,7 +18,6 @@ import set from 'lodash/set'
import { getModelByName } from '../../../database/ObjectModels'
import { useLocation, useNavigate } from 'react-router-dom'
import PropTypes from 'prop-types'
import { useActions } from '../context/ActionsContext'
const arrayReplaceCustomizer = (objValue, srcValue) => {
if (Array.isArray(srcValue)) {
@ -87,13 +86,9 @@ const buildObjectFromEntries = (entries = []) => {
* - children: function({
* loading, isEditing, startEditing, cancelEditing, handleUpdate, form, formValid, objectData, setIsEditing, setObjectData
* }) => ReactNode
* - setCurrentObject: boolean (sync object data to ActionsContext)
*/
const ObjectForm = forwardRef(
(
{ id, type, style, children, onEdit, onStateChange, setCurrentObject = false },
ref
) => {
({ id, type, style, children, onEdit, onStateChange }, ref) => {
const [objectData, setObjectData] = useState(null)
const serverObjectData = useRef(null)
const onStateChangeRef = useRef(onStateChange)
@ -123,10 +118,6 @@ const ObjectForm = forwardRef(
flushFile
} = useContext(ApiServerContext)
const { token, userProfile } = useContext(AuthContext)
const {
setCurrentObject: setActionsCurrentObject,
setCurrentObjectType: setActionsCurrentObjectType
} = useActions()
const location = useLocation()
const navigate = useNavigate()
@ -597,32 +588,6 @@ const ObjectForm = forwardRef(
return () => clearTimeout(timeoutId)
}, [objectData])
useEffect(() => {
if (!setCurrentObject) {
return
}
setActionsCurrentObjectType(type)
return () => {
setActionsCurrentObject(null)
setActionsCurrentObjectType(null)
}
}, [
setCurrentObject,
type,
setActionsCurrentObject,
setActionsCurrentObjectType
])
useEffect(() => {
if (!setCurrentObject || !objectData?._id || objectData._id !== id) {
return
}
setActionsCurrentObject(objectData)
}, [setCurrentObject, objectData, id, setActionsCurrentObject])
const startEditing = async () => {
try {
const latestActivities = await fetchObjectActivities(id, type)
@ -849,8 +814,7 @@ ObjectForm.propTypes = {
children: PropTypes.func.isRequired,
style: PropTypes.object,
onEdit: PropTypes.func,
onStateChange: PropTypes.func,
setCurrentObject: PropTypes.bool
onStateChange: PropTypes.func
}
export default ObjectForm

View File

@ -39,11 +39,10 @@ import ObjectCard from './ObjectCard'
import FilterSidebar from './FilterSidebar'
import XMarkIcon from '../../Icons/XMarkIcon'
import CheckIcon from '../../Icons/CheckIcon'
import { useLocation } from 'react-router-dom'
import { useNavigate, useLocation } from 'react-router-dom'
import QuestionCircleIcon from '../../Icons/QuestionCircleIcon'
import { AuthContext } from '../context/AuthContext'
import { ElectronContext } from '../context/ElectronContext'
import { useActions } from '../context/ActionsContext'
import ActionsIcon from '../../Icons/ActionsIcon'
import FilterIcon from '../../Icons/FilterIcon'
import ScrollBox from './ScrollBox'
@ -131,10 +130,10 @@ const ObjectTable = forwardRef(
},
ref
) => {
const { token, userProfile } = useContext(AuthContext)
const { token } = useContext(AuthContext)
const { isElectron } = useContext(ElectronContext)
const { callAction } = useActions()
const onStateChangeRef = useRef(onStateChange)
const { userProfile } = useContext(AuthContext)
useEffect(() => {
onStateChangeRef.current = onStateChange
}, [onStateChange])
@ -148,6 +147,7 @@ const ObjectTable = forwardRef(
clearObjectActivity
} = useContext(ApiServerContext)
const isMobile = useMediaQuery({ maxWidth: 768 })
const navigate = useNavigate()
const location = useLocation()
const {
getPersistedFilter,
@ -292,11 +292,9 @@ const ObjectTable = forwardRef(
) {
return
}
callAction(
action,
{ ...objectData, _user: userProfile },
type
)
if (action.url) {
navigate(action.url(objectData._id))
}
}}
/>
</Tooltip>

View File

@ -6,7 +6,6 @@ import { useContext } from 'react'
import { useNavigate } from 'react-router-dom'
import LogoutIcon from '../../Icons/LogoutIcon'
import { User } from '../../../database/models/User'
import { buildActionUrl } from '../../../utils/modelActions'
import { AuthContext } from '../context/AuthContext'
const { Text } = Typography
@ -30,8 +29,8 @@ const UserProfilePopover = ({ onClose }) => {
const runAction = (action) => {
if (action.name === 'logout') {
logout()
} else if (userProfile?._id) {
const url = buildActionUrl(User, action, userProfile._id, '', '')
} else if (action.url && userProfile?._id) {
const url = action.url(userProfile._id)
navigate(url)
}
onClose?.()

View File

@ -1,222 +0,0 @@
import {
createContext,
Suspense,
useCallback,
useContext,
useEffect,
useRef,
useState
} from 'react'
import PropTypes from 'prop-types'
import { Modal, Spin, Flex } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import { useLocation, useNavigate } from 'react-router-dom'
import { getModelByName } from '../../../database/ObjectModels'
import {
buildActionUrl,
findAction,
getObjectIdFromSearch,
stripModalActionParams
} from '../../../utils/modelActions'
import { AuthContext } from './AuthContext'
const ActionsContext = createContext()
const ActionsProvider = ({ children }) => {
const navigate = useNavigate()
const location = useLocation()
const { userProfile } = useContext(AuthContext)
const [currentObject, setCurrentObject] = useState(null)
const [currentObjectType, setCurrentObjectType] = useState(null)
const [modalAction, setModalAction] = useState(null)
const [onModalOk, setOnModalOk] = useState(null)
const lastHandledAction = useRef(null)
const searchParams = new URLSearchParams(location.search)
const actionName = searchParams.get('action')
const actionObjectType = searchParams.get('actionObjectType')
const clearAction = useCallback(() => {
const nextUrl = stripModalActionParams(location.pathname, location.search)
if (nextUrl !== location.pathname + location.search) {
navigate(nextUrl, { replace: true })
}
setModalAction(null)
lastHandledAction.current = null
}, [location.pathname, location.search, navigate])
const handleModalOk = useCallback(() => {
onModalOk?.()
clearAction()
}, [clearAction, onModalOk])
const callAction = useCallback(
(action, objectData, objectType) => {
setCurrentObject(objectData)
setCurrentObjectType(objectType)
const model = getModelByName(objectType)
const url = buildActionUrl(
model,
action,
objectData._id,
location.pathname,
location.search
)
navigate(url)
},
[location.pathname, location.search, navigate]
)
useEffect(() => {
if (!actionObjectType) return
const model = getModelByName(actionObjectType)
if (!model.pages?.length) return
const onPage = model.pages.some(
(page) => location.pathname === `${model.url}/${page.name}`
)
if (!onPage) return
if (actionName) {
const action = findAction(model, actionName)
if (action?.type === 'modal') return
}
const params = new URLSearchParams(location.search)
params.delete('actionObjectType')
const query = params.toString()
const nextUrl = location.pathname + (query ? `?${query}` : '')
if (nextUrl !== location.pathname + location.search) {
navigate(nextUrl, { replace: true })
}
}, [
actionName,
actionObjectType,
location.pathname,
location.search,
navigate
])
useEffect(() => {
if (!actionName || !actionObjectType) {
setModalAction(null)
lastHandledAction.current = null
return
}
const actionKey = `${actionObjectType}:${actionName}:${location.pathname}${location.search}`
if (lastHandledAction.current === actionKey) return
const model = getModelByName(actionObjectType)
const action = findAction(model, actionName)
if (!action) return
if (action.type === 'modal') {
lastHandledAction.current = actionKey
setModalAction(action)
return
}
if (action.type === 'page') {
const pageName = action.pageName || action.name
const objectId =
getObjectIdFromSearch(actionObjectType, location.search) ||
currentObject?._id
if (!objectId) return
const expectedPath = `${model.url}/${pageName}`
if (location.pathname === expectedPath) {
lastHandledAction.current = actionKey
return
}
lastHandledAction.current = actionKey
const url = buildActionUrl(
model,
action,
objectId,
location.pathname,
location.search
)
navigate(url, { replace: true })
}
}, [
actionName,
actionObjectType,
currentObject,
location.pathname,
location.search,
navigate
])
const modalObjectData = currentObject
? { ...currentObject, _user: userProfile }
: null
const [modelWidth, setModelWidth] = useState(520)
useEffect(() => {
if (modalAction?.modalWidth) {
setModelWidth(modalAction.modalWidth)
}
}, [modalAction?.modalWidth])
const [modalCentered, setModalCentered] = useState(false)
useEffect(() => {
if (modalAction?.modalCentered !== undefined) {
setModalCentered(modalAction.modalCentered)
}
}, [modalAction?.modalCentered])
return (
<ActionsContext.Provider
value={{
currentObject,
currentObjectType,
setCurrentObject,
setCurrentObjectType,
callAction,
clearAction,
setOnModalOk
}}
>
<Modal
open={modalAction != null}
destroyOnHidden={true}
width={modelWidth}
onCancel={clearAction}
footer={null}
centered={modalCentered}
>
<Suspense
fallback={
<Flex
justify='center'
align='center'
style={{
height: modalCentered ? '120px' : '357px',
width: '100%'
}}
>
<Spin indicator={<LoadingOutlined spin />} />
</Flex>
}
>
{modalAction?.content && modalObjectData
? modalAction.content(modalObjectData, { onOk: handleModalOk })
: null}
</Suspense>
</Modal>
{children}
</ActionsContext.Provider>
)
}
ActionsProvider.propTypes = {
children: PropTypes.node.isRequired
}
const useActions = () => useContext(ActionsContext)
// eslint-disable-next-line react-refresh/only-export-components
export { ActionsProvider, ActionsContext, useActions }

View File

@ -12,15 +12,16 @@ import { useLocation, useNavigate } from 'react-router-dom'
import { getModelByName } from '../../../database/ObjectModels'
import { AuthContext } from './AuthContext'
import {
buildActionUrl,
stripActionParams
} from '../../../utils/modelActions'
const ActionsModalContext = createContext()
// Remove action query params from a URL so we don't navigate to the same URL again
const stripActionParam = stripActionParams
// Remove the "action" query param from a URL so we don't navigate to the same URL again
const stripActionParam = (pathname, search) => {
const params = new URLSearchParams(search)
params.delete('action')
const query = params.toString()
return pathname + (query ? `?${query}` : '')
}
// Flatten nested actions (including children) into a single list
const flattenActions = (actions, parentLabel = '') => {
@ -33,10 +34,7 @@ const flattenActions = (actions, parentLabel = '') => {
return
}
const hasUrl =
typeof action.url === 'function' ||
action.type === 'page' ||
action.type === 'modal'
const hasUrl = typeof action.url === 'function'
const hasChildren =
Array.isArray(action.children) && action.children.length > 0
@ -124,13 +122,7 @@ const ActionsModalProvider = ({ children }) => {
if (!action) return true
let disabled = false
const url = buildActionUrl(
getModelByName(context.type),
action,
id,
location.pathname,
location.search
)
const url = action.url ? action.url(id) : undefined
// Match ObjectActions default disabling behaviour
if (url && url === currentUrlWithoutActions) {
@ -182,18 +174,11 @@ const ActionsModalProvider = ({ children }) => {
})
const runAction = (action) => {
if (!action) return
if (!action || typeof action.url !== 'function') return
if (getActionDisabled(action)) return
const { id } = context
const model = getModelByName(context.type)
const targetUrl = buildActionUrl(
model,
action,
id,
location.pathname,
location.search
)
const targetUrl = action.url(id)
if (targetUrl && targetUrl !== '#') {
navigate(targetUrl)
hideActionsModal()

View File

@ -33,7 +33,6 @@ import {
getModelByPrefix,
searchModelsByLabel
} from '../../../database/ObjectModels'
import { buildActionUrl } from '../../../utils/modelActions'
import InfoCircleIcon from '../../Icons/InfoCircleIcon'
import MenuIcon from '../../Icons/MenuIcon'
import { ApiServerContext } from './ApiServerContext'
@ -284,10 +283,11 @@ const SpotlightContent = ({
const getDefaultRowAction = (model) =>
getRowActions(model).find((action) => action.default)
const triggerRowAction = (action, item, model) => {
if (action) {
const triggerRowAction = (action, item) => {
if (action && action.url) {
// Try to get the id (support _id or id)
const itemId = item._id || item.id
const url = buildActionUrl(model, action, itemId, '', '')
const url = action.url(itemId)
if (url && url !== '#') {
if (isElectron) {
openInternalUrl(url)
@ -314,7 +314,7 @@ const SpotlightContent = ({
? getDefaultRowAction(model)
: null
if (defaultAction) {
triggerRowAction(defaultAction, item, model)
triggerRowAction(defaultAction, item)
}
return
}
@ -332,7 +332,7 @@ const SpotlightContent = ({
? getDefaultRowAction(model)
: null
if (defaultAction) {
triggerRowAction(defaultAction, item, model)
triggerRowAction(defaultAction, item)
}
}
return
@ -539,7 +539,7 @@ const SpotlightContent = ({
}
size={'small'}
type={'text'}
onClick={() => triggerRowAction(action, item, model)}
onClick={() => triggerRowAction(action, item)}
/>
))}
{rowActions
@ -556,7 +556,7 @@ const SpotlightContent = ({
}
size={'small'}
type={'text'}
onClick={() => triggerRowAction(action, item, model)}
onClick={() => triggerRowAction(action, item)}
/>
))}
{shortcutText && <Text keyboard>{shortcutText}</Text>}

View File

@ -1,11 +1,3 @@
import { createElement, lazy } from 'react'
const AppPasswordInfo = lazy(
() => import('../../components/Dashboard/Management/AppPasswords/AppPasswordInfo')
)
const RegenerateAppPasswordSecret = lazy(
() => import('../../components/Dashboard/Management/AppPasswords/RegenerateAppPasswordSecret')
)
import AppPasswordIcon from '../../components/Icons/AppPasswordIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -23,20 +15,21 @@ export const AppPassword = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) =>
`/dashboard/management/apppasswords/info?appPasswordId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/apppasswords/info?appPasswordId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -45,21 +38,21 @@ export const AppPassword = {
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/apppasswords/info?appPasswordId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/apppasswords/info?appPasswordId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -67,25 +60,17 @@ export const AppPassword = {
{ type: 'divider' },
{
name: 'regenerateSecret',
type: 'modal',
modalWidth: 520,
label: 'Regenerate Secret',
type: 'button',
row: true,
icon: LockIcon,
url: (_id) =>
`/dashboard/management/apppasswords/info?appPasswordId=${_id}&action=regenerateSecret`,
disabled: (objectData) => {
return objectData?._user?._id != objectData?.user?._id
},
content: (objectData, { onOk } = {}) => {
return createElement(RegenerateAppPasswordSecret, { id: objectData._id, onOk })
}
}
],
pages: [
{
name: 'info',
content: () => createElement(AppPasswordInfo)
}
],
columns: ['_reference', 'name', 'user', 'active', 'createdAt', 'updatedAt'],
filters: [
'_id',

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const ClientInfo = lazy(
() => import('../../components/Dashboard/Sales/Clients/ClientInfo')
)
import ClientIcon from '../../components/Icons/ClientIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -20,40 +15,38 @@ export const Client = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/sales/clients/info?clientId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) => `/dashboard/sales/clients/info?clientId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/sales/clients/info?clientId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/sales/clients/info?clientId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -61,17 +54,11 @@ export const Client = {
{ type: 'divider' },
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
icon: BinIcon,
danger: true
}
],
pages: [
{
name: 'info',
content: () => createElement(ClientInfo)
danger: true,
url: (_id) =>
`/dashboard/sales/clients/info?clientId=${_id}&action=delete`
}
],
columns: [

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const CourierInfo = lazy(
() => import('../../components/Dashboard/Management/Couriers/CourierInfo')
)
import CourierIcon from '../../components/Icons/CourierIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -20,40 +15,39 @@ export const Courier = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/management/couriers/info?courierId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/couriers/info?courierId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/couriers/info?courierId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/couriers/info?courierId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -61,17 +55,11 @@ export const Courier = {
{ type: 'divider' },
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
icon: BinIcon,
danger: true
}
],
pages: [
{
name: 'info',
content: () => createElement(CourierInfo)
danger: true,
url: (_id) =>
`/dashboard/management/couriers/info?courierId=${_id}&action=delete`
}
],
columns: ['_reference', 'name', 'country', 'email', 'website', 'createdAt'],

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const CourierServiceInfo = lazy(
() => import('../../components/Dashboard/Management/CourierServices/CourierServiceInfo')
)
import CourierServiceIcon from '../../components/Icons/CourierServiceIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -20,40 +15,40 @@ export const CourierService = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) =>
`/dashboard/management/courierservices/info?courierServiceId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/courierservices/info?courierServiceId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/courierservices/info?courierServiceId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/courierservices/info?courierServiceId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -61,17 +56,11 @@ export const CourierService = {
{ type: 'divider' },
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
icon: BinIcon,
danger: true
}
],
pages: [
{
name: 'info',
content: () => createElement(CourierServiceInfo)
danger: true,
url: (_id) =>
`/dashboard/management/courierservices/info?courierServiceId=${_id}&action=delete`
}
],
columns: [

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const DocumentJobInfo = lazy(
() => import('../../components/Dashboard/Management/DocumentJobs/DocumentJobInfo')
)
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
@ -20,49 +15,44 @@ export const DocumentJob = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) =>
`/dashboard/management/documentjobs/info?documentJobId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/documentjobs/info?documentJobId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
}
, {
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/documentjobs/info?documentJobId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
],
pages: [
{
name: 'info',
content: () => createElement(DocumentJobInfo)
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/documentjobs/info?documentJobId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
}
],
columns: ['_reference', 'name', 'state', 'createdAt', 'updatedAt'],

View File

@ -1,13 +1,8 @@
import { createElement, lazy } from 'react'
const DocumentPrinterInfo = lazy(
() => import('../../components/Dashboard/Management/DocumentPrinters/DocumentPrinterInfo')
)
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
import DocumentPrinterIcon from '../../components/Icons/DocumentPrinterIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import DocumentPrinterIcon from '../../components/Icons/DocumentPrinterIcon'
export const DocumentPrinter = {
name: 'documentPrinter',
@ -19,49 +14,44 @@ export const DocumentPrinter = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) =>
`/dashboard/management/documentprinters/info?documentPrinterId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/documentprinters/info?documentPrinterId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
}
, {
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/documentprinters/info?documentPrinterId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
],
pages: [
{
name: 'info',
content: () => createElement(DocumentPrinterInfo)
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/documentprinters/info?documentPrinterId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
}
],
columns: [

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const DocumentSizeInfo = lazy(
() => import('../../components/Dashboard/Management/DocumentSizes/DocumentSizeInfo')
)
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
@ -19,49 +14,44 @@ export const DocumentSize = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) =>
`/dashboard/management/documentsizes/info?documentSizeId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/documentsizes/info?documentSizeId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
}
, {
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/documentsizes/info?documentSizeId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
],
pages: [
{
name: 'info',
content: () => createElement(DocumentSizeInfo)
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/documentsizes/info?documentSizeId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
}
],
columns: [

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const DocumentTemplateInfo = lazy(
() => import('../../components/Dashboard/Management/DocumentTemplates/DocumentTemplateInfo')
)
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
@ -28,49 +23,44 @@ export const DocumentTemplate = {
},
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) =>
`/dashboard/management/documenttemplates/info?documentTemplateId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/documenttemplates/info?documentTemplateId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
}
, {
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/documenttemplates/info?documentTemplateId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
],
pages: [
{
name: 'info',
content: () => createElement(DocumentTemplateInfo)
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/documenttemplates/info?documentTemplateId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
}
],
columns: [

View File

@ -1,16 +1,8 @@
import { createElement, lazy } from 'react'
const FilamentInfo = lazy(
() => import('../../components/Dashboard/Management/Filaments/FilamentInfo')
)
const NewFilamentSku = lazy(
() => import('../../components/Dashboard/Management/FilamentSkus/NewFilamentSku')
)
import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import FilamentIcon from '../../components/Icons/FilamentIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import PlusIcon from '../../components/Icons/PlusIcon'
import BinIcon from '../../components/Icons/BinIcon'
@ -24,40 +16,39 @@ export const Filament = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/management/filaments/info?filamentId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/filaments/info?filamentId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/filaments/info?filamentId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/filaments/info?filamentId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -65,36 +56,28 @@ export const Filament = {
{ type: 'divider' },
{
name: 'newFilamentSku',
type: 'modal',
modalWidth: 700,
label: 'New Filament SKU',
type: 'button',
icon: PlusIcon,
url: (_id) =>
`/dashboard/management/filaments/info?filamentId=${_id}&action=newFilamentSku`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
content: (objectData, { onOk } = {}) => {
return createElement(NewFilamentSku, { defaultValues: { filament: objectData }, onOk, reset: true })
}
},
{ type: 'divider' },
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
icon: BinIcon,
danger: true,
url: (_id) =>
`/dashboard/management/filaments/info?filamentId=${_id}&action=delete`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
}
],
pages: [
{
name: 'info',
content: () => createElement(FilamentInfo)
}
],
columns: [
'_reference',
'name',

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const FilamentProfileInfo = lazy(
() => import('../../components/Dashboard/Production/FilamentProfiles/FilamentProfileInfo')
)
import FilamentProfileIcon from '../../components/Icons/FilamentProfileIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -20,57 +15,47 @@ export const FilamentProfile = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) =>
`/dashboard/production/filamentprofiles/info?filamentProfileId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/production/filamentprofiles/info?filamentProfileId=${_id}&action=edit`,
visible: (objectData) => !objectData?._isEditing
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
url: (_id) =>
`/dashboard/production/filamentprofiles/info?filamentProfileId=${_id}&action=finishEdit`,
visible: (objectData) => objectData?._isEditing === true
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/production/filamentprofiles/info?filamentProfileId=${_id}&action=cancelEdit`,
visible: (objectData) => objectData?._isEditing === true
},
{ type: 'divider' },
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
row: true,
icon: BinIcon,
danger: true
}
],
pages: [
{
name: 'info',
content: () => createElement(FilamentProfileInfo)
danger: true,
url: (_id) =>
`/dashboard/production/filamentprofiles/info?filamentProfileId=${_id}&action=delete`
}
],
columns: ['_reference', 'name', 'filamentType', 'filament', 'updatedAt'],

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const FilamentSkuInfo = lazy(
() => import('../../components/Dashboard/Management/FilamentSkus/FilamentSkuInfo')
)
import FilamentSkuIcon from '../../components/Icons/FilamentSkuIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -20,40 +15,40 @@ export const FilamentSku = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) =>
`/dashboard/management/filamentskus/info?filamentSkuId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/filamentskus/info?filamentSkuId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/filamentskus/info?filamentSkuId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/filamentskus/info?filamentSkuId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -61,17 +56,11 @@ export const FilamentSku = {
{ type: 'divider' },
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
icon: BinIcon,
danger: true
}
],
pages: [
{
name: 'info',
content: () => createElement(FilamentSkuInfo)
danger: true,
url: (_id) =>
`/dashboard/management/filamentskus/info?filamentSkuId=${_id}&action=delete`
}
],
columns: [

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const FilamentStockInfo = lazy(
() => import('../../components/Dashboard/Inventory/FilamentStocks/FilamentStockInfo')
)
import FilamentStockIcon from '../../components/Icons/FilamentStockIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
@ -16,18 +11,12 @@ export const FilamentStock = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
}
],
pages: [
{
name: 'info',
content: () => createElement(FilamentStockInfo)
icon: InfoCircleIcon,
url: (_id) =>
`/dashboard/inventory/filamentstocks/info?filamentStockId=${_id}`
}
],
columns: [

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const FileInfo = lazy(
() => import('../../components/Dashboard/Management/Files/FileInfo')
)
import DownloadIcon from '../../components/Icons/DownloadIcon'
import FileIcon from '../../components/Icons/FileIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
@ -21,66 +16,59 @@ export const File = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/management/files/info?fileId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/files/info?fileId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/files/info?fileId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/files/info?fileId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'download',
type: 'page',
pageName: 'info',
label: 'Download',
row: true,
icon: DownloadIcon
icon: DownloadIcon,
url: (_id) =>
`/dashboard/management/files/info?fileId=${_id}&action=download`
},
{ type: 'divider' },
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
icon: BinIcon,
danger: true
}
],
pages: [
{
name: 'info',
content: () => createElement(FileInfo)
danger: true,
url: (_id) =>
`/dashboard/management/files/info?fileId=${_id}&action=delete`
}
],
columns: [

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const GCodeFileInfo = lazy(
() => import('../../components/Dashboard/Production/GCodeFiles/GCodeFileInfo')
)
import DownloadIcon from '../../components/Icons/DownloadIcon'
import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
@ -29,57 +24,50 @@ export const GCodeFile = {
},
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/production/gcodefiles/info?gcodeFileId=${_id}`
},
{
name: 'download',
type: 'page',
pageName: 'info',
label: 'Download',
row: true,
icon: DownloadIcon
icon: DownloadIcon,
url: (_id) =>
`/dashboard/production/gcodefiles/info?gcodeFileId=${_id}&action=download`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/production/gcodefiles/info?gcodeFileId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
}
, {
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
url: (_id) =>
`/dashboard/production/gcodefiles/info?gcodeFileId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
],
pages: [
{
name: 'info',
content: () => createElement(GCodeFileInfo)
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/production/gcodefiles/info?gcodeFileId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
}
],

View File

@ -1,11 +1,3 @@
import { createElement, lazy } from 'react'
const HostInfo = lazy(
() => import('../../components/Dashboard/Management/Hosts/HostInfo')
)
const HostOTP = lazy(
() => import('../../components/Dashboard/Management/Hosts/HostOtp')
)
import HostIcon from '../../components/Icons/HostIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -24,40 +16,40 @@ export const Host = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/management/hosts/info?hostId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/hosts/info?hostId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/hosts/info?hostId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/hosts/info?hostId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -67,27 +59,18 @@ export const Host = {
},
{
name: 'connect',
type: 'modal',
modalWidth: 520,
label: 'Connect',
icon: OTPIcon,
content: (objectData, { onOk } = {}) => {
return createElement(HostOTP, { id: objectData._id, onOk })
}
url: (_id) =>
`/dashboard/management/hosts/info?hostId=${_id}&action=hostOTP`
},
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
icon: BinIcon,
danger: true
}
],
pages: [
{
name: 'info',
content: () => createElement(HostInfo)
danger: true,
url: (_id) =>
`/dashboard/management/hosts/info?hostId=${_id}&action=delete`
}
],
columns: ['_reference', 'name', 'state', 'tags', 'connectedAt'],

View File

@ -1,17 +1,3 @@
import { createElement, lazy } from 'react'
const InvoiceInfo = lazy(
() => import('../../components/Dashboard/Finance/Invoices/InvoiceInfo')
)
const PostInvoice = lazy(
() => import('../../components/Dashboard/Finance/Invoices/PostInvoice')
)
const AcknowledgeInvoice = lazy(
() => import('../../components/Dashboard/Finance/Invoices/AcknowledgeInvoice')
)
const NewPayment = lazy(
() => import('../../components/Dashboard/Finance/Payments/NewPayment')
)
import InvoiceIcon from '../../components/Icons/InvoiceIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
@ -30,19 +16,19 @@ export const Invoice = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/finance/invoices/info?invoiceId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
type: 'button',
icon: EditIcon,
url: (_id) =>
`/dashboard/finance/invoices/info?invoiceId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -52,31 +38,34 @@ export const Invoice = {
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
label: 'Cancel Edit',
type: 'button',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/finance/invoices/info?invoiceId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
label: 'Finish Edit',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/finance/invoices/info?invoiceId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
type: 'button',
icon: BinIcon,
danger: true,
url: (_id) =>
`/dashboard/finance/invoices/info?invoiceId=${_id}&action=delete`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -87,59 +76,47 @@ export const Invoice = {
{ type: 'divider' },
{
name: 'newPayment',
type: 'modal',
modalWidth: 700,
label: 'New Payment',
type: 'button',
icon: PlusIcon,
url: (_id) =>
`/dashboard/finance/invoices/info?invoiceId=${_id}&action=newPayment`,
disabled: (objectData) => {
const allowedStates = ['acknowledged', 'partiallyPaid', 'overdue']
return !allowedStates.includes(objectData?.state?.type)
},
content: (objectData, { onOk } = {}) => {
return createElement(NewPayment, {
defaultValues: {
invoice: objectData,
amount: objectData?.grandTotalAmount
},
onOk,
reset: true
})
}
},
{ type: 'divider' },
{
name: 'post',
type: 'modal',
modalWidth: 520,
label: 'Post',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/finance/invoices/info?invoiceId=${_id}&action=post`,
visible: (objectData) => {
return objectData?.state?.type == 'draft'
},
content: (objectData, { onOk } = {}) => {
return createElement(PostInvoice, { objectData, onOk })
}
},
{
name: 'acknowledge',
type: 'modal',
modalWidth: 520,
label: 'Acknowledge',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/finance/invoices/info?invoiceId=${_id}&action=acknowledge`,
visible: (objectData) => {
return objectData?.state?.type == 'sent'
},
content: (objectData, { onOk } = {}) => {
return createElement(AcknowledgeInvoice, { objectData, onOk })
}
},
{
name: 'cancel',
type: 'page',
pageName: 'info',
label: 'Cancel',
type: 'button',
icon: XMarkIcon,
danger: true,
url: (_id) =>
`/dashboard/finance/invoices/info?invoiceId=${_id}&action=cancel`,
disabled: (objectData) => {
const allowedStates = [
'acknowledged',
@ -154,12 +131,6 @@ export const Invoice = {
}
}
],
pages: [
{
name: 'info',
content: () => createElement(InvoiceInfo)
}
],
group: ['orderType'],
filters: [
'vendor',

View File

@ -1,11 +1,3 @@
import { createElement, lazy } from 'react'
const JobInfo = lazy(
() => import('../../components/Dashboard/Production/Jobs/JobInfo')
)
const DeployJob = lazy(
() => import('../../components/Dashboard/Production/Jobs/DeployJob')
)
import JobIcon from '../../components/Icons/JobIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
@ -24,19 +16,18 @@ export const Job = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/production/jobs/info?jobId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
type: 'button',
icon: EditIcon,
url: (_id) => `/dashboard/production/jobs/info?jobId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -46,31 +37,34 @@ export const Job = {
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
label: 'Cancel Edit',
type: 'button',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/production/jobs/info?jobId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
label: 'Finish Edit',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/production/jobs/info?jobId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
type: 'button',
icon: BinIcon,
danger: true,
url: (_id) =>
`/dashboard/production/jobs/info?jobId=${_id}&action=delete`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -81,26 +75,17 @@ export const Job = {
{ type: 'divider' },
{
name: 'deploy',
type: 'modal',
modalWidth: 680,
label: 'Deploy',
default: true,
row: true,
icon: CheckIcon,
url: (_id) =>
`/dashboard/production/jobs/info?jobId=${_id}&action=deploy`,
disabled: (objectData) => {
return objectData?.state?.type != 'draft'
},
content: (objectData, { onOk } = {}) => {
return createElement(DeployJob, { objectData, onOk })
}
}
],
pages: [
{
name: 'info',
content: () => createElement(JobInfo)
}
],
columns: ['_reference', 'quantity', 'state', 'gcodeFile', 'createdAt'],
filters: [
'state',
@ -111,7 +96,13 @@ export const Job = {
'createdAt',
'updatedAt'
],
sorters: ['createdAt', 'state', 'quantity', 'gcodeFile', 'updatedAt'],
sorters: [
'createdAt',
'state',
'quantity',
'gcodeFile',
'updatedAt'
],
properties: [
{
name: '_id',

View File

@ -1,17 +1,3 @@
import { createElement, lazy } from 'react'
const ListingInfo = lazy(
() => import('../../components/Dashboard/Sales/Listings/ListingInfo')
)
const NewListingVarient = lazy(
() => import('../../components/Dashboard/Sales/ListingVarients/NewListingVarient')
)
const PublishListing = lazy(
() => import('../../components/Dashboard/Sales/Listings/PublishListing')
)
const UnpublishListing = lazy(
() => import('../../components/Dashboard/Sales/Listings/UnpublishListing')
)
import ListingIcon from '../../components/Icons/ListingIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -30,40 +16,39 @@ export const Listing = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/sales/listings/info?listingId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/sales/listings/info?listingId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/sales/listings/info?listingId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/sales/listings/info?listingId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -71,56 +56,44 @@ export const Listing = {
{ type: 'divider' },
{
name: 'newListingVarient',
type: 'modal',
modalWidth: 700,
label: 'New Listing Varient',
type: 'button',
icon: PlusIcon,
content: (objectData, { onOk } = {}) => {
return createElement(NewListingVarient, { defaultValues: { listing: objectData }, onOk, reset: true })
}
url: (_id) =>
`/dashboard/sales/listings/info?listingId=${_id}&action=newListingVarient`
},
{ type: 'divider' },
{
name: 'publish',
type: 'modal',
modalWidth: 520,
label: 'Publish',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/sales/listings/info?listingId=${_id}&action=publish`,
visible: (objectData) =>
objectData?.state?.type === 'draft' ||
objectData?.state?.type === 'inactive',
disabled: (objectData) => objectData?.state?.type === 'syncing',
content: (objectData, { onOk } = {}) => {
return createElement(PublishListing, { objectData, onOk })
}
disabled: (objectData) => objectData?.state?.type === 'syncing'
},
{
name: 'unpublish',
type: 'modal',
modalWidth: 520,
label: 'Unpublish',
type: 'button',
icon: XMarkIcon,
danger: true,
url: (_id) =>
`/dashboard/sales/listings/info?listingId=${_id}&action=unpublish`,
visible: (objectData) => objectData?.state?.type === 'active',
disabled: (objectData) => objectData?.state?.type === 'syncing',
content: (objectData, { onOk } = {}) => {
return createElement(UnpublishListing, { objectData, onOk })
}
disabled: (objectData) => objectData?.state?.type === 'syncing'
},
{ type: 'divider' },
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
icon: BinIcon,
danger: true
}
],
pages: [
{
name: 'info',
content: () => createElement(ListingInfo)
danger: true,
url: (_id) =>
`/dashboard/sales/listings/info?listingId=${_id}&action=delete`
}
],
columns: [

View File

@ -1,14 +1,3 @@
import { createElement, lazy } from 'react'
const ListingVarientInfo = lazy(
() => import('../../components/Dashboard/Sales/ListingVarients/ListingVarientInfo')
)
const PublishListingVarient = lazy(
() => import('../../components/Dashboard/Sales/ListingVarients/PublishListingVarient')
)
const UnpublishListingVarient = lazy(
() => import('../../components/Dashboard/Sales/ListingVarients/UnpublishListingVarient')
)
import ListingVarientIcon from '../../components/Icons/ListingVarientIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -18,7 +7,6 @@ import BinIcon from '../../components/Icons/BinIcon'
export const ListingVarient = {
name: 'listingVarient',
url: '/dashboard/sales/listingvarients',
label: 'Listing Varient',
labelPlural: 'Listing Varients',
prefix: 'LVR',
@ -26,40 +14,40 @@ export const ListingVarient = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) =>
`/dashboard/sales/listingvarients/info?listingVarientId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/sales/listingvarients/info?listingVarientId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/sales/listingvarients/info?listingVarientId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/sales/listingvarients/info?listingVarientId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -67,45 +55,35 @@ export const ListingVarient = {
{ type: 'divider' },
{
name: 'publish',
type: 'modal',
modalWidth: 520,
label: 'Publish',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/sales/listingvarients/info?listingVarientId=${_id}&action=publish`,
visible: (objectData) =>
objectData?.state?.type === 'draft' ||
objectData?.state?.type === 'inactive',
disabled: (objectData) => objectData?.state?.type === 'syncing',
content: (objectData, { onOk } = {}) => {
return createElement(PublishListingVarient, { objectData, onOk })
}
disabled: (objectData) => objectData?.state?.type === 'syncing'
},
{
name: 'unpublish',
type: 'modal',
modalWidth: 520,
label: 'Unpublish',
type: 'button',
icon: XMarkIcon,
danger: true,
url: (_id) =>
`/dashboard/sales/listingvarients/info?listingVarientId=${_id}&action=unpublish`,
visible: (objectData) => objectData?.state?.type === 'active',
disabled: (objectData) => objectData?.state?.type === 'syncing',
content: (objectData, { onOk } = {}) => {
return createElement(UnpublishListingVarient, { objectData, onOk })
}
disabled: (objectData) => objectData?.state?.type === 'syncing'
},
{ type: 'divider' },
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
icon: BinIcon,
danger: true
}
],
pages: [
{
name: 'info',
content: () => createElement(ListingVarientInfo)
danger: true,
url: (_id) =>
`/dashboard/sales/listingvarients/info?listingVarientId=${_id}&action=delete`
}
],
columns: [

View File

@ -1,14 +1,3 @@
import { createElement, lazy } from 'react'
const MarketplaceInfo = lazy(
() => import('../../components/Dashboard/Sales/Marketplaces/MarketplaceInfo')
)
const SyncListings = lazy(
() => import('../../components/Dashboard/Sales/Marketplaces/SyncListings')
)
const SyncOrders = lazy(
() => import('../../components/Dashboard/Sales/Marketplaces/SyncOrders')
)
import MarketplaceIcon from '../../components/Icons/MarketplaceIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -28,40 +17,39 @@ export const Marketplace = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/sales/marketplaces/info?marketplaceId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/sales/marketplaces/info?marketplaceId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/sales/marketplaces/info?marketplaceId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/sales/marketplaces/info?marketplaceId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -69,37 +57,34 @@ export const Marketplace = {
{ type: 'divider' },
{
name: 'syncListings',
type: 'modal',
modalWidth: 520,
label: 'Sync Listings',
type: 'button',
icon: ReloadIcon,
url: (_id) =>
`/dashboard/sales/marketplaces/info?marketplaceId=${_id}&action=syncListings`,
disabled: (objectData) => {
return objectData?.state?.type != 'ready'
},
content: (objectData, { onOk } = {}) => {
return createElement(SyncListings, { objectData, onOk })
}
},
{
name: 'syncOrders',
type: 'modal',
modalWidth: 520,
label: 'Sync Orders',
type: 'button',
icon: ReloadIcon,
url: (_id) =>
`/dashboard/sales/marketplaces/info?marketplaceId=${_id}&action=syncOrders`,
disabled: (objectData) => {
return objectData?.state?.type != 'ready'
},
content: (objectData, { onOk } = {}) => {
return createElement(SyncOrders, { objectData, onOk })
}
},
{ type: 'divider' },
{
name: 'connect',
type: 'page',
pageName: 'info',
label: 'Connect',
type: 'button',
icon: LinkIcon,
url: (_id) =>
`/dashboard/sales/marketplaces/info?marketplaceId=${_id}&action=connect`,
disabled: (objectData) => {
return (
objectData?.state?.type == 'ready' ||
@ -110,20 +95,22 @@ export const Marketplace = {
},
{
name: 'reconnect',
type: 'page',
pageName: 'info',
label: 'Reconnect',
type: 'button',
icon: LinkIcon,
url: (_id) =>
`/dashboard/sales/marketplaces/info?marketplaceId=${_id}&action=reconnect`,
disabled: (objectData) => {
return objectData?.state?.type != 'ready'
}
},
{
name: 'refreshToken',
type: 'page',
pageName: 'info',
label: 'Refresh Token',
type: 'button',
icon: ReloadIcon,
url: (_id) =>
`/dashboard/sales/marketplaces/info?marketplaceId=${_id}&action=refreshToken`,
disabled: (objectData) => {
return objectData?.state?.type != 'ready'
}
@ -131,17 +118,11 @@ export const Marketplace = {
{ type: 'divider' },
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
icon: BinIcon,
danger: true
}
],
pages: [
{
name: 'info',
content: () => createElement(MarketplaceInfo)
danger: true,
url: (_id) =>
`/dashboard/sales/marketplaces/info?marketplaceId=${_id}&action=delete`
}
],
columns: [

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const MaterialInfo = lazy(
() => import('../../components/Dashboard/Management/Materials/MaterialInfo')
)
import MaterialIcon from '../../components/Icons/MaterialIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -20,40 +15,39 @@ export const Material = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/management/materials/info?materialId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/materials/info?materialId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/materials/info?materialId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/materials/info?materialId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -61,17 +55,11 @@ export const Material = {
{ type: 'divider' },
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
icon: BinIcon,
danger: true
}
],
pages: [
{
name: 'info',
content: () => createElement(MaterialInfo)
danger: true,
url: (_id) =>
`/dashboard/management/materials/info?materialId=${_id}&action=delete`
}
],
columns: ['_reference', 'name', 'tags', 'createdAt', 'updatedAt'],

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const NoteTypeInfo = lazy(
() => import('../../components/Dashboard/Management/NoteTypes/NoteTypeInfo')
)
import NoteTypeIcon from '../../components/Icons/NoteTypeIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -19,49 +14,42 @@ export const NoteType = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/management/notetypes/info?noteTypeId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/notetypes/info?noteTypeId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
}
, {
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/notetypes/info?noteTypeId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
],
pages: [
{
name: 'info',
content: () => createElement(NoteTypeInfo)
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/notetypes/info?noteTypeId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
}
],
columns: ['_reference', 'name', 'color', 'active', 'createdAt', 'updatedAt'],

View File

@ -1,14 +1,9 @@
import { createElement, lazy } from 'react'
const OrderItemInfo = lazy(
() => import('../../components/Dashboard/Inventory/OrderItems/OrderItemInfo')
)
import OrderItemIcon from '../../components/Icons/OrderItemIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
import BinIcon from '../../components/Icons/BinIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import BinIcon from '../../components/Icons/BinIcon'
export const OrderItem = {
name: 'orderItem',
@ -20,19 +15,19 @@ export const OrderItem = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/inventory/orderitems/info?orderItemId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
type: 'button',
icon: EditIcon,
url: (_id) =>
`/dashboard/inventory/orderitems/info?orderItemId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -42,31 +37,40 @@ export const OrderItem = {
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
label: 'Cancel Edit',
type: 'button',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/inventory/orderitems/info?orderItemId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
},
disabled: (objectData) => {
return objectData?.state?.type != 'draft'
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
label: 'Finish Edit',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/inventory/orderitems/info?orderItemId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
},
disabled: (objectData) => {
return objectData?.state?.type != 'draft'
}
},
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
type: 'button',
icon: BinIcon,
danger: true,
url: (_id) =>
`/dashboard/inventory/orderitems/info?orderItemId=${_id}&action=delete`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -75,12 +79,6 @@ export const OrderItem = {
}
}
],
pages: [
{
name: 'info',
content: () => createElement(OrderItemInfo)
}
],
group: [],
filters: [
'name',

View File

@ -1,16 +1,8 @@
import { createElement, lazy } from 'react'
const PartInfo = lazy(
() => import('../../components/Dashboard/Management/Parts/PartInfo')
)
const NewPartSku = lazy(
() => import('../../components/Dashboard/Management/PartSkus/NewPartSku')
)
import EditIcon from '../../components/Icons/EditIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import PartIcon from '../../components/Icons/PartIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
import XMarkIcon from '../../components/Icons/XMarkIcon'
import PlusIcon from '../../components/Icons/PlusIcon'
export const Part = {
@ -23,40 +15,39 @@ export const Part = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/management/parts/info?partId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/parts/info?partId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/parts/info?partId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/parts/info?partId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -64,24 +55,16 @@ export const Part = {
{ type: 'divider' },
{
name: 'newPartSku',
type: 'modal',
modalWidth: 700,
label: 'New Part SKU',
type: 'button',
icon: PlusIcon,
url: (_id) =>
`/dashboard/management/parts/info?partId=${_id}&action=newPartSku`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
content: (objectData, { onOk } = {}) => {
return createElement(NewPartSku, { defaultValues: { part: objectData }, onOk, reset: true })
}
}
],
pages: [
{
name: 'info',
content: () => createElement(PartInfo)
}
],
columns: [
'_reference',
'name',

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const PartSkuInfo = lazy(
() => import('../../components/Dashboard/Management/PartSkus/PartSkuInfo')
)
import PartSkuIcon from '../../components/Icons/PartSkuIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -20,40 +15,39 @@ export const PartSku = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/management/partskus/info?partSkuId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/partskus/info?partSkuId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/partskus/info?partSkuId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/partskus/info?partSkuId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -61,17 +55,11 @@ export const PartSku = {
{ type: 'divider' },
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
icon: BinIcon,
danger: true
}
],
pages: [
{
name: 'info',
content: () => createElement(PartSkuInfo)
danger: true,
url: (_id) =>
`/dashboard/management/partskus/info?partSkuId=${_id}&action=delete`
}
],
columns: [

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const PartStockInfo = lazy(
() => import('../../components/Dashboard/Inventory/PartStocks/PartStockInfo')
)
import PartStockIcon from '../../components/Icons/PartStockIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
@ -16,18 +11,11 @@ export const PartStock = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
}
],
pages: [
{
name: 'info',
content: () => createElement(PartStockInfo)
icon: InfoCircleIcon,
url: (_id) => `/dashboard/inventory/partstocks/info?partStockId=${_id}`
}
],
filters: [

View File

@ -1,20 +1,3 @@
import { createElement, lazy } from 'react'
const PaymentInfo = lazy(
() => import('../../components/Dashboard/Finance/Payments/PaymentInfo')
)
const PostPayment = lazy(
() => import('../../components/Dashboard/Finance/Payments/PostPayment')
)
const AuthorisePayment = lazy(
() => import('../../components/Dashboard/Finance/Payments/AuthorisePayment')
)
const DeclinePayment = lazy(
() => import('../../components/Dashboard/Finance/Payments/DeclinePayment')
)
const CancelPayment = lazy(
() => import('../../components/Dashboard/Finance/Payments/CancelPayment')
)
import PaymentIcon from '../../components/Icons/PaymentIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import CheckIcon from '../../components/Icons/CheckIcon'
@ -32,19 +15,19 @@ export const Payment = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/finance/payments/info?paymentId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
type: 'button',
icon: EditIcon,
url: (_id) =>
`/dashboard/finance/payments/info?paymentId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -54,31 +37,34 @@ export const Payment = {
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
label: 'Cancel Edit',
type: 'button',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/finance/payments/info?paymentId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
label: 'Finish Edit',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/finance/payments/info?paymentId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
type: 'button',
icon: BinIcon,
danger: true,
url: (_id) =>
`/dashboard/finance/payments/info?paymentId=${_id}&action=delete`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -89,74 +75,60 @@ export const Payment = {
{ type: 'divider' },
{
name: 'post',
type: 'modal',
modalWidth: 520,
label: 'Post',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/finance/payments/info?paymentId=${_id}&action=post`,
visible: (objectData) => {
return objectData?.state?.type == 'draft'
},
content: (objectData, { onOk } = {}) => {
return createElement(PostPayment, { objectData, onOk })
}
},
{
name: 'authorise',
type: 'modal',
modalWidth: 520,
label: 'Authorise',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/finance/payments/info?paymentId=${_id}&action=authorise`,
disabled: (objectData) => {
return objectData?.state?.type != 'posted'
},
visible: (objectData) => {
return objectData?.state?.type == 'posted'
},
content: (objectData, { onOk } = {}) => {
return createElement(AuthorisePayment, { objectData, onOk })
}
},
{
name: 'decline',
type: 'modal',
modalWidth: 520,
label: 'Decline',
type: 'button',
icon: XMarkIcon,
danger: true,
url: (_id) =>
`/dashboard/finance/payments/info?paymentId=${_id}&action=decline`,
disabled: (objectData) => {
return objectData?.state?.type != 'posted'
},
visible: (objectData) => {
return objectData?.state?.type == 'posted'
},
content: (objectData, { onOk } = {}) => {
return createElement(DeclinePayment, { objectData, onOk })
}
},
{
name: 'cancel',
type: 'modal',
modalWidth: 520,
label: 'Cancel',
type: 'button',
icon: XMarkIcon,
danger: true,
url: (_id) =>
`/dashboard/finance/payments/info?paymentId=${_id}&action=cancel`,
disabled: (objectData) => {
return objectData?.state?.type != 'posted'
},
visible: (objectData) => {
return objectData?.state?.type == 'posted'
},
content: (objectData, { onOk } = {}) => {
return createElement(CancelPayment, { objectData, onOk })
}
}
],
pages: [
{
name: 'info',
content: () => createElement(PaymentInfo)
}
],
group: ['vendor', 'client', 'invoice'],
filters: [
'vendor',

View File

@ -1,17 +1,3 @@
import { createElement, lazy } from 'react'
const PrinterInfo = lazy(
() => import('../../components/Dashboard/Production/Printers/PrinterInfo')
)
const NewPrinterProfile = lazy(
() => import('../../components/Dashboard/Production/PrinterProfiles/NewPrinterProfile')
)
const LoadFilamentStock = lazy(
() => import('../../components/Dashboard/Inventory/FilamentStocks/LoadFilamentStock')
)
const UnloadFilamentStock = lazy(
() => import('../../components/Dashboard/Inventory/FilamentStocks/UnloadFilamentStock')
)
import PrinterIcon from '../../components/Icons/PrinterIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import ReloadIcon from '../../components/Icons/ReloadIcon'
@ -36,13 +22,13 @@ export const Printer = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/production/printers/info?printerId=${_id}`
},
{
name: 'control',
label: 'Control',
@ -52,31 +38,31 @@ export const Printer = {
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/production/printers/info?printerId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/production/printers/info?printerId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/production/printers/info?printerId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -84,13 +70,11 @@ export const Printer = {
{ type: 'divider' },
{
name: 'newPrinterProfile',
type: 'modal',
modalWidth: 700,
label: 'New Printer Profile',
type: 'button',
icon: PlusIcon,
content: (objectData, { onOk } = {}) => {
return createElement(NewPrinterProfile, { defaultValues: { printer: objectData }, onOk, reset: true })
}
url: (_id) =>
`/dashboard/production/printers/info?printerId=${_id}&action=newPrinterProfile`
},
{ type: 'divider' },
{
@ -204,57 +188,35 @@ export const Printer = {
children: [
{
name: 'loadFilamentStock',
type: 'modal',
modalWidth: 700,
label: 'Load Filament Stock',
icon: FilamentStockIcon,
url: (_id) =>
`/dashboard/production/printers/control?printerId=${_id}&action=loadFilamentStock`,
disabled: (objectData) => {
return (
objectData?.state?.type == 'printing' ||
objectData?.state?.type == 'error' ||
objectData?.currentFilamentStock != null
)
},
content: (objectData, { onOk } = {}) => {
return createElement(LoadFilamentStock, {
printer: objectData,
onOk,
reset: false,
filamentStockLoaded: false
})
}
},
{
name: 'unloadFilamentStock',
type: 'modal',
modalWidth: 700,
label: 'Unload Filament Stock',
icon: FilamentStockIcon,
url: (_id) =>
`/dashboard/production/printers/control?printerId=${_id}&action=unloadFilamentStock`,
disabled: (objectData) => {
return (
objectData?.state?.type == 'printing' ||
objectData?.state?.type == 'error' ||
objectData?.currentFilamentStock == null
)
},
content: (objectData, { onOk } = {}) => {
return createElement(UnloadFilamentStock, {
printer: objectData,
onOk,
reset: false,
filamentStockLoaded: false
})
}
}
]
}
],
pages: [
{
name: 'info',
content: () => createElement(PrinterInfo)
}
],
columns: [
'_reference',
'name',

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const PrinterProfileInfo = lazy(
() => import('../../components/Dashboard/Production/PrinterProfiles/PrinterProfileInfo')
)
import PrinterProfileIcon from '../../components/Icons/PrinterProfileIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -285,57 +280,47 @@ export const PrinterProfile = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) =>
`/dashboard/production/printerprofiles/info?printerProfileId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/production/printerprofiles/info?printerProfileId=${_id}&action=edit`,
visible: (objectData) => !objectData?._isEditing
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
url: (_id) =>
`/dashboard/production/printerprofiles/info?printerProfileId=${_id}&action=finishEdit`,
visible: (objectData) => objectData?._isEditing === true
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/production/printerprofiles/info?printerProfileId=${_id}&action=cancelEdit`,
visible: (objectData) => objectData?._isEditing === true
},
{ type: 'divider' },
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
row: true,
icon: BinIcon,
danger: true
}
],
pages: [
{
name: 'info',
content: () => createElement(PrinterProfileInfo)
danger: true,
url: (_id) =>
`/dashboard/production/printerprofiles/info?printerProfileId=${_id}&action=delete`
}
],
columns: [

View File

@ -1,11 +1,3 @@
import { createElement, lazy } from 'react'
const ProductInfo = lazy(
() => import('../../components/Dashboard/Management/Products/ProductInfo')
)
const NewProductSku = lazy(
() => import('../../components/Dashboard/Management/ProductSkus/NewProductSku')
)
import ProductIcon from '../../components/Icons/ProductIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -23,40 +15,39 @@ export const Product = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/management/products/info?productId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/products/info?productId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/products/info?productId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/products/info?productId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -66,24 +57,16 @@ export const Product = {
},
{
name: 'newProductSku',
type: 'modal',
modalWidth: 700,
label: 'New Product SKU',
type: 'button',
icon: PlusIcon,
url: (_id) =>
`/dashboard/management/products/info?productId=${_id}&action=newProductSku`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
content: (objectData, { onOk } = {}) => {
return createElement(NewProductSku, { defaultValues: { product: objectData }, onOk, reset: true })
}
}
],
pages: [
{
name: 'info',
content: () => createElement(ProductInfo)
}
],
columns: [
'_reference',
'name',

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const ProductCategoryInfo = lazy(
() => import('../../components/Dashboard/Management/ProductCategories/ProductCategoryInfo')
)
import ProductCategoryIcon from '../../components/Icons/ProductCategoryIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -21,40 +16,40 @@ export const ProductCategory = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) =>
`/dashboard/management/productcategories/info?productCategoryId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/productcategories/info?productCategoryId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/productcategories/info?productCategoryId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/productcategories/info?productCategoryId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -62,17 +57,11 @@ export const ProductCategory = {
{ type: 'divider' },
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
icon: BinIcon,
danger: true
}
],
pages: [
{
name: 'info',
content: () => createElement(ProductCategoryInfo)
danger: true,
url: (_id) =>
`/dashboard/management/productcategories/info?productCategoryId=${_id}&action=delete`
}
],
columns: ['_reference', 'name', 'createdAt', 'updatedAt'],

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const ProductSkuInfo = lazy(
() => import('../../components/Dashboard/Management/ProductSkus/ProductSkuInfo')
)
import ProductSkuIcon from '../../components/Icons/ProductSkuIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -20,40 +15,39 @@ export const ProductSku = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/management/productskus/info?productSkuId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
row: true,
icon: EditIcon,
url: (_id) =>
`/dashboard/management/productskus/info?productSkuId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
}
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
icon: XMarkIcon,
name: 'finishEdit',
label: 'Save Edits',
icon: CheckIcon,
url: (_id) =>
`/dashboard/management/productskus/info?productSkuId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
icon: CheckIcon,
name: 'cancelEdit',
label: 'Cancel Edits',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/management/productskus/info?productSkuId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
@ -61,17 +55,11 @@ export const ProductSku = {
{ type: 'divider' },
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
icon: BinIcon,
danger: true
}
],
pages: [
{
name: 'info',
content: () => createElement(ProductSkuInfo)
danger: true,
url: (_id) =>
`/dashboard/management/productskus/info?productSkuId=${_id}&action=delete`
}
],
columns: [

View File

@ -1,11 +1,3 @@
import { createElement, lazy } from 'react'
const ProductStockInfo = lazy(
() => import('../../components/Dashboard/Inventory/ProductStocks/ProductStockInfo')
)
const PostProductStock = lazy(
() => import('../../components/Dashboard/Inventory/ProductStocks/PostProductStock')
)
import ProductStockIcon from '../../components/Icons/ProductStockIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -23,19 +15,20 @@ export const ProductStock = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) =>
`/dashboard/inventory/productstocks/info?productStockId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
type: 'button',
icon: EditIcon,
url: (_id) =>
`/dashboard/inventory/productstocks/info?productStockId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -45,31 +38,34 @@ export const ProductStock = {
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
label: 'Cancel Edit',
type: 'button',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/inventory/productstocks/info?productStockId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
label: 'Finish Edit',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/inventory/productstocks/info?productStockId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
type: 'button',
icon: BinIcon,
danger: true,
url: (_id) =>
`/dashboard/inventory/productstocks/info?productStockId=${_id}&action=delete`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -80,24 +76,16 @@ export const ProductStock = {
{ type: 'divider' },
{
name: 'post',
type: 'modal',
modalWidth: 520,
label: 'Post',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/inventory/productstocks/info?productStockId=${_id}&action=post`,
visible: (objectData) => {
return objectData?.state?.type == 'draft'
},
content: (objectData, { onOk } = {}) => {
return createElement(PostProductStock, { objectData, onOk })
}
}
],
pages: [
{
name: 'info',
content: () => createElement(ProductStockInfo)
}
],
filters: [
'productSku',
'state',

View File

@ -1,26 +1,3 @@
import { createElement, lazy } from 'react'
const PurchaseOrderInfo = lazy(
() => import('../../components/Dashboard/Inventory/PurchaseOrders/PurchaseOrderInfo')
)
const NewOrderItem = lazy(
() => import('../../components/Dashboard/Inventory/OrderItems/NewOrderItem')
)
const NewShipment = lazy(
() => import('../../components/Dashboard/Inventory/Shipments/NewShipment')
)
const NewInvoice = lazy(
() => import('../../components/Dashboard/Finance/Invoices/NewInvoice')
)
const PostPurchaseOrder = lazy(
() => import('../../components/Dashboard/Inventory/PurchaseOrders/PostPurchaseOrder')
)
const AcknowledgePurchaseOrder = lazy(
() => import('../../components/Dashboard/Inventory/PurchaseOrders/AcknowledgePurchaseOrder')
)
const CancelPurchaseOrder = lazy(
() => import('../../components/Dashboard/Inventory/PurchaseOrders/CancelPurchaseOrder')
)
import PurchaseOrderIcon from '../../components/Icons/PurchaseOrderIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import PlusIcon from '../../components/Icons/PlusIcon'
@ -39,19 +16,20 @@ export const PurchaseOrder = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) =>
`/dashboard/inventory/purchaseorders/info?purchaseOrderId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
type: 'button',
icon: EditIcon,
url: (_id) =>
`/dashboard/inventory/purchaseorders/info?purchaseOrderId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -61,31 +39,34 @@ export const PurchaseOrder = {
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
label: 'Cancel Edit',
type: 'button',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/inventory/purchaseorders/info?purchaseOrderId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
label: 'Finish Edit',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/inventory/purchaseorders/info?purchaseOrderId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
type: 'button',
icon: BinIcon,
danger: true,
url: (_id) =>
`/dashboard/inventory/purchaseorders/info?purchaseOrderId=${_id}&action=delete`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -95,49 +76,34 @@ export const PurchaseOrder = {
},
{ type: 'divider' },
{
name: 'newOrderItem',
type: 'modal',
modalWidth: 700,
name: 'New Order Item',
label: 'New Order Item',
type: 'button',
icon: PlusIcon,
url: (_id) =>
`/dashboard/inventory/purchaseorders/info?purchaseOrderId=${_id}&action=newOrderItem`,
disabled: (objectData) => {
return objectData?.state?.type != 'draft'
},
content: (objectData, { onOk } = {}) => {
return createElement(NewOrderItem, {
defaultValues: {
order: { _id: objectData._id },
orderType: 'purchaseOrder',
syncAmount: 'itemCost'
},
onOk,
reset: true
})
}
},
{
name: 'newShipment',
type: 'modal',
modalWidth: 700,
name: 'New Shipment',
label: 'New Shipment',
type: 'button',
icon: PlusIcon,
url: (_id) =>
`/dashboard/inventory/purchaseorders/info?purchaseOrderId=${_id}&action=newShipment`,
disabled: (objectData) => {
return objectData?.state?.type != 'draft'
},
content: (objectData, { onOk } = {}) => {
return createElement(NewShipment, {
defaultValues: { orderType: 'purchaseOrder', order: { _id: objectData._id } },
onOk,
reset: true
})
}
},
{
name: 'newInvoice',
type: 'modal',
modalWidth: 700,
name: 'New Invoice',
label: 'New Invoice',
type: 'button',
icon: PlusIcon,
url: (_id) =>
`/dashboard/inventory/purchaseorders/info?purchaseOrderId=${_id}&action=newInvoice`,
disabled: (objectData) => {
const allowedStates = [
'received',
@ -146,13 +112,6 @@ export const PurchaseOrder = {
'partiallyShipped'
]
return !allowedStates.includes(objectData?.state?.type)
},
content: (objectData, { onOk } = {}) => {
return createElement(NewInvoice, {
defaultValues: { orderType: 'purchaseOrder', order: objectData },
onOk,
reset: true
})
}
},
{
@ -160,33 +119,30 @@ export const PurchaseOrder = {
},
{
name: 'post',
type: 'modal',
modalWidth: 520,
label: 'Post',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/inventory/purchaseorders/info?purchaseOrderId=${_id}&action=post`,
visible: (objectData) => {
return objectData?.state?.type == 'draft'
},
content: (objectData, { onOk } = {}) => {
return createElement(PostPurchaseOrder, { objectData, onOk })
}
},
{
name: 'acknowledge',
type: 'modal',
modalWidth: 520,
label: 'Acknowledge',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/inventory/purchaseorders/info?purchaseOrderId=${_id}&action=acknowledge`,
visible: (objectData) => {
return objectData?.state?.type == 'sent'
},
content: (objectData, { onOk } = {}) => {
return createElement(AcknowledgePurchaseOrder, { objectData, onOk })
}
},
{
name: 'complete',
label: 'Complete',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/inventory/shipments/info?shipmentId=${_id}&action=complete`,
@ -199,11 +155,12 @@ export const PurchaseOrder = {
},
{
name: 'cancel',
type: 'modal',
modalWidth: 520,
label: 'Cancel',
type: 'button',
icon: XMarkIcon,
danger: true,
url: (_id) =>
`/dashboard/inventory/purchaseorders/info?purchaseOrderId=${_id}&action=cancel`,
disabled: (objectData) => {
return objectData?.state?.type == 'cancelled'
},
@ -213,18 +170,9 @@ export const PurchaseOrder = {
objectData?.state?.type != 'completed' &&
objectData?.state?.type != 'received'
)
},
content: (objectData, { onOk } = {}) => {
return createElement(CancelPurchaseOrder, { objectData, onOk })
}
}
],
pages: [
{
name: 'info',
content: () => createElement(PurchaseOrderInfo)
}
],
group: ['vendor'],
filters: [
'vendor',

View File

@ -1,26 +1,3 @@
import { createElement, lazy } from 'react'
const SalesOrderInfo = lazy(
() => import('../../components/Dashboard/Sales/SalesOrders/SalesOrderInfo')
)
const NewOrderItem = lazy(
() => import('../../components/Dashboard/Inventory/OrderItems/NewOrderItem')
)
const NewShipment = lazy(
() => import('../../components/Dashboard/Inventory/Shipments/NewShipment')
)
const NewInvoice = lazy(
() => import('../../components/Dashboard/Finance/Invoices/NewInvoice')
)
const PostSalesOrder = lazy(
() => import('../../components/Dashboard/Sales/SalesOrders/PostSalesOrder')
)
const ConfirmSalesOrder = lazy(
() => import('../../components/Dashboard/Sales/SalesOrders/ConfirmSalesOrder')
)
const CancelSalesOrder = lazy(
() => import('../../components/Dashboard/Sales/SalesOrders/CancelSalesOrder')
)
import SalesOrderIcon from '../../components/Icons/SalesOrderIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import PlusIcon from '../../components/Icons/PlusIcon'
@ -39,19 +16,19 @@ export const SalesOrder = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/sales/salesorders/info?salesOrderId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
type: 'button',
icon: EditIcon,
url: (_id) =>
`/dashboard/sales/salesorders/info?salesOrderId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -61,31 +38,34 @@ export const SalesOrder = {
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
label: 'Cancel Edit',
type: 'button',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/sales/salesorders/info?salesOrderId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
label: 'Finish Edit',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/sales/salesorders/info?salesOrderId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
}
},
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
type: 'button',
icon: BinIcon,
danger: true,
url: (_id) =>
`/dashboard/sales/salesorders/info?salesOrderId=${_id}&action=delete`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -95,54 +75,34 @@ export const SalesOrder = {
},
{ type: 'divider' },
{
name: 'newOrderItem',
type: 'modal',
modalWidth: 700,
name: 'New Order Item',
label: 'New Order Item',
type: 'button',
icon: PlusIcon,
url: (_id) =>
`/dashboard/sales/salesorders/info?salesOrderId=${_id}&action=newOrderItem`,
disabled: (objectData) => {
return objectData?.state?.type != 'draft'
},
content: (objectData, { onOk } = {}) => {
return createElement(NewOrderItem, {
defaultValues: {
order: { _id: objectData._id },
orderType: 'salesOrder',
syncAmount: 'itemPrice'
},
onOk,
reset: true
})
}
},
{
name: 'newShipment',
type: 'modal',
modalWidth: 700,
modalCentered: false,
name: 'New Shipment',
label: 'New Shipment',
type: 'button',
icon: PlusIcon,
url: (_id) =>
`/dashboard/sales/salesorders/info?salesOrderId=${_id}&action=newShipment`,
disabled: (objectData) => {
return objectData?.state?.type != 'draft'
},
content: (objectData, { onOk } = {}) => {
return createElement(NewShipment, {
defaultValues: {
orderType: 'salesOrder',
order: { _id: objectData._id }
},
onOk,
reset: true
})
}
},
{
name: 'newInvoice',
type: 'modal',
modalWidth: 700,
modalCentered: false,
name: 'New Invoice',
label: 'New Invoice',
type: 'button',
icon: PlusIcon,
url: (_id) =>
`/dashboard/sales/salesorders/info?salesOrderId=${_id}&action=newInvoice`,
disabled: (objectData) => {
const allowedStates = [
'delivered',
@ -153,50 +113,38 @@ export const SalesOrder = {
'partiallyShipped'
]
return !allowedStates.includes(objectData?.state?.type)
},
content: (objectData, { onOk } = {}) => {
return createElement(NewInvoice, {
defaultValues: { orderType: 'salesOrder', order: objectData },
onOk,
reset: true
})
}
},
{ type: 'divider' },
{
name: 'post',
type: 'modal',
modalWidth: 520,
modalCentered: true,
label: 'Post',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/sales/salesorders/info?salesOrderId=${_id}&action=post`,
visible: (objectData) => {
return objectData?.state?.type == 'draft'
},
content: (objectData, { onOk } = {}) => {
return createElement(PostSalesOrder, { objectData, onOk })
}
},
{
name: 'confirm',
type: 'modal',
modalWidth: 520,
label: 'Confirm',
modalCentered: true,
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/sales/salesorders/info?salesOrderId=${_id}&action=confirm`,
visible: (objectData) => {
return objectData?.state?.type == 'sent'
},
content: (objectData, { onOk } = {}) => {
return createElement(ConfirmSalesOrder, { objectData, onOk })
}
},
{
name: 'complete',
type: 'page',
pageName: 'info',
label: 'Complete',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/sales/salesorders/info?salesOrderId=${_id}&action=complete`,
disabled: (objectData) => {
return objectData?.state?.type != 'delivered'
},
@ -206,11 +154,12 @@ export const SalesOrder = {
},
{
name: 'cancel',
type: 'modal',
modalWidth: 520,
label: 'Cancel',
type: 'button',
icon: XMarkIcon,
danger: true,
url: (_id) =>
`/dashboard/sales/salesorders/info?salesOrderId=${_id}&action=cancel`,
disabled: (objectData) => {
return objectData?.state?.type == 'cancelled'
},
@ -220,18 +169,9 @@ export const SalesOrder = {
objectData?.state?.type != 'completed' &&
objectData?.state?.type != 'delivered'
)
},
content: (objectData, { onOk } = {}) => {
return createElement(CancelSalesOrder, { objectData, onOk })
}
}
],
pages: [
{
name: 'info',
content: () => createElement(SalesOrderInfo)
}
],
group: ['client'],
filters: [
'client',

View File

@ -1,17 +1,3 @@
import { createElement, lazy } from 'react'
const ShipmentInfo = lazy(
() => import('../../components/Dashboard/Inventory/Shipments/ShipmentInfo')
)
const ShipShipment = lazy(
() => import('../../components/Dashboard/Inventory/Shipments/ShipShipment')
)
const ReceiveShipment = lazy(
() => import('../../components/Dashboard/Inventory/Shipments/ReceiveShipment')
)
const CancelShipment = lazy(
() => import('../../components/Dashboard/Inventory/Shipments/CancelShipment')
)
import ShipmentIcon from '../../components/Icons/ShipmentIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
import EditIcon from '../../components/Icons/EditIcon'
@ -29,19 +15,19 @@ export const Shipment = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
icon: InfoCircleIcon,
url: (_id) => `/dashboard/inventory/shipments/info?shipmentId=${_id}`
},
{
name: 'edit',
type: 'page',
pageName: 'info',
label: 'Edit',
type: 'button',
icon: EditIcon,
url: (_id) =>
`/dashboard/inventory/shipments/info?shipmentId=${_id}&action=edit`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -51,31 +37,40 @@ export const Shipment = {
},
{
name: 'cancelEdit',
label: 'Cancel Edits',
type: 'page',
pageName: 'info',
label: 'Cancel Edit',
type: 'button',
icon: XMarkIcon,
url: (_id) =>
`/dashboard/inventory/shipments/info?shipmentId=${_id}&action=cancelEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
},
disabled: (objectData) => {
return objectData?.state?.type != 'draft'
}
},
{
name: 'finishEdit',
label: 'Save Edits',
type: 'page',
pageName: 'info',
label: 'Finish Edit',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/inventory/shipments/info?shipmentId=${_id}&action=finishEdit`,
visible: (objectData) => {
return objectData?._isEditing && objectData?._isEditing == true
},
disabled: (objectData) => {
return objectData?.state?.type != 'draft'
}
},
{
name: 'delete',
type: 'page',
pageName: 'info',
label: 'Delete',
type: 'button',
icon: BinIcon,
danger: true,
url: (_id) =>
`/dashboard/inventory/shipments/info?shipmentId=${_id}&action=delete`,
visible: (objectData) => {
return !(objectData?._isEditing && objectData?._isEditing == true)
},
@ -86,10 +81,11 @@ export const Shipment = {
{ type: 'divider' },
{
name: 'ship',
type: 'modal',
modalWidth: 520,
label: 'Ship',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/inventory/shipments/info?shipmentId=${_id}&action=ship`,
disabled: (objectData) => {
return objectData?.state?.type != 'planned'
},
@ -98,17 +94,15 @@ export const Shipment = {
objectData?.state?.type == 'planned' ||
objectData?.state?.type == 'draft'
)
},
content: (objectData, { onOk } = {}) => {
return createElement(ShipShipment, { objectData, onOk })
}
},
{
name: 'receive',
type: 'modal',
modalWidth: 520,
label: 'Receive',
type: 'button',
icon: CheckIcon,
url: (_id) =>
`/dashboard/inventory/shipments/info?shipmentId=${_id}&action=receive`,
disabled: (objectData) => {
return objectData?.state?.type != 'shipped'
},
@ -117,27 +111,7 @@ export const Shipment = {
objectData?.state?.type == 'shipped' ||
objectData?.state?.type == 'delivered'
)
},
content: (objectData, { onOk } = {}) => {
return createElement(ReceiveShipment, { objectData, onOk })
}
},
{
name: 'cancel',
type: 'modal',
modalWidth: 520,
label: 'Cancel',
icon: CheckIcon,
danger: true,
content: (objectData, { onOk } = {}) => {
return createElement(CancelShipment, { objectData, onOk })
}
}
],
pages: [
{
name: 'info',
content: () => createElement(ShipmentInfo)
}
],
group: [],

View File

@ -1,8 +1,3 @@
import { createElement, lazy } from 'react'
const StockAuditInfo = lazy(
() => import('../../components/Dashboard/Inventory/StockAudits/StockAuditInfo')
)
import StockAuditIcon from '../../components/Icons/StockAuditIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
@ -16,18 +11,11 @@ export const StockAudit = {
actions: [
{
name: 'info',
type: 'page',
pageName: 'info',
label: 'Info',
default: true,
row: true,
icon: InfoCircleIcon
}
],
pages: [
{
name: 'info',
content: () => createElement(StockAuditInfo)
icon: InfoCircleIcon,
url: (_id) => `/dashboard/inventory/stockaudits/info?stockAuditId=${_id}`
}
],
columns: ['_reference', 'state', 'createdAt', 'updatedAt'],

Some files were not shown because too many files have changed in this diff Show More