FPSMS-frontend
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 

132 строки
4.4 KiB

  1. "use client";
  2. import Box from "@mui/material/Box";
  3. import { useEffect, useMemo, useState } from "react";
  4. import {
  5. MOCK_WORKBENCH_SEARCH_RESULTS,
  6. WORKBENCH_GRID_TEMPLATE_COLUMNS,
  7. WORKBENCH_GRID_TEMPLATE_ROWS,
  8. } from "@/components/PoWorkbench/mock/workbenchMockData";
  9. import PoWorkbenchDetailsPlaceholder from "@/components/PoWorkbench/PoWorkbenchDetailsPlaceholder";
  10. import PoWorkbenchRegion from "@/components/PoWorkbench/PoWorkbenchRegion";
  11. import PoWorkbenchSearchCriteriaBar from "@/components/PoWorkbench/PoWorkbenchSearchCriteriaBar";
  12. import PoWorkbenchLeftPane from "@/components/PoWorkbench/PoWorkbenchSearchResultsPane";
  13. import {
  14. DEFAULT_ADVANCED_FILTERS,
  15. type PoWorkbenchAdvancedFilters,
  16. } from "@/components/PoWorkbench/types";
  17. /**
  18. * Root layout for PO Workbench: a 2×2 CSS Grid with configurable column and row templates
  19. * defined in {@link WORKBENCH_GRID_TEMPLATE_COLUMNS} and {@link WORKBENCH_GRID_TEMPLATE_ROWS}.
  20. * Search UI uses mock data until `/po/list` is integrated.
  21. */
  22. export default function PoWorkbenchShell() {
  23. const [poNumberQuery, setPoNumberQuery] = useState("");
  24. const [isAdvancedSearchOpen, setIsAdvancedSearchOpen] = useState(false);
  25. const [advancedFilters, setAdvancedFilters] = useState<PoWorkbenchAdvancedFilters>(
  26. { ...DEFAULT_ADVANCED_FILTERS },
  27. );
  28. const [selectedId, setSelectedId] = useState<string | null>(
  29. () => MOCK_WORKBENCH_SEARCH_RESULTS[0]?.id ?? null,
  30. );
  31. const filteredResults = useMemo(() => {
  32. let rows = MOCK_WORKBENCH_SEARCH_RESULTS;
  33. const q = poNumberQuery.trim().toLowerCase();
  34. if (q) {
  35. rows = rows.filter((row) => row.poNumber.toLowerCase().includes(q));
  36. }
  37. const supplierQ = advancedFilters.supplierQuery.trim().toLowerCase();
  38. if (supplierQ) {
  39. rows = rows.filter((row) =>
  40. row.supplierName.toLowerCase().includes(supplierQ),
  41. );
  42. }
  43. if (advancedFilters.orderDateFrom) {
  44. rows = rows.filter((row) => row.orderDate >= advancedFilters.orderDateFrom);
  45. }
  46. if (advancedFilters.orderDateTo) {
  47. rows = rows.filter((row) => row.orderDate <= advancedFilters.orderDateTo);
  48. }
  49. if (advancedFilters.etaDateFrom) {
  50. rows = rows.filter(
  51. (row) => row.estimatedArrivalDate >= advancedFilters.etaDateFrom,
  52. );
  53. }
  54. if (advancedFilters.etaDateTo) {
  55. rows = rows.filter(
  56. (row) => row.estimatedArrivalDate <= advancedFilters.etaDateTo,
  57. );
  58. }
  59. if (advancedFilters.reportStatus !== "ALL") {
  60. const want = advancedFilters.reportStatus === "REPORTED";
  61. rows = rows.filter((row) => row.reported === want);
  62. }
  63. if (advancedFilters.receiveStatus !== "ALL") {
  64. const want = advancedFilters.receiveStatus === "RECEIVED";
  65. rows = rows.filter((row) => row.received === want);
  66. }
  67. return rows;
  68. }, [poNumberQuery, advancedFilters]);
  69. useEffect(() => {
  70. setSelectedId((prev) => {
  71. if (filteredResults.length === 0) {
  72. return null;
  73. }
  74. if (prev && filteredResults.some((r) => r.id === prev)) {
  75. return prev;
  76. }
  77. return filteredResults[0].id;
  78. });
  79. }, [filteredResults]);
  80. return (
  81. <Box
  82. sx={{
  83. display: "grid",
  84. gridTemplateColumns: WORKBENCH_GRID_TEMPLATE_COLUMNS,
  85. gridTemplateRows: WORKBENCH_GRID_TEMPLATE_ROWS,
  86. gap: 0,
  87. width: "100%",
  88. height: "100%",
  89. minHeight: 0,
  90. }}
  91. >
  92. <PoWorkbenchRegion region="searchCriteria">
  93. <PoWorkbenchSearchCriteriaBar
  94. poNumber={poNumberQuery}
  95. onPoNumberChange={setPoNumberQuery}
  96. isAdvancedSearchOpen={isAdvancedSearchOpen}
  97. onToggleAdvancedSearch={() => setIsAdvancedSearchOpen((open) => !open)}
  98. />
  99. </PoWorkbenchRegion>
  100. <PoWorkbenchRegion region="detailsHeader">
  101. <PoWorkbenchDetailsPlaceholder region="detailsHeader" />
  102. </PoWorkbenchRegion>
  103. <PoWorkbenchRegion region="searchResults">
  104. <PoWorkbenchLeftPane
  105. isAdvancedSearchOpen={isAdvancedSearchOpen}
  106. results={filteredResults}
  107. selectedId={selectedId}
  108. onSelect={setSelectedId}
  109. appliedAdvancedFilters={advancedFilters}
  110. onApplyAdvancedFilters={setAdvancedFilters}
  111. onResetAdvancedFilters={() => setAdvancedFilters({ ...DEFAULT_ADVANCED_FILTERS })}
  112. />
  113. </PoWorkbenchRegion>
  114. <PoWorkbenchRegion region="details">
  115. <PoWorkbenchDetailsPlaceholder region="details" />
  116. </PoWorkbenchRegion>
  117. </Box>
  118. );
  119. }