Add order details new column picker (#3934)
Co-authored-by: Renata <renata.gajzlerowicz@gmail.com> Co-authored-by: wojteknowacki <124166231+wojteknowacki@users.noreply.github.com> Co-authored-by: wojteknowacki <wojciech.nowacki@saleor.io>
This commit is contained in:
parent
9d0233e466
commit
8592c6a4dc
14 changed files with 386 additions and 232 deletions
5
.changeset/gold-crews-cry.md
Normal file
5
.changeset/gold-crews-cry.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"saleor-dashboard": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Introduce new column picker on order details datagrids
|
|
@ -13,7 +13,11 @@ import {
|
||||||
createCustomer,
|
createCustomer,
|
||||||
updateOrdersSettings,
|
updateOrdersSettings,
|
||||||
} from "../../support/api/requests/";
|
} from "../../support/api/requests/";
|
||||||
import { createShipping, getDefaultChannel } from "../../support/api/utils/";
|
import {
|
||||||
|
createShipping,
|
||||||
|
createUnconfirmedOrder,
|
||||||
|
getDefaultChannel,
|
||||||
|
} from "../../support/api/utils/";
|
||||||
import * as productsUtils from "../../support/api/utils/products/productsUtils";
|
import * as productsUtils from "../../support/api/utils/products/productsUtils";
|
||||||
import { ensureCanvasStatic } from "../../support/customCommands/sharedElementsOperations/canvas";
|
import { ensureCanvasStatic } from "../../support/customCommands/sharedElementsOperations/canvas";
|
||||||
import {
|
import {
|
||||||
|
@ -24,10 +28,12 @@ import {
|
||||||
describe("Draft orders", () => {
|
describe("Draft orders", () => {
|
||||||
const startsWith = "CyDraftOrders-";
|
const startsWith = "CyDraftOrders-";
|
||||||
const randomName = startsWith + faker.datatype.number();
|
const randomName = startsWith + faker.datatype.number();
|
||||||
|
let customer;
|
||||||
let defaultChannel;
|
let defaultChannel;
|
||||||
let warehouse;
|
let warehouse;
|
||||||
let address;
|
let address;
|
||||||
|
let variantsList;
|
||||||
|
let shippingMethod;
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
cy.clearSessionData().loginUserViaRequest();
|
cy.clearSessionData().loginUserViaRequest();
|
||||||
|
@ -46,19 +52,25 @@ describe("Draft orders", () => {
|
||||||
randomName,
|
randomName,
|
||||||
addresses.plAddress,
|
addresses.plAddress,
|
||||||
true,
|
true,
|
||||||
);
|
).then(customerResp => {
|
||||||
|
customer = customerResp.user;
|
||||||
|
});
|
||||||
createShipping({
|
createShipping({
|
||||||
channelId: defaultChannel.id,
|
channelId: defaultChannel.id,
|
||||||
name: randomName,
|
name: randomName,
|
||||||
address: addresses.plAddress,
|
address: addresses.plAddress,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(({ warehouse: warehouseResp }) => {
|
.then(
|
||||||
|
({ warehouse: warehouseResp, shippingMethod: shippingMethodResp }) => {
|
||||||
warehouse = warehouseResp;
|
warehouse = warehouseResp;
|
||||||
|
shippingMethod = shippingMethodResp;
|
||||||
|
|
||||||
productsUtils.createTypeAttributeAndCategoryForProduct({
|
productsUtils.createTypeAttributeAndCategoryForProduct({
|
||||||
name: randomName,
|
name: randomName,
|
||||||
});
|
});
|
||||||
})
|
},
|
||||||
|
)
|
||||||
.then(
|
.then(
|
||||||
({
|
({
|
||||||
productType: productTypeResp,
|
productType: productTypeResp,
|
||||||
|
@ -74,8 +86,11 @@ describe("Draft orders", () => {
|
||||||
categoryId: categoryResp.id,
|
categoryId: categoryResp.id,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
cy.checkIfDataAreNotNull({ defaultChannel, warehouse, address }),
|
)
|
||||||
);
|
.then(({ variantsList: variantsResp, product }) => {
|
||||||
|
variantsList = variantsResp;
|
||||||
|
cy.checkIfDataAreNotNull({ defaultChannel, warehouse, address });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -115,4 +130,53 @@ describe("Draft orders", () => {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
it(
|
||||||
|
"should be able to turn of all but one static columns on draft orders detail. TC: SALEOR_2135",
|
||||||
|
{ tags: ["@orders", "@allEnv", "@stable"] },
|
||||||
|
() => {
|
||||||
|
let order;
|
||||||
|
createUnconfirmedOrder({
|
||||||
|
customerId: customer.id,
|
||||||
|
channelId: defaultChannel.id,
|
||||||
|
shippingMethod,
|
||||||
|
variantsList,
|
||||||
|
address,
|
||||||
|
warehouse: warehouse.id,
|
||||||
|
}).then(({ order: orderResp }) => {
|
||||||
|
order = orderResp;
|
||||||
|
cy.visit(urlList.orders + `${order.id}`);
|
||||||
|
cy.openColumnPicker();
|
||||||
|
cy.get(SHARED_ELEMENTS.staticColumnContainer)
|
||||||
|
.should("contain.text", "Product")
|
||||||
|
.should("contain.text", "SKU")
|
||||||
|
.should("contain.text", "Variant")
|
||||||
|
.should("contain.text", "Quantity")
|
||||||
|
.should("contain.text", "Price")
|
||||||
|
.should("contain.text", "Total")
|
||||||
|
.should("contain.text", "Status");
|
||||||
|
// switching off all but one static columns
|
||||||
|
cy.get(SHARED_ELEMENTS.gridStaticSkuButton).click();
|
||||||
|
cy.get(SHARED_ELEMENTS.gridStaticVariantNameButton).click();
|
||||||
|
cy.get(SHARED_ELEMENTS.gridStaticQuantityButton).click();
|
||||||
|
cy.get(SHARED_ELEMENTS.gridStaticPriceButton).click();
|
||||||
|
cy.get(SHARED_ELEMENTS.gridStaticTotalButton).click();
|
||||||
|
cy.get(SHARED_ELEMENTS.gridStaticStatusButton).click();
|
||||||
|
cy.get(SHARED_ELEMENTS.gridStaticProductButton).should(
|
||||||
|
"have.attr",
|
||||||
|
"data-state",
|
||||||
|
"on",
|
||||||
|
);
|
||||||
|
cy.get(SHARED_ELEMENTS.dataGridTable)
|
||||||
|
.find("th")
|
||||||
|
// on draft first th is empty so length need to be 2
|
||||||
|
.should("have.length", 2)
|
||||||
|
.last()
|
||||||
|
.should("have.text", "Product");
|
||||||
|
//next line hides picker
|
||||||
|
cy.get(SHARED_ELEMENTS.pageHeader).click({ force: true });
|
||||||
|
cy.get(SHARED_ELEMENTS.dynamicColumnContainer).should("not.exist");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -574,4 +574,47 @@ describe("Orders", () => {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
it(
|
||||||
|
"should be able to turn off all but one static columns on orders detail. TC: SALEOR_2136",
|
||||||
|
{ tags: ["@orders", "@allEnv", "@stable"] },
|
||||||
|
() => {
|
||||||
|
let order;
|
||||||
|
createReadyToFulfillOrder({
|
||||||
|
customerId: customer.id,
|
||||||
|
channelId: defaultChannel.id,
|
||||||
|
shippingMethod,
|
||||||
|
variantsList,
|
||||||
|
address,
|
||||||
|
}).then(({ order: orderResp }) => {
|
||||||
|
order = orderResp;
|
||||||
|
cy.visit(urlList.orders + `${order.id}`);
|
||||||
|
cy.openColumnPicker();
|
||||||
|
cy.get(SHARED_ELEMENTS.staticColumnContainer)
|
||||||
|
.should("contain.text", "Product")
|
||||||
|
.should("contain.text", "SKU")
|
||||||
|
.should("contain.text", "Variant")
|
||||||
|
.should("contain.text", "Quantity")
|
||||||
|
.should("contain.text", "Price")
|
||||||
|
.should("contain.text", "Total");
|
||||||
|
// switching off all but one static columns
|
||||||
|
cy.get(SHARED_ELEMENTS.gridStaticSkuButton).click();
|
||||||
|
cy.get(SHARED_ELEMENTS.gridStaticVariantNameButton).click();
|
||||||
|
cy.get(SHARED_ELEMENTS.gridStaticQuantityButton).click();
|
||||||
|
cy.get(SHARED_ELEMENTS.gridStaticPriceButton).click();
|
||||||
|
cy.get(SHARED_ELEMENTS.gridStaticTotalButton).click();
|
||||||
|
cy.get(SHARED_ELEMENTS.gridStaticProductButton).should(
|
||||||
|
"have.attr",
|
||||||
|
"data-state",
|
||||||
|
"on",
|
||||||
|
);
|
||||||
|
cy.get(SHARED_ELEMENTS.dataGridTable)
|
||||||
|
.find("th")
|
||||||
|
.should("have.length", 1)
|
||||||
|
.should("have.text", "Product");
|
||||||
|
//next line hides picker
|
||||||
|
cy.get(SHARED_ELEMENTS.pageHeader).click({ force: true });
|
||||||
|
cy.get(SHARED_ELEMENTS.dynamicColumnContainer).should("not.exist");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,11 +16,19 @@ export const SHARED_ELEMENTS = {
|
||||||
activeStaticColumnOnGridButton: '[data-state="on"]',
|
activeStaticColumnOnGridButton: '[data-state="on"]',
|
||||||
dynamicColumnSelector: '[data-test-id="dynamic-column"]',
|
dynamicColumnSelector: '[data-test-id="dynamic-column"]',
|
||||||
dynamicColumnNameSelector: '[data-test-id^="dynamic-column-name"]',
|
dynamicColumnNameSelector: '[data-test-id^="dynamic-column-name"]',
|
||||||
|
gridStaticSkuButton: '[data-test-id="stat-col-sku"]',
|
||||||
|
gridStaticVariantNameButton: '[data-test-id="stat-col-variantName"]',
|
||||||
|
gridStaticQuantityButton: '[data-test-id="stat-col-quantity"]',
|
||||||
|
gridStaticPriceButton: '[data-test-id="stat-col-price"]',
|
||||||
|
gridStaticStatusButton: '[data-test-id="stat-col-status"]',
|
||||||
|
gridStaticTotalButton: '[data-test-id="stat-col-total"]',
|
||||||
|
gridStaticProductButton: '[data-test-id="stat-col-product"]',
|
||||||
dynamicColumnSearchInput: '[data-test-id="search-columns"]',
|
dynamicColumnSearchInput: '[data-test-id="search-columns"]',
|
||||||
selectedDynamicColumnNameSelector: '[data-test-id^="column-name-"]',
|
selectedDynamicColumnNameSelector: '[data-test-id^="column-name-"]',
|
||||||
removeSelectedDynamicColumnButton:
|
removeSelectedDynamicColumnButton:
|
||||||
'[data-test-id^="remove-dynamic-col-button"]',
|
'[data-test-id^="remove-dynamic-col-button"]',
|
||||||
dynamicColumnContainer: '[data-test-id="dynamic-col-container"]',
|
dynamicColumnContainer: '[data-test-id="dynamic-col-container"]',
|
||||||
|
staticColumnContainer: '[data-test-id="static-col-container"]',
|
||||||
paginationForwardOnColumnPicker: '[data-test-id="pagination-forward"]',
|
paginationForwardOnColumnPicker: '[data-test-id="pagination-forward"]',
|
||||||
paginationBackOnColumnPicker: '[data-test-id="pagination-back"]',
|
paginationBackOnColumnPicker: '[data-test-id="pagination-back"]',
|
||||||
notificationSuccess:
|
notificationSuccess:
|
||||||
|
|
|
@ -23,6 +23,9 @@ Cypress.Commands.add("clickSubmitButton", () =>
|
||||||
Cypress.Commands.add("clickConfirmButton", () =>
|
Cypress.Commands.add("clickConfirmButton", () =>
|
||||||
cy.get(BUTTON_SELECTORS.confirm).click(),
|
cy.get(BUTTON_SELECTORS.confirm).click(),
|
||||||
);
|
);
|
||||||
|
Cypress.Commands.add("openColumnPicker", () =>
|
||||||
|
cy.get(SHARED_ELEMENTS.openColumnPickerButton).click(),
|
||||||
|
);
|
||||||
|
|
||||||
Cypress.Commands.add("createNewOption", (selectSelector, newOption) => {
|
Cypress.Commands.add("createNewOption", (selectSelector, newOption) => {
|
||||||
cy.get(selectSelector).type(newOption);
|
cy.get(selectSelector).type(newOption);
|
||||||
|
|
|
@ -60,7 +60,7 @@ export const ColumnPicker = ({
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Popover.Trigger>
|
</Popover.Trigger>
|
||||||
<Popover.Content className={sprinkles({ margin: 1.5 })}>
|
<Popover.Content className={sprinkles({ margin: 1.5 })} align="end">
|
||||||
<Box
|
<Box
|
||||||
display="grid"
|
display="grid"
|
||||||
gridTemplateColumns={expanded ? 2 : 1}
|
gridTemplateColumns={expanded ? 2 : 1}
|
||||||
|
|
|
@ -182,6 +182,11 @@ export const Datagrid: React.FC<DatagridProps> = ({
|
||||||
const columnIndex = availableColumns.findIndex(
|
const columnIndex = availableColumns.findIndex(
|
||||||
column => column.id === recentlyAddedColumn,
|
column => column.id === recentlyAddedColumn,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (columnIndex === -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const datagridScroll = editor.current.scrollTo;
|
const datagridScroll = editor.current.scrollTo;
|
||||||
datagridScroll(columnIndex, 0, "horizontal", 0, 0, { hAlign: "start" });
|
datagridScroll(columnIndex, 0, "horizontal", 0, 0, { hAlign: "start" });
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,8 @@ export interface AppListViewSettings {
|
||||||
[ListViews.WEBHOOK_LIST]: ListSettings;
|
[ListViews.WEBHOOK_LIST]: ListSettings;
|
||||||
[ListViews.TRANSLATION_ATTRIBUTE_VALUE_LIST]: ListSettings;
|
[ListViews.TRANSLATION_ATTRIBUTE_VALUE_LIST]: ListSettings;
|
||||||
[ListViews.GIFT_CARD_LIST]: ListSettings;
|
[ListViews.GIFT_CARD_LIST]: ListSettings;
|
||||||
|
[ListViews.ORDER_DETAILS_LIST]: ListSettings;
|
||||||
|
[ListViews.ORDER_DRAFT_DETAILS_LIST]: ListSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultListSettings: AppListViewSettings = {
|
export const defaultListSettings: AppListViewSettings = {
|
||||||
|
@ -138,6 +140,22 @@ export const defaultListSettings: AppListViewSettings = {
|
||||||
rowNumber: PAGINATE_BY,
|
rowNumber: PAGINATE_BY,
|
||||||
columns: ["giftCardCode", "status", "tag", "product", "usedBy", "balance"],
|
columns: ["giftCardCode", "status", "tag", "product", "usedBy", "balance"],
|
||||||
},
|
},
|
||||||
|
[ListViews.ORDER_DETAILS_LIST]: {
|
||||||
|
rowNumber: PAGINATE_BY,
|
||||||
|
columns: ["product", "sku", "variantName", "quantity", "price", "total"],
|
||||||
|
},
|
||||||
|
[ListViews.ORDER_DRAFT_DETAILS_LIST]: {
|
||||||
|
rowNumber: PAGINATE_BY,
|
||||||
|
columns: [
|
||||||
|
"product",
|
||||||
|
"status",
|
||||||
|
"sku",
|
||||||
|
"variantName",
|
||||||
|
"quantity",
|
||||||
|
"price",
|
||||||
|
"total",
|
||||||
|
],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const APP_VERSION =
|
export const APP_VERSION =
|
||||||
|
|
|
@ -1,20 +1,25 @@
|
||||||
// @ts-strict-ignore
|
// @ts-strict-ignore
|
||||||
import ColumnPicker from "@dashboard/components/ColumnPicker";
|
import { ColumnPicker } from "@dashboard/components/Datagrid/ColumnPicker/ColumnPicker";
|
||||||
|
import { useColumns } from "@dashboard/components/Datagrid/ColumnPicker/useColumns";
|
||||||
import Datagrid from "@dashboard/components/Datagrid/Datagrid";
|
import Datagrid from "@dashboard/components/Datagrid/Datagrid";
|
||||||
import { useColumnsDefault } from "@dashboard/components/Datagrid/hooks/useColumnsDefault";
|
|
||||||
import {
|
import {
|
||||||
DatagridChangeStateContext,
|
DatagridChangeStateContext,
|
||||||
useDatagridChangeState,
|
useDatagridChangeState,
|
||||||
} from "@dashboard/components/Datagrid/hooks/useDatagridChange";
|
} from "@dashboard/components/Datagrid/hooks/useDatagridChange";
|
||||||
import { OrderLineFragment } from "@dashboard/graphql";
|
import { OrderLineFragment } from "@dashboard/graphql";
|
||||||
|
import useListSettings from "@dashboard/hooks/useListSettings";
|
||||||
import { productPath } from "@dashboard/products/urls";
|
import { productPath } from "@dashboard/products/urls";
|
||||||
|
import { ListViews } from "@dashboard/types";
|
||||||
import { ExternalLinkIcon } from "@saleor/macaw-ui/next";
|
import { ExternalLinkIcon } from "@saleor/macaw-ui/next";
|
||||||
import React, { useCallback } from "react";
|
import React, { useCallback, useMemo } from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
import { messages as orderMessages } from "../OrderListDatagrid/messages";
|
import { messages as orderMessages } from "../OrderListDatagrid/messages";
|
||||||
import { useColumns, useGetCellContent } from "./datagrid";
|
import {
|
||||||
|
createGetCellContent,
|
||||||
|
orderDetailsStaticColumnsAdapter,
|
||||||
|
} from "./datagrid";
|
||||||
import { messages } from "./messages";
|
import { messages } from "./messages";
|
||||||
|
|
||||||
interface OrderDetailsDatagridProps {
|
interface OrderDetailsDatagridProps {
|
||||||
|
@ -29,24 +34,44 @@ export const OrderDetailsDatagrid = ({
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const datagrid = useDatagridChangeState();
|
const datagrid = useDatagridChangeState();
|
||||||
|
|
||||||
const availableColumns = useColumns();
|
const { updateListSettings, settings } = useListSettings(
|
||||||
|
ListViews.ORDER_DETAILS_LIST,
|
||||||
|
);
|
||||||
|
|
||||||
|
const orderDetailsStaticColumns = useMemo(
|
||||||
|
() => orderDetailsStaticColumnsAdapter(intl),
|
||||||
|
[intl],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleColumnChange = useCallback(
|
||||||
|
picked => {
|
||||||
|
if (updateListSettings) {
|
||||||
|
updateListSettings("columns", picked.filter(Boolean));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[updateListSettings],
|
||||||
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
availableColumnsChoices,
|
handlers,
|
||||||
columnChoices,
|
visibleColumns,
|
||||||
columns,
|
staticColumns,
|
||||||
defaultColumns,
|
selectedColumns,
|
||||||
onColumnMoved,
|
recentlyAddedColumn,
|
||||||
onColumnResize,
|
} = useColumns({
|
||||||
onColumnsChange,
|
staticColumns: orderDetailsStaticColumns,
|
||||||
picker,
|
selectedColumns: settings?.columns ?? [],
|
||||||
} = useColumnsDefault(availableColumns);
|
onSave: handleColumnChange,
|
||||||
|
});
|
||||||
|
|
||||||
const getCellContent = useGetCellContent({
|
const getCellContent = useCallback(
|
||||||
columns,
|
createGetCellContent({
|
||||||
|
columns: visibleColumns,
|
||||||
data: lines,
|
data: lines,
|
||||||
loading,
|
loading,
|
||||||
});
|
}),
|
||||||
|
[intl, visibleColumns, loading],
|
||||||
|
);
|
||||||
|
|
||||||
const getMenuItems = useCallback(
|
const getMenuItems = useCallback(
|
||||||
index => [
|
index => [
|
||||||
|
@ -76,31 +101,21 @@ export const OrderDetailsDatagrid = ({
|
||||||
rowMarkers="none"
|
rowMarkers="none"
|
||||||
columnSelect="single"
|
columnSelect="single"
|
||||||
freezeColumns={1}
|
freezeColumns={1}
|
||||||
availableColumns={columns}
|
availableColumns={visibleColumns}
|
||||||
emptyText={intl.formatMessage(orderMessages.emptyText)}
|
emptyText={intl.formatMessage(orderMessages.emptyText)}
|
||||||
getCellContent={getCellContent}
|
getCellContent={getCellContent}
|
||||||
getCellError={() => false}
|
getCellError={() => false}
|
||||||
menuItems={getMenuItems}
|
menuItems={getMenuItems}
|
||||||
rows={loading ? 1 : lines.length}
|
rows={loading ? 1 : lines.length}
|
||||||
selectionActions={() => null}
|
selectionActions={() => null}
|
||||||
onColumnResize={onColumnResize}
|
onColumnResize={handlers.onResize}
|
||||||
onColumnMoved={onColumnMoved}
|
onColumnMoved={handlers.onMove}
|
||||||
renderColumnPicker={defaultProps => (
|
recentlyAddedColumn={recentlyAddedColumn}
|
||||||
|
renderColumnPicker={() => (
|
||||||
<ColumnPicker
|
<ColumnPicker
|
||||||
{...defaultProps}
|
staticColumns={staticColumns}
|
||||||
IconButtonProps={{
|
selectedColumns={selectedColumns}
|
||||||
...defaultProps.IconButtonProps,
|
onToggle={handlers.onToggle}
|
||||||
disabled: lines.length === 0,
|
|
||||||
}}
|
|
||||||
availableColumns={availableColumnsChoices}
|
|
||||||
initialColumns={columnChoices}
|
|
||||||
defaultColumns={defaultColumns}
|
|
||||||
onSave={onColumnsChange}
|
|
||||||
hasMore={false}
|
|
||||||
loading={false}
|
|
||||||
onFetchMore={() => undefined}
|
|
||||||
onQueryChange={picker.setQuery}
|
|
||||||
query={picker.query}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -10,16 +10,13 @@ import { AvailableColumn } from "@dashboard/components/Datagrid/types";
|
||||||
import { OrderLineFragment } from "@dashboard/graphql";
|
import { OrderLineFragment } from "@dashboard/graphql";
|
||||||
import { getDatagridRowDataIndex } from "@dashboard/misc";
|
import { getDatagridRowDataIndex } from "@dashboard/misc";
|
||||||
import { GridCell, Item } from "@glideapps/glide-data-grid";
|
import { GridCell, Item } from "@glideapps/glide-data-grid";
|
||||||
import { useCallback, useMemo } from "react";
|
import { IntlShape } from "react-intl";
|
||||||
import { useIntl } from "react-intl";
|
|
||||||
|
|
||||||
import { columnsMessages } from "./messages";
|
import { columnsMessages } from "./messages";
|
||||||
|
|
||||||
export const useColumns = (): AvailableColumn[] => {
|
export const orderDetailsStaticColumnsAdapter = (
|
||||||
const intl = useIntl();
|
intl: IntlShape,
|
||||||
|
): AvailableColumn[] => [
|
||||||
const columns = useMemo(
|
|
||||||
() => [
|
|
||||||
{
|
{
|
||||||
id: "product",
|
id: "product",
|
||||||
title: intl.formatMessage(columnsMessages.product),
|
title: intl.formatMessage(columnsMessages.product),
|
||||||
|
@ -50,12 +47,7 @@ export const useColumns = (): AvailableColumn[] => {
|
||||||
title: intl.formatMessage(columnsMessages.total),
|
title: intl.formatMessage(columnsMessages.total),
|
||||||
width: 150,
|
width: 150,
|
||||||
},
|
},
|
||||||
],
|
];
|
||||||
[intl],
|
|
||||||
);
|
|
||||||
|
|
||||||
return columns;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface GetCellContentProps {
|
interface GetCellContentProps {
|
||||||
columns: AvailableColumn[];
|
columns: AvailableColumn[];
|
||||||
|
@ -63,23 +55,19 @@ interface GetCellContentProps {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useGetCellContent = ({
|
export const createGetCellContent =
|
||||||
columns,
|
({ columns, data, loading }: GetCellContentProps) =>
|
||||||
data,
|
|
||||||
loading,
|
|
||||||
}: GetCellContentProps) => {
|
|
||||||
const getCellContent = useCallback(
|
|
||||||
([column, row]: Item, { added, removed }: GetCellContentOpts): GridCell => {
|
([column, row]: Item, { added, removed }: GetCellContentOpts): GridCell => {
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return loadingCell();
|
return loadingCell();
|
||||||
}
|
}
|
||||||
|
|
||||||
const columnId = columns[column].id;
|
const columnId = columns[column]?.id;
|
||||||
const rowData = added.includes(row)
|
const rowData = added.includes(row)
|
||||||
? undefined
|
? undefined
|
||||||
: data[getDatagridRowDataIndex(row, removed)];
|
: data[getDatagridRowDataIndex(row, removed)];
|
||||||
|
|
||||||
if (!rowData) {
|
if (!rowData || !columnId) {
|
||||||
return readonlyTextCell("", false);
|
return readonlyTextCell("", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,11 +101,6 @@ export const useGetCellContent = ({
|
||||||
default:
|
default:
|
||||||
return readonlyTextCell("", false);
|
return readonlyTextCell("", false);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
[columns, data, loading],
|
|
||||||
);
|
|
||||||
|
|
||||||
return getCellContent;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const readonyOptions: Partial<GridCell> = {
|
const readonyOptions: Partial<GridCell> = {
|
||||||
|
|
|
@ -1,26 +1,32 @@
|
||||||
// @ts-strict-ignore
|
// @ts-strict-ignore
|
||||||
import ColumnPicker from "@dashboard/components/ColumnPicker";
|
import { ColumnPicker } from "@dashboard/components/Datagrid/ColumnPicker/ColumnPicker";
|
||||||
|
import { useColumns } from "@dashboard/components/Datagrid/ColumnPicker/useColumns";
|
||||||
import Datagrid from "@dashboard/components/Datagrid/Datagrid";
|
import Datagrid from "@dashboard/components/Datagrid/Datagrid";
|
||||||
import { useColumnsDefault } from "@dashboard/components/Datagrid/hooks/useColumnsDefault";
|
|
||||||
import {
|
import {
|
||||||
DatagridChangeOpts,
|
DatagridChangeOpts,
|
||||||
DatagridChangeStateContext,
|
DatagridChangeStateContext,
|
||||||
useDatagridChangeState,
|
useDatagridChangeState,
|
||||||
} from "@dashboard/components/Datagrid/hooks/useDatagridChange";
|
} from "@dashboard/components/Datagrid/hooks/useDatagridChange";
|
||||||
|
import { useEmptyColumn } from "@dashboard/components/Datagrid/hooks/useEmptyColumn";
|
||||||
import { OrderDetailsFragment, OrderErrorFragment } from "@dashboard/graphql";
|
import { OrderDetailsFragment, OrderErrorFragment } from "@dashboard/graphql";
|
||||||
|
import useListSettings from "@dashboard/hooks/useListSettings";
|
||||||
import { productUrl } from "@dashboard/products/urls";
|
import { productUrl } from "@dashboard/products/urls";
|
||||||
|
import { ListViews } from "@dashboard/types";
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
ExternalLinkIcon,
|
ExternalLinkIcon,
|
||||||
sprinkles,
|
sprinkles,
|
||||||
TrashBinIcon,
|
TrashBinIcon,
|
||||||
} from "@saleor/macaw-ui/next";
|
} from "@saleor/macaw-ui/next";
|
||||||
import React, { useCallback } from "react";
|
import React, { useCallback, useMemo } from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
import { FormData } from "../OrderDraftDetailsProducts/OrderDraftDetailsProducts";
|
import { FormData } from "../OrderDraftDetailsProducts/OrderDraftDetailsProducts";
|
||||||
import { useColumns, useGetCellContent } from "./datagrid";
|
import {
|
||||||
|
orderDraftDetailsStaticColumnsAdapter,
|
||||||
|
useGetCellContent,
|
||||||
|
} from "./datagrid";
|
||||||
import { messages } from "./messages";
|
import { messages } from "./messages";
|
||||||
|
|
||||||
interface OrderDraftDetailsDatagridProps {
|
interface OrderDraftDetailsDatagridProps {
|
||||||
|
@ -40,21 +46,40 @@ export const OrderDraftDetailsDatagrid = ({
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const datagrid = useDatagridChangeState();
|
const datagrid = useDatagridChangeState();
|
||||||
|
|
||||||
const { availableColumns } = useColumns();
|
const { updateListSettings, settings } = useListSettings(
|
||||||
|
ListViews.ORDER_DRAFT_DETAILS_LIST,
|
||||||
|
);
|
||||||
|
|
||||||
|
const emptyColumn = useEmptyColumn();
|
||||||
|
|
||||||
|
const orderDraftDetailsStaticColumns = useMemo(
|
||||||
|
() => orderDraftDetailsStaticColumnsAdapter(emptyColumn, intl),
|
||||||
|
[emptyColumn, intl],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleColumnChange = useCallback(
|
||||||
|
picked => {
|
||||||
|
if (updateListSettings) {
|
||||||
|
updateListSettings("columns", picked.filter(Boolean));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[updateListSettings],
|
||||||
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
availableColumnsChoices,
|
handlers,
|
||||||
columnChoices,
|
visibleColumns,
|
||||||
columns,
|
staticColumns,
|
||||||
defaultColumns,
|
selectedColumns,
|
||||||
onColumnMoved,
|
recentlyAddedColumn,
|
||||||
onColumnResize,
|
} = useColumns({
|
||||||
onColumnsChange,
|
staticColumns: orderDraftDetailsStaticColumns,
|
||||||
picker,
|
selectedColumns: settings?.columns ?? [],
|
||||||
} = useColumnsDefault(availableColumns);
|
onSave: handleColumnChange,
|
||||||
|
});
|
||||||
|
|
||||||
const getCellContent = useGetCellContent({
|
const getCellContent = useGetCellContent({
|
||||||
columns,
|
columns: visibleColumns,
|
||||||
lines,
|
lines,
|
||||||
errors,
|
errors,
|
||||||
});
|
});
|
||||||
|
@ -138,31 +163,21 @@ export const OrderDraftDetailsDatagrid = ({
|
||||||
columnSelect="none"
|
columnSelect="none"
|
||||||
freezeColumns={2}
|
freezeColumns={2}
|
||||||
verticalBorder={col => col > 1}
|
verticalBorder={col => col > 1}
|
||||||
availableColumns={columns}
|
availableColumns={visibleColumns}
|
||||||
emptyText={intl.formatMessage(messages.emptyText)}
|
emptyText={intl.formatMessage(messages.emptyText)}
|
||||||
getCellContent={getCellContent}
|
getCellContent={getCellContent}
|
||||||
getCellError={() => false}
|
getCellError={() => false}
|
||||||
menuItems={getMenuItems}
|
menuItems={getMenuItems}
|
||||||
rows={lines.length}
|
rows={lines.length}
|
||||||
selectionActions={() => null}
|
selectionActions={() => null}
|
||||||
onColumnResize={onColumnResize}
|
onColumnResize={handlers.onResize}
|
||||||
onColumnMoved={onColumnMoved}
|
onColumnMoved={handlers.onMove}
|
||||||
renderColumnPicker={defaultProps => (
|
recentlyAddedColumn={recentlyAddedColumn}
|
||||||
|
renderColumnPicker={() => (
|
||||||
<ColumnPicker
|
<ColumnPicker
|
||||||
{...defaultProps}
|
selectedColumns={selectedColumns}
|
||||||
IconButtonProps={{
|
staticColumns={staticColumns}
|
||||||
...defaultProps.IconButtonProps,
|
onToggle={handlers.onToggle}
|
||||||
disabled: lines.length === 0,
|
|
||||||
}}
|
|
||||||
availableColumns={availableColumnsChoices}
|
|
||||||
initialColumns={columnChoices}
|
|
||||||
defaultColumns={defaultColumns}
|
|
||||||
onSave={onColumnsChange}
|
|
||||||
hasMore={false}
|
|
||||||
loading={false}
|
|
||||||
onFetchMore={() => undefined}
|
|
||||||
onQueryChange={picker.setQuery}
|
|
||||||
query={picker.query}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
onChange={handleDatagridChange}
|
onChange={handleDatagridChange}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import {
|
||||||
thumbnailCell,
|
thumbnailCell,
|
||||||
} from "@dashboard/components/Datagrid/customCells/cells";
|
} from "@dashboard/components/Datagrid/customCells/cells";
|
||||||
import { GetCellContentOpts } from "@dashboard/components/Datagrid/Datagrid";
|
import { GetCellContentOpts } from "@dashboard/components/Datagrid/Datagrid";
|
||||||
import { useEmptyColumn } from "@dashboard/components/Datagrid/hooks/useEmptyColumn";
|
|
||||||
import { AvailableColumn } from "@dashboard/components/Datagrid/types";
|
import { AvailableColumn } from "@dashboard/components/Datagrid/types";
|
||||||
import { OrderDetailsFragment, OrderErrorFragment } from "@dashboard/graphql";
|
import { OrderDetailsFragment, OrderErrorFragment } from "@dashboard/graphql";
|
||||||
import useLocale from "@dashboard/hooks/useLocale";
|
import useLocale from "@dashboard/hooks/useLocale";
|
||||||
|
@ -21,18 +20,15 @@ import { useOrderLineDiscountContext } from "@dashboard/products/components/Orde
|
||||||
import getOrderErrorMessage from "@dashboard/utils/errors/order";
|
import getOrderErrorMessage from "@dashboard/utils/errors/order";
|
||||||
import { GridCell, Item } from "@glideapps/glide-data-grid";
|
import { GridCell, Item } from "@glideapps/glide-data-grid";
|
||||||
import { DefaultTheme, useTheme } from "@saleor/macaw-ui/next";
|
import { DefaultTheme, useTheme } from "@saleor/macaw-ui/next";
|
||||||
import { useMemo } from "react";
|
|
||||||
import { IntlShape, useIntl } from "react-intl";
|
import { IntlShape, useIntl } from "react-intl";
|
||||||
|
|
||||||
import { lineAlertMessages } from "../OrderDraftDetailsProducts/messages";
|
import { lineAlertMessages } from "../OrderDraftDetailsProducts/messages";
|
||||||
import { columnsMessages } from "./messages";
|
import { columnsMessages } from "./messages";
|
||||||
|
|
||||||
export const useColumns = () => {
|
export const orderDraftDetailsStaticColumnsAdapter = (
|
||||||
const emptyColumn = useEmptyColumn();
|
emptyColumn: AvailableColumn,
|
||||||
const intl = useIntl();
|
intl: IntlShape,
|
||||||
|
) => [
|
||||||
const availableColumns = useMemo(
|
|
||||||
() => [
|
|
||||||
emptyColumn,
|
emptyColumn,
|
||||||
{
|
{
|
||||||
id: "product",
|
id: "product",
|
||||||
|
@ -66,17 +62,10 @@ export const useColumns = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "status",
|
id: "status",
|
||||||
title: "Status",
|
title: intl.formatMessage(columnsMessages.status),
|
||||||
width: 250,
|
width: 250,
|
||||||
},
|
},
|
||||||
],
|
];
|
||||||
[emptyColumn, intl],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
availableColumns,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
interface GetCellContentProps {
|
interface GetCellContentProps {
|
||||||
columns: AvailableColumn[];
|
columns: AvailableColumn[];
|
||||||
|
@ -102,13 +91,13 @@ export const useGetCellContent = ({
|
||||||
return readonlyTextCell("", false);
|
return readonlyTextCell("", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const columnId = columns[column].id;
|
const columnId = columns[column]?.id;
|
||||||
const change = changes.current[getChangeIndex(columnId, row)]?.data;
|
const change = changes.current[getChangeIndex(columnId, row)]?.data;
|
||||||
const rowData = added.includes(row)
|
const rowData = added.includes(row)
|
||||||
? undefined
|
? undefined
|
||||||
: lines[getDatagridRowDataIndex(row, removed)];
|
: lines[getDatagridRowDataIndex(row, removed)];
|
||||||
|
|
||||||
if (!rowData) {
|
if (!rowData || !columnId) {
|
||||||
return readonlyTextCell("", false);
|
return readonlyTextCell("", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,10 @@ export const columnsMessages = defineMessages({
|
||||||
defaultMessage: "Total",
|
defaultMessage: "Total",
|
||||||
description: "total price of ordered products",
|
description: "total price of ordered products",
|
||||||
},
|
},
|
||||||
|
status: {
|
||||||
|
id: "tzMNF3",
|
||||||
|
defaultMessage: "Status",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const messages = defineMessages({
|
export const messages = defineMessages({
|
||||||
|
|
|
@ -30,6 +30,8 @@ export enum ListViews {
|
||||||
DRAFT_LIST = "DRAFT_LIST",
|
DRAFT_LIST = "DRAFT_LIST",
|
||||||
NAVIGATION_LIST = "NAVIGATION_LIST",
|
NAVIGATION_LIST = "NAVIGATION_LIST",
|
||||||
ORDER_LIST = "ORDER_LIST",
|
ORDER_LIST = "ORDER_LIST",
|
||||||
|
ORDER_DETAILS_LIST = "ORDER_DETAILS_LIST",
|
||||||
|
ORDER_DRAFT_DETAILS_LIST = "ORDER_DRAFT_DETAILS_LIST",
|
||||||
PAGES_LIST = "PAGES_LIST",
|
PAGES_LIST = "PAGES_LIST",
|
||||||
PAGE_TYPES_LIST = "PAGE_TYPES_LIST",
|
PAGE_TYPES_LIST = "PAGE_TYPES_LIST",
|
||||||
PLUGINS_LIST = "PLUGIN_LIST",
|
PLUGINS_LIST = "PLUGIN_LIST",
|
||||||
|
|
Loading…
Reference in a new issue