diff --git a/integration-tests/http/__tests__/product/admin/product-export.spec.ts b/integration-tests/http/__tests__/product/admin/product-export.spec.ts index 4ad050df52b7f..91655030cf699 100644 --- a/integration-tests/http/__tests__/product/admin/product-export.spec.ts +++ b/integration-tests/http/__tests__/product/admin/product-export.spec.ts @@ -12,7 +12,8 @@ import { ModuleRegistrationName } from "@medusajs/utils" jest.setTimeout(50000) const compareCSVs = async (filePath, expectedFilePath) => { - let fileContent = await fs.readFile(filePath, { encoding: "utf-8" }) + const asLocalPath = filePath.replace("http://localhost:9000", process.cwd()) + let fileContent = await fs.readFile(asLocalPath, { encoding: "utf-8" }) let fixturesContent = await fs.readFile(expectedFilePath, { encoding: "utf-8", }) diff --git a/packages/admin-next/dashboard/src/components/table/data-table/data-table-filter/data-table-filter.tsx b/packages/admin-next/dashboard/src/components/table/data-table/data-table-filter/data-table-filter.tsx index 8405f46f4c5c8..77efa132598d0 100644 --- a/packages/admin-next/dashboard/src/components/table/data-table/data-table-filter/data-table-filter.tsx +++ b/packages/admin-next/dashboard/src/components/table/data-table/data-table-filter/data-table-filter.tsx @@ -41,10 +41,15 @@ export type Filter = { type DataTableFilterProps = { filters: Filter[] + readonly?: boolean prefix?: string } -export const DataTableFilter = ({ filters, prefix }: DataTableFilterProps) => { +export const DataTableFilter = ({ + filters, + readonly, + prefix, +}: DataTableFilterProps) => { const { t } = useTranslation() const [searchParams] = useSearchParams() const [open, setOpen] = useState(false) @@ -127,6 +132,7 @@ export const DataTableFilter = ({ filters, prefix }: DataTableFilterProps) => { key={filter.key} filter={filter} prefix={prefix} + readonly={readonly} options={filter.options} multiple={filter.multiple} searchable={filter.searchable} @@ -139,6 +145,7 @@ export const DataTableFilter = ({ filters, prefix }: DataTableFilterProps) => { key={filter.key} filter={filter} prefix={prefix} + readonly={readonly} openOnMount={filter.openOnMount} /> ) @@ -148,6 +155,7 @@ export const DataTableFilter = ({ filters, prefix }: DataTableFilterProps) => { key={filter.key} filter={filter} prefix={prefix} + readonly={readonly} openOnMount={filter.openOnMount} /> ) @@ -157,6 +165,7 @@ export const DataTableFilter = ({ filters, prefix }: DataTableFilterProps) => { key={filter.key} filter={filter} prefix={prefix} + readonly={readonly} openOnMount={filter.openOnMount} /> ) @@ -164,7 +173,7 @@ export const DataTableFilter = ({ filters, prefix }: DataTableFilterProps) => { break } })} - {availableFilters.length > 0 && ( + {!readonly && availableFilters.length > 0 && ( - - ) - })} -
  • - +
  • + ) + })} +
  • + -
  • - - {showCustom && ( -
    -
    -
    - - {t("filters.date.from")} - -
    -
    - handleCustomDateChange(d, "start")} - /> -
    -
    -
    -
    - - {t("filters.date.to")} - +
    + +
    + {t("filters.date.custom")} + + + + {showCustom && ( +
    +
    +
    + + {t("filters.date.from")} + +
    +
    + handleCustomDateChange(d, "start")} + /> +
    -
    - { - handleCustomDateChange(d, "end") - }} - /> +
    +
    + + {t("filters.date.to")} + +
    +
    + { + handleCustomDateChange(d, "end") + }} + /> +
    -
    - )} - - + )} + + + )} ) } @@ -231,10 +239,16 @@ export const DateFilter = ({ type DateDisplayProps = { label: string value?: string + readonly?: boolean onRemove: () => void } -const DateDisplay = ({ label, value, onRemove }: DateDisplayProps) => { +const DateDisplay = ({ + label, + value, + readonly, + onRemove, +}: DateDisplayProps) => { const handleRemove = (e: MouseEvent) => { e.stopPropagation() onRemove() @@ -245,8 +259,10 @@ const DateDisplay = ({ label, value, onRemove }: DateDisplayProps) => { asChild className={clx( "bg-ui-bg-field transition-fg shadow-borders-base text-ui-fg-subtle flex cursor-pointer select-none items-center rounded-md", - "hover:bg-ui-bg-field-hover", - "data-[state=open]:bg-ui-bg-field-hover" + { + "hover:bg-ui-bg-field-hover": !readonly, + "data-[state=open]:bg-ui-bg-field-hover": !readonly, + } )} >
    @@ -268,7 +284,7 @@ const DateDisplay = ({ label, value, onRemove }: DateDisplayProps) => {
    )} - {value && ( + {!readonly && value && (
    + }} + > + + {searchable && ( +
    +
    + +
    + +
    -
    - )} - - - {t("general.noResultsTitle")} - - - - {options.map((option) => { - const isSelected = selectedParams - .get() - .includes(String(option.value)) + )} + + + {t("general.noResultsTitle")} + + + + {options.map((option) => { + const isSelected = selectedParams + .get() + .includes(String(option.value)) - return ( - { - handleSelect(option.value) - }} - > -
    { + handleSelect(option.value) + }} > - {multiple ? : } -
    - {option.label} -
    - ) - })} -
    - - - +
    + {multiple ? : } +
    + {option.label} + + ) + })} +
    + + + + )} ) } type SelectDisplayProps = { label: string + readonly?: boolean value?: string | string[] onRemove: () => void } @@ -185,6 +191,7 @@ export const SelectDisplay = ({ label, value, onRemove, + readonly, }: SelectDisplayProps) => { const { t } = useTranslation() const v = value ? (Array.isArray(value) ? value : [value]) : null @@ -200,8 +207,10 @@ export const SelectDisplay = ({
    )}
    - {v && v.length > 0 && ( + {!readonly && v && v.length > 0 && (
    + + +
    + + + ) +} diff --git a/packages/admin-next/dashboard/src/routes/products/product-import/index.ts b/packages/admin-next/dashboard/src/routes/products/product-import/index.ts new file mode 100644 index 0000000000000..4f065847b31dc --- /dev/null +++ b/packages/admin-next/dashboard/src/routes/products/product-import/index.ts @@ -0,0 +1 @@ +export { ProductImport as Component } from "./product-import" diff --git a/packages/admin-next/dashboard/src/routes/products/product-import/product-import.tsx b/packages/admin-next/dashboard/src/routes/products/product-import/product-import.tsx new file mode 100644 index 0000000000000..d8ac5bf515955 --- /dev/null +++ b/packages/admin-next/dashboard/src/routes/products/product-import/product-import.tsx @@ -0,0 +1,21 @@ +import { Heading } from "@medusajs/ui" +import { RouteDrawer } from "../../../components/modals" +import { useTranslation } from "react-i18next" + +export const ProductImport = () => { + const { t } = useTranslation() + + return ( + + + + {t("products.import.header")} + + + {t("products.import.description")} + + + + + ) +} diff --git a/packages/admin-next/dashboard/src/routes/products/product-list/components/product-list-table/product-list-table.tsx b/packages/admin-next/dashboard/src/routes/products/product-list/components/product-list-table/product-list-table.tsx index 26e08f8a522d0..7d1279cd754c8 100644 --- a/packages/admin-next/dashboard/src/routes/products/product-list/components/product-list-table/product-list-table.tsx +++ b/packages/admin-next/dashboard/src/routes/products/product-list/components/product-list-table/product-list-table.tsx @@ -4,7 +4,7 @@ import { keepPreviousData } from "@tanstack/react-query" import { createColumnHelper } from "@tanstack/react-table" import { useMemo } from "react" import { useTranslation } from "react-i18next" -import { Link, Outlet, useLoaderData } from "react-router-dom" +import { Link, Outlet, useLoaderData, useLocation } from "react-router-dom" import { HttpTypes } from "@medusajs/types" import { ActionMenu } from "../../../../../components/common/action-menu" @@ -23,6 +23,7 @@ const PAGE_SIZE = 20 export const ProductListTable = () => { const { t } = useTranslation() + const location = useLocation() const initialData = useLoaderData() as Awaited< ReturnType> @@ -59,9 +60,17 @@ export const ProductListTable = () => {
    {t("products.domain")} - +
    + + {/* */} + +
    ( diff --git a/packages/modules/providers/file-local/src/services/local-file.ts b/packages/modules/providers/file-local/src/services/local-file.ts index 312246f076b65..808127aac4d58 100644 --- a/packages/modules/providers/file-local/src/services/local-file.ts +++ b/packages/modules/providers/file-local/src/services/local-file.ts @@ -77,7 +77,6 @@ export class LocalFileService extends AbstractFileProviderService { return } - // For private files, we simply return the file path, which can then be loaded manually by the backend. // The local file provider doesn't support presigned URLs for private files (i.e files not placed in /static). async getPresignedDownloadUrl( file: FileTypes.ProviderGetFileDTO @@ -96,10 +95,6 @@ export class LocalFileService extends AbstractFileProviderService { ) } - if (isPrivate) { - return filePath - } - return this.getUploadFileUrl(file.fileKey) }