From 8700d1854aa58abe3b38fab3feca0d8ea00de385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 17:17:20 +0200 Subject: [PATCH 001/195] eslint - update .eslintrc to enforce no-unused-vars rule --- .eslintrc.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.eslintrc.json b/.eslintrc.json index d1689baf..6753eb5c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -48,6 +48,14 @@ "import/namespace": 0, "import/default": 0, "import/export": 0, + "@typescript-eslint/no-unused-vars": [ + "error", + { + "argsIgnorePattern": "^_", + "varsIgnorePattern": "^_", + "caughtErrorsIgnorePattern": "^_" + } + ], "no-restricted-imports": [ "error", { From 2147e7a7541af26f706da7d5c45574a8b7a1af47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 17:38:03 +0200 Subject: [PATCH 002/195] chore: update dependencies - install missing @types/lodash --- package.json | 1 + yarn.lock | 25 +++++++------------------ 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index 339f417d..deaa8e97 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "@medusajs/types": "2.10.3", "@medusajs/ui-preset": "2.10.3", "@trivago/prettier-plugin-sort-imports": "^5.2.2", + "@types/lodash": "^4.17.20", "@types/node": "^20.11.15", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", diff --git a/yarn.lock b/yarn.lock index f3619f7f..ed5311dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2985,6 +2985,11 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/lodash@^4.17.20": + version "4.17.20" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.20.tgz#1ca77361d7363432d29f5e55950d9ec1e1c6ea93" + integrity sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA== + "@types/node@^20.11.15": version "20.19.21" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.19.21.tgz#6e5378e04993c40395473b13baf94a09875157b8" @@ -6203,16 +6208,7 @@ stop-iteration-iterator@^1.1.0: es-errors "^1.3.0" internal-slot "^1.1.0" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -6298,14 +6294,7 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== From da8510856a99a77debcbe99803b0c49056767262 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:18:01 +0200 Subject: [PATCH 003/195] eslint/prettier - fix components/authentication/protected-route --- .../authentication/protected-route/index.ts | 2 +- .../protected-route/protected-route.tsx | 27 ++++++++++--------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/components/authentication/protected-route/index.ts b/src/components/authentication/protected-route/index.ts index ca67fd59..825eb371 100644 --- a/src/components/authentication/protected-route/index.ts +++ b/src/components/authentication/protected-route/index.ts @@ -1 +1 @@ -export * from "./protected-route" +export * from "./protected-route"; diff --git a/src/components/authentication/protected-route/protected-route.tsx b/src/components/authentication/protected-route/protected-route.tsx index 94d6bc81..3e226fd2 100644 --- a/src/components/authentication/protected-route/protected-route.tsx +++ b/src/components/authentication/protected-route/protected-route.tsx @@ -1,23 +1,26 @@ -import { Spinner } from "@medusajs/icons" -import { Navigate, Outlet, useLocation } from "react-router-dom" -import { useMe } from "../../../hooks/api/users" -import { SearchProvider } from "../../../providers/search-provider" -import { SidebarProvider } from "../../../providers/sidebar-provider" +import { Spinner } from "@medusajs/icons"; + +import { Navigate, Outlet, useLocation } from "react-router-dom"; + +import { useMe } from "@hooks/api"; + +import { SearchProvider } from "@providers/search-provider"; +import { SidebarProvider } from "@providers/sidebar-provider"; export const ProtectedRoute = () => { - const { user, isLoading } = useMe() - const location = useLocation() + const { user, isLoading } = useMe(); + const location = useLocation(); if (isLoading) { return (
- +
- ) + ); } if (!user) { - return + return ; } return ( @@ -26,5 +29,5 @@ export const ProtectedRoute = () => { - ) -} + ); +}; From 5b4d944859aa2170a99588d885a011a46b295c58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:27:54 +0200 Subject: [PATCH 004/195] eslint/prettier - fix components/common/action-menu --- src/components/common/action-menu/index.ts | 2 +- .../common/actions-button/actions-button.tsx | 37 ++++++++++++++----- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/components/common/action-menu/index.ts b/src/components/common/action-menu/index.ts index a3a827d6..ab05f281 100644 --- a/src/components/common/action-menu/index.ts +++ b/src/components/common/action-menu/index.ts @@ -1 +1 @@ -export * from "./action-menu" +export * from "./action-menu"; diff --git a/src/components/common/actions-button/actions-button.tsx b/src/components/common/actions-button/actions-button.tsx index 313bdbbc..c9460765 100644 --- a/src/components/common/actions-button/actions-button.tsx +++ b/src/components/common/actions-button/actions-button.tsx @@ -1,19 +1,38 @@ -import { Button, DropdownMenu } from "@medusajs/ui" -import { EllipsisHorizontal } from "@medusajs/icons" import { useState } from "react"; -export const ActionsButton = ({actions}: {actions: {label: string, onClick: () => void, icon?: JSX.Element}[]}) => { +import { EllipsisHorizontal } from "@medusajs/icons"; +import { Button, DropdownMenu } from "@medusajs/ui"; + +export const ActionsButton = ({ + actions, +}: { + actions: { label: string; onClick: () => void; icon?: JSX.Element }[]; +}) => { const [open, setOpen] = useState(false); + return ( - + + + - {actions.map(({ label, onClick, icon}) => ( - - {icon}{label} + {actions.map(({ label, onClick, icon }) => ( + + {icon} + {label} ))} - ) -} \ No newline at end of file + ); +}; From d913f6814db296da3a701b42bd83eee568fb2c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:28:18 +0200 Subject: [PATCH 005/195] eslint/prettier - fix components/common/badge-list-summary --- .../badge-list-summary/badge-list-summary.tsx | 31 ++++++++++--------- .../common/badge-list-summary/index.ts | 2 +- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/components/common/badge-list-summary/badge-list-summary.tsx b/src/components/common/badge-list-summary/badge-list-summary.tsx index af4259d1..50c204c3 100644 --- a/src/components/common/badge-list-summary/badge-list-summary.tsx +++ b/src/components/common/badge-list-summary/badge-list-summary.tsx @@ -1,27 +1,28 @@ -import { Badge, Tooltip, clx } from "@medusajs/ui" -import { useTranslation } from "react-i18next" +import { Badge, Tooltip, clx } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; type BadgeListSummaryProps = { /** * Number of initial items to display * @default 2 */ - n?: number + n?: number; /** * List of strings to display as abbreviated list */ - list: string[] + list: string[]; /** * Is the summary displayed inline. * Determines whether the center text is truncated if there is no space in the container */ - inline?: boolean + inline?: boolean; /** * Whether the badges should be rounded */ - rounded?: boolean - className?: string -} + rounded?: boolean; + className?: string; +}; export const BadgeListSummary = ({ list, @@ -30,21 +31,21 @@ export const BadgeListSummary = ({ rounded = false, n = 2, }: BadgeListSummaryProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); const title = t("general.plusCount", { count: list.length - n, - }) + }); return (
{list.slice(0, n).map((item) => { @@ -52,7 +53,7 @@ export const BadgeListSummary = ({ {item} - ) + ); })} {list.length > n && ( @@ -77,5 +78,5 @@ export const BadgeListSummary = ({
)} - ) -} + ); +}; diff --git a/src/components/common/badge-list-summary/index.ts b/src/components/common/badge-list-summary/index.ts index a156dab6..e2c38848 100644 --- a/src/components/common/badge-list-summary/index.ts +++ b/src/components/common/badge-list-summary/index.ts @@ -1 +1 @@ -export * from "./badge-list-summary" +export * from "./badge-list-summary"; From 36e6cbcbdd1cc25d5bc95513813b1c08afaba110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:29:03 +0200 Subject: [PATCH 006/195] eslint/prettier - fix components/common/conditional-tooltip --- .../conditional-tooltip/conditional-tooltip.tsx | 15 ++++++++------- .../common/conditional-tooltip/index.ts | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/components/common/conditional-tooltip/conditional-tooltip.tsx b/src/components/common/conditional-tooltip/conditional-tooltip.tsx index 829da904..13634a92 100644 --- a/src/components/common/conditional-tooltip/conditional-tooltip.tsx +++ b/src/components/common/conditional-tooltip/conditional-tooltip.tsx @@ -1,11 +1,12 @@ -import { Tooltip } from "@medusajs/ui" -import { ComponentPropsWithoutRef, PropsWithChildren } from "react" +import type { ComponentPropsWithoutRef, PropsWithChildren } from "react"; + +import { Tooltip } from "@medusajs/ui"; type ConditionalTooltipProps = PropsWithChildren< ComponentPropsWithoutRef & { - showTooltip?: boolean + showTooltip?: boolean; } -> +>; export const ConditionalTooltip = ({ children, @@ -13,8 +14,8 @@ export const ConditionalTooltip = ({ ...props }: ConditionalTooltipProps) => { if (showTooltip) { - return {children} + return {children}; } - return children -} + return children; +}; diff --git a/src/components/common/conditional-tooltip/index.ts b/src/components/common/conditional-tooltip/index.ts index a5a9ef37..8504d341 100644 --- a/src/components/common/conditional-tooltip/index.ts +++ b/src/components/common/conditional-tooltip/index.ts @@ -1 +1 @@ -export * from "./conditional-tooltip" +export * from "./conditional-tooltip"; From 7585c0716f0ea57e8bbc62c89ba5500e20ae83d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:29:18 +0200 Subject: [PATCH 007/195] eslint/prettier - fix components/common/conditional-tooltip --- .../common/display-id/display-id.tsx | 33 ++++++++++--------- src/components/common/display-id/index.ts | 2 +- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/components/common/display-id/display-id.tsx b/src/components/common/display-id/display-id.tsx index 844dc048..57f123f8 100644 --- a/src/components/common/display-id/display-id.tsx +++ b/src/components/common/display-id/display-id.tsx @@ -1,30 +1,31 @@ -import { useTranslation } from "react-i18next" -import { useState } from "react" -import copy from "copy-to-clipboard" +import { useState } from "react"; -import { clx, toast, Tooltip } from "@medusajs/ui" +import { Tooltip, clx, toast } from "@medusajs/ui"; + +import copy from "copy-to-clipboard"; +import { useTranslation } from "react-i18next"; type DisplayIdProps = { - id: string - className?: string -} + id: string; + className?: string; +}; function DisplayId({ id, className }: DisplayIdProps) { - const { t } = useTranslation() - const [open, setOpen] = useState(false) + const { t } = useTranslation(); + const [open, setOpen] = useState(false); const onClick = () => { - copy(id) - toast.success(t("actions.idCopiedToClipboard")) - } + copy(id); + toast.success(t("actions.idCopiedToClipboard")); + }; return ( - + - ) + ); } -export default DisplayId +export default DisplayId; diff --git a/src/components/common/display-id/index.ts b/src/components/common/display-id/index.ts index c423966f..c985dc21 100644 --- a/src/components/common/display-id/index.ts +++ b/src/components/common/display-id/index.ts @@ -1 +1 @@ -export * from "./display-id" +export * from "./display-id"; From 89777a4aec990a3e29b5442aec881d6030612521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:29:24 +0200 Subject: [PATCH 008/195] eslint/prettier - fix components/common/data-range-display --- .../date-range-display/date-range-display.tsx | 42 ++++++++++--------- .../common/date-range-display/index.ts | 2 +- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/components/common/date-range-display/date-range-display.tsx b/src/components/common/date-range-display/date-range-display.tsx index 738c9d9f..5511eee2 100644 --- a/src/components/common/date-range-display/date-range-display.tsx +++ b/src/components/common/date-range-display/date-range-display.tsx @@ -1,27 +1,29 @@ -import { Text, clx } from "@medusajs/ui" -import { useTranslation } from "react-i18next" -import { useDate } from "../../../hooks/use-date" +import { Text, clx } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; + +import { useDate } from "@hooks/use-date.tsx"; type DateRangeDisplayProps = { - startsAt?: Date | string | null - endsAt?: Date | string | null - showTime?: boolean -} + startsAt?: Date | string | null; + endsAt?: Date | string | null; + showTime?: boolean; +}; export const DateRangeDisplay = ({ startsAt, endsAt, showTime = false, }: DateRangeDisplayProps) => { - const startDate = startsAt ? new Date(startsAt) : null - const endDate = endsAt ? new Date(endsAt) : null + const startDate = startsAt ? new Date(startsAt) : null; + const endDate = endsAt ? new Date(endsAt) : null; - const { t } = useTranslation() - const { getFullDate } = useDate() + const { t } = useTranslation(); + const { getFullDate } = useDate(); return (
-
+
@@ -38,7 +40,7 @@ export const DateRangeDisplay = ({
-
+
@@ -55,19 +57,19 @@ export const DateRangeDisplay = ({
- ) -} + ); +}; const Bar = ({ date }: { date: Date | null }) => { - const now = new Date() + const now = new Date(); - const isDateInFuture = date && date > now + const isDateInFuture = date && date > now; return (
- ) -} + ); +}; diff --git a/src/components/common/date-range-display/index.ts b/src/components/common/date-range-display/index.ts index f703c451..21f0e4f0 100644 --- a/src/components/common/date-range-display/index.ts +++ b/src/components/common/date-range-display/index.ts @@ -1 +1 @@ -export * from "./date-range-display" +export * from "./date-range-display"; From 2951d5a1b11a832ee779a92ea7ab6ed413845943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:31:02 +0200 Subject: [PATCH 009/195] eslint/prettier - fix components/common/customer-info --- .../common/customer-info/customer-info.tsx | 98 +++++++++---------- src/components/common/customer-info/index.ts | 2 +- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/components/common/customer-info/customer-info.tsx b/src/components/common/customer-info/customer-info.tsx index 2c0c82ea..53206b39 100644 --- a/src/components/common/customer-info/customer-info.tsx +++ b/src/components/common/customer-info/customer-info.tsx @@ -1,52 +1,54 @@ -import { Avatar, Copy, Text } from "@medusajs/ui" -import { useTranslation } from "react-i18next" -import { Link } from "react-router-dom" -import { HttpTypes } from "@medusajs/types" -import { getFormattedAddress, isSameAddress } from "../../../lib/addresses" +import type { HttpTypes } from "@medusajs/types"; +import { Avatar, Copy, Text } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; +import { Link } from "react-router-dom"; + +import { getFormattedAddress, isSameAddress } from "@lib/addresses.ts"; const ID = ({ data }: { data: HttpTypes.AdminOrder }) => { - const { t } = useTranslation() + const { t } = useTranslation(); - const id = data.customer_id - const name = getOrderCustomer(data) - const email = data.email - const fallback = (name || email || "").charAt(0).toUpperCase() + const id = data.customer_id; + const name = getOrderCustomer(data); + const email = data.email; + const fallback = (name || email || "").charAt(0).toUpperCase(); return ( -
+
{t("fields.id")}
{name || email}
- ) -} + ); +}; const Company = ({ data }: { data: HttpTypes.AdminOrder }) => { - const { t } = useTranslation() + const { t } = useTranslation(); const company = - data.shipping_address?.company || data.billing_address?.company + data.shipping_address?.company || data.billing_address?.company; if (!company) { - return null + return null; } return ( -
+
{t("fields.company")} @@ -54,17 +56,17 @@ const Company = ({ data }: { data: HttpTypes.AdminOrder }) => { {company}
- ) -} + ); +}; const Contact = ({ data }: { data: HttpTypes.AdminOrder }) => { - const { t } = useTranslation() + const { t } = useTranslation(); - const phone = data.shipping_address?.phone || data.billing_address?.phone - const email = data.email || "" + const phone = data.shipping_address?.phone || data.billing_address?.phone; + const email = data.email || ""; return ( -
+
{t("orders.customer.contactLabel")} @@ -99,8 +101,8 @@ const Contact = ({ data }: { data: HttpTypes.AdminOrder }) => { )}
- ) -} + ); +}; const AddressPrint = ({ address, @@ -108,13 +110,13 @@ const AddressPrint = ({ }: { address: | HttpTypes.AdminOrder["shipping_address"] - | HttpTypes.AdminOrder["billing_address"] - type: "shipping" | "billing" + | HttpTypes.AdminOrder["billing_address"]; + type: "shipping" | "billing"; }) => { - const { t } = useTranslation() + const { t } = useTranslation(); return ( -
+
{type === "shipping" ? t("addresses.shippingAddress.label") @@ -129,7 +131,7 @@ const AddressPrint = ({ {line}
- ) + ); })}
@@ -145,11 +147,11 @@ const AddressPrint = ({ )}
- ) -} + ); +}; const Addresses = ({ data }: { data: HttpTypes.AdminOrder }) => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
@@ -172,8 +174,8 @@ const Addresses = ({ data }: { data: HttpTypes.AdminOrder }) => {
)}
- ) -} + ); +}; export const CustomerInfo = Object.assign( {}, @@ -182,21 +184,19 @@ export const CustomerInfo = Object.assign( Company, Contact, Addresses, - } -) + }, +); const getOrderCustomer = (obj: HttpTypes.AdminOrder) => { const { first_name: sFirstName, last_name: sLastName } = - obj.shipping_address || {} + obj.shipping_address || {}; const { first_name: bFirstName, last_name: bLastName } = - obj.billing_address || {} - const { first_name: cFirstName, last_name: cLastName } = obj.customer || {} - - const customerName = [cFirstName, cLastName].filter(Boolean).join(" ") - const shippingName = [sFirstName, sLastName].filter(Boolean).join(" ") - const billingName = [bFirstName, bLastName].filter(Boolean).join(" ") + obj.billing_address || {}; + const { first_name: cFirstName, last_name: cLastName } = obj.customer || {}; - const name = customerName || shippingName || billingName + const customerName = [cFirstName, cLastName].filter(Boolean).join(" "); + const shippingName = [sFirstName, sLastName].filter(Boolean).join(" "); + const billingName = [bFirstName, bLastName].filter(Boolean).join(" "); - return name -} + return customerName || shippingName || billingName; +}; diff --git a/src/components/common/customer-info/index.ts b/src/components/common/customer-info/index.ts index 892c7d76..6587d519 100644 --- a/src/components/common/customer-info/index.ts +++ b/src/components/common/customer-info/index.ts @@ -1 +1 @@ -export * from "./customer-info" +export * from "./customer-info"; From 5c2d39fa088052ccd5975a5dcd02326b863184ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:31:27 +0200 Subject: [PATCH 010/195] eslint/prettier - fix components/common/chip-group --- .../common/chip-group/chip-group.tsx | 73 ++++++++++--------- src/components/common/chip-group/index.ts | 2 +- 2 files changed, 40 insertions(+), 35 deletions(-) diff --git a/src/components/common/chip-group/chip-group.tsx b/src/components/common/chip-group/chip-group.tsx index 48ed2ef3..7557a0ad 100644 --- a/src/components/common/chip-group/chip-group.tsx +++ b/src/components/common/chip-group/chip-group.tsx @@ -1,33 +1,38 @@ -import { XMarkMini } from "@medusajs/icons" -import { Button, clx } from "@medusajs/ui" -import { Children, PropsWithChildren, createContext, useContext } from "react" -import { useTranslation } from "react-i18next" +import type { PropsWithChildren } from "react"; +import { Children, createContext, useContext } from "react"; -type ChipGroupVariant = "base" | "component" +import { XMarkMini } from "@medusajs/icons"; +import { Button, clx } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; + +type ChipGroupVariant = "base" | "component"; type ChipGroupProps = PropsWithChildren<{ - onClearAll?: () => void - onRemove?: (index: number) => void - variant?: ChipGroupVariant - className?: string -}> + onClearAll?: () => void; + onRemove?: (index: number) => void; + variant?: ChipGroupVariant; + className?: string; +}>; type GroupContextValue = { - onRemove?: (index: number) => void - variant: ChipGroupVariant -} + onRemove?: (index: number) => void; + variant: ChipGroupVariant; +}; -const GroupContext = createContext(null) +const GroupContext = createContext(null); const useGroupContext = () => { - const context = useContext(GroupContext) + const context = useContext(GroupContext); if (!context) { - throw new Error("useGroupContext must be used within a ChipGroup component") + throw new Error( + "useGroupContext must be used within a ChipGroup component", + ); } - return context -} + return context; +}; const Group = ({ onClearAll, @@ -36,9 +41,9 @@ const Group = ({ className, children, }: ChipGroupProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); - const showClearAll = !!onClearAll && Children.count(children) > 0 + const showClearAll = !!onClearAll && Children.count(children) > 0; return ( @@ -62,29 +67,29 @@ const Group = ({ )} - ) -} + ); +}; type ChipProps = PropsWithChildren<{ - index: number - className?: string -}> + index: number; + className?: string; +}>; const Chip = ({ index, className, children }: ChipProps) => { - const { onRemove, variant } = useGroupContext() + const { onRemove, variant } = useGroupContext(); return (
  • - + {children} {!!onRemove && ( @@ -92,20 +97,20 @@ const Chip = ({ index, className, children }: ChipProps) => { onClick={() => onRemove(index)} type="button" className={clx( - "text-ui-fg-muted active:text-ui-fg-subtle transition-fg flex items-center justify-center p-1", + "flex items-center justify-center p-1 text-ui-fg-muted transition-fg active:text-ui-fg-subtle", { "hover:bg-ui-bg-component-hover active:bg-ui-bg-component-pressed": variant === "component", "hover:bg-ui-bg-base-hover active:bg-ui-bg-base-pressed": variant === "base", - } + }, )} > )}
  • - ) -} + ); +}; -export const ChipGroup = Object.assign(Group, { Chip }) +export const ChipGroup = Object.assign(Group, { Chip }); diff --git a/src/components/common/chip-group/index.ts b/src/components/common/chip-group/index.ts index c919f6cc..7dbc8124 100644 --- a/src/components/common/chip-group/index.ts +++ b/src/components/common/chip-group/index.ts @@ -1 +1 @@ -export * from "./chip-group" +export * from "./chip-group"; From e3df544c3852b147ddb2452f02ed0c13462c50c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:38:12 +0200 Subject: [PATCH 011/195] eslint/prettier - fix components/common/empty-table-content --- .../empty-table-content.tsx | 60 ++++++++++--------- .../common/empty-table-content/index.ts | 2 +- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/components/common/empty-table-content/empty-table-content.tsx b/src/components/common/empty-table-content/empty-table-content.tsx index 6c824263..856320b1 100644 --- a/src/components/common/empty-table-content/empty-table-content.tsx +++ b/src/components/common/empty-table-content/empty-table-content.tsx @@ -1,23 +1,25 @@ -import { ExclamationCircle, MagnifyingGlass, PlusMini } from "@medusajs/icons" -import { Button, Text, clx } from "@medusajs/ui" -import React from "react" -import { useTranslation } from "react-i18next" -import { Link } from "react-router-dom" +import type React from "react"; + +import { ExclamationCircle, MagnifyingGlass, PlusMini } from "@medusajs/icons"; +import { Button, Text, clx } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; +import { Link } from "react-router-dom"; export type NoResultsProps = { - title?: string - message?: string - className?: string -} + title?: string; + message?: string; + className?: string; +}; export const NoResults = ({ title, message, className }: NoResultsProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    @@ -30,23 +32,23 @@ export const NoResults = ({ title, message, className }: NoResultsProps) => {
    - ) -} + ); +}; type ActionProps = { action?: { - to: string - label: string - } -} + to: string; + label: string; + }; +}; type NoRecordsProps = { - title?: string - message?: string - className?: string - buttonVariant?: string - icon?: React.ReactNode -} & ActionProps + title?: string; + message?: string; + className?: string; + buttonVariant?: string; + icon?: React.ReactNode; +} & ActionProps; const DefaultButton = ({ action }: ActionProps) => action && ( @@ -55,7 +57,7 @@ const DefaultButton = ({ action }: ActionProps) => {action.label} - ) + ); const TransparentIconLeftButton = ({ action }: ActionProps) => action && ( @@ -64,7 +66,7 @@ const TransparentIconLeftButton = ({ action }: ActionProps) => {action.label} - ) + ); export const NoRecords = ({ title, @@ -74,13 +76,13 @@ export const NoRecords = ({ buttonVariant = "default", icon = , }: NoRecordsProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    @@ -102,5 +104,5 @@ export const NoRecords = ({ )}
    - ) -} + ); +}; diff --git a/src/components/common/empty-table-content/index.ts b/src/components/common/empty-table-content/index.ts index 405e5ca3..93ce125f 100644 --- a/src/components/common/empty-table-content/index.ts +++ b/src/components/common/empty-table-content/index.ts @@ -1 +1 @@ -export * from "./empty-table-content" +export * from "./empty-table-content"; From 09d78fa5eff5665f78b9fb827902de0d92a99f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:41:19 +0200 Subject: [PATCH 012/195] eslint/prettier - fix components/common/file-preview --- .../common/file-preview/file-preview.tsx | 108 +++++++++--------- src/components/common/file-preview/index.ts | 2 +- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/src/components/common/file-preview/file-preview.tsx b/src/components/common/file-preview/file-preview.tsx index e7a2fa83..698a292e 100644 --- a/src/components/common/file-preview/file-preview.tsx +++ b/src/components/common/file-preview/file-preview.tsx @@ -1,6 +1,8 @@ -import { ArrowDownTray, Spinner } from "@medusajs/icons" -import { IconButton, Text } from "@medusajs/ui" -import { ActionGroup, ActionMenu } from "../action-menu" +import { ArrowDownTray, Spinner } from "@medusajs/icons"; +import { IconButton, Text } from "@medusajs/ui"; + +import type { ActionGroup } from "@components/common/action-menu"; +import { ActionMenu } from "@components/common/action-menu"; export const FilePreview = ({ filename, @@ -10,52 +12,50 @@ export const FilePreview = ({ actions, hideThumbnail, }: { - filename: string - url?: string - loading?: boolean - activity?: string - actions?: ActionGroup[] - hideThumbnail?: boolean -}) => { - return ( -
    -
    -
    - {!hideThumbnail && } -
    + filename: string; + url?: string; + loading?: boolean; + activity?: string; + actions?: ActionGroup[]; + hideThumbnail?: boolean; +}) => ( +
    +
    +
    + {!hideThumbnail && } +
    + + {filename} + + + {loading && !!activity && ( - {filename} + {activity} - - {loading && !!activity && ( - - {activity} - - )} -
    + )}
    - - {loading && } - {!loading && actions && } - {!loading && url && ( - - - - - - )}
    + + {loading && } + {!loading && actions && } + {!loading && url && ( + + + + + + )}
    - ) -} +
    +); const FileThumbnail = () => { return ( @@ -70,14 +70,14 @@ const FileThumbnail = () => { d="M20 31.75H4C1.92893 31.75 0.25 30.0711 0.25 28V4C0.25 1.92893 1.92893 0.25 4 0.25H15.9431C16.9377 0.25 17.8915 0.645088 18.5948 1.34835L22.6516 5.4052C23.3549 6.10847 23.75 7.06229 23.75 8.05685V28C23.75 30.0711 22.0711 31.75 20 31.75Z" fill="url(#paint0_linear_6594_388107)" stroke="url(#paint1_linear_6594_388107)" - stroke-width="0.5" + strokeWidth="0.5" /> { y2="32" gradientUnits="userSpaceOnUse" > - - + + { y2="32" gradientUnits="userSpaceOnUse" > - - + + { y2="21.25" gradientUnits="userSpaceOnUse" > - - + + { y2="21.25" gradientUnits="userSpaceOnUse" > - - + + - ) -} + ); +}; diff --git a/src/components/common/file-preview/index.ts b/src/components/common/file-preview/index.ts index 1a365200..cbac03dc 100644 --- a/src/components/common/file-preview/index.ts +++ b/src/components/common/file-preview/index.ts @@ -1 +1 @@ -export * from "./file-preview" +export * from "./file-preview"; From 84a6bf98f2ecb6e483326f21087315af25a7ccf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:41:50 +0200 Subject: [PATCH 013/195] eslint/prettier - fix components/common/file-upload --- .../common/file-upload/file-upload.tsx | 101 +++++++++--------- src/components/common/file-upload/index.ts | 2 +- 2 files changed, 53 insertions(+), 50 deletions(-) diff --git a/src/components/common/file-upload/file-upload.tsx b/src/components/common/file-upload/file-upload.tsx index f05c45ac..213c6e9d 100644 --- a/src/components/common/file-upload/file-upload.tsx +++ b/src/components/common/file-upload/file-upload.tsx @@ -1,20 +1,22 @@ -import { ArrowDownTray } from "@medusajs/icons" -import { Text, clx } from "@medusajs/ui" -import { ChangeEvent, DragEvent, useRef, useState } from "react" +import type { ChangeEvent, DragEvent } from "react"; +import { useRef, useState } from "react"; + +import { ArrowDownTray } from "@medusajs/icons"; +import { Text, clx } from "@medusajs/ui"; export interface FileType { - id: string - url: string - file: File + id: string; + url: string; + file: File; } export interface FileUploadProps { - label: string - multiple?: boolean - hint?: string - hasError?: boolean - formats: string[] - onUploaded: (files: FileType[]) => void + label: string; + multiple?: boolean; + hint?: string; + hasError?: boolean; + formats: string[]; + onUploaded: (files: FileType[]) => void; } export const FileUpload = ({ @@ -25,72 +27,73 @@ export const FileUpload = ({ formats, onUploaded, }: FileUploadProps) => { - const [isDragOver, setIsDragOver] = useState(false) - const inputRef = useRef(null) - const dropZoneRef = useRef(null) + const [isDragOver, setIsDragOver] = useState(false); + const inputRef = useRef(null); + const dropZoneRef = useRef(null); const handleOpenFileSelector = () => { - inputRef.current?.click() - } + inputRef.current?.click(); + }; const handleDragEnter = (event: DragEvent) => { - event.preventDefault() - event.stopPropagation() + event.preventDefault(); + event.stopPropagation(); - const files = event.dataTransfer?.files + const files = event.dataTransfer?.files; if (!files) { - return + return; } - setIsDragOver(true) - } + setIsDragOver(true); + }; const handleDragLeave = (event: DragEvent) => { - event.preventDefault() - event.stopPropagation() + event.preventDefault(); + event.stopPropagation(); if ( !dropZoneRef.current || dropZoneRef.current.contains(event.relatedTarget as Node) ) { - return + return; } - setIsDragOver(false) - } + setIsDragOver(false); + }; const handleUploaded = (files: FileList | null) => { if (!files) { - return + return; } - const fileList = Array.from(files) + const fileList = Array.from(files); const fileObj = fileList.map((file) => { - const id = Math.random().toString(36).substring(7) + const id = Math.random().toString(36).substring(7); + + const previewUrl = URL.createObjectURL(file); - const previewUrl = URL.createObjectURL(file) return { id: id, url: previewUrl, file, - } - }) + }; + }); - onUploaded(fileObj) - } + onUploaded(fileObj); + }; const handleDrop = (event: DragEvent) => { - event.preventDefault() - event.stopPropagation() + event.preventDefault(); + event.stopPropagation(); - setIsDragOver(false) + setIsDragOver(false); - handleUploaded(event.dataTransfer?.files) - } + handleUploaded(event.dataTransfer?.files); + }; const handleFileChange = async (event: ChangeEvent) => { - handleUploaded(event.target.files) - } + handleUploaded(event.target.files); + }; return (
    @@ -103,16 +106,16 @@ export const FileUpload = ({ onDragEnter={handleDragEnter} onDragLeave={handleDragLeave} className={clx( - "bg-ui-bg-component border-ui-border-strong transition-fg group flex w-full flex-col items-center gap-y-2 rounded-lg border border-dashed p-8", + "group flex w-full flex-col items-center gap-y-2 rounded-lg border border-dashed border-ui-border-strong bg-ui-bg-component p-8 transition-fg", "hover:border-ui-border-interactive focus:border-ui-border-interactive", - "focus:shadow-borders-focus outline-none focus:border-solid", + "outline-none focus:border-solid focus:shadow-borders-focus", { "!border-ui-border-error": hasError, "!border-ui-border-interactive": isDragOver, - } + }, )} > -
    +
    {label}
    @@ -135,5 +138,5 @@ export const FileUpload = ({ multiple={multiple} />
    - ) -} + ); +}; diff --git a/src/components/common/file-upload/index.ts b/src/components/common/file-upload/index.ts index 622ec7e6..b64999d1 100644 --- a/src/components/common/file-upload/index.ts +++ b/src/components/common/file-upload/index.ts @@ -1 +1 @@ -export * from "./file-upload" +export * from "./file-upload"; From 4c92ff69d734fc5950bd71ed1ff897ebe4397fd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:42:24 +0200 Subject: [PATCH 014/195] eslint/prettier - fix components/common/form --- src/components/common/form/form.tsx | 129 ++++++++++++++-------------- 1 file changed, 63 insertions(+), 66 deletions(-) diff --git a/src/components/common/form/form.tsx b/src/components/common/form/form.tsx index 2e7fbf05..419c8983 100644 --- a/src/components/common/form/form.tsx +++ b/src/components/common/form/form.tsx @@ -1,46 +1,43 @@ -import { InformationCircleSolid } from "@medusajs/icons" +import type { ReactNode } from "react"; +import type React from "react"; +import { createContext, forwardRef, useContext, useId } from "react"; + +import { InformationCircleSolid } from "@medusajs/icons"; import { Hint as HintComponent, Label as LabelComponent, Text, Tooltip, clx, -} from "@medusajs/ui" -import { Label as RadixLabel, Slot } from "radix-ui" -import React, { - ReactNode, - createContext, - forwardRef, - useContext, - useId, -} from "react" +} from "@medusajs/ui"; + +import type { Label as RadixLabel } from "radix-ui"; +import { Slot } from "radix-ui"; +import type { ControllerProps, FieldPath, FieldValues } from "react-hook-form"; import { Controller, - ControllerProps, - FieldPath, - FieldValues, FormProvider, useFormContext, useFormState, -} from "react-hook-form" -import { useTranslation } from "react-i18next" +} from "react-hook-form"; +import { useTranslation } from "react-i18next"; -const Provider = FormProvider +const Provider = FormProvider; type FormFieldContextValue< TFieldValues extends FieldValues = FieldValues, - TName extends FieldPath = FieldPath + TName extends FieldPath = FieldPath, > = { - name: TName -} + name: TName; +}; const FormFieldContext = createContext( - {} as FormFieldContextValue -) + {} as FormFieldContextValue, +); const Field = < TFieldValues extends FieldValues = FieldValues, - TName extends FieldPath = FieldPath + TName extends FieldPath = FieldPath, >({ ...props }: ControllerProps) => { @@ -48,30 +45,30 @@ const Field = < - ) -} + ); +}; type FormItemContextValue = { - id: string -} + id: string; +}; const FormItemContext = createContext( - {} as FormItemContextValue -) + {} as FormItemContextValue, +); const useFormField = () => { - const fieldContext = useContext(FormFieldContext) - const itemContext = useContext(FormItemContext) - const { getFieldState } = useFormContext() + const fieldContext = useContext(FormFieldContext); + const itemContext = useContext(FormItemContext); + const { getFieldState } = useFormContext(); - const formState = useFormState({ name: fieldContext.name }) - const fieldState = getFieldState(fieldContext.name, formState) + const formState = useFormState({ name: fieldContext.name }); + const fieldState = getFieldState(fieldContext.name, formState); if (!fieldContext) { - throw new Error("useFormField should be used within a FormField") + throw new Error("useFormField should be used within a FormField"); } - const { id } = itemContext + const { id } = itemContext; return { id, @@ -81,12 +78,12 @@ const useFormField = () => { formDescriptionId: `${id}-form-item-description`, formErrorMessageId: `${id}-form-item-message`, ...fieldState, - } -} + }; +}; const Item = forwardRef>( ({ className, ...props }, ref) => { - const id = useId() + const id = useId(); return ( @@ -96,21 +93,21 @@ const Item = forwardRef>( {...props} /> - ) - } -) -Item.displayName = "Form.Item" + ); + }, +); +Item.displayName = "Form.Item"; const Label = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef & { - optional?: boolean - tooltip?: ReactNode - icon?: ReactNode + optional?: boolean; + tooltip?: ReactNode; + icon?: ReactNode; } >(({ className, optional = false, tooltip, icon, ...props }, ref) => { - const { formLabelId, formItemId } = useFormField() - const { t } = useTranslation() + const { formLabelId, formItemId } = useFormField(); + const { t } = useTranslation(); return (
    @@ -135,9 +132,9 @@ const Label = forwardRef< )}
    - ) -}) -Label.displayName = "Form.Label" + ); +}); +Label.displayName = "Form.Label"; const Control = forwardRef< React.ElementRef, @@ -149,7 +146,7 @@ const Control = forwardRef< formDescriptionId, formErrorMessageId, formLabelId, - } = useFormField() + } = useFormField(); return ( - ) -}) -Control.displayName = "Form.Control" + ); +}); +Control.displayName = "Form.Control"; const Hint = forwardRef< HTMLParagraphElement, React.HTMLAttributes >(({ className, ...props }, ref) => { - const { formDescriptionId } = useFormField() + const { formDescriptionId } = useFormField(); return ( - ) -}) -Hint.displayName = "Form.Hint" + ); +}); +Hint.displayName = "Form.Hint"; const ErrorMessage = forwardRef< HTMLParagraphElement, React.HTMLAttributes >(({ className, children, ...props }, ref) => { - const { error, formErrorMessageId } = useFormField() - const msg = error ? String(error?.message) : children + const { error, formErrorMessageId } = useFormField(); + const msg = error ? String(error?.message) : children; if (!msg || msg === "undefined") { - return null + return null; } return ( @@ -206,9 +203,9 @@ const ErrorMessage = forwardRef< > {msg} - ) -}) -ErrorMessage.displayName = "Form.ErrorMessage" + ); +}); +ErrorMessage.displayName = "Form.ErrorMessage"; const Form = Object.assign(Provider, { Item, @@ -217,6 +214,6 @@ const Form = Object.assign(Provider, { Hint, ErrorMessage, Field, -}) +}); -export { Form } +export { Form }; From 9c5e9aca7a972e4ced0bc6ebcab09a081c51eea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:45:03 +0200 Subject: [PATCH 015/195] eslint/prettier - fix components/common/icon-avatar --- .../common/icon-avatar/icon-avatar.tsx | 51 +++++++++---------- src/components/common/icon-avatar/index.ts | 2 +- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/components/common/icon-avatar/icon-avatar.tsx b/src/components/common/icon-avatar/icon-avatar.tsx index 9d5cdc3e..f5b34c34 100644 --- a/src/components/common/icon-avatar/icon-avatar.tsx +++ b/src/components/common/icon-avatar/icon-avatar.tsx @@ -1,10 +1,11 @@ -import { clx } from "@medusajs/ui" -import { PropsWithChildren } from "react" +import type { PropsWithChildren } from "react"; + +import { clx } from "@medusajs/ui"; type IconAvatarProps = PropsWithChildren<{ - className?: string - size?: "small" | "large" | "xlarge" -}> + className?: string; + size?: "small" | "large" | "xlarge"; +}>; /** * Use this component when a design calls for an avatar with an icon. @@ -15,24 +16,22 @@ export const IconAvatar = ({ size = "small", children, className, -}: IconAvatarProps) => { - return ( -
    div]:bg-ui-bg-field [&>div]:text-ui-fg-subtle [&>div]:flex [&>div]:size-6 [&>div]:items-center [&>div]:justify-center", - { - "size-7 rounded-md [&>div]:size-6 [&>div]:rounded-[4px]": - size === "small", - "size-10 rounded-lg [&>div]:size-9 [&>div]:rounded-[6px]": - size === "large", - "size-12 rounded-xl [&>div]:size-11 [&>div]:rounded-[10px]": - size === "xlarge", - }, - className - )} - > -
    {children}
    -
    - ) -} +}: IconAvatarProps) => ( +
    div]:flex [&>div]:size-6 [&>div]:items-center [&>div]:justify-center [&>div]:bg-ui-bg-field [&>div]:text-ui-fg-subtle", + { + "size-7 rounded-md [&>div]:size-6 [&>div]:rounded-[4px]": + size === "small", + "size-10 rounded-lg [&>div]:size-9 [&>div]:rounded-[6px]": + size === "large", + "size-12 rounded-xl [&>div]:size-11 [&>div]:rounded-[10px]": + size === "xlarge", + }, + className, + )} + > +
    {children}
    +
    +); diff --git a/src/components/common/icon-avatar/index.ts b/src/components/common/icon-avatar/index.ts index ee6f4861..ab1c1be2 100644 --- a/src/components/common/icon-avatar/index.ts +++ b/src/components/common/icon-avatar/index.ts @@ -1 +1 @@ -export * from "./icon-avatar" +export * from "./icon-avatar"; From 7bd5a29307fef428bed907620d57612680eca0b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:45:52 +0200 Subject: [PATCH 016/195] eslint/prettier - fix components/common/infinite-list --- src/components/common/infinite-list/index.ts | 2 +- .../common/infinite-list/infinite-list.tsx | 92 ++++++++++--------- 2 files changed, 50 insertions(+), 44 deletions(-) diff --git a/src/components/common/infinite-list/index.ts b/src/components/common/infinite-list/index.ts index c60bfb6b..06265b70 100644 --- a/src/components/common/infinite-list/index.ts +++ b/src/components/common/infinite-list/index.ts @@ -1 +1 @@ -export * from "./infinite-list" +export * from "./infinite-list"; diff --git a/src/components/common/infinite-list/infinite-list.tsx b/src/components/common/infinite-list/infinite-list.tsx index c2a7cf07..da9351e3 100644 --- a/src/components/common/infinite-list/infinite-list.tsx +++ b/src/components/common/infinite-list/infinite-list.tsx @@ -1,17 +1,21 @@ -import { QueryKey, useInfiniteQuery } from "@tanstack/react-query" -import { ReactNode, useEffect, useMemo, useRef } from "react" -import { toast } from "@medusajs/ui" -import { Spinner } from "@medusajs/icons" +import type { ReactNode } from "react"; +import { useEffect, useMemo, useRef } from "react"; + +import { Spinner } from "@medusajs/icons"; +import { toast } from "@medusajs/ui"; + +import type { QueryKey } from "@tanstack/react-query"; +import { useInfiniteQuery } from "@tanstack/react-query"; type InfiniteListProps = { - queryKey: QueryKey - queryFn: (params: TParams) => Promise - queryOptions?: { enabled?: boolean } - renderItem: (item: TEntity) => ReactNode - renderEmpty: () => ReactNode - responseKey: keyof TResponse - pageSize?: number -} + queryKey: QueryKey; + queryFn: (params: TParams) => Promise; + queryOptions?: { enabled?: boolean }; + renderItem: (item: TEntity) => ReactNode; + renderEmpty: () => ReactNode; + responseKey: keyof TResponse; + pageSize?: number; +}; export const InfiniteList = < TResponse extends { count: number; offset: number; limit: number }, @@ -41,34 +45,36 @@ export const InfiniteList = < return await queryFn({ limit: pageSize, offset: pageParam, - } as TParams) + } as TParams); }, initialPageParam: 0, maxPages: 5, getNextPageParam: (lastPage) => { - const moreItemsExist = lastPage.count > lastPage.offset + lastPage.limit - return moreItemsExist ? lastPage.offset + lastPage.limit : undefined + const moreItemsExist = lastPage.count > lastPage.offset + lastPage.limit; + + return moreItemsExist ? lastPage.offset + lastPage.limit : undefined; }, getPreviousPageParam: (firstPage) => { - const moreItemsExist = firstPage.offset !== 0 + const moreItemsExist = firstPage.offset !== 0; + return moreItemsExist ? Math.max(firstPage.offset - firstPage.limit, 0) - : undefined + : undefined; }, ...queryOptions, - }) + }); const items = useMemo(() => { - return data?.pages.flatMap((p) => p[responseKey] as TEntity[]) ?? [] - }, [data, responseKey]) + return data?.pages.flatMap((p) => p[responseKey] as TEntity[]) ?? []; + }, [data, responseKey]); - const parentRef = useRef(null) - const startObserver = useRef() - const endObserver = useRef() + const parentRef = useRef(null); + const startObserver = useRef(); + const endObserver = useRef(); useEffect(() => { if (isPending) { - return + return; } // Define the new observers after we stop fetching @@ -77,41 +83,41 @@ export const InfiniteList = < startObserver.current = new IntersectionObserver( (entries) => { if (entries[0].isIntersecting && hasPreviousPage) { - startObserver.current?.disconnect() - fetchPreviousPage() + startObserver.current?.disconnect(); + fetchPreviousPage(); } }, { threshold: 0.5, - } - ) + }, + ); endObserver.current = new IntersectionObserver( (entries) => { if (entries[0].isIntersecting && hasNextPage) { - endObserver.current?.disconnect() - fetchNextPage() + endObserver.current?.disconnect(); + fetchNextPage(); } }, { threshold: 0.5, - } - ) + }, + ); // Register the new observers to observe the new first and last children if (parentRef.current?.firstChild) { - startObserver.current?.observe(parentRef.current.firstChild as Element) + startObserver.current?.observe(parentRef.current.firstChild as Element); } if (parentRef.current?.lastChild) { - endObserver.current?.observe(parentRef.current.lastChild as Element) + endObserver.current?.observe(parentRef.current.lastChild as Element); } } // Clear the old observers return () => { - startObserver.current?.disconnect() - endObserver.current?.disconnect() - } + startObserver.current?.disconnect(); + endObserver.current?.disconnect(); + }; }, [ fetchNextPage, fetchPreviousPage, @@ -119,20 +125,20 @@ export const InfiniteList = < hasPreviousPage, isFetching, isPending, - ]) + ]); useEffect(() => { if (error) { - toast.error(error.message) + toast.error(error.message); } - }, [error]) + }, [error]); if (isPending) { return (
    - ) + ); } return ( @@ -147,5 +153,5 @@ export const InfiniteList = <
    )}
    - ) -} + ); +}; From 06674ddc0fda37d4449a14bbd6f3f4486905e154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:47:58 +0200 Subject: [PATCH 017/195] eslint/prettier - fix components/common/json-view-section --- .../common/json-view-section/index.ts | 2 +- .../json-view-section/json-view-section.tsx | 85 +++++++++---------- 2 files changed, 43 insertions(+), 44 deletions(-) diff --git a/src/components/common/json-view-section/index.ts b/src/components/common/json-view-section/index.ts index be52949a..51f597db 100644 --- a/src/components/common/json-view-section/index.ts +++ b/src/components/common/json-view-section/index.ts @@ -1 +1 @@ -export * from "./json-view-section" +export * from "./json-view-section"; diff --git a/src/components/common/json-view-section/json-view-section.tsx b/src/components/common/json-view-section/json-view-section.tsx index fc3f3d74..f2f37b05 100644 --- a/src/components/common/json-view-section/json-view-section.tsx +++ b/src/components/common/json-view-section/json-view-section.tsx @@ -1,10 +1,13 @@ +import type { CSSProperties, MouseEvent } from "react"; +import { Suspense, useState } from "react"; + import { ArrowUpRightOnBox, Check, SquareTwoStack, TriangleDownMini, XMarkMini, -} from "@medusajs/icons" +} from "@medusajs/icons"; import { Badge, Container, @@ -12,19 +15,19 @@ import { Heading, IconButton, Kbd, -} from "@medusajs/ui" -import Primitive from "@uiw/react-json-view" -import { CSSProperties, MouseEvent, Suspense, useState } from "react" -import { Trans, useTranslation } from "react-i18next" +} from "@medusajs/ui"; + +import Primitive from "@uiw/react-json-view"; +import { Trans, useTranslation } from "react-i18next"; type JsonViewSectionProps = { - data: object - title?: string -} + data: object; + title?: string; +}; export const JsonViewSection = ({ data }: JsonViewSectionProps) => { - const { t } = useTranslation() - const numberOfKeys = Object.keys(data).length + const { t } = useTranslation(); + const numberOfKeys = Object.keys(data).length; return ( @@ -48,7 +51,7 @@ export const JsonViewSection = ({ data }: JsonViewSectionProps) => {
    @@ -68,14 +71,14 @@ export const JsonViewSection = ({ data }: JsonViewSectionProps) => {
    - + esc @@ -83,7 +86,7 @@ export const JsonViewSection = ({ data }: JsonViewSectionProps) => {
    -
    +
    } > @@ -130,24 +133,24 @@ export const JsonViewSection = ({ data }: JsonViewSectionProps) => { { return ( - + {t("general.items", { count: Object.keys(value as object).length, })} - ) + ); }} /> - + : { - return - }} + render={({ style }, { value }) => ( + + )} /> @@ -156,46 +159,42 @@ export const JsonViewSection = ({ data }: JsonViewSectionProps) => { - ) -} + ); +}; type CopiedProps = { - style?: CSSProperties - value: object | undefined -} + style?: CSSProperties; + value: object | undefined; +}; const Copied = ({ style, value }: CopiedProps) => { - const [copied, setCopied] = useState(false) + const [copied, setCopied] = useState(false); const handler = (e: MouseEvent) => { - e.stopPropagation() - setCopied(true) + e.stopPropagation(); + setCopied(true); - if (typeof value === "string") { - navigator.clipboard.writeText(value) - } else { - const json = JSON.stringify(value, null, 2) - navigator.clipboard.writeText(json) - } + const json = JSON.stringify(value, null, 2); + navigator.clipboard.writeText(json); setTimeout(() => { - setCopied(false) - }, 2000) - } + setCopied(false); + }, 2000); + }; - const styl = { whiteSpace: "nowrap", width: "20px" } + const styl = { whiteSpace: "nowrap", width: "20px" }; if (copied) { return ( - ) + ); } return ( - + + ); +}; From 9c77ac91fbe9c569d33e5eb6d4593e40c2fd518f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:48:25 +0200 Subject: [PATCH 018/195] eslint/prettier - fix components/common/link-button --- src/components/common/link-button/index.ts | 2 +- .../common/link-button/link-button.tsx | 42 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/components/common/link-button/index.ts b/src/components/common/link-button/index.ts index b71efb56..bd302126 100644 --- a/src/components/common/link-button/index.ts +++ b/src/components/common/link-button/index.ts @@ -1 +1 @@ -export * from "./link-button" +export * from "./link-button"; diff --git a/src/components/common/link-button/link-button.tsx b/src/components/common/link-button/link-button.tsx index cd5ed5bf..875d93b3 100644 --- a/src/components/common/link-button/link-button.tsx +++ b/src/components/common/link-button/link-button.tsx @@ -1,29 +1,29 @@ -import { clx } from "@medusajs/ui" -import { ComponentPropsWithoutRef } from "react" -import { Link } from "react-router-dom" +import type { ComponentPropsWithoutRef } from "react"; + +import { clx } from "@medusajs/ui"; + +import { Link } from "react-router-dom"; interface LinkButtonProps extends ComponentPropsWithoutRef { - variant?: "primary" | "interactive" + variant?: "primary" | "interactive"; } export const LinkButton = ({ className, variant = "interactive", ...props -}: LinkButtonProps) => { - return ( - - ) -} +}: LinkButtonProps) => ( + +); From dbf0615ebea633ebccad46f2bf9cbc56ee1cc69b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:52:05 +0200 Subject: [PATCH 019/195] eslint/prettier - fix components/common/listicle --- src/components/common/listicle/index.ts | 2 +- src/components/common/listicle/listicle.tsx | 45 ++++++++++----------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/components/common/listicle/index.ts b/src/components/common/listicle/index.ts index 49b9a3a3..65a929c7 100644 --- a/src/components/common/listicle/index.ts +++ b/src/components/common/listicle/index.ts @@ -1 +1 @@ -export * from "./listicle" +export * from "./listicle"; diff --git a/src/components/common/listicle/listicle.tsx b/src/components/common/listicle/listicle.tsx index 05b7836d..c7389cdb 100644 --- a/src/components/common/listicle/listicle.tsx +++ b/src/components/common/listicle/listicle.tsx @@ -1,34 +1,33 @@ -import { Text } from "@medusajs/ui" -import { ReactNode } from "react" +import type { ReactNode } from "react"; + +import { Text } from "@medusajs/ui"; export interface ListicleProps { - labelKey: string - descriptionKey: string - children?: ReactNode + labelKey: string; + descriptionKey: string; + children?: ReactNode; } export const Listicle = ({ labelKey, descriptionKey, children, -}: ListicleProps) => { - return ( -
    -
    -
    -
    - - {labelKey} - - - {descriptionKey} - -
    -
    - {children} -
    +}: ListicleProps) => ( +
    +
    +
    +
    + + {labelKey} + + + {descriptionKey} + +
    +
    + {children}
    - ) -} +
    +); From 358c9361293f81c06db8e1f36e745f604517c3da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:52:26 +0200 Subject: [PATCH 020/195] eslint/prettier - fix components/common/loading-spinner --- .../common/loading-spinner/loading-spinner.tsx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/components/common/loading-spinner/loading-spinner.tsx b/src/components/common/loading-spinner/loading-spinner.tsx index cbc20f06..14271ec6 100644 --- a/src/components/common/loading-spinner/loading-spinner.tsx +++ b/src/components/common/loading-spinner/loading-spinner.tsx @@ -1,9 +1,7 @@ -import { Spinner } from "@medusajs/icons" +import { Spinner } from "@medusajs/icons"; -export const LoadingSpinner = () => { -return ( -
    - -
    - ) -} +export const LoadingSpinner = () => ( +
    + +
    +); From e97da8f5d7417974ccb06c5cdba0d850a92aa9d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:53:21 +0200 Subject: [PATCH 021/195] eslint/prettier - fix components/common/logo-box --- src/components/common/logo-box/avatar-box.tsx | 8 +- src/components/common/logo-box/index.ts | 4 +- src/components/common/logo-box/logo-box.tsx | 114 +++++++++--------- 3 files changed, 63 insertions(+), 63 deletions(-) diff --git a/src/components/common/logo-box/avatar-box.tsx b/src/components/common/logo-box/avatar-box.tsx index 2269ede1..027556da 100644 --- a/src/components/common/logo-box/avatar-box.tsx +++ b/src/components/common/logo-box/avatar-box.tsx @@ -1,12 +1,12 @@ -import { motion } from "motion/react" +import { motion } from "motion/react"; -import { IconAvatar } from "../icon-avatar" +import { IconAvatar } from "@components/common/icon-avatar"; export default function AvatarBox({ checked }: { checked?: boolean }) { return ( {checked && ( - ) + ); } diff --git a/src/components/common/logo-box/index.ts b/src/components/common/logo-box/index.ts index 96e7eccd..0f906d07 100644 --- a/src/components/common/logo-box/index.ts +++ b/src/components/common/logo-box/index.ts @@ -1,2 +1,2 @@ -export * from "./logo-box" -export * from "./avatar-box" +export * from "./logo-box"; +export * from "./avatar-box"; diff --git a/src/components/common/logo-box/logo-box.tsx b/src/components/common/logo-box/logo-box.tsx index 9df3cc54..91483e82 100644 --- a/src/components/common/logo-box/logo-box.tsx +++ b/src/components/common/logo-box/logo-box.tsx @@ -1,12 +1,14 @@ -import { clx } from "@medusajs/ui" -import { Transition, motion } from "motion/react" +import { clx } from "@medusajs/ui"; + +import type { Transition } from "motion/react"; +import { motion } from "motion/react"; type LogoBoxProps = { - className?: string - checked?: boolean - containerTransition?: Transition - pathTransition?: Transition -} + className?: string; + checked?: boolean; + containerTransition?: Transition; + pathTransition?: Transition; +}; export const LogoBox = ({ className, @@ -21,54 +23,52 @@ export const LogoBox = ({ delay: 0.6, ease: [0.1, 0.8, 0.2, 1.01], }, -}: LogoBoxProps) => { - return ( -
    - {checked && ( - - - - - - )} - ( +
    + {checked && ( + - - -
    - ) -} + + + + + )} + + + +
    +); From 6663b18025305d16e62bf595914dec30f08542a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:53:59 +0200 Subject: [PATCH 022/195] eslint/prettier - fix components/common/metadata-editor --- .../common/metadata-editor/index.tsx | 102 ++++++++++++------ 1 file changed, 68 insertions(+), 34 deletions(-) diff --git a/src/components/common/metadata-editor/index.tsx b/src/components/common/metadata-editor/index.tsx index 0a7101db..8fc1f2ac 100644 --- a/src/components/common/metadata-editor/index.tsx +++ b/src/components/common/metadata-editor/index.tsx @@ -1,61 +1,84 @@ -import { Button, Input, Text, Heading, DropdownMenu } from "@medusajs/ui" -import { useFieldArray, UseFormReturn, FieldValues, Path, FieldError, FieldErrors, ArrayPath, FieldArray } from "react-hook-form" -import { EllipsisHorizontal, Trash } from "@medusajs/icons" +import { EllipsisHorizontal, Trash } from "@medusajs/icons"; +import { Button, DropdownMenu, Heading, Input, Text } from "@medusajs/ui"; + +import type { + ArrayPath, + FieldArray, + FieldError, + FieldErrors, + FieldValues, + Path, + UseFormReturn, +} from "react-hook-form"; +import { useFieldArray } from "react-hook-form"; interface MetadataField { - key: string - value: string + key: string; + value: string; } -interface MetadataEditorProps { - form: UseFormReturn - name?: ArrayPath - title?: string +interface MetadataEditorProps< + T extends FieldValues & { metadata: MetadataField[] }, +> { + form: UseFormReturn; + name?: ArrayPath; + title?: string; } -export const MetadataEditor = ({ - form, +export const MetadataEditor = < + T extends FieldValues & { metadata: MetadataField[] }, +>({ + form, name = "metadata" as ArrayPath, - title = "Metadata" + title = "Metadata", }: MetadataEditorProps) => { const { fields, append, remove } = useFieldArray({ control: form.control, name, - }) + }); const getErrorMessage = (error: FieldError | undefined) => { - return error?.message ? String(error.message) : "" - } + return error?.message ? String(error.message) : ""; + }; const getFieldErrors = (index: number) => { - const errors = form.formState.errors[name] as FieldErrors | undefined + const errors = form.formState.errors[name] as + | FieldErrors + | undefined; + return { key: errors?.[index]?.key, - value: errors?.[index]?.value - } - } + value: errors?.[index]?.value, + }; + }; return (
    - {title} -
    -
    + + {title} + +
    +
    Key Value
    {fields.map((field, index) => { - const fieldErrors = getFieldErrors(index) + const fieldErrors = getFieldErrors(index); + return ( -
    -
    +
    +
    )} /> {fieldErrors.key && ( - + {getErrorMessage(fieldErrors.key)} )} @@ -63,11 +86,11 @@ export const MetadataEditor = )} /> {fieldErrors.value && ( - + {getErrorMessage(fieldErrors.value)} )} @@ -80,7 +103,10 @@ export const MetadataEditor = - remove(index)} className="gap-x-2"> + remove(index)} + className="gap-x-2" + > Remove @@ -88,14 +114,22 @@ export const MetadataEditor =
    - ) + ); })}
    -
    - ) -} \ No newline at end of file + ); +}; From c7424df105e251065a7cffc867ead5117f0f9b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:54:24 +0200 Subject: [PATCH 023/195] eslint/prettier - fix components/common/metadata-section --- .../common/metadata-section/index.ts | 2 +- .../metadata-section/metadata-section.tsx | 27 ++++++++++--------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/components/common/metadata-section/index.ts b/src/components/common/metadata-section/index.ts index 2281a512..527d968b 100644 --- a/src/components/common/metadata-section/index.ts +++ b/src/components/common/metadata-section/index.ts @@ -1 +1 @@ -export * from "./metadata-section" +export * from "./metadata-section"; diff --git a/src/components/common/metadata-section/metadata-section.tsx b/src/components/common/metadata-section/metadata-section.tsx index 4786bb31..d2dcf08c 100644 --- a/src/components/common/metadata-section/metadata-section.tsx +++ b/src/components/common/metadata-section/metadata-section.tsx @@ -1,28 +1,29 @@ -import { ArrowUpRightOnBox } from "@medusajs/icons" -import { Badge, Container, Heading, IconButton } from "@medusajs/ui" -import { useTranslation } from "react-i18next" -import { Link } from "react-router-dom" +import { ArrowUpRightOnBox } from "@medusajs/icons"; +import { Badge, Container, Heading, IconButton } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; +import { Link } from "react-router-dom"; type MetadataSectionProps = { - data: TData - href?: string -} + data: TData; + href?: string; +}; export const MetadataSection = ({ data, href = "metadata/edit", }: MetadataSectionProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); if (!data) { - return null + return null; } if (!("metadata" in data)) { - return null + return null; } - const numberOfKeys = data.metadata ? Object.keys(data.metadata).length : 0 + const numberOfKeys = data.metadata ? Object.keys(data.metadata).length : 0; return ( @@ -45,5 +46,5 @@ export const MetadataSection = ({ - ) -} + ); +}; From 4ddd63b4751b201686ca824f3fd6d95dfb2c68fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:56:28 +0200 Subject: [PATCH 024/195] eslint/prettier - fix components/common/progress-bar --- src/components/common/progress-bar/index.ts | 2 +- .../common/progress-bar/progress-bar.tsx | 46 +++++++++---------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/components/common/progress-bar/index.ts b/src/components/common/progress-bar/index.ts index ad8afe82..c56d4c06 100644 --- a/src/components/common/progress-bar/index.ts +++ b/src/components/common/progress-bar/index.ts @@ -1 +1 @@ -export * from "./progress-bar" +export * from "./progress-bar"; diff --git a/src/components/common/progress-bar/progress-bar.tsx b/src/components/common/progress-bar/progress-bar.tsx index ebfec4c3..a2302df7 100644 --- a/src/components/common/progress-bar/progress-bar.tsx +++ b/src/components/common/progress-bar/progress-bar.tsx @@ -1,4 +1,4 @@ -import { motion } from "motion/react" +import { motion } from "motion/react"; interface ProgressBarProps { /** @@ -6,28 +6,26 @@ interface ProgressBarProps { * * @default 2 */ - duration?: number + duration?: number; } -export const ProgressBar = ({ duration = 2 }: ProgressBarProps) => { - return ( - - ) -} +export const ProgressBar = ({ duration = 2 }: ProgressBarProps) => ( + +); From 57f4d4a836edc4dc9892002ea8a6fb5db4011f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:57:23 +0200 Subject: [PATCH 025/195] eslint/prettier - fix components/common/section --- src/components/common/section/index.ts | 2 +- src/components/common/section/section-row.tsx | 23 ++++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/components/common/section/index.ts b/src/components/common/section/index.ts index 88b24669..7d90198b 100644 --- a/src/components/common/section/index.ts +++ b/src/components/common/section/index.ts @@ -1 +1 @@ -export * from "./section-row" +export * from "./section-row"; diff --git a/src/components/common/section/section-row.tsx b/src/components/common/section/section-row.tsx index 3ebbc5b5..f5eecb1e 100644 --- a/src/components/common/section/section-row.tsx +++ b/src/components/common/section/section-row.tsx @@ -1,22 +1,23 @@ -import { Text, clx } from "@medusajs/ui" -import { ReactNode } from "react" +import type { ReactNode } from "react"; + +import { Text, clx } from "@medusajs/ui"; export type SectionRowProps = { - title: string - value?: ReactNode | string | null - actions?: ReactNode -} + title: string; + value?: ReactNode | string | null; + actions?: ReactNode; +}; export const SectionRow = ({ title, value, actions }: SectionRowProps) => { - const isValueString = typeof value === "string" || !value + const isValueString = typeof value === "string" || !value; return (
    @@ -37,5 +38,5 @@ export const SectionRow = ({ title, value, actions }: SectionRowProps) => { {actions &&
    {actions}
    }
    - ) -} + ); +}; From 783154a31e6be81a444b234ebf1dcb91507578ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 15:58:48 +0200 Subject: [PATCH 026/195] eslint/prettier - fix components/common/sidebar-link --- src/components/common/sidebar-link/indext.ts | 2 +- .../common/sidebar-link/sidebar-link.tsx | 64 +++++++++---------- 2 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/components/common/sidebar-link/indext.ts b/src/components/common/sidebar-link/indext.ts index e5d18112..4c583799 100644 --- a/src/components/common/sidebar-link/indext.ts +++ b/src/components/common/sidebar-link/indext.ts @@ -1 +1 @@ -export * from "./sidebar-link" +export * from "./sidebar-link"; diff --git a/src/components/common/sidebar-link/sidebar-link.tsx b/src/components/common/sidebar-link/sidebar-link.tsx index 7e0c2c9c..33cc35d2 100644 --- a/src/components/common/sidebar-link/sidebar-link.tsx +++ b/src/components/common/sidebar-link/sidebar-link.tsx @@ -1,15 +1,17 @@ -import { ReactNode } from "react" -import { Link } from "react-router-dom" +import type { ReactNode } from "react"; -import { TriangleRightMini } from "@medusajs/icons" -import { Text } from "@medusajs/ui" -import { IconAvatar } from "../icon-avatar" +import { TriangleRightMini } from "@medusajs/icons"; +import { Text } from "@medusajs/ui"; + +import { Link } from "react-router-dom"; + +import { IconAvatar } from "@components/common/icon-avatar"; export interface SidebarLinkProps { - to: string - labelKey: string - descriptionKey: string - icon: ReactNode + to: string; + labelKey: string; + descriptionKey: string; + icon: ReactNode; } export const SidebarLink = ({ @@ -17,31 +19,25 @@ export const SidebarLink = ({ labelKey, descriptionKey, icon, -}: SidebarLinkProps) => { - return ( - -
    -
    -
    - {icon} -
    - - {labelKey} - - - {descriptionKey} - -
    -
    - -
    +}: SidebarLinkProps) => ( + +
    +
    +
    + {icon} +
    + + {labelKey} + + + {descriptionKey} + +
    +
    +
    - - ) -} +
    + +); From dac3b82bdc660671fc889b20adc28de955a2fa36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 16:00:43 +0200 Subject: [PATCH 027/195] eslint/prettier - fix components/common/skeleton --- src/components/common/skeleton/index.ts | 2 +- src/components/common/skeleton/skeleton.tsx | 300 ++++++++++---------- 2 files changed, 145 insertions(+), 157 deletions(-) diff --git a/src/components/common/skeleton/index.ts b/src/components/common/skeleton/index.ts index d889ad70..8e713ba5 100644 --- a/src/components/common/skeleton/index.ts +++ b/src/components/common/skeleton/index.ts @@ -1 +1 @@ -export * from "./skeleton" +export * from "./skeleton"; diff --git a/src/components/common/skeleton/skeleton.tsx b/src/components/common/skeleton/skeleton.tsx index 90671af6..65984d68 100644 --- a/src/components/common/skeleton/skeleton.tsx +++ b/src/components/common/skeleton/skeleton.tsx @@ -1,51 +1,51 @@ -import { Container, Heading, Text, clx } from "@medusajs/ui" -import { CSSProperties, ComponentPropsWithoutRef } from "react" +import type { CSSProperties, ComponentPropsWithoutRef } from "react"; + +import type { Heading, Text } from "@medusajs/ui"; +import { Container, clx } from "@medusajs/ui"; type SkeletonProps = { - className?: string - style?: CSSProperties -} + className?: string; + style?: CSSProperties; +}; -export const Skeleton = ({ className, style }: SkeletonProps) => { - return ( -
    - ) -} +export const Skeleton = ({ className, style }: SkeletonProps) => ( +
    +); type TextSkeletonProps = { - size?: ComponentPropsWithoutRef["size"] - leading?: ComponentPropsWithoutRef["leading"] - characters?: number -} + size?: ComponentPropsWithoutRef["size"]; + leading?: ComponentPropsWithoutRef["leading"]; + characters?: number; +}; type HeadingSkeletonProps = { - level?: ComponentPropsWithoutRef["level"] - characters?: number -} + level?: ComponentPropsWithoutRef["level"]; + characters?: number; +}; export const HeadingSkeleton = ({ level = "h1", characters = 10, }: HeadingSkeletonProps) => { - let charWidth = 9 + let charWidth = 9; switch (level) { case "h1": - charWidth = 11 - break + charWidth = 11; + break; case "h2": - charWidth = 10 - break + charWidth = 10; + break; case "h3": - charWidth = 9 - break + charWidth = 9; + break; } return ( @@ -59,32 +59,32 @@ export const HeadingSkeleton = ({ width: `${charWidth * characters}px`, }} /> - ) -} + ); +}; export const TextSkeleton = ({ size = "small", leading = "compact", characters = 10, }: TextSkeletonProps) => { - let charWidth = 9 + let charWidth = 9; switch (size) { case "xlarge": - charWidth = 13 - break + charWidth = 13; + break; case "large": - charWidth = 11 - break + charWidth = 11; + break; case "base": - charWidth = 10 - break + charWidth = 10; + break; case "small": - charWidth = 9 - break + charWidth = 9; + break; case "xsmall": - charWidth = 8 - break + charWidth = 8; + break; } return ( @@ -100,21 +100,21 @@ export const TextSkeleton = ({ width: `${charWidth * characters}px`, }} /> - ) -} + ); +}; -export const IconButtonSkeleton = () => { - return -} +export const IconButtonSkeleton = () => ( + +); type GeneralSectionSkeletonProps = { - rowCount?: number -} + rowCount?: number; +}; export const GeneralSectionSkeleton = ({ rowCount, }: GeneralSectionSkeletonProps) => { - const rows = Array.from({ length: rowCount ?? 0 }, (_, i) => i) + const rows = Array.from({ length: rowCount ?? 0 }, (_, i) => i); return ( @@ -133,34 +133,32 @@ export const GeneralSectionSkeleton = ({
    ))} - ) -} + ); +}; -export const TableFooterSkeleton = ({ layout }: { layout: "fill" | "fit" }) => { - return ( -
    - -
    - - - -
    +export const TableFooterSkeleton = ({ layout }: { layout: "fill" | "fit" }) => ( +
    + +
    + + +
    - ) -} +
    +); type TableSkeletonProps = { - rowCount?: number - search?: boolean - filters?: boolean - orderBy?: boolean - pagination?: boolean - layout?: "fit" | "fill" -} + rowCount?: number; + search?: boolean; + filters?: boolean; + orderBy?: boolean; + pagination?: boolean; + layout?: "fit" | "fill"; +}; export const TableSkeleton = ({ rowCount = 10, @@ -171,10 +169,10 @@ export const TableSkeleton = ({ layout = "fit", }: TableSkeletonProps) => { // Row count + header row - const totalRowCount = rowCount + 1 + const totalRowCount = rowCount + 1; - const rows = Array.from({ length: totalRowCount }, (_, i) => i) - const hasToolbar = search || filters || orderBy + const rows = Array.from({ length: totalRowCount }, (_, i) => i); + const hasToolbar = search || filters || orderBy; return (
    {pagination && }
    - ) -} + ); +}; -export const TableSectionSkeleton = (props: TableSkeletonProps) => { - return ( - -
    - - -
    - -
    - ) -} +export const TableSectionSkeleton = (props: TableSkeletonProps) => ( + +
    + + +
    + +
    +); -export const JsonViewSectionSkeleton = () => { - return ( - -
    -
    - - -
    - +export const JsonViewSectionSkeleton = () => ( + +
    +
    + +
    - - ) -} + +
    +
    +); type SingleColumnPageSkeletonProps = { - sections?: number - showJSON?: boolean - showMetadata?: boolean -} + sections?: number; + showJSON?: boolean; + showMetadata?: boolean; +}; export const SingleColumnPageSkeleton = ({ sections = 2, showJSON = false, showMetadata = false, -}: SingleColumnPageSkeletonProps) => { - return ( -
    - {Array.from({ length: sections }, (_, i) => i).map((section) => { - return ( - - ) - })} - {showMetadata && } - {showJSON && } -
    - ) -} +}: SingleColumnPageSkeletonProps) => ( +
    + {Array.from({ length: sections }, (_, i) => i).map((section) => { + return ( + + ); + })} + {showMetadata && } + {showJSON && } +
    +); type TwoColumnPageSkeletonProps = { - mainSections?: number - sidebarSections?: number - showJSON?: boolean - showMetadata?: boolean -} + mainSections?: number; + sidebarSections?: number; + showJSON?: boolean; + showMetadata?: boolean; +}; export const TwoColumnPageSkeleton = ({ mainSections = 2, @@ -274,22 +266,20 @@ export const TwoColumnPageSkeleton = ({ showJSON = false, showMetadata = true, }: TwoColumnPageSkeletonProps) => { - const showExtraData = showJSON || showMetadata + const showExtraData = showJSON || showMetadata; return (
    - {Array.from({ length: mainSections }, (_, i) => i).map((section) => { - return ( - - ) - })} + {Array.from({ length: mainSections }, (_, i) => i).map((section) => ( + + ))} {showExtraData && (
    {showMetadata && ( @@ -301,16 +291,14 @@ export const TwoColumnPageSkeleton = ({
    {Array.from({ length: sidebarSections }, (_, i) => i).map( - (section) => { - return ( - - ) - } + (section) => ( + + ), )} {showExtraData && (
    @@ -323,5 +311,5 @@ export const TwoColumnPageSkeleton = ({
    - ) -} + ); +}; From 448ad660e571ce80c3f46ca32cf2914d3f3e612c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 16:03:13 +0200 Subject: [PATCH 028/195] eslint/prettier - fix components/common/sortable-list --- src/components/common/sortable-list/index.ts | 2 +- .../common/sortable-list/sortable-list.tsx | 160 +++++++++--------- 2 files changed, 80 insertions(+), 82 deletions(-) diff --git a/src/components/common/sortable-list/index.ts b/src/components/common/sortable-list/index.ts index c9eb55be..e9062e5a 100644 --- a/src/components/common/sortable-list/index.ts +++ b/src/components/common/sortable-list/index.ts @@ -1 +1 @@ -export * from "./sortable-list" +export * from "./sortable-list"; diff --git a/src/components/common/sortable-list/sortable-list.tsx b/src/components/common/sortable-list/sortable-list.tsx index e588fc8b..8376300c 100644 --- a/src/components/common/sortable-list/sortable-list.tsx +++ b/src/components/common/sortable-list/sortable-list.tsx @@ -1,46 +1,42 @@ -import { +import type { CSSProperties, PropsWithChildren, ReactNode } from "react"; +import { Fragment, createContext, useContext, useMemo, useState } from "react"; + +import { DotsSix } from "@medusajs/icons"; +import { IconButton, clx } from "@medusajs/ui"; + +import type { Active, - DndContext, DragEndEvent, - DragOverlay, DragStartEvent, DraggableSyntheticListeners, +} from "@dnd-kit/core"; +import { + DndContext, + DragOverlay, + type DropAnimation, KeyboardSensor, PointerSensor, + type UniqueIdentifier, defaultDropAnimationSideEffects, useSensor, useSensors, - type DropAnimation, - type UniqueIdentifier, -} from "@dnd-kit/core" +} from "@dnd-kit/core"; import { SortableContext, arrayMove, sortableKeyboardCoordinates, useSortable, -} from "@dnd-kit/sortable" -import { CSS } from "@dnd-kit/utilities" -import { DotsSix } from "@medusajs/icons" -import { IconButton, clx } from "@medusajs/ui" -import { - CSSProperties, - Fragment, - PropsWithChildren, - ReactNode, - createContext, - useContext, - useMemo, - useState, -} from "react" +} from "@dnd-kit/sortable"; +import { CSS } from "@dnd-kit/utilities"; type SortableBaseItem = { - id: UniqueIdentifier -} + id: UniqueIdentifier; +}; interface SortableListProps { - items: TItem[] - onChange: (items: TItem[]) => void - renderItem: (item: TItem, index: number) => ReactNode + items: TItem[]; + onChange: (items: TItem[]) => void; + renderItem: (item: TItem, index: number) => ReactNode; } const List = ({ @@ -48,43 +44,43 @@ const List = ({ onChange, renderItem, }: SortableListProps) => { - const [active, setActive] = useState(null) + const [active, setActive] = useState(null); const [activeItem, activeIndex] = useMemo(() => { if (active === null) { - return [null, null] + return [null, null]; } - const index = items.findIndex(({ id }) => id === active.id) + const index = items.findIndex(({ id }) => id === active.id); - return [items[index], index] - }, [active, items]) + return [items[index], index]; + }, [active, items]); const sensors = useSensors( useSensor(PointerSensor), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates, - }) - ) + }), + ); const handleDragStart = ({ active }: DragStartEvent) => { - setActive(active) - } + setActive(active); + }; const handleDragEnd = ({ active, over }: DragEndEvent) => { if (over && active.id !== over.id) { - const activeIndex = items.findIndex(({ id }) => id === active.id) - const overIndex = items.findIndex(({ id }) => id === over.id) + const activeIndex = items.findIndex(({ id }) => id === active.id); + const overIndex = items.findIndex(({ id }) => id === over.id); - onChange(arrayMove(items, activeIndex, overIndex)) + onChange(arrayMove(items, activeIndex, overIndex)); } - setActive(null) - } + setActive(null); + }; const handleDragCancel = () => { - setActive(null) - } + setActive(null); + }; return ( ({ - ) -} + ); +}; const dropAnimationConfig: DropAnimation = { sideEffects: defaultDropAnimationSideEffects({ @@ -120,46 +116,48 @@ const dropAnimationConfig: DropAnimation = { }, }, }), -} +}; -type SortableOverlayProps = PropsWithChildren +type SortableOverlayProps = PropsWithChildren; -const Overlay = ({ children }: SortableOverlayProps) => { - return ( - - {children} - - ) -} +const Overlay = ({ children }: SortableOverlayProps) => ( + + {children} + +); type SortableItemProps = PropsWithChildren<{ - id: TItem["id"] - className?: string -}> + id: TItem["id"]; + className?: string; +}>; type SortableItemContextValue = { - attributes: Record - listeners: DraggableSyntheticListeners - ref: (node: HTMLElement | null) => void - isDragging: boolean -} - -const SortableItemContext = createContext(null) + // @todo fix any type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + attributes: Record; + listeners: DraggableSyntheticListeners; + ref: (node: HTMLElement | null) => void; + isDragging: boolean; +}; + +const SortableItemContext = createContext( + null, +); const useSortableItemContext = () => { - const context = useContext(SortableItemContext) + const context = useContext(SortableItemContext); if (!context) { throw new Error( - "useSortableItemContext must be used within a SortableItemContext" - ) + "useSortableItemContext must be used within a SortableItemContext", + ); } - return context -} + return context; +}; const Item = ({ id, @@ -174,7 +172,7 @@ const Item = ({ setActivatorNodeRef, transform, transition, - } = useSortable({ id }) + } = useSortable({ id }); const context = useMemo( () => ({ @@ -183,30 +181,30 @@ const Item = ({ ref: setActivatorNodeRef, isDragging, }), - [attributes, listeners, setActivatorNodeRef, isDragging] - ) + [attributes, listeners, setActivatorNodeRef, isDragging], + ); const style: CSSProperties = { opacity: isDragging ? 0.4 : undefined, transform: CSS.Translate.toString(transform), transition, - } + }; return (
  • {children}
  • - ) -} + ); +}; const DragHandle = () => { - const { attributes, listeners, ref } = useSortableItemContext() + const { attributes, listeners, ref } = useSortableItemContext(); return ( { > - ) -} + ); +}; export const SortableList = Object.assign(List, { Item, DragHandle, -}) +}); From 9917f465cd1f1d59520e3e1c294ed4c2182e9a63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 16:08:20 +0200 Subject: [PATCH 029/195] eslint/prettier - fix components/common/sortable-tree --- src/components/common/sortable-tree/index.ts | 2 +- .../sortable-tree/keyboard-coordinates.ts | 98 ++++--- .../sortable-tree/sortable-tree-item.tsx | 27 +- .../common/sortable-tree/sortable-tree.tsx | 240 +++++++++--------- .../common/sortable-tree/tree-item.tsx | 213 ++++++++-------- src/components/common/sortable-tree/types.ts | 27 +- src/components/common/sortable-tree/utils.ts | 191 +++++++------- 7 files changed, 397 insertions(+), 401 deletions(-) diff --git a/src/components/common/sortable-tree/index.ts b/src/components/common/sortable-tree/index.ts index 46f2ac3c..7757efd4 100644 --- a/src/components/common/sortable-tree/index.ts +++ b/src/components/common/sortable-tree/index.ts @@ -1 +1 @@ -export * from "./sortable-tree" +export * from "./sortable-tree"; diff --git a/src/components/common/sortable-tree/keyboard-coordinates.ts b/src/components/common/sortable-tree/keyboard-coordinates.ts index a836cc5a..3cfb8544 100644 --- a/src/components/common/sortable-tree/keyboard-coordinates.ts +++ b/src/components/common/sortable-tree/keyboard-coordinates.ts @@ -1,26 +1,24 @@ -import { +import type { DroppableContainer, - KeyboardCode, KeyboardCoordinateGetter, - closestCorners, - getFirstCollision, -} from "@dnd-kit/core" +} from "@dnd-kit/core"; +import { KeyboardCode, closestCorners, getFirstCollision } from "@dnd-kit/core"; -import type { SensorContext } from "./types" -import { getProjection } from "./utils" +import type { SensorContext } from "./types"; +import { getProjection } from "./utils"; const directions: string[] = [ KeyboardCode.Down, KeyboardCode.Right, KeyboardCode.Up, KeyboardCode.Left, -] +]; -const horizontal: string[] = [KeyboardCode.Left, KeyboardCode.Right] +const horizontal: string[] = [KeyboardCode.Left, KeyboardCode.Right]; export const sortableTreeKeyboardCoordinates: ( context: SensorContext, - indentationWidth: number + indentationWidth: number, ) => KeyboardCoordinateGetter = (context, indentationWidth) => ( @@ -34,18 +32,18 @@ export const sortableTreeKeyboardCoordinates: ( droppableRects, droppableContainers, }, - } + }, ) => { if (directions.includes(event.code)) { if (!active || !collisionRect) { - return + return; } - event.preventDefault() + event.preventDefault(); const { current: { items, offset }, - } = context + } = context; if (horizontal.includes(event.code) && over?.id) { const { depth, maxDepth, minDepth } = getProjection( @@ -53,8 +51,8 @@ export const sortableTreeKeyboardCoordinates: ( active.id, over.id, offset, - indentationWidth - ) + indentationWidth, + ); switch (event.code) { case KeyboardCode.Left: @@ -62,48 +60,48 @@ export const sortableTreeKeyboardCoordinates: ( return { ...currentCoordinates, x: currentCoordinates.x - indentationWidth, - } + }; } - break + break; case KeyboardCode.Right: if (depth < maxDepth) { return { ...currentCoordinates, x: currentCoordinates.x + indentationWidth, - } + }; } - break + break; } - return undefined + return undefined; } - const containers: DroppableContainer[] = [] + const containers: DroppableContainer[] = []; droppableContainers.forEach((container) => { if (container?.disabled || container.id === over?.id) { - return + return; } - const rect = droppableRects.get(container.id) + const rect = droppableRects.get(container.id); if (!rect) { - return + return; } switch (event.code) { case KeyboardCode.Down: if (collisionRect.top < rect.top) { - containers.push(container) + containers.push(container); } - break + break; case KeyboardCode.Up: if (collisionRect.top > rect.top) { - containers.push(container) + containers.push(container); } - break + break; } - }) + }); const collisions = closestCorners({ active, @@ -111,23 +109,23 @@ export const sortableTreeKeyboardCoordinates: ( pointerCoordinates: null, droppableRects, droppableContainers: containers, - }) - let closestId = getFirstCollision(collisions, "id") + }); + let closestId = getFirstCollision(collisions, "id"); if (closestId === over?.id && collisions.length > 1) { - closestId = collisions[1].id + closestId = collisions[1].id; } if (closestId && over?.id) { - const activeRect = droppableRects.get(active.id) - const newRect = droppableRects.get(closestId) - const newDroppable = droppableContainers.get(closestId) + const activeRect = droppableRects.get(active.id); + const newRect = droppableRects.get(closestId); + const newDroppable = droppableContainers.get(closestId); if (activeRect && newRect && newDroppable) { - const newIndex = items.findIndex(({ id }) => id === closestId) - const newItem = items[newIndex] - const activeIndex = items.findIndex(({ id }) => id === active.id) - const activeItem = items[activeIndex] + const newIndex = items.findIndex(({ id }) => id === closestId); + const newItem = items[newIndex]; + const activeIndex = items.findIndex(({ id }) => id === active.id); + const activeItem = items[activeIndex]; if (newItem && activeItem) { const { depth } = getProjection( @@ -135,22 +133,20 @@ export const sortableTreeKeyboardCoordinates: ( active.id, closestId, (newItem.depth - activeItem.depth) * indentationWidth, - indentationWidth - ) - const isBelow = newIndex > activeIndex - const modifier = isBelow ? 1 : -1 - const offset = 0 + indentationWidth, + ); + const isBelow = newIndex > activeIndex; + const modifier = isBelow ? 1 : -1; + const offset = 0; - const newCoordinates = { + return { x: newRect.left + depth * indentationWidth, y: newRect.top + modifier * offset, - } - - return newCoordinates + }; } } } } - return undefined - } + return undefined; + }; diff --git a/src/components/common/sortable-tree/sortable-tree-item.tsx b/src/components/common/sortable-tree/sortable-tree-item.tsx index d87821a9..b1d313aa 100644 --- a/src/components/common/sortable-tree/sortable-tree-item.tsx +++ b/src/components/common/sortable-tree/sortable-tree-item.tsx @@ -1,21 +1,24 @@ -import type { UniqueIdentifier } from "@dnd-kit/core" -import { AnimateLayoutChanges, useSortable } from "@dnd-kit/sortable" -import { CSS } from "@dnd-kit/utilities" -import { CSSProperties } from "react" +import type { CSSProperties } from "react"; -import { TreeItem, TreeItemProps } from "./tree-item" -import { iOS } from "./utils" +import type { UniqueIdentifier } from "@dnd-kit/core"; +import type { AnimateLayoutChanges } from "@dnd-kit/sortable"; +import { useSortable } from "@dnd-kit/sortable"; +import { CSS } from "@dnd-kit/utilities"; + +import type { TreeItemProps } from "./tree-item"; +import { TreeItem } from "./tree-item"; +import { iOS } from "./utils"; interface SortableTreeItemProps extends TreeItemProps { - id: UniqueIdentifier + id: UniqueIdentifier; } const animateLayoutChanges: AnimateLayoutChanges = ({ isSorting, wasDragging, }) => { - return isSorting || wasDragging ? false : true -} + return !(isSorting || wasDragging); +}; export function SortableTreeItem({ id, @@ -36,11 +39,11 @@ export function SortableTreeItem({ id, animateLayoutChanges, disabled, - }) + }); const style: CSSProperties = { transform: CSS.Translate.toString(transform), transition, - } + }; return ( - ) + ); } diff --git a/src/components/common/sortable-tree/sortable-tree.tsx b/src/components/common/sortable-tree/sortable-tree.tsx index 9ddeb896..53510d15 100644 --- a/src/components/common/sortable-tree/sortable-tree.tsx +++ b/src/components/common/sortable-tree/sortable-tree.tsx @@ -1,46 +1,50 @@ -import { +import type { ReactNode } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; + +import type { Announcements, - DndContext, DragEndEvent, DragMoveEvent, DragOverEvent, - DragOverlay, DragStartEvent, DropAnimation, + UniqueIdentifier, +} from "@dnd-kit/core"; +import { + DndContext, + DragOverlay, KeyboardSensor, MeasuringStrategy, PointerSensor, - UniqueIdentifier, closestCenter, defaultDropAnimation, useSensor, useSensors, -} from "@dnd-kit/core" +} from "@dnd-kit/core"; import { SortableContext, arrayMove, verticalListSortingStrategy, -} from "@dnd-kit/sortable" -import { CSS } from "@dnd-kit/utilities" -import { ReactNode, useEffect, useMemo, useRef, useState } from "react" -import { createPortal } from "react-dom" - -import { sortableTreeKeyboardCoordinates } from "./keyboard-coordinates" -import { SortableTreeItem } from "./sortable-tree-item" -import type { FlattenedItem, SensorContext, TreeItem } from "./types" +} from "@dnd-kit/sortable"; +import { CSS } from "@dnd-kit/utilities"; +import { createPortal } from "react-dom"; + +import { sortableTreeKeyboardCoordinates } from "./keyboard-coordinates"; +import { SortableTreeItem } from "./sortable-tree-item"; +import type { FlattenedItem, SensorContext, TreeItem } from "./types"; import { buildTree, flattenTree, getChildCount, getProjection, removeChildrenOf, -} from "./utils" +} from "./utils"; const measuring = { droppable: { strategy: MeasuringStrategy.Always, }, -} +}; const dropAnimationConfig: DropAnimation = { keyframes({ transform }) { @@ -54,36 +58,36 @@ const dropAnimationConfig: DropAnimation = { y: transform.final.y + 5, }), }, - ] + ]; }, easing: "ease-out", sideEffects({ active }) { active.node.animate([{ opacity: 0 }, { opacity: 1 }], { duration: defaultDropAnimation.duration, easing: defaultDropAnimation.easing, - }) + }); }, -} +}; interface Props { - collapsible?: boolean - childrenProp?: string - items: T[] - indentationWidth?: number + collapsible?: boolean; + childrenProp?: string; + items: T[]; + indentationWidth?: number; /** * Enable drag for all items or provide a function to enable drag for specific items. * @default true */ - enableDrag?: boolean | ((item: T) => boolean) + enableDrag?: boolean | ((item: T) => boolean); onChange: ( updatedItem: { - id: UniqueIdentifier - parentId: UniqueIdentifier | null - index: number + id: UniqueIdentifier; + parentId: UniqueIdentifier | null; + index: number; }, - items: T[] - ) => void - renderValue: (item: T) => ReactNode + items: T[], + ) => void; + renderValue: (item: T) => ReactNode; } export function SortableTree({ @@ -97,35 +101,35 @@ export function SortableTree({ }: Props) { const [collapsedState, setCollapsedState] = useState< Record - >({}) + >({}); - const [activeId, setActiveId] = useState(null) - const [overId, setOverId] = useState(null) - const [offsetLeft, setOffsetLeft] = useState(0) + const [activeId, setActiveId] = useState(null); + const [overId, setOverId] = useState(null); + const [offsetLeft, setOffsetLeft] = useState(0); const [currentPosition, setCurrentPosition] = useState<{ - parentId: UniqueIdentifier | null - overId: UniqueIdentifier - } | null>(null) + parentId: UniqueIdentifier | null; + overId: UniqueIdentifier; + } | null>(null); const flattenedItems = useMemo(() => { - const flattenedTree = flattenTree(items, childrenProp) + const flattenedTree = flattenTree(items, childrenProp); const collapsedItems = flattenedTree.reduce( (acc, item) => { - const { id } = item - const children = (item[childrenProp] || []) as FlattenedItem[] - const collapsed = collapsedState[id] + const { id } = item; + const children = (item[childrenProp] || []) as FlattenedItem[]; + const collapsed = collapsedState[id]; - return collapsed && children.length ? [...acc, id] : acc + return collapsed && children.length ? [...acc, id] : acc; }, - [] - ) + [], + ); return removeChildrenOf( flattenedTree, activeId ? [activeId, ...collapsedItems] : collapsedItems, - childrenProp - ) - }, [activeId, items, childrenProp, collapsedState]) + childrenProp, + ); + }, [activeId, items, childrenProp, collapsedState]); const projected = activeId && overId @@ -134,117 +138,117 @@ export function SortableTree({ activeId, overId, offsetLeft, - indentationWidth + indentationWidth, ) - : null + : null; const sensorContext: SensorContext = useRef({ items: flattenedItems, offset: offsetLeft, - }) + }); const [coordinateGetter] = useState(() => - sortableTreeKeyboardCoordinates(sensorContext, indentationWidth) - ) + sortableTreeKeyboardCoordinates(sensorContext, indentationWidth), + ); const sensors = useSensors( useSensor(PointerSensor), useSensor(KeyboardSensor, { coordinateGetter, - }) - ) + }), + ); const sortedIds = useMemo( () => flattenedItems.map(({ id }) => id), - [flattenedItems] - ) + [flattenedItems], + ); const activeItem = activeId ? flattenedItems.find(({ id }) => id === activeId) - : null + : null; useEffect(() => { sensorContext.current = { items: flattenedItems, offset: offsetLeft, - } - }, [flattenedItems, offsetLeft]) + }; + }, [flattenedItems, offsetLeft]); function handleDragStart({ active: { id: activeId } }: DragStartEvent) { - setActiveId(activeId) - setOverId(activeId) + setActiveId(activeId); + setOverId(activeId); - const activeItem = flattenedItems.find(({ id }) => id === activeId) + const activeItem = flattenedItems.find(({ id }) => id === activeId); if (activeItem) { setCurrentPosition({ parentId: activeItem.parentId, overId: activeId, - }) + }); } - document.body.style.setProperty("cursor", "grabbing") + document.body.style.setProperty("cursor", "grabbing"); } function handleDragMove({ delta }: DragMoveEvent) { - setOffsetLeft(delta.x) + setOffsetLeft(delta.x); } function handleDragOver({ over }: DragOverEvent) { - setOverId(over?.id ?? null) + setOverId(over?.id ?? null); } function handleDragEnd({ active, over }: DragEndEvent) { - resetState() + resetState(); if (projected && over) { - const { depth, parentId } = projected + const { depth, parentId } = projected; const clonedItems: FlattenedItem[] = JSON.parse( - JSON.stringify(flattenTree(items, childrenProp)) - ) - const overIndex = clonedItems.findIndex(({ id }) => id === over.id) + JSON.stringify(flattenTree(items, childrenProp)), + ); + const overIndex = clonedItems.findIndex(({ id }) => id === over.id); - const activeIndex = clonedItems.findIndex(({ id }) => id === active.id) - const activeTreeItem = clonedItems[activeIndex] + const activeIndex = clonedItems.findIndex(({ id }) => id === active.id); + const activeTreeItem = clonedItems[activeIndex]; - clonedItems[activeIndex] = { ...activeTreeItem, depth, parentId } + clonedItems[activeIndex] = { ...activeTreeItem, depth, parentId }; - const sortedItems = arrayMove(clonedItems, activeIndex, overIndex) + const sortedItems = arrayMove(clonedItems, activeIndex, overIndex); const { items: newItems, update } = buildTree( sortedItems, overIndex, - childrenProp - ) + childrenProp, + ); - onChange(update, newItems) + onChange(update, newItems); } } function handleDragCancel() { - resetState() + resetState(); } function resetState() { - setOverId(null) - setActiveId(null) - setOffsetLeft(0) - setCurrentPosition(null) + setOverId(null); + setActiveId(null); + setOffsetLeft(0); + setCurrentPosition(null); - document.body.style.setProperty("cursor", "") + document.body.style.setProperty("cursor", ""); } function handleCollapse(id: UniqueIdentifier) { setCollapsedState((state) => ({ ...state, - [id]: state[id] ? false : true, - })) + [id]: !state[id], + })); } function getMovementAnnouncement( eventName: string, activeId: UniqueIdentifier, - overId?: UniqueIdentifier + overId?: UniqueIdentifier, ) { if (overId && projected) { if (eventName !== "onDragEnd") { @@ -253,70 +257,70 @@ export function SortableTree({ projected.parentId === currentPosition.parentId && overId === currentPosition.overId ) { - return + return; } else { setCurrentPosition({ parentId: projected.parentId, overId, - }) + }); } } const clonedItems: FlattenedItem[] = JSON.parse( - JSON.stringify(flattenTree(items, childrenProp)) - ) - const overIndex = clonedItems.findIndex(({ id }) => id === overId) - const activeIndex = clonedItems.findIndex(({ id }) => id === activeId) - const sortedItems = arrayMove(clonedItems, activeIndex, overIndex) + JSON.stringify(flattenTree(items, childrenProp)), + ); + const overIndex = clonedItems.findIndex(({ id }) => id === overId); + const activeIndex = clonedItems.findIndex(({ id }) => id === activeId); + const sortedItems = arrayMove(clonedItems, activeIndex, overIndex); - const previousItem = sortedItems[overIndex - 1] + const previousItem = sortedItems[overIndex - 1]; - let announcement - const movedVerb = eventName === "onDragEnd" ? "dropped" : "moved" - const nestedVerb = eventName === "onDragEnd" ? "dropped" : "nested" + let announcement; + const movedVerb = eventName === "onDragEnd" ? "dropped" : "moved"; + const nestedVerb = eventName === "onDragEnd" ? "dropped" : "nested"; if (!previousItem) { - const nextItem = sortedItems[overIndex + 1] - announcement = `${activeId} was ${movedVerb} before ${nextItem.id}.` + const nextItem = sortedItems[overIndex + 1]; + announcement = `${activeId} was ${movedVerb} before ${nextItem.id}.`; } else { if (projected.depth > previousItem.depth) { - announcement = `${activeId} was ${nestedVerb} under ${previousItem.id}.` + announcement = `${activeId} was ${nestedVerb} under ${previousItem.id}.`; } else { - let previousSibling: FlattenedItem | undefined = previousItem + let previousSibling: FlattenedItem | undefined = previousItem; while (previousSibling && projected.depth < previousSibling.depth) { - const parentId: UniqueIdentifier | null = previousSibling.parentId - previousSibling = sortedItems.find(({ id }) => id === parentId) + const parentId: UniqueIdentifier | null = previousSibling.parentId; + previousSibling = sortedItems.find(({ id }) => id === parentId); } if (previousSibling) { - announcement = `${activeId} was ${movedVerb} after ${previousSibling.id}.` + announcement = `${activeId} was ${movedVerb} after ${previousSibling.id}.`; } } } - return announcement + return announcement; } - return + return; } const announcements: Announcements = { onDragStart({ active }) { - return `Picked up ${active.id}.` + return `Picked up ${active.id}.`; }, onDragMove({ active, over }) { - return getMovementAnnouncement("onDragMove", active.id, over?.id) + return getMovementAnnouncement("onDragMove", active.id, over?.id); }, onDragOver({ active, over }) { - return getMovementAnnouncement("onDragOver", active.id, over?.id) + return getMovementAnnouncement("onDragOver", active.id, over?.id); }, onDragEnd({ active, over }) { - return getMovementAnnouncement("onDragEnd", active.id, over?.id) + return getMovementAnnouncement("onDragEnd", active.id, over?.id); }, onDragCancel({ active }) { - return `Moving was cancelled. ${active.id} was dropped in its original position.` + return `Moving was cancelled. ${active.id} was dropped in its original position.`; }, - } + }; return ( ({ > {flattenedItems.map((item) => { - const { id, depth } = item - const children = (item[childrenProp] || []) as FlattenedItem[] + const { id, depth } = item; + const children = (item[childrenProp] || []) as FlattenedItem[]; const disabled = typeof enableDrag === "function" ? !enableDrag(item as unknown as T) - : !enableDrag + : !enableDrag; return ( ({ : undefined } /> - ) + ); })} {createPortal( @@ -371,9 +375,9 @@ export function SortableTree({ /> ) : null} , - document.body + document.body, )} - ) + ); } diff --git a/src/components/common/sortable-tree/tree-item.tsx b/src/components/common/sortable-tree/tree-item.tsx index 1516e68a..7e9625fc 100644 --- a/src/components/common/sortable-tree/tree-item.tsx +++ b/src/components/common/sortable-tree/tree-item.tsx @@ -1,4 +1,6 @@ -import React, { forwardRef, HTMLAttributes, ReactNode } from "react" +import type { HTMLAttributes, ReactNode } from "react"; +import type React from "react"; +import { forwardRef } from "react"; import { DotsSix, @@ -6,25 +8,26 @@ import { FolderOpenIllustration, TagIllustration, TriangleRightMini, -} from "@medusajs/icons" -import { Badge, clx, IconButton } from "@medusajs/ui" -import { HandleProps } from "./types" +} from "@medusajs/icons"; +import { Badge, IconButton, clx } from "@medusajs/ui"; + +import type { HandleProps } from "./types"; export interface TreeItemProps extends Omit, "id"> { - childCount?: number - clone?: boolean - collapsed?: boolean - depth: number - disableInteraction?: boolean - disableSelection?: boolean - ghost?: boolean - handleProps?: HandleProps - indentationWidth: number - value: ReactNode - disabled?: boolean - onCollapse?(): void - wrapperRef?(node: HTMLLIElement): void + childCount?: number; + clone?: boolean; + collapsed?: boolean; + depth: number; + disableInteraction?: boolean; + disableSelection?: boolean; + ghost?: boolean; + handleProps?: HandleProps; + indentationWidth: number; + value: ReactNode; + disabled?: boolean; + onCollapse?(): void; + wrapperRef?(node: HTMLLIElement): void; } export const TreeItem = forwardRef( @@ -46,86 +49,74 @@ export const TreeItem = forwardRef( wrapperRef, ...props }, - ref - ) => { - return ( -
  • ( +
  • div]:border-t-0": !clone, + })} + {...props} + > +
    div]:border-t-0": !clone, - })} - {...props} + "border-l": depth > 0, + "w-fit rounded-lg border-none bg-ui-bg-base pr-6 opacity-80 shadow-elevation-flyout": + clone, + "z-[1] bg-ui-bg-base-hover opacity-50": ghost, + "bg-ui-bg-disabled": disabled, + }, + )} > -
    0, - "shadow-elevation-flyout bg-ui-bg-base w-fit rounded-lg border-none pr-6 opacity-80": - clone, - "bg-ui-bg-base-hover z-[1] opacity-50": ghost, - "bg-ui-bg-disabled": disabled, - } - )} - > - - - - - -
    -
  • - ) - } -) -TreeItem.displayName = "TreeItem" + + + + + +
    + + ), +); +TreeItem.displayName = "TreeItem"; const Handle = ({ listeners, attributes, disabled, -}: HandleProps & { disabled?: boolean }) => { - return ( - - - - ) -} +}: HandleProps & { disabled?: boolean }) => ( + + + +); type IconProps = { - childrenCount?: number - collapsed?: boolean - clone?: boolean -} + childrenCount?: number; + collapsed?: boolean; + clone?: boolean; +}; const Icon = ({ childrenCount, collapsed, clone }: IconProps) => { - const isBranch = clone ? childrenCount && childrenCount > 1 : childrenCount - const isOpen = clone ? false : !collapsed + const isBranch = clone ? childrenCount && childrenCount > 1 : childrenCount; + const isOpen = clone ? false : !collapsed; return (
    @@ -139,22 +130,22 @@ const Icon = ({ childrenCount, collapsed, clone }: IconProps) => { )}
    - ) -} + ); +}; type CollapseProps = { - collapsed?: boolean - onCollapse?: () => void - clone?: boolean -} + collapsed?: boolean; + onCollapse?: () => void; + clone?: boolean; +}; const Collapse = ({ collapsed, onCollapse, clone }: CollapseProps) => { if (clone) { - return null + return null; } if (!onCollapse) { - return
    + return
    ; } return ( @@ -170,38 +161,36 @@ const Collapse = ({ collapsed, onCollapse, clone }: CollapseProps) => { })} /> - ) -} + ); +}; type ValueProps = { - value: ReactNode -} + value: ReactNode; +}; -const Value = ({ value }: ValueProps) => { - return ( -
    - {value} -
    - ) -} +const Value = ({ value }: ValueProps) => ( +
    + {value} +
    +); type ChildrenCountProps = { - clone?: boolean - childrenCount?: number -} + clone?: boolean; + childrenCount?: number; +}; const ChildrenCount = ({ clone, childrenCount }: ChildrenCountProps) => { if (!clone || !childrenCount) { - return null + return null; } if (clone && childrenCount <= 1) { - return null + return null; } return ( {childrenCount} - ) -} + ); +}; diff --git a/src/components/common/sortable-tree/types.ts b/src/components/common/sortable-tree/types.ts index 8b78d701..ad7b261a 100644 --- a/src/components/common/sortable-tree/types.ts +++ b/src/components/common/sortable-tree/types.ts @@ -1,23 +1,24 @@ -import type { DraggableAttributes, UniqueIdentifier } from "@dnd-kit/core" -import { SyntheticListenerMap } from "@dnd-kit/core/dist/hooks/utilities" -import type { MutableRefObject } from "react" +import type { MutableRefObject } from "react"; + +import type { DraggableAttributes, UniqueIdentifier } from "@dnd-kit/core"; +import type { SyntheticListenerMap } from "@dnd-kit/core/dist/hooks/utilities"; export interface TreeItem extends Record { - id: UniqueIdentifier + id: UniqueIdentifier; } export interface FlattenedItem extends TreeItem { - parentId: UniqueIdentifier | null - depth: number - index: number + parentId: UniqueIdentifier | null; + depth: number; + index: number; } export type SensorContext = MutableRefObject<{ - items: FlattenedItem[] - offset: number -}> + items: FlattenedItem[]; + offset: number; +}>; export type HandleProps = { - attributes?: DraggableAttributes | undefined - listeners?: SyntheticListenerMap | undefined -} + attributes?: DraggableAttributes | undefined; + listeners?: SyntheticListenerMap | undefined; +}; diff --git a/src/components/common/sortable-tree/utils.ts b/src/components/common/sortable-tree/utils.ts index 064546dc..99db0ace 100644 --- a/src/components/common/sortable-tree/utils.ts +++ b/src/components/common/sortable-tree/utils.ts @@ -1,12 +1,12 @@ -import type { UniqueIdentifier } from "@dnd-kit/core" -import { arrayMove } from "@dnd-kit/sortable" +import type { UniqueIdentifier } from "@dnd-kit/core"; +import { arrayMove } from "@dnd-kit/sortable"; -import type { FlattenedItem, TreeItem } from "./types" +import type { FlattenedItem, TreeItem } from "./types"; -export const iOS = /iPad|iPhone|iPod/.test(navigator.platform) +export const iOS = /iPad|iPhone|iPod/.test(navigator.platform); function getDragDepth(offset: number, indentationWidth: number) { - return Math.round(offset / indentationWidth) + return Math.round(offset / indentationWidth); } export function getProjection( @@ -14,191 +14,193 @@ export function getProjection( activeId: UniqueIdentifier, overId: UniqueIdentifier, dragOffset: number, - indentationWidth: number + indentationWidth: number, ) { - const overItemIndex = items.findIndex(({ id }) => id === overId) - const activeItemIndex = items.findIndex(({ id }) => id === activeId) - const activeItem = items[activeItemIndex] - const newItems = arrayMove(items, activeItemIndex, overItemIndex) - const previousItem = newItems[overItemIndex - 1] - const nextItem = newItems[overItemIndex + 1] - const dragDepth = getDragDepth(dragOffset, indentationWidth) - const projectedDepth = activeItem.depth + dragDepth + const overItemIndex = items.findIndex(({ id }) => id === overId); + const activeItemIndex = items.findIndex(({ id }) => id === activeId); + const activeItem = items[activeItemIndex]; + const newItems = arrayMove(items, activeItemIndex, overItemIndex); + const previousItem = newItems[overItemIndex - 1]; + const nextItem = newItems[overItemIndex + 1]; + const dragDepth = getDragDepth(dragOffset, indentationWidth); + const projectedDepth = activeItem.depth + dragDepth; const maxDepth = getMaxDepth({ previousItem, - }) - const minDepth = getMinDepth({ nextItem }) - let depth = projectedDepth + }); + const minDepth = getMinDepth({ nextItem }); + let depth = projectedDepth; if (projectedDepth >= maxDepth) { - depth = maxDepth + depth = maxDepth; } else if (projectedDepth < minDepth) { - depth = minDepth + depth = minDepth; } - return { depth, maxDepth, minDepth, parentId: getParentId() } + return { depth, maxDepth, minDepth, parentId: getParentId() }; function getParentId() { if (depth === 0 || !previousItem) { - return null + return null; } if (depth === previousItem.depth) { - return previousItem.parentId + return previousItem.parentId; } if (depth > previousItem.depth) { - return previousItem.id + return previousItem.id; } const newParent = newItems .slice(0, overItemIndex) .reverse() - .find((item) => item.depth === depth)?.parentId + .find((item) => item.depth === depth)?.parentId; - return newParent ?? null + return newParent ?? null; } } function getMaxDepth({ previousItem }: { previousItem: FlattenedItem }) { if (previousItem) { - return previousItem.depth + 1 + return previousItem.depth + 1; } - return 0 + return 0; } function getMinDepth({ nextItem }: { nextItem: FlattenedItem }) { if (nextItem) { - return nextItem.depth + return nextItem.depth; } - return 0 + return 0; } function flatten( items: T[], parentId: UniqueIdentifier | null = null, depth = 0, - childrenProp: string + childrenProp: string, ): FlattenedItem[] { return items.reduce((acc, item, index) => { - const children = (item[childrenProp] || []) as T[] + const children = (item[childrenProp] || []) as T[]; return [ ...acc, { ...item, parentId, depth, index }, ...flatten(children, item.id, depth + 1, childrenProp), - ] - }, []) + ]; + }, []); } export function flattenTree( items: T[], - childrenProp: string + childrenProp: string, ): FlattenedItem[] { - return flatten(items, undefined, undefined, childrenProp) + return flatten(items, undefined, undefined, childrenProp); } type ItemUpdate = { - id: UniqueIdentifier - parentId: UniqueIdentifier | null - index: number -} + id: UniqueIdentifier; + parentId: UniqueIdentifier | null; + index: number; +}; export function buildTree( flattenedItems: FlattenedItem[], newIndex: number, - childrenProp: string + childrenProp: string, ): { items: T[]; update: ItemUpdate } { - const root = { id: "root", [childrenProp]: [] } as T - const nodes: Record = { [root.id]: root } - const items = flattenedItems.map((item) => ({ ...item, [childrenProp]: [] })) + const root = { id: "root", [childrenProp]: [] } as T; + const nodes: Record = { [root.id]: root }; + const items = flattenedItems.map((item) => ({ ...item, [childrenProp]: [] })); let update: { - id: UniqueIdentifier | null - parentId: UniqueIdentifier | null - index: number + id: UniqueIdentifier | null; + parentId: UniqueIdentifier | null; + index: number; } = { id: null, parentId: null, index: 0, - } + }; items.forEach((item, index) => { const { id, + // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-unused-vars index: _index, + // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-unused-vars depth: _depth, parentId: _parentId, ...rest - } = item - const children = (item[childrenProp] || []) as T[] + } = item; + const children = (item[childrenProp] || []) as T[]; - const parentId = _parentId ?? root.id - const parent = nodes[parentId] ?? findItem(items, parentId) + const parentId = _parentId ?? root.id; + const parent = nodes[parentId] ?? findItem(items, parentId); - nodes[id] = { id, [childrenProp]: children } as T - ;(parent[childrenProp] as T[]).push({ + nodes[id] = { id, [childrenProp]: children } as T; + (parent[childrenProp] as T[]).push({ id, ...rest, [childrenProp]: children, - } as T) + } as T); /** * Get the information for them item that was moved to the `newIndex`. */ if (index === newIndex) { - const parentChildren = parent[childrenProp] as FlattenedItem[] + const parentChildren = parent[childrenProp] as FlattenedItem[]; update = { id: item.id, parentId: parent.id === "root" ? null : parent.id, index: parentChildren.length - 1, - } + }; } - }) + }); if (!update.id) { - throw new Error("Could not find item") + throw new Error("Could not find item"); } return { items: root[childrenProp] as T[], update: update as ItemUpdate, - } + }; } export function findItem( items: T[], - itemId: UniqueIdentifier + itemId: UniqueIdentifier, ) { - return items.find(({ id }) => id === itemId) + return items.find(({ id }) => id === itemId); } export function findItemDeep( items: T[], itemId: UniqueIdentifier, - childrenProp: string + childrenProp: string, ): TreeItem | undefined { for (const item of items) { - const { id } = item - const children = (item[childrenProp] || []) as T[] + const { id } = item; + const children = (item[childrenProp] || []) as T[]; if (id === itemId) { - return item + return item; } if (children.length) { - const child = findItemDeep(children, itemId, childrenProp) + const child = findItemDeep(children, itemId, childrenProp); if (child) { - return child + return child; } } } - return undefined + return undefined; } export function setProperty( @@ -206,17 +208,17 @@ export function setProperty( id: UniqueIdentifier, property: T, childrenProp: keyof TItem, // Make childrenProp a key of TItem - setter: (value: TItem[T]) => TItem[T] + setter: (value: TItem[T]) => TItem[T], ): TItem[] { return items.map((item) => { if (item.id === id) { return { ...item, [property]: setter(item[property]), - } + }; } - const children = item[childrenProp] as TItem[] | undefined + const children = item[childrenProp] as TItem[] | undefined; if (children && children.length) { return { @@ -226,67 +228,68 @@ export function setProperty( id, property, childrenProp, - setter + setter, ), - } as TItem // Explicitly cast to TItem + } as TItem; // Explicitly cast to TItem } - return item - }) + return item; + }); } function countChildren( items: T[], count = 0, - childrenProp: string + childrenProp: string, ): number { return items.reduce((acc, item) => { - const children = (item[childrenProp] || []) as T[] + const children = (item[childrenProp] || []) as T[]; if (children.length) { - return countChildren(children, acc + 1, childrenProp) + return countChildren(children, acc + 1, childrenProp); } - return acc + 1 - }, count) + return acc + 1; + }, count); } export function getChildCount( items: T[], id: UniqueIdentifier, - childrenProp: string + childrenProp: string, ) { - const item = findItemDeep(items, id, childrenProp) + const item = findItemDeep(items, id, childrenProp); - const children = (item?.[childrenProp] || []) as T[] + const children = (item?.[childrenProp] || []) as T[]; - return item ? countChildren(children, 0, childrenProp) : 0 + return item ? countChildren(children, 0, childrenProp) : 0; } export function removeChildrenOf( items: FlattenedItem[], ids: UniqueIdentifier[], - childrenProp: string + childrenProp: string, ) { - const excludeParentIds = [...ids] + const excludeParentIds = [...ids]; return items.filter((item) => { if (item.parentId && excludeParentIds.includes(item.parentId)) { - const children = (item[childrenProp] || []) as FlattenedItem[] + const children = (item[childrenProp] || []) as FlattenedItem[]; if (children.length) { - excludeParentIds.push(item.id) + excludeParentIds.push(item.id); } - return false + + return false; } - return true - }) + return true; + }); } export function listItemsWithChildren( items: T[], - childrenProp: string + childrenProp: string, ): T[] { return items.map((item) => { return { @@ -294,6 +297,6 @@ export function listItemsWithChildren( [childrenProp]: item[childrenProp] ? listItemsWithChildren(item[childrenProp] as TreeItem[], childrenProp) : [], - } - }) + }; + }); } From 8a76ff4c08507bb8c6a3888835e622af4a373011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 16:11:01 +0200 Subject: [PATCH 030/195] eslint/prettier - fix components/common/switch-box --- src/components/common/switch-box/index.ts | 2 +- .../common/switch-box/switch-box.tsx | 88 +++++++++---------- 2 files changed, 44 insertions(+), 46 deletions(-) diff --git a/src/components/common/switch-box/index.ts b/src/components/common/switch-box/index.ts index c245e8b7..f305f15b 100644 --- a/src/components/common/switch-box/index.ts +++ b/src/components/common/switch-box/index.ts @@ -1 +1 @@ -export * from "./switch-box" +export * from "./switch-box"; diff --git a/src/components/common/switch-box/switch-box.tsx b/src/components/common/switch-box/switch-box.tsx index 4fde523d..ae8eebc6 100644 --- a/src/components/common/switch-box/switch-box.tsx +++ b/src/components/common/switch-box/switch-box.tsx @@ -1,27 +1,29 @@ -import { Switch } from "@medusajs/ui" -import { ReactNode } from "react" -import { ControllerProps, FieldPath, FieldValues } from "react-hook-form" +import type { ReactNode } from "react"; -import { Form } from "../../common/form" +import { Switch } from "@medusajs/ui"; -interface HeadlessControllerProps< +import type { ControllerProps, FieldPath, FieldValues } from "react-hook-form"; + +import { Form } from "@/components/common/form"; + +type HeadlessControllerProps< TFieldValues extends FieldValues = FieldValues, TName extends FieldPath = FieldPath, -> extends Omit, "render"> {} +> = Omit, "render">; interface SwitchBoxProps< TFieldValues extends FieldValues = FieldValues, TName extends FieldPath = FieldPath, > extends HeadlessControllerProps { - label: string - description: string - optional?: boolean - tooltip?: ReactNode + label: string; + description: string; + optional?: boolean; + tooltip?: ReactNode; /** * Callback for performing additional actions when the checked state changes. * This does not intercept the form control, it is only used for injecting side-effects. */ - onCheckedChange?: (checked: boolean) => void + onCheckedChange?: (checked: boolean) => void; } /** @@ -40,37 +42,33 @@ export const SwitchBox = < tooltip, onCheckedChange, ...props -}: SwitchBoxProps) => { - return ( - { - return ( - -
    - - { - onCheckedChange?.(e) - onChange(e) - }} - /> - -
    - - {label} - - {description} -
    -
    - -
    - ) - }} - /> - ) -} +}: SwitchBoxProps) => ( + ( + +
    + + { + onCheckedChange?.(e); + onChange(e); + }} + /> + +
    + + {label} + + {description} +
    +
    + +
    + )} + /> +); From fe7637a6cf3fac250ca93fa5cd6701377e9ea7fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 16:12:21 +0200 Subject: [PATCH 031/195] eslint/prettier - fix components/common/tax-badge --- src/components/common/tax-badge/index.ts | 1 + src/components/common/tax-badge/tax-badge.tsx | 21 ++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 src/components/common/tax-badge/index.ts diff --git a/src/components/common/tax-badge/index.ts b/src/components/common/tax-badge/index.ts new file mode 100644 index 00000000..00f6a596 --- /dev/null +++ b/src/components/common/tax-badge/index.ts @@ -0,0 +1 @@ +export * from "./tax-badge"; diff --git a/src/components/common/tax-badge/tax-badge.tsx b/src/components/common/tax-badge/tax-badge.tsx index c8ca4295..cb181f5b 100644 --- a/src/components/common/tax-badge/tax-badge.tsx +++ b/src/components/common/tax-badge/tax-badge.tsx @@ -1,15 +1,16 @@ -import { TaxExclusive, TaxInclusive } from "@medusajs/icons" -import { Tooltip } from "@medusajs/ui" -import { useTranslation } from "react-i18next" +import { TaxExclusive, TaxInclusive } from "@medusajs/icons"; +import { Tooltip } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; type IncludesTaxTooltipProps = { - includesTax?: boolean -} + includesTax?: boolean; +}; export const IncludesTaxTooltip = ({ includesTax, }: IncludesTaxTooltipProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); return ( {includesTax ? ( - + ) : ( - + )} - ) -} + ); +}; From 403861d01d154cf8b889846816a4e7ee08d42448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 16:12:49 +0200 Subject: [PATCH 032/195] eslint/prettier - fix components/common/thumbnail --- src/components/common/thumbnail/thumbnail.tsx | 56 +++++++++---------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/src/components/common/thumbnail/thumbnail.tsx b/src/components/common/thumbnail/thumbnail.tsx index 5e32de1c..f9ea44df 100644 --- a/src/components/common/thumbnail/thumbnail.tsx +++ b/src/components/common/thumbnail/thumbnail.tsx @@ -1,32 +1,30 @@ -import { Photo } from "@medusajs/icons" -import { clx } from "@medusajs/ui" +import { Photo } from "@medusajs/icons"; +import { clx } from "@medusajs/ui"; type ThumbnailProps = { - src?: string | null - alt?: string - size?: "small" | "base" -} + src?: string | null; + alt?: string; + size?: "small" | "base"; +}; -export const Thumbnail = ({ src, alt, size = "base" }: ThumbnailProps) => { - return ( -
    - {src ? ( - {alt} - ) : ( - - )} -
    - ) -} +export const Thumbnail = ({ src, alt, size = "base" }: ThumbnailProps) => ( +
    + {src ? ( + {alt} + ) : ( + + )} +
    +); From 52bbb058e5ded2ec24b9753f295b74ba623578ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 16:13:24 +0200 Subject: [PATCH 033/195] eslint/prettier - fix components/common/user-link --- src/components/common/user-link/index.ts | 2 +- src/components/common/user-link/user-link.tsx | 40 ++++++++++--------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/components/common/user-link/index.ts b/src/components/common/user-link/index.ts index 951235f8..686ccd33 100644 --- a/src/components/common/user-link/index.ts +++ b/src/components/common/user-link/index.ts @@ -1 +1 @@ -export * from "./user-link" +export * from "./user-link"; diff --git a/src/components/common/user-link/user-link.tsx b/src/components/common/user-link/user-link.tsx index 239abb8b..a2704731 100644 --- a/src/components/common/user-link/user-link.tsx +++ b/src/components/common/user-link/user-link.tsx @@ -1,14 +1,16 @@ -import { Avatar, Text } from "@medusajs/ui" -import { Link } from "react-router-dom" -import { useUser } from "../../../hooks/api/users" +import { Avatar, Text } from "@medusajs/ui"; + +import { Link } from "react-router-dom"; + +import { useUser } from "@hooks/api"; type UserLinkProps = { - id: string - first_name?: string | null - last_name?: string | null - email: string - type?: "customer" | "user" -} + id: string; + first_name?: string | null; + last_name?: string | null; + email: string; + type?: "customer" | "user"; +}; export const UserLink = ({ id, @@ -17,29 +19,29 @@ export const UserLink = ({ email, type = "user", }: UserLinkProps) => { - const name = [first_name, last_name].filter(Boolean).join(" ") - const fallback = name ? name.slice(0, 1) : email.slice(0, 1) - const link = type === "user" ? `/settings/users/${id}` : `/customers/${id}` + const name = [first_name, last_name].filter(Boolean).join(" "); + const fallback = name ? name.slice(0, 1) : email.slice(0, 1); + const link = type === "user" ? `/settings/users/${id}` : `/customers/${id}`; return ( {name || email} - ) -} + ); +}; export const By = ({ id }: { id: string }) => { - const { user } = useUser(id) // todo: extend to support customers + const { user } = useUser(id); // todo: extend to support customers if (!user) { - return null + return null; } - return -} + return ; +}; From 998a625538c366b3329c31ddfe9f33eac3966c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 16:59:40 +0200 Subject: [PATCH 034/195] eslint/prettier - fix components/data-grid/components --- .../components/data-grid-boolean-cell.tsx | 68 +-- .../components/data-grid-cell-container.tsx | 58 ++- .../components/data-grid-currency-cell.tsx | 123 ++--- .../components/data-grid-duplicate-cell.tsx | 17 +- .../data-grid-keyboard-shortcut-modal.tsx | 60 +-- .../components/data-grid-number-cell.tsx | 93 ++-- .../components/data-grid-readonly-cell.tsx | 28 +- .../data-grid/components/data-grid-root.tsx | 474 +++++++++--------- .../data-grid-row-error-indicator.tsx | 30 +- .../components/data-grid-skeleton.tsx | 63 ++- .../components/data-grid-text-cell.tsx | 82 +-- .../data-grid-toggleable-number-cell.tsx | 191 +++---- src/components/data-grid/components/index.ts | 15 +- 13 files changed, 698 insertions(+), 604 deletions(-) diff --git a/src/components/data-grid/components/data-grid-boolean-cell.tsx b/src/components/data-grid/components/data-grid-boolean-cell.tsx index f9dad4b9..9450b31a 100644 --- a/src/components/data-grid/components/data-grid-boolean-cell.tsx +++ b/src/components/data-grid/components/data-grid-boolean-cell.tsx @@ -1,56 +1,66 @@ -import { Checkbox } from "@medusajs/ui" -import { Controller, ControllerRenderProps } from "react-hook-form" +import { Checkbox } from "@medusajs/ui"; -import { useCombinedRefs } from "../../../hooks/use-combined-refs" -import { useDataGridCell, useDataGridCellError } from "../hooks" -import { DataGridCellProps, InputProps } from "../types" -import { DataGridCellContainer } from "./data-grid-cell-container" +import type { ControllerRenderProps } from "react-hook-form"; +import { Controller } from "react-hook-form"; -export const DataGridBooleanCell = ({ +import { + useDataGridCell, + useDataGridCellError, +} from "@components/data-grid/hooks"; +import type { + DataGridCellProps, + InputProps, +} from "@components/data-grid/types"; + +import { useCombinedRefs } from "@hooks/use-combined-refs.tsx"; + +import { DataGridCellContainer } from "./data-grid-cell-container"; + +export const DataGridBooleanCell = ({ context, disabled, }: DataGridCellProps & { disabled?: boolean }) => { const { field, control, renderProps } = useDataGridCell({ context, - }) - const errorProps = useDataGridCellError({ context }) + }); + const errorProps = useDataGridCellError({ context }); - const { container, input } = renderProps + const { container, input } = renderProps; return ( { - return ( - - - - ) - }} + render={({ field }) => ( + + + + )} /> - ) -} + ); +}; const Inner = ({ field, inputProps, disabled, }: { - field: ControllerRenderProps - inputProps: InputProps - disabled?: boolean + //@todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + field: ControllerRenderProps; + inputProps: InputProps; + disabled?: boolean; }) => { - const { ref, value, onBlur, name, disabled: fieldDisabled } = field + const { ref, value, onBlur, name, disabled: fieldDisabled } = field; const { ref: inputRef, onBlur: onInputBlur, onChange, onFocus, ...attributes - } = inputProps + } = inputProps; - const combinedRefs = useCombinedRefs(ref, inputRef) + const combinedRefs = useCombinedRefs(ref, inputRef); return ( onChange(newValue === true, value)} onFocus={onFocus} onBlur={() => { - onBlur() - onInputBlur() + onBlur(); + onInputBlur(); }} ref={combinedRefs} tabIndex={-1} {...attributes} /> - ) -} + ); +}; diff --git a/src/components/data-grid/components/data-grid-cell-container.tsx b/src/components/data-grid/components/data-grid-cell-container.tsx index 3a4f8136..67a380e1 100644 --- a/src/components/data-grid/components/data-grid-cell-container.tsx +++ b/src/components/data-grid/components/data-grid-cell-container.tsx @@ -1,11 +1,17 @@ -import { ErrorMessage } from "@hookform/error-message" -import { ExclamationCircle } from "@medusajs/icons" -import { Tooltip, clx } from "@medusajs/ui" -import { PropsWithChildren } from "react" -import { get } from "react-hook-form" +import type { PropsWithChildren } from "react"; -import { DataGridCellContainerProps, DataGridErrorRenderProps } from "../types" -import { DataGridRowErrorIndicator } from "./data-grid-row-error-indicator" +import { ExclamationCircle } from "@medusajs/icons"; +import { Tooltip, clx } from "@medusajs/ui"; + +import { ErrorMessage } from "@hookform/error-message"; +import { get } from "react-hook-form"; + +import type { + DataGridCellContainerProps, + DataGridErrorRenderProps, +} from "@components/data-grid/types"; + +import { DataGridRowErrorIndicator } from "./data-grid-row-error-indicator"; export const DataGridCellContainer = ({ isAnchor, @@ -20,23 +26,25 @@ export const DataGridCellContainer = ({ errors, rowErrors, outerComponent, + //@todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any }: DataGridCellContainerProps & DataGridErrorRenderProps) => { - const error = get(errors, field) - const hasError = !!error + const error = get(errors, field); + const hasError = !!error; return (
    { - return ( -
    - - - -
    - ) - }} + render={({ message }) => ( +
    + + + +
    + )} />
    @@ -70,8 +76,8 @@ export const DataGridCellContainer = ({
    {outerComponent}
    - ) -} + ); +}; const RenderChildren = ({ isAnchor, @@ -81,8 +87,8 @@ const RenderChildren = ({ Pick >) => { if (!isAnchor && placeholder) { - return placeholder + return placeholder; } - return children -} + return children; +}; diff --git a/src/components/data-grid/components/data-grid-currency-cell.tsx b/src/components/data-grid/components/data-grid-currency-cell.tsx index 2c50b5df..efb26454 100644 --- a/src/components/data-grid/components/data-grid-currency-cell.tsx +++ b/src/components/data-grid/components/data-grid-currency-cell.tsx @@ -1,116 +1,127 @@ -import CurrencyInput, { - CurrencyInputProps, - formatValue, -} from "react-currency-input-field" -import { Controller, ControllerRenderProps } from "react-hook-form" - -import { useCallback, useEffect, useState } from "react" -import { useCombinedRefs } from "../../../hooks/use-combined-refs" -import { CurrencyInfo, currencies } from "../../../lib/data/currencies" -import { useDataGridCell, useDataGridCellError } from "../hooks" -import { DataGridCellProps, InputProps } from "../types" -import { DataGridCellContainer } from "./data-grid-cell-container" +import { useCallback, useEffect, useState } from "react"; +import type { CurrencyInputProps } from "react-currency-input-field"; +import CurrencyInput, { formatValue } from "react-currency-input-field"; +import type { ControllerRenderProps } from "react-hook-form"; +import { Controller } from "react-hook-form"; + +import { + useDataGridCell, + useDataGridCellError, +} from "@components/data-grid/hooks"; +import type { + DataGridCellProps, + InputProps, +} from "@components/data-grid/types"; + +import { useCombinedRefs } from "@hooks/use-combined-refs.tsx"; + +import type { CurrencyInfo } from "@lib/data/currencies.ts"; +import { currencies } from "@lib/data/currencies.ts"; + +import { DataGridCellContainer } from "./data-grid-cell-container"; + +//@todo fix type +// eslint-disable-next-line @typescript-eslint/no-explicit-any interface DataGridCurrencyCellProps extends DataGridCellProps { - code: string + code: string; } +//@todo fix type +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const DataGridCurrencyCell = ({ context, code, }: DataGridCurrencyCellProps) => { const { field, control, renderProps } = useDataGridCell({ context, - }) - const errorProps = useDataGridCellError({ context }) + }); + const errorProps = useDataGridCellError({ context }); - const { container, input } = renderProps + const { container, input } = renderProps; - const currency = currencies[code.toUpperCase()] + const currency = currencies[code.toUpperCase()]; return ( { - return ( - - - - ) - }} + render={({ field }) => ( + + + + )} /> - ) -} + ); +}; const Inner = ({ field, inputProps, currencyInfo, }: { - field: ControllerRenderProps - inputProps: InputProps - currencyInfo: CurrencyInfo + //@todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + field: ControllerRenderProps; + inputProps: InputProps; + currencyInfo: CurrencyInfo; }) => { - const { value, onChange: _, onBlur, ref, ...rest } = field + const { value, onBlur, ref, ...rest } = field; const { ref: inputRef, onBlur: onInputBlur, onFocus, onChange, ...attributes - } = inputProps + } = inputProps; const formatter = useCallback( (value?: string | number) => { const ensuredValue = - typeof value === "number" ? value.toString() : value || "" + typeof value === "number" ? value.toString() : value || ""; return formatValue({ value: ensuredValue, decimalScale: currencyInfo.decimal_digits, disableGroupSeparators: true, decimalSeparator: ".", - }) + }); }, - [currencyInfo] - ) + [currencyInfo], + ); - const [localValue, setLocalValue] = useState(value || "") + const [localValue, setLocalValue] = useState(value || ""); - const handleValueChange: CurrencyInputProps["onValueChange"] = ( - value, - _name, - _values - ) => { + const handleValueChange: CurrencyInputProps["onValueChange"] = (value) => { if (!value) { - setLocalValue("") - return + setLocalValue(""); + + return; } - setLocalValue(value) - } + setLocalValue(value); + }; useEffect(() => { - let update = value + let update = value; // The component we use is a bit fidly when the value is updated externally // so we need to ensure a format that will result in the cell being formatted correctly // according to the users locale on the next render. if (!isNaN(Number(value))) { - update = formatter(update) + update = formatter(update); } - setLocalValue(update) - }, [value, formatter]) + setLocalValue(update); + }, [value, formatter]); - const combinedRed = useCombinedRefs(inputRef, ref) + const combinedRed = useCombinedRefs(inputRef, ref); return (
    {currencyInfo.symbol_native} @@ -124,10 +135,10 @@ const Inner = ({ onValueChange={handleValueChange} formatValueOnBlur onBlur={() => { - onBlur() - onInputBlur() + onBlur(); + onInputBlur(); - onChange(localValue, value) + onChange(localValue, value); }} onFocus={onFocus} decimalScale={currencyInfo.decimal_digits} @@ -136,5 +147,5 @@ const Inner = ({ tabIndex={-1} />
    - ) -} + ); +}; diff --git a/src/components/data-grid/components/data-grid-duplicate-cell.tsx b/src/components/data-grid/components/data-grid-duplicate-cell.tsx index 19e8218f..56ecbdf8 100644 --- a/src/components/data-grid/components/data-grid-duplicate-cell.tsx +++ b/src/components/data-grid/components/data-grid-duplicate-cell.tsx @@ -1,21 +1,22 @@ -import { ReactNode } from "react" -import { useDataGridDuplicateCell } from "../hooks" +import type { ReactNode } from "react"; + +import { useDataGridDuplicateCell } from "@components/data-grid/hooks"; interface DataGridDuplicateCellProps { - duplicateOf: string - children?: ReactNode | ((props: { value: TValue }) => ReactNode) + duplicateOf: string; + children?: ReactNode | ((props: { value: TValue }) => ReactNode); } export const DataGridDuplicateCell = ({ duplicateOf, children, }: DataGridDuplicateCellProps) => { - const { watchedValue } = useDataGridDuplicateCell({ duplicateOf }) + const { watchedValue } = useDataGridDuplicateCell({ duplicateOf }); return ( -
    +
    {typeof children === "function" ? children({ value: watchedValue }) : children}
    - ) -} + ); +}; diff --git a/src/components/data-grid/components/data-grid-keyboard-shortcut-modal.tsx b/src/components/data-grid/components/data-grid-keyboard-shortcut-modal.tsx index a8b5f123..5176708a 100644 --- a/src/components/data-grid/components/data-grid-keyboard-shortcut-modal.tsx +++ b/src/components/data-grid/components/data-grid-keyboard-shortcut-modal.tsx @@ -1,21 +1,23 @@ -import { XMark } from "@medusajs/icons" +import { useMemo, useState } from "react"; + +import { XMark } from "@medusajs/icons"; import { Button, - clx, Heading, IconButton, Input, Kbd, Text, -} from "@medusajs/ui" -import { Dialog as RadixDialog } from "radix-ui" -import { useMemo, useState } from "react" -import { useTranslation } from "react-i18next" + clx, +} from "@medusajs/ui"; + +import { Dialog as RadixDialog } from "radix-ui"; +import { useTranslation } from "react-i18next"; const useDataGridShortcuts = () => { - const { t } = useTranslation() + const { t } = useTranslation(); - const shortcuts = useMemo( + return useMemo( () => [ { label: t("dataGrid.shortcuts.commands.undo"), @@ -151,30 +153,28 @@ const useDataGridShortcuts = () => { }, }, ], - [t] - ) - - return shortcuts -} + [t], + ); +}; type DataGridKeyboardShortcutModalProps = { - open: boolean - onOpenChange: (open: boolean) => void -} + open: boolean; + onOpenChange: (open: boolean) => void; +}; export const DataGridKeyboardShortcutModal = ({ open, onOpenChange, }: DataGridKeyboardShortcutModalProps) => { - const { t } = useTranslation() - const [searchValue, onSearchValueChange] = useState("") - const shortcuts = useDataGridShortcuts() + const { t } = useTranslation(); + const [searchValue, onSearchValueChange] = useState(""); + const shortcuts = useDataGridShortcuts(); const searchResults = useMemo(() => { return shortcuts.filter((shortcut) => - shortcut.label.toLowerCase().includes(searchValue.toLowerCase()) - ) - }, [searchValue, shortcuts]) + shortcut.label.toLowerCase().includes(searchValue.toLowerCase()), + ); + }, [searchValue, shortcuts]); return ( @@ -186,11 +186,11 @@ export const DataGridKeyboardShortcutModal = ({ - +
    @@ -222,7 +222,7 @@ export const DataGridKeyboardShortcutModal = ({ return (
    {shortcut.label}
    @@ -231,15 +231,15 @@ export const DataGridKeyboardShortcutModal = ({
    {key}
    - ) + ); })}
    - ) + ); })}
    - ) -} + ); +}; diff --git a/src/components/data-grid/components/data-grid-number-cell.tsx b/src/components/data-grid/components/data-grid-number-cell.tsx index 86d1f6ab..e41809f8 100644 --- a/src/components/data-grid/components/data-grid-number-cell.tsx +++ b/src/components/data-grid/components/data-grid-number-cell.tsx @@ -1,68 +1,83 @@ -import { clx } from "@medusajs/ui" -import { useEffect, useState } from "react" -import { Controller, ControllerRenderProps } from "react-hook-form" -import { useCombinedRefs } from "../../../hooks/use-combined-refs" -import { useDataGridCell, useDataGridCellError } from "../hooks" -import { DataGridCellProps, InputProps } from "../types" -import { DataGridCellContainer } from "./data-grid-cell-container" +import { useEffect, useState } from "react"; +import { clx } from "@medusajs/ui"; + +import type { ControllerRenderProps } from "react-hook-form"; +import { Controller } from "react-hook-form"; + +import { + useDataGridCell, + useDataGridCellError, +} from "@components/data-grid/hooks"; +import type { + DataGridCellProps, + InputProps, +} from "@components/data-grid/types"; + +import { useCombinedRefs } from "@hooks/use-combined-refs.tsx"; + +import { DataGridCellContainer } from "./data-grid-cell-container"; + +//@todo fix type +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const DataGridNumberCell = ({ context, ...rest }: DataGridCellProps & { - min?: number - max?: number - placeholder?: string + min?: number; + max?: number; + placeholder?: string; }) => { const { field, control, renderProps } = useDataGridCell({ context, - }) - const errorProps = useDataGridCellError({ context }) + }); + const errorProps = useDataGridCellError({ context }); - const { container, input } = renderProps + const { container, input } = renderProps; return ( { - return ( - - - - ) - }} + render={({ field }) => ( + + + + )} /> - ) -} + ); +}; const Inner = ({ field, inputProps, ...props }: { - field: ControllerRenderProps - inputProps: InputProps - min?: number - max?: number - placeholder?: string + //@todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + field: ControllerRenderProps; + inputProps: InputProps; + min?: number; + max?: number; + placeholder?: string; }) => { - const { ref, value, onChange: _, onBlur, ...fieldProps } = field + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { ref, value, onChange: _, onBlur, ...fieldProps } = field; const { ref: inputRef, onChange, onBlur: onInputBlur, onFocus, ...attributes - } = inputProps + } = inputProps; - const [localValue, setLocalValue] = useState(value) + const [localValue, setLocalValue] = useState(value); useEffect(() => { - setLocalValue(value) - }, [value]) + setLocalValue(value); + }, [value]); - const combinedRefs = useCombinedRefs(inputRef, ref) + const combinedRefs = useCombinedRefs(inputRef, ref); return (
    @@ -71,18 +86,18 @@ const Inner = ({ value={localValue} onChange={(e) => setLocalValue(e.target.value)} onBlur={() => { - onBlur() - onInputBlur() + onBlur(); + onInputBlur(); // We propagate the change to the field only when the input is blurred - onChange(localValue, value) + onChange(localValue, value); }} onFocus={onFocus} type="number" inputMode="decimal" className={clx( "txt-compact-small size-full bg-transparent outline-none", - "placeholder:text-ui-fg-muted" + "placeholder:text-ui-fg-muted", )} tabIndex={-1} {...props} @@ -90,5 +105,5 @@ const Inner = ({ {...attributes} />
    - ) -} + ); +}; diff --git a/src/components/data-grid/components/data-grid-readonly-cell.tsx b/src/components/data-grid/components/data-grid-readonly-cell.tsx index cf842684..3ea4a169 100644 --- a/src/components/data-grid/components/data-grid-readonly-cell.tsx +++ b/src/components/data-grid/components/data-grid-readonly-cell.tsx @@ -1,33 +1,37 @@ -import { PropsWithChildren } from "react" +import type { PropsWithChildren } from "react"; -import { clx } from "@medusajs/ui" -import { useDataGridCellError } from "../hooks" -import { DataGridCellProps } from "../types" -import { DataGridRowErrorIndicator } from "./data-grid-row-error-indicator" +import { clx } from "@medusajs/ui"; +import { useDataGridCellError } from "@components/data-grid/hooks"; +import type { DataGridCellProps } from "@components/data-grid/types"; + +import { DataGridRowErrorIndicator } from "./data-grid-row-error-indicator"; + +//@todo fix type +// eslint-disable-next-line @typescript-eslint/no-explicit-any type DataGridReadonlyCellProps = PropsWithChildren< DataGridCellProps > & { - color?: "muted" | "normal" -} + color?: "muted" | "normal"; +}; export const DataGridReadonlyCell = ({ context, color = "muted", children, }: DataGridReadonlyCellProps) => { - const { rowErrors } = useDataGridCellError({ context }) + const { rowErrors } = useDataGridCellError({ context }); return (
    {children}
    - ) -} + ); +}; diff --git a/src/components/data-grid/components/data-grid-root.tsx b/src/components/data-grid/components/data-grid-root.tsx index 64ff426e..0a42ecb7 100644 --- a/src/components/data-grid/components/data-grid-root.tsx +++ b/src/components/data-grid/components/data-grid-root.tsx @@ -1,37 +1,34 @@ +import type { CSSProperties, ReactNode } from "react"; +import type React from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; + import { Adjustments, AdjustmentsDone, ExclamationCircle, -} from "@medusajs/icons" -import { Button, DropdownMenu, clx } from "@medusajs/ui" -import { +} from "@medusajs/icons"; +import { Button, DropdownMenu, clx } from "@medusajs/ui"; + +import type { Cell, CellContext, Column, ColumnDef, Row, VisibilityState, +} from "@tanstack/react-table"; +import { flexRender, getCoreRowModel, useReactTable, -} from "@tanstack/react-table" -import { VirtualItem, useVirtualizer } from "@tanstack/react-virtual" -import React, { - CSSProperties, - ReactNode, - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from "react" -import { FieldValues, UseFormReturn } from "react-hook-form" -import { useTranslation } from "react-i18next" - -import { useCommandHistory } from "../../../hooks/use-command-history" -import { useDocumentDirection } from "../../../hooks/use-document-direction" -import { ConditionalTooltip } from "../../common/conditional-tooltip" -import { DataGridContext } from "../context" +} from "@tanstack/react-table"; +import type { VirtualItem } from "@tanstack/react-virtual"; +import { useVirtualizer } from "@tanstack/react-virtual"; +import type { FieldValues, UseFormReturn } from "react-hook-form"; +import { useTranslation } from "react-i18next"; + +import { ConditionalTooltip } from "@components/common/conditional-tooltip"; +import { DataGridContext } from "@components/data-grid/context"; import { useDataGridCellHandlers, useDataGridCellMetadata, @@ -44,30 +41,38 @@ import { useDataGridMouseUpEvent, useDataGridNavigation, useDataGridQueryTool, -} from "../hooks" -import { DataGridMatrix } from "../models" -import { DataGridCoordinates, GridColumnOption } from "../types" -import { isCellMatch, isSpecialFocusKey } from "../utils" -import { DataGridKeyboardShortcutModal } from "./data-grid-keyboard-shortcut-modal" +} from "@components/data-grid/hooks"; +import { DataGridMatrix } from "@components/data-grid/models"; +import type { + DataGridCoordinates, + GridColumnOption, +} from "@components/data-grid/types"; +import { isCellMatch, isSpecialFocusKey } from "@components/data-grid/utils"; + +import { useCommandHistory } from "@hooks/use-command-history.tsx"; +import { useDocumentDirection } from "@hooks/use-document-direction.tsx"; + +import { DataGridKeyboardShortcutModal } from "./data-grid-keyboard-shortcut-modal"; + export interface DataGridRootProps< TData, TFieldValues extends FieldValues = FieldValues, > { - data?: TData[] - columns: ColumnDef[] - state: UseFormReturn - getSubRows?: (row: TData) => TData[] | undefined - onEditingChange?: (isEditing: boolean) => void - disableInteractions?: boolean - multiColumnSelection?: boolean + data?: TData[]; + columns: ColumnDef[]; + state: UseFormReturn; + getSubRows?: (row: TData) => TData[] | undefined; + onEditingChange?: (isEditing: boolean) => void; + disableInteractions?: boolean; + multiColumnSelection?: boolean; } -const ROW_HEIGHT = 40 +const ROW_HEIGHT = 40; const getCommonPinningStyles = ( - column: Column + column: Column, ): CSSProperties => { - const isPinned = column.getIsPinned() + const isPinned = column.getIsPinned(); /** * Since our border colors are semi-transparent, we need to set a custom border color @@ -76,8 +81,8 @@ const getCommonPinningStyles = ( * We do this by checking if the current theme is dark mode, and then setting the border color * to the corresponding color. */ - const isDarkMode = document.documentElement.classList.contains("dark") - const BORDER_COLOR = isDarkMode ? "rgb(50,50,53)" : "rgb(228,228,231)" + const isDarkMode = document.documentElement.classList.contains("dark"); + const BORDER_COLOR = isDarkMode ? "rgb(50,50,53)" : "rgb(228,228,231)"; return { position: isPinned ? "sticky" : "relative", @@ -87,8 +92,8 @@ const getCommonPinningStyles = ( borderRight: isPinned ? `1px solid ${BORDER_COLOR}` : undefined, left: isPinned === "left" ? `${column.getStart("left")}px` : undefined, right: isPinned === "right" ? `${column.getAfter("right")}px` : undefined, - } -} + }; +}; /** * TODO: @@ -107,32 +112,32 @@ export const DataGridRoot = < disableInteractions, multiColumnSelection = false, }: DataGridRootProps) => { - const containerRef = useRef(null) + const containerRef = useRef(null); - const { redo, undo, execute } = useCommandHistory() + const { redo, undo, execute } = useCommandHistory(); const { register, control, getValues, setValue, formState: { errors }, - } = state + } = state; - const [internalTrapActive, setTrapActive] = useState(true) + const [internalTrapActive, setTrapActive] = useState(true); - const trapActive = !disableInteractions && internalTrapActive + const trapActive = !disableInteractions && internalTrapActive; - const [anchor, setAnchor] = useState(null) - const [rangeEnd, setRangeEnd] = useState(null) - const [dragEnd, setDragEnd] = useState(null) + const [anchor, setAnchor] = useState(null); + const [rangeEnd, setRangeEnd] = useState(null); + const [dragEnd, setDragEnd] = useState(null); - const [isSelecting, setIsSelecting] = useState(false) - const [isDragging, setIsDragging] = useState(false) + const [isSelecting, setIsSelecting] = useState(false); + const [isDragging, setIsDragging] = useState(false); - const [isEditing, setIsEditing] = useState(false) + const [isEditing, setIsEditing] = useState(false); - const [columnVisibility, setColumnVisibility] = useState({}) - const [rowVisibility, setRowVisibility] = useState({}) + const [columnVisibility, setColumnVisibility] = useState({}); + const [rowVisibility, setRowVisibility] = useState({}); const grid = useReactTable({ data: data, @@ -152,16 +157,16 @@ export const DataGridRoot = < size: 200, maxSize: 400, }, - }) + }); - const { flatRows } = grid.getRowModel() - const flatColumns = grid.getAllFlatColumns() + const { flatRows } = grid.getRowModel(); + const flatColumns = grid.getAllFlatColumns(); const visibleRows = useMemo( () => flatRows.filter((_, index) => rowVisibility?.[index] !== false), - [flatRows, rowVisibility] - ) - const visibleColumns = grid.getVisibleLeafColumns() + [flatRows, rowVisibility], + ); + const visibleColumns = grid.getVisibleLeafColumns(); const rowVirtualizer = useVirtualizer({ count: visibleRows.length, @@ -172,22 +177,22 @@ export const DataGridRoot = < const toRender = new Set( Array.from( { length: range.endIndex - range.startIndex + 1 }, - (_, i) => range.startIndex + i - ) - ) + (_, i) => range.startIndex + i, + ), + ); if (anchor && visibleRows[anchor.row]) { - toRender.add(anchor.row) + toRender.add(anchor.row); } if (rangeEnd && visibleRows[rangeEnd.row]) { - toRender.add(rangeEnd.row) + toRender.add(rangeEnd.row); } - return Array.from(toRender).sort((a, b) => a - b) + return Array.from(toRender).sort((a, b) => a - b); }, - }) - const virtualRows = rowVirtualizer.getVirtualItems() + }); + const virtualRows = rowVirtualizer.getVirtualItems(); const columnVirtualizer = useVirtualizer({ count: visibleColumns.length, @@ -196,40 +201,40 @@ export const DataGridRoot = < horizontal: true, overscan: 3, rangeExtractor: (range) => { - const startIndex = range.startIndex - const endIndex = range.endIndex + const startIndex = range.startIndex; + const endIndex = range.endIndex; const toRender = new Set( Array.from( { length: endIndex - startIndex + 1 }, - (_, i) => startIndex + i - ) - ) + (_, i) => startIndex + i, + ), + ); if (anchor && visibleColumns[anchor.col]) { - toRender.add(anchor.col) + toRender.add(anchor.col); } if (rangeEnd && visibleColumns[rangeEnd.col]) { - toRender.add(rangeEnd.col) + toRender.add(rangeEnd.col); } // The first column is pinned, so we always render it - toRender.add(0) + toRender.add(0); - return Array.from(toRender).sort((a, b) => a - b) + return Array.from(toRender).sort((a, b) => a - b); }, - }) - const virtualColumns = columnVirtualizer.getVirtualItems() + }); + const virtualColumns = columnVirtualizer.getVirtualItems(); - let virtualPaddingLeft: number | undefined - let virtualPaddingRight: number | undefined + let virtualPaddingLeft: number | undefined; + let virtualPaddingRight: number | undefined; if (columnVirtualizer && virtualColumns?.length) { - virtualPaddingLeft = virtualColumns[0]?.start ?? 0 + virtualPaddingLeft = virtualColumns[0]?.start ?? 0; virtualPaddingRight = columnVirtualizer.getTotalSize() - - (virtualColumns[virtualColumns.length - 1]?.end ?? 0) + (virtualColumns[virtualColumns.length - 1]?.end ?? 0); } const matrix = useMemo( @@ -237,45 +242,45 @@ export const DataGridRoot = < new DataGridMatrix( flatRows, columns, - multiColumnSelection + multiColumnSelection, ), - [flatRows, columns, multiColumnSelection] - ) - const queryTool = useDataGridQueryTool(containerRef) + [flatRows, columns, multiColumnSelection], + ); + const queryTool = useDataGridQueryTool(containerRef); const setSingleRange = useCallback( (coordinates: DataGridCoordinates | null) => { - setAnchor(coordinates) - setRangeEnd(coordinates) + setAnchor(coordinates); + setRangeEnd(coordinates); }, - [] - ) + [], + ); const { errorCount, isHighlighted, toggleErrorHighlighting } = - useDataGridErrorHighlighting(matrix, grid, errors) + useDataGridErrorHighlighting(matrix, grid, errors); const handleToggleErrorHighlighting = useCallback(() => { toggleErrorHighlighting( rowVisibility, columnVisibility, setRowVisibility, - setColumnVisibility - ) - }, [toggleErrorHighlighting, rowVisibility, columnVisibility]) + setColumnVisibility, + ); + }, [toggleErrorHighlighting, rowVisibility, columnVisibility]); const { columnOptions, handleToggleColumn, handleResetColumns, isDisabled: isColumsDisabled, - } = useDataGridColumnVisibility(grid, matrix) + } = useDataGridColumnVisibility(grid, matrix); const handleToggleColumnVisibility = useCallback( (index: number) => { - return handleToggleColumn(index) + return handleToggleColumn(index); }, - [handleToggleColumn] - ) + [handleToggleColumn], + ); const { navigateToField, scrollToCoordinates } = useDataGridNavigation< TData, @@ -291,7 +296,7 @@ export const DataGridRoot = < setSingleRange, visibleColumns, visibleRows, - }) + }); const { createSnapshot, restoreSnapshot } = useDataGridCellSnapshot< TData, @@ -299,22 +304,22 @@ export const DataGridRoot = < >({ matrix, form: state, - }) + }); const onEditingChangeHandler = useCallback( (value: boolean) => { if (onEditingChange) { - onEditingChange(value) + onEditingChange(value); } if (value) { - createSnapshot(anchor) + createSnapshot(anchor); } - setIsEditing(value) + setIsEditing(value); }, - [anchor, createSnapshot, onEditingChange] - ) + [anchor, createSnapshot, onEditingChange], + ); const { getSelectionValues, setSelectionValues } = useDataGridFormHandlers< TData, @@ -323,7 +328,7 @@ export const DataGridRoot = < matrix, form: state, anchor, - }) + }); const { handleKeyDownEvent, handleSpecialFocusKeys } = useDataGridKeydownEvent({ @@ -347,7 +352,7 @@ export const DataGridRoot = < undo, redo, setValue, - }) + }); const { handleMouseUpEvent } = useDataGridMouseUpEvent({ matrix, @@ -361,7 +366,7 @@ export const DataGridRoot = < getSelectionValues, setSelectionValues, execute, - }) + }); const { handleCopyEvent, handlePasteEvent } = useDataGridClipboardEvents< TData, @@ -374,7 +379,7 @@ export const DataGridRoot = < getSelectionValues, setSelectionValues, execute, - }) + }); const { getWrapperFocusHandler, @@ -399,14 +404,14 @@ export const DataGridRoot = < setValue, execute, multiColumnSelection, - }) + }); const { getCellErrorMetadata, getCellMetadata } = useDataGridCellMetadata< TData, TFieldValues >({ matrix, - }) + }); /** Effects */ @@ -415,51 +420,52 @@ export const DataGridRoot = < */ useEffect(() => { if (!trapActive) { - return + return; } - window.addEventListener("keydown", handleKeyDownEvent) - window.addEventListener("mouseup", handleMouseUpEvent) + window.addEventListener("keydown", handleKeyDownEvent); + window.addEventListener("mouseup", handleMouseUpEvent); // Copy and paste event listeners need to be added to the window - window.addEventListener("copy", handleCopyEvent) - window.addEventListener("paste", handlePasteEvent) + window.addEventListener("copy", handleCopyEvent); + window.addEventListener("paste", handlePasteEvent); return () => { - window.removeEventListener("keydown", handleKeyDownEvent) - window.removeEventListener("mouseup", handleMouseUpEvent) + window.removeEventListener("keydown", handleKeyDownEvent); + window.removeEventListener("mouseup", handleMouseUpEvent); - window.removeEventListener("copy", handleCopyEvent) - window.removeEventListener("paste", handlePasteEvent) - } + window.removeEventListener("copy", handleCopyEvent); + window.removeEventListener("paste", handlePasteEvent); + }; }, [ trapActive, handleKeyDownEvent, handleMouseUpEvent, handleCopyEvent, handlePasteEvent, - ]) + ]); useEffect(() => { const specialFocusHandler = (e: KeyboardEvent) => { if (isSpecialFocusKey(e)) { - handleSpecialFocusKeys(e) - return + handleSpecialFocusKeys(e); + + return; } - } + }; - window.addEventListener("keydown", specialFocusHandler) + window.addEventListener("keydown", specialFocusHandler); return () => { - window.removeEventListener("keydown", specialFocusHandler) - } - }, [handleSpecialFocusKeys]) + window.removeEventListener("keydown", specialFocusHandler); + }; + }, [handleSpecialFocusKeys]); const handleHeaderInteractionChange = useCallback((isActive: boolean) => { if (isActive) { - setTrapActive(false) + setTrapActive(false); } - }, []) + }, []); /** * Auto corrective effect for ensuring we always @@ -467,28 +473,28 @@ export const DataGridRoot = < */ useEffect(() => { if (!anchor) { - return + return; } if (rangeEnd) { - return + return; } - setRangeEnd(anchor) - }, [anchor, rangeEnd]) + setRangeEnd(anchor); + }, [anchor, rangeEnd]); /** * Ensure that we set a anchor on first render. */ useEffect(() => { if (!anchor && matrix) { - const coords = matrix.getFirstNavigableCell() + const coords = matrix.getFirstNavigableCell(); if (coords) { - setSingleRange(coords) + setSingleRange(coords); } } - }, [anchor, matrix, setSingleRange]) + }, [anchor, matrix, setSingleRange]); const values = useMemo( () => ({ @@ -532,25 +538,25 @@ export const DataGridRoot = < getCellMetadata, getCellErrorMetadata, navigateToField, - ] - ) + ], + ); const handleRestoreGridFocus = useCallback(() => { if (anchor && !trapActive) { - setTrapActive(true) + setTrapActive(true); - setSingleRange(anchor) - scrollToCoordinates(anchor, "both") + setSingleRange(anchor); + scrollToCoordinates(anchor, "both"); requestAnimationFrame(() => { - queryTool?.getContainer(anchor)?.focus() - }) + queryTool?.getContainer(anchor)?.focus(); + }); } - }, [anchor, trapActive, setSingleRange, scrollToCoordinates, queryTool]) + }, [anchor, trapActive, setSingleRange, scrollToCoordinates, queryTool]); return ( -
    +
    + {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-noninteractive-element-interactions */}
    -
    +
    {grid.getHeaderGroups().map((headerGroup) => (
    ) : null} {virtualColumns.reduce((acc, vc, index, array) => { - const header = headerGroup.headers[vc.index] - const previousVC = array[index - 1] + const header = headerGroup.headers[vc.index]; + const previousVC = array[index - 1]; if (previousVC && vc.index !== previousVC.index + 1) { // If there's a gap between the current and previous virtual columns @@ -603,8 +614,8 @@ export const DataGridRoot = < display: "flex", width: `${vc.start - previousVC.end}px`, }} - /> - ) + />, + ); } acc.push( @@ -616,18 +627,18 @@ export const DataGridRoot = < width: header.getSize(), ...getCommonPinningStyles(header.column), }} - className="bg-ui-bg-base txt-compact-small-plus flex items-center border-b border-r px-4 py-2.5" + className="txt-compact-small-plus flex items-center border-b border-r bg-ui-bg-base px-4 py-2.5" > {header.isPlaceholder ? null : flexRender( header.column.columnDef.header, - header.getContext() + header.getContext(), )} -
    - ) +
    , + ); - return acc + return acc; }, [] as ReactNode[])} {virtualPaddingRight ? (
    {virtualRows.map((virtualRow) => { - const row = visibleRows[virtualRow.index] as Row - const rowIndex = flatRows.findIndex((r) => r.id === row.id) + const row = visibleRows[virtualRow.index] as Row; + const rowIndex = flatRows.findIndex((r) => r.id === row.id); return ( - ) + ); })}
    @@ -674,19 +685,19 @@ export const DataGridRoot = <
    - ) -} + ); +}; type DataGridHeaderProps = { - columnOptions: GridColumnOption[] - isDisabled: boolean - onToggleColumn: (index: number) => (value: boolean) => void - onResetColumns: () => void - isHighlighted: boolean - errorCount: number - onToggleErrorHighlighting: () => void - onHeaderInteractionChange: (isActive: boolean) => void -} + columnOptions: GridColumnOption[]; + isDisabled: boolean; + onToggleColumn: (index: number) => (value: boolean) => void; + onResetColumns: () => void; + isHighlighted: boolean; + errorCount: number; + onToggleErrorHighlighting: () => void; + onHeaderInteractionChange: (isActive: boolean) => void; +}; const DataGridHeader = ({ columnOptions, @@ -698,25 +709,26 @@ const DataGridHeader = ({ onToggleErrorHighlighting, onHeaderInteractionChange, }: DataGridHeaderProps) => { - const [shortcutsOpen, setShortcutsOpen] = useState(false) - const [columnsOpen, setColumnsOpen] = useState(false) - const { t } = useTranslation() - const direction = useDocumentDirection() + const [shortcutsOpen, setShortcutsOpen] = useState(false); + const [columnsOpen, setColumnsOpen] = useState(false); + const { t } = useTranslation(); + const direction = useDocumentDirection(); // Since all columns are checked by default, we can check if any column is unchecked - const hasChanged = columnOptions.some((column) => !column.checked) + const hasChanged = columnOptions.some((column) => !column.checked); const handleShortcutsOpenChange = (value: boolean) => { - onHeaderInteractionChange(value) - setShortcutsOpen(value) - } + onHeaderInteractionChange(value); + setShortcutsOpen(value); + }; const handleColumnsOpenChange = (value: boolean) => { - onHeaderInteractionChange(value) - setColumnsOpen(value) - } + onHeaderInteractionChange(value); + setColumnsOpen(value); + }; + return ( -
    +
    {columnOptions.map((column, index) => { - const { checked, disabled, id, name } = column + const { checked, disabled, id, name } = column; if (disabled) { - return null + return null; } return ( @@ -751,7 +763,7 @@ const DataGridHeader = ({ > {name} - ) + ); })} @@ -793,17 +805,17 @@ const DataGridHeader = ({ />
    - ) -} + ); +}; type DataGridCellProps = { - cell: Cell - columnIndex: number - rowIndex: number - anchor: DataGridCoordinates | null - onDragToFillStart: (e: React.MouseEvent) => void - multiColumnSelection: boolean -} + cell: Cell; + columnIndex: number; + rowIndex: number; + anchor: DataGridCoordinates | null; + onDragToFillStart: (e: React.MouseEvent) => void; + multiColumnSelection: boolean; +}; const DataGridCell = ({ cell, @@ -816,9 +828,9 @@ const DataGridCell = ({ const coords: DataGridCoordinates = { row: rowIndex, col: columnIndex, - } + }; - const isAnchor = isCellMatch(coords, anchor) + const isAnchor = isCellMatch(coords, anchor); return (
    ({ data-row-index={rowIndex} data-column-index={columnIndex} className={clx( - "relative flex items-center border-b border-r p-0 outline-none" + "relative flex items-center border-b border-r p-0 outline-none", )} tabIndex={-1} > @@ -841,35 +853,41 @@ const DataGridCell = ({ ...cell.getContext(), columnIndex, rowIndex: rowIndex, - } as CellContext)} + } as CellContext)} {isAnchor && ( + //@todo fix a11y + // eslint-disable-next-line jsx-a11y/no-static-element-interactions
    )}
    - ) -} + ); +}; type DataGridRowProps = { - row: Row - rowIndex: number - virtualRow: VirtualItem - virtualPaddingLeft?: number - virtualPaddingRight?: number - virtualColumns: VirtualItem[] - flatColumns: Column[] - anchor: DataGridCoordinates | null - onDragToFillStart: (e: React.MouseEvent) => void - multiColumnSelection: boolean -} + row: Row; + rowIndex: number; + //@todo fix type + // @ts-expect-error TS2315: Type VirtualItem is not generic. + virtualRow: VirtualItem; + virtualPaddingLeft?: number; + virtualPaddingRight?: number; + //@todo fix type + // @ts-expect-error TS2315: Type VirtualItem is not generic. + virtualColumns: VirtualItem[]; + flatColumns: Column[]; + anchor: DataGridCoordinates | null; + onDragToFillStart: (e: React.MouseEvent) => void; + multiColumnSelection: boolean; +}; const DataGridRow = ({ row, @@ -883,7 +901,7 @@ const DataGridRow = ({ onDragToFillStart, multiColumnSelection, }: DataGridRowProps) => { - const visibleCells = row.getVisibleCells() + const visibleCells = row.getVisibleCells(); return (
    ({ style={{ transform: `translateY(${virtualRow.start}px)`, }} - className="bg-ui-bg-subtle txt-compact-small absolute flex h-10 w-full" + className="txt-compact-small absolute flex h-10 w-full bg-ui-bg-subtle" > {virtualPaddingLeft ? (
    ({ /> ) : null} {virtualColumns.reduce((acc, vc, index, array) => { - const cell = visibleCells[vc.index] - const column = cell.column - const columnIndex = flatColumns.findIndex((c) => c.id === column.id) - const previousVC = array[index - 1] + const cell = visibleCells[vc.index]; + const column = cell.column; + const columnIndex = flatColumns.findIndex((c) => c.id === column.id); + const previousVC = array[index - 1]; if (previousVC && vc.index !== previousVC.index + 1) { // If there's a gap between the current and previous virtual columns @@ -916,8 +934,8 @@ const DataGridRow = ({ display: "flex", width: `${vc.start - previousVC.end}px`, }} - /> - ) + />, + ); } acc.push( @@ -929,10 +947,10 @@ const DataGridRow = ({ anchor={anchor} onDragToFillStart={onDragToFillStart} multiColumnSelection={multiColumnSelection} - /> - ) + />, + ); - return acc + return acc; }, [] as ReactNode[])} {virtualPaddingRight ? (
    ({ /> ) : null}
    - ) -} + ); +}; diff --git a/src/components/data-grid/components/data-grid-row-error-indicator.tsx b/src/components/data-grid/components/data-grid-row-error-indicator.tsx index 05315110..560c42ff 100644 --- a/src/components/data-grid/components/data-grid-row-error-indicator.tsx +++ b/src/components/data-grid/components/data-grid-row-error-indicator.tsx @@ -1,18 +1,20 @@ -import { Badge, Tooltip } from "@medusajs/ui" -import { useTranslation } from "react-i18next" -import { DataGridRowError } from "../types" +import { Badge, Tooltip } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; + +import type { DataGridRowError } from "@components/data-grid/types"; type DataGridRowErrorIndicatorProps = { - rowErrors: DataGridRowError[] -} + rowErrors: DataGridRowError[]; +}; export const DataGridRowErrorIndicator = ({ rowErrors, }: DataGridRowErrorIndicatorProps) => { - const rowErrorCount = rowErrors ? rowErrors.length : 0 + const rowErrorCount = rowErrors ? rowErrors.length : 0; if (!rowErrors || rowErrorCount <= 0) { - return null + return null; } return ( @@ -30,15 +32,15 @@ export const DataGridRowErrorIndicator = ({ {rowErrorCount} - ) -} + ); +}; const DataGridRowErrorLine = ({ error, }: { - error: { message: string; to: () => void } + error: { message: string; to: () => void }; }) => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
  • @@ -46,10 +48,10 @@ const DataGridRowErrorLine = ({
  • - ) -} + ); +}; diff --git a/src/components/data-grid/components/data-grid-skeleton.tsx b/src/components/data-grid/components/data-grid-skeleton.tsx index a54f203c..18cfc400 100644 --- a/src/components/data-grid/components/data-grid-skeleton.tsx +++ b/src/components/data-grid/components/data-grid-skeleton.tsx @@ -1,41 +1,40 @@ -import { ColumnDef } from "@tanstack/react-table" -import { Skeleton } from "../../common/skeleton" +import type { ColumnDef } from "@tanstack/react-table"; + +import { Skeleton } from "@components/common/skeleton"; type DataGridSkeletonProps = { - columns: ColumnDef[] - rows?: number -} + columns: ColumnDef[]; + rows?: number; +}; export const DataGridSkeleton = ({ columns, rows: rowCount = 10, }: DataGridSkeletonProps) => { - const rows = Array.from({ length: rowCount }, (_, i) => i) + const rows = Array.from({ length: rowCount }, (_, i) => i); - const colCount = columns.length + const colCount = columns.length; return ( -
    -
    -
    +
    +
    +
    -
    +
    - {columns.map((_col, i) => { - return ( -
    - -
    - ) - })} + {columns.map((_col, i) => ( +
    + +
    + ))}
    {rows.map((_, j) => ( @@ -44,20 +43,18 @@ export const DataGridSkeleton = ({ style={{ gridTemplateColumns: `repeat(${colCount}, 1fr)` }} key={j} > - {columns.map((_col, k) => { - return ( -
    - -
    - ) - })} + {columns.map((_col, k) => ( +
    + +
    + ))}
    ))}
    - ) -} + ); +}; diff --git a/src/components/data-grid/components/data-grid-text-cell.tsx b/src/components/data-grid/components/data-grid-text-cell.tsx index 3b1fb279..dbdb0d9e 100644 --- a/src/components/data-grid/components/data-grid-text-cell.tsx +++ b/src/components/data-grid/components/data-grid-text-cell.tsx @@ -1,60 +1,72 @@ -import { clx } from "@medusajs/ui" -import { useEffect, useState } from "react" -import { Controller, ControllerRenderProps } from "react-hook-form" +import { useEffect, useState } from "react"; -import { useCombinedRefs } from "../../../hooks/use-combined-refs" -import { useDataGridCell, useDataGridCellError } from "../hooks" -import { DataGridCellProps, InputProps } from "../types" -import { DataGridCellContainer } from "./data-grid-cell-container" +import { clx } from "@medusajs/ui"; -export const DataGridTextCell = ({ +import type { ControllerRenderProps } from "react-hook-form"; +import { Controller } from "react-hook-form"; + +import { + useDataGridCell, + useDataGridCellError, +} from "@components/data-grid/hooks"; +import type { + DataGridCellProps, + InputProps, +} from "@components/data-grid/types"; + +import { useCombinedRefs } from "@hooks/use-combined-refs.tsx"; + +import { DataGridCellContainer } from "./data-grid-cell-container"; + +export const DataGridTextCell = ({ context, }: DataGridCellProps) => { const { field, control, renderProps } = useDataGridCell({ context, - }) - const errorProps = useDataGridCellError({ context }) + }); + const errorProps = useDataGridCellError({ context }); - const { container, input } = renderProps + const { container, input } = renderProps; return ( { - return ( - - - - ) - }} + render={({ field }) => ( + + + + )} /> - ) -} + ); +}; const Inner = ({ field, inputProps, }: { - field: ControllerRenderProps - inputProps: InputProps + //@todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + field: ControllerRenderProps; + inputProps: InputProps; }) => { - const { onChange: _, onBlur, ref, value, ...rest } = field - const { ref: inputRef, onBlur: onInputBlur, onChange, ...input } = inputProps + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { onChange: _, onBlur, ref, value, ...rest } = field; + const { ref: inputRef, onBlur: onInputBlur, onChange, ...input } = inputProps; - const [localValue, setLocalValue] = useState(value) + const [localValue, setLocalValue] = useState(value); useEffect(() => { - setLocalValue(value) - }, [value]) + setLocalValue(value); + }, [value]); - const combinedRefs = useCombinedRefs(inputRef, ref) + const combinedRefs = useCombinedRefs(inputRef, ref); return ( setLocalValue(e.target.value)} ref={combinedRefs} onBlur={() => { - onBlur() - onInputBlur() + onBlur(); + onInputBlur(); // We propagate the change to the field only when the input is blurred - onChange(localValue, value) + onChange(localValue, value); }} {...input} {...rest} /> - ) -} + ); +}; diff --git a/src/components/data-grid/components/data-grid-toggleable-number-cell.tsx b/src/components/data-grid/components/data-grid-toggleable-number-cell.tsx index aac12fa3..6a4cdd5a 100644 --- a/src/components/data-grid/components/data-grid-toggleable-number-cell.tsx +++ b/src/components/data-grid/components/data-grid-toggleable-number-cell.tsx @@ -1,55 +1,68 @@ -import { Switch } from "@medusajs/ui" -import { useEffect, useRef, useState } from "react" -import CurrencyInput, { CurrencyInputProps } from "react-currency-input-field" -import { Controller, ControllerRenderProps } from "react-hook-form" -import { useCombinedRefs } from "../../../hooks/use-combined-refs" -import { ConditionalTooltip } from "../../common/conditional-tooltip" -import { useDataGridCell, useDataGridCellError } from "../hooks" -import { DataGridCellProps, InputProps } from "../types" -import { DataGridCellContainer } from "./data-grid-cell-container" +import { useEffect, useRef, useState } from "react"; +import { Switch } from "@medusajs/ui"; + +import type { CurrencyInputProps } from "react-currency-input-field"; +import CurrencyInput from "react-currency-input-field"; +import type { ControllerRenderProps } from "react-hook-form"; +import { Controller } from "react-hook-form"; + +import { ConditionalTooltip } from "@components/common/conditional-tooltip"; +import { + useDataGridCell, + useDataGridCellError, +} from "@components/data-grid/hooks"; +import type { + DataGridCellProps, + InputProps, +} from "@components/data-grid/types"; + +import { useCombinedRefs } from "@hooks/use-combined-refs.tsx"; + +import { DataGridCellContainer } from "./data-grid-cell-container"; + +//@todo fix type +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const DataGridTogglableNumberCell = ({ context, disabledToggleTooltip, ...rest }: DataGridCellProps & { - min?: number - max?: number - placeholder?: string - disabledToggleTooltip?: string + min?: number; + max?: number; + placeholder?: string; + disabledToggleTooltip?: string; }) => { const { field, control, renderProps } = useDataGridCell({ context, - }) - const errorProps = useDataGridCellError({ context }) + }); + const errorProps = useDataGridCellError({ context }); - const { container, input } = renderProps + const { container, input } = renderProps; return ( { - return ( - - } - > - - - ) - }} + render={({ field }) => ( + + } + > + + + )} /> - ) -} + ); +}; const OuterComponent = ({ field, @@ -57,47 +70,50 @@ const OuterComponent = ({ isAnchor, tooltip, }: { - field: ControllerRenderProps - inputProps: InputProps - isAnchor: boolean - tooltip?: string + //@todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + field: ControllerRenderProps; + inputProps: InputProps; + isAnchor: boolean; + tooltip?: string; }) => { - const buttonRef = useRef(null) - const { value } = field - const { onChange } = inputProps + const buttonRef = useRef(null); + const { value } = field; + const { onChange } = inputProps; - const [localValue, setLocalValue] = useState(value) + const [localValue, setLocalValue] = useState(value); useEffect(() => { - setLocalValue(value) - }, [value]) + setLocalValue(value); + }, [value]); const handleCheckedChange = (update: boolean) => { - const newValue = { ...localValue, checked: update } + const newValue = { ...localValue, checked: update }; if (!update && !newValue.disabledToggle) { - newValue.quantity = "" + newValue.quantity = ""; } if (update && newValue.quantity === "") { - newValue.quantity = 0 + newValue.quantity = 0; } - setLocalValue(newValue) - onChange(newValue, value) - } + setLocalValue(newValue); + onChange(newValue, value); + }; useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (isAnchor && e.key.toLowerCase() === "x") { - e.preventDefault() - buttonRef.current?.click() + e.preventDefault(); + buttonRef.current?.click(); } - } + }; + + document.addEventListener("keydown", handleKeyDown); - document.addEventListener("keydown", handleKeyDown) - return () => document.removeEventListener("keydown", handleKeyDown) - }, [isAnchor]) + return () => document.removeEventListener("keydown", handleKeyDown); + }, [isAnchor]); return (
    - ) -} + ); +}; const Inner = ({ field, @@ -125,36 +141,37 @@ const Inner = ({ placeholder, ...props }: { - field: ControllerRenderProps - inputProps: InputProps - min?: number - max?: number - placeholder?: string + //@todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + field: ControllerRenderProps; + inputProps: InputProps; + min?: number; + max?: number; + placeholder?: string; }) => { - const { ref, value, onChange: _, onBlur, ...fieldProps } = field + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { ref, value, onChange: _, onBlur, ...fieldProps } = field; const { ref: inputRef, onChange, onBlur: onInputBlur, onFocus, ...attributes - } = inputProps + } = inputProps; - const [localValue, setLocalValue] = useState(value) + const [localValue, setLocalValue] = useState(value); useEffect(() => { - setLocalValue(value) - }, [value]) + setLocalValue(value); + }, [value]); - const combinedRefs = useCombinedRefs(inputRef, ref) + const combinedRefs = useCombinedRefs(inputRef, ref); const handleInputChange: CurrencyInputProps["onValueChange"] = ( updatedValue, - _name, - _values ) => { - const ensuredValue = updatedValue !== undefined ? updatedValue : "" - const newValue = { ...localValue, quantity: ensuredValue } + const ensuredValue = updatedValue !== undefined ? updatedValue : ""; + const newValue = { ...localValue, quantity: ensuredValue }; /** * If the value is not empty, then the location should be enabled. @@ -163,21 +180,21 @@ const Inner = ({ * location should be disabled, unless toggling the location is disabled. */ if (ensuredValue !== "") { - newValue.checked = true + newValue.checked = true; } else if (newValue.checked && newValue.disabledToggle === false) { - newValue.checked = false + newValue.checked = false; } - setLocalValue(newValue) - } + setLocalValue(newValue); + }; const handleOnChange = () => { if (localValue.disabledToggle && localValue.quantity === "") { - localValue.quantity = 0 + localValue.quantity = 0; } - onChange(localValue, value) - } + onChange(localValue, value); + }; return (
    @@ -191,9 +208,9 @@ const Inner = ({ onValueChange={handleInputChange} formatValueOnBlur onBlur={() => { - onBlur() - onInputBlur() - handleOnChange() + onBlur(); + onInputBlur(); + handleOnChange(); }} onFocus={onFocus} decimalsLimit={0} @@ -202,5 +219,5 @@ const Inner = ({ placeholder={!localValue.checked ? placeholder : undefined} />
    - ) -} + ); +}; diff --git a/src/components/data-grid/components/index.ts b/src/components/data-grid/components/index.ts index 3968df05..bbada8c6 100644 --- a/src/components/data-grid/components/index.ts +++ b/src/components/data-grid/components/index.ts @@ -1,7 +1,8 @@ -export { DataGridBooleanCell } from "./data-grid-boolean-cell" -export { DataGridCurrencyCell } from "./data-grid-currency-cell" -export { DataGridNumberCell } from "./data-grid-number-cell" -export { DataGridReadonlyCell as DataGridReadOnlyCell } from "./data-grid-readonly-cell" -export { DataGridRoot, type DataGridRootProps } from "./data-grid-root" -export { DataGridSkeleton } from "./data-grid-skeleton" -export { DataGridTextCell } from "./data-grid-text-cell" +export { DataGridBooleanCell } from "./data-grid-boolean-cell"; +export { DataGridCurrencyCell } from "./data-grid-currency-cell"; +export { DataGridNumberCell } from "./data-grid-number-cell"; +export { DataGridReadonlyCell as DataGridReadOnlyCell } from "./data-grid-readonly-cell"; +export { DataGridRoot, type DataGridRootProps } from "./data-grid-root"; +export { DataGridSkeleton } from "./data-grid-skeleton"; +export { DataGridTextCell } from "./data-grid-text-cell"; +export { DataGridReadonlyCell } from "./data-grid-readonly-cell"; From c1a97e17d96dec72b444e76c43d8716ae9060cf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 17:01:02 +0200 Subject: [PATCH 035/195] eslint/prettier - fix components/data-grid/context --- .../data-grid/context/data-grid-context.tsx | 65 +++++++++++-------- src/components/data-grid/context/index.ts | 4 +- .../context/use-data-grid-context.tsx | 15 +++-- 3 files changed, 47 insertions(+), 37 deletions(-) diff --git a/src/components/data-grid/context/data-grid-context.tsx b/src/components/data-grid/context/data-grid-context.tsx index 83f2612d..21668e0a 100644 --- a/src/components/data-grid/context/data-grid-context.tsx +++ b/src/components/data-grid/context/data-grid-context.tsx @@ -1,45 +1,54 @@ -import { FocusEvent, MouseEvent, createContext } from "react" -import { +import type { FocusEvent, MouseEvent } from "react"; +import { createContext } from "react"; + +import type { Control, FieldErrors, FieldValues, Path, UseFormRegister, -} from "react-hook-form" -import { CellErrorMetadata, CellMetadata, DataGridCoordinates } from "../types" +} from "react-hook-form"; + +import type { + CellErrorMetadata, + CellMetadata, + DataGridCoordinates, +} from "@components/data-grid/types"; type DataGridContextType = { // Grid state - anchor: DataGridCoordinates | null - trapActive: boolean - setTrapActive: (value: boolean) => void - errors: FieldErrors + anchor: DataGridCoordinates | null; + trapActive: boolean; + setTrapActive: (value: boolean) => void; + errors: FieldErrors; // Cell handlers - getIsCellSelected: (coords: DataGridCoordinates) => boolean - getIsCellDragSelected: (coords: DataGridCoordinates) => boolean + getIsCellSelected: (coords: DataGridCoordinates) => boolean; + getIsCellDragSelected: (coords: DataGridCoordinates) => boolean; // Grid handlers - setIsEditing: (value: boolean) => void - setIsSelecting: (value: boolean) => void - setRangeEnd: (coords: DataGridCoordinates) => void - setSingleRange: (coords: DataGridCoordinates) => void + setIsEditing: (value: boolean) => void; + setIsSelecting: (value: boolean) => void; + setRangeEnd: (coords: DataGridCoordinates) => void; + setSingleRange: (coords: DataGridCoordinates) => void; // Form state and handlers - register: UseFormRegister - control: Control + register: UseFormRegister; + control: Control; getInputChangeHandler: ( - field: Path - ) => (next: any, prev: any) => void + field: Path, + //@todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ) => (next: any, prev: any) => void; // Wrapper handlers getWrapperFocusHandler: ( - coordinates: DataGridCoordinates - ) => (e: FocusEvent) => void + coordinates: DataGridCoordinates, + ) => (e: FocusEvent) => void; getWrapperMouseOverHandler: ( - coordinates: DataGridCoordinates - ) => ((e: MouseEvent) => void) | undefined - getCellMetadata: (coords: DataGridCoordinates) => CellMetadata - getCellErrorMetadata: (coords: DataGridCoordinates) => CellErrorMetadata - navigateToField: (field: string) => void -} + coordinates: DataGridCoordinates, + ) => ((e: MouseEvent) => void) | undefined; + getCellMetadata: (coords: DataGridCoordinates) => CellMetadata; + getCellErrorMetadata: (coords: DataGridCoordinates) => CellErrorMetadata; + navigateToField: (field: string) => void; +}; export const DataGridContext = createContext | null>( - null -) + null, +); diff --git a/src/components/data-grid/context/index.ts b/src/components/data-grid/context/index.ts index dda988e4..4122d595 100644 --- a/src/components/data-grid/context/index.ts +++ b/src/components/data-grid/context/index.ts @@ -1,2 +1,2 @@ -export * from "./data-grid-context" -export * from "./use-data-grid-context" +export * from "./data-grid-context"; +export * from "./use-data-grid-context"; diff --git a/src/components/data-grid/context/use-data-grid-context.tsx b/src/components/data-grid/context/use-data-grid-context.tsx index 3a0f8bfa..ad9363c2 100644 --- a/src/components/data-grid/context/use-data-grid-context.tsx +++ b/src/components/data-grid/context/use-data-grid-context.tsx @@ -1,14 +1,15 @@ -import { useContext } from "react" -import { DataGridContext } from "./data-grid-context" +import { useContext } from "react"; + +import { DataGridContext } from "./data-grid-context"; export const useDataGridContext = () => { - const context = useContext(DataGridContext) + const context = useContext(DataGridContext); if (!context) { throw new Error( - "useDataGridContext must be used within a DataGridContextProvider" - ) + "useDataGridContext must be used within a DataGridContextProvider", + ); } - return context -} + return context; +}; From 4c709b0b649a721605c28bc527311ebf8625a8d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 17:05:08 +0200 Subject: [PATCH 036/195] eslint/prettier - fix components/data-grid/helpers --- .../helpers/create-data-grid-column-helper.ts | 37 ++++---- .../create-data-grid-price-columns.tsx | 88 ++++++++++--------- src/components/data-grid/helpers/index.ts | 4 +- 3 files changed, 68 insertions(+), 61 deletions(-) diff --git a/src/components/data-grid/helpers/create-data-grid-column-helper.ts b/src/components/data-grid/helpers/create-data-grid-column-helper.ts index c47b9e80..0afb9dbd 100644 --- a/src/components/data-grid/helpers/create-data-grid-column-helper.ts +++ b/src/components/data-grid/helpers/create-data-grid-column-helper.ts @@ -1,54 +1,57 @@ -import { +import type { CellContext, ColumnDefTemplate, - createColumnHelper, HeaderContext, -} from "@tanstack/react-table" -import { FieldValues } from "react-hook-form" +} from "@tanstack/react-table"; +import { createColumnHelper } from "@tanstack/react-table"; +import type { FieldValues } from "react-hook-form"; -import { DataGridColumnType, FieldFunction } from "../types" +import type { + DataGridColumnType, + FieldFunction, +} from "@components/data-grid/types"; type DataGridHelperColumnsProps = { /** * The id of the column. */ - id: string + id: string; /** * The name of the column, shown in the column visibility menu. */ - name?: string + name?: string; /** * The header template for the column. */ - header: ColumnDefTemplate> | undefined + header: ColumnDefTemplate> | undefined; /** * The cell template for the column. */ - cell: ColumnDefTemplate> | undefined + cell: ColumnDefTemplate> | undefined; /** * Callback to set the field path for each cell in the column. * If a callback is not provided, or returns null, the cell will not be editable. */ - field?: FieldFunction + field?: FieldFunction; /** * Whether the column cannot be hidden by the user. * * @default false */ - disableHiding?: boolean + disableHiding?: boolean; } & ( | { - field: FieldFunction - type: DataGridColumnType + field: FieldFunction; + type: DataGridColumnType; } | { field?: null | undefined; type?: never } -) +); export function createDataGridHelper< TData, - TFieldValues extends FieldValues + TFieldValues extends FieldValues, >() { - const columnHelper = createColumnHelper() + const columnHelper = createColumnHelper(); return { column: ({ @@ -71,5 +74,5 @@ export function createDataGridHelper< type, }, }), - } + }; } diff --git a/src/components/data-grid/helpers/create-data-grid-price-columns.tsx b/src/components/data-grid/helpers/create-data-grid-price-columns.tsx index 0c1fff4e..25617ae1 100644 --- a/src/components/data-grid/helpers/create-data-grid-price-columns.tsx +++ b/src/components/data-grid/helpers/create-data-grid-price-columns.tsx @@ -1,31 +1,35 @@ -import { HttpTypes } from "@medusajs/types" -import { ColumnDef } from "@tanstack/react-table" -import { TFunction } from "i18next" -import { FieldPath, FieldValues } from "react-hook-form" -import { IncludesTaxTooltip } from "../../common/tax-badge/tax-badge" -import { DataGridCurrencyCell } from "../components/data-grid-currency-cell" -import { DataGridReadonlyCell } from "../components/data-grid-readonly-cell" -import { FieldContext } from "../types" -import { createDataGridHelper } from "./create-data-grid-column-helper" +import type { HttpTypes } from "@medusajs/types"; + +import type { ColumnDef } from "@tanstack/react-table"; +import type { TFunction } from "i18next"; +import type { FieldPath, FieldValues } from "react-hook-form"; + +import { IncludesTaxTooltip } from "@components/common/tax-badge"; +import { createDataGridHelper } from "@components/data-grid"; +import { + DataGridCurrencyCell, + DataGridReadonlyCell, +} from "@components/data-grid/components"; +import type { FieldContext } from "@components/data-grid/types"; type CreateDataGridPriceColumnsProps< TData, - TFieldValues extends FieldValues + TFieldValues extends FieldValues, > = { - currencies?: string[] - regions?: HttpTypes.AdminRegion[] - pricePreferences?: HttpTypes.AdminPricePreference[] - isReadyOnly?: (context: FieldContext) => boolean + currencies?: string[]; + regions?: HttpTypes.AdminRegion[]; + pricePreferences?: HttpTypes.AdminPricePreference[]; + isReadyOnly?: (context: FieldContext) => boolean; getFieldName: ( context: FieldContext, - value: string - ) => FieldPath | null - t: TFunction -} + value: string, + ) => FieldPath | null; + t: TFunction; +}; export const createDataGridPriceColumns = < TData, - TFieldValues extends FieldValues + TFieldValues extends FieldValues, >({ currencies, regions, @@ -37,17 +41,17 @@ export const createDataGridPriceColumns = < TData, unknown >[] => { - const columnHelper = createDataGridHelper() + const columnHelper = createDataGridHelper(); return [ ...(currencies?.map((currency) => { const preference = pricePreferences?.find( - (p) => p.attribute === "currency_code" && p.value === currency - ) + (p) => p.attribute === "currency_code" && p.value === currency, + ); const translatedCurrencyName = t("fields.priceTemplate", { regionOrCurrency: currency.toUpperCase(), - }) + }); return columnHelper.column({ id: `currency_prices.${currency}`, @@ -55,13 +59,13 @@ export const createDataGridPriceColumns = < regionOrCurrency: currency.toUpperCase(), }), field: (context) => { - const isReadyOnlyValue = isReadyOnly?.(context) + const isReadyOnlyValue = isReadyOnly?.(context); if (isReadyOnlyValue) { - return null + return null; } - return getFieldName(context, currency) + return getFieldName(context, currency); }, type: "number", header: () => ( @@ -74,21 +78,21 @@ export const createDataGridPriceColumns = < ), cell: (context) => { if (isReadyOnly?.(context)) { - return + return ; } - return + return ; }, - }) + }); }) ?? []), ...(regions?.map((region) => { const preference = pricePreferences?.find( - (p) => p.attribute === "region_id" && p.value === region.id - ) + (p) => p.attribute === "region_id" && p.value === region.id, + ); const translatedRegionName = t("fields.priceTemplate", { regionOrCurrency: region.name, - }) + }); return columnHelper.column({ id: `region_prices.${region.id}`, @@ -96,13 +100,13 @@ export const createDataGridPriceColumns = < regionOrCurrency: region.name, }), field: (context) => { - const isReadyOnlyValue = isReadyOnly?.(context) + const isReadyOnlyValue = isReadyOnly?.(context); if (isReadyOnlyValue) { - return null + return null; } - return getFieldName(context, region.id) + return getFieldName(context, region.id); }, type: "number", header: () => ( @@ -115,12 +119,12 @@ export const createDataGridPriceColumns = < ), cell: (context) => { if (isReadyOnly?.(context)) { - return + return ; } - const currency = currencies?.find((c) => c === region.currency_code) + const currency = currencies?.find((c) => c === region.currency_code); if (!currency) { - return null + return null; } return ( @@ -128,9 +132,9 @@ export const createDataGridPriceColumns = < code={region.currency_code} context={context} /> - ) + ); }, - }) + }); }) ?? []), - ] -} + ]; +}; diff --git a/src/components/data-grid/helpers/index.ts b/src/components/data-grid/helpers/index.ts index 5a490604..a5d6e690 100644 --- a/src/components/data-grid/helpers/index.ts +++ b/src/components/data-grid/helpers/index.ts @@ -1,2 +1,2 @@ -export * from "./create-data-grid-column-helper" -export * from "./create-data-grid-price-columns" +export * from "./create-data-grid-column-helper"; +export * from "./create-data-grid-price-columns"; From ef4728b84e2d3e17675fee00bd0f3342c6508c60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 17:41:54 +0200 Subject: [PATCH 037/195] eslint/prettier - fix components/data-grid/hooks --- src/components/data-grid/hooks/index.ts | 28 +- .../hooks/use-data-grid-cell-error.tsx | 60 ++- .../hooks/use-data-grid-cell-handlers.tsx | 154 +++--- .../hooks/use-data-grid-cell-metadata.tsx | 56 +- .../hooks/use-data-grid-cell-snapshot.tsx | 57 +- .../data-grid/hooks/use-data-grid-cell.tsx | 165 +++--- .../hooks/use-data-grid-clipboard-events.tsx | 81 +-- .../hooks/use-data-grid-column-visibility.tsx | 55 +- .../hooks/use-data-grid-duplicate-cell.tsx | 15 +- .../use-data-grid-error-highlighting.tsx | 95 ++-- .../hooks/use-data-grid-form-handlers.tsx | 182 ++++--- .../hooks/use-data-grid-keydown-event.tsx | 492 +++++++++--------- .../hooks/use-data-grid-mouse-up-event.tsx | 81 +-- .../hooks/use-data-grid-navigation.tsx | 106 ++-- .../hooks/use-data-grid-query-tool.tsx | 15 +- 15 files changed, 858 insertions(+), 784 deletions(-) diff --git a/src/components/data-grid/hooks/index.ts b/src/components/data-grid/hooks/index.ts index 2307c30c..202f57a2 100644 --- a/src/components/data-grid/hooks/index.ts +++ b/src/components/data-grid/hooks/index.ts @@ -1,14 +1,14 @@ -export * from "./use-data-grid-cell" -export * from "./use-data-grid-cell-error" -export * from "./use-data-grid-cell-handlers" -export * from "./use-data-grid-cell-metadata" -export * from "./use-data-grid-cell-snapshot" -export * from "./use-data-grid-clipboard-events" -export * from "./use-data-grid-column-visibility" -export * from "./use-data-grid-duplicate-cell" -export * from "./use-data-grid-error-highlighting" -export * from "./use-data-grid-form-handlers" -export * from "./use-data-grid-keydown-event" -export * from "./use-data-grid-mouse-up-event" -export * from "./use-data-grid-navigation" -export * from "./use-data-grid-query-tool" +export * from "./use-data-grid-cell"; +export * from "./use-data-grid-cell-error"; +export * from "./use-data-grid-cell-handlers"; +export * from "./use-data-grid-cell-metadata"; +export * from "./use-data-grid-cell-snapshot"; +export * from "./use-data-grid-clipboard-events"; +export * from "./use-data-grid-column-visibility"; +export * from "./use-data-grid-duplicate-cell"; +export * from "./use-data-grid-error-highlighting"; +export * from "./use-data-grid-form-handlers"; +export * from "./use-data-grid-keydown-event"; +export * from "./use-data-grid-mouse-up-event"; +export * from "./use-data-grid-navigation"; +export * from "./use-data-grid-query-tool"; diff --git a/src/components/data-grid/hooks/use-data-grid-cell-error.tsx b/src/components/data-grid/hooks/use-data-grid-cell-error.tsx index b54e3125..7d64fea9 100644 --- a/src/components/data-grid/hooks/use-data-grid-cell-error.tsx +++ b/src/components/data-grid/hooks/use-data-grid-cell-error.tsx @@ -1,78 +1,84 @@ -import { CellContext } from "@tanstack/react-table" -import { useMemo } from "react" -import { FieldError, FieldErrors, get } from "react-hook-form" +import { useMemo } from "react"; -import { useDataGridContext } from "../context" -import { DataGridCellContext, DataGridRowError } from "../types" +import type { CellContext } from "@tanstack/react-table"; +import type { FieldError, FieldErrors } from "react-hook-form"; +import { get } from "react-hook-form"; + +import { useDataGridContext } from "@components/data-grid/context"; +import type { + DataGridCellContext, + DataGridRowError, +} from "@components/data-grid/types"; type UseDataGridCellErrorOptions = { - context: CellContext -} + context: CellContext; +}; export const useDataGridCellError = ({ context, }: UseDataGridCellErrorOptions) => { - const { errors, getCellErrorMetadata, navigateToField } = useDataGridContext() + const { errors, getCellErrorMetadata, navigateToField } = + useDataGridContext(); const { rowIndex, columnIndex } = context as DataGridCellContext< TextData, TValue - > + >; const { accessor, field } = useMemo(() => { - return getCellErrorMetadata({ row: rowIndex, col: columnIndex }) - }, [rowIndex, columnIndex, getCellErrorMetadata]) + return getCellErrorMetadata({ row: rowIndex, col: columnIndex }); + }, [rowIndex, columnIndex, getCellErrorMetadata]); const rowErrorsObject: FieldErrors | undefined = - accessor && columnIndex === 0 ? get(errors, accessor) : undefined + accessor && columnIndex === 0 ? get(errors, accessor) : undefined; - const rowErrors: DataGridRowError[] = [] + const rowErrors: DataGridRowError[] = []; function collectErrors( errorObject: FieldErrors | FieldError | undefined, - baseAccessor: string + baseAccessor: string, ) { if (!errorObject) { - return + return; } if (isFieldError(errorObject)) { // Handle a single FieldError directly - const message = errorObject.message + const message = errorObject.message; - const to = () => navigateToField(baseAccessor) + const to = () => navigateToField(baseAccessor); if (message) { - rowErrors.push({ message, to }) + rowErrors.push({ message, to }); } } else { // Traverse nested objects Object.keys(errorObject).forEach((key) => { - const nestedError = errorObject[key] - const fieldAccessor = `${baseAccessor}.${key}` + const nestedError = errorObject[key]; + const fieldAccessor = `${baseAccessor}.${key}`; if (nestedError && typeof nestedError === "object") { - collectErrors(nestedError, fieldAccessor) + collectErrors(nestedError, fieldAccessor); } - }) + }); } } if (rowErrorsObject && accessor) { - collectErrors(rowErrorsObject, accessor) + collectErrors(rowErrorsObject, accessor); } const cellError: FieldError | undefined = field ? get(errors, field) - : undefined + : undefined; return { errors, rowErrors, cellError, - } -} + }; +}; function isFieldError(errors: FieldErrors | FieldError): errors is FieldError { - return typeof errors === "object" && "message" in errors && "type" in errors + return typeof errors === "object" && "message" in errors && "type" in errors; } diff --git a/src/components/data-grid/hooks/use-data-grid-cell-handlers.tsx b/src/components/data-grid/hooks/use-data-grid-cell-handlers.tsx index 1aee1dc2..735aaec4 100644 --- a/src/components/data-grid/hooks/use-data-grid-cell-handlers.tsx +++ b/src/components/data-grid/hooks/use-data-grid-cell-handlers.tsx @@ -1,28 +1,32 @@ -import { FocusEvent, MouseEvent, useCallback } from "react" -import { FieldValues, UseFormSetValue } from "react-hook-form" -import { DataGridMatrix, DataGridUpdateCommand } from "../models" -import { DataGridCoordinates } from "../types" +import type { FocusEvent, MouseEvent } from "react"; +import { useCallback } from "react"; + +import type { FieldValues, UseFormSetValue } from "react-hook-form"; + +import type { DataGridMatrix } from "@components/data-grid/models"; +import { DataGridUpdateCommand } from "@components/data-grid/models"; +import type { DataGridCoordinates } from "@components/data-grid/types"; type UseDataGridCellHandlersOptions = { - matrix: DataGridMatrix - anchor: DataGridCoordinates | null - rangeEnd: DataGridCoordinates | null - setRangeEnd: (coords: DataGridCoordinates | null) => void - isSelecting: boolean - setIsSelecting: (isSelecting: boolean) => void - isDragging: boolean - setIsDragging: (isDragging: boolean) => void - setSingleRange: (coords: DataGridCoordinates) => void - dragEnd: DataGridCoordinates | null - setDragEnd: (coords: DataGridCoordinates | null) => void - setValue: UseFormSetValue - execute: (command: DataGridUpdateCommand) => void - multiColumnSelection?: boolean -} + matrix: DataGridMatrix; + anchor: DataGridCoordinates | null; + rangeEnd: DataGridCoordinates | null; + setRangeEnd: (coords: DataGridCoordinates | null) => void; + isSelecting: boolean; + setIsSelecting: (isSelecting: boolean) => void; + isDragging: boolean; + setIsDragging: (isDragging: boolean) => void; + setSingleRange: (coords: DataGridCoordinates) => void; + dragEnd: DataGridCoordinates | null; + setDragEnd: (coords: DataGridCoordinates | null) => void; + setValue: UseFormSetValue; + execute: (command: DataGridUpdateCommand) => void; + multiColumnSelection?: boolean; +}; export const useDataGridCellHandlers = < TData, - TFieldValues extends FieldValues + TFieldValues extends FieldValues, >({ matrix, anchor, @@ -40,54 +44,52 @@ export const useDataGridCellHandlers = < multiColumnSelection, }: UseDataGridCellHandlersOptions) => { const getWrapperFocusHandler = useCallback( - (coords: DataGridCoordinates) => { - return (_e: FocusEvent) => { - setSingleRange(coords) - } + (coords: DataGridCoordinates) => (_e: FocusEvent) => { + setSingleRange(coords); }, - [setSingleRange] - ) + [setSingleRange], + ); const getOverlayMouseDownHandler = useCallback( - (coords: DataGridCoordinates) => { - return (e: MouseEvent) => { - e.stopPropagation() - e.preventDefault() + (coords: DataGridCoordinates) => (e: MouseEvent) => { + e.stopPropagation(); + e.preventDefault(); - if (e.shiftKey) { - setRangeEnd(coords) - return - } + if (e.shiftKey) { + setRangeEnd(coords); - setIsSelecting(true) - - setSingleRange(coords) + return; } + + setIsSelecting(true); + + setSingleRange(coords); }, - [setIsSelecting, setRangeEnd, setSingleRange] - ) + [setIsSelecting, setRangeEnd, setSingleRange], + ); const getWrapperMouseOverHandler = useCallback( (coords: DataGridCoordinates) => { if (!isDragging && !isSelecting) { - return + return; } + // eslint-disable-next-line @typescript-eslint/no-unused-vars return (_e: MouseEvent) => { /** * If the column is not the same as the anchor col, * we don't want to select the cell. Unless multiColumnSelection is true. */ if (anchor?.col !== coords.col && !multiColumnSelection) { - return + return; } if (isSelecting) { - setRangeEnd(coords) + setRangeEnd(coords); } else { - setDragEnd(coords) + setDragEnd(coords); } - } + }; }, [ anchor?.col, @@ -96,59 +98,59 @@ export const useDataGridCellHandlers = < setDragEnd, setRangeEnd, multiColumnSelection, - ] - ) + ], + ); const getInputChangeHandler = useCallback( // Using `any` here as the generic type of Path will // not be inferred correctly. - (field: any) => { - return (next: any, prev: any) => { - const command = new DataGridUpdateCommand({ - next, - prev, - setter: (value) => { - setValue(field, value, { - shouldDirty: true, - shouldTouch: true, - }) - }, - }) - - execute(command) - } + // @todo fix any type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (field: any) => (next: any, prev: any) => { + const command = new DataGridUpdateCommand({ + next, + prev, + setter: (value) => { + setValue(field, value, { + shouldDirty: true, + shouldTouch: true, + }); + }, + }); + + execute(command); }, - [setValue, execute] - ) + [setValue, execute], + ); const onDragToFillStart = useCallback( (_e: MouseEvent) => { - setIsDragging(true) + setIsDragging(true); }, - [setIsDragging] - ) + [setIsDragging], + ); const getIsCellSelected = useCallback( (cell: DataGridCoordinates | null) => { if (!cell || !anchor || !rangeEnd) { - return false + return false; } - return matrix.getIsCellSelected(cell, anchor, rangeEnd) + return matrix.getIsCellSelected(cell, anchor, rangeEnd); }, - [anchor, rangeEnd, matrix] - ) + [anchor, rangeEnd, matrix], + ); const getIsCellDragSelected = useCallback( (cell: DataGridCoordinates | null) => { if (!cell || !anchor || !dragEnd) { - return false + return false; } - return matrix.getIsCellSelected(cell, anchor, dragEnd) + return matrix.getIsCellSelected(cell, anchor, dragEnd); }, - [anchor, dragEnd, matrix] - ) + [anchor, dragEnd, matrix], + ); return { getWrapperFocusHandler, @@ -158,5 +160,5 @@ export const useDataGridCellHandlers = < getIsCellSelected, getIsCellDragSelected, onDragToFillStart, - } -} + }; +}; diff --git a/src/components/data-grid/hooks/use-data-grid-cell-metadata.tsx b/src/components/data-grid/hooks/use-data-grid-cell-metadata.tsx index 182c81d3..187a3a21 100644 --- a/src/components/data-grid/hooks/use-data-grid-cell-metadata.tsx +++ b/src/components/data-grid/hooks/use-data-grid-cell-metadata.tsx @@ -1,16 +1,22 @@ -import { useCallback } from "react" -import { FieldValues } from "react-hook-form" -import { DataGridMatrix } from "../models" -import { CellErrorMetadata, CellMetadata, DataGridCoordinates } from "../types" -import { generateCellId } from "../utils" +import { useCallback } from "react"; + +import type { FieldValues } from "react-hook-form"; + +import type { DataGridMatrix } from "@components/data-grid/models"; +import type { + CellErrorMetadata, + CellMetadata, + DataGridCoordinates, +} from "@components/data-grid/types"; +import { generateCellId } from "@components/data-grid/utils"; type UseDataGridCellMetadataOptions = { - matrix: DataGridMatrix -} + matrix: DataGridMatrix; +}; export const useDataGridCellMetadata = < TData, - TFieldValues extends FieldValues + TFieldValues extends FieldValues, >({ matrix, }: UseDataGridCellMetadataOptions) => { @@ -19,14 +25,14 @@ export const useDataGridCellMetadata = < */ const getCellMetadata = useCallback( (coords: DataGridCoordinates): CellMetadata => { - const { row, col } = coords + const { row, col } = coords; - const id = generateCellId(coords) - const field = matrix.getCellField(coords) - const type = matrix.getCellType(coords) + const id = generateCellId(coords); + const field = matrix.getCellField(coords); + const type = matrix.getCellType(coords); if (!field || !type) { - throw new Error(`'field' or 'type' is null for cell ${id}`) + throw new Error(`'field' or 'type' is null for cell ${id}`); } const inputAttributes = { @@ -34,11 +40,11 @@ export const useDataGridCellMetadata = < "data-col": col, "data-cell-id": id, "data-field": field, - } + }; const innerAttributes = { "data-container-id": id, - } + }; return { id, @@ -46,10 +52,10 @@ export const useDataGridCellMetadata = < type, inputAttributes, innerAttributes, - } + }; }, - [matrix] - ) + [matrix], + ); /** * Creates error metadata for a cell. This is used to display error messages @@ -57,19 +63,19 @@ export const useDataGridCellMetadata = < */ const getCellErrorMetadata = useCallback( (coords: DataGridCoordinates): CellErrorMetadata => { - const accessor = matrix.getRowAccessor(coords.row) - const field = matrix.getCellField(coords) + const accessor = matrix.getRowAccessor(coords.row); + const field = matrix.getCellField(coords); return { accessor, field, - } + }; }, - [matrix] - ) + [matrix], + ); return { getCellMetadata, getCellErrorMetadata, - } -} + }; +}; diff --git a/src/components/data-grid/hooks/use-data-grid-cell-snapshot.tsx b/src/components/data-grid/hooks/use-data-grid-cell-snapshot.tsx index 9f73327c..5fff0c6c 100644 --- a/src/components/data-grid/hooks/use-data-grid-cell-snapshot.tsx +++ b/src/components/data-grid/hooks/use-data-grid-cell-snapshot.tsx @@ -1,24 +1,29 @@ -import { useCallback, useState } from "react" -import { FieldValues, Path, UseFormReturn } from "react-hook-form" -import { DataGridMatrix } from "../models" -import { DataGridCellSnapshot, DataGridCoordinates } from "../types" +import { useCallback, useState } from "react"; + +import type { FieldValues, Path, UseFormReturn } from "react-hook-form"; + +import type { DataGridMatrix } from "@components/data-grid/models"; +import type { + DataGridCellSnapshot, + DataGridCoordinates, +} from "@components/data-grid/types"; type UseDataGridCellSnapshotOptions = { - matrix: DataGridMatrix - form: UseFormReturn -} + matrix: DataGridMatrix; + form: UseFormReturn; +}; export const useDataGridCellSnapshot = < TData, - TFieldValues extends FieldValues + TFieldValues extends FieldValues, >({ matrix, form, }: UseDataGridCellSnapshotOptions) => { const [snapshot, setSnapshot] = - useState | null>(null) + useState | null>(null); - const { getValues, setValue } = form + const { getValues, setValue } = form; /** * Creates a snapshot of the current cell value. @@ -26,16 +31,16 @@ export const useDataGridCellSnapshot = < const createSnapshot = useCallback( (cell: DataGridCoordinates | null) => { if (!cell) { - return null + return null; } - const field = matrix.getCellField(cell) + const field = matrix.getCellField(cell); if (!field) { - return null + return null; } - const value = getValues(field as Path) + const value = getValues(field as Path); setSnapshot((curr) => { /** @@ -44,32 +49,32 @@ export const useDataGridCellSnapshot = < * we create a snapshot of the value before its destroyed by the space key. */ if (curr?.field === field) { - return curr + return curr; } - return { field, value } - }) + return { field, value }; + }); }, - [getValues, matrix] - ) + [getValues, matrix], + ); /** * Restores the cell value from the snapshot if it exists. */ const restoreSnapshot = useCallback(() => { if (!snapshot) { - return + return; } - const { field, value } = snapshot + const { field, value } = snapshot; requestAnimationFrame(() => { - setValue(field as Path, value) - }) - }, [setValue, snapshot]) + setValue(field as Path, value); + }); + }, [setValue, snapshot]); return { createSnapshot, restoreSnapshot, - } -} + }; +}; diff --git a/src/components/data-grid/hooks/use-data-grid-cell.tsx b/src/components/data-grid/hooks/use-data-grid-cell.tsx index 1fa693f2..eaeddecb 100644 --- a/src/components/data-grid/hooks/use-data-grid-cell.tsx +++ b/src/components/data-grid/hooks/use-data-grid-cell.tsx @@ -1,20 +1,22 @@ -import { CellContext } from "@tanstack/react-table" -import React, { useCallback, useEffect, useMemo, useRef, useState } from "react" +import type React from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; -import { useDataGridContext } from "../context" -import { +import type { CellContext } from "@tanstack/react-table"; + +import { useDataGridContext } from "@components/data-grid/context"; +import type { DataGridCellContext, DataGridCellRenderProps, DataGridCoordinates, -} from "../types" -import { isCellMatch, isSpecialFocusKey } from "../utils" +} from "@components/data-grid/types"; +import { isCellMatch, isSpecialFocusKey } from "@components/data-grid/utils"; type UseDataGridCellOptions = { - context: CellContext -} + context: CellContext; +}; -const textCharacterRegex = /^.$/u -const numberCharacterRegex = /^[0-9]$/u +const textCharacterRegex = /^.$/u; +const numberCharacterRegex = /^[0-9]$/u; export const useDataGridCell = ({ context, @@ -33,39 +35,39 @@ export const useDataGridCell = ({ getIsCellSelected, getIsCellDragSelected, getCellMetadata, - } = useDataGridContext() + } = useDataGridContext(); const { rowIndex, columnIndex } = context as DataGridCellContext< TData, TValue - > + >; const coords: DataGridCoordinates = useMemo( () => ({ row: rowIndex, col: columnIndex }), - [rowIndex, columnIndex] - ) + [rowIndex, columnIndex], + ); const { id, field, type, innerAttributes, inputAttributes } = useMemo(() => { - return getCellMetadata(coords) - }, [coords, getCellMetadata]) + return getCellMetadata(coords); + }, [coords, getCellMetadata]); - const [showOverlay, setShowOverlay] = useState(true) + const [showOverlay, setShowOverlay] = useState(true); - const containerRef = useRef(null) - const inputRef = useRef(null) + const containerRef = useRef(null); + const inputRef = useRef(null); const handleOverlayMouseDown = useCallback( (e: React.MouseEvent) => { - e.preventDefault() - e.stopPropagation() + e.preventDefault(); + e.stopPropagation(); if (e.detail === 2) { if (inputRef.current) { - setShowOverlay(false) + setShowOverlay(false); - inputRef.current.focus() + inputRef.current.focus(); - return + return; } } @@ -73,138 +75,141 @@ export const useDataGridCell = ({ // Only allow setting the rangeEnd if the column matches the anchor column. // If not we let the function continue and treat the click as if the shift key was not pressed. if (coords.col === anchor?.col) { - setRangeEnd(coords) - return + setRangeEnd(coords); + + return; } } if (containerRef.current) { - setSingleRange(coords) - setIsSelecting(true) - containerRef.current.focus() + setSingleRange(coords); + setIsSelecting(true); + containerRef.current.focus(); } }, - [coords, anchor, setRangeEnd, setSingleRange, setIsSelecting] - ) + [coords, anchor, setRangeEnd, setSingleRange, setIsSelecting], + ); const handleBooleanInnerMouseDown = useCallback( (e: React.MouseEvent) => { - e.preventDefault() - e.stopPropagation() + e.preventDefault(); + e.stopPropagation(); if (e.detail === 2) { - inputRef.current?.focus() - return + inputRef.current?.focus(); + + return; } if (e.shiftKey) { - setRangeEnd(coords) - return + setRangeEnd(coords); + + return; } if (containerRef.current) { - setSingleRange(coords) - setIsSelecting(true) - containerRef.current.focus() + setSingleRange(coords); + setIsSelecting(true); + containerRef.current.focus(); } }, - [setIsSelecting, setSingleRange, setRangeEnd, coords] - ) + [setIsSelecting, setSingleRange, setRangeEnd, coords], + ); const handleInputBlur = useCallback(() => { - setShowOverlay(true) - setIsEditing(false) - }, [setIsEditing]) + setShowOverlay(true); + setIsEditing(false); + }, [setIsEditing]); const handleInputFocus = useCallback(() => { - setShowOverlay(false) - setIsEditing(true) - }, [setIsEditing]) + setShowOverlay(false); + setIsEditing(true); + }, [setIsEditing]); const validateKeyStroke = useCallback( (key: string) => { switch (type) { case "togglable-number": case "number": - return numberCharacterRegex.test(key) + return numberCharacterRegex.test(key); case "text": - return textCharacterRegex.test(key) + return textCharacterRegex.test(key); default: // KeyboardEvents should not be forwareded to other types of cells - return false + return false; } }, - [type] - ) + [type], + ); const handleContainerKeyDown = useCallback( (e: React.KeyboardEvent) => { if (!inputRef.current || !validateKeyStroke(e.key) || !showOverlay) { - return + return; } // Allow the user to undo/redo if (e.key.toLowerCase() === "z" && (e.ctrlKey || e.metaKey)) { - return + return; } // Allow the user to copy if (e.key.toLowerCase() === "c" && (e.ctrlKey || e.metaKey)) { - return + return; } // Allow the user to paste if (e.key.toLowerCase() === "v" && (e.ctrlKey || e.metaKey)) { - return + return; } if (e.key === "Enter") { - return + return; } if (isSpecialFocusKey(e.nativeEvent)) { - return + return; } - inputRef.current.focus() - setShowOverlay(false) + inputRef.current.focus(); + setShowOverlay(false); if (inputRef.current instanceof HTMLInputElement) { // Clear the current value - inputRef.current.value = "" + inputRef.current.value = ""; // Simulate typing the new key const nativeInputValueSetter = Object.getOwnPropertyDescriptor( window.HTMLInputElement.prototype, - "value" - )?.set - nativeInputValueSetter?.call(inputRef.current, e.key) + "value", + )?.set; + nativeInputValueSetter?.call(inputRef.current, e.key); // Trigger input event to notify react-hook-form - const event = new Event("input", { bubbles: true }) - inputRef.current.dispatchEvent(event) + const event = new Event("input", { bubbles: true }); + inputRef.current.dispatchEvent(event); } // Prevent the original event from propagating - e.stopPropagation() - e.preventDefault() + e.stopPropagation(); + e.preventDefault(); }, - [showOverlay, validateKeyStroke] - ) + [showOverlay, validateKeyStroke], + ); const isAnchor = useMemo(() => { - return anchor ? isCellMatch(coords, anchor) : false - }, [anchor, coords]) + return anchor ? isCellMatch(coords, anchor) : false; + }, [anchor, coords]); const fieldWithoutOverlay = useMemo(() => { - return type === "boolean" - }, [type]) + return type === "boolean"; + }, [type]); useEffect(() => { if (isAnchor && !containerRef.current?.contains(document.activeElement)) { - containerRef.current?.focus() + containerRef.current?.focus(); } - }, [isAnchor]) + }, [isAnchor]); const renderProps: DataGridCellRenderProps = { container: { @@ -233,7 +238,7 @@ export const useDataGridCell = ({ onChange: getInputChangeHandler(field), ...inputAttributes, }, - } + }; return { id, @@ -241,5 +246,5 @@ export const useDataGridCell = ({ register, control, renderProps, - } -} + }; +}; diff --git a/src/components/data-grid/hooks/use-data-grid-clipboard-events.tsx b/src/components/data-grid/hooks/use-data-grid-clipboard-events.tsx index d8170b48..93f3e6e2 100644 --- a/src/components/data-grid/hooks/use-data-grid-clipboard-events.tsx +++ b/src/components/data-grid/hooks/use-data-grid-clipboard-events.tsx @@ -1,30 +1,32 @@ -import { useCallback } from "react" -import { FieldValues, Path, PathValue } from "react-hook-form" +import { useCallback } from "react"; -import { DataGridBulkUpdateCommand, DataGridMatrix } from "../models" -import { DataGridCoordinates } from "../types" +import type { FieldValues, Path, PathValue } from "react-hook-form"; + +import type { DataGridMatrix } from "@components/data-grid/models"; +import { DataGridBulkUpdateCommand } from "@components/data-grid/models"; +import type { DataGridCoordinates } from "@components/data-grid/types"; type UseDataGridClipboardEventsOptions< TData, - TFieldValues extends FieldValues + TFieldValues extends FieldValues, > = { - matrix: DataGridMatrix - isEditing: boolean - anchor: DataGridCoordinates | null - rangeEnd: DataGridCoordinates | null + matrix: DataGridMatrix; + isEditing: boolean; + anchor: DataGridCoordinates | null; + rangeEnd: DataGridCoordinates | null; getSelectionValues: ( - fields: string[] - ) => PathValue>[] + fields: string[], + ) => PathValue>[]; setSelectionValues: ( fields: string[], - values: PathValue>[] - ) => void - execute: (command: DataGridBulkUpdateCommand) => void -} + values: PathValue>[], + ) => void; + execute: (command: DataGridBulkUpdateCommand) => void; +}; export const useDataGridClipboardEvents = < TData, - TFieldValues extends FieldValues + TFieldValues extends FieldValues, >({ matrix, anchor, @@ -37,55 +39,56 @@ export const useDataGridClipboardEvents = < const handleCopyEvent = useCallback( (e: ClipboardEvent) => { if (isEditing || !anchor || !rangeEnd) { - return + return; } - e.preventDefault() + e.preventDefault(); - const fields = matrix.getFieldsInSelection(anchor, rangeEnd) - const values = getSelectionValues(fields) + const fields = matrix.getFieldsInSelection(anchor, rangeEnd); + const values = getSelectionValues(fields); const text = values .map((value) => { if (typeof value === "object" && value !== null) { - return JSON.stringify(value) + return JSON.stringify(value); } - return `${value}` ?? "" + + return `${value}` ?? ""; }) - .join("\t") + .join("\t"); - e.clipboardData?.setData("text/plain", text) + e.clipboardData?.setData("text/plain", text); }, - [isEditing, anchor, rangeEnd, matrix, getSelectionValues] - ) + [isEditing, anchor, rangeEnd, matrix, getSelectionValues], + ); const handlePasteEvent = useCallback( (e: ClipboardEvent) => { if (isEditing || !anchor || !rangeEnd) { - return + return; } - e.preventDefault() + e.preventDefault(); - const text = e.clipboardData?.getData("text/plain") + const text = e.clipboardData?.getData("text/plain"); if (!text) { - return + return; } - const next = text.split("\t") + const next = text.split("\t"); - const fields = matrix.getFieldsInSelection(anchor, rangeEnd) - const prev = getSelectionValues(fields) + const fields = matrix.getFieldsInSelection(anchor, rangeEnd); + const prev = getSelectionValues(fields); const command = new DataGridBulkUpdateCommand({ fields, next, prev, setter: setSelectionValues, - }) + }); - execute(command) + execute(command); }, [ isEditing, @@ -95,11 +98,11 @@ export const useDataGridClipboardEvents = < getSelectionValues, setSelectionValues, execute, - ] - ) + ], + ); return { handleCopyEvent, handlePasteEvent, - } -} + }; +}; diff --git a/src/components/data-grid/hooks/use-data-grid-column-visibility.tsx b/src/components/data-grid/hooks/use-data-grid-column-visibility.tsx index 27714bda..4a237ce9 100644 --- a/src/components/data-grid/hooks/use-data-grid-column-visibility.tsx +++ b/src/components/data-grid/hooks/use-data-grid-column-visibility.tsx @@ -1,68 +1,69 @@ -import type { Column, Table } from "@tanstack/react-table" -import { useCallback } from "react" -import type { FieldValues } from "react-hook-form" +import { useCallback } from "react"; -import { DataGridMatrix } from "../models" -import { GridColumnOption } from "../types" +import type { Column, Table } from "@tanstack/react-table"; +import type { FieldValues } from "react-hook-form"; + +import type { DataGridMatrix } from "@components/data-grid/models"; +import type { GridColumnOption } from "@components/data-grid/types"; export function useDataGridColumnVisibility< TData, - TFieldValues extends FieldValues + TFieldValues extends FieldValues, >(grid: Table, matrix: DataGridMatrix) { - const columns = grid.getAllLeafColumns() + const columns = grid.getAllLeafColumns(); const columnOptions: GridColumnOption[] = columns.map((column) => ({ id: column.id, name: getColumnName(column), checked: column.getIsVisible(), disabled: !column.getCanHide(), - })) + })); const handleToggleColumn = useCallback( (index: number) => (value: boolean) => { - const column = columns[index] + const column = columns[index]; if (!column.getCanHide()) { - return + return; } - matrix.toggleColumn(index, value) - column.toggleVisibility(value) + matrix.toggleColumn(index, value); + column.toggleVisibility(value); }, - [columns, matrix] - ) + [columns, matrix], + ); const handleResetColumns = useCallback(() => { - grid.setColumnVisibility({}) - }, [grid]) + grid.setColumnVisibility({}); + }, [grid]); - const optionCount = columnOptions.filter((c) => !c.disabled).length - const isDisabled = optionCount === 0 + const optionCount = columnOptions.filter((c) => !c.disabled).length; + const isDisabled = optionCount === 0; return { columnOptions, handleToggleColumn, handleResetColumns, isDisabled, - } + }; } function getColumnName(column: Column): string { - const id = column.columnDef.id - const enableHiding = column.columnDef.enableHiding - const meta = column?.columnDef.meta as { name?: string } | undefined + const id = column.columnDef.id; + const enableHiding = column.columnDef.enableHiding; + const meta = column?.columnDef.meta as { name?: string } | undefined; if (!id) { throw new Error( - "Column is missing an id, which is a required field. Please provide an id for the column." - ) + "Column is missing an id, which is a required field. Please provide an id for the column.", + ); } if (process.env.NODE_ENV === "development" && !meta?.name && enableHiding) { console.warn( - `Column "${id}" does not have a name. You should add a name to the column definition. Falling back to the column id.` - ) + `Column "${id}" does not have a name. You should add a name to the column definition. Falling back to the column id.`, + ); } - return meta?.name || id + return meta?.name || id; } diff --git a/src/components/data-grid/hooks/use-data-grid-duplicate-cell.tsx b/src/components/data-grid/hooks/use-data-grid-duplicate-cell.tsx index 4244466c..8cee12e9 100644 --- a/src/components/data-grid/hooks/use-data-grid-duplicate-cell.tsx +++ b/src/components/data-grid/hooks/use-data-grid-duplicate-cell.tsx @@ -1,18 +1,19 @@ -import { useWatch } from "react-hook-form" -import { useDataGridContext } from "../context" +import { useWatch } from "react-hook-form"; + +import { useDataGridContext } from "@components/data-grid/context"; interface UseDataGridDuplicateCellOptions { - duplicateOf: string + duplicateOf: string; } export const useDataGridDuplicateCell = ({ duplicateOf, }: UseDataGridDuplicateCellOptions) => { - const { control } = useDataGridContext() + const { control } = useDataGridContext(); - const watchedValue = useWatch({ control, name: duplicateOf }) + const watchedValue = useWatch({ control, name: duplicateOf }); return { watchedValue, - } -} + }; +}; diff --git a/src/components/data-grid/hooks/use-data-grid-error-highlighting.tsx b/src/components/data-grid/hooks/use-data-grid-error-highlighting.tsx index 393b7b67..4350c19f 100644 --- a/src/components/data-grid/hooks/use-data-grid-error-highlighting.tsx +++ b/src/components/data-grid/hooks/use-data-grid-error-highlighting.tsx @@ -1,102 +1,103 @@ -import { Table, VisibilityState } from "@tanstack/react-table" -import { useCallback, useMemo, useState } from "react" -import { FieldError, FieldErrors, FieldValues } from "react-hook-form" +import { useCallback, useMemo, useState } from "react"; -import { DataGridMatrix } from "../models" -import { VisibilitySnapshot } from "../types" +import type { Table, VisibilityState } from "@tanstack/react-table"; +import type { FieldError, FieldErrors, FieldValues } from "react-hook-form"; + +import type { DataGridMatrix } from "@components/data-grid/models"; +import type { VisibilitySnapshot } from "@components/data-grid/types"; export const useDataGridErrorHighlighting = < TData, - TFieldValues extends FieldValues + TFieldValues extends FieldValues, >( matrix: DataGridMatrix, grid: Table, - errors: FieldErrors + errors: FieldErrors, ) => { - const [isHighlighted, setIsHighlighted] = useState(false) + const [isHighlighted, setIsHighlighted] = useState(false); const [visibilitySnapshot, setVisibilitySnapshot] = - useState(null) + useState(null); - const { flatRows } = grid.getRowModel() - const flatColumns = grid.getAllFlatColumns() + const { flatRows } = grid.getRowModel(); + const flatColumns = grid.getAllFlatColumns(); - const errorPaths = findErrorPaths(errors) - const errorCount = errorPaths.length + const errorPaths = findErrorPaths(errors); + const errorCount = errorPaths.length; const { rowsWithErrors, columnsWithErrors } = useMemo(() => { - const rowsWithErrors = new Set() - const columnsWithErrors = new Set() + const rowsWithErrors = new Set(); + const columnsWithErrors = new Set(); errorPaths.forEach((errorPath) => { const rowIndex = matrix.rowAccessors.findIndex( (accessor) => accessor && - (errorPath === accessor || errorPath.startsWith(`${accessor}.`)) - ) + (errorPath === accessor || errorPath.startsWith(`${accessor}.`)), + ); if (rowIndex !== -1) { - rowsWithErrors.add(rowIndex) + rowsWithErrors.add(rowIndex); } const columnIndex = matrix.columnAccessors.findIndex( (accessor) => accessor && - (errorPath === accessor || errorPath.endsWith(`.${accessor}`)) - ) + (errorPath === accessor || errorPath.endsWith(`.${accessor}`)), + ); if (columnIndex !== -1) { - columnsWithErrors.add(columnIndex) + columnsWithErrors.add(columnIndex); } - }) + }); - return { rowsWithErrors, columnsWithErrors } - }, [errorPaths, matrix.rowAccessors, matrix.columnAccessors]) + return { rowsWithErrors, columnsWithErrors }; + }, [errorPaths, matrix.rowAccessors, matrix.columnAccessors]); const toggleErrorHighlighting = useCallback( ( currentRowVisibility: VisibilityState, currentColumnVisibility: VisibilityState, setRowVisibility: (visibility: VisibilityState) => void, - setColumnVisibility: (visibility: VisibilityState) => void + setColumnVisibility: (visibility: VisibilityState) => void, ) => { if (isHighlighted) { // Clear error highlights if (visibilitySnapshot) { - setRowVisibility(visibilitySnapshot.rows) - setColumnVisibility(visibilitySnapshot.columns) + setRowVisibility(visibilitySnapshot.rows); + setColumnVisibility(visibilitySnapshot.columns); } } else { // Highlight errors setVisibilitySnapshot({ rows: { ...currentRowVisibility }, columns: { ...currentColumnVisibility }, - }) + }); const rowsToHide = flatRows .map((_, index) => { - return !rowsWithErrors.has(index) ? index : undefined + return !rowsWithErrors.has(index) ? index : undefined; }) - .filter((index): index is number => index !== undefined) + .filter((index): index is number => index !== undefined); const columnsToHide = flatColumns .map((column, index) => { return !columnsWithErrors.has(index) && index !== 0 ? column.id - : undefined + : undefined; }) - .filter((id): id is string => id !== undefined) + .filter((id): id is string => id !== undefined); setRowVisibility( - rowsToHide.reduce((acc, row) => ({ ...acc, [row]: false }), {}) - ) + rowsToHide.reduce((acc, row) => ({ ...acc, [row]: false }), {}), + ); setColumnVisibility( columnsToHide.reduce( (acc, column) => ({ ...acc, [column]: false }), - {} - ) - ) + {}, + ), + ); } - setIsHighlighted((prev) => !prev) + setIsHighlighted((prev) => !prev); }, [ isHighlighted, @@ -105,29 +106,29 @@ export const useDataGridErrorHighlighting = < flatColumns, rowsWithErrors, columnsWithErrors, - ] - ) + ], + ); return { errorCount, isHighlighted, toggleErrorHighlighting, - } -} + }; +}; function findErrorPaths( obj: FieldErrors | FieldError, - path: string[] = [] + path: string[] = [], ): string[] { if (typeof obj !== "object" || obj === null) { - return [] + return []; } if ("message" in obj && "type" in obj) { - return [path.join(".")] + return [path.join(".")]; } return Object.entries(obj).flatMap(([key, value]) => - findErrorPaths(value, [...path, key]) - ) + findErrorPaths(value, [...path, key]), + ); } diff --git a/src/components/data-grid/hooks/use-data-grid-form-handlers.tsx b/src/components/data-grid/hooks/use-data-grid-form-handlers.tsx index cf603950..77168c89 100644 --- a/src/components/data-grid/hooks/use-data-grid-form-handlers.tsx +++ b/src/components/data-grid/hooks/use-data-grid-form-handlers.tsx @@ -1,222 +1,242 @@ -import get from "lodash/get" -import set from "lodash/set" -import { useCallback } from "react" -import { FieldValues, Path, PathValue, UseFormReturn } from "react-hook-form" - -import { DataGridMatrix } from "../models" -import { +import { useCallback } from "react"; + +import get from "lodash/get"; +import set from "lodash/set"; +import type { + FieldValues, + Path, + PathValue, + UseFormReturn, +} from "react-hook-form"; + +import type { DataGridMatrix } from "@components/data-grid/models"; +import type { DataGridColumnType, DataGridCoordinates, DataGridToggleableNumber, -} from "../types" +} from "@components/data-grid/types"; type UseDataGridFormHandlersOptions = { - matrix: DataGridMatrix - form: UseFormReturn - anchor: DataGridCoordinates | null -} + matrix: DataGridMatrix; + form: UseFormReturn; + anchor: DataGridCoordinates | null; +}; export const useDataGridFormHandlers = < TData, - TFieldValues extends FieldValues + TFieldValues extends FieldValues, >({ matrix, form, anchor, }: UseDataGridFormHandlersOptions) => { - const { getValues, reset } = form + const { getValues, reset } = form; const getSelectionValues = useCallback( (fields: string[]): PathValue>[] => { if (!fields.length) { - return [] + return []; } - const allValues = getValues() + const allValues = getValues(); return fields.map((field) => { - return field.split(".").reduce((obj, key) => obj?.[key], allValues) - }) as PathValue>[] + return field.split(".").reduce((obj, key) => obj?.[key], allValues); + }) as PathValue>[]; }, - [getValues] - ) + [getValues], + ); const setSelectionValues = useCallback( async (fields: string[], values: string[], isHistory?: boolean) => { if (!fields.length || !anchor) { - return + return; } - const type = matrix.getCellType(anchor) + const type = matrix.getCellType(anchor); if (!type) { - return + return; } - const convertedValues = convertArrayToPrimitive(values, type) - const currentValues = getValues() + const convertedValues = convertArrayToPrimitive(values, type); + const currentValues = getValues(); fields.forEach((field, index) => { if (!field) { - return + return; } - const valueIndex = index % values.length - const newValue = convertedValues[valueIndex] + const valueIndex = index % values.length; + const newValue = convertedValues[valueIndex]; - setValue(currentValues, field, newValue, type, isHistory) - }) + setValue(currentValues, field, newValue, type, isHistory); + }); reset(currentValues, { keepDirty: true, keepTouched: true, keepDefaultValues: true, - }) + }); }, - [matrix, anchor, getValues, reset] - ) + [matrix, anchor, getValues, reset], + ); return { getSelectionValues, setSelectionValues, - } -} + }; +}; function convertToNumber(value: string | number): number { if (typeof value === "number") { - return value + return value; } - const converted = Number(value) + const converted = Number(value); if (isNaN(converted)) { - throw new Error(`String "${value}" cannot be converted to number.`) + throw new Error(`String "${value}" cannot be converted to number.`); } - return converted + return converted; } function convertToBoolean(value: string | boolean): boolean { if (typeof value === "boolean") { - return value + return value; } if (typeof value === "undefined" || value === null) { - return false + return false; } - const lowerValue = value.toLowerCase() + const lowerValue = value.toLowerCase(); if (lowerValue === "true" || lowerValue === "false") { - return lowerValue === "true" + return lowerValue === "true"; } - throw new Error(`String "${value}" cannot be converted to boolean.`) + throw new Error(`String "${value}" cannot be converted to boolean.`); } +// @todo fix type +// eslint-disable-next-line @typescript-eslint/no-explicit-any function covertToString(value: any): string { if (typeof value === "undefined" || value === null) { - return "" + return ""; } - return String(value) + return String(value); } - +// @todo fix type +// eslint-disable-next-line @typescript-eslint/no-explicit-any function convertToggleableNumber(value: any): { - quantity: number - checked: boolean - disabledToggle: boolean + quantity: number; + checked: boolean; + disabledToggle: boolean; } { - let obj = value + let obj = value; if (typeof obj === "string") { try { - obj = JSON.parse(obj) - } catch (error) { - throw new Error(`String "${value}" cannot be converted to object.`) + obj = JSON.parse(obj); + } catch (_error) { + throw new Error(`String "${value}" cannot be converted to object.`); } } - return obj + return obj; } function setValue< - T extends DataGridToggleableNumber = DataGridToggleableNumber + T extends DataGridToggleableNumber = DataGridToggleableNumber, >( + //@todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any currentValues: any, field: string, newValue: T, type: string, - isHistory?: boolean + isHistory?: boolean, ) { if (type !== "togglable-number") { - set(currentValues, field, newValue) - return + set(currentValues, field, newValue); + + return; } - setValueToggleableNumber(currentValues, field, newValue, isHistory) + setValueToggleableNumber(currentValues, field, newValue, isHistory); } function setValueToggleableNumber( + // @todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any currentValues: any, field: string, newValue: DataGridToggleableNumber, - isHistory?: boolean + isHistory?: boolean, ) { - const currentValue = get(currentValues, field) - const { disabledToggle } = currentValue + const currentValue = get(currentValues, field); + const { disabledToggle } = currentValue; const normalizeQuantity = (value: number | string | null | undefined) => { if (disabledToggle && value === "") { - return 0 + return 0; } - return value - } + + return value; + }; const determineChecked = (quantity: number | string | null | undefined) => { if (disabledToggle) { - return true + return true; } - return quantity !== "" && quantity != null - } - const quantity = normalizeQuantity(newValue.quantity) + return quantity !== "" && quantity != null; + }; + + const quantity = normalizeQuantity(newValue.quantity); const checked = isHistory ? disabledToggle ? true : newValue.checked - : determineChecked(quantity) + : determineChecked(quantity); set(currentValues, field, { ...currentValue, quantity, checked, - }) + }); } export function convertArrayToPrimitive( + // @todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any values: any[], - type: DataGridColumnType + type: DataGridColumnType, + // @todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any ): any[] { switch (type) { case "number": return values.map((v) => { if (v === "") { - return v + return v; } if (v == null) { - return "" + return ""; } - return convertToNumber(v) - }) + return convertToNumber(v); + }); case "togglable-number": - return values.map(convertToggleableNumber) + return values.map(convertToggleableNumber); case "boolean": - return values.map(convertToBoolean) + return values.map(convertToBoolean); case "text": - return values.map(covertToString) + return values.map(covertToString); default: - throw new Error(`Unsupported target type "${type}".`) + throw new Error(`Unsupported target type "${type}".`); } } diff --git a/src/components/data-grid/hooks/use-data-grid-keydown-event.tsx b/src/components/data-grid/hooks/use-data-grid-keydown-event.tsx index 9980db9a..f4150ca1 100644 --- a/src/components/data-grid/hooks/use-data-grid-keydown-event.tsx +++ b/src/components/data-grid/hooks/use-data-grid-keydown-event.tsx @@ -1,53 +1,58 @@ -import React, { useCallback } from "react" +import type React from "react"; +import { useCallback } from "react"; + import type { FieldValues, Path, PathValue, UseFormGetValues, UseFormSetValue, -} from "react-hook-form" -import { - DataGridBulkUpdateCommand, +} from "react-hook-form"; + +import type { DataGridMatrix, DataGridQueryTool, +} from "@components/data-grid/models"; +import { + DataGridBulkUpdateCommand, DataGridUpdateCommand, -} from "../models" -import { DataGridCoordinates } from "../types" +} from "@components/data-grid/models"; +import type { DataGridCoordinates } from "@components/data-grid/types"; type UseDataGridKeydownEventOptions = { - containerRef: React.RefObject - matrix: DataGridMatrix - anchor: DataGridCoordinates | null - rangeEnd: DataGridCoordinates | null - isEditing: boolean + containerRef: React.RefObject; + matrix: DataGridMatrix; + anchor: DataGridCoordinates | null; + rangeEnd: DataGridCoordinates | null; + isEditing: boolean; scrollToCoordinates: ( coords: DataGridCoordinates, - direction: "horizontal" | "vertical" | "both" - ) => void - setTrapActive: (active: boolean) => void - setSingleRange: (coordinates: DataGridCoordinates | null) => void - setRangeEnd: (coordinates: DataGridCoordinates | null) => void - onEditingChangeHandler: (value: boolean) => void - getValues: UseFormGetValues - setValue: UseFormSetValue - execute: (command: DataGridUpdateCommand | DataGridBulkUpdateCommand) => void - undo: () => void - redo: () => void - queryTool: DataGridQueryTool | null + direction: "horizontal" | "vertical" | "both", + ) => void; + setTrapActive: (active: boolean) => void; + setSingleRange: (coordinates: DataGridCoordinates | null) => void; + setRangeEnd: (coordinates: DataGridCoordinates | null) => void; + onEditingChangeHandler: (value: boolean) => void; + getValues: UseFormGetValues; + setValue: UseFormSetValue; + execute: (command: DataGridUpdateCommand | DataGridBulkUpdateCommand) => void; + undo: () => void; + redo: () => void; + queryTool: DataGridQueryTool | null; getSelectionValues: ( - fields: string[] - ) => PathValue>[] - setSelectionValues: (fields: string[], values: string[]) => void - restoreSnapshot: () => void - createSnapshot: (coords: DataGridCoordinates) => void -} + fields: string[], + ) => PathValue>[]; + setSelectionValues: (fields: string[], values: string[]) => void; + restoreSnapshot: () => void; + createSnapshot: (coords: DataGridCoordinates) => void; +}; -const ARROW_KEYS = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"] -const VERTICAL_KEYS = ["ArrowUp", "ArrowDown"] +const ARROW_KEYS = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"]; +const VERTICAL_KEYS = ["ArrowUp", "ArrowDown"]; export const useDataGridKeydownEvent = < TData, - TFieldValues extends FieldValues + TFieldValues extends FieldValues, >({ containerRef, matrix, @@ -73,10 +78,10 @@ export const useDataGridKeydownEvent = < const handleKeyboardNavigation = useCallback( (e: KeyboardEvent) => { if (!anchor) { - return + return; } - const type = matrix.getCellType(anchor) + const type = matrix.getCellType(anchor); /** * If the user is currently editing a cell, we don't want to @@ -87,12 +92,12 @@ export const useDataGridKeydownEvent = < * away from the cell directly, as you cannot "enter" a boolean cell. */ if (isEditing && type !== "boolean") { - return + return; } const direction = VERTICAL_KEYS.includes(e.key) ? "vertical" - : "horizontal" + : "horizontal"; /** * If the user performs a horizontal navigation, we want to @@ -104,37 +109,37 @@ export const useDataGridKeydownEvent = < * we want to use the anchor as the basis. */ const basis = - direction === "horizontal" ? anchor : e.shiftKey ? rangeEnd : anchor + direction === "horizontal" ? anchor : e.shiftKey ? rangeEnd : anchor; const updater = direction === "horizontal" ? setSingleRange : e.shiftKey - ? setRangeEnd - : setSingleRange + ? setRangeEnd + : setSingleRange; if (!basis) { - return + return; } - const { row, col } = basis + const { row, col } = basis; const handleNavigation = (coords: DataGridCoordinates) => { - e.preventDefault() - e.stopPropagation() + e.preventDefault(); + e.stopPropagation(); - scrollToCoordinates(coords, direction) - updater(coords) - } + scrollToCoordinates(coords, direction); + updater(coords); + }; const next = matrix.getValidMovement( row, col, e.key, - e.metaKey || e.ctrlKey - ) + e.metaKey || e.ctrlKey, + ); - handleNavigation(next) + handleNavigation(next); }, [ isEditing, @@ -144,86 +149,87 @@ export const useDataGridKeydownEvent = < setSingleRange, setRangeEnd, matrix, - ] - ) + ], + ); const handleTabKey = useCallback( (e: KeyboardEvent) => { if (!anchor) { - return + return; } - e.preventDefault() - e.stopPropagation() + e.preventDefault(); + e.stopPropagation(); - const { row, col } = anchor + const { row, col } = anchor; - const key = e.shiftKey ? "ArrowLeft" : "ArrowRight" - const direction = "horizontal" + const key = e.shiftKey ? "ArrowLeft" : "ArrowRight"; + const direction = "horizontal"; const next = matrix.getValidMovement( row, col, key, - e.metaKey || e.ctrlKey - ) + e.metaKey || e.ctrlKey, + ); - scrollToCoordinates(next, direction) - setSingleRange(next) + scrollToCoordinates(next, direction); + setSingleRange(next); }, - [anchor, scrollToCoordinates, setSingleRange, matrix] - ) + [anchor, scrollToCoordinates, setSingleRange, matrix], + ); const handleUndo = useCallback( (e: KeyboardEvent) => { - e.preventDefault() + e.preventDefault(); if (e.shiftKey) { - redo() - return + redo(); + + return; } - undo() + undo(); }, - [redo, undo] - ) + [redo, undo], + ); const handleSpaceKeyBoolean = useCallback( (anchor: DataGridCoordinates) => { - const end = rangeEnd ?? anchor + const end = rangeEnd ?? anchor; - const fields = matrix.getFieldsInSelection(anchor, end) + const fields = matrix.getFieldsInSelection(anchor, end); - const prev = getSelectionValues(fields) as boolean[] + const prev = getSelectionValues(fields) as boolean[]; - const allChecked = prev.every((value) => value === true) - const next = Array.from({ length: prev.length }, () => !allChecked) + const allChecked = prev.every((value) => value); + const next = Array.from({ length: prev.length }, () => !allChecked); const command = new DataGridBulkUpdateCommand({ fields, next, prev, setter: setSelectionValues, - }) + }); - execute(command) + execute(command); }, - [rangeEnd, matrix, getSelectionValues, setSelectionValues, execute] - ) + [rangeEnd, matrix, getSelectionValues, setSelectionValues, execute], + ); const handleSpaceKeyTextOrNumber = useCallback( (anchor: DataGridCoordinates) => { - const field = matrix.getCellField(anchor) - const input = queryTool?.getInput(anchor) + const field = matrix.getCellField(anchor); + const input = queryTool?.getInput(anchor); if (!field || !input) { - return + return; } - createSnapshot(anchor) + createSnapshot(anchor); - const current = getValues(field as Path) - const next = "" + const current = getValues(field as Path); + const next = ""; const command = new DataGridUpdateCommand({ next, @@ -232,37 +238,37 @@ export const useDataGridKeydownEvent = < setValue(field as Path, value, { shouldDirty: true, shouldTouch: true, - }) + }); }, - }) + }); - execute(command) + execute(command); - input.focus() + input.focus(); }, - [matrix, queryTool, getValues, execute, setValue, createSnapshot] - ) + [matrix, queryTool, getValues, execute, setValue, createSnapshot], + ); const handleSpaceKeyTogglableNumber = useCallback( (anchor: DataGridCoordinates) => { - const field = matrix.getCellField(anchor) - const input = queryTool?.getInput(anchor) + const field = matrix.getCellField(anchor); + const input = queryTool?.getInput(anchor); if (!field || !input) { - return + return; } - createSnapshot(anchor) + createSnapshot(anchor); - const current = getValues(field as Path) - let checked = current.checked + const current = getValues(field as Path); + let checked = current.checked; // If the toggle is not disabled, then we want to uncheck the toggle. if (!current.disabledToggle) { - checked = false + checked = false; } - const next = { ...current, quantity: "", checked } + const next = { ...current, quantity: "", checked }; const command = new DataGridUpdateCommand({ next, @@ -271,42 +277,42 @@ export const useDataGridKeydownEvent = < setValue(field as Path, value, { shouldDirty: true, shouldTouch: true, - }) + }); }, - }) + }); - execute(command) + execute(command); - input.focus() + input.focus(); }, - [matrix, queryTool, getValues, execute, setValue, createSnapshot] - ) + [matrix, queryTool, getValues, execute, setValue, createSnapshot], + ); const handleSpaceKey = useCallback( (e: KeyboardEvent) => { if (!anchor || isEditing) { - return + return; } - e.preventDefault() + e.preventDefault(); - const type = matrix.getCellType(anchor) + const type = matrix.getCellType(anchor); if (!type) { - return + return; } switch (type) { case "boolean": - handleSpaceKeyBoolean(anchor) - break + handleSpaceKeyBoolean(anchor); + break; case "togglable-number": - handleSpaceKeyTogglableNumber(anchor) - break + handleSpaceKeyTogglableNumber(anchor); + break; case "number": case "text": - handleSpaceKeyTextOrNumber(anchor) - break + handleSpaceKeyTextOrNumber(anchor); + break; } }, [ @@ -316,31 +322,31 @@ export const useDataGridKeydownEvent = < handleSpaceKeyBoolean, handleSpaceKeyTextOrNumber, handleSpaceKeyTogglableNumber, - ] - ) + ], + ); const handleMoveOnEnter = useCallback( (e: KeyboardEvent, anchor: DataGridCoordinates) => { - const direction = e.shiftKey ? "ArrowUp" : "ArrowDown" + const direction = e.shiftKey ? "ArrowUp" : "ArrowDown"; const pos = matrix.getValidMovement( anchor.row, anchor.col, direction, - false - ) + false, + ); if (anchor.row !== pos.row || anchor.col !== pos.col) { - setSingleRange(pos) - scrollToCoordinates(pos, "vertical") + setSingleRange(pos); + scrollToCoordinates(pos, "vertical"); } else { // If the the user is at the last cell, we want to focus the container of the cell. - const container = queryTool?.getContainer(anchor) + const container = queryTool?.getContainer(anchor); - container?.focus() + container?.focus(); } - onEditingChangeHandler(false) + onEditingChangeHandler(false); }, [ queryTool, @@ -348,22 +354,22 @@ export const useDataGridKeydownEvent = < scrollToCoordinates, setSingleRange, onEditingChangeHandler, - ] - ) + ], + ); const handleEditOnEnter = useCallback( (anchor: DataGridCoordinates) => { - const input = queryTool?.getInput(anchor) + const input = queryTool?.getInput(anchor); if (!input) { - return + return; } - input.focus() - onEditingChangeHandler(true) + input.focus(); + onEditingChangeHandler(true); }, - [queryTool, onEditingChangeHandler] - ) + [queryTool, onEditingChangeHandler], + ); /** * Handles the enter key for text and number cells. @@ -375,14 +381,15 @@ export const useDataGridKeydownEvent = < const handleEnterKeyTextOrNumber = useCallback( (e: KeyboardEvent, anchor: DataGridCoordinates) => { if (isEditing) { - handleMoveOnEnter(e, anchor) - return + handleMoveOnEnter(e, anchor); + + return; } - handleEditOnEnter(anchor) + handleEditOnEnter(anchor); }, - [handleMoveOnEnter, handleEditOnEnter, isEditing] - ) + [handleMoveOnEnter, handleEditOnEnter, isEditing], + ); /** * Handles the enter key for boolean cells. @@ -394,20 +401,14 @@ export const useDataGridKeydownEvent = < */ const handleEnterKeyBoolean = useCallback( (e: KeyboardEvent, anchor: DataGridCoordinates) => { - const field = matrix.getCellField(anchor) + const field = matrix.getCellField(anchor); if (!field) { - return + return; } - const current = getValues(field as Path) - let next: boolean - - if (typeof current === "boolean") { - next = !current - } else { - next = true - } + const current = getValues(field as Path); + const next = true; const command = new DataGridUpdateCommand({ next, @@ -416,125 +417,125 @@ export const useDataGridKeydownEvent = < setValue(field as Path, value, { shouldDirty: true, shouldTouch: true, - }) + }); }, - }) + }); - execute(command) - handleMoveOnEnter(e, anchor) + execute(command); + handleMoveOnEnter(e, anchor); }, - [execute, getValues, handleMoveOnEnter, matrix, setValue] - ) + [execute, getValues, handleMoveOnEnter, matrix, setValue], + ); const handleEnterKey = useCallback( (e: KeyboardEvent) => { if (!anchor) { - return + return; } - e.preventDefault() + e.preventDefault(); - const type = matrix.getCellType(anchor) + const type = matrix.getCellType(anchor); switch (type) { case "togglable-number": case "text": case "number": - handleEnterKeyTextOrNumber(e, anchor) - break + handleEnterKeyTextOrNumber(e, anchor); + break; case "boolean": { - handleEnterKeyBoolean(e, anchor) - break + handleEnterKeyBoolean(e, anchor); + break; } } }, - [anchor, matrix, handleEnterKeyTextOrNumber, handleEnterKeyBoolean] - ) + [anchor, matrix, handleEnterKeyTextOrNumber, handleEnterKeyBoolean], + ); const handleDeleteKeyTogglableNumber = useCallback( (anchor: DataGridCoordinates, rangeEnd: DataGridCoordinates) => { - const fields = matrix.getFieldsInSelection(anchor, rangeEnd) - const prev = getSelectionValues(fields) + const fields = matrix.getFieldsInSelection(anchor, rangeEnd); + const prev = getSelectionValues(fields); const next = prev.map((value) => ({ ...value, quantity: "", checked: value.disableToggle ? value.checked : false, - })) + })); const command = new DataGridBulkUpdateCommand({ fields, next, prev, setter: setSelectionValues, - }) + }); - execute(command) + execute(command); }, - [matrix, getSelectionValues, setSelectionValues, execute] - ) + [matrix, getSelectionValues, setSelectionValues, execute], + ); const handleDeleteKeyTextOrNumber = useCallback( (anchor: DataGridCoordinates, rangeEnd: DataGridCoordinates) => { - const fields = matrix.getFieldsInSelection(anchor, rangeEnd) - const prev = getSelectionValues(fields) - const next = Array.from({ length: prev.length }, () => "") + const fields = matrix.getFieldsInSelection(anchor, rangeEnd); + const prev = getSelectionValues(fields); + const next = Array.from({ length: prev.length }, () => ""); const command = new DataGridBulkUpdateCommand({ fields, next, prev, setter: setSelectionValues, - }) + }); - execute(command) + execute(command); }, - [matrix, getSelectionValues, setSelectionValues, execute] - ) + [matrix, getSelectionValues, setSelectionValues, execute], + ); const handleDeleteKeyBoolean = useCallback( (anchor: DataGridCoordinates, rangeEnd: DataGridCoordinates) => { - const fields = matrix.getFieldsInSelection(anchor, rangeEnd) - const prev = getSelectionValues(fields) - const next = Array.from({ length: prev.length }, () => false) + const fields = matrix.getFieldsInSelection(anchor, rangeEnd); + const prev = getSelectionValues(fields); + const next = Array.from({ length: prev.length }, () => false); const command = new DataGridBulkUpdateCommand({ fields, next, prev, setter: setSelectionValues, - }) + }); - execute(command) + execute(command); }, - [execute, getSelectionValues, matrix, setSelectionValues] - ) + [execute, getSelectionValues, matrix, setSelectionValues], + ); const handleDeleteKey = useCallback( (e: KeyboardEvent) => { if (!anchor || !rangeEnd || isEditing) { - return + return; } - e.preventDefault() + e.preventDefault(); - const type = matrix.getCellType(anchor) + const type = matrix.getCellType(anchor); if (!type) { - return + return; } switch (type) { case "text": case "number": - handleDeleteKeyTextOrNumber(anchor, rangeEnd) - break + handleDeleteKeyTextOrNumber(anchor, rangeEnd); + break; case "boolean": - handleDeleteKeyBoolean(anchor, rangeEnd) - break + handleDeleteKeyBoolean(anchor, rangeEnd); + break; case "togglable-number": - handleDeleteKeyTogglableNumber(anchor, rangeEnd) - break + handleDeleteKeyTogglableNumber(anchor, rangeEnd); + break; } }, [ @@ -545,92 +546,99 @@ export const useDataGridKeydownEvent = < handleDeleteKeyTextOrNumber, handleDeleteKeyBoolean, handleDeleteKeyTogglableNumber, - ] - ) + ], + ); const handleEscapeKey = useCallback( (e: KeyboardEvent) => { if (!anchor || !isEditing) { - return + return; } - e.preventDefault() - e.stopPropagation() + e.preventDefault(); + e.stopPropagation(); // try to restore the previous value - restoreSnapshot() + restoreSnapshot(); // Restore focus to the container element - const container = queryTool?.getContainer(anchor) - container?.focus() + const container = queryTool?.getContainer(anchor); + container?.focus(); }, - [queryTool, isEditing, anchor, restoreSnapshot] - ) + [queryTool, isEditing, anchor, restoreSnapshot], + ); const handleSpecialFocusKeys = useCallback( (e: KeyboardEvent) => { if (!containerRef || isEditing) { - return + return; } - const focusableElements = getFocusableElements(containerRef) + const focusableElements = getFocusableElements(containerRef); const focusElement = (element: HTMLElement | null) => { if (element) { - setTrapActive(false) - element.focus() + setTrapActive(false); + element.focus(); } - } + }; switch (e.key) { case ".": - focusElement(focusableElements.cancel) - break + focusElement(focusableElements.cancel); + break; case ",": - focusElement(focusableElements.shortcuts) - break + focusElement(focusableElements.shortcuts); + break; default: - break + break; } }, - [isEditing, setTrapActive, containerRef] - ) + [isEditing, setTrapActive, containerRef], + ); const handleKeyDownEvent = useCallback( (e: KeyboardEvent) => { if (ARROW_KEYS.includes(e.key)) { - handleKeyboardNavigation(e) - return + handleKeyboardNavigation(e); + + return; } if (e.key === "z" && (e.metaKey || e.ctrlKey)) { - handleUndo(e) - return + handleUndo(e); + + return; } if (e.key === " ") { - handleSpaceKey(e) - return + handleSpaceKey(e); + + return; } if (e.key === "Delete" || e.key === "Backspace") { - handleDeleteKey(e) - return + handleDeleteKey(e); + + return; } if (e.key === "Enter") { - handleEnterKey(e) - return + handleEnterKey(e); + + return; } if (e.key === "Escape") { - handleEscapeKey(e) - return + handleEscapeKey(e); + + return; } if (e.key === "Tab") { - handleTabKey(e) - return + handleTabKey(e); + + return; } }, [ @@ -641,34 +649,34 @@ export const useDataGridKeydownEvent = < handleEnterKey, handleDeleteKey, handleTabKey, - ] - ) + ], + ); return { handleKeyDownEvent, handleSpecialFocusKeys, - } -} + }; +}; function getFocusableElements(ref: React.RefObject) { const focusableElements = Array.from( document.querySelectorAll( - "[tabindex], a, button, input, select, textarea" - ) - ) + "[tabindex], a, button, input, select, textarea", + ), + ); - const currentElementIndex = focusableElements.indexOf(ref.current!) + const currentElementIndex = focusableElements.indexOf(ref.current!); const shortcuts = - currentElementIndex > 0 ? focusableElements[currentElementIndex - 1] : null + currentElementIndex > 0 ? focusableElements[currentElementIndex - 1] : null; - let cancel = null + let cancel = null; for (let i = currentElementIndex + 1; i < focusableElements.length; i++) { if (!ref.current!.contains(focusableElements[i])) { - cancel = focusableElements[i] - break + cancel = focusableElements[i]; + break; } } - return { shortcuts, cancel } + return { shortcuts, cancel }; } diff --git a/src/components/data-grid/hooks/use-data-grid-mouse-up-event.tsx b/src/components/data-grid/hooks/use-data-grid-mouse-up-event.tsx index f936b193..6cb3cb38 100644 --- a/src/components/data-grid/hooks/use-data-grid-mouse-up-event.tsx +++ b/src/components/data-grid/hooks/use-data-grid-mouse-up-event.tsx @@ -1,30 +1,33 @@ -import { useCallback } from "react" -import { FieldValues, Path, PathValue } from "react-hook-form" -import { DataGridBulkUpdateCommand, DataGridMatrix } from "../models" -import { DataGridCoordinates } from "../types" +import { useCallback } from "react"; + +import type { FieldValues, Path, PathValue } from "react-hook-form"; + +import type { DataGridMatrix } from "@components/data-grid/models"; +import { DataGridBulkUpdateCommand } from "@components/data-grid/models"; +import type { DataGridCoordinates } from "@components/data-grid/types"; type UseDataGridMouseUpEventOptions = { - matrix: DataGridMatrix - anchor: DataGridCoordinates | null - dragEnd: DataGridCoordinates | null - setDragEnd: (coords: DataGridCoordinates | null) => void - setRangeEnd: (coords: DataGridCoordinates | null) => void - setIsSelecting: (isSelecting: boolean) => void - setIsDragging: (isDragging: boolean) => void + matrix: DataGridMatrix; + anchor: DataGridCoordinates | null; + dragEnd: DataGridCoordinates | null; + setDragEnd: (coords: DataGridCoordinates | null) => void; + setRangeEnd: (coords: DataGridCoordinates | null) => void; + setIsSelecting: (isSelecting: boolean) => void; + setIsDragging: (isDragging: boolean) => void; getSelectionValues: ( - fields: string[] - ) => PathValue>[] + fields: string[], + ) => PathValue>[]; setSelectionValues: ( fields: string[], - values: PathValue>[] - ) => void - execute: (command: DataGridBulkUpdateCommand) => void - isDragging: boolean -} + values: PathValue>[], + ) => void; + execute: (command: DataGridBulkUpdateCommand) => void; + isDragging: boolean; +}; export const useDataGridMouseUpEvent = < TData, - TFieldValues extends FieldValues + TFieldValues extends FieldValues, >({ matrix, anchor, @@ -40,38 +43,38 @@ export const useDataGridMouseUpEvent = < }: UseDataGridMouseUpEventOptions) => { const handleDragEnd = useCallback(() => { if (!isDragging) { - return + return; } if (!anchor || !dragEnd) { - return + return; } - const dragSelection = matrix.getFieldsInSelection(anchor, dragEnd) - const anchorField = matrix.getCellField(anchor) + const dragSelection = matrix.getFieldsInSelection(anchor, dragEnd); + const anchorField = matrix.getCellField(anchor); if (!anchorField || !dragSelection.length) { - return + return; } - const anchorValue = getSelectionValues([anchorField]) - const fields = dragSelection.filter((field) => field !== anchorField) + const anchorValue = getSelectionValues([anchorField]); + const fields = dragSelection.filter((field) => field !== anchorField); - const prev = getSelectionValues(fields) - const next = Array.from({ length: prev.length }, () => anchorValue[0]) + const prev = getSelectionValues(fields); + const next = Array.from({ length: prev.length }, () => anchorValue[0]); const command = new DataGridBulkUpdateCommand({ fields, prev, next, setter: setSelectionValues, - }) + }); - execute(command) + execute(command); - setIsDragging(false) - setDragEnd(null) + setIsDragging(false); + setDragEnd(null); - setRangeEnd(dragEnd) + setRangeEnd(dragEnd); }, [ isDragging, anchor, @@ -83,14 +86,14 @@ export const useDataGridMouseUpEvent = < setIsDragging, setDragEnd, setRangeEnd, - ]) + ]); const handleMouseUpEvent = useCallback(() => { - handleDragEnd() - setIsSelecting(false) - }, [handleDragEnd, setIsSelecting]) + handleDragEnd(); + setIsSelecting(false); + }, [handleDragEnd, setIsSelecting]); return { handleMouseUpEvent, - } -} + }; +}; diff --git a/src/components/data-grid/hooks/use-data-grid-navigation.tsx b/src/components/data-grid/hooks/use-data-grid-navigation.tsx index 598ebe40..b6d717e9 100644 --- a/src/components/data-grid/hooks/use-data-grid-navigation.tsx +++ b/src/components/data-grid/hooks/use-data-grid-navigation.tsx @@ -1,22 +1,28 @@ -import { Column, Row, VisibilityState } from "@tanstack/react-table" -import { ScrollToOptions, Virtualizer } from "@tanstack/react-virtual" -import { Dispatch, SetStateAction, useCallback } from "react" -import { FieldValues } from "react-hook-form" -import { DataGridMatrix, DataGridQueryTool } from "../models" -import { DataGridCoordinates } from "../types" +import type { Dispatch, SetStateAction } from "react"; +import { useCallback } from "react"; + +import type { Column, Row, VisibilityState } from "@tanstack/react-table"; +import type { ScrollToOptions, Virtualizer } from "@tanstack/react-virtual"; +import type { FieldValues } from "react-hook-form"; + +import type { + DataGridMatrix, + DataGridQueryTool, +} from "@components/data-grid/models"; +import type { DataGridCoordinates } from "@components/data-grid/types"; type UseDataGridNavigationOptions = { - matrix: DataGridMatrix - anchor: DataGridCoordinates | null - visibleRows: Row[] - visibleColumns: Column[] - rowVirtualizer: Virtualizer - columnVirtualizer: Virtualizer - setColumnVisibility: Dispatch> - flatColumns: Column[] - queryTool: DataGridQueryTool | null - setSingleRange: (coords: DataGridCoordinates | null) => void -} + matrix: DataGridMatrix; + anchor: DataGridCoordinates | null; + visibleRows: Row[]; + visibleColumns: Column[]; + rowVirtualizer: Virtualizer; + columnVirtualizer: Virtualizer; + setColumnVisibility: Dispatch>; + flatColumns: Column[]; + queryTool: DataGridQueryTool | null; + setSingleRange: (coords: DataGridCoordinates | null) => void; +}; export const useDataGridNavigation = ({ matrix, @@ -31,70 +37,76 @@ export const useDataGridNavigation = ({ setSingleRange, }: UseDataGridNavigationOptions) => { const scrollToCoordinates = useCallback( - (coords: DataGridCoordinates, direction: "horizontal" | "vertical" | "both") => { + ( + coords: DataGridCoordinates, + direction: "horizontal" | "vertical" | "both", + ) => { if (!anchor) { - return + return; } - const { row, col } = coords - const { row: anchorRow, col: anchorCol } = anchor + const { row, col } = coords; + const { row: anchorRow, col: anchorCol } = anchor; - const rowDirection = row >= anchorRow ? "down" : "up" - const colDirection = col >= anchorCol ? "right" : "left" + const rowDirection = row >= anchorRow ? "down" : "up"; + const colDirection = col >= anchorCol ? "right" : "left"; - let toRow = rowDirection === "down" ? row + 1 : row - 1 + let toRow = rowDirection === "down" ? row + 1 : row - 1; if (visibleRows[toRow] === undefined) { - toRow = row + toRow = row; } - let toCol = colDirection === "right" ? col + 1 : col - 1 + let toCol = colDirection === "right" ? col + 1 : col - 1; if (visibleColumns[toCol] === undefined) { - toCol = col + toCol = col; } - const scrollOptions: ScrollToOptions = { align: "auto", behavior: "auto" } + const scrollOptions: ScrollToOptions = { + align: "auto", + behavior: "auto", + }; if (direction === "horizontal" || direction === "both") { - columnVirtualizer.scrollToIndex(toCol, scrollOptions) + columnVirtualizer.scrollToIndex(toCol, scrollOptions); } if (direction === "vertical" || direction === "both") { - rowVirtualizer.scrollToIndex(toRow, scrollOptions) + rowVirtualizer.scrollToIndex(toRow, scrollOptions); } }, - [anchor, columnVirtualizer, visibleRows, rowVirtualizer, visibleColumns] - ) + [anchor, columnVirtualizer, visibleRows, rowVirtualizer, visibleColumns], + ); const navigateToField = useCallback( (field: string) => { - const coords = matrix.getCoordinatesByField(field) + const coords = matrix.getCoordinatesByField(field); if (!coords) { - return + return; } - const column = flatColumns[coords.col] + const column = flatColumns[coords.col]; // Ensure that the column is visible setColumnVisibility((prev) => { return { ...prev, [column.id]: true, - } - }) + }; + }); requestAnimationFrame(() => { - scrollToCoordinates(coords, "both") - setSingleRange(coords) - }) + scrollToCoordinates(coords, "both"); + setSingleRange(coords); + }); requestAnimationFrame(() => { - const input = queryTool?.getInput(coords) + const input = queryTool?.getInput(coords); if (input) { - input.focus() + input.focus(); } - }) + }); }, [ matrix, @@ -103,11 +115,11 @@ export const useDataGridNavigation = ({ scrollToCoordinates, setSingleRange, queryTool, - ] - ) + ], + ); return { scrollToCoordinates, navigateToField, - } -} + }; +}; diff --git a/src/components/data-grid/hooks/use-data-grid-query-tool.tsx b/src/components/data-grid/hooks/use-data-grid-query-tool.tsx index 38470166..b4f40970 100644 --- a/src/components/data-grid/hooks/use-data-grid-query-tool.tsx +++ b/src/components/data-grid/hooks/use-data-grid-query-tool.tsx @@ -1,15 +1,16 @@ -import { RefObject, useEffect, useRef } from "react" +import type { RefObject } from "react"; +import { useEffect, useRef } from "react"; -import { DataGridQueryTool } from "../models" +import { DataGridQueryTool } from "@components/data-grid/models"; export const useDataGridQueryTool = (containerRef: RefObject) => { - const queryToolRef = useRef(null) + const queryToolRef = useRef(null); useEffect(() => { if (containerRef.current) { - queryToolRef.current = new DataGridQueryTool(containerRef.current) + queryToolRef.current = new DataGridQueryTool(containerRef.current); } - }, [containerRef]) + }, [containerRef]); - return queryToolRef.current -} + return queryToolRef.current; +}; From 76e08fc96bc8209021352dde991331a4db06325f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 17:46:15 +0200 Subject: [PATCH 038/195] eslint/prettier - fix components/data-grid/models --- .../models/data-grid-bulk-update-command.ts | 40 +-- .../data-grid/models/data-grid-matrix.ts | 251 +++++++++--------- .../data-grid/models/data-grid-query-tool.ts | 52 ++-- .../models/data-grid-update-command.ts | 32 +-- src/components/data-grid/models/index.ts | 9 +- 5 files changed, 194 insertions(+), 190 deletions(-) diff --git a/src/components/data-grid/models/data-grid-bulk-update-command.ts b/src/components/data-grid/models/data-grid-bulk-update-command.ts index 426b7ea4..c8a5a5a3 100644 --- a/src/components/data-grid/models/data-grid-bulk-update-command.ts +++ b/src/components/data-grid/models/data-grid-bulk-update-command.ts @@ -1,38 +1,40 @@ -import { Command } from "../../../hooks/use-command-history" +// @todo fix types +/* eslint-disable @typescript-eslint/no-explicit-any */ +import type { Command } from "@hooks/use-command-history.tsx"; export type DataGridBulkUpdateCommandArgs = { - fields: string[] - next: any[] - prev: any[] - setter: (fields: string[], values: any[], isHistory?: boolean) => void -} + fields: string[]; + next: any[]; + prev: any[]; + setter: (fields: string[], values: any[], isHistory?: boolean) => void; +}; export class DataGridBulkUpdateCommand implements Command { - private _fields: string[] + private readonly _fields: string[]; - private _prev: any[] - private _next: any[] + private readonly _prev: any[]; + private readonly _next: any[]; - private _setter: ( + private readonly _setter: ( fields: string[], values: any[], - isHistory?: boolean - ) => void + isHistory?: boolean, + ) => void; constructor({ fields, prev, next, setter }: DataGridBulkUpdateCommandArgs) { - this._fields = fields - this._prev = prev - this._next = next - this._setter = setter + this._fields = fields; + this._prev = prev; + this._next = next; + this._setter = setter; } execute(redo = false): void { - this._setter(this._fields, this._next, redo) + this._setter(this._fields, this._next, redo); } undo(): void { - this._setter(this._fields, this._prev, true) + this._setter(this._fields, this._prev, true); } redo(): void { - this.execute(true) + this.execute(true); } } diff --git a/src/components/data-grid/models/data-grid-matrix.ts b/src/components/data-grid/models/data-grid-matrix.ts index bfaf31bd..79f2da8c 100644 --- a/src/components/data-grid/models/data-grid-matrix.ts +++ b/src/components/data-grid/models/data-grid-matrix.ts @@ -1,175 +1,176 @@ -import { ColumnDef, Row } from "@tanstack/react-table" -import { FieldValues } from "react-hook-form" -import { +import type { ColumnDef, Row } from "@tanstack/react-table"; +import type { FieldValues } from "react-hook-form"; + +import type { DataGridColumnType, DataGridCoordinates, Grid, GridCell, InternalColumnMeta, -} from "../types" +} from "@components/data-grid/types"; export class DataGridMatrix { - private multiColumnSelection: boolean - private cells: Grid - public rowAccessors: (string | null)[] = [] - public columnAccessors: (string | null)[] = [] + private readonly multiColumnSelection: boolean; + private readonly cells: Grid; + public rowAccessors: (string | null)[] = []; + public columnAccessors: (string | null)[] = []; constructor( data: Row[], columns: ColumnDef[], - multiColumnSelection: boolean = false + multiColumnSelection: boolean = false, ) { - this.multiColumnSelection = multiColumnSelection - this.cells = this._populateCells(data, columns) + this.multiColumnSelection = multiColumnSelection; + this.cells = this._populateCells(data, columns); - this.rowAccessors = this._computeRowAccessors() - this.columnAccessors = this._computeColumnAccessors() + this.rowAccessors = this._computeRowAccessors(); + this.columnAccessors = this._computeColumnAccessors(); } private _computeRowAccessors(): (string | null)[] { - return this.cells.map((_, rowIndex) => this.getRowAccessor(rowIndex)) + return this.cells.map((_, rowIndex) => this.getRowAccessor(rowIndex)); } private _computeColumnAccessors(): (string | null)[] { if (this.cells.length === 0) { - return [] + return []; } - return this.cells[0].map((_, colIndex) => this.getColumnAccessor(colIndex)) + return this.cells[0].map((_, colIndex) => this.getColumnAccessor(colIndex)); } getFirstNavigableCell(): DataGridCoordinates | null { for (let row = 0; row < this.cells.length; row++) { for (let col = 0; col < this.cells[0].length; col++) { if (this.cells[row][col] !== null) { - return { row, col } + return { row, col }; } } } - return null + return null; } getFieldsInRow(row: number): string[] { - const keys: string[] = [] + const keys: string[] = []; if (row < 0 || row >= this.cells.length) { - return keys + return keys; } this.cells[row].forEach((cell) => { if (cell !== null) { - keys.push(cell.field) + keys.push(cell.field); } - }) + }); - return keys + return keys; } getFieldsInSelection( start: DataGridCoordinates | null, - end: DataGridCoordinates | null + end: DataGridCoordinates | null, ): string[] { - const keys: string[] = [] + const keys: string[] = []; if (!start || !end) { - return keys + return keys; } if (!this.multiColumnSelection && start.col !== end.col) { throw new Error( - "Selection must be in the same column when multiColumnSelection is disabled" - ) + "Selection must be in the same column when multiColumnSelection is disabled", + ); } - const startRow = Math.min(start.row, end.row) - const endRow = Math.max(start.row, end.row) + const startRow = Math.min(start.row, end.row); + const endRow = Math.max(start.row, end.row); const startCol = this.multiColumnSelection ? Math.min(start.col, end.col) - : start.col + : start.col; const endCol = this.multiColumnSelection ? Math.max(start.col, end.col) - : start.col + : start.col; for (let row = startRow; row <= endRow; row++) { for (let col = startCol; col <= endCol; col++) { if (this._isValidPosition(row, col) && this.cells[row][col] !== null) { - keys.push(this.cells[row][col]?.field as string) + keys.push(this.cells[row][col]?.field as string); } } } - return keys + return keys; } getCellField(cell: DataGridCoordinates): string | null { if (this._isValidPosition(cell.row, cell.col)) { - return this.cells[cell.row][cell.col]?.field || null + return this.cells[cell.row][cell.col]?.field || null; } - return null + return null; } getCellType(cell: DataGridCoordinates): DataGridColumnType | null { if (this._isValidPosition(cell.row, cell.col)) { - return this.cells[cell.row][cell.col]?.type || null + return this.cells[cell.row][cell.col]?.type || null; } - return null + return null; } getIsCellSelected( cell: DataGridCoordinates | null, start: DataGridCoordinates | null, - end: DataGridCoordinates | null + end: DataGridCoordinates | null, ): boolean { if (!cell || !start || !end) { - return false + return false; } if (!this.multiColumnSelection && start.col !== end.col) { throw new Error( - "Selection must be in the same column when multiColumnSelection is disabled" - ) + "Selection must be in the same column when multiColumnSelection is disabled", + ); } - const startRow = Math.min(start.row, end.row) - const endRow = Math.max(start.row, end.row) + const startRow = Math.min(start.row, end.row); + const endRow = Math.max(start.row, end.row); const startCol = this.multiColumnSelection ? Math.min(start.col, end.col) - : start.col + : start.col; const endCol = this.multiColumnSelection ? Math.max(start.col, end.col) - : start.col + : start.col; return ( cell.row >= startRow && cell.row <= endRow && cell.col >= startCol && cell.col <= endCol - ) + ); } toggleColumn(col: number, enabled: boolean) { if (col < 0 || col >= this.cells[0].length) { - return + return; } this.cells.forEach((row, index) => { - const cell = row[col] + const cell = row[col]; if (cell) { this.cells[index][col] = { ...cell, enabled, - } + }; } - }) + }); } toggleRow(row: number, enabled: boolean) { if (row < 0 || row >= this.cells.length) { - return + return; } this.cells[row].forEach((cell, index) => { @@ -177,176 +178,176 @@ export class DataGridMatrix { this.cells[row][index] = { ...cell, enabled, - } + }; } - }) + }); } getCoordinatesByField(field: string): DataGridCoordinates | null { if (this.rowAccessors.length === 1) { - const col = this.columnAccessors.indexOf(field) + const col = this.columnAccessors.indexOf(field); if (col === -1) { - return null + return null; } - return { row: 0, col } + return { row: 0, col }; } for (let row = 0; row < this.rowAccessors.length; row++) { - const rowAccessor = this.rowAccessors[row] + const rowAccessor = this.rowAccessors[row]; if (rowAccessor === null) { - continue + continue; } if (!field.startsWith(rowAccessor)) { - continue + continue; } for (let column = 0; column < this.columnAccessors.length; column++) { - const columnAccessor = this.columnAccessors[column] + const columnAccessor = this.columnAccessors[column]; if (columnAccessor === null) { - continue + continue; } - const fullFieldPath = `${rowAccessor}.${columnAccessor}` + const fullFieldPath = `${rowAccessor}.${columnAccessor}`; if (fullFieldPath === field) { - return { row, col: column } + return { row, col: column }; } } } - return null + return null; } getRowAccessor(row: number): string | null { if (row < 0 || row >= this.cells.length) { - return null + return null; } - const cells = this.cells[row] + const cells = this.cells[row]; const nonNullFields = cells .filter((cell): cell is GridCell => cell !== null) - .map((cell) => cell.field.split(".")) + .map((cell) => cell.field.split(".")); if (nonNullFields.length === 0) { - return null + return null; } - let commonParts = nonNullFields[0] + let commonParts = nonNullFields[0]; for (const segments of nonNullFields) { commonParts = commonParts.filter( - (part, index) => segments[index] === part - ) + (part, index) => segments[index] === part, + ); if (commonParts.length === 0) { - break + break; } } - const accessor = commonParts.join(".") + const accessor = commonParts.join("."); if (!accessor) { - return null + return null; } - return accessor + return accessor; } public getColumnAccessor(column: number): string | null { if (column < 0 || column >= this.cells[0].length) { - return null + return null; } // Extract the unique part of the field name for each row in the specified column const uniqueParts = this.cells .map((row, rowIndex) => { - const cell = row[column] + const cell = row[column]; if (!cell) { - return null + return null; } // Get the row accessor for the current row - const rowAccessor = this.getRowAccessor(rowIndex) + const rowAccessor = this.getRowAccessor(rowIndex); // Remove the row accessor part from the field name if (rowAccessor && cell.field.startsWith(rowAccessor + ".")) { - return cell.field.slice(rowAccessor.length + 1) // Extract the part after the row accessor + return cell.field.slice(rowAccessor.length + 1); // Extract the part after the row accessor } - return null + return null; }) - .filter((part) => part !== null) // Filter out null values + .filter((part) => part !== null); // Filter out null values if (uniqueParts.length === 0) { - return null + return null; } // Ensure all unique parts are the same (this should be true for well-formed data) - const firstPart = uniqueParts[0] - const isConsistent = uniqueParts.every((part) => part === firstPart) + const firstPart = uniqueParts[0]; + const isConsistent = uniqueParts.every((part) => part === firstPart); - return isConsistent ? firstPart : null + return isConsistent ? firstPart : null; } getValidMovement( row: number, col: number, direction: string, - metaKey: boolean = false + metaKey: boolean = false, ): DataGridCoordinates { - const [dRow, dCol] = this._getDirectionDeltas(direction) + const [dRow, dCol] = this._getDirectionDeltas(direction); if (metaKey) { - return this._getLastValidCellInDirection(row, col, dRow, dCol) + return this._getLastValidCellInDirection(row, col, dRow, dCol); } else { - let newRow = row + dRow - let newCol = col + dCol + let newRow = row + dRow; + let newCol = col + dCol; while (this._isValidPosition(newRow, newCol)) { if ( this.cells[newRow][newCol] !== null && this.cells[newRow][newCol]?.enabled !== false ) { - return { row: newRow, col: newCol } + return { row: newRow, col: newCol }; } - newRow += dRow - newCol += dCol + newRow += dRow; + newCol += dCol; } - return { row, col } + return { row, col }; } } private _isValidPosition( row: number, col: number, - cells?: Grid + cells?: Grid, ): boolean { if (!cells) { - cells = this.cells + cells = this.cells; } - return row >= 0 && row < cells.length && col >= 0 && col < cells[0].length + return row >= 0 && row < cells.length && col >= 0 && col < cells[0].length; } private _getDirectionDeltas(direction: string): [number, number] { switch (direction) { case "ArrowUp": - return [-1, 0] + return [-1, 0]; case "ArrowDown": - return [1, 0] + return [1, 0]; case "ArrowLeft": - return [0, -1] + return [0, -1]; case "ArrowRight": - return [0, 1] + return [0, 1]; default: - return [0, 0] + return [0, 0]; } } @@ -354,37 +355,37 @@ export class DataGridMatrix { row: number, col: number, dRow: number, - dCol: number + dCol: number, ): DataGridCoordinates { - let newRow = row - let newCol = col - let lastValidRow = row - let lastValidCol = col + let newRow = row; + let newCol = col; + let lastValidRow = row; + let lastValidCol = col; while (this._isValidPosition(newRow + dRow, newCol + dCol)) { - newRow += dRow - newCol += dCol + newRow += dRow; + newCol += dCol; if (this.cells[newRow][newCol] !== null) { - lastValidRow = newRow - lastValidCol = newCol + lastValidRow = newRow; + lastValidCol = newCol; } } return { row: lastValidRow, col: lastValidCol, - } + }; } private _populateCells(rows: Row[], columns: ColumnDef[]) { const cells = Array.from({ length: rows.length }, () => - Array(columns.length).fill(null) - ) as Grid + Array(columns.length).fill(null), + ) as Grid; rows.forEach((row, rowIndex) => { columns.forEach((column, colIndex) => { if (!this._isValidPosition(rowIndex, colIndex, cells)) { - return + return; } const { @@ -392,7 +393,7 @@ export class DataGridMatrix { field, type, ...rest - } = column.meta as InternalColumnMeta + } = column.meta as InternalColumnMeta; const context = { row, @@ -400,22 +401,22 @@ export class DataGridMatrix { ...column, meta: rest, }, - } + }; - const fieldValue = field ? field(context) : null + const fieldValue = field ? field(context) : null; if (!fieldValue || !type) { - return + return; } cells[rowIndex][colIndex] = { field: fieldValue, type, enabled: true, - } - }) - }) + }; + }); + }); - return cells + return cells; } } diff --git a/src/components/data-grid/models/data-grid-query-tool.ts b/src/components/data-grid/models/data-grid-query-tool.ts index 61d50742..f2a7792e 100644 --- a/src/components/data-grid/models/data-grid-query-tool.ts +++ b/src/components/data-grid/models/data-grid-query-tool.ts @@ -1,74 +1,74 @@ -import { DataGridCoordinates } from "../types" -import { generateCellId } from "../utils" +import type { DataGridCoordinates } from "@components/data-grid/types"; +import { generateCellId } from "@components/data-grid/utils"; export class DataGridQueryTool { - private container: HTMLElement | null + private container: HTMLElement | null; constructor(container: HTMLElement | null) { - this.container = container + this.container = container; } getInput(cell: DataGridCoordinates) { - const id = this._getCellId(cell) + const id = this._getCellId(cell); - const input = this.container?.querySelector(`[data-cell-id="${id}"]`) + const input = this.container?.querySelector(`[data-cell-id="${id}"]`); if (!input) { - return null + return null; } - return input as HTMLElement + return input as HTMLElement; } getInputByField(field: string) { - const input = this.container?.querySelector(`[data-field="${field}"]`) + const input = this.container?.querySelector(`[data-field="${field}"]`); if (!input) { - return null + return null; } - return input as HTMLElement + return input as HTMLElement; } getCoordinatesByField(field: string): DataGridCoordinates | null { const cell = this.container?.querySelector( - `[data-field="${field}"][data-cell-id]` - ) + `[data-field="${field}"][data-cell-id]`, + ); if (!cell) { - return null + return null; } - const cellId = cell.getAttribute("data-cell-id") + const cellId = cell.getAttribute("data-cell-id"); if (!cellId) { - return null + return null; } - const [row, col] = cellId.split(":").map((n) => parseInt(n, 10)) + const [row, col] = cellId.split(":").map((n) => parseInt(n, 10)); if (isNaN(row) || isNaN(col)) { - return null + return null; } - return { row, col } + return { row, col }; } getContainer(cell: DataGridCoordinates) { - const id = this._getCellId(cell) + const id = this._getCellId(cell); const container = this.container?.querySelector( - `[data-container-id="${id}"]` - ) + `[data-container-id="${id}"]`, + ); if (!container) { - return null + return null; } - return container as HTMLElement + return container as HTMLElement; } private _getCellId(cell: DataGridCoordinates): string { - return generateCellId(cell) + return generateCellId(cell); } -} \ No newline at end of file +} diff --git a/src/components/data-grid/models/data-grid-update-command.ts b/src/components/data-grid/models/data-grid-update-command.ts index 30b0f4be..b3d55a7c 100644 --- a/src/components/data-grid/models/data-grid-update-command.ts +++ b/src/components/data-grid/models/data-grid-update-command.ts @@ -1,33 +1,35 @@ -import { Command } from "../../../hooks/use-command-history" +// @todo fix types +/* eslint-disable @typescript-eslint/no-explicit-any */ +import type { Command } from "@hooks/use-command-history.tsx"; export type DataGridUpdateCommandArgs = { - prev: any - next: any - setter: (value: any) => void -} + prev: any; + next: any; + setter: (value: any) => void; +}; export class DataGridUpdateCommand implements Command { - private _prev: any - private _next: any + private _prev: any; + private _next: any; - private _setter: (value: any) => void + private _setter: (value: any) => void; constructor({ prev, next, setter }: DataGridUpdateCommandArgs) { - this._prev = prev - this._next = next + this._prev = prev; + this._next = next; - this._setter = setter + this._setter = setter; } execute(): void { - this._setter(this._next) + this._setter(this._next); } undo(): void { - this._setter(this._prev) + this._setter(this._prev); } redo(): void { - this.execute() + this.execute(); } -} \ No newline at end of file +} diff --git a/src/components/data-grid/models/index.ts b/src/components/data-grid/models/index.ts index 976bfad4..a7078b79 100644 --- a/src/components/data-grid/models/index.ts +++ b/src/components/data-grid/models/index.ts @@ -1,5 +1,4 @@ -export * from "./data-grid-bulk-update-command" -export * from "./data-grid-matrix" -export * from "./data-grid-query-tool" -export * from "./data-grid-update-command" - +export * from "./data-grid-bulk-update-command"; +export * from "./data-grid-matrix"; +export * from "./data-grid-query-tool"; +export * from "./data-grid-update-command"; From 775a1b88da16ec3cc1d0e96cf6134abcf8964e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 17:49:13 +0200 Subject: [PATCH 039/195] eslint/prettier - fix components/data-grid --- src/components/data-grid/data-grid.tsx | 17 ++- src/components/data-grid/index.ts | 4 +- src/components/data-grid/types.ts | 186 +++++++++++++------------ src/components/data-grid/utils.ts | 18 +-- 4 files changed, 115 insertions(+), 110 deletions(-) diff --git a/src/components/data-grid/data-grid.tsx b/src/components/data-grid/data-grid.tsx index 74a08383..cb78637c 100644 --- a/src/components/data-grid/data-grid.tsx +++ b/src/components/data-grid/data-grid.tsx @@ -1,4 +1,4 @@ -import { FieldValues } from "react-hook-form" +import type { FieldValues } from "react-hook-form"; import { DataGridBooleanCell, @@ -6,21 +6,21 @@ import { DataGridNumberCell, DataGridReadOnlyCell, DataGridRoot, + type DataGridRootProps, DataGridSkeleton, DataGridTextCell, - type DataGridRootProps, -} from "./components" +} from "@components/data-grid/components"; interface DataGridProps extends DataGridRootProps { - isLoading?: boolean + isLoading?: boolean; } const _DataGrid = ({ isLoading, ...props -}: DataGridProps) => { - return isLoading ? ( +}: DataGridProps) => + isLoading ? ( ({ /> ) : ( - ) -} + ); export const DataGrid = Object.assign(_DataGrid, { BooleanCell: DataGridBooleanCell, @@ -38,4 +37,4 @@ export const DataGrid = Object.assign(_DataGrid, { NumberCell: DataGridNumberCell, CurrencyCell: DataGridCurrencyCell, ReadonlyCell: DataGridReadOnlyCell, -}) +}); diff --git a/src/components/data-grid/index.ts b/src/components/data-grid/index.ts index fd72f65b..07795db0 100644 --- a/src/components/data-grid/index.ts +++ b/src/components/data-grid/index.ts @@ -1,2 +1,2 @@ -export * from "./data-grid" -export * from "./helpers" +export * from "./data-grid"; +export * from "./helpers"; diff --git a/src/components/data-grid/types.ts b/src/components/data-grid/types.ts index 8ddc4a41..c4613d65 100644 --- a/src/components/data-grid/types.ts +++ b/src/components/data-grid/types.ts @@ -1,32 +1,36 @@ -import { +// @todo fix types +/* eslint-disable @typescript-eslint/no-explicit-any */ +import type { PropsWithChildren, ReactNode, RefObject } from "react"; +import type React from "react"; + +import type { CellContext, ColumnDef, ColumnMeta, Row, VisibilityState, -} from "@tanstack/react-table" -import React, { PropsWithChildren, ReactNode, RefObject } from "react" -import { +} from "@tanstack/react-table"; +import type { FieldErrors, FieldPath, FieldValues, Path, PathValue, -} from "react-hook-form" +} from "react-hook-form"; export type DataGridColumnType = | "text" | "number" | "boolean" - | "togglable-number" + | "togglable-number"; export type DataGridCoordinates = { - row: number - col: number -} + row: number; + col: number; +}; export interface DataGridCellProps { - context: CellContext + context: CellContext; } export interface DataGridCellContext @@ -34,139 +38,139 @@ export interface DataGridCellContext /** * The index of the column in the grid. */ - columnIndex: number + columnIndex: number; /** * The index of the row in the grid. */ - rowIndex: number + rowIndex: number; } export type DataGridRowError = { - message: string - to: () => void -} + message: string; + to: () => void; +}; export type DataGridErrorRenderProps = { - errors: FieldErrors - rowErrors: DataGridRowError[] -} + errors: FieldErrors; + rowErrors: DataGridRowError[]; +}; export interface DataGridCellRenderProps { - container: DataGridCellContainerProps - input: InputProps + container: DataGridCellContainerProps; + input: InputProps; } type InputAttributes = { - "data-row": number - "data-col": number - "data-cell-id": string - "data-field": string -} + "data-row": number; + "data-col": number; + "data-cell-id": string; + "data-field": string; +}; export interface InputProps { - ref: RefObject - onBlur: () => void - onFocus: () => void - onChange: (next: any, prev: any) => void - "data-row": number - "data-col": number - "data-cell-id": string - "data-field": string + ref: RefObject; + onBlur: () => void; + onFocus: () => void; + onChange: (next: any, prev: any) => void; + "data-row": number; + "data-col": number; + "data-cell-id": string; + "data-field": string; } type InnerAttributes = { - "data-container-id": string -} + "data-container-id": string; +}; interface InnerProps { - ref: RefObject - onMouseOver: ((e: React.MouseEvent) => void) | undefined - onMouseDown: ((e: React.MouseEvent) => void) | undefined - onKeyDown: (e: React.KeyboardEvent) => void - onFocus: (e: React.FocusEvent) => void - "data-container-id": string + ref: RefObject; + onMouseOver: ((e: React.MouseEvent) => void) | undefined; + onMouseDown: ((e: React.MouseEvent) => void) | undefined; + onKeyDown: (e: React.KeyboardEvent) => void; + onFocus: (e: React.FocusEvent) => void; + "data-container-id": string; } interface OverlayProps { - onMouseDown: (e: React.MouseEvent) => void + onMouseDown: (e: React.MouseEvent) => void; } -export interface DataGridCellContainerProps extends PropsWithChildren<{}> { - field: string - innerProps: InnerProps - overlayProps: OverlayProps - isAnchor: boolean - isSelected: boolean - isDragSelected: boolean - placeholder?: ReactNode - showOverlay: boolean - outerComponent?: ReactNode +export interface DataGridCellContainerProps extends PropsWithChildren { + field: string; + innerProps: InnerProps; + overlayProps: OverlayProps; + isAnchor: boolean; + isSelected: boolean; + isDragSelected: boolean; + placeholder?: ReactNode; + showOverlay: boolean; + outerComponent?: ReactNode; } export type DataGridCellSnapshot< TFieldValues extends FieldValues = FieldValues, > = { - field: string - value: PathValue> -} + field: string; + value: PathValue>; +}; export type FieldContext = { - row: Row - column: ColumnDef -} + row: Row; + column: ColumnDef; +}; export type FieldFunction = ( - context: FieldContext -) => FieldPath | null + context: FieldContext, +) => FieldPath | null; export type InternalColumnMeta = { - name: string - field?: FieldFunction + name: string; + field?: FieldFunction; } & ( | { - field: FieldFunction - type: DataGridColumnType + field: FieldFunction; + type: DataGridColumnType; } | { field?: null | undefined; type?: never } ) & - ColumnMeta + ColumnMeta; export type GridCell = { - field: FieldPath - type: DataGridColumnType - enabled: boolean -} + field: FieldPath; + type: DataGridColumnType; + enabled: boolean; +}; export type Grid = - (GridCell | null)[][] + (GridCell | null)[][]; export type CellMetadata = { - id: string - field: string - type: DataGridColumnType - inputAttributes: InputAttributes - innerAttributes: InnerAttributes -} + id: string; + field: string; + type: DataGridColumnType; + inputAttributes: InputAttributes; + innerAttributes: InnerAttributes; +}; export type CellErrorMetadata = { - field: string | null - accessor: string | null -} + field: string | null; + accessor: string | null; +}; export type VisibilitySnapshot = { - rows: VisibilityState - columns: VisibilityState -} + rows: VisibilityState; + columns: VisibilityState; +}; export type GridColumnOption = { - id: string - name: string - checked: boolean - disabled: boolean -} + id: string; + name: string; + checked: boolean; + disabled: boolean; +}; export type DataGridToggleableNumber = { - quantity: number | string - checked: boolean - disabledToggle: boolean -} + quantity: number | string; + checked: boolean; + disabledToggle: boolean; +}; diff --git a/src/components/data-grid/utils.ts b/src/components/data-grid/utils.ts index a10c6338..181f6f20 100644 --- a/src/components/data-grid/utils.ts +++ b/src/components/data-grid/utils.ts @@ -1,7 +1,7 @@ -import { DataGridCoordinates } from "./types" +import type { DataGridCoordinates } from "@components/data-grid/types"; export function generateCellId(coords: DataGridCoordinates) { - return `${coords.row}:${coords.col}` + return `${coords.row}:${coords.col}`; } /** @@ -12,17 +12,19 @@ export function generateCellId(coords: DataGridCoordinates) { */ export function isCellMatch( cell: DataGridCoordinates, - coords?: DataGridCoordinates | null + coords?: DataGridCoordinates | null, ) { if (!coords) { - return false + return false; } - return cell.row === coords.row && cell.col === coords.col + return cell.row === coords.row && cell.col === coords.col; } -const SPECIAL_FOCUS_KEYS = [".", ","] +const SPECIAL_FOCUS_KEYS = [".", ","]; export function isSpecialFocusKey(event: KeyboardEvent) { - return SPECIAL_FOCUS_KEYS.includes(event.key) && event.ctrlKey && event.altKey -} \ No newline at end of file + return ( + SPECIAL_FOCUS_KEYS.includes(event.key) && event.ctrlKey && event.altKey + ); +} From 43a0bdf52658e2d357a1aab4a7b8834bc2818b4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 18:59:54 +0200 Subject: [PATCH 040/195] eslint/prettier - fix components/data-table/components/data-table/helpers --- .../data-table/helpers/general/index.ts | 2 + .../general/use-data-table-date-columns.tsx | 112 +++++++++--------- .../general/use-data-table-date-filters.tsx | 61 +++++----- .../helpers/sales-channels/index.ts | 8 +- .../use-sales-channel-table-columns.tsx | 33 +++--- .../use-sales-channel-table-empty-state.tsx | 18 +-- .../use-sales-channel-table-filters.tsx | 25 ++-- .../use-sales-channel-table-query.tsx | 23 ++-- 8 files changed, 151 insertions(+), 131 deletions(-) create mode 100644 src/components/data-table/helpers/general/index.ts diff --git a/src/components/data-table/helpers/general/index.ts b/src/components/data-table/helpers/general/index.ts new file mode 100644 index 00000000..052830d5 --- /dev/null +++ b/src/components/data-table/helpers/general/index.ts @@ -0,0 +1,2 @@ +export * from "./use-data-table-date-columns.tsx"; +export * from "./use-data-table-date-filters.tsx"; diff --git a/src/components/data-table/helpers/general/use-data-table-date-columns.tsx b/src/components/data-table/helpers/general/use-data-table-date-columns.tsx index 5513f275..43e7141e 100644 --- a/src/components/data-table/helpers/general/use-data-table-date-columns.tsx +++ b/src/components/data-table/helpers/general/use-data-table-date-columns.tsx @@ -1,61 +1,63 @@ -import { - createDataTableColumnHelper, - DataTableColumnDef, - Tooltip, -} from "@medusajs/ui" -import { useMemo } from "react" -import { useTranslation } from "react-i18next" -import { useDate } from "../../../../hooks/use-date" +import { useMemo } from "react"; + +import type { DataTableColumnDef } from "@medusajs/ui"; +import { Tooltip, createDataTableColumnHelper } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; + +import { useDate } from "@hooks/use-date.tsx"; type EntityWithDates = { - created_at: string - updated_at: string -} + created_at: string; + updated_at: string; +}; -const columnHelper = createDataTableColumnHelper() +const columnHelper = createDataTableColumnHelper(); export const useDataTableDateColumns = () => { - const { t } = useTranslation() - const { getFullDate } = useDate() + const { t } = useTranslation(); + const { getFullDate } = useDate(); - return useMemo(() => { - return [ - columnHelper.accessor("created_at", { - header: t("fields.createdAt"), - cell: ({ row }) => { - return ( - - {getFullDate({ date: row.original.created_at })} - - ) - }, - enableSorting: true, - sortAscLabel: t("filters.sorting.dateAsc"), - sortDescLabel: t("filters.sorting.dateDesc"), - }), - columnHelper.accessor("updated_at", { - header: t("fields.updatedAt"), - cell: ({ row }) => { - return ( - - {getFullDate({ date: row.original.updated_at })} - - ) - }, - enableSorting: true, - sortAscLabel: t("filters.sorting.dateAsc"), - sortDescLabel: t("filters.sorting.dateDesc"), - }), - ] as DataTableColumnDef[] - }, [t, getFullDate]) -} + return useMemo( + () => + [ + columnHelper.accessor("created_at", { + header: t("fields.createdAt"), + cell: ({ row }) => { + return ( + + {getFullDate({ date: row.original.created_at })} + + ); + }, + enableSorting: true, + sortAscLabel: t("filters.sorting.dateAsc"), + sortDescLabel: t("filters.sorting.dateDesc"), + }), + columnHelper.accessor("updated_at", { + header: t("fields.updatedAt"), + cell: ({ row }) => { + return ( + + {getFullDate({ date: row.original.updated_at })} + + ); + }, + enableSorting: true, + sortAscLabel: t("filters.sorting.dateAsc"), + sortDescLabel: t("filters.sorting.dateDesc"), + }), + ] as DataTableColumnDef[], + [t, getFullDate], + ); +}; diff --git a/src/components/data-table/helpers/general/use-data-table-date-filters.tsx b/src/components/data-table/helpers/general/use-data-table-date-filters.tsx index 83b1eacb..8791f5ba 100644 --- a/src/components/data-table/helpers/general/use-data-table-date-filters.tsx +++ b/src/components/data-table/helpers/general/use-data-table-date-filters.tsx @@ -1,23 +1,28 @@ -import { createDataTableFilterHelper } from "@medusajs/ui" -import { subDays, subMonths } from "date-fns" -import { useMemo } from "react" -import { useTranslation } from "react-i18next" +import { useMemo } from "react"; -import { useDate } from "../../../../hooks/use-date" +import { createDataTableFilterHelper } from "@medusajs/ui"; -const filterHelper = createDataTableFilterHelper() +import { subDays, subMonths } from "date-fns"; +import { useTranslation } from "react-i18next"; + +import { useDate } from "@hooks/use-date.tsx"; + +// @todo fix any type +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const filterHelper = createDataTableFilterHelper(); const useDateFilterOptions = () => { - const { t } = useTranslation() + const { t } = useTranslation(); const today = useMemo(() => { - const date = new Date() - date.setHours(0, 0, 0, 0) - return date - }, []) + const date = new Date(); + date.setHours(0, 0, 0, 0); - return useMemo(() => { - return [ + return date; + }, []); + + return useMemo( + () => [ { label: t("filters.date.today"), value: { @@ -48,20 +53,21 @@ const useDateFilterOptions = () => { $gte: subMonths(today, 12).toISOString(), // 12 months ago }, }, - ] - }, [today, t]) -} + ], + [today, t], + ); +}; export const useDataTableDateFilters = (disableRangeOption?: boolean) => { - const { t } = useTranslation() - const { getFullDate } = useDate() - const dateFilterOptions = useDateFilterOptions() + const { t } = useTranslation(); + const { getFullDate } = useDate(); + const dateFilterOptions = useDateFilterOptions(); const rangeOptions = useMemo(() => { if (disableRangeOption) { return { disableRangeOption: true, - } + }; } return { @@ -69,11 +75,11 @@ export const useDataTableDateFilters = (disableRangeOption?: boolean) => { rangeOptionEndLabel: t("filters.date.ending"), rangeOptionLabel: t("filters.date.custom"), options: dateFilterOptions, - } - }, [disableRangeOption, t, dateFilterOptions]) + }; + }, [disableRangeOption, t, dateFilterOptions]); - return useMemo(() => { - return [ + return useMemo( + () => [ filterHelper.accessor("created_at", { type: "date", label: t("fields.createdAt"), @@ -90,6 +96,7 @@ export const useDataTableDateFilters = (disableRangeOption?: boolean) => { options: dateFilterOptions, ...rangeOptions, }), - ] - }, [t, dateFilterOptions, getFullDate, rangeOptions]) -} + ], + [t, dateFilterOptions, getFullDate, rangeOptions], + ); +}; diff --git a/src/components/data-table/helpers/sales-channels/index.ts b/src/components/data-table/helpers/sales-channels/index.ts index 197fc601..e28cf964 100644 --- a/src/components/data-table/helpers/sales-channels/index.ts +++ b/src/components/data-table/helpers/sales-channels/index.ts @@ -1,4 +1,4 @@ -export * from "./use-sales-channel-table-columns" -export * from "./use-sales-channel-table-empty-state" -export * from "./use-sales-channel-table-filters" -export * from "./use-sales-channel-table-query" +export * from "./use-sales-channel-table-columns"; +export * from "./use-sales-channel-table-empty-state"; +export * from "./use-sales-channel-table-filters"; +export * from "./use-sales-channel-table-query"; diff --git a/src/components/data-table/helpers/sales-channels/use-sales-channel-table-columns.tsx b/src/components/data-table/helpers/sales-channels/use-sales-channel-table-columns.tsx index 255ee68d..79b44239 100644 --- a/src/components/data-table/helpers/sales-channels/use-sales-channel-table-columns.tsx +++ b/src/components/data-table/helpers/sales-channels/use-sales-channel-table-columns.tsx @@ -1,16 +1,18 @@ -import { HttpTypes } from "@medusajs/types" -import { useMemo } from "react" -import { useTranslation } from "react-i18next" +import { useMemo } from "react"; -import { createDataTableColumnHelper, Tooltip } from "@medusajs/ui" -import { DataTableStatusCell } from "../../components/data-table-status-cell/data-table-status-cell" -import { useDataTableDateColumns } from "../general/use-data-table-date-columns" +import type { HttpTypes } from "@medusajs/types"; +import { Tooltip, createDataTableColumnHelper } from "@medusajs/ui"; -const columnHelper = createDataTableColumnHelper() +import { useTranslation } from "react-i18next"; + +import { DataTableStatusCell } from "@components/data-table/components"; +import { useDataTableDateColumns } from "@components/data-table/helpers/general/use-data-table-date-columns.tsx"; + +const columnHelper = createDataTableColumnHelper(); export const useSalesChannelTableColumns = () => { - const { t } = useTranslation() - const dateColumns = useDataTableDateColumns() + const { t } = useTranslation(); + const dateColumns = useDataTableDateColumns(); return useMemo( () => [ @@ -30,7 +32,7 @@ export const useSalesChannelTableColumns = () => { {getValue()} - ) + ); }, enableSorting: true, sortLabel: t("fields.description"), @@ -46,16 +48,17 @@ export const useSalesChannelTableColumns = () => { sortAscLabel: t("filters.sorting.alphabeticallyAsc"), sortDescLabel: t("filters.sorting.alphabeticallyDesc"), cell: ({ getValue }) => { - const value = getValue() + const value = getValue(); + return ( {value ? t("general.disabled") : t("general.enabled")} - ) + ); }, }), ...dateColumns, ], - [t, dateColumns] - ) -} + [t, dateColumns], + ); +}; diff --git a/src/components/data-table/helpers/sales-channels/use-sales-channel-table-empty-state.tsx b/src/components/data-table/helpers/sales-channels/use-sales-channel-table-empty-state.tsx index f92daa9e..e11a2c73 100644 --- a/src/components/data-table/helpers/sales-channels/use-sales-channel-table-empty-state.tsx +++ b/src/components/data-table/helpers/sales-channels/use-sales-channel-table-empty-state.tsx @@ -1,9 +1,11 @@ -import { DataTableEmptyStateProps } from "@medusajs/ui" -import { useMemo } from "react" -import { useTranslation } from "react-i18next" +import { useMemo } from "react"; + +import type { DataTableEmptyStateProps } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; export const useSalesChannelTableEmptyState = (): DataTableEmptyStateProps => { - const { t } = useTranslation() + const { t } = useTranslation(); return useMemo(() => { const content: DataTableEmptyStateProps = { @@ -15,8 +17,8 @@ export const useSalesChannelTableEmptyState = (): DataTableEmptyStateProps => { heading: t("salesChannels.list.filtered.heading"), description: t("salesChannels.list.filtered.description"), }, - } + }; - return content - }, [t]) -} + return content; + }, [t]); +}; diff --git a/src/components/data-table/helpers/sales-channels/use-sales-channel-table-filters.tsx b/src/components/data-table/helpers/sales-channels/use-sales-channel-table-filters.tsx index ff8ad147..17f24ce1 100644 --- a/src/components/data-table/helpers/sales-channels/use-sales-channel-table-filters.tsx +++ b/src/components/data-table/helpers/sales-channels/use-sales-channel-table-filters.tsx @@ -1,14 +1,17 @@ -import { HttpTypes } from "@medusajs/types" -import { createDataTableFilterHelper } from "@medusajs/ui" -import { useMemo } from "react" -import { useTranslation } from "react-i18next" -import { useDataTableDateFilters } from "../general/use-data-table-date-filters" +import { useMemo } from "react"; -const filterHelper = createDataTableFilterHelper() +import type { HttpTypes } from "@medusajs/types"; +import { createDataTableFilterHelper } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; + +import { useDataTableDateFilters } from "@components/data-table/helpers/general/use-data-table-date-filters"; + +const filterHelper = createDataTableFilterHelper(); export const useSalesChannelTableFilters = () => { - const { t } = useTranslation() - const dateFilters = useDataTableDateFilters() + const { t } = useTranslation(); + const dateFilters = useDataTableDateFilters(); return useMemo( () => [ @@ -28,6 +31,6 @@ export const useSalesChannelTableFilters = () => { }), ...dateFilters, ], - [dateFilters, t] - ) -} + [dateFilters, t], + ); +}; diff --git a/src/components/data-table/helpers/sales-channels/use-sales-channel-table-query.tsx b/src/components/data-table/helpers/sales-channels/use-sales-channel-table-query.tsx index 2252691d..c64746ab 100644 --- a/src/components/data-table/helpers/sales-channels/use-sales-channel-table-query.tsx +++ b/src/components/data-table/helpers/sales-channels/use-sales-channel-table-query.tsx @@ -1,10 +1,11 @@ -import { HttpTypes } from "@medusajs/types" -import { useQueryParams } from "../../../../hooks/use-query-params" +import type { HttpTypes } from "@medusajs/types"; + +import { useQueryParams } from "@hooks/use-query-params.tsx"; type UseSalesChannelTableQueryProps = { - prefix?: string - pageSize?: number -} + prefix?: string; + pageSize?: number; +}; export const useSalesChannelTableQuery = ({ prefix, @@ -12,10 +13,10 @@ export const useSalesChannelTableQuery = ({ }: UseSalesChannelTableQueryProps) => { const queryObject = useQueryParams( ["offset", "q", "order", "created_at", "updated_at", "is_disabled"], - prefix - ) + prefix, + ); - const { offset, created_at, updated_at, is_disabled, ...rest } = queryObject + const { offset, created_at, updated_at, is_disabled, ...rest } = queryObject; const searchParams: HttpTypes.AdminSalesChannelListParams = { limit: pageSize, @@ -24,7 +25,7 @@ export const useSalesChannelTableQuery = ({ updated_at: updated_at ? JSON.parse(updated_at) : undefined, is_disabled: is_disabled ? JSON.parse(is_disabled) : undefined, ...rest, - } + }; - return searchParams -} + return searchParams; +}; From 2d0911644a0bef0fd1c160b2c11fe251e344fa0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 19:01:16 +0200 Subject: [PATCH 041/195] eslint/prettier - fix components/data-table/components/data-table/components --- .../components/data-table-status-cell.tsx | 34 ++++++++++++++++++ .../data-table-status-cell.tsx | 35 ------------------- src/components/data-table/components/index.ts | 1 + 3 files changed, 35 insertions(+), 35 deletions(-) create mode 100644 src/components/data-table/components/data-table-status-cell.tsx delete mode 100644 src/components/data-table/components/data-table-status-cell/data-table-status-cell.tsx create mode 100644 src/components/data-table/components/index.ts diff --git a/src/components/data-table/components/data-table-status-cell.tsx b/src/components/data-table/components/data-table-status-cell.tsx new file mode 100644 index 00000000..449353ba --- /dev/null +++ b/src/components/data-table/components/data-table-status-cell.tsx @@ -0,0 +1,34 @@ +import type { PropsWithChildren } from "react"; + +import { clx } from "@medusajs/ui"; + +type DataTableStatusCellProps = PropsWithChildren<{ + color?: "green" | "red" | "blue" | "orange" | "grey" | "purple"; +}>; + +export const DataTableStatusCell = ({ + color, + children, +}: DataTableStatusCellProps) => ( +
    +
    +
    +
    + {children} +
    +); diff --git a/src/components/data-table/components/data-table-status-cell/data-table-status-cell.tsx b/src/components/data-table/components/data-table-status-cell/data-table-status-cell.tsx deleted file mode 100644 index 2bf7a2b8..00000000 --- a/src/components/data-table/components/data-table-status-cell/data-table-status-cell.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { clx } from "@medusajs/ui" -import { PropsWithChildren } from "react" - -type DataTableStatusCellProps = PropsWithChildren<{ - color?: "green" | "red" | "blue" | "orange" | "grey" | "purple" -}> - -export const DataTableStatusCell = ({ - color, - children, -}: DataTableStatusCellProps) => { - return ( -
    -
    -
    -
    - {children} -
    - ) -} diff --git a/src/components/data-table/components/index.ts b/src/components/data-table/components/index.ts new file mode 100644 index 00000000..8384768e --- /dev/null +++ b/src/components/data-table/components/index.ts @@ -0,0 +1 @@ +export { DataTableStatusCell } from "./data-table-status-cell"; From a423a80a7eff115a2309b782c542598fe25366b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 22:19:52 +0200 Subject: [PATCH 042/195] eslint/prettier - fix components/data-table/components/data-table --- src/components/data-table/data-table.tsx | 346 ++++++++++++----------- src/components/data-table/index.ts | 2 +- 2 files changed, 180 insertions(+), 168 deletions(-) diff --git a/src/components/data-table/data-table.tsx b/src/components/data-table/data-table.tsx index 770baef3..c5b17463 100644 --- a/src/components/data-table/data-table.tsx +++ b/src/components/data-table/data-table.tsx @@ -1,104 +1,111 @@ -import { - DataTable as UiDataTable, - useDataTable, +import type { ReactNode } from "react"; +import React, { useCallback, useMemo } from "react"; + +import type { DataTableColumnDef, DataTableCommand, DataTableEmptyStateProps, DataTableFilter, + DataTableFilteringState, + DataTablePaginationState, DataTableRow, DataTableRowSelectionState, + DataTableSortingState, +} from "@medusajs/ui"; +import { + Button, Heading, Text, - Button, - DataTableFilteringState, - DataTablePaginationState, - DataTableSortingState, -} from "@medusajs/ui" -import React, { ReactNode, useCallback, useMemo } from "react" -import { useTranslation } from "react-i18next" -import { Link, useNavigate, useSearchParams } from "react-router-dom" + DataTable as UiDataTable, + useDataTable, +} from "@medusajs/ui"; -import { useQueryParams } from "../../hooks/use-query-params" -import { ActionMenu } from "../common/action-menu" -import { ViewPills } from "../table/view-selector" -import { useFeatureFlag } from "../../providers/feature-flag-provider" +import { useTranslation } from "react-i18next"; +import { Link, useNavigate, useSearchParams } from "react-router-dom"; + +import { ActionMenu } from "@components/common/action-menu"; +import { ViewPills } from "@components/table/view-selector"; + +import { useQueryParams } from "@hooks/use-query-params"; + +import { useFeatureFlag } from "@providers/feature-flag-provider"; // Types for column visibility and ordering -type VisibilityState = Record -type ColumnOrderState = string[] +type VisibilityState = Record; +type ColumnOrderState = string[]; type DataTableActionProps = { - label: string - disabled?: boolean + label: string; + disabled?: boolean; } & ( | { - to: string + to: string; } | { - onClick: () => void + onClick: () => void; } -) +); type DataTableActionMenuActionProps = { - label: string - icon: ReactNode - disabled?: boolean + label: string; + icon: ReactNode; + disabled?: boolean; } & ( | { - to: string + to: string; } | { - onClick: () => void + onClick: () => void; } -) +); type DataTableActionMenuGroupProps = { - actions: DataTableActionMenuActionProps[] -} + actions: DataTableActionMenuActionProps[]; +}; type DataTableActionMenuProps = { - groups: DataTableActionMenuGroupProps[] -} + groups: DataTableActionMenuGroupProps[]; +}; interface DataTableProps { - data?: TData[] - columns: DataTableColumnDef[] - filters?: DataTableFilter[] - commands?: DataTableCommand[] - action?: DataTableActionProps - actions?: DataTableActionProps[] - actionMenu?: DataTableActionMenuProps - rowCount?: number - getRowId: (row: TData) => string - enablePagination?: boolean - enableSearch?: boolean - autoFocusSearch?: boolean - enableFilterMenu?: boolean - rowHref?: (row: TData) => string - emptyState?: DataTableEmptyStateProps - heading?: string - subHeading?: string - prefix?: string - pageSize?: number - isLoading?: boolean + data?: TData[]; + columns: DataTableColumnDef[]; + filters?: DataTableFilter[]; + commands?: DataTableCommand[]; + action?: DataTableActionProps; + actions?: DataTableActionProps[]; + actionMenu?: DataTableActionMenuProps; + rowCount?: number; + getRowId: (row: TData) => string; + enablePagination?: boolean; + enableSearch?: boolean; + autoFocusSearch?: boolean; + enableFilterMenu?: boolean; + rowHref?: (row: TData) => string; + emptyState?: DataTableEmptyStateProps; + heading?: string; + subHeading?: string; + prefix?: string; + pageSize?: number; + isLoading?: boolean; rowSelection?: { - state: DataTableRowSelectionState - onRowSelectionChange: (value: DataTableRowSelectionState) => void - enableRowSelection?: boolean | ((row: DataTableRow) => boolean) - } - layout?: "fill" | "auto" - enableColumnVisibility?: boolean - initialColumnVisibility?: VisibilityState - onColumnVisibilityChange?: (visibility: VisibilityState) => void - columnOrder?: ColumnOrderState - onColumnOrderChange?: (order: ColumnOrderState) => void - enableViewSelector?: boolean - entity?: string + state: DataTableRowSelectionState; + onRowSelectionChange: (value: DataTableRowSelectionState) => void; + enableRowSelection?: boolean | ((row: DataTableRow) => boolean); + }; + layout?: "fill" | "auto"; + enableColumnVisibility?: boolean; + initialColumnVisibility?: VisibilityState; + onColumnVisibilityChange?: (visibility: VisibilityState) => void; + columnOrder?: ColumnOrderState; + onColumnOrderChange?: (order: ColumnOrderState) => void; + enableViewSelector?: boolean; + entity?: string; currentColumns?: { - visible: string[] - order: string[] - } - filterBarContent?: React.ReactNode + visible: string[]; + order: string[]; + }; + filterBarContent?: React.ReactNode; } export const DataTable = ({ @@ -134,53 +141,53 @@ export const DataTable = ({ currentColumns, filterBarContent, }: DataTableProps) => { - const { t } = useTranslation() - const isViewConfigEnabled = useFeatureFlag("view_configurations") + const { t } = useTranslation(); + const isViewConfigEnabled = useFeatureFlag("view_configurations"); // If view config is disabled, don't use column visibility features const effectiveEnableColumnVisibility = - isViewConfigEnabled && enableColumnVisibility - const effectiveEnableViewSelector = isViewConfigEnabled && enableViewSelector + isViewConfigEnabled && enableColumnVisibility; + const effectiveEnableViewSelector = isViewConfigEnabled && enableViewSelector; - const enableFiltering = filters && filters.length > 0 + const enableFiltering = filters && filters.length > 0; const showFilterMenu = - enableFilterMenu !== undefined ? enableFilterMenu : enableFiltering - const enableCommands = commands && commands.length > 0 - const enableSorting = columns.some((column) => column.enableSorting) + enableFilterMenu !== undefined ? enableFilterMenu : enableFiltering; + const enableCommands = commands && commands.length > 0; + const enableSorting = columns.some((column) => column.enableSorting); const [columnVisibility, setColumnVisibility] = - React.useState(initialColumnVisibility) + React.useState(initialColumnVisibility); // Update column visibility when initial visibility changes React.useEffect(() => { // Deep compare to check if the visibility has actually changed - const currentKeys = Object.keys(columnVisibility).sort() - const newKeys = Object.keys(initialColumnVisibility).sort() + const currentKeys = Object.keys(columnVisibility).sort(); + const newKeys = Object.keys(initialColumnVisibility).sort(); const hasChanged = currentKeys.length !== newKeys.length || currentKeys.some((key, index) => key !== newKeys[index]) || Object.entries(initialColumnVisibility).some( - ([key, value]) => columnVisibility[key] !== value - ) + ([key, value]) => columnVisibility[key] !== value, + ); if (hasChanged) { - setColumnVisibility(initialColumnVisibility) + setColumnVisibility(initialColumnVisibility); } - }, [initialColumnVisibility]) + }, [initialColumnVisibility]); // Wrapper function to handle column visibility changes const handleColumnVisibilityChange = React.useCallback( (visibility: VisibilityState) => { - setColumnVisibility(visibility) - onColumnVisibilityChange?.(visibility) + setColumnVisibility(visibility); + onColumnVisibilityChange?.(visibility); }, - [onColumnVisibilityChange] - ) + [onColumnVisibilityChange], + ); // Extract filter IDs for query param management - const filterIds = useMemo(() => filters?.map((f) => f.id) ?? [], [filters]) - const prefixedFilterIds = filterIds.map((id) => getQueryParamKey(id, prefix)) + const filterIds = useMemo(() => filters?.map((f) => f.id) ?? [], [filters]); + const prefixedFilterIds = filterIds.map((id) => getQueryParamKey(id, prefix)); const { offset, order, q, ...filterParams } = useQueryParams( [ @@ -189,50 +196,51 @@ export const DataTable = ({ ...(enableSearch ? ["q"] : []), ...(enablePagination ? ["offset"] : []), ], - prefix - ) - const [_, setSearchParams] = useSearchParams() + prefix, + ); + const [_, setSearchParams] = useSearchParams(); const search = useMemo(() => { - return q ?? "" - }, [q]) + return q ?? ""; + }, [q]); const handleSearchChange = (value: string) => { setSearchParams((prev) => { if (value) { - prev.set(getQueryParamKey("q", prefix), value) + prev.set(getQueryParamKey("q", prefix), value); } else { - prev.delete(getQueryParamKey("q", prefix)) + prev.delete(getQueryParamKey("q", prefix)); } - return prev - }) - } + return prev; + }); + }; const pagination: DataTablePaginationState = useMemo(() => { return offset ? parsePaginationState(offset, pageSize) - : { pageIndex: 0, pageSize } - }, [offset, pageSize]) + : { pageIndex: 0, pageSize }; + }, [offset, pageSize]); const handlePaginationChange = (value: DataTablePaginationState) => { setSearchParams((prev) => { if (value.pageIndex === 0) { - prev.delete(getQueryParamKey("offset", prefix)) + prev.delete(getQueryParamKey("offset", prefix)); } else { prev.set( getQueryParamKey("offset", prefix), - transformPaginationState(value).toString() - ) + transformPaginationState(value).toString(), + ); } - return prev - }) - } + + return prev; + }); + }; const filtering: DataTableFilteringState = useMemo( () => parseFilterState(filterIds, filterParams), - [filterIds, filterParams] - ) + [filterIds, filterParams], + ); const handleFilteringChange = (value: DataTableFilteringState) => { setSearchParams((prev) => { @@ -240,30 +248,30 @@ export const DataTable = ({ Array.from(prev.keys()).forEach((key) => { if (prefixedFilterIds.includes(key)) { // Extract the unprefixed key - const unprefixedKey = prefix ? key.replace(`${prefix}_`, "") : key + const unprefixedKey = prefix ? key.replace(`${prefix}_`, "") : key; if (!(unprefixedKey in value)) { - prev.delete(key) + prev.delete(key); } } - }) + }); // Add or update filters in the state Object.entries(value).forEach(([key, filter]) => { - const prefixedKey = getQueryParamKey(key, prefix) + const prefixedKey = getQueryParamKey(key, prefix); if (filter !== undefined) { - prev.set(prefixedKey, JSON.stringify(filter)) + prev.set(prefixedKey, JSON.stringify(filter)); } else { - prev.delete(prefixedKey) + prev.delete(prefixedKey); } - }) + }); - return prev - }) - } + return prev; + }); + }; const sorting: DataTableSortingState | null = useMemo(() => { - return order ? parseSortingState(order) : null - }, [order]) + return order ? parseSortingState(order) : null; + }, [order]); // Memoize current configuration to prevent infinite loops const currentConfiguration = useMemo( @@ -272,50 +280,52 @@ export const DataTable = ({ sorting: sorting, search: search, }), - [filtering, sorting, search] - ) + [filtering, sorting, search], + ); const handleSortingChange = (value: DataTableSortingState) => { setSearchParams((prev) => { if (value) { - const valueToStore = transformSortingState(value) + const valueToStore = transformSortingState(value); - prev.set(getQueryParamKey("order", prefix), valueToStore) + prev.set(getQueryParamKey("order", prefix), valueToStore); } else { - prev.delete(getQueryParamKey("order", prefix)) + prev.delete(getQueryParamKey("order", prefix)); } - return prev - }) - } + return prev; + }); + }; const { pagination: paginationTranslations, toolbar: toolbarTranslations } = - useDataTableTranslations() + useDataTableTranslations(); - const navigate = useNavigate() + const navigate = useNavigate(); const onRowClick = useCallback( (event: React.MouseEvent, row: TData) => { if (!rowHref) { - return + return; } - const href = rowHref(row) + const href = rowHref(row); if (event.metaKey || event.ctrlKey || event.button === 1) { - window.open(href, "_blank", "noreferrer") - return + window.open(href, "_blank", "noreferrer"); + + return; } if (event.shiftKey) { - window.open(href, undefined, "noreferrer") - return + window.open(href, undefined, "noreferrer"); + + return; } - navigate(href) + navigate(href); }, - [navigate, rowHref] - ) + [navigate, rowHref], + ); const instance = useDataTable({ data, @@ -364,9 +374,9 @@ export const DataTable = ({ onColumnOrderChange: onColumnOrderChange, } : undefined, - }) + }); - const shouldRenderHeading = heading || subHeading + const shouldRenderHeading = heading || subHeading; return ( ({
    @@ -429,59 +441,59 @@ export const DataTable = ({ /> )}
    - ) -} + ); +}; function transformSortingState(value: DataTableSortingState) { - return value.desc ? `-${value.id}` : value.id + return value.desc ? `-${value.id}` : value.id; } function parseSortingState(value: string) { return value.startsWith("-") ? { id: value.slice(1), desc: true } - : { id: value, desc: false } + : { id: value, desc: false }; } function transformPaginationState(value: DataTablePaginationState) { - return value.pageIndex * value.pageSize + return value.pageIndex * value.pageSize; } function parsePaginationState(value: string, pageSize: number) { - const offset = parseInt(value) + const offset = parseInt(value); return { pageIndex: Math.floor(offset / pageSize), pageSize, - } + }; } function parseFilterState( filterIds: string[], - value: Record + value: Record, ) { if (!value) { - return {} + return {}; } - const filters: DataTableFilteringState = {} + const filters: DataTableFilteringState = {}; for (const id of filterIds) { - const filterValue = value[id] + const filterValue = value[id]; if (filterValue !== undefined) { - filters[id] = JSON.parse(filterValue) + filters[id] = JSON.parse(filterValue); } } - return filters + return filters; } function getQueryParamKey(key: string, prefix?: string) { - return prefix ? `${prefix}_${key}` : key + return prefix ? `${prefix}_${key}` : key; } const useDataTableTranslations = () => { - const { t } = useTranslation() + const { t } = useTranslation(); const paginationTranslations = { of: t("general.of"), @@ -489,19 +501,19 @@ const useDataTableTranslations = () => { pages: t("general.pages"), prev: t("general.prev"), next: t("general.next"), - } + }; const toolbarTranslations = { clearAll: t("actions.clearAll"), sort: t("filters.sortLabel"), columns: "Columns", - } + }; return { pagination: paginationTranslations, toolbar: toolbarTranslations, - } -} + }; +}; const DataTableAction = ({ label, @@ -513,22 +525,22 @@ const DataTableAction = ({ disabled: disabled ?? false, type: "button" as const, variant: "secondary" as const, - } + }; if ("to" in props) { return ( - ) + ); } return ( - ) -} + ); +}; const DataTableActions = ({ actions }: { actions: DataTableActionProps[] }) => { return ( @@ -537,5 +549,5 @@ const DataTableActions = ({ actions }: { actions: DataTableActionProps[] }) => { ))}
    - ) -} + ); +}; diff --git a/src/components/data-table/index.ts b/src/components/data-table/index.ts index 8e2d5f82..ff428399 100644 --- a/src/components/data-table/index.ts +++ b/src/components/data-table/index.ts @@ -1 +1 @@ -export * from "./data-table" +export * from "./data-table"; From bf89a961a78158e04814988a100a4c32c72d4fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 22:21:13 +0200 Subject: [PATCH 043/195] eslint/prettier - fix components/filtering/filter-group --- .../filtering/filter-group/filter-group.tsx | 50 ++++++++++--------- .../filtering/filter-group/index.ts | 2 +- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/components/filtering/filter-group/filter-group.tsx b/src/components/filtering/filter-group/filter-group.tsx index bba70491..582bc9c0 100644 --- a/src/components/filtering/filter-group/filter-group.tsx +++ b/src/components/filtering/filter-group/filter-group.tsx @@ -1,28 +1,31 @@ -import { Button, DropdownMenu } from "@medusajs/ui" -import { ReactNode } from "react" -import { useSearchParams } from "react-router-dom" -import { useDocumentDirection } from "../../../hooks/use-document-direction" +import type { ReactNode } from "react"; + +import { Button, DropdownMenu } from "@medusajs/ui"; + +import { useSearchParams } from "react-router-dom"; + +import { useDocumentDirection } from "@hooks/use-document-direction"; type FilterGroupProps = { filters: { - [key: string]: ReactNode - } -} + [key: string]: ReactNode; + }; +}; export const FilterGroup = ({ filters }: FilterGroupProps) => { - const [searchParams] = useSearchParams() - const filterKeys = Object.keys(filters) + const [searchParams] = useSearchParams(); + const filterKeys = Object.keys(filters); if (filterKeys.length === 0) { - return null + return null; } - const isClearable = filterKeys.some((key) => searchParams.get(key)) - const hasMore = !filterKeys.every((key) => searchParams.get(key)) - const availableKeys = filterKeys.filter((key) => !searchParams.get(key)) + const isClearable = filterKeys.some((key) => searchParams.get(key)); + const hasMore = !filterKeys.every((key) => searchParams.get(key)); + const availableKeys = filterKeys.filter((key) => !searchParams.get(key)); return ( -
    +
    {hasMore && } {isClearable && ( )}
    - ) -} + ); +}; type AddFilterMenuProps = { - availableKeys: string[] -} + availableKeys: string[]; +}; const AddFilterMenu = ({ availableKeys }: AddFilterMenuProps) => { - const direction = useDocumentDirection() + const direction = useDocumentDirection(); + return ( - +
    - ) -} + ); +}; diff --git a/src/components/forms/address-form/index.ts b/src/components/forms/address-form/index.ts index ea5dea61..57e3d008 100644 --- a/src/components/forms/address-form/index.ts +++ b/src/components/forms/address-form/index.ts @@ -1 +1 @@ -export * from "./address-form" +export * from "./address-form"; From 19fa9065775763dcafaa12ab35e7625b64d560ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 22:28:22 +0200 Subject: [PATCH 047/195] eslint/prettier - fix components/form/email-form --- .../forms/email-form/email-form.tsx | 49 ++++++++++--------- src/components/forms/email-form/index.ts | 2 +- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/components/forms/email-form/email-form.tsx b/src/components/forms/email-form/email-form.tsx index b100334a..0362901b 100644 --- a/src/components/forms/email-form/email-form.tsx +++ b/src/components/forms/email-form/email-form.tsx @@ -1,19 +1,22 @@ -import { Input, clx } from "@medusajs/ui" -import { Control } from "react-hook-form" -import { useTranslation } from "react-i18next" -import { z } from "zod" -import { EmailSchema } from "../../../lib/schemas" -import { Form } from "../../common/form" +import { Input, clx } from "@medusajs/ui"; -type EmailFieldValues = z.infer +import type { Control } from "react-hook-form"; +import { useTranslation } from "react-i18next"; +import type { z } from "zod"; + +import { Form } from "@components/common/form"; + +import type { EmailSchema } from "@lib/schemas"; + +type EmailFieldValues = z.infer; type EmailFormProps = { - control: Control - layout?: "grid" | "stack" -} + control: Control; + layout?: "grid" | "stack"; +}; export const EmailForm = ({ control, layout = "stack" }: EmailFormProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    { { - return ( - - {t("fields.email")} - - - - - - ) - }} + render={({ field }) => ( + + {t("fields.email")} + + + + + + )} />
    - ) -} + ); +}; diff --git a/src/components/forms/email-form/index.ts b/src/components/forms/email-form/index.ts index ba4619f6..fd45d99c 100644 --- a/src/components/forms/email-form/index.ts +++ b/src/components/forms/email-form/index.ts @@ -1 +1 @@ -export * from "./email-form" +export * from "./email-form"; From 0483c54da33a28d82869f12de7057eac6d16cbb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 22:32:41 +0200 Subject: [PATCH 048/195] eslint/prettier - fix components/form/metadata-form --- src/components/forms/metadata-form/index.ts | 2 +- .../forms/metadata-form/metadata-form.tsx | 327 +++++++++--------- 2 files changed, 169 insertions(+), 160 deletions(-) diff --git a/src/components/forms/metadata-form/index.ts b/src/components/forms/metadata-form/index.ts index 77c403fc..3e4bafb1 100644 --- a/src/components/forms/metadata-form/index.ts +++ b/src/components/forms/metadata-form/index.ts @@ -1 +1 @@ -export * from "./metadata-form" +export * from "./metadata-form"; diff --git a/src/components/forms/metadata-form/metadata-form.tsx b/src/components/forms/metadata-form/metadata-form.tsx index bf65a27e..0c5becf2 100644 --- a/src/components/forms/metadata-form/metadata-form.tsx +++ b/src/components/forms/metadata-form/metadata-form.tsx @@ -1,4 +1,13 @@ -import { zodResolver } from "@hookform/resolvers/zod" +import type { ComponentPropsWithoutRef } from "react"; +import { forwardRef } from "react"; + +import { + ArrowDownMini, + ArrowUpMini, + EllipsisVertical, + Trash, +} from "@medusajs/icons"; +import type { FetchError } from "@medusajs/js-sdk"; import { Button, DropdownMenu, @@ -7,51 +16,50 @@ import { InlineTip, clx, toast, -} from "@medusajs/ui" -import { useFieldArray, useForm } from "react-hook-form" -import { useTranslation } from "react-i18next" -import { z } from "zod" +} from "@medusajs/ui"; -import { - ArrowDownMini, - ArrowUpMini, - EllipsisVertical, - Trash, -} from "@medusajs/icons" -import { FetchError } from "@medusajs/js-sdk" -import { ComponentPropsWithoutRef, forwardRef } from "react" -import { ConditionalTooltip } from "../../common/conditional-tooltip" -import { Form } from "../../common/form" -import { Skeleton } from "../../common/skeleton" -import { RouteDrawer, useRouteModal } from "../../modals" -import { KeyboundForm } from "../../utilities/keybound-form" -import { useDocumentDirection } from "../../../hooks/use-document-direction" +import { zodResolver } from "@hookform/resolvers/zod"; +import { useFieldArray, useForm } from "react-hook-form"; +import { useTranslation } from "react-i18next"; +import { z } from "zod"; + +import { ConditionalTooltip } from "@components//common/conditional-tooltip"; +import { Form } from "@components/common/form"; +import { Skeleton } from "@components/common/skeleton"; +import { RouteDrawer, useRouteModal } from "@components/modals"; +import { KeyboundForm } from "@components/utilities/keybound-form"; + +import { useDocumentDirection } from "@hooks/use-document-direction"; type MetaDataSubmitHook = ( + // @todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any params: { metadata?: Record | null }, - callbacks: { onSuccess: () => void; onError: (error: FetchError) => void } -) => Promise + callbacks: { onSuccess: () => void; onError: (error: FetchError) => void }, +) => Promise; type MetadataFormProps = { - metadata?: Record | null - hook: MetaDataSubmitHook - isPending: boolean - isMutating: boolean -} + // @todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + metadata?: Record | null; + hook: MetaDataSubmitHook; + isPending: boolean; + isMutating: boolean; +}; const MetadataFieldSchema = z.object({ key: z.string(), disabled: z.boolean().optional(), value: z.any(), -}) +}); const MetadataSchema = z.object({ metadata: z.array(MetadataFieldSchema), -}) +}); export const MetadataForm = (props: MetadataFormProps) => { - const { t } = useTranslation() - const { isPending, ...innerProps } = props + const { t } = useTranslation(); + const { isPending, ...innerProps } = props; return ( @@ -65,31 +73,31 @@ export const MetadataForm = (props: MetadataFormProps) => { {isPending ? : } - ) -} + ); +}; -const METADATA_KEY_LABEL_ID = "metadata-form-key-label" -const METADATA_VALUE_LABEL_ID = "metadata-form-value-label" +const METADATA_KEY_LABEL_ID = "metadata-form-key-label"; +const METADATA_VALUE_LABEL_ID = "metadata-form-value-label"; const InnerForm = ({ metadata, hook, isMutating, }: Omit, "isPending">) => { - const { t } = useTranslation() - const { handleSuccess } = useRouteModal() - const direction = useDocumentDirection() - const hasUneditableRows = getHasUneditableRows(metadata) + const { t } = useTranslation(); + const { handleSuccess } = useRouteModal(); + const direction = useDocumentDirection(); + const hasUneditableRows = getHasUneditableRows(metadata); const form = useForm>({ defaultValues: { metadata: getDefaultValues(metadata), }, resolver: zodResolver(MetadataSchema), - }) + }); const handleSubmit = form.handleSubmit(async (data) => { - const parsedData = parseValues(data, metadata) + const parsedData = parseValues(data, metadata); await hook( { @@ -97,23 +105,23 @@ const InnerForm = ({ }, { onSuccess: () => { - toast.success(t("metadata.edit.successToast")) - handleSuccess() + toast.success(t("metadata.edit.successToast")); + handleSuccess(); }, onError: (error) => { - toast.error(error.message) + toast.error(error.message); }, - } - ) - }) + }, + ); + }); const { fields, insert, remove } = useFieldArray({ control: form.control, name: "metadata", - }) + }); function deleteRow(index: number) { - remove(index) + remove(index); // If the last row is deleted, add a new blank row if (fields.length === 1) { @@ -121,7 +129,7 @@ const InnerForm = ({ key: "", value: "", disabled: false, - }) + }); } } @@ -130,7 +138,7 @@ const InnerForm = ({ key: "", value: "", disabled: false, - }) + }); } return ( @@ -140,29 +148,29 @@ const InnerForm = ({ className="flex flex-1 flex-col overflow-hidden" > -
    -
    -
    +
    +
    +
    -
    +
    {fields.map((field, index) => { - const isDisabled = field.disabled || false - let placeholder = "-" + const isDisabled = field.disabled || false; + let placeholder = "-"; if (typeof field.value === "object") { - placeholder = "{ ... }" + placeholder = "{ ... }"; } if (Array.isArray(field.value)) { - placeholder = "[ ... ]" + placeholder = "[ ... ]"; } return ( @@ -181,50 +189,44 @@ const InnerForm = ({ { - return ( - - - - - - ) - }} + render={({ field }) => ( + + + + + + )} /> { - return ( - - - - - - ) - }} + render={({ field: { value, ...field } }) => ( + + + + + + )} />
    - + ({
    - ) + ); })}
    {hasUneditableRows && ( @@ -291,47 +293,45 @@ const InnerForm = ({ - ) -} + ); +}; const GridInput = forwardRef< HTMLInputElement, ComponentPropsWithoutRef<"input"> ->(({ className, ...props }, ref) => { - return ( - - ) -}) -GridInput.displayName = "MetadataForm.GridInput" - -const PlaceholderInner = () => { - return ( -
    - - - - -
    - - -
    -
    -
    - ) -} - -const EDITABLE_TYPES = ["string", "number", "boolean"] +>(({ className, ...props }, ref) => ( + +)); +GridInput.displayName = "MetadataForm.GridInput"; + +const PlaceholderInner = () => ( +
    + + + + +
    + + +
    +
    +
    +); + +const EDITABLE_TYPES = ["string", "number", "boolean"]; function getDefaultValues( - metadata?: Record | null + // @todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + metadata?: Record | null, ): z.infer[] { if (!metadata || !Object.keys(metadata).length) { return [ @@ -340,7 +340,7 @@ function getDefaultValues( value: "", disabled: false, }, - ] + ]; } return Object.entries(metadata).map(([key, value]) => { @@ -349,90 +349,99 @@ function getDefaultValues( key, value: value, disabled: true, - } + }; } - let stringValue = value + let stringValue = value; if (typeof value !== "string") { - stringValue = JSON.stringify(value) + stringValue = JSON.stringify(value); } return { key, value: stringValue, original_key: key, - } - }) + }; + }); } function parseValues( values: z.infer, - original?: Record | null + // @todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + original?: Record | null, + // @todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any ): Record | null { - const metadata = values.metadata + const metadata = values.metadata; const isEmpty = !metadata.length || - (metadata.length === 1 && !metadata[0].key && !metadata[0].value) + (metadata.length === 1 && !metadata[0].key && !metadata[0].value); if (isEmpty) { - return null + return null; } - const update: Record = {} + // @todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const update: Record = {}; // First, handle removed keys from original if (original) { Object.keys(original).forEach((originalKey) => { - const exists = metadata.some((field) => field.key === originalKey) + const exists = metadata.some((field) => field.key === originalKey); if (!exists) { - update[originalKey] = "" + update[originalKey] = ""; } - }) + }); } metadata.forEach((field) => { - let key = field.key - let value = field.value - const disabled = field.disabled + let key = field.key; + let value = field.value; + const disabled = field.disabled; if (!key) { - return + return; } if (disabled) { - update[key] = value - return + update[key] = value; + + return; } - key = key.trim() - value = value?.trim() ?? "" + key = key.trim(); + value = value?.trim() ?? ""; // We try to cast the value to a boolean or number if possible if (value === "true") { - update[key] = true + update[key] = true; } else if (value === "false") { - update[key] = false + update[key] = false; } else { - const isNumeric = /^-?\d*\.?\d+$/.test(value) + const isNumeric = /^-?\d*\.?\d+$/.test(value); if (isNumeric) { - update[key] = parseFloat(value) + update[key] = parseFloat(value); } else { - update[key] = value + update[key] = value; } } - }) + }); - return update + return update; } +// @todo fix type +// eslint-disable-next-line @typescript-eslint/no-explicit-any function getHasUneditableRows(metadata?: Record | null) { if (!metadata) { - return false + return false; } return Object.values(metadata).some( - (value) => !EDITABLE_TYPES.includes(typeof value) - ) + (value) => !EDITABLE_TYPES.includes(typeof value), + ); } From e3d942d90d0a4b8b7fd9d4ae1b7ef28594df0d56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 22:34:23 +0200 Subject: [PATCH 049/195] eslint/prettier - fix components/inputs/chip-input --- .../inputs/chip-input/chip-input.tsx | 188 +++++++++--------- src/components/inputs/chip-input/index.ts | 2 +- 2 files changed, 93 insertions(+), 97 deletions(-) diff --git a/src/components/inputs/chip-input/chip-input.tsx b/src/components/inputs/chip-input/chip-input.tsx index ce942d4f..d50390fe 100644 --- a/src/components/inputs/chip-input/chip-input.tsx +++ b/src/components/inputs/chip-input/chip-input.tsx @@ -1,27 +1,23 @@ -import { XMarkMini } from "@medusajs/icons" -import { Badge, clx } from "@medusajs/ui" -import { AnimatePresence, motion } from "motion/react" -import { - FocusEvent, - KeyboardEvent, - forwardRef, - useImperativeHandle, - useRef, - useState, -} from "react" +import type { FocusEvent, KeyboardEvent } from "react"; +import { forwardRef, useImperativeHandle, useRef, useState } from "react"; + +import { XMarkMini } from "@medusajs/icons"; +import { Badge, clx } from "@medusajs/ui"; + +import { AnimatePresence, motion } from "motion/react"; type ChipInputProps = { - value?: string[] - onChange?: (value: string[]) => void - onBlur?: () => void - name?: string - disabled?: boolean - allowDuplicates?: boolean - showRemove?: boolean - variant?: "base" | "contrast" - placeholder?: string - className?: string -} + value?: string[]; + onChange?: (value: string[]) => void; + onBlur?: () => void; + name?: string; + disabled?: boolean; + allowDuplicates?: boolean; + showRemove?: boolean; + variant?: "base" | "contrast"; + placeholder?: string; + className?: string; +}; export const ChipInput = forwardRef( ( @@ -37,143 +33,143 @@ export const ChipInput = forwardRef( placeholder, className, }, - ref + ref, ) => { - const innerRef = useRef(null) + const innerRef = useRef(null); - const isControlledRef = useRef(typeof value !== "undefined") - const isControlled = isControlledRef.current + const isControlledRef = useRef(typeof value !== "undefined"); + const isControlled = isControlledRef.current; - const [uncontrolledValue, setUncontrolledValue] = useState([]) + const [uncontrolledValue, setUncontrolledValue] = useState([]); useImperativeHandle( ref, - () => innerRef.current - ) + () => innerRef.current, + ); - const [duplicateIndex, setDuplicateIndex] = useState(null) + const [duplicateIndex, setDuplicateIndex] = useState(null); - const chips = isControlled ? (value as string[]) : uncontrolledValue + const chips = isControlled ? (value as string[]) : uncontrolledValue; const handleAddChip = (chip: string) => { - const cleanValue = chip.trim() + const cleanValue = chip.trim(); if (!cleanValue) { - return + return; } if (!allowDuplicates && chips.includes(cleanValue)) { - setDuplicateIndex(chips.indexOf(cleanValue)) + setDuplicateIndex(chips.indexOf(cleanValue)); setTimeout(() => { - setDuplicateIndex(null) - }, 300) + setDuplicateIndex(null); + }, 300); - return + return; } - onChange?.([...chips, cleanValue]) + onChange?.([...chips, cleanValue]); if (!isControlled) { - setUncontrolledValue([...chips, cleanValue]) + setUncontrolledValue([...chips, cleanValue]); } - } + }; const handleRemoveChip = (chip: string) => { - onChange?.(chips.filter((v) => v !== chip)) + onChange?.(chips.filter((v) => v !== chip)); if (!isControlled) { - setUncontrolledValue(chips.filter((v) => v !== chip)) + setUncontrolledValue(chips.filter((v) => v !== chip)); } - } + }; const handleBlur = (e: FocusEvent) => { - onBlur?.() + onBlur?.(); if (e.target.value) { - handleAddChip(e.target.value) - e.target.value = "" + handleAddChip(e.target.value); + e.target.value = ""; } - } + }; const handleKeyDown = (e: KeyboardEvent) => { if (e.key === "Enter" || e.key === ",") { - e.preventDefault() + e.preventDefault(); if (!innerRef.current?.value) { - return + return; } - handleAddChip(innerRef.current?.value ?? "") - innerRef.current.value = "" - innerRef.current?.focus() + handleAddChip(innerRef.current?.value ?? ""); + innerRef.current.value = ""; + innerRef.current?.focus(); } if (e.key === "Backspace" && innerRef.current?.value === "") { - handleRemoveChip(chips[chips.length - 1]) + handleRemoveChip(chips[chips.length - 1]); } - } + }; // create a shake animation using framer motion const shake = { x: [0, -2, 2, -2, 2, 0], transition: { duration: 0.3 }, - } + }; return ( + //@todo fix a11y issue + // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
    innerRef.current?.focus()} > - {chips.map((v, index) => { - return ( - - ( + + + - - {v} - {showRemove && ( - - )} - - - - ) - })} + {v} + {showRemove && ( + + )} + + + + ))} ( autoComplete="off" />
    - ) - } -) + ); + }, +); -ChipInput.displayName = "ChipInput" +ChipInput.displayName = "ChipInput"; diff --git a/src/components/inputs/chip-input/index.ts b/src/components/inputs/chip-input/index.ts index 30cc6cbe..26f5d871 100644 --- a/src/components/inputs/chip-input/index.ts +++ b/src/components/inputs/chip-input/index.ts @@ -1 +1 @@ -export * from "./chip-input" +export * from "./chip-input"; From a19272614f0c0f2e56f30f58a781d35b2fac701f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 22:38:13 +0200 Subject: [PATCH 050/195] eslint/prettier - fix components/inputs/combobox --- src/components/inputs/combobox/combobox.tsx | 265 ++++++++++---------- src/components/inputs/combobox/index.ts | 2 +- 2 files changed, 138 insertions(+), 129 deletions(-) diff --git a/src/components/inputs/combobox/combobox.tsx b/src/components/inputs/combobox/combobox.tsx index a8875443..b04ae16f 100644 --- a/src/components/inputs/combobox/combobox.tsx +++ b/src/components/inputs/combobox/combobox.tsx @@ -1,28 +1,11 @@ -import { - Combobox as PrimitiveCombobox, - ComboboxDisclosure as PrimitiveComboboxDisclosure, - ComboboxItem as PrimitiveComboboxItem, - ComboboxItemCheck as PrimitiveComboboxItemCheck, - ComboboxItemValue as PrimitiveComboboxItemValue, - ComboboxPopover as PrimitiveComboboxPopover, - ComboboxProvider as PrimitiveComboboxProvider, - Separator as PrimitiveSeparator, -} from "@ariakit/react" -import { - CheckMini, - EllipseMiniSolid, - PlusMini, - TrianglesMini, - XMarkMini, -} from "@medusajs/icons" -import { clx, Text } from "@medusajs/ui" -import { matchSorter } from "match-sorter" -import { - ComponentPropsWithoutRef, +import type { CSSProperties, + ComponentPropsWithoutRef, ForwardedRef, - Fragment, ReactNode, +} from "react"; +import { + Fragment, useCallback, useDeferredValue, useImperativeHandle, @@ -30,35 +13,56 @@ import { useRef, useState, useTransition, -} from "react" -import { useTranslation } from "react-i18next" +} from "react"; -import { genericForwardRef } from "../../utilities/generic-forward-ref" +import { + CheckMini, + EllipseMiniSolid, + PlusMini, + TrianglesMini, + XMarkMini, +} from "@medusajs/icons"; +import { Text, clx } from "@medusajs/ui"; + +import { + Combobox as PrimitiveCombobox, + ComboboxDisclosure as PrimitiveComboboxDisclosure, + ComboboxItem as PrimitiveComboboxItem, + ComboboxItemCheck as PrimitiveComboboxItemCheck, + ComboboxItemValue as PrimitiveComboboxItemValue, + ComboboxPopover as PrimitiveComboboxPopover, + ComboboxProvider as PrimitiveComboboxProvider, + Separator as PrimitiveSeparator, +} from "@ariakit/react"; +import { matchSorter } from "match-sorter"; +import { useTranslation } from "react-i18next"; + +import { genericForwardRef } from "@components/utilities/generic-forward-ref"; type ComboboxOption = { - value: string - label: string - disabled?: boolean -} + value: string; + label: string; + disabled?: boolean; +}; -type Value = string[] | string +type Value = string[] | string; -const TABLUAR_NUM_WIDTH = 8 -const TAG_BASE_WIDTH = 28 +const TABLUAR_NUM_WIDTH = 8; +const TAG_BASE_WIDTH = 28; interface ComboboxProps extends Omit, "onChange" | "value"> { - value?: T - onChange?: (value?: T) => void - searchValue?: string - onSearchValueChange?: (value: string) => void - options: ComboboxOption[] - fetchNextPage?: () => void - isFetchingNextPage?: boolean - onCreateOption?: (value: string) => void - noResultsPlaceholder?: ReactNode - allowClear?: boolean - forceHideInput?: boolean // always hide input -> used for singe value select that don't have query/filter + value?: T; + onChange?: (value?: T) => void; + searchValue?: string; + onSearchValueChange?: (value: string) => void; + options: ComboboxOption[]; + fetchNextPage?: () => void; + isFetchingNextPage?: boolean; + onCreateOption?: (value: string) => void; + noResultsPlaceholder?: ReactNode; + allowClear?: boolean; + forceHideInput?: boolean; // always hide input -> used for singe value select that don't have query/filter } const ComboboxImpl = ( @@ -78,34 +82,36 @@ const ComboboxImpl = ( forceHideInput, ...inputProps }: ComboboxProps, - ref: ForwardedRef + ref: ForwardedRef, ) => { - const [open, setOpen] = useState(false) - const [isPending, startTransition] = useTransition() - const { t } = useTranslation() + const [open, setOpen] = useState(false); + const [isPending, startTransition] = useTransition(); + const { t } = useTranslation(); - const comboboxRef = useRef(null) - const listboxRef = useRef(null) + const comboboxRef = useRef(null); + const listboxRef = useRef(null); - useImperativeHandle(ref, () => comboboxRef.current!) + useImperativeHandle(ref, () => comboboxRef.current!); - const isValueControlled = controlledValue !== undefined - const isSearchControlled = controlledSearchValue !== undefined + const isValueControlled = controlledValue !== undefined; + const isSearchControlled = controlledSearchValue !== undefined; - const isArrayValue = Array.isArray(controlledValue) - const emptyState = (isArrayValue ? [] : "") as T + const isArrayValue = Array.isArray(controlledValue); + const emptyState = (isArrayValue ? [] : "") as T; const [uncontrolledSearchValue, setUncontrolledSearchValue] = useState( - controlledSearchValue || "" - ) - const defferedSearchValue = useDeferredValue(uncontrolledSearchValue) + controlledSearchValue || "", + ); + const defferedSearchValue = useDeferredValue(uncontrolledSearchValue); - const [uncontrolledValue, setUncontrolledValue] = useState(emptyState) + const [uncontrolledValue, setUncontrolledValue] = useState(emptyState); const searchValue = isSearchControlled ? controlledSearchValue - : uncontrolledSearchValue - const selectedValues = isValueControlled ? controlledValue : uncontrolledValue + : uncontrolledSearchValue; + const selectedValues = isValueControlled + ? controlledValue + : uncontrolledValue; const handleValueChange = (newValues?: T) => { // check if the value already exists in options @@ -113,35 +119,36 @@ const ComboboxImpl = ( .filter((o) => !o.disabled) .find((o) => { if (isArrayValue) { - return newValues?.includes(o.value) + return newValues?.includes(o.value); } - return o.value === newValues - }) + + return o.value === newValues; + }); // If the value does not exist in the options, and the component has a handler // for creating new options, call it. if (!exists && onCreateOption && newValues) { - onCreateOption(newValues as string) + onCreateOption(newValues as string); } if (!isValueControlled) { - setUncontrolledValue(newValues || emptyState) + setUncontrolledValue(newValues || emptyState); } if (onChange) { - onChange(newValues) + onChange(newValues); } - setUncontrolledSearchValue("") - } + setUncontrolledSearchValue(""); + }; const handleSearchChange = (query: string) => { - setUncontrolledSearchValue(query) + setUncontrolledSearchValue(query); if (onSearchValueChange) { - onSearchValueChange(query) + onSearchValueChange(query); } - } + }; /** * Filter and sort the options based on the search value, @@ -151,78 +158,78 @@ const ComboboxImpl = ( */ const matches = useMemo(() => { if (isSearchControlled) { - return [] + return []; } // do not use `matcher` if the input is hidden if (forceHideInput) { - return options + return options; } return matchSorter(options, defferedSearchValue, { keys: ["label"], - }) - }, [options, defferedSearchValue, isSearchControlled, forceHideInput]) + }); + }, [options, defferedSearchValue, isSearchControlled, forceHideInput]); const observer = useRef( new IntersectionObserver( (entries) => { - const first = entries[0] + const first = entries[0]; if (first.isIntersecting) { - fetchNextPage?.() + fetchNextPage?.(); } }, - { threshold: 1 } - ) - ) + { threshold: 1 }, + ), + ); const lastOptionRef = useCallback( (node: HTMLDivElement) => { if (isFetchingNextPage) { - return + return; } if (observer.current) { - observer.current.disconnect() + observer.current.disconnect(); } if (node) { - observer.current.observe(node) + observer.current.observe(node); } }, - [isFetchingNextPage] - ) + [isFetchingNextPage], + ); const handleOpenChange = (open: boolean) => { if (!open) { - setUncontrolledSearchValue("") + setUncontrolledSearchValue(""); } - setOpen(open) - } + setOpen(open); + }; - const hasValue = selectedValues?.length > 0 + const hasValue = selectedValues?.length > 0; - const showTag = hasValue && isArrayValue - const showSelected = showTag && !searchValue && !open + const showTag = hasValue && isArrayValue; + const showSelected = showTag && !searchValue && !open; - const hideInput = forceHideInput || (!isArrayValue && hasValue && !open) - const selectedLabel = options.find((o) => o.value === selectedValues)?.label + const hideInput = forceHideInput || (!isArrayValue && hasValue && !open); + const selectedLabel = options.find((o) => o.value === selectedValues)?.label; - const hidePlaceholder = showSelected || open + const hidePlaceholder = showSelected || open; const tagWidth = useMemo(() => { if (!Array.isArray(selectedValues)) { - return TAG_BASE_WIDTH + TABLUAR_NUM_WIDTH // There can only be a single digit + return TAG_BASE_WIDTH + TABLUAR_NUM_WIDTH; // There can only be a single digit } - const count = selectedValues.length - const digits = count.toString().length + const count = selectedValues.length; + const digits = count.toString().length; - return TAG_BASE_WIDTH + digits * TABLUAR_NUM_WIDTH - }, [selectedValues]) + return TAG_BASE_WIDTH + digits * TABLUAR_NUM_WIDTH; + }, [selectedValues]); const results = useMemo(() => { - return isSearchControlled ? options : matches - }, [matches, options, isSearchControlled]) + return isSearchControlled ? options : matches; + }, [matches, options, isSearchControlled]); return ( ( setSelectedValue={(value) => handleValueChange(value as T)} value={uncontrolledSearchValue} setValue={(query) => { - startTransition(() => handleSearchChange(query)) + startTransition(() => handleSearchChange(query)); }} >
    ( @@ -330,11 +339,11 @@ const ComboboxImpl = ( - ) + ); }} />
    @@ -344,11 +353,11 @@ const ComboboxImpl = ( ref={listboxRef} role="listbox" className={clx( - "shadow-elevation-flyout bg-ui-bg-base z-50 rounded-[8px] p-1", + "z-50 rounded-[8px] bg-ui-bg-base p-1 shadow-elevation-flyout", "max-h-[200px] overflow-y-auto", "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95", "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95", - "data-[side=bottom]:slide-in-from-top-2 data-[side=start]:slide-in-from-end-2 data-[side=end]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2" + "data-[side=start]:slide-in-from-end-2 data-[side=end]:slide-in-from-start-2 data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2", )} style={{ pointerEvents: open ? "auto" : "none", @@ -363,11 +372,11 @@ const ComboboxImpl = ( setValueOnClick={false} disabled={disabled} className={clx( - "transition-fg bg-ui-bg-base data-[active-item=true]:bg-ui-bg-base-hover group flex cursor-pointer items-center gap-x-2 rounded-[4px] px-2 py-1", + "group flex cursor-pointer items-center gap-x-2 rounded-[4px] bg-ui-bg-base px-2 py-1 transition-fg data-[active-item=true]:bg-ui-bg-base-hover", { "text-ui-fg-disabled": disabled, "bg-ui-bg-component": disabled, - } + }, )} > @@ -380,8 +389,8 @@ const ComboboxImpl = ( ))} {!!fetchNextPage &&
    } {isFetchingNextPage && ( -
    -
    +
    +
    )} {!results.length && @@ -400,12 +409,12 @@ const ComboboxImpl = ( ))} {!results.length && onCreateOption && ( - + @@ -416,7 +425,7 @@ const ComboboxImpl = ( )} - ) -} + ); +}; -export const Combobox = genericForwardRef(ComboboxImpl) +export const Combobox = genericForwardRef(ComboboxImpl); diff --git a/src/components/inputs/combobox/index.ts b/src/components/inputs/combobox/index.ts index abd73dd0..1be314de 100644 --- a/src/components/inputs/combobox/index.ts +++ b/src/components/inputs/combobox/index.ts @@ -1 +1 @@ -export * from "./combobox" +export * from "./combobox"; From 3b24640226b36bb6d591b5383046d44a46f43f04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 22:38:46 +0200 Subject: [PATCH 051/195] eslint/prettier - fix components/inputs/country-select --- .../inputs/country-select/country-select.tsx | 37 +++++++++---------- src/components/inputs/country-select/index.ts | 2 +- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/components/inputs/country-select/country-select.tsx b/src/components/inputs/country-select/country-select.tsx index 07d8904c..915079cf 100644 --- a/src/components/inputs/country-select/country-select.tsx +++ b/src/components/inputs/country-select/country-select.tsx @@ -1,26 +1,25 @@ -import { - ComponentPropsWithoutRef, - forwardRef, - useImperativeHandle, - useRef, -} from "react" -import { useTranslation } from "react-i18next" -import { countries } from "../../../lib/data/countries" -import { Select } from "@medusajs/ui" +import type { ComponentPropsWithoutRef } from "react"; +import { forwardRef, useImperativeHandle, useRef } from "react"; + +import { Select } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; + +import { countries } from "@lib/data/countries"; export const CountrySelect = forwardRef< HTMLButtonElement, ComponentPropsWithoutRef & { - placeholder?: string - defaultValue?: string - onChange?: (value: string) => void + placeholder?: string; + defaultValue?: string; + onChange?: (value: string) => void; } >(({ disabled, placeholder, defaultValue, onChange, ...field }, ref) => { - const { t } = useTranslation() - const innerRef = useRef(null) + const { t } = useTranslation(); + const innerRef = useRef(null); + + useImperativeHandle(ref, () => innerRef.current as HTMLButtonElement); - useImperativeHandle(ref, () => innerRef.current as HTMLButtonElement) - return (
    - ) -}) + ); +}); -CountrySelect.displayName = "CountrySelect" +CountrySelect.displayName = "CountrySelect"; diff --git a/src/components/inputs/country-select/index.ts b/src/components/inputs/country-select/index.ts index 4e19e8a7..8a01107a 100644 --- a/src/components/inputs/country-select/index.ts +++ b/src/components/inputs/country-select/index.ts @@ -1 +1 @@ -export * from "./country-select" +export * from "./country-select"; From 0aa3d14d5c70b03225ec3ec16842ea01b3396f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 22:39:17 +0200 Subject: [PATCH 052/195] eslint/prettier - fix components/inputs/country/handle-input --- .../inputs/handle-input/handle-input.tsx | 38 +++++++++---------- src/components/inputs/handle-input/index.ts | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/components/inputs/handle-input/handle-input.tsx b/src/components/inputs/handle-input/handle-input.tsx index 78f22f80..15135803 100644 --- a/src/components/inputs/handle-input/handle-input.tsx +++ b/src/components/inputs/handle-input/handle-input.tsx @@ -1,24 +1,24 @@ -import { Input, Text } from "@medusajs/ui" -import { ComponentProps, ElementRef, forwardRef } from "react" +import type { ComponentProps, ElementRef } from "react"; +import { forwardRef } from "react"; + +import { Input, Text } from "@medusajs/ui"; export const HandleInput = forwardRef< ElementRef, ComponentProps ->((props, ref) => { - return ( -
    -
    - - / - -
    - +>((props, ref) => ( +
    +
    + + / +
    - ) -}) -HandleInput.displayName = "HandleInput" + +
    +)); +HandleInput.displayName = "HandleInput"; diff --git a/src/components/inputs/handle-input/index.ts b/src/components/inputs/handle-input/index.ts index ed461fed..5007a373 100644 --- a/src/components/inputs/handle-input/index.ts +++ b/src/components/inputs/handle-input/index.ts @@ -1 +1 @@ -export * from "./handle-input" +export * from "./handle-input"; From f38ad5aa4b26559dd59ffd0507d2fd0222f825c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 22:47:59 +0200 Subject: [PATCH 053/195] eslint/prettier - fix components/inputs/country/percentage-input --- .../inputs/percentage-input/index.ts | 2 +- .../percentage-input/percentage-input.tsx | 73 ++++++++++--------- 2 files changed, 40 insertions(+), 35 deletions(-) diff --git a/src/components/inputs/percentage-input/index.ts b/src/components/inputs/percentage-input/index.ts index 69f623aa..57e17393 100644 --- a/src/components/inputs/percentage-input/index.ts +++ b/src/components/inputs/percentage-input/index.ts @@ -1 +1 @@ -export * from "./percentage-input" +export * from "./percentage-input"; diff --git a/src/components/inputs/percentage-input/percentage-input.tsx b/src/components/inputs/percentage-input/percentage-input.tsx index aa7e544d..b21a67cb 100644 --- a/src/components/inputs/percentage-input/percentage-input.tsx +++ b/src/components/inputs/percentage-input/percentage-input.tsx @@ -1,50 +1,53 @@ -import { clx, Input, Text } from "@medusajs/ui"; -import { getNumberOfDecimalPlaces } from "../../../lib/number-helpers"; -import { ComponentProps, ElementRef, forwardRef } from "react"; +import type { ComponentProps, ElementRef } from "react"; +import { forwardRef } from "react"; + +import { Input, Text, clx } from "@medusajs/ui"; + import Primitive from "react-currency-input-field"; +import { getNumberOfDecimalPlaces } from "@lib/number-helpers"; + const MIN_DECIMAL_SCALE = 2; function resolveDecimalScale( - value: string | readonly string[] | number | undefined | null + value: string | readonly string[] | number | undefined | null, ): number | undefined { if (value == null || Array.isArray(value)) { return MIN_DECIMAL_SCALE; } + return Math.max( getNumberOfDecimalPlaces(parseFloat(value.toString())), - MIN_DECIMAL_SCALE + MIN_DECIMAL_SCALE, ); } export const DeprecatedPercentageInput = forwardRef< ElementRef, Omit, "type"> ->(({ min = 0, max = 100, step = 0.0001, ...props }, ref) => { - return ( -
    -
    - - % - -
    - +>(({ min = 0, max = 100, step = 0.0001, ...props }, ref) => ( +
    +
    + + % +
    - ); -}); + +
    +)); DeprecatedPercentageInput.displayName = "PercentageInput"; export const PercentageInput = forwardRef< @@ -61,7 +64,7 @@ export const PercentageInput = forwardRef< className, ...props }, - ref + ref, ) => { const resolvedDecimalScale = decimalScale ?? resolveDecimalScale(value); const resolvedDecimalsLimit = decimalsLimit ?? resolvedDecimalScale; @@ -69,6 +72,8 @@ export const PercentageInput = forwardRef< return (
    @@ -100,6 +105,6 @@ export const PercentageInput = forwardRef<
    ); - } + }, ); PercentageInput.displayName = "PercentageInput"; From 986470adec217b1d7b70da03bec27ac5d17b074c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Sun, 19 Oct 2025 22:48:51 +0200 Subject: [PATCH 054/195] eslint/prettier - fix components/inputs/country/province-input --- .../inputs/province-select/index.ts | 2 +- .../province-select/province-select.tsx | 55 +++++++++---------- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/components/inputs/province-select/index.ts b/src/components/inputs/province-select/index.ts index f1baa16a..9791dc50 100644 --- a/src/components/inputs/province-select/index.ts +++ b/src/components/inputs/province-select/index.ts @@ -1 +1 @@ -export * from "./province-select" +export * from "./province-select"; diff --git a/src/components/inputs/province-select/province-select.tsx b/src/components/inputs/province-select/province-select.tsx index d1c60d95..2440d66e 100644 --- a/src/components/inputs/province-select/province-select.tsx +++ b/src/components/inputs/province-select/province-select.tsx @@ -1,21 +1,20 @@ -import { - ComponentPropsWithoutRef, - forwardRef, - useImperativeHandle, - useRef, -} from "react" -import { Select } from "@medusajs/ui" -import { useTranslation } from "react-i18next" -import { getCountryProvinceObjectByIso2 } from "../../../lib/data/country-states" +import type { ComponentPropsWithoutRef } from "react"; +import { forwardRef, useImperativeHandle, useRef } from "react"; + +import { Select } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; + +import { getCountryProvinceObjectByIso2 } from "@lib/data/country-states"; export const ProvinceSelect = forwardRef< HTMLButtonElement, ComponentPropsWithoutRef & { - placeholder?: string - defaultValue?: string - country_code: string - valueAs?: "iso_2" | "name" - onChange?: (value: string) => void + placeholder?: string; + defaultValue?: string; + country_code: string; + valueAs?: "iso_2" | "name"; + onChange?: (value: string) => void; } >( ( @@ -28,17 +27,17 @@ export const ProvinceSelect = forwardRef< onChange, ...field }, - ref + ref, ) => { - const { t } = useTranslation() - const innerRef = useRef(null) + const { t } = useTranslation(); + const innerRef = useRef(null); - useImperativeHandle(ref, () => innerRef.current as HTMLButtonElement) + useImperativeHandle(ref, () => innerRef.current as HTMLButtonElement); - const provinceObject = getCountryProvinceObjectByIso2(country_code) + const provinceObject = getCountryProvinceObjectByIso2(country_code); if (!provinceObject) { - disabled = true + disabled = true; } const options = Object.entries(provinceObject?.options ?? {}).map( @@ -50,13 +49,13 @@ export const ProvinceSelect = forwardRef< > {name} - ) - } - ) + ); + }, + ); const placeholderText = provinceObject ? t(`taxRegions.fields.sublevels.placeholders.${provinceObject.type}`) - : "" + : ""; return (
    @@ -85,7 +84,7 @@ export const ProvinceSelect = forwardRef< {options}
    - ) - } -) -ProvinceSelect.displayName = "ProvinceSelect" + ); + }, +); +ProvinceSelect.displayName = "ProvinceSelect"; From dc7032fa04ccf3c3b992933cf67ed6a433e03fb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Mon, 20 Oct 2025 08:44:52 +0200 Subject: [PATCH 055/195] eslint/prettier - fix components/layout/main-layout --- src/components/layout/main-layout/index.ts | 2 +- .../layout/main-layout/main-layout.tsx | 107 +++++++++--------- 2 files changed, 53 insertions(+), 56 deletions(-) diff --git a/src/components/layout/main-layout/index.ts b/src/components/layout/main-layout/index.ts index 035d09e6..b816f0d4 100644 --- a/src/components/layout/main-layout/index.ts +++ b/src/components/layout/main-layout/index.ts @@ -1 +1 @@ -export * from "./main-layout" +export * from "./main-layout"; diff --git a/src/components/layout/main-layout/main-layout.tsx b/src/components/layout/main-layout/main-layout.tsx index 5480df70..6ea99829 100644 --- a/src/components/layout/main-layout/main-layout.tsx +++ b/src/components/layout/main-layout/main-layout.tsx @@ -18,54 +18,53 @@ import { Users, } from "@medusajs/icons"; import { Avatar, Divider, DropdownMenu, Text, clx } from "@medusajs/ui"; + import { Collapsible as RadixCollapsible } from "radix-ui"; import { useTranslation } from "react-i18next"; +import { Link, useLocation, useNavigate } from "react-router-dom"; -import { useStore } from "../../../hooks/api/store"; -import { Skeleton } from "../../common/skeleton"; -import { INavItem, NavItem } from "../../layout/nav-item"; -import { Shell } from "../../layout/shell"; +import { Skeleton } from "@components/common/skeleton"; +import type { INavItem } from "@components/layout/nav-item"; +import { NavItem } from "@components/layout/nav-item"; +import { Shell } from "@components/layout/shell"; +import { UserMenu } from "@components/layout/user-menu"; -import { Link, useLocation, useNavigate } from "react-router-dom"; -import { useLogout } from "../../../hooks/api"; -import { queryClient } from "../../../lib/query-client"; -import { useExtension } from "../../../providers/extension-provider"; -import { useSearch } from "../../../providers/search-provider"; -import { UserMenu } from "../user-menu"; -import { useDocumentDirection } from "../../../hooks/use-document-direction"; +import { useLogout, useStore } from "@hooks/api"; +import { useDocumentDirection } from "@hooks/use-document-direction.tsx"; -export const MainLayout = () => { - return ( - - - - ); -}; +import { queryClient } from "@lib/query-client"; -const MainSidebar = () => { - return ( - +); const Logout = () => { const { t } = useTranslation(); @@ -114,10 +113,10 @@ const Header = () => { {fallback ? ( @@ -188,7 +187,7 @@ const useCoreRoutes = (): Omit[] => { label: t("orders.domain"), to: "/orders", items: [ - // TODO: Enable when domin is introduced + // TODO: Enable when domain is introduced // { // label: t("draftOrders.domain"), // to: "/draft-orders", @@ -208,7 +207,7 @@ const useCoreRoutes = (): Omit[] => { label: t("categories.domain"), to: "/categories", }, - // TODO: Enable when domin is introduced + // TODO: Enable when domain is introduced // { // label: t("giftCards.domain"), // to: "/gift-cards", @@ -318,9 +317,9 @@ const Searchbar = () => { - ) + ); } if (isError) { - throw error + throw error; } return ( @@ -111,10 +115,10 @@ const UserBadge = () => {
    @@ -141,26 +145,31 @@ const UserBadge = () => {
    - ) -} + ); +}; const ThemeToggle = () => { - const { t } = useTranslation() - const { theme, setTheme } = useTheme() + const { t } = useTranslation(); + const { theme, setTheme } = useTheme(); return ( - - - {t("app.menus.user.theme.label")} + + + + {t("app.menus.user.theme.label")} + { - e.preventDefault() - setTheme("system") + e.preventDefault(); + setTheme("system"); }} > {t("app.menus.user.theme.system")} @@ -168,8 +177,8 @@ const ThemeToggle = () => { { - e.preventDefault() - setTheme("light") + e.preventDefault(); + setTheme("light"); }} > {t("app.menus.user.theme.light")} @@ -177,8 +186,8 @@ const ThemeToggle = () => { { - e.preventDefault() - setTheme("dark") + e.preventDefault(); + setTheme("dark"); }} > {t("app.menus.user.theme.dark")} @@ -186,14 +195,14 @@ const ThemeToggle = () => { - ) -} + ); +}; const Logout = () => { - const { t } = useTranslation() - const navigate = useNavigate() + const { t } = useTranslation(); + const navigate = useNavigate(); - const { mutateAsync: logoutMutation } = useLogout() + const { mutateAsync: logoutMutation } = useLogout(); const handleLogout = async () => { await logoutMutation(undefined, { @@ -201,11 +210,11 @@ const Logout = () => { /** * When the user logs out, we want to clear the query cache */ - queryClient.clear() - navigate("/login") + queryClient.clear(); + navigate("/login"); }, - }) - } + }); + }; return ( @@ -214,29 +223,31 @@ const Logout = () => { {t("app.menus.actions.logout")}
    - ) -} + ); +}; const GlobalKeybindsModal = (props: { - open: boolean - onOpenChange: (open: boolean) => void + open: boolean; + onOpenChange: (open: boolean) => void; }) => { - const { t } = useTranslation() - const globalShortcuts = useGlobalShortcuts() + const { t } = useTranslation(); + const globalShortcuts = useGlobalShortcuts(); - const [searchValue, onSearchValueChange] = useState("") + const [searchValue, onSearchValueChange] = useState(""); const searchResults = searchValue ? globalShortcuts.filter((shortcut) => { - return shortcut.label.toLowerCase().includes(searchValue?.toLowerCase()) + return shortcut.label + .toLowerCase() + .includes(searchValue?.toLowerCase()); }) - : globalShortcuts + : globalShortcuts; return ( - - + +
    @@ -263,53 +274,49 @@ const GlobalKeybindsModal = (props: {
    - {searchResults.map((shortcut, index) => { - return ( -
    - {shortcut.label} -
    - {shortcut.keys.Mac?.map((key, index) => { - return ( -
    - {key} - {index < (shortcut.keys.Mac?.length || 0) - 1 && ( - - {t("app.keyboardShortcuts.then")} - - )} -
    - ) - })} -
    + {searchResults.map((shortcut, index) => ( +
    + {shortcut.label} +
    + {shortcut.keys.Mac?.map((key, index) => ( +
    + {key} + {index < (shortcut.keys.Mac?.length || 0) - 1 && ( + + {t("app.keyboardShortcuts.then")} + + )} +
    + ))}
    - ) - })} +
    + ))}
    - ) -} + ); +}; const UserItem = () => { - const { user, isPending, isError, error } = useMe() + const { user, isPending, isError, error } = useMe(); - const loaded = !isPending && !!user + const loaded = !isPending && !!user; if (!loaded) { - return
    + return
    ; } - const name = [user.first_name, user.last_name].filter(Boolean).join(" ") - const email = user.email - const fallback = name ? name[0].toUpperCase() : email[0].toUpperCase() - const avatar = user.avatar_url + const name = [user.first_name, user.last_name].filter(Boolean).join(" "); + const email = user.email; + const fallback = name ? name[0].toUpperCase() : email[0].toUpperCase(); + const avatar = user.avatar_url; if (isError) { - throw error + throw error; } return ( @@ -333,12 +340,12 @@ const UserItem = () => { {email} )}
    - ) -} + ); +}; From 3bb95338a23f8b3804117a6f0fe3d1ea609cb659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Mon, 20 Oct 2025 09:05:16 +0200 Subject: [PATCH 065/195] eslint/prettier - fix components/localization --- .../localized-table-pagination/index.ts | 2 +- .../localized-table-pagination.tsx | 21 +++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/components/localization/localized-table-pagination/index.ts b/src/components/localization/localized-table-pagination/index.ts index 40d1ccdf..c9864f2b 100644 --- a/src/components/localization/localized-table-pagination/index.ts +++ b/src/components/localization/localized-table-pagination/index.ts @@ -1 +1 @@ -export * from "./localized-table-pagination" +export * from "./localized-table-pagination"; diff --git a/src/components/localization/localized-table-pagination/localized-table-pagination.tsx b/src/components/localization/localized-table-pagination/localized-table-pagination.tsx index 8ec8a469..a09ae122 100644 --- a/src/components/localization/localized-table-pagination/localized-table-pagination.tsx +++ b/src/components/localization/localized-table-pagination/localized-table-pagination.tsx @@ -1,17 +1,20 @@ -import { Table } from "@medusajs/ui" -import { ComponentPropsWithoutRef, ElementRef, forwardRef } from "react" -import { useTranslation } from "react-i18next" +import type { ComponentPropsWithoutRef, ElementRef } from "react"; +import { forwardRef } from "react"; + +import { Table } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; type LocalizedTablePaginationProps = Omit< ComponentPropsWithoutRef, "translations" -> +>; export const LocalizedTablePagination = forwardRef< ElementRef, LocalizedTablePaginationProps >((props, ref) => { - const { t } = useTranslation() + const { t } = useTranslation(); const translations = { of: t("general.of"), @@ -19,8 +22,8 @@ export const LocalizedTablePagination = forwardRef< pages: t("general.pages"), prev: t("general.prev"), next: t("general.next"), - } + }; - return -}) -LocalizedTablePagination.displayName = "LocalizedTablePagination" + return ; +}); +LocalizedTablePagination.displayName = "LocalizedTablePagination"; From c292d660c674a6b7adb0d015ebd9d7c01a2e3d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Mon, 20 Oct 2025 09:05:55 +0200 Subject: [PATCH 066/195] eslint/prettier - fix components/modals/hooks --- .../modals/hooks/use-state-aware-to.tsx | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/components/modals/hooks/use-state-aware-to.tsx b/src/components/modals/hooks/use-state-aware-to.tsx index 83818902..817d8434 100644 --- a/src/components/modals/hooks/use-state-aware-to.tsx +++ b/src/components/modals/hooks/use-state-aware-to.tsx @@ -1,5 +1,7 @@ -import { useMemo } from "react" -import { Path, useLocation } from "react-router-dom" +import { useMemo } from "react"; + +import type { Path } from "react-router-dom"; +import { useLocation } from "react-router-dom"; /** * Checks if the current location has a restore_params property. @@ -11,22 +13,20 @@ import { Path, useLocation } from "react-router-dom" * the params that were present when the modal was opened. */ export const useStateAwareTo = (prev: string | Partial) => { - const location = useLocation() + const location = useLocation(); - const to = useMemo(() => { - const params = location.state?.restore_params + return useMemo(() => { + const params = location.state?.restore_params; if (params) { - return `${prev}?${params.toString()}` + return `${prev}?${params.toString()}`; } // If no restore_params in state, check if the current URL has search params if (location.search) { - return `${prev}${location.search}` + return `${prev}${location.search}`; } - return prev - }, [location.state, location.search, prev]) - - return to -} + return prev; + }, [location.state, location.search, prev]); +}; From 85f2df51b2d7475bb2bf2164d21c21d3f3b1e8ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Mon, 20 Oct 2025 09:08:46 +0200 Subject: [PATCH 067/195] eslint/prettier - fix components/modals/route-drawer --- src/components/modals/route-drawer/index.ts | 2 +- .../modals/route-drawer/route-drawer.tsx | 74 ++++++++++--------- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/src/components/modals/route-drawer/index.ts b/src/components/modals/route-drawer/index.ts index 82f4bb96..c867291d 100644 --- a/src/components/modals/route-drawer/index.ts +++ b/src/components/modals/route-drawer/index.ts @@ -1 +1 @@ -export * from "./route-drawer" +export * from "./route-drawer"; diff --git a/src/components/modals/route-drawer/route-drawer.tsx b/src/components/modals/route-drawer/route-drawer.tsx index 3de85342..4895c5ed 100644 --- a/src/components/modals/route-drawer/route-drawer.tsx +++ b/src/components/modals/route-drawer/route-drawer.tsx @@ -1,44 +1,50 @@ -import { Drawer, clx } from "@medusajs/ui" -import { PropsWithChildren, useEffect, useState } from "react" -import { Path, useNavigate } from "react-router-dom" -import { useStateAwareTo } from "../hooks/use-state-aware-to" -import { RouteModalForm } from "../route-modal-form" -import { RouteModalProvider } from "../route-modal-provider/route-provider" -import { StackedModalProvider } from "../stacked-modal-provider" +import type { PropsWithChildren } from "react"; +import { useEffect, useState } from "react"; + +import { Drawer, clx } from "@medusajs/ui"; + +import type { Path } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; + +import { useStateAwareTo } from "@components/modals/hooks/use-state-aware-to"; +import { RouteModalForm } from "@components/modals/route-modal-form"; +import { RouteModalProvider } from "@components/modals/route-modal-provider/route-provider"; +import { StackedModalProvider } from "@components/modals/stacked-modal-provider"; type RouteDrawerProps = PropsWithChildren<{ - prev?: string | Partial -}> + prev?: string | Partial; +}>; const Root = ({ prev = "..", children }: RouteDrawerProps) => { - const navigate = useNavigate() - const [open, setOpen] = useState(false) - const [stackedModalOpen, onStackedModalOpen] = useState(false) + const navigate = useNavigate(); + const [open, setOpen] = useState(false); + const [stackedModalOpen, onStackedModalOpen] = useState(false); - const to = useStateAwareTo(prev) + const to = useStateAwareTo(prev); /** * Open the modal when the component mounts. This * ensures that the entry animation is played. */ useEffect(() => { - setOpen(true) + setOpen(true); return () => { - setOpen(false) - onStackedModalOpen(false) - } - }, []) + setOpen(false); + onStackedModalOpen(false); + }; + }, []); const handleOpenChange = (open: boolean) => { if (!open) { - document.body.style.pointerEvents = "auto" - navigate(to, { replace: true }) - return + document.body.style.pointerEvents = "auto"; + navigate(to, { replace: true }); + + return; } - setOpen(open) - } + setOpen(open); + }; return ( @@ -47,7 +53,7 @@ const Root = ({ prev = "..", children }: RouteDrawerProps) => { {children} @@ -55,16 +61,16 @@ const Root = ({ prev = "..", children }: RouteDrawerProps) => { - ) -} + ); +}; -const Header = Drawer.Header -const Title = Drawer.Title -const Description = Drawer.Description -const Body = Drawer.Body -const Footer = Drawer.Footer -const Close = Drawer.Close -const Form = RouteModalForm +const Header = Drawer.Header; +const Title = Drawer.Title; +const Description = Drawer.Description; +const Body = Drawer.Body; +const Footer = Drawer.Footer; +const Close = Drawer.Close; +const Form = RouteModalForm; /** * Drawer that is used to render a form on a separate route. @@ -79,4 +85,4 @@ export const RouteDrawer = Object.assign(Root, { Footer, Close, Form, -}) +}); From 180d1fac274de4d00953e0dccd8d45292257caa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Mon, 20 Oct 2025 09:25:27 +0200 Subject: [PATCH 068/195] eslint/prettier - fix components/modals/route-focus-modal --- .../modals/route-focus-modal/index.ts | 2 +- .../route-focus-modal/route-focus-modal.tsx | 90 ++++++++++--------- 2 files changed, 49 insertions(+), 43 deletions(-) diff --git a/src/components/modals/route-focus-modal/index.ts b/src/components/modals/route-focus-modal/index.ts index 764e6c80..9fa42abd 100644 --- a/src/components/modals/route-focus-modal/index.ts +++ b/src/components/modals/route-focus-modal/index.ts @@ -1 +1 @@ -export * from "./route-focus-modal" +export * from "./route-focus-modal"; diff --git a/src/components/modals/route-focus-modal/route-focus-modal.tsx b/src/components/modals/route-focus-modal/route-focus-modal.tsx index 4ee7b0e0..f508e4c3 100644 --- a/src/components/modals/route-focus-modal/route-focus-modal.tsx +++ b/src/components/modals/route-focus-modal/route-focus-modal.tsx @@ -1,45 +1,51 @@ -import { FocusModal, clx } from "@medusajs/ui" -import { PropsWithChildren, useEffect, useState } from "react" -import { Path, useNavigate } from "react-router-dom" -import { useStateAwareTo } from "../hooks/use-state-aware-to" -import { RouteModalForm } from "../route-modal-form" -import { useRouteModal } from "../route-modal-provider" -import { RouteModalProvider } from "../route-modal-provider/route-provider" -import { StackedModalProvider } from "../stacked-modal-provider" +import type { PropsWithChildren } from "react"; +import { useEffect, useState } from "react"; + +import { FocusModal, clx } from "@medusajs/ui"; + +import type { Path } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; + +import { useStateAwareTo } from "@components/modals/hooks/use-state-aware-to"; +import { RouteModalForm } from "@components/modals/route-modal-form"; +import { useRouteModal } from "@components/modals/route-modal-provider"; +import { RouteModalProvider } from "@components/modals/route-modal-provider/route-provider"; +import { StackedModalProvider } from "@components/modals/stacked-modal-provider"; type RouteFocusModalProps = PropsWithChildren<{ - prev?: string | Partial -}> + prev?: string | Partial; +}>; const Root = ({ prev = "..", children }: RouteFocusModalProps) => { - const navigate = useNavigate() - const [open, setOpen] = useState(false) - const [stackedModalOpen, onStackedModalOpen] = useState(false) + const navigate = useNavigate(); + const [open, setOpen] = useState(false); + const [stackedModalOpen, onStackedModalOpen] = useState(false); - const to = useStateAwareTo(prev) + const to = useStateAwareTo(prev); /** * Open the modal when the component mounts. This * ensures that the entry animation is played. */ useEffect(() => { - setOpen(true) + setOpen(true); return () => { - setOpen(false) - onStackedModalOpen(false) - } - }, []) + setOpen(false); + onStackedModalOpen(false); + }; + }, []); const handleOpenChange = (open: boolean) => { if (!open) { - document.body.style.pointerEvents = "auto" - navigate(to, { replace: true }) - return + document.body.style.pointerEvents = "auto"; + navigate(to, { replace: true }); + + return; } - setOpen(open) - } + setOpen(open); + }; return ( @@ -49,43 +55,43 @@ const Root = ({ prev = "..", children }: RouteFocusModalProps) => { - ) -} + ); +}; type ContentProps = PropsWithChildren<{ - stackedModalOpen: boolean -}> + stackedModalOpen: boolean; +}>; const Content = ({ stackedModalOpen, children }: ContentProps) => { - const { __internal } = useRouteModal() + const { __internal } = useRouteModal(); - const shouldPreventClose = !__internal.closeOnEscape + const shouldPreventClose = !__internal.closeOnEscape; return ( { - e.preventDefault() + e.preventDefault(); } : undefined } className={clx({ - "!bg-ui-bg-disabled !inset-x-5 !inset-y-3": stackedModalOpen, + "!inset-x-5 !inset-y-3 !bg-ui-bg-disabled": stackedModalOpen, })} > {children} - ) -} + ); +}; -const Header = FocusModal.Header -const Title = FocusModal.Title -const Description = FocusModal.Description -const Footer = FocusModal.Footer -const Body = FocusModal.Body -const Close = FocusModal.Close -const Form = RouteModalForm +const Header = FocusModal.Header; +const Title = FocusModal.Title; +const Description = FocusModal.Description; +const Footer = FocusModal.Footer; +const Body = FocusModal.Body; +const Close = FocusModal.Close; +const Form = RouteModalForm; /** * FocusModal that is used to render a form on a separate route. @@ -101,4 +107,4 @@ export const RouteFocusModal = Object.assign(Root, { Footer, Close, Form, -}) +}); From 13ddfa54f28c481f9de00c163dc63250e7986b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Mon, 20 Oct 2025 09:26:04 +0200 Subject: [PATCH 069/195] eslint/prettier - fix components/modals/route-modal-form --- .../modals/route-modal-form/index.ts | 2 +- .../route-modal-form/route-modal-form.tsx | 66 ++++++++++--------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/src/components/modals/route-modal-form/index.ts b/src/components/modals/route-modal-form/index.ts index 0e1450ed..eb36ca7f 100644 --- a/src/components/modals/route-modal-form/index.ts +++ b/src/components/modals/route-modal-form/index.ts @@ -1 +1 @@ -export * from "./route-modal-form" +export * from "./route-modal-form"; diff --git a/src/components/modals/route-modal-form/route-modal-form.tsx b/src/components/modals/route-modal-form/route-modal-form.tsx index 4328f9f4..2eb73a85 100644 --- a/src/components/modals/route-modal-form/route-modal-form.tsx +++ b/src/components/modals/route-modal-form/route-modal-form.tsx @@ -1,15 +1,18 @@ -import { Prompt } from "@medusajs/ui" -import { PropsWithChildren } from "react" -import { FieldValues, UseFormReturn } from "react-hook-form" -import { useTranslation } from "react-i18next" -import { useBlocker } from "react-router-dom" -import { Form } from "../../common/form" +import type { PropsWithChildren } from "react"; + +import { Prompt } from "@medusajs/ui"; + +import type { FieldValues, UseFormReturn } from "react-hook-form"; +import { useTranslation } from "react-i18next"; +import { useBlocker } from "react-router-dom"; + +import { Form } from "@components/common/form"; type RouteModalFormProps = PropsWithChildren<{ - form: UseFormReturn - blockSearchParams?: boolean - onClose?: (isSubmitSuccessful: boolean) => void -}> + form: UseFormReturn; + blockSearchParams?: boolean; + onClose?: (isSubmitSuccessful: boolean) => void; +}>; export const RouteModalForm = ({ form, @@ -17,50 +20,51 @@ export const RouteModalForm = ({ children, onClose, }: RouteModalFormProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); const { formState: { isDirty }, - } = form + } = form; const blocker = useBlocker(({ currentLocation, nextLocation }) => { - const { isSubmitSuccessful } = nextLocation.state || {} + const { isSubmitSuccessful } = nextLocation.state || {}; if (isSubmitSuccessful) { - onClose?.(true) - return false + onClose?.(true); + + return false; } - const isPathChanged = currentLocation.pathname !== nextLocation.pathname - const isSearchChanged = currentLocation.search !== nextLocation.search + const isPathChanged = currentLocation.pathname !== nextLocation.pathname; + const isSearchChanged = currentLocation.search !== nextLocation.search; if (blockSearch) { - const shouldBlock = isDirty && (isPathChanged || isSearchChanged) + const shouldBlock = isDirty && (isPathChanged || isSearchChanged); if (isPathChanged) { - onClose?.(isSubmitSuccessful) + onClose?.(isSubmitSuccessful); } - return shouldBlock + return shouldBlock; } - const shouldBlock = isDirty && isPathChanged + const shouldBlock = isDirty && isPathChanged; if (isPathChanged) { - onClose?.(isSubmitSuccessful) + onClose?.(isSubmitSuccessful); } - return shouldBlock - }) + return shouldBlock; + }); const handleCancel = () => { - blocker?.reset?.() - } + blocker?.reset?.(); + }; const handleContinue = () => { - blocker?.proceed?.() - onClose?.(false) - } + blocker?.proceed?.(); + onClose?.(false); + }; return (
    @@ -84,5 +88,5 @@ export const RouteModalForm = ({ - ) -} + ); +}; From 3b360899fa160088da6be02a615f3658cd7e289c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Mon, 20 Oct 2025 09:26:44 +0200 Subject: [PATCH 070/195] eslint/prettier - fix components/modals/route-modal-provider --- .../modals/route-modal-provider/index.ts | 4 +-- .../route-modal-context.tsx | 14 ++++---- .../route-modal-provider/route-provider.tsx | 34 +++++++++++-------- .../route-modal-provider/use-route-modal.tsx | 13 +++---- 4 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/components/modals/route-modal-provider/index.ts b/src/components/modals/route-modal-provider/index.ts index f819a019..09d6e7b3 100644 --- a/src/components/modals/route-modal-provider/index.ts +++ b/src/components/modals/route-modal-provider/index.ts @@ -1,2 +1,2 @@ -export * from "./route-provider" -export * from "./use-route-modal" +export * from "./route-provider"; +export * from "./use-route-modal"; diff --git a/src/components/modals/route-modal-provider/route-modal-context.tsx b/src/components/modals/route-modal-provider/route-modal-context.tsx index 95a5aae5..fe8a0614 100644 --- a/src/components/modals/route-modal-provider/route-modal-context.tsx +++ b/src/components/modals/route-modal-provider/route-modal-context.tsx @@ -1,12 +1,12 @@ -import { createContext } from "react" +import { createContext } from "react"; type RouteModalProviderState = { - handleSuccess: (path?: string) => void - setCloseOnEscape: (value: boolean) => void + handleSuccess: (path?: string) => void; + setCloseOnEscape: (value: boolean) => void; __internal: { - closeOnEscape: boolean - } -} + closeOnEscape: boolean; + }; +}; export const RouteModalProviderContext = - createContext(null) + createContext(null); diff --git a/src/components/modals/route-modal-provider/route-provider.tsx b/src/components/modals/route-modal-provider/route-provider.tsx index 44e51398..cacda4f0 100644 --- a/src/components/modals/route-modal-provider/route-provider.tsx +++ b/src/components/modals/route-modal-provider/route-provider.tsx @@ -1,26 +1,30 @@ -import { PropsWithChildren, useCallback, useMemo, useState } from "react" -import { Path, useNavigate } from "react-router-dom" -import { RouteModalProviderContext } from "./route-modal-context" +import type { PropsWithChildren } from "react"; +import { useCallback, useMemo, useState } from "react"; + +import type { Path } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; + +import { RouteModalProviderContext } from "./route-modal-context"; type RouteModalProviderProps = PropsWithChildren<{ - prev: string | Partial -}> + prev: string | Partial; +}>; export const RouteModalProvider = ({ prev, children, }: RouteModalProviderProps) => { - const navigate = useNavigate() + const navigate = useNavigate(); - const [closeOnEscape, setCloseOnEscape] = useState(true) + const [closeOnEscape, setCloseOnEscape] = useState(true); const handleSuccess = useCallback( (path?: string) => { - const to = path || prev - navigate(to, { replace: true, state: { isSubmitSuccessful: true } }) + const to = path || prev; + navigate(to, { replace: true, state: { isSubmitSuccessful: true } }); }, - [navigate, prev] - ) + [navigate, prev], + ); const value = useMemo( () => ({ @@ -28,12 +32,12 @@ export const RouteModalProvider = ({ setCloseOnEscape, __internal: { closeOnEscape }, }), - [handleSuccess, setCloseOnEscape, closeOnEscape] - ) + [handleSuccess, setCloseOnEscape, closeOnEscape], + ); return ( {children} - ) -} + ); +}; diff --git a/src/components/modals/route-modal-provider/use-route-modal.tsx b/src/components/modals/route-modal-provider/use-route-modal.tsx index 04dad573..83b7c349 100644 --- a/src/components/modals/route-modal-provider/use-route-modal.tsx +++ b/src/components/modals/route-modal-provider/use-route-modal.tsx @@ -1,12 +1,13 @@ -import { useContext } from "react" -import { RouteModalProviderContext } from "./route-modal-context" +import { useContext } from "react"; + +import { RouteModalProviderContext } from "./route-modal-context"; export const useRouteModal = () => { - const context = useContext(RouteModalProviderContext) + const context = useContext(RouteModalProviderContext); if (!context) { - throw new Error("useRouteModal must be used within a RouteModalProvider") + throw new Error("useRouteModal must be used within a RouteModalProvider"); } - return context -} + return context; +}; From 37a5176d40f517ac4d3ba1301db665a42a747937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Mon, 20 Oct 2025 09:52:33 +0200 Subject: [PATCH 071/195] eslint/prettier - fix components/modals/stacked-drawer --- src/components/modals/stacked-drawer/index.ts | 2 +- .../modals/stacked-drawer/stacked-drawer.tsx | 67 +++++++++---------- 2 files changed, 33 insertions(+), 36 deletions(-) diff --git a/src/components/modals/stacked-drawer/index.ts b/src/components/modals/stacked-drawer/index.ts index 2467d18d..e229f109 100644 --- a/src/components/modals/stacked-drawer/index.ts +++ b/src/components/modals/stacked-drawer/index.ts @@ -1 +1 @@ -export * from "./stacked-drawer" +export * from "./stacked-drawer"; diff --git a/src/components/modals/stacked-drawer/stacked-drawer.tsx b/src/components/modals/stacked-drawer/stacked-drawer.tsx index 9c3c2091..2b8a6b8e 100644 --- a/src/components/modals/stacked-drawer/stacked-drawer.tsx +++ b/src/components/modals/stacked-drawer/stacked-drawer.tsx @@ -1,60 +1,57 @@ -import { Drawer, clx } from "@medusajs/ui" -import { - ComponentPropsWithoutRef, - PropsWithChildren, - forwardRef, - useEffect, -} from "react" -import { useStackedModal } from "../stacked-modal-provider" +import type { ComponentPropsWithoutRef, PropsWithChildren } from "react"; +import { forwardRef, useEffect } from "react"; + +import { Drawer, clx } from "@medusajs/ui"; + +import { useStackedModal } from "@components/modals/stacked-modal-provider"; type StackedDrawerProps = PropsWithChildren<{ /** * A unique identifier for the modal. This is used to differentiate stacked modals, * when multiple stacked modals are registered to the same parent modal. */ - id: string -}> + id: string; +}>; /** * A stacked modal that can be rendered above a parent modal. */ export const Root = ({ id, children }: StackedDrawerProps) => { - const { register, unregister, getIsOpen, setIsOpen } = useStackedModal() + const { register, unregister, getIsOpen, setIsOpen } = useStackedModal(); useEffect(() => { - register(id) + register(id); - return () => unregister(id) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) + return () => unregister(id); + }, []); return ( setIsOpen(id, open)}> {children} - ) -} + ); +}; -const Close = Drawer.Close -Close.displayName = "StackedDrawer.Close" +const Close = Drawer.Close; +Close.displayName = "StackedDrawer.Close"; -const Header = Drawer.Header -Header.displayName = "StackedDrawer.Header" +const Header = Drawer.Header; +Header.displayName = "StackedDrawer.Header"; -const Body = Drawer.Body -Body.displayName = "StackedDrawer.Body" +const Body = Drawer.Body; +Body.displayName = "StackedDrawer.Body"; -const Trigger = Drawer.Trigger -Trigger.displayName = "StackedDrawer.Trigger" +const Trigger = Drawer.Trigger; +Trigger.displayName = "StackedDrawer.Trigger"; -const Footer = Drawer.Footer -Footer.displayName = "StackedDrawer.Footer" +const Footer = Drawer.Footer; +Footer.displayName = "StackedDrawer.Footer"; -const Title = Drawer.Title -Title.displayName = "StackedDrawer.Title" +const Title = Drawer.Title; +Title.displayName = "StackedDrawer.Title"; -const Description = Drawer.Description -Description.displayName = "StackedDrawer.Description" +const Description = Drawer.Description; +Description.displayName = "StackedDrawer.Description"; const Content = forwardRef< HTMLDivElement, @@ -69,9 +66,9 @@ const Content = forwardRef< }} {...props} /> - ) -}) -Content.displayName = "StackedDrawer.Content" + ); +}); +Content.displayName = "StackedDrawer.Content"; export const StackedDrawer = Object.assign(Root, { Close, @@ -82,4 +79,4 @@ export const StackedDrawer = Object.assign(Root, { Footer, Description, Title, -}) +}); From 6432e7a5b8e4698c7388b654bbad4703bbf667c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Mon, 20 Oct 2025 09:53:30 +0200 Subject: [PATCH 072/195] eslint/prettier - fix components/modals/stacked-modal --- .../modals/stacked-focus-modal/index.ts | 2 +- .../stacked-focus-modal.tsx | 75 +++++++++---------- 2 files changed, 37 insertions(+), 40 deletions(-) diff --git a/src/components/modals/stacked-focus-modal/index.ts b/src/components/modals/stacked-focus-modal/index.ts index e1c50817..09784cb1 100644 --- a/src/components/modals/stacked-focus-modal/index.ts +++ b/src/components/modals/stacked-focus-modal/index.ts @@ -1 +1 @@ -export * from "./stacked-focus-modal" +export * from "./stacked-focus-modal"; diff --git a/src/components/modals/stacked-focus-modal/stacked-focus-modal.tsx b/src/components/modals/stacked-focus-modal/stacked-focus-modal.tsx index 92764504..1d83c676 100644 --- a/src/components/modals/stacked-focus-modal/stacked-focus-modal.tsx +++ b/src/components/modals/stacked-focus-modal/stacked-focus-modal.tsx @@ -1,23 +1,21 @@ -import { FocusModal, clx } from "@medusajs/ui" -import { - ComponentPropsWithoutRef, - PropsWithChildren, - forwardRef, - useEffect, -} from "react" -import { useStackedModal } from "../stacked-modal-provider" +import type { ComponentPropsWithoutRef, PropsWithChildren } from "react"; +import { forwardRef, useEffect } from "react"; + +import { FocusModal, clx } from "@medusajs/ui"; + +import { useStackedModal } from "@components/modals/stacked-modal-provider"; type StackedFocusModalProps = PropsWithChildren<{ /** * A unique identifier for the modal. This is used to differentiate stacked modals, * when multiple stacked modals are registered to the same parent modal. */ - id: string + id: string; /** * An optional callback that is called when the modal is opened or closed. */ - onOpenChangeCallback?: (open: boolean) => void -}> + onOpenChangeCallback?: (open: boolean) => void; +}>; /** * A stacked modal that can be rendered above a parent modal. @@ -27,47 +25,46 @@ export const Root = ({ onOpenChangeCallback, children, }: StackedFocusModalProps) => { - const { register, unregister, getIsOpen, setIsOpen } = useStackedModal() + const { register, unregister, getIsOpen, setIsOpen } = useStackedModal(); useEffect(() => { - register(id) + register(id); - return () => unregister(id) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) + return () => unregister(id); + }, []); const handleOpenChange = (open: boolean) => { - setIsOpen(id, open) - onOpenChangeCallback?.(open) - } + setIsOpen(id, open); + onOpenChangeCallback?.(open); + }; return ( {children} - ) -} + ); +}; -const Close = FocusModal.Close -Close.displayName = "StackedFocusModal.Close" +const Close = FocusModal.Close; +Close.displayName = "StackedFocusModal.Close"; -const Header = FocusModal.Header -Header.displayName = "StackedFocusModal.Header" +const Header = FocusModal.Header; +Header.displayName = "StackedFocusModal.Header"; -const Body = FocusModal.Body -Body.displayName = "StackedFocusModal.Body" +const Body = FocusModal.Body; +Body.displayName = "StackedFocusModal.Body"; -const Trigger = FocusModal.Trigger -Trigger.displayName = "StackedFocusModal.Trigger" +const Trigger = FocusModal.Trigger; +Trigger.displayName = "StackedFocusModal.Trigger"; -const Footer = FocusModal.Footer -Footer.displayName = "StackedFocusModal.Footer" +const Footer = FocusModal.Footer; +Footer.displayName = "StackedFocusModal.Footer"; -const Title = FocusModal.Title -Title.displayName = "StackedFocusModal.Title" +const Title = FocusModal.Title; +Title.displayName = "StackedFocusModal.Title"; -const Description = FocusModal.Description -Description.displayName = "StackedFocusModal.Description" +const Description = FocusModal.Description; +Description.displayName = "StackedFocusModal.Description"; const Content = forwardRef< HTMLDivElement, @@ -82,9 +79,9 @@ const Content = forwardRef< }} {...props} /> - ) -}) -Content.displayName = "StackedFocusModal.Content" + ); +}); +Content.displayName = "StackedFocusModal.Content"; export const StackedFocusModal = Object.assign(Root, { Close, @@ -95,4 +92,4 @@ export const StackedFocusModal = Object.assign(Root, { Footer, Description, Title, -}) +}); From 9815c34ce6d576701978e279ee998683e9c89cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Mon, 20 Oct 2025 09:54:50 +0200 Subject: [PATCH 073/195] eslint/prettier - fix components/modals/stacked-modal-provider --- .../modals/stacked-modal-provider/index.ts | 4 +- .../stacked-modal-context.tsx | 16 ++++---- .../stacked-modal-provider.tsx | 41 ++++++++++--------- .../use-stacked-modal.ts | 15 +++---- 4 files changed, 41 insertions(+), 35 deletions(-) diff --git a/src/components/modals/stacked-modal-provider/index.ts b/src/components/modals/stacked-modal-provider/index.ts index 998c3fba..1f5f02d0 100644 --- a/src/components/modals/stacked-modal-provider/index.ts +++ b/src/components/modals/stacked-modal-provider/index.ts @@ -1,2 +1,2 @@ -export * from "./stacked-modal-provider" -export * from "./use-stacked-modal" +export * from "./stacked-modal-provider"; +export * from "./use-stacked-modal"; diff --git a/src/components/modals/stacked-modal-provider/stacked-modal-context.tsx b/src/components/modals/stacked-modal-provider/stacked-modal-context.tsx index ebd50944..9d86d654 100644 --- a/src/components/modals/stacked-modal-provider/stacked-modal-context.tsx +++ b/src/components/modals/stacked-modal-provider/stacked-modal-context.tsx @@ -1,10 +1,12 @@ -import { createContext } from "react" +import { createContext } from "react"; type StackedModalState = { - getIsOpen: (id: string) => boolean - setIsOpen: (id: string, open: boolean) => void - register: (id: string) => void - unregister: (id: string) => void -} + getIsOpen: (id: string) => boolean; + setIsOpen: (id: string, open: boolean) => void; + register: (id: string) => void; + unregister: (id: string) => void; +}; -export const StackedModalContext = createContext(null) +export const StackedModalContext = createContext( + null, +); diff --git a/src/components/modals/stacked-modal-provider/stacked-modal-provider.tsx b/src/components/modals/stacked-modal-provider/stacked-modal-provider.tsx index ca3799cc..eb9df7eb 100644 --- a/src/components/modals/stacked-modal-provider/stacked-modal-provider.tsx +++ b/src/components/modals/stacked-modal-provider/stacked-modal-provider.tsx @@ -1,43 +1,46 @@ -import { PropsWithChildren, useState } from "react" -import { StackedModalContext } from "./stacked-modal-context" +import type { PropsWithChildren } from "react"; +import { useState } from "react"; + +import { StackedModalContext } from "./stacked-modal-context"; type StackedModalProviderProps = PropsWithChildren<{ - onOpenChange: (open: boolean) => void -}> + onOpenChange: (open: boolean) => void; +}>; export const StackedModalProvider = ({ children, onOpenChange, }: StackedModalProviderProps) => { - const [state, setState] = useState>({}) + const [state, setState] = useState>({}); const getIsOpen = (id: string) => { - return state[id] || false - } + return state[id] || false; + }; const setIsOpen = (id: string, open: boolean) => { setState((prevState) => ({ ...prevState, [id]: open, - })) + })); - onOpenChange(open) - } + onOpenChange(open); + }; const register = (id: string) => { setState((prevState) => ({ ...prevState, [id]: false, - })) - } + })); + }; const unregister = (id: string) => { setState((prevState) => { - const newState = { ...prevState } - delete newState[id] - return newState - }) - } + const newState = { ...prevState }; + delete newState[id]; + + return newState; + }); + }; return ( {children} - ) -} + ); +}; diff --git a/src/components/modals/stacked-modal-provider/use-stacked-modal.ts b/src/components/modals/stacked-modal-provider/use-stacked-modal.ts index f246c0d0..c991abee 100644 --- a/src/components/modals/stacked-modal-provider/use-stacked-modal.ts +++ b/src/components/modals/stacked-modal-provider/use-stacked-modal.ts @@ -1,14 +1,15 @@ -import { useContext } from "react" -import { StackedModalContext } from "./stacked-modal-context" +import { useContext } from "react"; + +import { StackedModalContext } from "./stacked-modal-context"; export const useStackedModal = () => { - const context = useContext(StackedModalContext) + const context = useContext(StackedModalContext); if (!context) { throw new Error( - "useStackedModal must be used within a StackedModalProvider" - ) + "useStackedModal must be used within a StackedModalProvider", + ); } - return context -} + return context; +}; From 75daa4a7c5d36419dc80b3906f5eede45f832238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Mon, 20 Oct 2025 09:55:01 +0200 Subject: [PATCH 074/195] eslint/prettier - fix components/modals --- src/components/modals/index.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/modals/index.ts b/src/components/modals/index.ts index 566853b6..e3e0e047 100644 --- a/src/components/modals/index.ts +++ b/src/components/modals/index.ts @@ -1,7 +1,7 @@ -export { RouteDrawer } from "./route-drawer" -export { RouteFocusModal } from "./route-focus-modal" -export { useRouteModal } from "./route-modal-provider" +export { RouteDrawer } from "./route-drawer"; +export { RouteFocusModal } from "./route-focus-modal"; +export { useRouteModal } from "./route-modal-provider"; -export { StackedDrawer } from "./stacked-drawer" -export { StackedFocusModal } from "./stacked-focus-modal" -export { useStackedModal } from "./stacked-modal-provider" +export { StackedDrawer } from "./stacked-drawer"; +export { StackedFocusModal } from "./stacked-focus-modal"; +export { useStackedModal } from "./stacked-modal-provider"; From 0a23f7bbf4d4c8278888747abfa52828a4ac603e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Mon, 20 Oct 2025 15:45:03 +0200 Subject: [PATCH 075/195] eslint/prettier - fix components/search --- .../hooks/use-data-grid-cell-handlers.tsx | 2 - src/components/search/constants.ts | 6 +- src/components/search/index.ts | 2 +- src/components/search/search.tsx | 294 +++++++++--------- src/components/search/types.ts | 30 +- src/components/search/use-search-results.tsx | 291 ++++++++--------- 6 files changed, 319 insertions(+), 306 deletions(-) diff --git a/src/components/data-grid/hooks/use-data-grid-cell-handlers.tsx b/src/components/data-grid/hooks/use-data-grid-cell-handlers.tsx index 735aaec4..22c2d52d 100644 --- a/src/components/data-grid/hooks/use-data-grid-cell-handlers.tsx +++ b/src/components/data-grid/hooks/use-data-grid-cell-handlers.tsx @@ -102,8 +102,6 @@ export const useDataGridCellHandlers = < ); const getInputChangeHandler = useCallback( - // Using `any` here as the generic type of Path will - // not be inferred correctly. // @todo fix any type // eslint-disable-next-line @typescript-eslint/no-explicit-any (field: any) => (next: any, prev: any) => { diff --git a/src/components/search/constants.ts b/src/components/search/constants.ts index 6bb9aab7..413ff6c0 100644 --- a/src/components/search/constants.ts +++ b/src/components/search/constants.ts @@ -24,7 +24,7 @@ export const SEARCH_AREAS = [ "secretApiKey", "command", "navigation", -] as const +] as const; -export const DEFAULT_SEARCH_LIMIT = 3 -export const SEARCH_LIMIT_INCREMENT = 20 +export const DEFAULT_SEARCH_LIMIT = 3; +export const SEARCH_LIMIT_INCREMENT = 20; diff --git a/src/components/search/index.ts b/src/components/search/index.ts index c368ec91..8ad84189 100644 --- a/src/components/search/index.ts +++ b/src/components/search/index.ts @@ -1 +1 @@ -export { Search } from "./search" +export { Search } from "./search"; diff --git a/src/components/search/search.tsx b/src/components/search/search.tsx index 10da8763..5c2775e2 100644 --- a/src/components/search/search.tsx +++ b/src/components/search/search.tsx @@ -1,29 +1,15 @@ -import { - Badge, - Button, - clx, - DropdownMenu, - IconButton, - Kbd, - Text, -} from "@medusajs/ui" -import { Command } from "cmdk" -import { Dialog as RadixDialog } from "radix-ui" +import type { ComponentPropsWithoutRef, ElementRef } from "react"; import { Children, - ComponentPropsWithoutRef, - ElementRef, - forwardRef, Fragment, + forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, -} from "react" -import { useTranslation } from "react-i18next" -import { useLocation, useNavigate } from "react-router-dom" +} from "react"; import { ArrowUturnLeft, @@ -31,123 +17,143 @@ import { Plus, Spinner, TriangleDownMini, -} from "@medusajs/icons" -import { matchSorter } from "match-sorter" +} from "@medusajs/icons"; +import { + Badge, + Button, + DropdownMenu, + IconButton, + Kbd, + Text, + clx, +} from "@medusajs/ui"; + +import { Command } from "cmdk"; +import { matchSorter } from "match-sorter"; +import { Dialog as RadixDialog } from "radix-ui"; +import { useTranslation } from "react-i18next"; +import { useLocation, useNavigate } from "react-router-dom"; + +import { Skeleton } from "@components/common/skeleton"; +import { Thumbnail } from "@components/common/thumbnail"; + +import { useDocumentDirection } from "@hooks/use-document-direction"; + +import { useSearch } from "@providers/search-provider"; -import { useSearch } from "../../providers/search-provider" -import { Skeleton } from "../common/skeleton" -import { Thumbnail } from "../common/thumbnail" import { DEFAULT_SEARCH_LIMIT, SEARCH_AREAS, SEARCH_LIMIT_INCREMENT, -} from "./constants" -import { SearchArea } from "./types" -import { useSearchResults } from "./use-search-results" -import { useDocumentDirection } from "../../hooks/use-document-direction" +} from "./constants"; +import type { SearchArea } from "./types"; +import { useSearchResults } from "./use-search-results"; export const Search = () => { - const [area, setArea] = useState("all") - const [search, setSearch] = useState("") - const [limit, setLimit] = useState(DEFAULT_SEARCH_LIMIT) - const { open, onOpenChange } = useSearch() - const location = useLocation() - const { t } = useTranslation() - const navigate = useNavigate() + const [area, setArea] = useState("all"); + const [search, setSearch] = useState(""); + const [limit, setLimit] = useState(DEFAULT_SEARCH_LIMIT); + const { open, onOpenChange } = useSearch(); + const location = useLocation(); + const { t } = useTranslation(); + const navigate = useNavigate(); - - const inputRef = useRef(null) - const listRef = useRef(null) + const inputRef = useRef(null); + const listRef = useRef(null); const { staticResults, dynamicResults, isFetching } = useSearchResults({ area, limit, q: search, - }) + }); const handleReset = useCallback(() => { - setArea("all") - setSearch("") - setLimit(DEFAULT_SEARCH_LIMIT) - }, [setLimit]) + setArea("all"); + setSearch(""); + setLimit(DEFAULT_SEARCH_LIMIT); + }, [setLimit]); const handleBack = () => { - handleReset() - inputRef.current?.focus() - } + handleReset(); + inputRef.current?.focus(); + }; const handleOpenChange = useCallback( (open: boolean) => { if (!open) { - handleReset() + handleReset(); } - onOpenChange(open) + onOpenChange(open); }, - [onOpenChange, handleReset] - ) + [onOpenChange, handleReset], + ); useEffect(() => { - handleOpenChange(false) - }, [location.pathname, handleOpenChange]) + handleOpenChange(false); + }, [location.pathname, handleOpenChange]); const handleSelect = (item: { to?: string; callback?: () => void }) => { - handleOpenChange(false) + handleOpenChange(false); if (item.to) { - navigate(item.to) - return + navigate(item.to); + + return; } if (item.callback) { - item.callback() - return + item.callback(); + + return; } - } + }; const handleShowMore = (area: SearchArea) => { if (area === "all") { - setLimit(DEFAULT_SEARCH_LIMIT) + setLimit(DEFAULT_SEARCH_LIMIT); } else { - setLimit(SEARCH_LIMIT_INCREMENT) + setLimit(SEARCH_LIMIT_INCREMENT); } - setArea(area) - inputRef.current?.focus() - } + setArea(area); + inputRef.current?.focus(); + }; const handleLoadMore = () => { - setLimit((l) => l + SEARCH_LIMIT_INCREMENT) - } + setLimit((l) => l + SEARCH_LIMIT_INCREMENT); + }; const filteredStaticResults = useMemo(() => { - const filteredResults: typeof staticResults = [] + const filteredResults: typeof staticResults = []; staticResults.forEach((group) => { const filteredItems = matchSorter(group.items, search, { keys: ["label"], - }) + }); if (filteredItems.length === 0) { - return + return; } filteredResults.push({ ...group, items: filteredItems, - }) - }) + }); + }); - return filteredResults - }, [staticResults, search]) + return filteredResults; + }, [staticResults, search]); const handleSearch = (q: string) => { - setSearch(q) - listRef.current?.scrollTo({ top: 0 }) - } + setSearch(q); + listRef.current?.scrollTo({ top: 0 }); + }; const showLoading = useMemo(() => { - return isFetching && !dynamicResults.length && !filteredStaticResults.length - }, [isFetching, dynamicResults, filteredStaticResults]) + return ( + isFetching && !dynamicResults.length && !filteredStaticResults.length + ); + }, [isFetching, dynamicResults, filteredStaticResults]); return ( @@ -190,7 +196,7 @@ export const Search = () => { )}
    - ) + ); })} {group.hasMore && area === "all" && ( { hidden={true} value={`${group.title}:show:more`} // Prevent the "Show more" buttons across groups from sharing the same value/state > -
    +
    {t("app.search.showMore")} @@ -212,13 +218,13 @@ export const Search = () => { hidden={true} value={`${group.title}:load:more`} > -
    +
    {t("app.search.loadMore", { count: Math.min( SEARCH_LIMIT_INCREMENT, - group.count - limit + group.count - limit, ), })} @@ -226,7 +232,7 @@ export const Search = () => { )} - ) + ); })} {filteredStaticResults.map((group) => { return ( @@ -256,20 +262,20 @@ export const Search = () => { )}
    - ) + ); })}
    - ) + ); })} - ) + ); })} {!showLoading && } - ) -} + ); +}; const CommandPalette = forwardRef< ElementRef, @@ -280,34 +286,34 @@ const CommandPalette = forwardRef< ref={ref} className={clx( "bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md", - className + className, )} {...props} /> -)) -CommandPalette.displayName = Command.displayName +)); +CommandPalette.displayName = Command.displayName; interface CommandDialogProps extends RadixDialog.DialogProps { - isLoading?: boolean + isLoading?: boolean; } const CommandDialog = ({ children, ...props }: CommandDialogProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); const preserveHeight = useMemo(() => { - return props.isLoading && Children.count(children) === 0 - }, [props.isLoading, children]) + return props.isLoading && Children.count(children) === 0; + }, [props.isLoading, children]); return ( - + @@ -319,7 +325,7 @@ const CommandDialog = ({ children, ...props }: CommandDialogProps) => { {children} -
    +
    @@ -330,7 +336,7 @@ const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
    -
    +
    {t("app.search.openResult")} @@ -342,16 +348,16 @@ const CommandDialog = ({ children, ...props }: CommandDialogProps) => { - ) -} + ); +}; const CommandInput = forwardRef< ElementRef, ComponentPropsWithoutRef & { - area: SearchArea - setArea: (area: SearchArea) => void - isFetching: boolean - onBack?: () => void + area: SearchArea; + setArea: (area: SearchArea) => void; + isFetching: boolean; + onBack?: () => void; } >( ( @@ -365,15 +371,15 @@ const CommandInput = forwardRef< onBack, ...props }, - ref + ref, ) => { - const { t } = useTranslation() - const innerRef = useRef(null) - const direction = useDocumentDirection() + const { t } = useTranslation(); + const innerRef = useRef(null); + const direction = useDocumentDirection(); useImperativeHandle( ref, - () => innerRef.current - ) + () => innerRef.current, + ); return (
    @@ -382,7 +388,7 @@ const CommandInput = forwardRef< {t(`app.search.groups.${area}`)} @@ -392,8 +398,8 @@ const CommandInput = forwardRef< align="start" className="h-full max-h-[360px] overflow-auto" onCloseAutoFocus={(e) => { - e.preventDefault() - innerRef.current?.focus() + e.preventDefault(); + innerRef.current?.focus(); }} >
    {isFetching && ( - + )} {value && (
    - ) - } -) + ); + }, +); -CommandInput.displayName = Command.Input.displayName +CommandInput.displayName = Command.Input.displayName; const CommandList = forwardRef< ElementRef, @@ -469,25 +475,25 @@ const CommandList = forwardRef< ref={ref} className={clx( "max-h-[300px] flex-1 overflow-y-auto overflow-x-hidden px-2 pb-4", - className + className, )} {...props} /> -)) +)); -CommandList.displayName = Command.List.displayName +CommandList.displayName = Command.List.displayName; const CommandEmpty = forwardRef< ElementRef, Omit, "children"> & { - q?: string + q?: string; } >((props, ref) => { - const { t } = useTranslation() + const { t } = useTranslation(); return ( -
    +
    @@ -503,10 +509,10 @@ const CommandEmpty = forwardRef<
    - ) -}) + ); +}); -CommandEmpty.displayName = Command.Empty.displayName +CommandEmpty.displayName = Command.Empty.displayName; const CommandLoading = forwardRef< ElementRef, @@ -516,7 +522,7 @@ const CommandLoading = forwardRef<
    @@ -527,9 +533,9 @@ const CommandLoading = forwardRef<
    ))}
    - ) -}) -CommandLoading.displayName = Command.Loading.displayName + ); +}); +CommandLoading.displayName = Command.Loading.displayName; const CommandGroup = forwardRef< ElementRef, @@ -538,14 +544,14 @@ const CommandGroup = forwardRef< -)) +)); -CommandGroup.displayName = Command.Group.displayName +CommandGroup.displayName = Command.Group.displayName; const CommandSeparator = forwardRef< ElementRef, @@ -556,8 +562,8 @@ const CommandSeparator = forwardRef< className={clx("bg-border -mx-1 h-px", className)} {...props} /> -)) -CommandSeparator.displayName = Command.Separator.displayName +)); +CommandSeparator.displayName = Command.Separator.displayName; const CommandItem = forwardRef< ElementRef, @@ -566,11 +572,11 @@ const CommandItem = forwardRef< svg]:text-ui-fg-subtle relative flex cursor-pointer select-none items-center gap-x-3 rounded-md p-2 outline-none data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50", - className + "txt-compact-small relative flex cursor-pointer select-none items-center gap-x-3 rounded-md p-2 outline-none focus-visible:bg-ui-bg-base-hover aria-selected:bg-ui-bg-base-hover data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 [&>svg]:text-ui-fg-subtle", + className, )} {...props} /> -)) +)); -CommandItem.displayName = Command.Item.displayName +CommandItem.displayName = Command.Item.displayName; diff --git a/src/components/search/types.ts b/src/components/search/types.ts index e73a1360..d3925316 100644 --- a/src/components/search/types.ts +++ b/src/components/search/types.ts @@ -1,20 +1,20 @@ -import { SEARCH_AREAS } from "./constants" +import type { SEARCH_AREAS } from "./constants"; -export type SearchArea = (typeof SEARCH_AREAS)[number] +export type SearchArea = (typeof SEARCH_AREAS)[number]; export type DynamicSearchResultItem = { - id: string - title: string - subtitle?: string - to: string - thumbnail?: string - value: string -} + id: string; + title: string; + subtitle?: string; + to: string; + thumbnail?: string; + value: string; +}; export type DynamicSearchResult = { - area: SearchArea - title: string - hasMore: boolean - count: number - items: DynamicSearchResultItem[] -} + area: SearchArea; + title: string; + hasMore: boolean; + count: number; + items: DynamicSearchResultItem[]; +}; diff --git a/src/components/search/use-search-results.tsx b/src/components/search/use-search-results.tsx index 41149d9b..e3dbb98a 100644 --- a/src/components/search/use-search-results.tsx +++ b/src/components/search/use-search-results.tsx @@ -1,8 +1,11 @@ -import { HttpTypes } from "@medusajs/types" -import { keepPreviousData } from "@tanstack/react-query" -import { TFunction } from "i18next" -import { useCallback, useEffect, useMemo, useState } from "react" -import { useTranslation } from "react-i18next" +import { useCallback, useEffect, useMemo, useState } from "react"; + +import type { HttpTypes } from "@medusajs/types"; + +import { keepPreviousData } from "@tanstack/react-query"; +import type { TFunction } from "i18next"; +import { useTranslation } from "react-i18next"; + import { useApiKeys, useCampaigns, @@ -13,9 +16,9 @@ import { useOrders, usePriceLists, useProductCategories, - useProducts, useProductTags, useProductTypes, + useProducts, usePromotions, useRegions, useSalesChannels, @@ -24,82 +27,86 @@ import { useTaxRegions, useUsers, useVariants, -} from "../../hooks/api" -import { useReturnReasons } from "../../hooks/api/return-reasons" -import { Shortcut, ShortcutType } from "../../providers/keybind-provider" -import { useGlobalShortcuts } from "../../providers/keybind-provider/hooks" -import { DynamicSearchResult, SearchArea } from "./types" +} from "@hooks/api"; +import { useReturnReasons } from "@hooks/api/return-reasons"; + +import type { Shortcut, ShortcutType } from "@providers/keybind-provider"; +import { useGlobalShortcuts } from "@providers/keybind-provider/hooks"; + +import type { DynamicSearchResult, SearchArea } from "./types"; type UseSearchProps = { - q?: string - limit: number - area?: SearchArea -} + q?: string; + limit: number; + area?: SearchArea; +}; export const useSearchResults = ({ q, limit, area = "all", }: UseSearchProps) => { - const staticResults = useStaticSearchResults(area) - const { dynamicResults, isFetching } = useDynamicSearchResults(area, limit, q) + const staticResults = useStaticSearchResults(area); + const { dynamicResults, isFetching } = useDynamicSearchResults( + area, + limit, + q, + ); return { staticResults, dynamicResults, isFetching, - } -} + }; +}; const useStaticSearchResults = (currentArea: SearchArea) => { - const globalCommands = useGlobalShortcuts() + const globalCommands = useGlobalShortcuts(); - const results = useMemo(() => { - const groups = new Map() + return useMemo(() => { + const groups = new Map(); globalCommands.forEach((command) => { - const group = groups.get(command.type) || [] - group.push(command) - groups.set(command.type, group) - }) + const group = groups.get(command.type) || []; + group.push(command); + groups.set(command.type, group); + }); - let filteredGroups: [ShortcutType, Shortcut[]][] + let filteredGroups: [ShortcutType, Shortcut[]][]; switch (currentArea) { case "all": - filteredGroups = Array.from(groups) - break + filteredGroups = Array.from(groups); + break; case "navigation": filteredGroups = Array.from(groups).filter( - ([type]) => type === "pageShortcut" || type === "settingShortcut" - ) - break + ([type]) => type === "pageShortcut" || type === "settingShortcut", + ); + break; case "command": filteredGroups = Array.from(groups).filter( - ([type]) => type === "commandShortcut" - ) - break + ([type]) => type === "commandShortcut", + ); + break; default: - filteredGroups = [] + filteredGroups = []; } return filteredGroups.map(([title, items]) => ({ title, items, - })) - }, [globalCommands, currentArea]) - - return results -} + })); + }, [globalCommands, currentArea]); +}; const useDynamicSearchResults = ( currentArea: SearchArea, limit: number, - q?: string + q?: string, ) => { - const { t } = useTranslation() + const { t } = useTranslation(); - const debouncedSearch = useDebouncedSearch(q, 300) + const debouncedSearch = useDebouncedSearch(q, 300); const orderResponse = useOrders( { @@ -110,8 +117,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "order"), placeholderData: keepPreviousData, - } - ) + }, + ); const productResponse = useProducts( { @@ -122,8 +129,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "product"), placeholderData: keepPreviousData, - } - ) + }, + ); const productVariantResponse = useVariants( { @@ -134,8 +141,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "productVariant"), placeholderData: keepPreviousData, - } - ) + }, + ); const categoryResponse = useProductCategories( { @@ -147,8 +154,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "category"), placeholderData: keepPreviousData, - } - ) + }, + ); const collectionResponse = useCollections( { @@ -159,8 +166,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "collection"), placeholderData: keepPreviousData, - } - ) + }, + ); const customerResponse = useCustomers( { @@ -171,8 +178,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "customer"), placeholderData: keepPreviousData, - } - ) + }, + ); const customerGroupResponse = useCustomerGroups( { @@ -183,8 +190,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "customerGroup"), placeholderData: keepPreviousData, - } - ) + }, + ); const inventoryResponse = useInventoryItems( { @@ -195,8 +202,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "inventory"), placeholderData: keepPreviousData, - } - ) + }, + ); const promotionResponse = usePromotions( { @@ -207,8 +214,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "promotion"), placeholderData: keepPreviousData, - } - ) + }, + ); const campaignResponse = useCampaigns( { @@ -219,8 +226,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "campaign"), placeholderData: keepPreviousData, - } - ) + }, + ); const priceListResponse = usePriceLists( { @@ -231,8 +238,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "priceList"), placeholderData: keepPreviousData, - } - ) + }, + ); const userResponse = useUsers( { @@ -243,8 +250,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "user"), placeholderData: keepPreviousData, - } - ) + }, + ); const regionResponse = useRegions( { @@ -255,8 +262,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "region"), placeholderData: keepPreviousData, - } - ) + }, + ); const taxRegionResponse = useTaxRegions( { @@ -267,8 +274,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "taxRegion"), placeholderData: keepPreviousData, - } - ) + }, + ); const returnReasonResponse = useReturnReasons( { @@ -279,8 +286,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "returnReason"), placeholderData: keepPreviousData, - } - ) + }, + ); const salesChannelResponse = useSalesChannels( { @@ -291,8 +298,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "salesChannel"), placeholderData: keepPreviousData, - } - ) + }, + ); const productTypeResponse = useProductTypes( { @@ -303,8 +310,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "productType"), placeholderData: keepPreviousData, - } - ) + }, + ); const productTagResponse = useProductTags( { @@ -315,8 +322,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "productTag"), placeholderData: keepPreviousData, - } - ) + }, + ); const locationResponse = useStockLocations( { @@ -327,8 +334,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "location"), placeholderData: keepPreviousData, - } - ) + }, + ); const shippingProfileResponse = useShippingProfiles( { @@ -339,8 +346,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "shippingProfile"), placeholderData: keepPreviousData, - } - ) + }, + ); const publishableApiKeyResponse = useApiKeys( { @@ -352,8 +359,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "publishableApiKey"), placeholderData: keepPreviousData, - } - ) + }, + ); const secretApiKeyResponse = useApiKeys( { @@ -365,8 +372,8 @@ const useDynamicSearchResults = ( { enabled: isAreaEnabled(currentArea, "secretApiKey"), placeholderData: keepPreviousData, - } - ) + }, + ); const responseMap = useMemo( () => ({ @@ -416,94 +423,95 @@ const useDynamicSearchResults = ( shippingProfileResponse, publishableApiKeyResponse, secretApiKeyResponse, - ] - ) + ], + ); const results = useMemo(() => { - const groups = Object.entries(responseMap) + // Remove null values + + return Object.entries(responseMap) .map(([key, response]) => { - const area = key as SearchArea + const area = key as SearchArea; if (isAreaEnabled(currentArea, area) || currentArea === "all") { - return transformDynamicSearchResults(area, limit, t, response) + return transformDynamicSearchResults(area, limit, t, response); } - return null - }) - .filter(Boolean) // Remove null values - return groups - }, [responseMap, currentArea, limit, t]) + return null; + }) + .filter(Boolean); + }, [responseMap, currentArea, limit, t]); const isAreaFetching = useCallback( (area: SearchArea): boolean => { if (area === "all") { return Object.values(responseMap).some( - (response) => response.isFetching - ) + (response) => response.isFetching, + ); } return ( isAreaEnabled(currentArea, area) && responseMap[area as keyof typeof responseMap]?.isFetching - ) + ); }, - [currentArea, responseMap] - ) + [currentArea, responseMap], + ); const isFetching = useMemo(() => { - return isAreaFetching(currentArea) - }, [currentArea, isAreaFetching]) + return isAreaFetching(currentArea); + }, [currentArea, isAreaFetching]); const dynamicResults = q ? (results.filter( - (group) => !!group && group.items.length > 0 + (group) => !!group && group.items.length > 0, ) as DynamicSearchResult[]) - : [] + : []; return { dynamicResults, isFetching, - } -} + }; +}; const useDebouncedSearch = (value: string | undefined, delay: number) => { - const [debouncedValue, setDebouncedValue] = useState(value) + const [debouncedValue, setDebouncedValue] = useState(value); useEffect(() => { const handler = setTimeout(() => { - setDebouncedValue(value) - }, delay) + setDebouncedValue(value); + }, delay); return () => { - clearTimeout(handler) - } - }, [value, delay]) + clearTimeout(handler); + }; + }, [value, delay]); - return debouncedValue -} + return debouncedValue; +}; function isAreaEnabled(area: SearchArea, currentArea: SearchArea) { if (area === "all") { - return true + return true; } - if (area === currentArea) { - return true - } - return false + + return area === currentArea; } type TransformMap = { [K in SearchArea]?: { - dataKey: string + dataKey: string; + // @todo fix any type + // eslint-disable-next-line @typescript-eslint/no-explicit-any transform: (item: any) => { - id: string - title: string - subtitle?: string - to: string - value: string - thumbnail?: string - } - } -} + id: string; + title: string; + subtitle?: string; + to: string; + value: string; + thumbnail?: string; + }; + }; +}; const transformMap: TransformMap = { order: { @@ -560,14 +568,15 @@ const transformMap: TransformMap = { transform: (customer: HttpTypes.AdminCustomer) => { const name = [customer.first_name, customer.last_name] .filter(Boolean) - .join(" ") + .join(" "); + return { id: customer.id, title: name || customer.email, subtitle: name ? customer.email : undefined, to: `/customers/${customer.id}`, value: `customer:${customer.id}`, - } + }; }, }, customerGroup: { @@ -721,23 +730,23 @@ const transformMap: TransformMap = { value: `secretApiKey:${apiKey.id}`, }), }, -} +}; function transformDynamicSearchResults( type: SearchArea, limit: number, t: TFunction, - response?: T + response?: T, ): DynamicSearchResult | undefined { if (!response || !transformMap[type]) { - return undefined + return undefined; } - const { dataKey, transform } = transformMap[type]! - const data = response[dataKey as keyof T] + const { dataKey, transform } = transformMap[type]!; + const data = response[dataKey as keyof T]; if (!data || !Array.isArray(data)) { - return undefined + return undefined; } return { @@ -746,5 +755,5 @@ function transformDynamicSearchResults( hasMore: response.count > limit, count: response.count, items: data.map(transform), - } + }; } From f94f7c3f8e254005ef2d35007e4016fff6e23efa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Mon, 20 Oct 2025 16:01:39 +0200 Subject: [PATCH 076/195] eslint/prettier - fix components/table/configurable-data-table --- .../configurable-data-table.tsx | 164 ++++++++++-------- .../table/configurable-data-table/index.ts | 6 +- .../save-view-dropdown.tsx | 53 +++--- .../table/data-table/data-table.tsx | 41 +++-- 4 files changed, 146 insertions(+), 118 deletions(-) diff --git a/src/components/table/configurable-data-table/configurable-data-table.tsx b/src/components/table/configurable-data-table/configurable-data-table.tsx index 60344f12..bd04afb5 100644 --- a/src/components/table/configurable-data-table/configurable-data-table.tsx +++ b/src/components/table/configurable-data-table/configurable-data-table.tsx @@ -1,35 +1,40 @@ -import { useState, ReactNode } from "react" -import { Container, Button } from "@medusajs/ui" -import { useTranslation } from "react-i18next" -import { DataTable } from "../../data-table" -import { SaveViewDialog } from "../save-view-dialog" -import { SaveViewDropdown } from "./save-view-dropdown" -import { useTableConfiguration } from "../../../hooks/table/use-table-configuration" -import { useConfigurableTableColumns } from "../../../hooks/table/columns/use-configurable-table-columns" -import { getEntityAdapter } from "../../../lib/table/entity-adapters" -import { TableAdapter } from "../../../lib/table/table-adapters" +import { useState } from "react"; + +import { Button, Container } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; + +import { DataTable } from "@components/data-table"; +import { SaveViewDialog } from "@components/table/save-view-dialog"; + +import { useConfigurableTableColumns } from "@hooks/table/columns/use-configurable-table-columns"; +import { useTableConfiguration } from "@hooks/table/use-table-configuration"; + +import { getEntityAdapter } from "@lib/table/entity-adapters"; +import type { TableAdapter } from "@lib/table/table-adapters"; + +import { SaveViewDropdown } from "./save-view-dropdown"; type DataTableActionProps = { - label: string - disabled?: boolean + label: string; + disabled?: boolean; } & ( - | { - to: string + | { + to: string; } - | { - onClick: () => void + | { + onClick: () => void; } - ) - +); export interface ConfigurableDataTableProps { - adapter: TableAdapter - heading?: string - subHeading?: string - pageSize?: number - queryPrefix?: string - layout?: "fill" | "auto" - actions?: DataTableActionProps[] + adapter: TableAdapter; + heading?: string; + subHeading?: string; + pageSize?: number; + queryPrefix?: string; + layout?: "fill" | "auto"; + actions?: DataTableActionProps[]; } export function ConfigurableDataTable({ @@ -41,15 +46,17 @@ export function ConfigurableDataTable({ layout = "fill", actions, }: ConfigurableDataTableProps) { - const { t } = useTranslation() - const [saveDialogOpen, setSaveDialogOpen] = useState(false) - const [editingView, setEditingView] = useState(null) + const { t } = useTranslation(); + const [saveDialogOpen, setSaveDialogOpen] = useState(false); + // @todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const [editingView, setEditingView] = useState(null); - const entity = adapter.entity - const entityName = adapter.entityName - const filters = adapter.filters || [] - const pageSize = pageSizeProp || adapter.pageSize || 20 - const queryPrefix = queryPrefixProp || adapter.queryPrefix || "" + const entity = adapter.entity; + const entityName = adapter.entityName; + const filters = adapter.filters || []; + const pageSize = pageSizeProp || adapter.pageSize || 20; + const queryPrefix = queryPrefixProp || adapter.queryPrefix || ""; const { activeView, @@ -73,37 +80,42 @@ export function ConfigurableDataTable({ pageSize, queryPrefix, filters, - }) + }); - const parsedQueryParams = { ...queryParams } - filters.forEach(filter => { - const filterKey = filter.id + const parsedQueryParams = { ...queryParams }; + filters.forEach((filter) => { + const filterKey = filter.id; if (parsedQueryParams[filterKey] !== undefined) { try { - parsedQueryParams[filterKey] = JSON.parse(parsedQueryParams[filterKey]) + parsedQueryParams[filterKey] = JSON.parse(parsedQueryParams[filterKey]); } catch { // If parsing fails, keep the original value } } - }) + }); const searchParams = { ...parsedQueryParams, fields: requiredFields, limit: pageSize, offset: parsedQueryParams.offset ? Number(parsedQueryParams.offset) : 0, - } + }; - const fetchResult = adapter.useData(requiredFields, searchParams) + const fetchResult = adapter.useData(requiredFields, searchParams); - const columnAdapter = adapter.columnAdapter || getEntityAdapter(entity) - const generatedColumns = useConfigurableTableColumns(entity, apiColumns || [], columnAdapter) - const columns = (adapter.getColumns && apiColumns) - ? adapter.getColumns(apiColumns) - : generatedColumns + const columnAdapter = adapter.columnAdapter || getEntityAdapter(entity); + const generatedColumns = useConfigurableTableColumns( + entity, + apiColumns || [], + columnAdapter, + ); + const columns = + adapter.getColumns && apiColumns + ? adapter.getColumns(apiColumns) + : generatedColumns; if (fetchResult.isError) { - throw fetchResult.error + throw fetchResult.error; } const handleSaveAsDefault = async () => { @@ -117,8 +129,8 @@ export function ConfigurableDataTable({ filters: currentConfiguration.filters || {}, sorting: currentConfiguration.sorting || null, search: currentConfiguration.search || "", - } - }) + }, + }); } else { await createView.mutateAsync({ name: "Default", @@ -130,16 +142,16 @@ export function ConfigurableDataTable({ filters: currentConfiguration.filters || {}, sorting: currentConfiguration.sorting || null, search: currentConfiguration.search || "", - } - }) + }, + }); } } catch (_) { // Error is handled by the hook } - } + }; const handleUpdateExisting = async () => { - if (!activeView) return + if (!activeView) return; try { await updateView.mutateAsync({ @@ -150,17 +162,17 @@ export function ConfigurableDataTable({ filters: currentConfiguration.filters || {}, sorting: currentConfiguration.sorting || null, search: currentConfiguration.search || "", - } - }) + }, + }); } catch (_) { // Error is handled by the hook } - } + }; const handleSaveAsNew = () => { - setSaveDialogOpen(true) - setEditingView(null) - } + setSaveDialogOpen(true); + setEditingView(null); + }; // Filter bar content with save controls const filterBarContent = hasConfigurationChanged ? ( @@ -182,7 +194,7 @@ export function ConfigurableDataTable({ onSaveAsNew={handleSaveAsNew} /> - ) : null + ) : null; return ( @@ -190,6 +202,8 @@ export function ConfigurableDataTable({ data={fetchResult.data || []} columns={columns} filters={filters} + // @todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any getRowId={adapter.getRowId || ((row: any) => row.id)} rowCount={fetchResult.count} enablePagination @@ -197,7 +211,11 @@ export function ConfigurableDataTable({ pageSize={pageSize} isLoading={fetchResult.isLoading || isLoadingColumns} layout={layout} - heading={heading || entityName || (entity ? t(`${entity}.domain` as any) : "")} + heading={ + // @todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + heading || entityName || (entity ? t(`${entity}.domain` as any) : "") + } subHeading={subHeading} enableColumnVisibility={isViewConfigEnabled} initialColumnVisibility={visibleColumns} @@ -208,12 +226,18 @@ export function ConfigurableDataTable({ entity={entity} currentColumns={currentColumns} filterBarContent={filterBarContent} + // @todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any rowHref={adapter.getRowHref as ((row: any) => string) | undefined} - emptyState={adapter.emptyState || { - empty: { - heading: t(`${entity}.list.noRecordsMessage` as any), + emptyState={ + adapter.emptyState || { + empty: { + // @todo fix type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + heading: t(`${entity}.list.noRecordsMessage` as any), + }, } - }} + } prefix={queryPrefix} actions={actions} enableFilterMenu={false} @@ -226,15 +250,15 @@ export function ConfigurableDataTable({ currentConfiguration={currentConfiguration} editingView={editingView} onClose={() => { - setSaveDialogOpen(false) - setEditingView(null) + setSaveDialogOpen(false); + setEditingView(null); }} onSaved={() => { - setSaveDialogOpen(false) - setEditingView(null) + setSaveDialogOpen(false); + setEditingView(null); }} /> )} - ) + ); } diff --git a/src/components/table/configurable-data-table/index.ts b/src/components/table/configurable-data-table/index.ts index 52187f40..fc48f34f 100644 --- a/src/components/table/configurable-data-table/index.ts +++ b/src/components/table/configurable-data-table/index.ts @@ -1,3 +1,3 @@ -export { ConfigurableDataTable } from "./configurable-data-table" -export type { ConfigurableDataTableProps } from "./configurable-data-table" -export { SaveViewDropdown } from "./save-view-dropdown" \ No newline at end of file +export { ConfigurableDataTable } from "./configurable-data-table"; +export type { ConfigurableDataTableProps } from "./configurable-data-table"; +export { SaveViewDropdown } from "./save-view-dropdown"; diff --git a/src/components/table/configurable-data-table/save-view-dropdown.tsx b/src/components/table/configurable-data-table/save-view-dropdown.tsx index 803712c0..6ae935f3 100644 --- a/src/components/table/configurable-data-table/save-view-dropdown.tsx +++ b/src/components/table/configurable-data-table/save-view-dropdown.tsx @@ -1,27 +1,28 @@ -import React from "react" -import { Button, DropdownMenu, usePrompt } from "@medusajs/ui" -import { ChevronDownMini } from "@medusajs/icons" -import { useTranslation } from "react-i18next" +import type React from "react"; + +import { ChevronDownMini } from "@medusajs/icons"; +import { Button, DropdownMenu, usePrompt } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; interface SaveViewDropdownProps { - isDefaultView: boolean - currentViewId?: string - currentViewName?: string - onSaveAsDefault: () => void - onUpdateExisting: () => void - onSaveAsNew: () => void + isDefaultView: boolean; + currentViewId?: string; + currentViewName?: string; + onSaveAsDefault: () => void; + onUpdateExisting: () => void; + onSaveAsNew: () => void; } export const SaveViewDropdown: React.FC = ({ isDefaultView, - currentViewId, currentViewName, onSaveAsDefault, onUpdateExisting, onSaveAsNew, }) => { - const { t } = useTranslation() - const prompt = usePrompt() + const { t } = useTranslation(); + const prompt = usePrompt(); const handleSaveAsDefault = async () => { const result = await prompt({ @@ -29,34 +30,32 @@ export const SaveViewDropdown: React.FC = ({ description: t("views.prompts.updateDefault.description"), confirmText: t("views.prompts.updateDefault.confirmText"), cancelText: t("views.prompts.updateDefault.cancelText"), - }) + }); if (result) { - onSaveAsDefault() + onSaveAsDefault(); } - } + }; const handleUpdateExisting = async () => { const result = await prompt({ title: t("views.prompts.updateView.title"), - description: t("views.prompts.updateView.description", { name: currentViewName }), + description: t("views.prompts.updateView.description", { + name: currentViewName, + }), confirmText: t("views.prompts.updateView.confirmText"), cancelText: t("views.prompts.updateView.cancelText"), - }) + }); if (result) { - onUpdateExisting() + onUpdateExisting(); } - } + }; return ( - @@ -83,5 +82,5 @@ export const SaveViewDropdown: React.FC = ({ )} - ) -} \ No newline at end of file + ); +}; diff --git a/src/components/table/data-table/data-table.tsx b/src/components/table/data-table/data-table.tsx index 9c741d08..1332de7b 100644 --- a/src/components/table/data-table/data-table.tsx +++ b/src/components/table/data-table/data-table.tsx @@ -1,22 +1,27 @@ -import { clx } from "@medusajs/ui" -import { memo } from "react" -import { NoRecords, NoResultsProps } from "../../common/empty-table-content" -import { TableSkeleton } from "../../common/skeleton" -import { DataTableQuery, DataTableQueryProps } from "./data-table-query" -import { DataTableRoot, DataTableRootProps } from "./data-table-root" +import { memo } from "react"; + +import { clx } from "@medusajs/ui"; + +import type { NoResultsProps } from "../../common/empty-table-content"; +import { NoRecords } from "../../common/empty-table-content"; +import { TableSkeleton } from "../../common/skeleton"; +import type { DataTableQueryProps } from "./data-table-query"; +import { DataTableQuery } from "./data-table-query"; +import type { DataTableRootProps } from "./data-table-root"; +import { DataTableRoot } from "./data-table-root"; interface DataTableProps extends Omit, "noResults">, DataTableQueryProps { - isLoading?: boolean - pageSize: number - queryObject?: Record - noRecords?: Pick + isLoading?: boolean; + pageSize: number; + queryObject?: Record; + noRecords?: Pick; } // Maybe we should use the memoized version of DataTableRoot // const MemoizedDataTableRoot = memo(DataTableRoot) as typeof DataTableRoot -const MemoizedDataTableQuery = memo(DataTableQuery) as typeof DataTableQuery +const MemoizedDataTableQuery = memo(DataTableQuery) as typeof DataTableQuery; /** * @deprecated Use the DataTable component from "/components/data-table" instead @@ -49,13 +54,13 @@ export const _DataTable = ({ orderBy={!!orderBy?.length} pagination={!!pagination} /> - ) + ); } const noQuery = - Object.values(queryObject).filter((v) => Boolean(v)).length === 0 - const noResults = !isLoading && count === 0 && !noQuery - const noRecords = !isLoading && count === 0 && noQuery + Object.values(queryObject).filter((v) => Boolean(v)).length === 0; + const noResults = !isLoading && count === 0 && !noQuery; + const noRecords = !isLoading && count === 0 && noQuery; if (noRecords) { return ( @@ -65,7 +70,7 @@ export const _DataTable = ({ })} {...noRecordsProps} /> - ) + ); } return ( @@ -92,5 +97,5 @@ export const _DataTable = ({ layout={layout} />
    - ) -} + ); +}; From 10840ee689b3cd59461a95c3cd621984699518ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Mon, 20 Oct 2025 16:49:16 +0200 Subject: [PATCH 077/195] eslint/prettier - fix components/table/data-table-filter --- .../data-table/data-table-filter/context.tsx | 21 +- .../data-table-filter/data-table-filter.tsx | 216 +++++++++--------- .../data-table-filter/date-filter.tsx | 203 ++++++++-------- .../data-table-filter/filter-chip.tsx | 50 ++-- .../data-table/data-table-filter/index.ts | 2 +- .../data-table-filter/number-filter.tsx | 194 ++++++++-------- .../data-table-filter/select-filter.tsx | 119 +++++----- .../data-table-filter/string-filter.tsx | 84 +++---- .../data-table/data-table-filter/types.ts | 12 +- 9 files changed, 464 insertions(+), 437 deletions(-) diff --git a/src/components/table/data-table/data-table-filter/context.tsx b/src/components/table/data-table/data-table-filter/context.tsx index daacb414..71ae8a7f 100644 --- a/src/components/table/data-table/data-table-filter/context.tsx +++ b/src/components/table/data-table/data-table-filter/context.tsx @@ -1,19 +1,20 @@ -import { createContext, useContext } from "react" +import { createContext, useContext } from "react"; type DataTableFilterContextValue = { - removeFilter: (key: string) => void - removeAllFilters: () => void -} + removeFilter: (key: string) => void; + removeAllFilters: () => void; +}; export const DataTableFilterContext = - createContext(null) + createContext(null); export const useDataTableFilterContext = () => { - const ctx = useContext(DataTableFilterContext) + const ctx = useContext(DataTableFilterContext); if (!ctx) { throw new Error( - "useDataTableFacetedFilterContext must be used within a DataTableFacetedFilter" - ) + "useDataTableFacetedFilterContext must be used within a DataTableFacetedFilter", + ); } - return ctx -} + + return ctx; +}; diff --git a/src/components/table/data-table/data-table-filter/data-table-filter.tsx b/src/components/table/data-table/data-table-filter/data-table-filter.tsx index b96a79a2..076af1cd 100644 --- a/src/components/table/data-table/data-table-filter/data-table-filter.tsx +++ b/src/components/table/data-table/data-table-filter/data-table-filter.tsx @@ -1,81 +1,83 @@ -import { Button, clx } from "@medusajs/ui" -import { Popover as RadixPopover } from "radix-ui" -import { useCallback, useEffect, useMemo, useRef, useState } from "react" -import { useSearchParams } from "react-router-dom" +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; -import { useTranslation } from "react-i18next" -import { DataTableFilterContext, useDataTableFilterContext } from "./context" -import { DateFilter } from "./date-filter" -import { NumberFilter } from "./number-filter" -import { SelectFilter } from "./select-filter" -import { StringFilter } from "./string-filter" +import { Button, clx } from "@medusajs/ui"; + +import { Popover as RadixPopover } from "radix-ui"; +import { useTranslation } from "react-i18next"; +import { useSearchParams } from "react-router-dom"; + +import { DataTableFilterContext, useDataTableFilterContext } from "./context"; +import { DateFilter } from "./date-filter"; +import { NumberFilter } from "./number-filter"; +import { SelectFilter } from "./select-filter"; +import { StringFilter } from "./string-filter"; type Option = { - label: string - value: unknown -} + label: string; + value: unknown; +}; export type Filter = { - key: string - label: string + key: string; + label: string; } & ( | { - type: "select" - options: Option[] - multiple?: boolean - searchable?: boolean + type: "select"; + options: Option[]; + multiple?: boolean; + searchable?: boolean; } | { - type: "date" - options?: never + type: "date"; + options?: never; } | { - type: "string" - options?: never + type: "string"; + options?: never; } | { - type: "number" - options?: never + type: "number"; + options?: never; } -) +); type DataTableFilterProps = { - filters: Filter[] - readonly?: boolean - prefix?: string -} + filters: Filter[]; + readonly?: boolean; + prefix?: string; +}; export const DataTableFilter = ({ filters, readonly, prefix, }: DataTableFilterProps) => { - const { t } = useTranslation() - const [searchParams] = useSearchParams() - const [open, setOpen] = useState(false) + const { t } = useTranslation(); + const [searchParams] = useSearchParams(); + const [open, setOpen] = useState(false); const [activeFilters, setActiveFilters] = useState( - getInitialFilters({ searchParams, filters, prefix }) - ) + getInitialFilters({ searchParams, filters, prefix }), + ); const availableFilters = filters.filter( - (f) => !activeFilters.find((af) => af.key === f.key) - ) + (f) => !activeFilters.find((af) => af.key === f.key), + ); /** * If there are any filters in the URL that are not in the active filters, * add them to the active filters. This ensures that we display the filters * if a user navigates to a page with filters in the URL. */ - const initialMount = useRef(true) + const initialMount = useRef(true); useEffect(() => { if (initialMount.current) { - const params = new URLSearchParams(searchParams) + const params = new URLSearchParams(searchParams); filters.forEach((filter) => { - const key = prefix ? `${prefix}_${filter.key}` : filter.key - const value = params.get(key) + const key = prefix ? `${prefix}_${filter.key}` : filter.key; + const value = params.get(key); if (value && !activeFilters.find((af) => af.key === filter.key)) { if (filter.type === "select") { setActiveFilters((prev) => [ @@ -86,32 +88,32 @@ export const DataTableFilter = ({ options: filter.options, openOnMount: false, }, - ]) + ]); } else { setActiveFilters((prev) => [ ...prev, { ...filter, openOnMount: false }, - ]) + ]); } } - }) + }); } - initialMount.current = false - }, [activeFilters, filters, prefix, searchParams]) + initialMount.current = false; + }, [activeFilters, filters, prefix, searchParams]); const addFilter = (filter: Filter) => { - setOpen(false) - setActiveFilters((prev) => [...prev, { ...filter, openOnMount: true }]) - } + setOpen(false); + setActiveFilters((prev) => [...prev, { ...filter, openOnMount: true }]); + }; const removeFilter = useCallback((key: string) => { - setActiveFilters((prev) => prev.filter((f) => f.key !== key)) - }, []) + setActiveFilters((prev) => prev.filter((f) => f.key !== key)); + }, []); const removeAllFilters = useCallback(() => { - setActiveFilters([]) - }, []) + setActiveFilters([]); + }, []); return (
    @@ -138,7 +140,7 @@ export const DataTableFilter = ({ searchable={filter.searchable} openOnMount={filter.openOnMount} /> - ) + ); case "date": return ( - ) + ); case "string": return ( - ) + ); case "number": return ( - ) + ); default: - break + break; } })} {!readonly && availableFilters.length > 0 && ( @@ -183,7 +185,7 @@ export const DataTableFilter = ({ { const hasOpenFilter = activeFilters.find( - (filter) => filter.openOnMount - ) + (filter) => filter.openOnMount, + ); if (hasOpenFilter) { - e.preventDefault() + e.preventDefault(); } }} > - {availableFilters.map((filter) => { - return ( -
    { - addFilter(filter) - }} - > - {filter.label} -
    - ) - })} + {availableFilters.map((filter) => ( + //@todo fix a11y issue + // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/interactive-supports-focus +
    { + addFilter(filter); + }} + > + {filter.label} +
    + ))}
    @@ -222,62 +224,62 @@ export const DataTableFilter = ({ )}
    - ) -} + ); +}; type ClearAllFiltersProps = { - filters: Filter[] - prefix?: string -} + filters: Filter[]; + prefix?: string; +}; const ClearAllFilters = ({ filters, prefix }: ClearAllFiltersProps) => { - const { removeAllFilters } = useDataTableFilterContext() - const [_, setSearchParams] = useSearchParams() + const { removeAllFilters } = useDataTableFilterContext(); + const [_, setSearchParams] = useSearchParams(); const handleRemoveAll = () => { setSearchParams((prev) => { - const newValues = new URLSearchParams(prev) + const newValues = new URLSearchParams(prev); filters.forEach((filter) => { - newValues.delete(prefix ? `${prefix}_${filter.key}` : filter.key) - }) + newValues.delete(prefix ? `${prefix}_${filter.key}` : filter.key); + }); - return newValues - }) + return newValues; + }); - removeAllFilters() - } + removeAllFilters(); + }; return ( - ) -} + ); +}; const getInitialFilters = ({ searchParams, filters, prefix, }: { - searchParams: URLSearchParams - filters: Filter[] - prefix?: string + searchParams: URLSearchParams; + filters: Filter[]; + prefix?: string; }) => { - const params = new URLSearchParams(searchParams) - const activeFilters: (Filter & { openOnMount: boolean })[] = [] + const params = new URLSearchParams(searchParams); + const activeFilters: (Filter & { openOnMount: boolean })[] = []; filters.forEach((filter) => { - const key = prefix ? `${prefix}_${filter.key}` : filter.key - const value = params.get(key) + const key = prefix ? `${prefix}_${filter.key}` : filter.key; + const value = params.get(key); if (value) { if (filter.type === "select") { activeFilters.push({ @@ -285,12 +287,12 @@ const getInitialFilters = ({ multiple: filter.multiple, options: filter.options, openOnMount: false, - }) + }); } else { - activeFilters.push({ ...filter, openOnMount: false }) + activeFilters.push({ ...filter, openOnMount: false }); } } - }) + }); - return activeFilters -} + return activeFilters; +}; diff --git a/src/components/table/data-table/data-table-filter/date-filter.tsx b/src/components/table/data-table/data-table-filter/date-filter.tsx index 48926942..2ded191c 100644 --- a/src/components/table/data-table/data-table-filter/date-filter.tsx +++ b/src/components/table/data-table/data-table-filter/date-filter.tsx @@ -1,37 +1,41 @@ -import { EllipseMiniSolid } from "@medusajs/icons" -import { DatePicker, Text, clx } from "@medusajs/ui" -import isEqual from "lodash/isEqual" -import { Popover as RadixPopover } from "radix-ui" -import { useMemo, useState } from "react" - -import { t } from "i18next" -import { useTranslation } from "react-i18next" -import { useDate } from "../../../../hooks/use-date" -import { useSelectedParams } from "../hooks" -import { useDataTableFilterContext } from "./context" -import FilterChip from "./filter-chip" -import { IFilter } from "./types" - -type DateFilterProps = IFilter +import { useMemo, useState } from "react"; + +import { EllipseMiniSolid } from "@medusajs/icons"; +import { DatePicker, Text, clx } from "@medusajs/ui"; + +import { t } from "i18next"; +import isEqual from "lodash/isEqual"; +import { Popover as RadixPopover } from "radix-ui"; +import { useTranslation } from "react-i18next"; + +import { useSelectedParams } from "@components/table/data-table/hooks"; + +import { useDate } from "@hooks/use-date"; + +import { useDataTableFilterContext } from "./context"; +import FilterChip from "./filter-chip"; +import type { IFilter } from "./types"; + +type DateFilterProps = IFilter; type DateComparisonOperator = { /** * The filtered date must be greater than or equal to this value. */ - $gte?: string + $gte?: string; /** * The filtered date must be less than or equal to this value. */ - $lte?: string + $lte?: string; /** * The filtered date must be less than this value. */ - $lt?: string + $lt?: string; /** * The filtered date must be greater than this value. */ - $gt?: string -} + $gt?: string; +}; export const DateFilter = ({ filter, @@ -39,96 +43,98 @@ export const DateFilter = ({ readonly, openOnMount, }: DateFilterProps) => { - const [open, setOpen] = useState(openOnMount) - const [showCustom, setShowCustom] = useState(false) + const [open, setOpen] = useState(openOnMount); + const [showCustom, setShowCustom] = useState(false); - const { getFullDate } = useDate() + const { getFullDate } = useDate(); - const { key, label } = filter + const { key, label } = filter; - const { removeFilter } = useDataTableFilterContext() - const selectedParams = useSelectedParams({ param: key, prefix }) + const { removeFilter } = useDataTableFilterContext(); + const selectedParams = useSelectedParams({ param: key, prefix }); - const presets = usePresets() + const presets = usePresets(); const handleSelectPreset = (value: DateComparisonOperator) => { - selectedParams.add(JSON.stringify(value)) - setShowCustom(false) - } + selectedParams.add(JSON.stringify(value)); + setShowCustom(false); + }; const handleSelectCustom = () => { - selectedParams.delete() - setShowCustom((prev) => !prev) - } + selectedParams.delete(); + setShowCustom((prev) => !prev); + }; - const currentValue = selectedParams.get() + const currentValue = selectedParams.get(); - const currentDateComparison = parseDateComparison(currentValue) - const customStartValue = getDateFromComparison(currentDateComparison, "$gte") - const customEndValue = getDateFromComparison(currentDateComparison, "$lte") + const currentDateComparison = parseDateComparison(currentValue); + const customStartValue = getDateFromComparison(currentDateComparison, "$gte"); + const customEndValue = getDateFromComparison(currentDateComparison, "$lte"); const handleCustomDateChange = (value: Date | null, pos: "start" | "end") => { - const key = pos === "start" ? "$gte" : "$lte" + const key = pos === "start" ? "$gte" : "$lte"; - let dateValue = value + let dateValue = value; // offset to the end of the day so the results include the selected end date if (key === "$lte" && value) { - dateValue = new Date(value.getTime()) - dateValue.setHours(23, 59, 59, 999) + dateValue = new Date(value.getTime()); + dateValue.setHours(23, 59, 59, 999); } selectedParams.add( JSON.stringify({ ...(currentDateComparison || {}), [key]: dateValue?.toISOString(), - }) - ) - } + }), + ); + }; const getDisplayValueFromPresets = () => { - const preset = presets.find((p) => isEqual(p.value, currentDateComparison)) - return preset?.label - } + const preset = presets.find((p) => isEqual(p.value, currentDateComparison)); + + return preset?.label; + }; const formatCustomDate = (date: Date | undefined) => { - return date ? getFullDate({ date: date }) : undefined - } + return date ? getFullDate({ date: date }) : undefined; + }; const getCustomDisplayValue = () => { const formattedDates = [customStartValue, customEndValue].map( - formatCustomDate - ) - return formattedDates.filter(Boolean).join(" - ") - } + formatCustomDate, + ); - const displayValue = getDisplayValueFromPresets() || getCustomDisplayValue() + return formattedDates.filter(Boolean).join(" - "); + }; + + const displayValue = getDisplayValueFromPresets() || getCustomDisplayValue(); const [previousValue, setPreviousValue] = useState( - displayValue - ) + displayValue, + ); const handleRemove = () => { - selectedParams.delete() - removeFilter(key) - } + selectedParams.delete(); + removeFilter(key); + }; - let timeoutId: ReturnType | null = null + let timeoutId: ReturnType | null = null; const handleOpenChange = (open: boolean) => { - setOpen(open) - setPreviousValue(displayValue) + setOpen(open); + setPreviousValue(displayValue); if (timeoutId) { - clearTimeout(timeoutId) + clearTimeout(timeoutId); } if (!open && !currentValue.length) { timeoutId = setTimeout(() => { - removeFilter(key) - }, 200) + removeFilter(key); + }, 200); } - } + }; return ( @@ -147,7 +153,7 @@ export const DateFilter = ({ sideOffset={8} collisionPadding={24} className={clx( - "bg-ui-bg-base text-ui-fg-base shadow-elevation-flyout h-full max-h-[var(--radix-popper-available-height)] w-[300px] overflow-auto rounded-lg" + "h-full max-h-[var(--radix-popper-available-height)] w-[300px] overflow-auto rounded-lg bg-ui-bg-base text-ui-fg-base shadow-elevation-flyout", )} onInteractOutside={(e) => { if (e.target instanceof HTMLElement) { @@ -155,7 +161,7 @@ export const DateFilter = ({ e.target.attributes.getNamedItem("data-name")?.value === "filters_menu_content" ) { - e.preventDefault() + e.preventDefault(); } } }} @@ -164,22 +170,23 @@ export const DateFilter = ({ {presets.map((preset) => { const isSelected = selectedParams .get() - .includes(JSON.stringify(preset.value)) + .includes(JSON.stringify(preset.value)); + return (
  • - ) + ); })}
  • )}
  • - ) -} + ); +}; -export default FilterChip +export default FilterChip; diff --git a/src/components/table/data-table/data-table-filter/index.ts b/src/components/table/data-table/data-table-filter/index.ts index 8363bf9a..513fb81e 100644 --- a/src/components/table/data-table/data-table-filter/index.ts +++ b/src/components/table/data-table/data-table-filter/index.ts @@ -1 +1 @@ -export * from "./data-table-filter" +export * from "./data-table-filter"; diff --git a/src/components/table/data-table/data-table-filter/number-filter.tsx b/src/components/table/data-table/data-table-filter/number-filter.tsx index 2d888618..bf828faa 100644 --- a/src/components/table/data-table/data-table-filter/number-filter.tsx +++ b/src/components/table/data-table/data-table-filter/number-filter.tsx @@ -1,23 +1,27 @@ -import { EllipseMiniSolid } from "@medusajs/icons" -import { Input, Label, clx } from "@medusajs/ui" -import { debounce } from "lodash" +import type { ChangeEvent } from "react"; +import { useCallback, useEffect, useState } from "react"; + +import { EllipseMiniSolid } from "@medusajs/icons"; +import { Input, Label, clx } from "@medusajs/ui"; + +import type { TFunction } from "i18next"; +import { debounce } from "lodash"; import { Popover as RadixPopover, RadioGroup as RadixRadioGroup, -} from "radix-ui" -import { ChangeEvent, useCallback, useEffect, useState } from "react" -import { useTranslation } from "react-i18next" +} from "radix-ui"; +import { useTranslation } from "react-i18next"; + +import { useSelectedParams } from "@components/table/data-table/hooks"; -import { TFunction } from "i18next" -import { useSelectedParams } from "../hooks" -import { useDataTableFilterContext } from "./context" -import FilterChip from "./filter-chip" -import { IFilter } from "./types" +import { useDataTableFilterContext } from "./context"; +import FilterChip from "./filter-chip"; +import type { IFilter } from "./types"; -type NumberFilterProps = IFilter +type NumberFilterProps = IFilter; -type Comparison = "exact" | "range" -type Operator = "lt" | "gt" | "eq" +type Comparison = "exact" | "range"; +type Operator = "lt" | "gt" | "eq"; export const NumberFilter = ({ filter, @@ -25,98 +29,100 @@ export const NumberFilter = ({ readonly, openOnMount, }: NumberFilterProps) => { - const { t } = useTranslation() - const [open, setOpen] = useState(openOnMount) + const { t } = useTranslation(); + const [open, setOpen] = useState(openOnMount); - const { key, label } = filter + const { key, label } = filter; - const { removeFilter } = useDataTableFilterContext() + const { removeFilter } = useDataTableFilterContext(); const selectedParams = useSelectedParams({ param: key, prefix, multiple: false, - }) + }); - const currentValue = selectedParams.get() + const currentValue = selectedParams.get(); const [previousValue, setPreviousValue] = useState( - currentValue - ) + currentValue, + ); const [operator, setOperator] = useState( - getOperator(currentValue) - ) + getOperator(currentValue), + ); - // eslint-disable-next-line react-hooks/exhaustive-deps const debouncedOnChange = useCallback( debounce((e: ChangeEvent, operator: Operator) => { - const value = e.target.value - const curr = JSON.parse(currentValue?.join(",") || "{}") - const isCurrentNumber = !isNaN(Number(curr)) + const value = e.target.value; + const curr = JSON.parse(currentValue?.join(",") || "{}"); + const isCurrentNumber = !isNaN(Number(curr)); const handleValue = (operator: Operator) => { if (!value && isCurrentNumber) { - selectedParams.delete() - return + selectedParams.delete(); + + return; } if (curr && !value) { - delete curr[operator] - selectedParams.add(JSON.stringify(curr)) - return + delete curr[operator]; + selectedParams.add(JSON.stringify(curr)); + + return; } if (!curr) { - selectedParams.add(JSON.stringify({ [operator]: value })) - return + selectedParams.add(JSON.stringify({ [operator]: value })); + + return; } - selectedParams.add(JSON.stringify({ ...curr, [operator]: value })) - } + selectedParams.add(JSON.stringify({ ...curr, [operator]: value })); + }; switch (operator) { case "eq": if (!value) { - selectedParams.delete() + selectedParams.delete(); } else { - selectedParams.add(value) + selectedParams.add(value); } - break + break; case "lt": case "gt": - handleValue(operator) - break + handleValue(operator); + break; } }, 500), - [selectedParams, currentValue] - ) + [selectedParams, currentValue], + ); useEffect(() => { return () => { - debouncedOnChange.cancel() - } - }, [debouncedOnChange]) + debouncedOnChange.cancel(); + }; + }, [debouncedOnChange]); - let timeoutId: ReturnType | null = null + let timeoutId: ReturnType | null = null; const handleOpenChange = (open: boolean) => { - setOpen(open) - setPreviousValue(currentValue) + setOpen(open); + setPreviousValue(currentValue); if (timeoutId) { - clearTimeout(timeoutId) + clearTimeout(timeoutId); } if (!open && !currentValue.length) { timeoutId = setTimeout(() => { - removeFilter(key) - }, 200) + removeFilter(key); + }, 200); } - } + }; const handleRemove = () => { - selectedParams.delete() - removeFilter(key) - } + selectedParams.delete(); + removeFilter(key); + }; const operators: { operator: Comparison; label: string }[] = [ { @@ -127,14 +133,14 @@ export const NumberFilter = ({ operator: "range", label: t("filters.compare.range"), }, - ] + ]; - const GT_KEY = `${key}-gt` - const LT_KEY = `${key}-lt` - const EQ_KEY = key + const GT_KEY = `${key}-gt`; + const LT_KEY = `${key}-lt`; + const EQ_KEY = key; - const displayValue = parseDisplayValue(currentValue, t) - const previousDisplayValue = parseDisplayValue(previousValue, t) + const displayValue = parseDisplayValue(currentValue, t); + const previousDisplayValue = parseDisplayValue(previousValue, t); return ( @@ -154,7 +160,7 @@ export const NumberFilter = ({ sideOffset={8} collisionPadding={24} className={clx( - "bg-ui-bg-base text-ui-fg-base shadow-elevation-flyout max-h-[var(--radix-popper-available-height)] w-[300px] divide-y overflow-y-auto rounded-lg outline-none" + "max-h-[var(--radix-popper-available-height)] w-[300px] divide-y overflow-y-auto rounded-lg bg-ui-bg-base text-ui-fg-base shadow-elevation-flyout outline-none", )} onInteractOutside={(e) => { if (e.target instanceof HTMLElement) { @@ -162,7 +168,7 @@ export const NumberFilter = ({ e.target.attributes.getNamedItem("data-name")?.value === "filters_menu_content" ) { - e.preventDefault() + e.preventDefault(); } } }} @@ -173,13 +179,15 @@ export const NumberFilter = ({ onValueChange={(val) => setOperator(val as Comparison)} className="flex flex-col items-start" orientation="vertical" + /*@todo fix a11y*/ + /* eslint-disable-next-line jsx-a11y/no-autofocus */ autoFocus > {operators.map((o) => (
    @@ -246,71 +254,71 @@ export const NumberFilter = ({ )} - ) -} + ); +}; const parseDisplayValue = ( value: string[] | null | undefined, - t: TFunction + t: TFunction, ) => { - const parsed = JSON.parse(value?.join(",") || "{}") - let displayValue = "" + const parsed = JSON.parse(value?.join(",") || "{}"); + let displayValue = ""; if (typeof parsed === "object") { - const parts = [] + const parts = []; if (parsed.gt) { - parts.push(t("filters.compare.greaterThanLabel", { value: parsed.gt })) + parts.push(t("filters.compare.greaterThanLabel", { value: parsed.gt })); } if (parsed.lt) { parts.push( t("filters.compare.lessThanLabel", { value: parsed.lt, - }) - ) + }), + ); } - displayValue = parts.join(` ${t("filters.compare.andLabel")} `) + displayValue = parts.join(` ${t("filters.compare.andLabel")} `); } if (typeof parsed === "number") { - displayValue = parsed.toString() + displayValue = parsed.toString(); } - return displayValue -} + return displayValue; +}; const parseValue = (value: string[] | null | undefined) => { if (!value) { - return undefined + return undefined; } - const val = value.join(",") + const val = value.join(","); if (!val) { - return undefined + return undefined; } - return JSON.parse(val) -} + return JSON.parse(val); +}; const getValue = ( value: string[] | null | undefined, - key: Operator + key: Operator, ): number | undefined => { - const parsed = parseValue(value) + const parsed = parseValue(value); if (typeof parsed === "object") { - return parsed[key] + return parsed[key]; } if (typeof parsed === "number" && key === "eq") { - return parsed + return parsed; } - return undefined -} + return undefined; +}; const getOperator = (value?: string[] | null): Comparison | undefined => { - const parsed = parseValue(value) + const parsed = parseValue(value); - return typeof parsed === "object" ? "range" : "exact" -} + return typeof parsed === "object" ? "range" : "exact"; +}; diff --git a/src/components/table/data-table/data-table-filter/select-filter.tsx b/src/components/table/data-table/data-table-filter/select-filter.tsx index fa7ba017..bf8cf147 100644 --- a/src/components/table/data-table/data-table-filter/select-filter.tsx +++ b/src/components/table/data-table/data-table-filter/select-filter.tsx @@ -1,20 +1,23 @@ -import { CheckMini, EllipseMiniSolid, XMarkMini } from "@medusajs/icons" -import { clx } from "@medusajs/ui" -import { Command } from "cmdk" -import { Popover as RadixPopover } from "radix-ui" -import { useState } from "react" -import { useTranslation } from "react-i18next" - -import { useSelectedParams } from "../hooks" -import { useDataTableFilterContext } from "./context" -import FilterChip from "./filter-chip" -import { IFilter } from "./types" +import { useState } from "react"; + +import { CheckMini, EllipseMiniSolid, XMarkMini } from "@medusajs/icons"; +import { clx } from "@medusajs/ui"; + +import { Command } from "cmdk"; +import { Popover as RadixPopover } from "radix-ui"; +import { useTranslation } from "react-i18next"; + +import { useSelectedParams } from "@components/table/data-table/hooks"; + +import { useDataTableFilterContext } from "./context"; +import FilterChip from "./filter-chip"; +import type { IFilter } from "./types"; interface SelectFilterProps extends IFilter { - options: { label: string; value: unknown }[] - readonly?: boolean - multiple?: boolean - searchable?: boolean + options: { label: string; value: unknown }[]; + readonly?: boolean; + multiple?: boolean; + searchable?: boolean; } export const SelectFilter = ({ @@ -26,76 +29,76 @@ export const SelectFilter = ({ options, openOnMount, }: SelectFilterProps) => { - const [open, setOpen] = useState(openOnMount) - const [search, setSearch] = useState("") - const [searchRef, setSearchRef] = useState(null) + const [open, setOpen] = useState(openOnMount); + const [search, setSearch] = useState(""); + const [searchRef, setSearchRef] = useState(null); - const { t } = useTranslation() - const { removeFilter } = useDataTableFilterContext() + const { t } = useTranslation(); + const { removeFilter } = useDataTableFilterContext(); - const { key, label } = filter - const selectedParams = useSelectedParams({ param: key, prefix, multiple }) - const currentValue = selectedParams.get() + const { key, label } = filter; + const selectedParams = useSelectedParams({ param: key, prefix, multiple }); + const currentValue = selectedParams.get(); const labelValues = currentValue .map((v) => options.find((o) => o.value === v)?.label) - .filter(Boolean) as string[] + .filter(Boolean) as string[]; const [previousValue, setPreviousValue] = useState< string | string[] | undefined - >(labelValues) + >(labelValues); const handleRemove = () => { - selectedParams.delete() - removeFilter(key) - } + selectedParams.delete(); + removeFilter(key); + }; - let timeoutId: ReturnType | null = null + let timeoutId: ReturnType | null = null; const handleOpenChange = (open: boolean) => { - setOpen(open) + setOpen(open); - setPreviousValue(labelValues) + setPreviousValue(labelValues); if (timeoutId) { - clearTimeout(timeoutId) + clearTimeout(timeoutId); } if (!open && !currentValue.length) { timeoutId = setTimeout(() => { - removeFilter(key) - }, 200) + removeFilter(key); + }, 200); } - } + }; const handleClearSearch = () => { - setSearch("") + setSearch(""); if (searchRef) { - searchRef.focus() + searchRef.focus(); } - } + }; const handleSelect = (value: unknown) => { - const isSelected = selectedParams.get().includes(String(value)) + const isSelected = selectedParams.get().includes(String(value)); if (isSelected) { - selectedParams.delete(String(value)) + selectedParams.delete(String(value)); } else { - selectedParams.add(String(value)) + selectedParams.add(String(value)); } - } + }; const normalizedValues = labelValues ? Array.isArray(labelValues) ? labelValues : [labelValues] - : null + : null; const normalizedPrev = previousValue ? Array.isArray(previousValue) ? previousValue : [previousValue] - : null + : null; return ( @@ -115,7 +118,7 @@ export const SelectFilter = ({ sideOffset={8} collisionPadding={8} className={clx( - "bg-ui-bg-base text-ui-fg-base shadow-elevation-flyout z-[1] h-full max-h-[200px] w-[300px] overflow-hidden rounded-lg outline-none" + "z-[1] h-full max-h-[200px] w-[300px] overflow-hidden rounded-lg bg-ui-bg-base text-ui-fg-base shadow-elevation-flyout outline-none", )} onInteractOutside={(e) => { if (e.target instanceof HTMLElement) { @@ -123,8 +126,8 @@ export const SelectFilter = ({ e.target.attributes.getNamedItem("data-name")?.value === "filters_menu_content" ) { - e.preventDefault() - e.stopPropagation() + e.preventDefault(); + e.stopPropagation(); } } }} @@ -137,7 +140,7 @@ export const SelectFilter = ({ ref={setSearchRef} value={search} onValueChange={setSearch} - className="txt-compact-small placeholder:text-ui-fg-muted bg-transparent outline-none" + className="txt-compact-small bg-transparent outline-none placeholder:text-ui-fg-muted" placeholder="Search" />
    @@ -145,10 +148,10 @@ export const SelectFilter = ({ disabled={!search} onClick={handleClearSearch} className={clx( - "transition-fg text-ui-fg-muted focus-visible:bg-ui-bg-base-pressed rounded-md outline-none", + "rounded-md text-ui-fg-muted outline-none transition-fg focus-visible:bg-ui-bg-base-pressed", { invisible: !search, - } + }, )} > @@ -166,30 +169,30 @@ export const SelectFilter = ({ {options.map((option) => { const isSelected = selectedParams .get() - .includes(String(option.value)) + .includes(String(option.value)); return ( { - handleSelect(option.value) + handleSelect(option.value); }} >
    {multiple ? : }
    {option.label}
    - ) + ); })} @@ -197,5 +200,5 @@ export const SelectFilter = ({ )} - ) -} + ); +}; diff --git a/src/components/table/data-table/data-table-filter/string-filter.tsx b/src/components/table/data-table/data-table-filter/string-filter.tsx index dd1162e3..bdfda11a 100644 --- a/src/components/table/data-table/data-table-filter/string-filter.tsx +++ b/src/components/table/data-table/data-table-filter/string-filter.tsx @@ -1,13 +1,18 @@ -import { Input, Label, clx } from "@medusajs/ui" -import { debounce } from "lodash" -import { Popover as RadixPopover } from "radix-ui" -import { ChangeEvent, useCallback, useEffect, useState } from "react" -import { useSelectedParams } from "../hooks" -import { useDataTableFilterContext } from "./context" -import FilterChip from "./filter-chip" -import { IFilter } from "./types" +import type { ChangeEvent } from "react"; +import { useCallback, useEffect, useState } from "react"; -type StringFilterProps = IFilter +import { Input, Label, clx } from "@medusajs/ui"; + +import { debounce } from "lodash"; +import { Popover as RadixPopover } from "radix-ui"; + +import { useSelectedParams } from "@components/table/data-table/hooks"; + +import { useDataTableFilterContext } from "./context"; +import FilterChip from "./filter-chip"; +import type { IFilter } from "./types"; + +type StringFilterProps = IFilter; export const StringFilter = ({ filter, @@ -15,60 +20,59 @@ export const StringFilter = ({ readonly, openOnMount, }: StringFilterProps) => { - const [open, setOpen] = useState(openOnMount) + const [open, setOpen] = useState(openOnMount); - const { key, label } = filter + const { key, label } = filter; - const { removeFilter } = useDataTableFilterContext() - const selectedParams = useSelectedParams({ param: key, prefix }) + const { removeFilter } = useDataTableFilterContext(); + const selectedParams = useSelectedParams({ param: key, prefix }); - const query = selectedParams.get() + const query = selectedParams.get(); const [previousValue, setPreviousValue] = useState( - query?.[0] - ) + query?.[0], + ); - // eslint-disable-next-line react-hooks/exhaustive-deps const debouncedOnChange = useCallback( debounce((e: ChangeEvent) => { - const value = e.target.value + const value = e.target.value; if (!value) { - selectedParams.delete() + selectedParams.delete(); } else { - selectedParams.add(value) + selectedParams.add(value); } }, 500), - [selectedParams] - ) + [selectedParams], + ); useEffect(() => { return () => { - debouncedOnChange.cancel() - } - }, [debouncedOnChange]) + debouncedOnChange.cancel(); + }; + }, [debouncedOnChange]); - let timeoutId: ReturnType | null = null + let timeoutId: ReturnType | null = null; const handleOpenChange = (open: boolean) => { - setOpen(open) - setPreviousValue(query?.[0]) + setOpen(open); + setPreviousValue(query?.[0]); if (timeoutId) { - clearTimeout(timeoutId) + clearTimeout(timeoutId); } if (!open && !query.length) { timeoutId = setTimeout(() => { - removeFilter(key) - }, 200) + removeFilter(key); + }, 200); } - } + }; const handleRemove = () => { - selectedParams.delete() - removeFilter(key) - } + selectedParams.delete(); + removeFilter(key); + }; return ( @@ -88,7 +92,7 @@ export const StringFilter = ({ sideOffset={8} collisionPadding={8} className={clx( - "bg-ui-bg-base text-ui-fg-base shadow-elevation-flyout z-[1] h-full max-h-[200px] w-[300px] overflow-hidden rounded-lg outline-none" + "z-[1] h-full max-h-[200px] w-[300px] overflow-hidden rounded-lg bg-ui-bg-base text-ui-fg-base shadow-elevation-flyout outline-none", )} onInteractOutside={(e) => { if (e.target instanceof HTMLElement) { @@ -96,8 +100,8 @@ export const StringFilter = ({ e.target.attributes.getNamedItem("data-name")?.value === "filters_menu_content" ) { - e.preventDefault() - e.stopPropagation() + e.preventDefault(); + e.stopPropagation(); } } }} @@ -121,5 +125,5 @@ export const StringFilter = ({ )} - ) -} + ); +}; diff --git a/src/components/table/data-table/data-table-filter/types.ts b/src/components/table/data-table/data-table-filter/types.ts index 598c9200..41b2919a 100644 --- a/src/components/table/data-table/data-table-filter/types.ts +++ b/src/components/table/data-table/data-table-filter/types.ts @@ -1,9 +1,9 @@ export interface IFilter { filter: { - key: string - label: string - } - readonly?: boolean - openOnMount?: boolean - prefix?: string + key: string; + label: string; + }; + readonly?: boolean; + openOnMount?: boolean; + prefix?: string; } From ce7689d5eff33c93e049c7b231eb97c0af1eb157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 09:20:08 +0200 Subject: [PATCH 078/195] eslint/prettier - fix components/table/save-view-dialog --- .../table/save-view-dialog/index.ts | 2 +- .../save-view-dialog/save-view-dialog.tsx | 119 ++++++++++-------- 2 files changed, 69 insertions(+), 52 deletions(-) diff --git a/src/components/table/save-view-dialog/index.ts b/src/components/table/save-view-dialog/index.ts index cbd00a55..e3d4ca3a 100644 --- a/src/components/table/save-view-dialog/index.ts +++ b/src/components/table/save-view-dialog/index.ts @@ -1 +1 @@ -export * from "./save-view-dialog" \ No newline at end of file +export * from "./save-view-dialog"; diff --git a/src/components/table/save-view-dialog/save-view-dialog.tsx b/src/components/table/save-view-dialog/save-view-dialog.tsx index 7f40f2f8..fc44823e 100644 --- a/src/components/table/save-view-dialog/save-view-dialog.tsx +++ b/src/components/table/save-view-dialog/save-view-dialog.tsx @@ -1,35 +1,36 @@ -import React, { useState } from "react" -import { - Button, - Input, - Label, - Drawer, - Heading, - Text, -} from "@medusajs/ui" -import { useForm } from "react-hook-form" -import { useViewConfigurations, useViewConfiguration } from "../../../hooks/use-view-configurations" -import type { ViewConfiguration } from "../../../hooks/use-view-configurations" +import type React from "react"; +import { useState } from "react"; + +import type { HttpTypes } from "@medusajs/types"; +import { Button, Drawer, Heading, Input, Label, Text } from "@medusajs/ui"; + +import { useForm } from "react-hook-form"; +import { + useViewConfiguration, + useViewConfigurations, +} from "@hooks/use-view-configurations.tsx"; type SaveViewFormData = { - name: string -} + name: string; +}; +type ViewConfiguration = + HttpTypes.AdminViewConfigurationResponse["view_configuration"]; interface SaveViewDialogProps { - entity: string + entity: string; currentColumns?: { - visible: string[] - order: string[] - } + visible: string[]; + order: string[]; + }; currentConfiguration?: { - filters?: Record - sorting?: { id: string; desc: boolean } | null - search?: string - } - editingView?: ViewConfiguration | null - onClose: () => void - onSaved: (view: ViewConfiguration) => void + filters?: Record; + sorting?: { id: string; desc: boolean } | null; + search?: string; + }; + editingView?: ViewConfiguration | null; + onClose: () => void; + onSaved: (view: ViewConfiguration) => void; } export const SaveViewDialog: React.FC = ({ @@ -40,9 +41,9 @@ export const SaveViewDialog: React.FC = ({ onClose, onSaved, }) => { - const { createView } = useViewConfigurations(entity) - const { updateView } = useViewConfiguration(entity, editingView?.id || '') - const [isLoading, setIsLoading] = useState(false) + const { createView } = useViewConfigurations(entity); + const { updateView } = useViewConfiguration(entity, editingView?.id || ""); + const [isLoading, setIsLoading] = useState(false); const { register, @@ -52,28 +53,40 @@ export const SaveViewDialog: React.FC = ({ defaultValues: { name: editingView?.name || "", }, - }) + }); const onSubmit = async (data: SaveViewFormData) => { if (!data.name.trim()) { - return + return; } - setIsLoading(true) + setIsLoading(true); try { if (editingView) { // Update existing view const result = await updateView.mutateAsync({ name: data.name.trim(), configuration: { - visible_columns: currentColumns?.visible || editingView.configuration.visible_columns, - column_order: currentColumns?.order || editingView.configuration.column_order, - filters: currentConfiguration?.filters || editingView.configuration.filters || {}, - sorting: currentConfiguration?.sorting || editingView.configuration.sorting || null, - search: currentConfiguration?.search || editingView.configuration.search || "", + visible_columns: + currentColumns?.visible || + editingView.configuration.visible_columns, + column_order: + currentColumns?.order || editingView.configuration.column_order, + filters: + currentConfiguration?.filters || + editingView.configuration.filters || + {}, + sorting: + currentConfiguration?.sorting || + editingView.configuration.sorting || + null, + search: + currentConfiguration?.search || + editingView.configuration.search || + "", }, - }) - onSaved(result.view_configuration) + }); + onSaved(result.view_configuration); } else { // Create new view const result = await createView.mutateAsync({ @@ -86,15 +99,17 @@ export const SaveViewDialog: React.FC = ({ sorting: currentConfiguration?.sorting || null, search: currentConfiguration?.search || "", }, - }) - onSaved(result.view_configuration) + }); + onSaved(result.view_configuration); } + //@todo ts error + // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (error) { // Error is handled by the hook } finally { - setIsLoading(false) + setIsLoading(false); } - } + }; return ( @@ -114,7 +129,10 @@ export const SaveViewDialog: React.FC = ({ -
    +
    - ) -} + ); +}; export const DateHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.date")}
    - ) -} + ); +}; diff --git a/src/components/table/table-cells/common/date-cell/index.ts b/src/components/table/table-cells/common/date-cell/index.ts index 9bf7e52e..98bf7f9f 100644 --- a/src/components/table/table-cells/common/date-cell/index.ts +++ b/src/components/table/table-cells/common/date-cell/index.ts @@ -1 +1 @@ -export * from "./date-cell" +export * from "./date-cell"; From 44e1b00db139fad4de7511646f8b6c343bf31aa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:13:20 +0200 Subject: [PATCH 080/195] eslint/prettier - fix components/table/table-cells/common/created-at-cell --- .../created-at-cell/created-at-cell.tsx | 29 ++++++++++--------- .../common/created-at-cell/index.ts | 2 +- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/components/table/table-cells/common/created-at-cell/created-at-cell.tsx b/src/components/table/table-cells/common/created-at-cell/created-at-cell.tsx index 3b830905..0b1cf7dd 100644 --- a/src/components/table/table-cells/common/created-at-cell/created-at-cell.tsx +++ b/src/components/table/table-cells/common/created-at-cell/created-at-cell.tsx @@ -1,17 +1,20 @@ -import { Tooltip } from "@medusajs/ui" -import { useTranslation } from "react-i18next" -import { useDate } from "../../../../../hooks/use-date" -import { PlaceholderCell } from "../placeholder-cell" +import { Tooltip } from "@medusajs/ui"; + +import { useTranslation } from "react-i18next"; + +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; + +import { useDate } from "@hooks/use-date"; type DateCellProps = { - date: Date | string | undefined -} + date: Date | string | undefined; +}; export const CreatedAtCell = ({ date }: DateCellProps) => { - const { getFullDate } = useDate() + const { getFullDate } = useDate(); if (!date) { - return + return ; } return ( @@ -30,15 +33,15 @@ export const CreatedAtCell = ({ date }: DateCellProps) => {
    - ) -} + ); +}; export const CreatedAtHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.createdAt")}
    - ) -} + ); +}; diff --git a/src/components/table/table-cells/common/created-at-cell/index.ts b/src/components/table/table-cells/common/created-at-cell/index.ts index 2a3ce946..466c927d 100644 --- a/src/components/table/table-cells/common/created-at-cell/index.ts +++ b/src/components/table/table-cells/common/created-at-cell/index.ts @@ -1 +1 @@ -export * from "./created-at-cell" +export * from "./created-at-cell"; From 77ab591e125ba5c5664539acfd414844771ec56e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:13:36 +0200 Subject: [PATCH 081/195] eslint/prettier - fix components/table/table-cells/common/code-cell --- .../common/code-cell/code-cell.tsx | 38 +++++++++---------- .../table-cells/common/code-cell/index.ts | 2 +- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/components/table/table-cells/common/code-cell/code-cell.tsx b/src/components/table/table-cells/common/code-cell/code-cell.tsx index 1f72501e..7e091d14 100644 --- a/src/components/table/table-cells/common/code-cell/code-cell.tsx +++ b/src/components/table/table-cells/common/code-cell/code-cell.tsx @@ -1,27 +1,23 @@ -import { Badge } from "@medusajs/ui" +import { Badge } from "@medusajs/ui"; type CellProps = { - code: string -} + code: string; +}; type HeaderProps = { - text: string -} + text: string; +}; -export const CodeCell = ({ code }: CellProps) => { - return ( -
    - - {code} - -
    - ) -} +export const CodeCell = ({ code }: CellProps) => ( +
    + + {code} + +
    +); -export const CodeHeader = ({ text }: HeaderProps) => { - return ( -
    - {text} -
    - ) -} +export const CodeHeader = ({ text }: HeaderProps) => ( +
    + {text} +
    +); diff --git a/src/components/table/table-cells/common/code-cell/index.ts b/src/components/table/table-cells/common/code-cell/index.ts index a2eb7174..be2795ec 100644 --- a/src/components/table/table-cells/common/code-cell/index.ts +++ b/src/components/table/table-cells/common/code-cell/index.ts @@ -1 +1 @@ -export * from "./code-cell" +export * from "./code-cell"; From 368260bfef4b1aaa33db2a7e5e76a0f521a12f2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:14:13 +0200 Subject: [PATCH 082/195] eslint/prettier - fix components/table/table-cells/common/email-cell --- .../common/email-cell/email-cell.tsx | 21 ++++++++++--------- .../table-cells/common/email-cell/index.ts | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/components/table/table-cells/common/email-cell/email-cell.tsx b/src/components/table/table-cells/common/email-cell/email-cell.tsx index 82563971..2f81cd4f 100644 --- a/src/components/table/table-cells/common/email-cell/email-cell.tsx +++ b/src/components/table/table-cells/common/email-cell/email-cell.tsx @@ -1,28 +1,29 @@ -import { useTranslation } from "react-i18next" -import { PlaceholderCell } from "../placeholder-cell" +import { useTranslation } from "react-i18next"; + +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; type EmailCellProps = { - email?: string | null -} + email?: string | null; +}; export const EmailCell = ({ email }: EmailCellProps) => { if (!email) { - return + return ; } return (
    {email}
    - ) -} + ); +}; export const EmailHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.email")}
    - ) -} + ); +}; diff --git a/src/components/table/table-cells/common/email-cell/index.ts b/src/components/table/table-cells/common/email-cell/index.ts index a65676ca..66d36c73 100644 --- a/src/components/table/table-cells/common/email-cell/index.ts +++ b/src/components/table/table-cells/common/email-cell/index.ts @@ -1 +1 @@ -export * from "./email-cell" +export * from "./email-cell"; From e29de145b660b1fb2db2789e61df29bc553a5642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:15:06 +0200 Subject: [PATCH 083/195] eslint/prettier - fix components/table/table-cells/common/money-amount-cell --- .../common/money-amount-cell/index.ts | 2 +- .../money-amount-cell/money-amount-cell.tsx | 28 ++++++++++--------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/components/table/table-cells/common/money-amount-cell/index.ts b/src/components/table/table-cells/common/money-amount-cell/index.ts index 9c559542..c788a02f 100644 --- a/src/components/table/table-cells/common/money-amount-cell/index.ts +++ b/src/components/table/table-cells/common/money-amount-cell/index.ts @@ -1 +1 @@ -export * from "./money-amount-cell" +export * from "./money-amount-cell"; diff --git a/src/components/table/table-cells/common/money-amount-cell/money-amount-cell.tsx b/src/components/table/table-cells/common/money-amount-cell/money-amount-cell.tsx index 06714047..86220f15 100644 --- a/src/components/table/table-cells/common/money-amount-cell/money-amount-cell.tsx +++ b/src/components/table/table-cells/common/money-amount-cell/money-amount-cell.tsx @@ -1,13 +1,15 @@ -import { clx } from "@medusajs/ui" -import { getStylizedAmount } from "../../../../../lib/money-amount-helpers" -import { PlaceholderCell } from "../placeholder-cell" +import { clx } from "@medusajs/ui"; + +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; + +import { getStylizedAmount } from "@lib/money-amount-helpers"; type MoneyAmountCellProps = { - currencyCode: string - amount?: number | null - align?: "left" | "right" - className?: string -} + currencyCode: string; + amount?: number | null; + align?: "left" | "right"; + className?: string; +}; export const MoneyAmountCell = ({ currencyCode, @@ -16,10 +18,10 @@ export const MoneyAmountCell = ({ className, }: MoneyAmountCellProps) => { if (typeof amount === "undefined" || amount === null) { - return + return ; } - const formatted = getStylizedAmount(amount, currencyCode) + const formatted = getStylizedAmount(amount, currencyCode); return (
    {formatted}
    - ) -} + ); +}; From 8522ae7bb816b9765fcb385b37b2061453210751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:16:13 +0200 Subject: [PATCH 084/195] eslint/prettier - fix components/table/table-cells/common/name-cell --- .../table-cells/common/name-cell/index.ts | 2 +- .../common/name-cell/name-cell.tsx | 25 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/components/table/table-cells/common/name-cell/index.ts b/src/components/table/table-cells/common/name-cell/index.ts index 9002871f..5c6e95cd 100644 --- a/src/components/table/table-cells/common/name-cell/index.ts +++ b/src/components/table/table-cells/common/name-cell/index.ts @@ -1 +1 @@ -export * from "./name-cell" +export * from "./name-cell"; diff --git a/src/components/table/table-cells/common/name-cell/name-cell.tsx b/src/components/table/table-cells/common/name-cell/name-cell.tsx index d9fce020..bc9d456c 100644 --- a/src/components/table/table-cells/common/name-cell/name-cell.tsx +++ b/src/components/table/table-cells/common/name-cell/name-cell.tsx @@ -1,31 +1,32 @@ -import { useTranslation } from "react-i18next" -import { PlaceholderCell } from "../placeholder-cell" +import { useTranslation } from "react-i18next"; + +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; type NameCellProps = { - firstName?: string | null - lastName?: string | null -} + firstName?: string | null; + lastName?: string | null; +}; export const NameCell = ({ firstName, lastName }: NameCellProps) => { if (!firstName && !lastName) { - return + return ; } - const name = [firstName, lastName].filter(Boolean).join(" ") + const name = [firstName, lastName].filter(Boolean).join(" "); return (
    {name}
    - ) -} + ); +}; export const NameHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.name")}
    - ) -} + ); +}; From aa996bc66842e5a7f3ea8be7ccb506e9beeb20de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:16:24 +0200 Subject: [PATCH 085/195] eslint/prettier - fix components/table/table-cells/common/placeholder-cell --- .../table-cells/common/placeholder-cell/index.ts | 2 +- .../common/placeholder-cell/placeholder-cell.tsx | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/components/table/table-cells/common/placeholder-cell/index.ts b/src/components/table/table-cells/common/placeholder-cell/index.ts index 2991d7f0..96684adb 100644 --- a/src/components/table/table-cells/common/placeholder-cell/index.ts +++ b/src/components/table/table-cells/common/placeholder-cell/index.ts @@ -1 +1 @@ -export * from "./placeholder-cell" +export * from "./placeholder-cell"; diff --git a/src/components/table/table-cells/common/placeholder-cell/placeholder-cell.tsx b/src/components/table/table-cells/common/placeholder-cell/placeholder-cell.tsx index 1deeb9bb..126d2280 100644 --- a/src/components/table/table-cells/common/placeholder-cell/placeholder-cell.tsx +++ b/src/components/table/table-cells/common/placeholder-cell/placeholder-cell.tsx @@ -1,7 +1,5 @@ -export const PlaceholderCell = () => { - return ( -
    - - -
    - ) -} +export const PlaceholderCell = () => ( +
    + - +
    +); From c79d245cab018e0c3c2f6d55834b7958c3865e92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:16:48 +0200 Subject: [PATCH 086/195] eslint/prettier - fix components/table/table-cells/common/status-cell --- .../table-cells/common/status-cell/index.ts | 2 +- .../common/status-cell/status-cell.tsx | 53 +++++++++---------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/components/table/table-cells/common/status-cell/index.ts b/src/components/table/table-cells/common/status-cell/index.ts index 8cc5d602..bc82061e 100644 --- a/src/components/table/table-cells/common/status-cell/index.ts +++ b/src/components/table/table-cells/common/status-cell/index.ts @@ -1 +1 @@ -export * from "./status-cell" +export * from "./status-cell"; diff --git a/src/components/table/table-cells/common/status-cell/status-cell.tsx b/src/components/table/table-cells/common/status-cell/status-cell.tsx index 97e8e578..2892878c 100644 --- a/src/components/table/table-cells/common/status-cell/status-cell.tsx +++ b/src/components/table/table-cells/common/status-cell/status-cell.tsx @@ -1,35 +1,34 @@ -import { clx } from "@medusajs/ui" -import { PropsWithChildren } from "react" +import type { PropsWithChildren } from "react"; + +import { clx } from "@medusajs/ui"; type StatusCellProps = PropsWithChildren<{ - color?: "green" | "red" | "blue" | "orange" | "grey" | "purple" -}> + color?: "green" | "red" | "blue" | "orange" | "grey" | "purple"; +}>; /** * @deprecated Use the new DataTable and DataTableStatusCell instead */ -export const StatusCell = ({ color, children }: StatusCellProps) => { - return ( -
    +export const StatusCell = ({ color, children }: StatusCellProps) => ( +
    +
    -
    -
    - {children} + className={clx( + "h-2 w-2 rounded-sm shadow-[0px_0px_0px_1px_rgba(0,0,0,0.12)_inset]", + { + "bg-ui-tag-neutral-icon": color === "grey", + "bg-ui-tag-green-icon": color === "green", + "bg-ui-tag-red-icon": color === "red", + "bg-ui-tag-blue-icon": color === "blue", + "bg-ui-tag-orange-icon": color === "orange", + "bg-ui-tag-purple-icon": color === "purple", + }, + )} + />
    - ) -} + {children} +
    +); From 18c38d22dda0b27b7f04660152be0b144a2e0e68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:18:11 +0200 Subject: [PATCH 087/195] eslint/prettier - fix components/table/table-cells/common/text-cell --- .../table-cells/common/text-cell/index.ts | 2 +- .../common/text-cell/text-cell.tsx | 76 +++++++++++-------- 2 files changed, 44 insertions(+), 34 deletions(-) diff --git a/src/components/table/table-cells/common/text-cell/index.ts b/src/components/table/table-cells/common/text-cell/index.ts index 22f7bca9..9e9b944b 100644 --- a/src/components/table/table-cells/common/text-cell/index.ts +++ b/src/components/table/table-cells/common/text-cell/index.ts @@ -1 +1 @@ -export * from "./text-cell" +export * from "./text-cell"; diff --git a/src/components/table/table-cells/common/text-cell/text-cell.tsx b/src/components/table/table-cells/common/text-cell/text-cell.tsx index 2804ef11..29a1c90e 100644 --- a/src/components/table/table-cells/common/text-cell/text-cell.tsx +++ b/src/components/table/table-cells/common/text-cell/text-cell.tsx @@ -1,49 +1,59 @@ -import { clx } from "@medusajs/ui" -import { ConditionalTooltip } from "../../../../common/conditional-tooltip" -import { PlaceholderCell } from "../placeholder-cell" +import { clx } from "@medusajs/ui"; + +import { ConditionalTooltip } from "@components/common/conditional-tooltip"; +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; type CellProps = { - text?: string | number - align?: "left" | "center" | "right" - maxWidth?: number -} + text?: string | number; + align?: "left" | "center" | "right"; + maxWidth?: number; +}; type HeaderProps = { - text: string - align?: "left" | "center" | "right" -} + text: string; + align?: "left" | "center" | "right"; +}; -export const TextCell = ({ text, align = "left", maxWidth = 220 }: CellProps) => { +export const TextCell = ({ + text, + align = "left", + maxWidth = 220, +}: CellProps) => { if (!text) { - return + return ; } - const stringLength = text.toString().length + const stringLength = text.toString().length; return ( 20}> -
    - {text} -
    +
    + {text} +
    - ) -} + ); +}; -export const TextHeader = ({ text, align = "left" }: HeaderProps) => { - return ( -
    ( +
    - {text} -
    - ) -} + })} + > + {text} +
    +); From 9d804023a2c430b5916e4d79595337ff9c926872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:21:38 +0200 Subject: [PATCH 088/195] eslint/prettier - fix components/table/table-cells/customer/first-seen-cell --- .../first-seen-cell/first-seen-cell.tsx | 23 ++++++++++--------- .../customer/first-seen-cell/index.ts | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/components/table/table-cells/customer/first-seen-cell/first-seen-cell.tsx b/src/components/table/table-cells/customer/first-seen-cell/first-seen-cell.tsx index 58005407..55bee0b4 100644 --- a/src/components/table/table-cells/customer/first-seen-cell/first-seen-cell.tsx +++ b/src/components/table/table-cells/customer/first-seen-cell/first-seen-cell.tsx @@ -1,25 +1,26 @@ -import { useTranslation } from "react-i18next" -import { DateCell } from "../../common/date-cell" -import { PlaceholderCell } from "../../common/placeholder-cell" +import { useTranslation } from "react-i18next"; + +import { DateCell } from "@components/table/table-cells/common/date-cell"; +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; type FirstSeenCellProps = { - createdAt?: Date | string | null -} + createdAt?: Date | string | null; +}; export const FirstSeenCell = ({ createdAt }: FirstSeenCellProps) => { if (!createdAt) { - return + return ; } - return -} + return ; +}; export const FirstSeenHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.createdAt")}
    - ) -} + ); +}; diff --git a/src/components/table/table-cells/customer/first-seen-cell/index.ts b/src/components/table/table-cells/customer/first-seen-cell/index.ts index 7a01262a..8967ba3f 100644 --- a/src/components/table/table-cells/customer/first-seen-cell/index.ts +++ b/src/components/table/table-cells/customer/first-seen-cell/index.ts @@ -1 +1 @@ -export * from "./first-seen-cell" +export * from "./first-seen-cell"; From 7de2a46c09d3b93ded42974cf6011f75031b7643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:21:48 +0200 Subject: [PATCH 089/195] eslint/prettier - fix components/table/table-cells/customer/account-cell --- .../customer/account-cell/account-cell.tsx | 25 ++++++++++--------- .../customer/account-cell/index.ts | 1 + 2 files changed, 14 insertions(+), 12 deletions(-) create mode 100644 src/components/table/table-cells/customer/account-cell/index.ts diff --git a/src/components/table/table-cells/customer/account-cell/account-cell.tsx b/src/components/table/table-cells/customer/account-cell/account-cell.tsx index e69372ac..cc20e6b2 100644 --- a/src/components/table/table-cells/customer/account-cell/account-cell.tsx +++ b/src/components/table/table-cells/customer/account-cell/account-cell.tsx @@ -1,27 +1,28 @@ -import { useTranslation } from "react-i18next" -import { StatusCell } from "../../common/status-cell" +import { useTranslation } from "react-i18next"; + +import { StatusCell } from "@components/table/table-cells/common/status-cell"; type AccountCellProps = { - hasAccount: boolean -} + hasAccount: boolean; +}; export const AccountCell = ({ hasAccount }: AccountCellProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); - const color = hasAccount ? "green" : ("orange" as const) + const color = hasAccount ? "green" : ("orange" as const); const text = hasAccount ? t("customers.fields.registered") - : t("customers.fields.guest") + : t("customers.fields.guest"); - return {text} -} + return {text}; +}; export const AccountHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.account")}
    - ) -} + ); +}; diff --git a/src/components/table/table-cells/customer/account-cell/index.ts b/src/components/table/table-cells/customer/account-cell/index.ts new file mode 100644 index 00000000..91066681 --- /dev/null +++ b/src/components/table/table-cells/customer/account-cell/index.ts @@ -0,0 +1 @@ +export * from "./account-cell"; From 6b75515c9ef2e36d3f55f8c9551eaea955544b39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:22:34 +0200 Subject: [PATCH 090/195] eslint/prettier - fix components/table/table-cells/order/country-cell --- .../order/country-cell/country-cell.tsx | 18 ++++++++++-------- .../table-cells/order/country-cell/index.ts | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/components/table/table-cells/order/country-cell/country-cell.tsx b/src/components/table/table-cells/order/country-cell/country-cell.tsx index e25d14f4..f64dde5e 100644 --- a/src/components/table/table-cells/order/country-cell/country-cell.tsx +++ b/src/components/table/table-cells/order/country-cell/country-cell.tsx @@ -1,15 +1,17 @@ -import { Tooltip } from "@medusajs/ui" -import ReactCountryFlag from "react-country-flag" -import { PlaceholderCell } from "../../common/placeholder-cell" -import { HttpTypes } from "@medusajs/types" +import type { HttpTypes } from "@medusajs/types"; +import { Tooltip } from "@medusajs/ui"; + +import ReactCountryFlag from "react-country-flag"; + +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; export const CountryCell = ({ country, }: { - country?: HttpTypes.AdminRegionCountry | null + country?: HttpTypes.AdminRegionCountry | null; }) => { if (!country) { - return + return ; } return ( @@ -28,5 +30,5 @@ export const CountryCell = ({
    - ) -} + ); +}; diff --git a/src/components/table/table-cells/order/country-cell/index.ts b/src/components/table/table-cells/order/country-cell/index.ts index 81953fd2..2896de8c 100644 --- a/src/components/table/table-cells/order/country-cell/index.ts +++ b/src/components/table/table-cells/order/country-cell/index.ts @@ -1 +1 @@ -export * from "./country-cell" +export * from "./country-cell"; From 2102c51d25cb6d8c538b77c65e5b36455cc0809f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:29:53 +0200 Subject: [PATCH 091/195] eslint/prettier - fix components/table/table-cells/order/customer-cell --- .../order/customer-cell/customer-cell.tsx | 23 ++++++++++--------- .../table-cells/order/customer-cell/index.ts | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/components/table/table-cells/order/customer-cell/customer-cell.tsx b/src/components/table/table-cells/order/customer-cell/customer-cell.tsx index 39d5045a..2bacb538 100644 --- a/src/components/table/table-cells/order/customer-cell/customer-cell.tsx +++ b/src/components/table/table-cells/order/customer-cell/customer-cell.tsx @@ -1,31 +1,32 @@ -import { HttpTypes } from "@medusajs/types" -import { useTranslation } from "react-i18next" +import type { HttpTypes } from "@medusajs/types"; + +import { useTranslation } from "react-i18next"; export const CustomerCell = ({ customer, }: { - customer?: HttpTypes.AdminCustomer | null + customer?: HttpTypes.AdminCustomer | null; }) => { if (!customer) { - return - + return -; } - const { first_name, last_name, email } = customer - const name = [first_name, last_name].filter(Boolean).join(" ") + const { first_name, last_name, email } = customer; + const name = [first_name, last_name].filter(Boolean).join(" "); return (
    {name || email}
    - ) -} + ); +}; export const CustomerHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.customer")}
    - ) -} + ); +}; diff --git a/src/components/table/table-cells/order/customer-cell/index.ts b/src/components/table/table-cells/order/customer-cell/index.ts index dbdd9761..d96cef08 100644 --- a/src/components/table/table-cells/order/customer-cell/index.ts +++ b/src/components/table/table-cells/order/customer-cell/index.ts @@ -1 +1 @@ -export * from "./customer-cell" +export * from "./customer-cell"; From 3b8c30a7bf2560e4b8637f397d411e91f9ec6c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:33:08 +0200 Subject: [PATCH 092/195] eslint/prettier - fix components/table/table-cells/order/display-id-cell --- .../order/display-id-cell/display-id-cell.tsx | 19 ++++++++++--------- .../order/display-id-cell/index.ts | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/components/table/table-cells/order/display-id-cell/display-id-cell.tsx b/src/components/table/table-cells/order/display-id-cell/display-id-cell.tsx index 97d7106b..c950f2e3 100644 --- a/src/components/table/table-cells/order/display-id-cell/display-id-cell.tsx +++ b/src/components/table/table-cells/order/display-id-cell/display-id-cell.tsx @@ -1,24 +1,25 @@ -import { useTranslation } from "react-i18next" -import { PlaceholderCell } from "../../common/placeholder-cell" +import { useTranslation } from "react-i18next"; + +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; export const DisplayIdCell = ({ displayId }: { displayId?: number | null }) => { if (!displayId) { - return + return ; } return ( -
    +
    #{displayId}
    - ) -} + ); +}; export const DisplayIdHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.order")}
    - ) -} + ); +}; diff --git a/src/components/table/table-cells/order/display-id-cell/index.ts b/src/components/table/table-cells/order/display-id-cell/index.ts index 057f15de..ba33c7c1 100644 --- a/src/components/table/table-cells/order/display-id-cell/index.ts +++ b/src/components/table/table-cells/order/display-id-cell/index.ts @@ -1 +1 @@ -export * from "./display-id-cell" +export * from "./display-id-cell"; From 8d1cf924ced0f9eab8557014773703c8fca02ec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:35:37 +0200 Subject: [PATCH 093/195] eslint/prettier - fix components/table/table-cells/order/fulfillment-status-cell --- .../fulfillment-status-cell.tsx | 29 ++++++++++--------- .../order/fulfillment-status-cell/index.ts | 2 +- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/components/table/table-cells/order/fulfillment-status-cell/fulfillment-status-cell.tsx b/src/components/table/table-cells/order/fulfillment-status-cell/fulfillment-status-cell.tsx index 8c767cb8..3ddf1684 100644 --- a/src/components/table/table-cells/order/fulfillment-status-cell/fulfillment-status-cell.tsx +++ b/src/components/table/table-cells/order/fulfillment-status-cell/fulfillment-status-cell.tsx @@ -1,35 +1,36 @@ -import { useTranslation } from "react-i18next" +import type { FulfillmentStatus } from "@medusajs/types"; -import { FulfillmentStatus } from "@medusajs/types" +import { useTranslation } from "react-i18next"; -import { getOrderFulfillmentStatus } from "../../../../../lib/order-helpers" -import { StatusCell } from "../../common/status-cell" +import { StatusCell } from "@components/table/table-cells/common/status-cell"; + +import { getOrderFulfillmentStatus } from "@lib/order-helpers"; type FulfillmentStatusCellProps = { - status: FulfillmentStatus -} + status: FulfillmentStatus; +}; export const FulfillmentStatusCell = ({ status, }: FulfillmentStatusCellProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); if (!status) { // TODO: remove this once fulfillment<>order link is added - return "-" + return "-"; } - const { label, color } = getOrderFulfillmentStatus(t, status) + const { label, color } = getOrderFulfillmentStatus(t, status); - return {label} -} + return {label}; +}; export const FulfillmentStatusHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.fulfillment")}
    - ) -} + ); +}; diff --git a/src/components/table/table-cells/order/fulfillment-status-cell/index.ts b/src/components/table/table-cells/order/fulfillment-status-cell/index.ts index a0f92c11..fb7cf510 100644 --- a/src/components/table/table-cells/order/fulfillment-status-cell/index.ts +++ b/src/components/table/table-cells/order/fulfillment-status-cell/index.ts @@ -1 +1 @@ -export * from "./fulfillment-status-cell" +export * from "./fulfillment-status-cell"; From 4798cf92bb6e6d479a31c508c509bfda3e488295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:37:04 +0200 Subject: [PATCH 094/195] eslint/prettier - fix components/table/table-cells/order/payment-status-cell --- .../order/payment-status-cell/index.ts | 2 +- .../payment-status-cell.tsx | 29 ++++++++++--------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/components/table/table-cells/order/payment-status-cell/index.ts b/src/components/table/table-cells/order/payment-status-cell/index.ts index f6c4b069..8a4618c9 100644 --- a/src/components/table/table-cells/order/payment-status-cell/index.ts +++ b/src/components/table/table-cells/order/payment-status-cell/index.ts @@ -1 +1 @@ -export * from "./payment-status-cell" +export * from "./payment-status-cell"; diff --git a/src/components/table/table-cells/order/payment-status-cell/payment-status-cell.tsx b/src/components/table/table-cells/order/payment-status-cell/payment-status-cell.tsx index 01382e09..c62206f5 100644 --- a/src/components/table/table-cells/order/payment-status-cell/payment-status-cell.tsx +++ b/src/components/table/table-cells/order/payment-status-cell/payment-status-cell.tsx @@ -1,26 +1,29 @@ -import { HttpTypes } from "@medusajs/types" -import { useTranslation } from "react-i18next" -import { getOrderPaymentStatus } from "../../../../../lib/order-helpers" -import { StatusCell } from "../../common/status-cell" +import type { HttpTypes } from "@medusajs/types"; + +import { useTranslation } from "react-i18next"; + +import { StatusCell } from "@components/table/table-cells/common/status-cell"; + +import { getOrderPaymentStatus } from "@lib/order-helpers"; type PaymentStatusCellProps = { - status: HttpTypes.AdminOrder["payment_status"] -} + status: HttpTypes.AdminOrder["payment_status"]; +}; export const PaymentStatusCell = ({ status }: PaymentStatusCellProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); - const { label, color } = getOrderPaymentStatus(t, status) + const { label, color } = getOrderPaymentStatus(t, status); - return {label} -} + return {label}; +}; export const PaymentStatusHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.payment")}
    - ) -} + ); +}; From 1dac6505c57bb8a368f60fe1726217ddc205d869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:37:29 +0200 Subject: [PATCH 095/195] eslint/prettier - fix components/table/table-cells/order/sales-channel-cell --- .../order/sales-channel-cell/index.ts | 2 +- .../sales-channel-cell/sales-channel-cell.tsx | 21 ++++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/components/table/table-cells/order/sales-channel-cell/index.ts b/src/components/table/table-cells/order/sales-channel-cell/index.ts index 8040cf7b..44856df3 100644 --- a/src/components/table/table-cells/order/sales-channel-cell/index.ts +++ b/src/components/table/table-cells/order/sales-channel-cell/index.ts @@ -1 +1 @@ -export * from "./sales-channel-cell" +export * from "./sales-channel-cell"; diff --git a/src/components/table/table-cells/order/sales-channel-cell/sales-channel-cell.tsx b/src/components/table/table-cells/order/sales-channel-cell/sales-channel-cell.tsx index 50a3e0f3..c7fca36d 100644 --- a/src/components/table/table-cells/order/sales-channel-cell/sales-channel-cell.tsx +++ b/src/components/table/table-cells/order/sales-channel-cell/sales-channel-cell.tsx @@ -1,30 +1,31 @@ -import { HttpTypes } from "@medusajs/types" -import { useTranslation } from "react-i18next" +import type { HttpTypes } from "@medusajs/types"; + +import { useTranslation } from "react-i18next"; export const SalesChannelCell = ({ channel, }: { - channel?: HttpTypes.AdminSalesChannel | null + channel?: HttpTypes.AdminSalesChannel | null; }) => { if (!channel) { - return - + return -; } - const { name } = channel + const { name } = channel; return (
    {name}
    - ) -} + ); +}; export const SalesChannelHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.salesChannel")}
    - ) -} + ); +}; From ae91a536c70c386c39935ad34065a24a294b56bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:38:13 +0200 Subject: [PATCH 096/195] eslint/prettier - fix components/table/table-cells/order/total-cell --- .../table-cells/order/total-cell/index.ts | 2 +- .../order/total-cell/total-cell.tsx | 25 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/components/table/table-cells/order/total-cell/index.ts b/src/components/table/table-cells/order/total-cell/index.ts index a58e61c2..5ada0f2c 100644 --- a/src/components/table/table-cells/order/total-cell/index.ts +++ b/src/components/table/table-cells/order/total-cell/index.ts @@ -1 +1 @@ -export * from "./total-cell" +export * from "./total-cell"; diff --git a/src/components/table/table-cells/order/total-cell/total-cell.tsx b/src/components/table/table-cells/order/total-cell/total-cell.tsx index f9543ad9..bbceb28c 100644 --- a/src/components/table/table-cells/order/total-cell/total-cell.tsx +++ b/src/components/table/table-cells/order/total-cell/total-cell.tsx @@ -1,28 +1,29 @@ -import { useTranslation } from "react-i18next" -import { MoneyAmountCell } from "../../common/money-amount-cell" -import { PlaceholderCell } from "../../common/placeholder-cell" +import { useTranslation } from "react-i18next"; + +import { MoneyAmountCell } from "@components/table/table-cells/common/money-amount-cell"; +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; type TotalCellProps = { - currencyCode: string - total: number | null -} + currencyCode: string; + total: number | null; +}; export const TotalCell = ({ currencyCode, total }: TotalCellProps) => { if (!total) { - return + return ; } return ( - ) -} + ); +}; export const TotalHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.total")}
    - ) -} + ); +}; From c8b3680285b0374040b32c423d91127b1bbfb0a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:38:57 +0200 Subject: [PATCH 097/195] eslint/prettier - fix components/table/table-cells/product/collection-cell --- .../collection-cell/collection-cell.tsx | 23 ++++++++++--------- .../product/collection-cell/index.ts | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/components/table/table-cells/product/collection-cell/collection-cell.tsx b/src/components/table/table-cells/product/collection-cell/collection-cell.tsx index bb316c8b..f42513fb 100644 --- a/src/components/table/table-cells/product/collection-cell/collection-cell.tsx +++ b/src/components/table/table-cells/product/collection-cell/collection-cell.tsx @@ -1,30 +1,31 @@ -import { useTranslation } from "react-i18next" +import type { HttpTypes } from "@medusajs/types"; -import { PlaceholderCell } from "../../common/placeholder-cell" -import { HttpTypes } from "@medusajs/types" +import { useTranslation } from "react-i18next"; + +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; type CollectionCellProps = { - collection?: HttpTypes.AdminCollection | null -} + collection?: HttpTypes.AdminCollection | null; +}; export const CollectionCell = ({ collection }: CollectionCellProps) => { if (!collection) { - return + return ; } return (
    {collection.title}
    - ) -} + ); +}; export const CollectionHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.collection")}
    - ) -} + ); +}; diff --git a/src/components/table/table-cells/product/collection-cell/index.ts b/src/components/table/table-cells/product/collection-cell/index.ts index c6184e99..7a6ccd84 100644 --- a/src/components/table/table-cells/product/collection-cell/index.ts +++ b/src/components/table/table-cells/product/collection-cell/index.ts @@ -1 +1 @@ -export * from "./collection-cell" +export * from "./collection-cell"; From d2f6bb6b4f1c0e9fed89093c0109a4a2cc2090c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:39:33 +0200 Subject: [PATCH 098/195] eslint/prettier - fix components/table/table-cells/product/product-cell --- .../table-cells/product/product-cell/index.ts | 2 +- .../product/product-cell/product-cell.tsx | 21 ++++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/components/table/table-cells/product/product-cell/index.ts b/src/components/table/table-cells/product/product-cell/index.ts index d2d7b283..41b9c820 100644 --- a/src/components/table/table-cells/product/product-cell/index.ts +++ b/src/components/table/table-cells/product/product-cell/index.ts @@ -1 +1 @@ -export * from "./product-cell" +export * from "./product-cell"; diff --git a/src/components/table/table-cells/product/product-cell/product-cell.tsx b/src/components/table/table-cells/product/product-cell/product-cell.tsx index f4862cff..7acb1710 100644 --- a/src/components/table/table-cells/product/product-cell/product-cell.tsx +++ b/src/components/table/table-cells/product/product-cell/product-cell.tsx @@ -1,11 +1,12 @@ -import { useTranslation } from "react-i18next" +import type { HttpTypes } from "@medusajs/types"; -import { Thumbnail } from "../../../../common/thumbnail" -import { HttpTypes } from "@medusajs/types" +import { useTranslation } from "react-i18next"; + +import { Thumbnail } from "@components/common/thumbnail"; type ProductCellProps = { - product: Pick -} + product: Pick; +}; export const ProductCell = ({ product }: ProductCellProps) => { return ( @@ -17,15 +18,15 @@ export const ProductCell = ({ product }: ProductCellProps) => { {product.title}
    - ) -} + ); +}; export const ProductHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.product")}
    - ) -} + ); +}; From ace998e89bd32cb3d85cfd97ef1cbc07d745c499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:42:31 +0200 Subject: [PATCH 099/195] eslint/prettier - fix components/table/table-cells/product/product-status-cell --- .../product/product-status-cell/index.ts | 2 +- .../product-status-cell.tsx | 25 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/components/table/table-cells/product/product-status-cell/index.ts b/src/components/table/table-cells/product/product-status-cell/index.ts index c4fd9163..4106ce20 100644 --- a/src/components/table/table-cells/product/product-status-cell/index.ts +++ b/src/components/table/table-cells/product/product-status-cell/index.ts @@ -1 +1 @@ -export * from "./product-status-cell" +export * from "./product-status-cell"; diff --git a/src/components/table/table-cells/product/product-status-cell/product-status-cell.tsx b/src/components/table/table-cells/product/product-status-cell/product-status-cell.tsx index 259f67c1..49e6cd7f 100644 --- a/src/components/table/table-cells/product/product-status-cell/product-status-cell.tsx +++ b/src/components/table/table-cells/product/product-status-cell/product-status-cell.tsx @@ -1,31 +1,32 @@ -import { useTranslation } from "react-i18next" +import type { HttpTypes } from "@medusajs/types"; -import { StatusCell } from "../../common/status-cell" -import { HttpTypes } from "@medusajs/types" +import { useTranslation } from "react-i18next"; + +import { StatusCell } from "@components/table/table-cells/common/status-cell"; type ProductStatusCellProps = { - status: HttpTypes.AdminProductStatus -} + status: HttpTypes.AdminProductStatus; +}; export const ProductStatusCell = ({ status }: ProductStatusCellProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); const [color, text] = { draft: ["grey", t("products.productStatus.draft")], proposed: ["orange", t("products.productStatus.proposed")], published: ["green", t("products.productStatus.published")], rejected: ["red", t("products.productStatus.rejected")], - }[status] as ["grey" | "orange" | "green" | "red", string] + }[status] as ["grey" | "orange" | "green" | "red", string]; - return {text} -} + return {text}; +}; export const ProductStatusHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.status")}
    - ) -} + ); +}; From 935eca56b727e02ec68d278a1c22fa920e7f9a63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:43:13 +0200 Subject: [PATCH 100/195] eslint/prettier - fix components/table/table-cells/product/sales-channels-cell --- .../product/sales-channels-cell/index.ts | 2 +- .../sales-channels-cell.tsx | 33 ++++++++++--------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/components/table/table-cells/product/sales-channels-cell/index.ts b/src/components/table/table-cells/product/sales-channels-cell/index.ts index 9beda926..9bda0e0e 100644 --- a/src/components/table/table-cells/product/sales-channels-cell/index.ts +++ b/src/components/table/table-cells/product/sales-channels-cell/index.ts @@ -1 +1 @@ -export * from "./sales-channels-cell" +export * from "./sales-channels-cell"; diff --git a/src/components/table/table-cells/product/sales-channels-cell/sales-channels-cell.tsx b/src/components/table/table-cells/product/sales-channels-cell/sales-channels-cell.tsx index 1af8ee0a..74b19d92 100644 --- a/src/components/table/table-cells/product/sales-channels-cell/sales-channels-cell.tsx +++ b/src/components/table/table-cells/product/sales-channels-cell/sales-channels-cell.tsx @@ -1,20 +1,21 @@ -import { Tooltip } from "@medusajs/ui" -import { useTranslation } from "react-i18next" +import type { SalesChannelDTO } from "@medusajs/types"; +import { Tooltip } from "@medusajs/ui"; -import { SalesChannelDTO } from "@medusajs/types" -import { PlaceholderCell } from "../../common/placeholder-cell" +import { useTranslation } from "react-i18next"; + +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; type SalesChannelsCellProps = { - salesChannels?: SalesChannelDTO[] | null -} + salesChannels?: SalesChannelDTO[] | null; +}; export const SalesChannelsCell = ({ salesChannels, }: SalesChannelsCellProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); if (!salesChannels || !salesChannels.length) { - return + return ; } if (salesChannels.length > 2) { @@ -42,26 +43,26 @@ export const SalesChannelsCell = ({
    - ) + ); } - const channels = salesChannels.map((sc) => sc.name).join(", ") + const channels = salesChannels.map((sc) => sc.name).join(", "); return ( -
    +
    {channels}
    - ) -} + ); +}; export const SalesChannelHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.salesChannels")}
    - ) -} + ); +}; From f3461bf848405fe963e307c3cb9d06b98c8b658b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:43:40 +0200 Subject: [PATCH 101/195] eslint/prettier - fix components/table/table-cells/product/variant-cell --- .../table-cells/product/variant-cell/index.ts | 2 +- .../product/variant-cell/variant-cell.tsx | 25 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/components/table/table-cells/product/variant-cell/index.ts b/src/components/table/table-cells/product/variant-cell/index.ts index 3a565aa3..72fd989c 100644 --- a/src/components/table/table-cells/product/variant-cell/index.ts +++ b/src/components/table/table-cells/product/variant-cell/index.ts @@ -1 +1 @@ -export * from "./variant-cell" +export * from "./variant-cell"; diff --git a/src/components/table/table-cells/product/variant-cell/variant-cell.tsx b/src/components/table/table-cells/product/variant-cell/variant-cell.tsx index fe2614be..fe59a76f 100644 --- a/src/components/table/table-cells/product/variant-cell/variant-cell.tsx +++ b/src/components/table/table-cells/product/variant-cell/variant-cell.tsx @@ -1,17 +1,18 @@ -import { useTranslation } from "react-i18next" +import type { HttpTypes } from "@medusajs/types"; -import { PlaceholderCell } from "../../common/placeholder-cell" -import { HttpTypes } from "@medusajs/types" +import { useTranslation } from "react-i18next"; + +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; type VariantCellProps = { - variants?: HttpTypes.AdminProductVariant[] | null -} + variants?: HttpTypes.AdminProductVariant[] | null; +}; export const VariantCell = ({ variants }: VariantCellProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); if (!variants || !variants.length) { - return + return ; } return ( @@ -20,15 +21,15 @@ export const VariantCell = ({ variants }: VariantCellProps) => { {t("products.variantCount", { count: variants.length })}
    - ) -} + ); +}; export const VariantHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.variants")}
    - ) -} + ); +}; From 8148fa800d124ae47131ac5ba52ab6aff2b3cb78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:45:21 +0200 Subject: [PATCH 102/195] eslint/prettier - fix components/table/table-cells/promotion/status-cell --- .../table-cells/promotion/status-cell/index.ts | 2 +- .../promotion/status-cell/status-cell.tsx | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/components/table/table-cells/promotion/status-cell/index.ts b/src/components/table/table-cells/promotion/status-cell/index.ts index 8cc5d602..bc82061e 100644 --- a/src/components/table/table-cells/promotion/status-cell/index.ts +++ b/src/components/table/table-cells/promotion/status-cell/index.ts @@ -1 +1 @@ -export * from "./status-cell" +export * from "./status-cell"; diff --git a/src/components/table/table-cells/promotion/status-cell/status-cell.tsx b/src/components/table/table-cells/promotion/status-cell/status-cell.tsx index 6aed3998..1c70baca 100644 --- a/src/components/table/table-cells/promotion/status-cell/status-cell.tsx +++ b/src/components/table/table-cells/promotion/status-cell/status-cell.tsx @@ -1,13 +1,15 @@ -import { HttpTypes } from "@medusajs/types" -import { getPromotionStatus } from "../../../../../lib/promotions" -import { StatusCell as StatusCell_ } from "../../common/status-cell" +import type { HttpTypes } from "@medusajs/types"; + +import { StatusCell as StatusCell_ } from "@components/table/table-cells/common/status-cell"; + +import { getPromotionStatus } from "@lib/promotions"; type PromotionCellProps = { - promotion: HttpTypes.AdminPromotion -} + promotion: HttpTypes.AdminPromotion; +}; export const StatusCell = ({ promotion }: PromotionCellProps) => { - const [color, text] = getPromotionStatus(promotion) + const [color, text] = getPromotionStatus(promotion); - return {text} -} + return {text}; +}; From ca34068dbb06564777007317a9e0c8f6600426bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:46:41 +0200 Subject: [PATCH 103/195] eslint/prettier - fix components/table/table-cells/promotion/region/countries-cell --- .../region/countries-cell/countries-cell.tsx | 32 ++++++++++--------- .../region/countries-cell/index.ts | 2 +- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/components/table/table-cells/region/countries-cell/countries-cell.tsx b/src/components/table/table-cells/region/countries-cell/countries-cell.tsx index 085f18de..9acb9151 100644 --- a/src/components/table/table-cells/region/countries-cell/countries-cell.tsx +++ b/src/components/table/table-cells/region/countries-cell/countries-cell.tsx @@ -1,39 +1,41 @@ -import { HttpTypes } from "@medusajs/types" -import { useTranslation } from "react-i18next" +import type { HttpTypes } from "@medusajs/types"; -import { countries as COUNTRIES } from "../../../../../lib/data/countries" -import { ListSummary } from "../../../../common/list-summary" -import { PlaceholderCell } from "../../common/placeholder-cell" +import { useTranslation } from "react-i18next"; + +import { ListSummary } from "@components/common/list-summary"; +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; + +import { countries as COUNTRIES } from "@lib/data/countries"; type CountriesCellProps = { - countries?: HttpTypes.AdminRegionCountry[] | null -} + countries?: HttpTypes.AdminRegionCountry[] | null; +}; export const CountriesCell = ({ countries }: CountriesCellProps) => { if (!countries || countries.length === 0) { - return + return ; } const list = countries .map( (country) => - COUNTRIES.find((c) => c.iso_2 === country.iso_2)?.display_name + COUNTRIES.find((c) => c.iso_2 === country.iso_2)?.display_name, ) - .filter(Boolean) as string[] + .filter(Boolean) as string[]; return (
    - ) -} + ); +}; export const CountriesHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.countries")}
    - ) -} + ); +}; diff --git a/src/components/table/table-cells/region/countries-cell/index.ts b/src/components/table/table-cells/region/countries-cell/index.ts index eba73ad9..de41befc 100644 --- a/src/components/table/table-cells/region/countries-cell/index.ts +++ b/src/components/table/table-cells/region/countries-cell/index.ts @@ -1 +1 @@ -export * from "./countries-cell" +export * from "./countries-cell"; From 55a41fb2030db1a5b4cc23886be7263f33254bf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:48:40 +0200 Subject: [PATCH 104/195] eslint/prettier - fix components/table/table-cells/promotion/region/fulfillment-providers-cell --- .../fulfillment-providers-cell.tsx | 35 ++++++++++--------- .../fulfillment-providers-cell/index.ts | 2 +- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/components/table/table-cells/region/fulfillment-providers-cell/fulfillment-providers-cell.tsx b/src/components/table/table-cells/region/fulfillment-providers-cell/fulfillment-providers-cell.tsx index 8ac650ac..fa62ad42 100644 --- a/src/components/table/table-cells/region/fulfillment-providers-cell/fulfillment-providers-cell.tsx +++ b/src/components/table/table-cells/region/fulfillment-providers-cell/fulfillment-providers-cell.tsx @@ -1,27 +1,30 @@ -import { useTranslation } from "react-i18next" -import { formatProvider } from "../../../../../lib/format-provider" -import { PlaceholderCell } from "../../common/placeholder-cell" -import { HttpTypes } from "@medusajs/types" +import type { HttpTypes } from "@medusajs/types"; + +import { useTranslation } from "react-i18next"; + +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; + +import { formatProvider } from "@lib/format-provider"; type FulfillmentProvidersCellProps = { - fulfillmentProviders?: HttpTypes.AdminFulfillmentProvider[] | null -} + fulfillmentProviders?: HttpTypes.AdminFulfillmentProvider[] | null; +}; export const FulfillmentProvidersCell = ({ fulfillmentProviders, }: FulfillmentProvidersCellProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); if (!fulfillmentProviders || fulfillmentProviders.length === 0) { - return + return ; } const displayValue = fulfillmentProviders .slice(0, 2) .map((p) => formatProvider(p.id)) - .join(", ") + .join(", "); - const additionalProviders = fulfillmentProviders.slice(2).length + const additionalProviders = fulfillmentProviders.slice(2).length; const text = `${displayValue}${ additionalProviders > 0 @@ -29,21 +32,21 @@ export const FulfillmentProvidersCell = ({ count: additionalProviders, })}` : "" - }` + }`; return (
    {text}
    - ) -} + ); +}; export const FulfillmentProvidersHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.fulfillmentProviders")}
    - ) -} + ); +}; diff --git a/src/components/table/table-cells/region/fulfillment-providers-cell/index.ts b/src/components/table/table-cells/region/fulfillment-providers-cell/index.ts index 59ceb739..70f8434c 100644 --- a/src/components/table/table-cells/region/fulfillment-providers-cell/index.ts +++ b/src/components/table/table-cells/region/fulfillment-providers-cell/index.ts @@ -1 +1 @@ -export * from "./fulfillment-providers-cell" +export * from "./fulfillment-providers-cell"; From 624b53100439388faaadda40cd31ffc4435e3d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:49:53 +0200 Subject: [PATCH 105/195] eslint/prettier - fix components/table/table-cells/promotion/region/payment-providers-cell --- .../region/payment-providers-cell/index.ts | 2 +- .../payment-providers-cell.tsx | 30 ++++++++++--------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/components/table/table-cells/region/payment-providers-cell/index.ts b/src/components/table/table-cells/region/payment-providers-cell/index.ts index 28efce12..4bb6be60 100644 --- a/src/components/table/table-cells/region/payment-providers-cell/index.ts +++ b/src/components/table/table-cells/region/payment-providers-cell/index.ts @@ -1 +1 @@ -export * from "./payment-providers-cell" +export * from "./payment-providers-cell"; diff --git a/src/components/table/table-cells/region/payment-providers-cell/payment-providers-cell.tsx b/src/components/table/table-cells/region/payment-providers-cell/payment-providers-cell.tsx index c7385341..8626082a 100644 --- a/src/components/table/table-cells/region/payment-providers-cell/payment-providers-cell.tsx +++ b/src/components/table/table-cells/region/payment-providers-cell/payment-providers-cell.tsx @@ -1,36 +1,38 @@ -import { useTranslation } from "react-i18next" -import { PaymentProviderDTO } from "@medusajs/types" +import type { PaymentProviderDTO } from "@medusajs/types"; -import { formatProvider } from "../../../../../lib/format-provider" -import { PlaceholderCell } from "../../common/placeholder-cell" -import { ListSummary } from "../../../../common/list-summary" +import { useTranslation } from "react-i18next"; + +import { ListSummary } from "@components/common/list-summary"; +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; + +import { formatProvider } from "@lib/format-provider.ts"; type PaymentProvidersCellProps = { - paymentProviders?: PaymentProviderDTO[] | null -} + paymentProviders?: PaymentProviderDTO[] | null; +}; export const PaymentProvidersCell = ({ paymentProviders, }: PaymentProvidersCellProps) => { if (!paymentProviders || paymentProviders.length === 0) { - return + return ; } - const displayValues = paymentProviders.map((p) => formatProvider(p.id)) + const displayValues = paymentProviders.map((p) => formatProvider(p.id)); return (
    - ) -} + ); +}; export const PaymentProvidersHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.paymentProviders")}
    - ) -} + ); +}; From 069c031f139e3daa144944a8d716a0c54a51747a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:50:20 +0200 Subject: [PATCH 106/195] eslint/prettier - fix components/table/table-cells/promotion/region/region-cell --- .../table-cells/region/region-cell/index.ts | 2 +- .../region/region-cell/region-cell.tsx | 24 +++++++++---------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/components/table/table-cells/region/region-cell/index.ts b/src/components/table/table-cells/region/region-cell/index.ts index 9d2849c7..f9e526b3 100644 --- a/src/components/table/table-cells/region/region-cell/index.ts +++ b/src/components/table/table-cells/region/region-cell/index.ts @@ -1 +1 @@ -export * from "./region-cell" +export * from "./region-cell"; diff --git a/src/components/table/table-cells/region/region-cell/region-cell.tsx b/src/components/table/table-cells/region/region-cell/region-cell.tsx index 2bdd6c16..a4fe214e 100644 --- a/src/components/table/table-cells/region/region-cell/region-cell.tsx +++ b/src/components/table/table-cells/region/region-cell/region-cell.tsx @@ -1,23 +1,21 @@ -import { useTranslation } from "react-i18next" +import { useTranslation } from "react-i18next"; type RegionCellProps = { - name: string -} + name: string; +}; -export const RegionCell = ({ name }: RegionCellProps) => { - return ( -
    - {name} -
    - ) -} +export const RegionCell = ({ name }: RegionCellProps) => ( +
    + {name} +
    +); export const RegionHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.name")}
    - ) -} + ); +}; From ef14f712cfe778429c958fc8ef53f24f3c68c1f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:51:45 +0200 Subject: [PATCH 107/195] eslint/prettier - fix components/table/table-cells/sales-channel-name-cell --- .../sales-channel/name-cell/index.ts | 2 +- .../sales-channel/name-cell/name-cell.tsx | 21 ++++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/components/table/table-cells/sales-channel/name-cell/index.ts b/src/components/table/table-cells/sales-channel/name-cell/index.ts index 9002871f..5c6e95cd 100644 --- a/src/components/table/table-cells/sales-channel/name-cell/index.ts +++ b/src/components/table/table-cells/sales-channel/name-cell/index.ts @@ -1 +1 @@ -export * from "./name-cell" +export * from "./name-cell"; diff --git a/src/components/table/table-cells/sales-channel/name-cell/name-cell.tsx b/src/components/table/table-cells/sales-channel/name-cell/name-cell.tsx index 97cae7a9..b9fe1099 100644 --- a/src/components/table/table-cells/sales-channel/name-cell/name-cell.tsx +++ b/src/components/table/table-cells/sales-channel/name-cell/name-cell.tsx @@ -1,28 +1,29 @@ -import { useTranslation } from "react-i18next" -import { PlaceholderCell } from "../../common/placeholder-cell" +import { useTranslation } from "react-i18next"; + +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; type NameCellProps = { - name?: string | null -} + name?: string | null; +}; export const NameCell = ({ name }: NameCellProps) => { if (!name) { - return + return ; } return (
    {name}
    - ) -} + ); +}; export const NameHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.name")}
    - ) -} + ); +}; From dc1750bd0bb930ad0cae4b092b9816ed4d088a17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:52:02 +0200 Subject: [PATCH 108/195] eslint/prettier - fix components/table/table-cells/sales-channel/description-cell --- .../description-cell/description-cell.tsx | 21 ++++++++++--------- .../sales-channel/description-cell/index.ts | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/components/table/table-cells/sales-channel/description-cell/description-cell.tsx b/src/components/table/table-cells/sales-channel/description-cell/description-cell.tsx index 67d625fa..59a8dde4 100644 --- a/src/components/table/table-cells/sales-channel/description-cell/description-cell.tsx +++ b/src/components/table/table-cells/sales-channel/description-cell/description-cell.tsx @@ -1,28 +1,29 @@ -import { useTranslation } from "react-i18next" -import { PlaceholderCell } from "../../common/placeholder-cell" +import { useTranslation } from "react-i18next"; + +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; type DescriptionCellProps = { - description?: string | null -} + description?: string | null; +}; export const DescriptionCell = ({ description }: DescriptionCellProps) => { if (!description) { - return + return ; } return (
    {description}
    - ) -} + ); +}; export const DescriptionHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.description")}
    - ) -} + ); +}; diff --git a/src/components/table/table-cells/sales-channel/description-cell/index.ts b/src/components/table/table-cells/sales-channel/description-cell/index.ts index 83760e2d..eae702af 100644 --- a/src/components/table/table-cells/sales-channel/description-cell/index.ts +++ b/src/components/table/table-cells/sales-channel/description-cell/index.ts @@ -1 +1 @@ -export * from "./description-cell" +export * from "./description-cell"; From d3a8b143a9f10f84335362f6d31b6d47123c9413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:53:02 +0200 Subject: [PATCH 109/195] eslint/prettier - fix components/table/table-cells/shipping-option/admin-only-cell --- .../admin-only-cell/admin-only-cell.tsx | 25 ++++++++++--------- .../shipping-option/admin-only-cell/index.ts | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/components/table/table-cells/shipping-option/admin-only-cell/admin-only-cell.tsx b/src/components/table/table-cells/shipping-option/admin-only-cell/admin-only-cell.tsx index 5cfce258..1cc12bb7 100644 --- a/src/components/table/table-cells/shipping-option/admin-only-cell/admin-only-cell.tsx +++ b/src/components/table/table-cells/shipping-option/admin-only-cell/admin-only-cell.tsx @@ -1,25 +1,26 @@ -import { useTranslation } from "react-i18next" -import { StatusCell } from "../../common/status-cell" +import { useTranslation } from "react-i18next"; + +import { StatusCell } from "@components/table/table-cells/common/status-cell"; type AdminOnlyCellProps = { - adminOnly: boolean -} + adminOnly: boolean; +}; export const AdminOnlyCell = ({ adminOnly }: AdminOnlyCellProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); - const color = adminOnly ? "blue" : "green" - const text = adminOnly ? t("general.admin") : t("general.store") + const color = adminOnly ? "blue" : "green"; + const text = adminOnly ? t("general.admin") : t("general.store"); - return {text} -} + return {text}; +}; export const AdminOnlyHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.availability")}
    - ) -} + ); +}; diff --git a/src/components/table/table-cells/shipping-option/admin-only-cell/index.ts b/src/components/table/table-cells/shipping-option/admin-only-cell/index.ts index 681a7427..f052d1d6 100644 --- a/src/components/table/table-cells/shipping-option/admin-only-cell/index.ts +++ b/src/components/table/table-cells/shipping-option/admin-only-cell/index.ts @@ -1 +1 @@ -export * from "./admin-only-cell" +export * from "./admin-only-cell"; From 842a96b7bf2b7f64c3581d5414d5f5256173e2f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:55:01 +0200 Subject: [PATCH 110/195] eslint/prettier - fix components/table/table-cells/shipping-option/is-return-cell --- .../shipping-option/is-return-cell/index.ts | 2 +- .../is-return-cell/is-return-cell.tsx | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/table/table-cells/shipping-option/is-return-cell/index.ts b/src/components/table/table-cells/shipping-option/is-return-cell/index.ts index d2c98c20..b645311d 100644 --- a/src/components/table/table-cells/shipping-option/is-return-cell/index.ts +++ b/src/components/table/table-cells/shipping-option/is-return-cell/index.ts @@ -1 +1 @@ -export * from "./is-return-cell" +export * from "./is-return-cell"; diff --git a/src/components/table/table-cells/shipping-option/is-return-cell/is-return-cell.tsx b/src/components/table/table-cells/shipping-option/is-return-cell/is-return-cell.tsx index ac90b44b..1726cee1 100644 --- a/src/components/table/table-cells/shipping-option/is-return-cell/is-return-cell.tsx +++ b/src/components/table/table-cells/shipping-option/is-return-cell/is-return-cell.tsx @@ -1,11 +1,11 @@ -import { useTranslation } from "react-i18next" +import { useTranslation } from "react-i18next"; type IsReturnCellProps = { - isReturn?: boolean -} + isReturn?: boolean; +}; export const IsReturnCell = ({ isReturn }: IsReturnCellProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    @@ -13,15 +13,15 @@ export const IsReturnCell = ({ isReturn }: IsReturnCellProps) => { {isReturn ? t("regions.return") : t("regions.outbound")}
    - ) -} + ); +}; export const IsReturnHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.type")}
    - ) -} + ); +}; From 2265a0a49b44f746a83b154dac968871fe6b5cd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:56:05 +0200 Subject: [PATCH 111/195] eslint/prettier - fix components/table/table-cells/shipping-option/price-type-cell --- .../shipping-option/price-type-cell/index.ts | 2 +- .../price-type-cell/price-type-cell.tsx | 25 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/components/table/table-cells/shipping-option/price-type-cell/index.ts b/src/components/table/table-cells/shipping-option/price-type-cell/index.ts index 74030ad1..17603b35 100644 --- a/src/components/table/table-cells/shipping-option/price-type-cell/index.ts +++ b/src/components/table/table-cells/shipping-option/price-type-cell/index.ts @@ -1 +1 @@ -export * from "./price-type-cell" +export * from "./price-type-cell"; diff --git a/src/components/table/table-cells/shipping-option/price-type-cell/price-type-cell.tsx b/src/components/table/table-cells/shipping-option/price-type-cell/price-type-cell.tsx index 5483fddc..7cd0b80e 100644 --- a/src/components/table/table-cells/shipping-option/price-type-cell/price-type-cell.tsx +++ b/src/components/table/table-cells/shipping-option/price-type-cell/price-type-cell.tsx @@ -1,18 +1,19 @@ -import { useTranslation } from "react-i18next" -import { PlaceholderCell } from "../../common/placeholder-cell" +import { useTranslation } from "react-i18next"; + +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; type PriceTypeCellProps = { - priceType?: "flat_rate" | "calculated" -} + priceType?: "flat_rate" | "calculated"; +}; export const PriceTypeCell = ({ priceType }: PriceTypeCellProps) => { - const { t } = useTranslation() + const { t } = useTranslation(); if (!priceType) { - return + return ; } - const isFlatRate = priceType === "flat_rate" + const isFlatRate = priceType === "flat_rate"; return (
    @@ -20,15 +21,15 @@ export const PriceTypeCell = ({ priceType }: PriceTypeCellProps) => { {isFlatRate ? t("regions.flatRate") : t("regions.calculated")}
    - ) -} + ); +}; export const PriceTypeHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("regions.priceType")}
    - ) -} + ); +}; From f284fd95c04aaed8b69c64cd10a7e49adc6938d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:58:10 +0200 Subject: [PATCH 112/195] eslint/prettier - fix components/table/table-cells/shipping-option/shipping-option-cell --- .../shipping-option-cell/index.ts | 2 +- .../shipping-option-cell.tsx | 21 ++++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/components/table/table-cells/shipping-option/shipping-option-cell/index.ts b/src/components/table/table-cells/shipping-option/shipping-option-cell/index.ts index 5b5fcbb4..8191b838 100644 --- a/src/components/table/table-cells/shipping-option/shipping-option-cell/index.ts +++ b/src/components/table/table-cells/shipping-option/shipping-option-cell/index.ts @@ -1 +1 @@ -export * from "./shipping-option-cell" +export * from "./shipping-option-cell"; diff --git a/src/components/table/table-cells/shipping-option/shipping-option-cell/shipping-option-cell.tsx b/src/components/table/table-cells/shipping-option/shipping-option-cell/shipping-option-cell.tsx index d4b7c437..d6b53267 100644 --- a/src/components/table/table-cells/shipping-option/shipping-option-cell/shipping-option-cell.tsx +++ b/src/components/table/table-cells/shipping-option/shipping-option-cell/shipping-option-cell.tsx @@ -1,28 +1,29 @@ -import { useTranslation } from "react-i18next" -import { PlaceholderCell } from "../../common/placeholder-cell" +import { useTranslation } from "react-i18next"; + +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; type ShippingOptionCellProps = { - name?: string | null -} + name?: string | null; +}; export const ShippingOptionCell = ({ name }: ShippingOptionCellProps) => { if (!name) { - return + return ; } return (
    {name}
    - ) -} + ); +}; export const ShippingOptionHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.name")}
    - ) -} + ); +}; From 06ca662f1f0199ed5da71a82a083923208079f33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 10:59:18 +0200 Subject: [PATCH 113/195] eslint/prettier - fix components/table/table-cells/shipping-option/shipping-price-cell --- .../shipping-price-cell/index.ts | 1 + .../shipping-price-cell.tsx | 27 ++++++++++--------- 2 files changed, 15 insertions(+), 13 deletions(-) create mode 100644 src/components/table/table-cells/shipping-option/shipping-price-cell/index.ts diff --git a/src/components/table/table-cells/shipping-option/shipping-price-cell/index.ts b/src/components/table/table-cells/shipping-option/shipping-price-cell/index.ts new file mode 100644 index 00000000..d34bc8fa --- /dev/null +++ b/src/components/table/table-cells/shipping-option/shipping-price-cell/index.ts @@ -0,0 +1 @@ +export * from "./shipping-price-cell"; diff --git a/src/components/table/table-cells/shipping-option/shipping-price-cell/shipping-price-cell.tsx b/src/components/table/table-cells/shipping-option/shipping-price-cell/shipping-price-cell.tsx index f9cb39ec..97c1c620 100644 --- a/src/components/table/table-cells/shipping-option/shipping-price-cell/shipping-price-cell.tsx +++ b/src/components/table/table-cells/shipping-option/shipping-price-cell/shipping-price-cell.tsx @@ -1,12 +1,13 @@ -import { useTranslation } from "react-i18next" -import { MoneyAmountCell } from "../../common/money-amount-cell" -import { PlaceholderCell } from "../../common/placeholder-cell" +import { useTranslation } from "react-i18next"; + +import { MoneyAmountCell } from "@components/table/table-cells/common/money-amount-cell"; +import { PlaceholderCell } from "@components/table/table-cells/common/placeholder-cell"; type ShippingPriceCellProps = { - isCalculated: boolean - price?: number | null - currencyCode: string -} + isCalculated: boolean; + price?: number | null; + currencyCode: string; +}; export const ShippingPriceCell = ({ price, @@ -14,18 +15,18 @@ export const ShippingPriceCell = ({ isCalculated, }: ShippingPriceCellProps) => { if (isCalculated || !price) { - return + return ; } - return -} + return ; +}; export const ShippingPriceHeader = () => { - const { t } = useTranslation() + const { t } = useTranslation(); return (
    {t("fields.price")}
    - ) -} + ); +}; From dead6e7bf6a62cf0c6fe4056121faccd38185a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 11:02:25 +0200 Subject: [PATCH 114/195] eslint/prettier - fix components/table/table-cells/taxes/type-cell --- .../table-cells/taxes/type-cell/index.ts | 2 +- .../table-cells/taxes/type-cell/type-cell.tsx | 50 +++++++++---------- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/src/components/table/table-cells/taxes/type-cell/index.ts b/src/components/table/table-cells/taxes/type-cell/index.ts index 4db84006..ce89f61c 100644 --- a/src/components/table/table-cells/taxes/type-cell/index.ts +++ b/src/components/table/table-cells/taxes/type-cell/index.ts @@ -1 +1 @@ -export * from "./type-cell" +export * from "./type-cell"; diff --git a/src/components/table/table-cells/taxes/type-cell/type-cell.tsx b/src/components/table/table-cells/taxes/type-cell/type-cell.tsx index 15b41543..d51529bf 100644 --- a/src/components/table/table-cells/taxes/type-cell/type-cell.tsx +++ b/src/components/table/table-cells/taxes/type-cell/type-cell.tsx @@ -1,33 +1,29 @@ -import { Badge } from "@medusajs/ui" +import { Badge } from "@medusajs/ui"; type CellProps = { - is_combinable: boolean -} + is_combinable: boolean; +}; type HeaderProps = { - text: string -} + text: string; +}; -export const TypeCell = ({ is_combinable }: CellProps) => { - return ( -
    - - {is_combinable ? ( - - Combinable - - ) : ( - "" - )} - -
    - ) -} +export const TypeCell = ({ is_combinable }: CellProps) => ( +
    + + {is_combinable ? ( + + Combinable + + ) : ( + "" + )} + +
    +); -export const TypeHeader = ({ text }: HeaderProps) => { - return ( -
    - {text} -
    - ) -} +export const TypeHeader = ({ text }: HeaderProps) => ( +
    + {text} +
    +); From 2d3c0340cb7eb9ca530c3b459b00bc8bf212fb9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 11:21:37 +0200 Subject: [PATCH 115/195] eslint/prettier - fix components/table/view-selector --- src/components/table/view-selector/index.ts | 4 +- .../table/view-selector/view-pills.tsx | 193 +++++++++--------- 2 files changed, 102 insertions(+), 95 deletions(-) diff --git a/src/components/table/view-selector/index.ts b/src/components/table/view-selector/index.ts index b297f544..9bd56376 100644 --- a/src/components/table/view-selector/index.ts +++ b/src/components/table/view-selector/index.ts @@ -1,2 +1,2 @@ -export * from "./view-selector" -export * from "./view-pills" \ No newline at end of file +export * from "./view-selector"; +export * from "./view-pills"; diff --git a/src/components/table/view-selector/view-pills.tsx b/src/components/table/view-selector/view-pills.tsx index ff66cf02..45e9eae1 100644 --- a/src/components/table/view-selector/view-pills.tsx +++ b/src/components/table/view-selector/view-pills.tsx @@ -1,74 +1,76 @@ -import React, { useEffect, useState, useRef } from "react" -import { - Badge, - usePrompt, - toast, - DropdownMenu, -} from "@medusajs/ui" +import type { FC } from "react"; +import { useEffect, useState } from "react"; + +import { ArrowUturnLeft, PencilSquare, Trash } from "@medusajs/icons"; +import { Badge, DropdownMenu, toast, usePrompt } from "@medusajs/ui"; + +import { SaveViewDialog } from "@components/table/save-view-dialog"; + import { - Trash, - PencilSquare, - ArrowUturnLeft, -} from "@medusajs/icons" -import { useViewConfigurations, useViewConfiguration } from "../../../hooks/use-view-configurations" -import type { ViewConfiguration } from "../../../hooks/use-view-configurations" -import { SaveViewDialog } from "../save-view-dialog" + useViewConfiguration, + useViewConfigurations, +} from "@hooks/use-view-configurations"; + +//@todo update ViewConfiguration +import type { ViewConfiguration } from "../../../hooks/use-view-configurations"; interface ViewPillsProps { - entity: string + entity: string; currentColumns?: { - visible: string[] - order: string[] - } + visible: string[]; + order: string[]; + }; currentConfiguration?: { - filters?: Record - sorting?: { id: string; desc: boolean } | null - search?: string - } + filters?: Record; + sorting?: { id: string; desc: boolean } | null; + search?: string; + }; } -export const ViewPills: React.FC = ({ +export const ViewPills: FC = ({ entity, currentColumns, currentConfiguration, }) => { - const { - listViews, - activeView, - setActiveView, - isDefaultViewActive, - } = useViewConfigurations(entity) + const { listViews, activeView, setActiveView, isDefaultViewActive } = + useViewConfigurations(entity); - const views = listViews?.view_configurations || [] + const views = listViews?.view_configurations || []; - const [saveDialogOpen, setSaveDialogOpen] = useState(false) - const [editingView, setEditingView] = useState(null) - const [contextMenuOpen, setContextMenuOpen] = useState(null) - const [contextMenuPosition, setContextMenuPosition] = useState({ x: 0, y: 0 }) - const [deletingViewId, setDeletingViewId] = useState(null) - const prompt = usePrompt() + const [saveDialogOpen, setSaveDialogOpen] = useState(false); + const [editingView, setEditingView] = useState( + null, + ); + const [contextMenuOpen, setContextMenuOpen] = useState(null); + const [contextMenuPosition, setContextMenuPosition] = useState({ + x: 0, + y: 0, + }); + const [deletingViewId, setDeletingViewId] = useState(null); + const prompt = usePrompt(); - const currentActiveView = activeView?.view_configuration || null + const currentActiveView = activeView?.view_configuration || null; // Get delete mutation for the current deleting view - const { deleteView } = useViewConfiguration(entity, deletingViewId || '') + const { deleteView } = useViewConfiguration(entity, deletingViewId || ""); const handleViewSelect = async (viewId: string | null) => { try { if (viewId === null) { // Select default view - clear the active view - await setActiveView.mutateAsync(null) - return + await setActiveView.mutateAsync(null); + + return; } - const view = views.find(v => v.id === viewId) + const view = views.find((v) => v.id === viewId); if (view) { - await setActiveView.mutateAsync(viewId) + await setActiveView.mutateAsync(viewId); } } catch (error) { - console.error("Error in handleViewSelect:", error) + console.error("Error in handleViewSelect:", error); } - } + }; const handleDeleteView = async (view: ViewConfiguration) => { const result = await prompt({ @@ -76,51 +78,57 @@ export const ViewPills: React.FC = ({ description: `Are you sure you want to delete "${view.name}"? This action cannot be undone.`, confirmText: "Delete", cancelText: "Cancel", - }) + }); if (result) { - setDeletingViewId(view.id) + setDeletingViewId(view.id); // The actual deletion will happen in the effect below } - } + }; // Handle deletion when deletingViewId is set useEffect(() => { if (deletingViewId && deleteView.mutateAsync) { - deleteView.mutateAsync().then(() => { - setDeletingViewId(null) - }).catch(() => { - setDeletingViewId(null) - // Error is handled by the hook - }) + deleteView + .mutateAsync() + .then(() => { + setDeletingViewId(null); + }) + .catch(() => { + setDeletingViewId(null); + // Error is handled by the hook + }); } - }, [deletingViewId, deleteView.mutateAsync]) + }, [deletingViewId, deleteView.mutateAsync]); const handleEditView = (view: ViewConfiguration) => { - setEditingView(view) - setSaveDialogOpen(true) - } + setEditingView(view); + setSaveDialogOpen(true); + }; - const handleResetSystemDefault = async (systemDefaultView: ViewConfiguration) => { + const handleResetSystemDefault = async ( + systemDefaultView: ViewConfiguration, + ) => { const result = await prompt({ title: "Reset system default", - description: "This will delete the saved system default and revert to the original code-level defaults. All users will be affected. Are you sure?", + description: + "This will delete the saved system default and revert to the original code-level defaults. All users will be affected. Are you sure?", confirmText: "Reset", cancelText: "Cancel", - }) + }); if (result) { - setDeletingViewId(systemDefaultView.id) + setDeletingViewId(systemDefaultView.id); // The actual deletion will happen in the effect above } - } + }; - const systemDefaultView = views.find(v => v.is_system_default) - const personalViews = views.filter(v => !v.is_system_default) + const systemDefaultView = views.find((v) => v.is_system_default); + const personalViews = views.filter((v) => !v.is_system_default); // Determine if we're showing default - const isDefaultActive = isDefaultViewActive - const defaultLabel = "Default" + const isDefaultActive = isDefaultViewActive; + const defaultLabel = "Default"; return ( <> @@ -133,38 +141,38 @@ export const ViewPills: React.FC = ({ className="cursor-pointer" onClick={() => handleViewSelect(null)} onContextMenu={(e) => { - e.preventDefault() + e.preventDefault(); if (systemDefaultView) { - setContextMenuPosition({ x: e.clientX, y: e.clientY }) - setContextMenuOpen('default') + setContextMenuPosition({ x: e.clientX, y: e.clientY }); + setContextMenuOpen("default"); } }} > {defaultLabel} - {systemDefaultView && contextMenuOpen === 'default' && ( + {systemDefaultView && contextMenuOpen === "default" && ( { - if (!open) setContextMenuOpen(null) + if (!open) setContextMenuOpen(null); }} >
    { - handleResetSystemDefault(systemDefaultView) - setContextMenuOpen(null) + handleResetSystemDefault(systemDefaultView); + setContextMenuOpen(null); }} className="flex items-center gap-x-2" > @@ -188,9 +196,9 @@ export const ViewPills: React.FC = ({ className="cursor-pointer" onClick={() => handleViewSelect(view.id)} onContextMenu={(e) => { - e.preventDefault() - setContextMenuPosition({ x: e.clientX, y: e.clientY }) - setContextMenuOpen(view.id) + e.preventDefault(); + setContextMenuPosition({ x: e.clientX, y: e.clientY }); + setContextMenuOpen(view.id); }} > {view.name} @@ -199,25 +207,25 @@ export const ViewPills: React.FC = ({ { - if (!open) setContextMenuOpen(null) + if (!open) setContextMenuOpen(null); }} >
    { - handleEditView(view) - setContextMenuOpen(null) + handleEditView(view); + setContextMenuOpen(null); }} className="flex items-center gap-x-2" > @@ -226,8 +234,8 @@ export const ViewPills: React.FC = ({ { - handleDeleteView(view) - setContextMenuOpen(null) + handleDeleteView(view); + setContextMenuOpen(null); }} className="flex items-center gap-x-2 text-ui-fg-error" > @@ -239,7 +247,6 @@ export const ViewPills: React.FC = ({ )}
    ))} -
    {saveDialogOpen && ( @@ -249,17 +256,17 @@ export const ViewPills: React.FC = ({ currentConfiguration={currentConfiguration} editingView={editingView} onClose={() => { - setSaveDialogOpen(false) - setEditingView(null) + setSaveDialogOpen(false); + setEditingView(null); }} onSaved={async (newView) => { - setSaveDialogOpen(false) - setEditingView(null) - toast.success(`View "${newView.name}" saved successfully`) + setSaveDialogOpen(false); + setEditingView(null); + toast.success(`View "${newView.name}" saved successfully`); // The view is already set as active in SaveViewDialog }} /> )} - ) -} + ); +}; From ce4a0dda2e9ef855b2b4d674dd85339502036b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Kiliasi=C5=84ski?= Date: Tue, 21 Oct 2025 11:26:25 +0200 Subject: [PATCH 116/195] eslint/prettier - fix components/table/view-selector --- .../table/view-selector/view-selector.tsx | 187 +++++++++--------- 1 file changed, 98 insertions(+), 89 deletions(-) diff --git a/src/components/table/view-selector/view-selector.tsx b/src/components/table/view-selector/view-selector.tsx index e0bd2fd8..634bb908 100644 --- a/src/components/table/view-selector/view-selector.tsx +++ b/src/components/table/view-selector/view-selector.tsx @@ -1,75 +1,73 @@ -import React, { useEffect, useState } from "react" -import { - Select, - Button, - Tooltip, - DropdownMenu, - Badge, - usePrompt, - toast, -} from "@medusajs/ui" -import { +import type { FC } from "react"; +import { useEffect, useState } from "react"; + +import { + ArrowUturnLeft, + CheckCircleSolid, Eye, - EyeSlash, - Plus, - Trash, PencilSquare, + Plus, Star, - CheckCircleSolid, - ArrowUturnLeft, -} from "@medusajs/icons" -import { useViewConfigurations, useViewConfiguration } from "../../../hooks/use-view-configurations" -import type { ViewConfiguration } from "../../../hooks/use-view-configurations" -import { SaveViewDialog } from "../save-view-dialog" + Trash, +} from "@medusajs/icons"; +import { Button, DropdownMenu, Tooltip, usePrompt } from "@medusajs/ui"; + +import { SaveViewDialog } from "@components/table/save-view-dialog"; + +import { + useViewConfiguration, + useViewConfigurations, +} from "@hooks/use-view-configurations.tsx"; + +//@todo update ViewConfiguration +import type { ViewConfiguration } from "../../../hooks/use-view-configurations"; interface ViewSelectorProps { - entity: string - onViewChange?: (view: ViewConfiguration | null) => void + entity: string; + onViewChange?: (view: ViewConfiguration | null) => void; currentColumns?: { - visible: string[] - order: string[] - } + visible: string[]; + order: string[]; + }; } -export const ViewSelector: React.FC = ({ +export const ViewSelector: FC = ({ entity, onViewChange, currentColumns, }) => { - const { - listViews, - activeView, - setActiveView, - isDefaultViewActive, - } = useViewConfigurations(entity) + const { listViews, activeView, setActiveView, isDefaultViewActive } = + useViewConfigurations(entity); - const [saveDialogOpen, setSaveDialogOpen] = useState(false) - const [editingView, setEditingView] = useState(null) - const [deletingViewId, setDeletingViewId] = useState(null) - const prompt = usePrompt() + const [saveDialogOpen, setSaveDialogOpen] = useState(false); + const [editingView, setEditingView] = useState( + null, + ); + const [deletingViewId, setDeletingViewId] = useState(null); + const prompt = usePrompt(); - const views = listViews.data?.view_configurations || [] - const currentActiveView = activeView.data?.view_configuration || null + const views = listViews.data?.view_configurations || []; + const currentActiveView = activeView.data?.view_configuration || null; // Get delete mutation for the current deleting view - const { deleteView } = useViewConfiguration(entity, deletingViewId || '') + const { deleteView } = useViewConfiguration(entity, deletingViewId || ""); // Load views and active view useEffect(() => { if (activeView.isSuccess && onViewChange) { - onViewChange(currentActiveView) + onViewChange(currentActiveView); } - }, [activeView.isSuccess, currentActiveView, onViewChange]) + }, [activeView.isSuccess, currentActiveView, onViewChange]); const handleViewSelect = async (viewId: string) => { - const view = views.find(v => v.id === viewId) + const view = views.find((v) => v.id === viewId); if (view) { - await setActiveView.mutateAsync(viewId) + await setActiveView.mutateAsync(viewId); if (onViewChange) { - onViewChange(view) + onViewChange(view); } } - } + }; const handleDeleteView = async (view: ViewConfiguration) => { const result = await prompt({ @@ -77,54 +75,65 @@ export const ViewSelector: React.FC = ({ description: `Are you sure you want to delete "${view.name}"? This action cannot be undone.`, confirmText: "Delete", cancelText: "Cancel", - }) + }); if (result) { - setDeletingViewId(view.id) + setDeletingViewId(view.id); } - } + }; // Handle deletion when deletingViewId is set useEffect(() => { if (deletingViewId && deleteView.mutateAsync) { - deleteView.mutateAsync().then(() => { - if (currentActiveView?.id === deletingViewId) { - if (onViewChange) { - onViewChange(null) + deleteView + .mutateAsync() + .then(() => { + if (currentActiveView?.id === deletingViewId) { + if (onViewChange) { + onViewChange(null); + } } - } - setDeletingViewId(null) - }).catch(() => { - setDeletingViewId(null) - }) + setDeletingViewId(null); + }) + .catch(() => { + setDeletingViewId(null); + }); } - }, [deletingViewId, deleteView.mutateAsync, currentActiveView?.id, onViewChange]) + }, [ + deletingViewId, + deleteView.mutateAsync, + currentActiveView?.id, + onViewChange, + ]); const handleSaveView = () => { - setSaveDialogOpen(true) - setEditingView(null) - } + setSaveDialogOpen(true); + setEditingView(null); + }; const handleEditView = (view: ViewConfiguration) => { - setEditingView(view) - setSaveDialogOpen(true) - } + setEditingView(view); + setSaveDialogOpen(true); + }; - const handleResetSystemDefault = async (systemDefaultView: ViewConfiguration) => { + const handleResetSystemDefault = async ( + systemDefaultView: ViewConfiguration, + ) => { const result = await prompt({ title: "Reset system default", - description: "This will delete the saved system default and revert to the original code-level defaults. All users will be affected. Are you sure?", + description: + "This will delete the saved system default and revert to the original code-level defaults. All users will be affected. Are you sure?", confirmText: "Reset", cancelText: "Cancel", - }) + }); if (result) { - setDeletingViewId(systemDefaultView.id) + setDeletingViewId(systemDefaultView.id); } - } + }; - const systemDefaultView = views.find(v => v.is_system_default) - const personalViews = views.filter(v => !v.is_system_default) + const systemDefaultView = views.find((v) => v.is_system_default); + const personalViews = views.filter((v) => !v.is_system_default); return ( <> @@ -142,7 +151,7 @@ export const ViewSelector: React.FC = ({ System Default handleViewSelect(systemDefaultView.id)} - className="justify-between group" + className="group justify-between" > @@ -150,7 +159,7 @@ export const ViewSelector: React.FC = ({
    {currentActiveView?.id === systemDefaultView.id && ( - + )}
    @@ -158,8 +167,8 @@ export const ViewSelector: React.FC = ({ variant="transparent" size="small" onClick={(e) => { - e.stopPropagation() - handleResetSystemDefault(systemDefaultView) + e.stopPropagation(); + handleResetSystemDefault(systemDefaultView); }} > @@ -179,21 +188,21 @@ export const ViewSelector: React.FC = ({ handleViewSelect(view.id)} - className="justify-between group" + className="group justify-between" > {view.name}
    {currentActiveView?.id === view.id && ( - + )} -
    +