From 231873515f7dfe19a4cc139eb2fb1276b9b69aca Mon Sep 17 00:00:00 2001 From: Giuseppe Ciotola <30926550+gciotola@users.noreply.github.com> Date: Thu, 30 May 2024 08:55:52 +0200 Subject: [PATCH 1/3] fix: handle new `delivered` status --- packages/app/src/data/dictionaries.ts | 4 +++- packages/app/src/data/status.ts | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/app/src/data/dictionaries.ts b/packages/app/src/data/dictionaries.ts index 3eec526..fcfd8c3 100644 --- a/packages/app/src/data/dictionaries.ts +++ b/packages/app/src/data/dictionaries.ts @@ -9,7 +9,9 @@ export function getShipmentStatusName(status: Shipment['status']): string { packing: 'Packing', ready_to_ship: 'Ready to ship', shipped: 'Shipped', - on_hold: 'On hold' + on_hold: 'On hold', + // @ts-expect-error waiting for new types from SDK + delivered: 'Delivered' } return dictionary[status] diff --git a/packages/app/src/data/status.ts b/packages/app/src/data/status.ts index be5ff16..3966464 100644 --- a/packages/app/src/data/status.ts +++ b/packages/app/src/data/status.ts @@ -58,6 +58,16 @@ export function getDisplayStatus(shipment: Shipment): DisplayStatus { badgeVariant: 'success-solid' } + // @ts-expect-error waiting for new types from SDK + case 'delivered': + return { + status: shipment.status, + label: getShipmentStatusName(shipment.status), + icon: 'check', + color: 'green', + badgeVariant: 'success-solid' + } + default: return { status: shipment.status, From aa3fa48283095defd20cde8231448e04bff74685 Mon Sep 17 00:00:00 2001 From: Giuseppe Ciotola <30926550+gciotola@users.noreply.github.com> Date: Thu, 30 May 2024 14:30:28 +0200 Subject: [PATCH 2/3] fix: update app-elements to v2 --- packages/app/package.json | 4 +- .../components/FormPackingFieldPackages.tsx | 8 +- .../components/ShipmentDetailsContextMenu.tsx | 65 --------------- packages/app/src/components/ShipmentSteps.tsx | 26 +++++- packages/app/src/data/status.ts | 80 ------------------- packages/app/src/hooks/useShipmentToolbar.tsx | 56 +++++++++++++ packages/app/src/mocks/index.ts | 2 +- packages/app/src/mocks/resource.ts | 2 +- packages/app/src/pages/ShipmentDetails.tsx | 6 +- packages/app/tsconfig.node.json | 2 +- pnpm-lock.yaml | 30 +++---- 11 files changed, 104 insertions(+), 177 deletions(-) delete mode 100644 packages/app/src/components/ShipmentDetailsContextMenu.tsx delete mode 100644 packages/app/src/data/status.ts create mode 100644 packages/app/src/hooks/useShipmentToolbar.tsx diff --git a/packages/app/package.json b/packages/app/package.json index f673a23..f8085a7 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -15,8 +15,8 @@ "prepare": "touch ./public/config.local.js" }, "dependencies": { - "@commercelayer/app-elements": "^1.24.3", - "@commercelayer/sdk": "5.37.0", + "@commercelayer/app-elements": "^2.0.2", + "@commercelayer/sdk": "6.3.0", "@hookform/resolvers": "^3.3.4", "lodash": "^4.17.21", "query-string": "^9.0.0", diff --git a/packages/app/src/components/FormPackingFieldPackages.tsx b/packages/app/src/components/FormPackingFieldPackages.tsx index 500d2b4..aa5610e 100644 --- a/packages/app/src/components/FormPackingFieldPackages.tsx +++ b/packages/app/src/components/FormPackingFieldPackages.tsx @@ -9,9 +9,7 @@ import { useCoreSdkProvider, type InputSelectValue } from '@commercelayer/app-elements' -import type { Package } from '@commercelayer/sdk' -import type { QueryParamsList } from '@commercelayer/sdk/lib/cjs/query' -import type { ListResponse } from '@commercelayer/sdk/lib/cjs/resource' +import type { ListResponse, Package, QueryParamsList } from '@commercelayer/sdk' import isEmpty from 'lodash/isEmpty' import { useCallback } from 'react' import { makePackage } from 'src/mocks/resources/packages' @@ -118,7 +116,9 @@ function makePackageQuery( hint?: string ): QueryParamsList { return { - fields: ['id', 'name', 'width', 'length', 'height', 'unit_of_length'], + fields: { + packages: ['id', 'name', 'width', 'length', 'height', 'unit_of_length'] + }, filters: { stock_location_id_eq: stockLocationId, ...(!isEmpty(hint) && { name_cont: hint }) diff --git a/packages/app/src/components/ShipmentDetailsContextMenu.tsx b/packages/app/src/components/ShipmentDetailsContextMenu.tsx deleted file mode 100644 index 6d78d70..0000000 --- a/packages/app/src/components/ShipmentDetailsContextMenu.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import { useTriggerAttribute } from '#hooks/useTriggerAttribute' -import { useViewStatus } from '#hooks/useViewStatus' -import { isMockedId } from '#mocks' -import { - Button, - Dropdown, - DropdownItem, - Icon, - useEditMetadataOverlay -} from '@commercelayer/app-elements' -import type { Shipment } from '@commercelayer/sdk' - -export const ShipmentDetailsContextMenu: React.FC<{ - shipment: Shipment -}> = ({ shipment }) => { - const { trigger } = useTriggerAttribute(shipment.id) - const viewStatus = useViewStatus(shipment) - - const { Overlay: EditMetadataOverlay, show: showEditMetadataOverlay } = - useEditMetadataOverlay() - - const dropdownItems = - viewStatus.contextActions?.map((action) => ( - { - if (action.triggerAttribute === '_create_parcel') { - return - } - - void trigger(action.triggerAttribute) - }} - /> - )) ?? [] - dropdownItems.push( - { - showEditMetadataOverlay() - }} - /> - ) - - return ( - <> - {!isMockedId(shipment.id) && ( - - )} - - - - } - dropdownItems={dropdownItems} - /> - - ) -} diff --git a/packages/app/src/components/ShipmentSteps.tsx b/packages/app/src/components/ShipmentSteps.tsx index fe4fb5e..bee20b1 100644 --- a/packages/app/src/components/ShipmentSteps.tsx +++ b/packages/app/src/components/ShipmentSteps.tsx @@ -1,11 +1,12 @@ -import { getDisplayStatus } from '#data/status' import { useActiveStockTransfers } from '#hooks/useActiveStockTransfers' import { Badge, + getShipmentDisplayStatus, Spacer, Stack, Text, - withSkeletonTemplate + withSkeletonTemplate, + type BadgeProps } from '@commercelayer/app-elements' import type { Shipment } from '@commercelayer/sdk' @@ -15,7 +16,7 @@ interface Props { export const ShipmentSteps = withSkeletonTemplate( ({ shipment }): JSX.Element => { - const displayStatus = getDisplayStatus(shipment) + const displayStatus = getShipmentDisplayStatus(shipment) const activeStockTransfers = useActiveStockTransfers(shipment) return ( @@ -28,7 +29,7 @@ export const ShipmentSteps = withSkeletonTemplate( {shipment.status !== undefined && ( <> - + {displayStatus.label.toUpperCase()} {shipment.status === 'on_hold' && @@ -56,3 +57,20 @@ export const ShipmentSteps = withSkeletonTemplate( ) } ) + +function getBadgeVariant(shipment: Shipment): BadgeProps['variant'] { + switch (shipment.status) { + case 'picking': + case 'ready_to_ship': + case 'on_hold': + return 'warning-solid' + + // @ts-expect-error waiting for new types from SDK + case 'delivered': + case 'shipped': + return 'success-solid' + + default: + return 'secondary-solid' + } +} diff --git a/packages/app/src/data/status.ts b/packages/app/src/data/status.ts deleted file mode 100644 index 3966464..0000000 --- a/packages/app/src/data/status.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { getShipmentStatusName } from '#data/dictionaries' -import type { BadgeProps } from '@commercelayer/app-elements' -import type { StatusIconProps } from '@commercelayer/app-elements/dist/ui/atoms/StatusIcon' -import type { Shipment } from '@commercelayer/sdk' - -interface DisplayStatus { - status: Shipment['status'] - label: string - icon: StatusIconProps['name'] - color: StatusIconProps['background'] - badgeVariant: BadgeProps['variant'] -} - -export function getDisplayStatus(shipment: Shipment): DisplayStatus { - switch (shipment.status) { - case 'picking': - return { - status: shipment.status, - label: getShipmentStatusName(shipment.status), - icon: 'arrowDown', - color: 'orange', - badgeVariant: 'warning-solid' - } - - case 'packing': - return { - status: shipment.status, - label: getShipmentStatusName(shipment.status), - icon: 'package', - color: 'orange', - badgeVariant: 'warning-solid' - } - - case 'ready_to_ship': - return { - status: shipment.status, - label: getShipmentStatusName(shipment.status), - icon: 'arrowUpRight', - color: 'orange', - badgeVariant: 'warning-solid' - } - - case 'on_hold': - return { - status: shipment.status, - label: getShipmentStatusName(shipment.status), - icon: 'hourglass', - color: 'orange', - badgeVariant: 'warning-solid' - } - - case 'shipped': - return { - status: shipment.status, - label: getShipmentStatusName(shipment.status), - icon: 'check', - color: 'green', - badgeVariant: 'success-solid' - } - - // @ts-expect-error waiting for new types from SDK - case 'delivered': - return { - status: shipment.status, - label: getShipmentStatusName(shipment.status), - icon: 'check', - color: 'green', - badgeVariant: 'success-solid' - } - - default: - return { - status: shipment.status, - label: shipment.status, - icon: 'warning', - color: 'gray', - badgeVariant: 'secondary-solid' - } - } -} diff --git a/packages/app/src/hooks/useShipmentToolbar.tsx b/packages/app/src/hooks/useShipmentToolbar.tsx new file mode 100644 index 0000000..4efdc56 --- /dev/null +++ b/packages/app/src/hooks/useShipmentToolbar.tsx @@ -0,0 +1,56 @@ +import { useTriggerAttribute } from '#hooks/useTriggerAttribute' +import { useViewStatus } from '#hooks/useViewStatus' +import { isMockedId } from '#mocks' +import { useEditMetadataOverlay } from '@commercelayer/app-elements' +import type { PageHeadingToolbarProps } from '@commercelayer/app-elements/dist/ui/atoms/PageHeading/PageHeadingToolbar' +import type { Shipment } from '@commercelayer/sdk' +import type { FC } from 'react' + +export function useShipmentToolbar({ shipment }: { shipment: Shipment }): { + props: PageHeadingToolbarProps + /** Components to be mounted in page to supports actions in toolbar props (eg: overlays) */ + Components: FC +} { + const { trigger } = useTriggerAttribute(shipment.id) + const viewStatus = useViewStatus(shipment) + + const { Overlay: EditMetadataOverlay, show: showEditMetadataOverlay } = + useEditMetadataOverlay() + + const dropdownItems = + viewStatus.contextActions?.map((action) => ({ + label: action.label, + onClick: () => { + if (action.triggerAttribute === '_create_parcel') { + return + } + + void trigger(action.triggerAttribute) + } + })) ?? [] + + dropdownItems.push({ + label: 'Set metadata', + onClick: () => { + showEditMetadataOverlay() + } + }) + + return { + Components: () => ( + <> + {!isMockedId(shipment.id) && ( + + )} + + ), + props: { + dropdownItems: [dropdownItems] + } + } +} diff --git a/packages/app/src/mocks/index.ts b/packages/app/src/mocks/index.ts index 90d1001..22d0f0b 100644 --- a/packages/app/src/mocks/index.ts +++ b/packages/app/src/mocks/index.ts @@ -1,4 +1,4 @@ -import type { Resource } from '@commercelayer/sdk/lib/cjs/resource' +import type { Resource } from '@commercelayer/sdk' export * from './resources/customers' export * from './resources/line_items' diff --git a/packages/app/src/mocks/resource.ts b/packages/app/src/mocks/resource.ts index f54f019..4efca3d 100644 --- a/packages/app/src/mocks/resource.ts +++ b/packages/app/src/mocks/resource.ts @@ -1,4 +1,4 @@ -import type { ResourceTypeLock } from '@commercelayer/sdk/lib/cjs/api' +import type { ResourceTypeLock } from '@commercelayer/sdk' interface GenericResource { readonly type: T diff --git a/packages/app/src/pages/ShipmentDetails.tsx b/packages/app/src/pages/ShipmentDetails.tsx index 8bb35de..a515db2 100644 --- a/packages/app/src/pages/ShipmentDetails.tsx +++ b/packages/app/src/pages/ShipmentDetails.tsx @@ -1,11 +1,11 @@ import { ShipmentAddresses } from '#components/ShipmentAddresses' -import { ShipmentDetailsContextMenu } from '#components/ShipmentDetailsContextMenu' import { ShipmentInfo } from '#components/ShipmentInfo' import { ShipmentPackingList } from '#components/ShipmentPackingList' import { ShipmentSteps } from '#components/ShipmentSteps' import { ShipmentTimeline } from '#components/ShipmentTimeline' import { appRoutes } from '#data/routes' import { useShipmentDetails } from '#hooks/useShipmentDetails' +import { useShipmentToolbar } from '#hooks/useShipmentToolbar' import { isMockedId } from '#mocks' import { Button, @@ -35,6 +35,7 @@ export function ShipmentDetails(): JSX.Element { const shipmentId = params?.shipmentId ?? '' const { shipment, isLoading } = useShipmentDetails(shipmentId) + const pageToolbar = useShipmentToolbar({ shipment }) if (shipmentId === undefined || !canUser('read', 'orders')) { return ( @@ -78,7 +79,7 @@ export function ShipmentDetails(): JSX.Element { return ( } + toolbar={pageToolbar.props} title={ {pageTitle} } @@ -109,6 +110,7 @@ export function ShipmentDetails(): JSX.Element { gap='only-top' > + {!isMockedId(shipment.id) && ( diff --git a/packages/app/tsconfig.node.json b/packages/app/tsconfig.node.json index b8afcc8..921f77e 100644 --- a/packages/app/tsconfig.node.json +++ b/packages/app/tsconfig.node.json @@ -6,6 +6,6 @@ "allowSyntheticDefaultImports": true }, "include": [ - "vite.config.ts" + "vite.config.mts" ] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 65a2541..b9f96ba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,11 +27,11 @@ importers: packages/app: dependencies: '@commercelayer/app-elements': - specifier: ^1.24.3 - version: 1.24.3(@commercelayer/sdk@5.37.0)(query-string@9.0.0)(react-dom@18.2.0(react@18.2.0))(react-gtm-module@2.0.11)(react-hook-form@7.51.3(react@18.2.0))(react@18.2.0)(wouter@3.1.2(react@18.2.0)) + specifier: ^2.0.2 + version: 2.0.2(@commercelayer/sdk@6.3.0)(query-string@9.0.0)(react-dom@18.2.0(react@18.2.0))(react-gtm-module@2.0.11)(react-hook-form@7.51.3(react@18.2.0))(react@18.2.0)(wouter@3.1.2(react@18.2.0)) '@commercelayer/sdk': - specifier: 5.37.0 - version: 5.37.0 + specifier: 6.3.0 + version: 6.3.0 '@hookform/resolvers': specifier: ^3.3.4 version: 3.3.4(react-hook-form@7.51.3(react@18.2.0)) @@ -244,11 +244,11 @@ packages: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} - '@commercelayer/app-elements@1.24.3': - resolution: {integrity: sha512-r/qSZHT0D8qK2YtZqA7rUiXC40wcssoBb6p/6YNFNMiGUCwxB4TeU+V4oE9O4cCuRcHYk9chFnaLOfd21t6Fsg==} + '@commercelayer/app-elements@2.0.2': + resolution: {integrity: sha512-uPUBveXw4CTSO4gHgDMCFFkLUNIwdWOBlnfeQ5eVZNA6oEgYK0QXaLHmZiJiQEaUEacVnndkFfMehHAxb/S2Zg==} engines: {node: '>=18', pnpm: '>=7'} peerDependencies: - '@commercelayer/sdk': ^5.x + '@commercelayer/sdk': ^6.x query-string: ^8.2.x react: ^18.2.x react-dom: ^18.2.x @@ -269,9 +269,9 @@ packages: eslint: '>=8.0' typescript: '>=5.0' - '@commercelayer/sdk@5.37.0': - resolution: {integrity: sha512-fx3KUKlb34f1U4OvxlaYaI/R64Jm+Ruh5NpuKqRvu/HE5C967q4jqII36ZXst3YfYz8wrxK2rFl6UZc8jX4W1A==} - engines: {node: '>=16 || ^14.17'} + '@commercelayer/sdk@6.3.0': + resolution: {integrity: sha512-xZn1rJPEod6Nt7u12oAG35iQ2Sf44eaxl4vpZ0nx+uoX+ugZ2wLhngtOF2yCSMb+iTyWmtCRRZrFq8zopuTntg==} + engines: {node: '>=20'} '@emotion/babel-plugin@11.11.0': resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==} @@ -5052,9 +5052,9 @@ snapshots: '@colors/colors@1.5.0': optional: true - '@commercelayer/app-elements@1.24.3(@commercelayer/sdk@5.37.0)(query-string@9.0.0)(react-dom@18.2.0(react@18.2.0))(react-gtm-module@2.0.11)(react-hook-form@7.51.3(react@18.2.0))(react@18.2.0)(wouter@3.1.2(react@18.2.0))': + '@commercelayer/app-elements@2.0.2(@commercelayer/sdk@6.3.0)(query-string@9.0.0)(react-dom@18.2.0(react@18.2.0))(react-gtm-module@2.0.11)(react-hook-form@7.51.3(react@18.2.0))(react@18.2.0)(wouter@3.1.2(react@18.2.0))': dependencies: - '@commercelayer/sdk': 5.37.0 + '@commercelayer/sdk': 6.3.0 '@types/lodash': 4.17.0 '@types/react': 18.2.79 '@types/react-datepicker': 6.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -5113,11 +5113,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - '@commercelayer/sdk@5.37.0': - dependencies: - axios: 1.6.7 - transitivePeerDependencies: - - debug + '@commercelayer/sdk@6.3.0': {} '@emotion/babel-plugin@11.11.0': dependencies: From 863f31f2e17bbebfd19b26ca1b4b570574d16f20 Mon Sep 17 00:00:00 2001 From: Giuseppe Ciotola <30926550+gciotola@users.noreply.github.com> Date: Thu, 30 May 2024 15:39:16 +0200 Subject: [PATCH 3/3] fix: set proper type to QueryParamsList --- packages/app/src/components/FormPackingFieldPackages.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/app/src/components/FormPackingFieldPackages.tsx b/packages/app/src/components/FormPackingFieldPackages.tsx index aa5610e..6b8be0b 100644 --- a/packages/app/src/components/FormPackingFieldPackages.tsx +++ b/packages/app/src/components/FormPackingFieldPackages.tsx @@ -114,11 +114,9 @@ function InputSelectPackages({ function makePackageQuery( stockLocationId: string, hint?: string -): QueryParamsList { +): QueryParamsList { return { - fields: { - packages: ['id', 'name', 'width', 'length', 'height', 'unit_of_length'] - }, + fields: ['id', 'name', 'width', 'length', 'height', 'unit_of_length'], filters: { stock_location_id_eq: stockLocationId, ...(!isEmpty(hint) && { name_cont: hint })