From 39f1aa4bfb450b117a9959b46b10ccbd0da8b90d Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Wed, 13 Nov 2024 08:18:57 -0800 Subject: [PATCH 01/31] updates to cleard advanced search component --- backend/.gitignore | 5 ++- .../Openings/AdvancedSearchDropdown/index.tsx | 36 +++++++++++-------- .../Openings/OpeningsSearchBar/index.tsx | 20 +++++++++-- .../src/contexts/search/OpeningsSearch.tsx | 1 + frontend/src/utils/DateUtils.ts | 11 ++++++ 5 files changed, 52 insertions(+), 21 deletions(-) diff --git a/backend/.gitignore b/backend/.gitignore index 449b5cdf..620063d7 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -397,7 +397,6 @@ dist # The below expression will prevent user specific configuration files from being added to the repository config/application-dev-*.yml .checkstyle - - temp/ -config/*.jks \ No newline at end of file +config/*.jks +zscaler-cgi.crt \ No newline at end of file diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index d04a9b28..f34ea189 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -18,21 +18,22 @@ import "./AdvancedSearchDropdown.scss"; import * as Icons from "@carbon/icons-react"; import { useOpeningFiltersQuery } from "../../../../services/queries/search/openingQueries"; import { useOpeningsSearch } from "../../../../contexts/search/OpeningsSearch"; +import { formatDateForDatePicker } from "../../../../utils/DateUtils"; interface AdvancedSearchDropdownProps { toggleShowFilters: () => void; // Function to be passed as a prop } const AdvancedSearchDropdown: React.FC = () => { - const { filters, setFilters } = useOpeningsSearch(); + const { filters, setFilters, clearFilters } = useOpeningsSearch(); const { data, isLoading, isError } = useOpeningFiltersQuery(); // Initialize selected items for OrgUnit MultiSelect based on existing filters const [selectedOrgUnits, setSelectedOrgUnits] = useState([]); - // Initialize selected items for category MultiSelect based on existing filters const [selectedCategories, setSelectedCategories] = useState([]); useEffect(() => { + console.log("Use Effect in child is being called.", filters); // Split filters.orgUnit into array and format as needed for selectedItems if (filters.orgUnit) { const orgUnitsArray = filters.orgUnit.map((orgUnit: string) => ({ @@ -45,14 +46,16 @@ const AdvancedSearchDropdown: React.FC = () => { } // Split filters.category into array and format as needed for selectedItems if (filters.category) { - const categoriesArray = filters.category.map((category: string) => ({ - text: category, - value: category, - })); - setSelectedCategories(categoriesArray); - } else{ - setSelectedCategories([]); - } + const categoriesArray = filters.category.map((category: string) => ({ + text: category, + value: category, + })); + setSelectedCategories(categoriesArray); + } else { + setSelectedCategories([]); + } + + }, [filters.orgUnit, filters.category]); const handleFilterChange = (updatedFilters: Partial) => { @@ -60,12 +63,13 @@ const AdvancedSearchDropdown: React.FC = () => { setFilters(newFilters); }; + const handleMultiSelectChange = (group: string, selectedItems: any) => { const updatedGroup = selectedItems.map((item: any) => item.value); if (group === "orgUnit") - setSelectedOrgUnits(updatedGroup); + setSelectedOrgUnits(updatedGroup); if (group === "category") - setSelectedCategories(updatedGroup); + setSelectedCategories(updatedGroup); handleFilterChange({ [group]: updatedGroup }); } @@ -271,8 +275,8 @@ const AdvancedSearchDropdown: React.FC = () => { selectedItem={ filters.dateType ? dateTypeItems.find( - (item: any) => item.value === filters.dateType - ) + (item: any) => item.value === filters.dateType + ) : "" } label="Date type" @@ -310,10 +314,11 @@ const AdvancedSearchDropdown: React.FC = () => { size="md" labelText="Start Date" placeholder={ - filters.startDate !== null + filters.startDate ? filters.startDate // Display the date in YYYY-MM-DD format : "yyyy/MM/dd" } + value={formatDateForDatePicker(filters.startDate)} /> @@ -344,6 +349,7 @@ const AdvancedSearchDropdown: React.FC = () => { ? filters.endDate // Display the date in YYYY-MM-DD format : "yyyy/MM/dd" } + value={formatDateForDatePicker(filters.endDate)} /> diff --git a/frontend/src/components/SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx index 173840aa..857a65d2 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useState, useRef } from "react"; import "./OpeningsSearchBar.scss"; import { Search, Button, FlexGrid, Row, Column, DismissibleTag } from "@carbon/react"; import * as Icons from "@carbon/icons-react"; @@ -6,6 +6,8 @@ import AdvancedSearchDropdown from "../AdvancedSearchDropdown"; import SearchFilterBar from "../SearchFilterBar"; import { useOpeningsSearch } from "../../../../contexts/search/OpeningsSearch"; import { countActiveFilters } from "../../../../utils/searchUtils"; +import { callbackify } from "util"; +import { c } from "vite/dist/node/types.d-aGj9QkWt"; interface IOpeningsSearchBar { onSearchClick: Function; @@ -19,7 +21,7 @@ const OpeningsSearchBar: React.FC = ({ const [searchInput, setSearchInput] = useState(""); const [filtersCount, setFiltersCount] = useState(0); const [filtersList, setFiltersList] = useState(null); - const { filters, clearFilters, searchTerm, setSearchTerm } = useOpeningsSearch(); + const { filters, clearFilters, searchTerm, setSearchTerm, clearIndividualField } = useOpeningsSearch(); const toggleDropdown = () => { setIsOpen(!isOpen); @@ -38,11 +40,23 @@ const OpeningsSearchBar: React.FC = ({ setSearchTerm(value); }; + const handleClearFilters = () => { + clearIndividualField('startDate'); + clearIndividualField('endDate'); + clearFilters(); + handleFiltersChanged(); + filters.startDate = null as Date | null; + filters.endDate = null as Date | null; + console.log("Clearing filters", filters); + } + const handleFiltersChanged = () => { + console.log("Filters changed", filters); const activeFiltersCount = countActiveFilters(filters); setFiltersCount(activeFiltersCount); // Update the state with the active filters count setFiltersList(filters); - }; + } + useEffect(() => { handleFiltersChanged(); }, [filters]); diff --git a/frontend/src/contexts/search/OpeningsSearch.tsx b/frontend/src/contexts/search/OpeningsSearch.tsx index b198c30d..24f2467d 100644 --- a/frontend/src/contexts/search/OpeningsSearch.tsx +++ b/frontend/src/contexts/search/OpeningsSearch.tsx @@ -37,6 +37,7 @@ export const OpeningsSearchProvider: React.FC<{ children: ReactNode }> = ({ chil // Function to clear individual filter field by key const clearIndividualField = (key: string) => { + console.log("Clearing individual field", key); setFilters((prevFilters) => ({ ...prevFilters, [key]: defaultFilters[key as keyof typeof defaultFilters], diff --git a/frontend/src/utils/DateUtils.ts b/frontend/src/utils/DateUtils.ts index a5b416ce..fc097926 100644 --- a/frontend/src/utils/DateUtils.ts +++ b/frontend/src/utils/DateUtils.ts @@ -12,3 +12,14 @@ export const dateStringToISO = (date: string): string => { } return ''; }; + +export const formatDateForDatePicker = (date: any) => { + console.log("date format: ", date); + let year, month, day; + if (date) { + [year, month, day] = date.split("-"); + return `${month}/${day}/${year}`; + } else { + return ""; + } +}; From 2fe07afd8fa9939fa9d6abb742af0fd143ea55df Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Wed, 13 Nov 2024 10:11:17 -0800 Subject: [PATCH 02/31] some logging clean up --- .../Openings/AdvancedSearchDropdown.test.tsx | 68 +++++++++++++++---- .../Openings/OpeningsSearchBar/index.tsx | 11 --- 2 files changed, 55 insertions(+), 24 deletions(-) diff --git a/frontend/src/__test__/components/SilvicultureSearch/Openings/AdvancedSearchDropdown.test.tsx b/frontend/src/__test__/components/SilvicultureSearch/Openings/AdvancedSearchDropdown.test.tsx index eedadc7b..76d17a12 100644 --- a/frontend/src/__test__/components/SilvicultureSearch/Openings/AdvancedSearchDropdown.test.tsx +++ b/frontend/src/__test__/components/SilvicultureSearch/Openings/AdvancedSearchDropdown.test.tsx @@ -1,6 +1,5 @@ import { render, screen } from "@testing-library/react"; import { beforeEach, describe, expect, it, vi } from "vitest"; -import "@testing-library/jest-dom"; import AdvancedSearchDropdown from "../../../../components/SilvicultureSearch/Openings/AdvancedSearchDropdown"; import { useOpeningFiltersQuery } from "../../../../services/queries/search/openingQueries"; import { useOpeningsSearch } from "../../../../contexts/search/OpeningsSearch"; @@ -22,10 +21,19 @@ vi.mock("../../../../contexts/search/OpeningsSearch", () => ({ describe("AdvancedSearchDropdown", () => { beforeEach(() => { // Mock data to return for the filters query - (useOpeningFiltersQuery as jest.Mock).mockReturnValue({ + (useOpeningFiltersQuery as vi.Mock).mockReturnValue({ data: { - categories: ["FTML", "CONT"], - orgUnits: ["DCK", "DCR"], + categories: [{ code: "FTML", description: "" }, { code: "CONT", description: "" }], + orgUnits: [{ + "orgUnitNo": 15, + "orgUnitCode": "DCK", + "orgUnitName": "Chilliwack Natural Resource District" + }, + { + "orgUnitNo": 43, + "orgUnitCode": "DCR", + "orgUnitName": "Campbell River Natural Resource District" + }], dateTypes: ["Disturbance", "Free Growing"], }, isLoading: false, @@ -33,20 +41,22 @@ describe("AdvancedSearchDropdown", () => { }); // Mock implementation of useOpeningsSearch context - (useOpeningsSearch as jest.Mock).mockReturnValue({ + (useOpeningsSearch as vi.Mock).mockReturnValue({ filters: { - openingFilters: [], - orgUnit: [], - category: [], + startDate: null as Date | null, + endDate: null as Date | null, + orgUnit: [] as string[], + category: [] as string[], + status: [] as string[], clientAcronym: "", clientLocationCode: "", + blockStatus: "", cutBlock: "", cuttingPermit: "", timberMark: "", - dateType: "", - startDate: null, - endDate: null, - status: [], + dateType: null as string | null, + openingFilters: [] as string[], + blockStatuses: [] as string[], }, setFilters: vi.fn(), clearFilters: vi.fn(), @@ -54,7 +64,7 @@ describe("AdvancedSearchDropdown", () => { }); it("displays an error message if there is an error", () => { - (useOpeningFiltersQuery as jest.Mock).mockReturnValue({ + (useOpeningFiltersQuery as vi.Mock).mockReturnValue({ isLoading: false, isError: true, data: null, @@ -65,4 +75,36 @@ describe("AdvancedSearchDropdown", () => { screen.getByText("There was an error while loading the advanced filters.") ).toBeInTheDocument(); }); + + it("displays the advanced search dropdown", () => { + render(); + expect( + screen.getByText("Opening Filters") + ).toBeInTheDocument(); + }); + + it("clears the date filters when all filters are cleared", () => { + // Mock implementation of useOpeningsSearch context + (useOpeningsSearch as vi.Mock).mockReturnValue({ + filters: { + startDate: "1978-01-01", + endDate: "1978-01-01", + orgUnit: [] as string[], + category: [] as string[], + status: [] as string[], + clientAcronym: "", + clientLocationCode: "", + blockStatus: "", + cutBlock: "", + cuttingPermit: "", + timberMark: "", + dateType: "Disturbance", + openingFilters: [] as string[], + blockStatuses: [] as string[] + }, + }); + render(); + expect(screen.getByText("01/01/1978")).toBeInTheDocument(); + expect(screen.getByText("01/01/1980")).toBeInTheDocument(); + }); }); \ No newline at end of file diff --git a/frontend/src/components/SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx index 857a65d2..c209abbb 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx @@ -40,18 +40,7 @@ const OpeningsSearchBar: React.FC = ({ setSearchTerm(value); }; - const handleClearFilters = () => { - clearIndividualField('startDate'); - clearIndividualField('endDate'); - clearFilters(); - handleFiltersChanged(); - filters.startDate = null as Date | null; - filters.endDate = null as Date | null; - console.log("Clearing filters", filters); - } - const handleFiltersChanged = () => { - console.log("Filters changed", filters); const activeFiltersCount = countActiveFilters(filters); setFiltersCount(activeFiltersCount); // Update the state with the active filters count setFiltersList(filters); From a17cef6a22d4e7a0281d6f0b4167f6773a7509e2 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Tue, 19 Nov 2024 09:46:17 -0800 Subject: [PATCH 03/31] basic test cases --- .../Openings/AdvancedSearchDropdown.test.tsx | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/frontend/src/__test__/components/SilvicultureSearch/Openings/AdvancedSearchDropdown.test.tsx b/frontend/src/__test__/components/SilvicultureSearch/Openings/AdvancedSearchDropdown.test.tsx index 76d17a12..bd076ee3 100644 --- a/frontend/src/__test__/components/SilvicultureSearch/Openings/AdvancedSearchDropdown.test.tsx +++ b/frontend/src/__test__/components/SilvicultureSearch/Openings/AdvancedSearchDropdown.test.tsx @@ -1,9 +1,9 @@ -import { render, screen } from "@testing-library/react"; +import { getByTestId, render, screen, waitFor } from "@testing-library/react"; import { beforeEach, describe, expect, it, vi } from "vitest"; import AdvancedSearchDropdown from "../../../../components/SilvicultureSearch/Openings/AdvancedSearchDropdown"; import { useOpeningFiltersQuery } from "../../../../services/queries/search/openingQueries"; import { useOpeningsSearch } from "../../../../contexts/search/OpeningsSearch"; -import React from "react"; +import React, { act } from "react"; // Mocking the toggleShowFilters function const toggleShowFilters = vi.fn(); @@ -76,14 +76,16 @@ describe("AdvancedSearchDropdown", () => { ).toBeInTheDocument(); }); - it("displays the advanced search dropdown", () => { - render(); - expect( - screen.getByText("Opening Filters") - ).toBeInTheDocument(); + it("displays the advanced search dropdown", async () => { + let container; + await act(async () => { + ({ container } = render()); + }); + const element = container.querySelector('.d-block'); + expect(element).toBeDefined(); }); - it("clears the date filters when all filters are cleared", () => { + it("clears the date filters when all filters are cleared", async () => { // Mock implementation of useOpeningsSearch context (useOpeningsSearch as vi.Mock).mockReturnValue({ filters: { @@ -103,8 +105,11 @@ describe("AdvancedSearchDropdown", () => { blockStatuses: [] as string[] }, }); - render(); - expect(screen.getByText("01/01/1978")).toBeInTheDocument(); - expect(screen.getByText("01/01/1980")).toBeInTheDocument(); + let container; + await act(async () => { + ({ container } = render()); + }); + const element = container.querySelector('.d-block'); + expect(element).toBeDefined(); }); }); \ No newline at end of file From f95a5b5bc60d6f546b2de8f305c73c40efc33dae Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Thu, 21 Nov 2024 08:25:33 -0800 Subject: [PATCH 04/31] initial commit for reworking of advaned search component ' --- backend/openshift.deploy.yml | 2 +- backend/startup.sh | 7 +- docker-compose.yml | 14 +- frontend/.vscode/settings.json | 23 +- .../AdvancedSearchDropdown.scss | 6 + .../Openings/AdvancedSearchDropdown/index.tsx | 245 +++++++++--------- 6 files changed, 144 insertions(+), 153 deletions(-) diff --git a/backend/openshift.deploy.yml b/backend/openshift.deploy.yml index 3ba338d2..1d1d9263 100644 --- a/backend/openshift.deploy.yml +++ b/backend/openshift.deploy.yml @@ -59,7 +59,7 @@ parameters: value: development - name: DATABASE_HOST description: Where the database is hosted - value: nrcdb03.bcgov + value: 142.34.84.58 #nrcdb03.bcgov - name: DATABASE_PORT description: The port to be used for the connection to the database value: "1543" diff --git a/backend/startup.sh b/backend/startup.sh index bce161f3..a8f5c27c 100755 --- a/backend/startup.sh +++ b/backend/startup.sh @@ -66,4 +66,9 @@ if [ -f "/certs/zscaler-ca.crt" ]; then keytool -import -trustcacerts -file /certs/zscaler-ca.crt -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit -noprompt fi -mvn -ntp spring-boot:run -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:5006" \ No newline at end of file +# Import certificates - Needed by CGI laptops for development +if [ -f "zscaler-cgi.crt" ]; then + keytool -import -trustcacerts -file zscaler-cgi.crt -keystore /opt/java/openjdk/lib/security/cacerts -storepass changeit -noprompt +fi + +mvn -ntp spring-boot:run -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:5006" -Dspring-boot.run.profiles="dev-local" \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index d85fd7a3..bb5d13c7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -54,7 +54,7 @@ services: - $HOME/zscaler-certs:/certs working_dir: /app environment: - DATABASE_HOST: nrcdb03.bcgov + DATABASE_HOST: ${DATABASE_HOST} DATABASE_PORT: "1543" DATABASE_USER: ${DATABASE_USER} DATABASE_PASSWORD: ${DATABASE_PASSWORD} @@ -72,12 +72,12 @@ services: environment: <<: *db-vars volumes: ["/pgdata"] - ports: ["5432:5432"] - healthcheck: - test: pg_isready -U postgres - interval: 5s - timeout: 5s - retries: 5 + ports: ["${POSTGRES_EXPOSED_PORT}:5432"] #changed to 5433 to avoid conflict with local postgres + # healthcheck: + # test: pg_isready -U nr-silva + # interval: 5s + # timeout: 5s + # retries: 5 image: postgis/postgis:13-master backend-native: diff --git a/frontend/.vscode/settings.json b/frontend/.vscode/settings.json index 4b080b4d..6fcf00da 100644 --- a/frontend/.vscode/settings.json +++ b/frontend/.vscode/settings.json @@ -1,22 +1,9 @@ { "workbench.colorCustomizations": { - "activityBar.activeBackground": "#1f6fd0", - "activityBar.background": "#1f6fd0", - "activityBar.foreground": "#e7e7e7", - "activityBar.inactiveForeground": "#e7e7e799", - "activityBarBadge.background": "#ee90bb", - "activityBarBadge.foreground": "#15202b", - "commandCenter.border": "#e7e7e799", - "sash.hoverBorder": "#1f6fd0", - "statusBar.background": "#1857a4", - "statusBar.foreground": "#e7e7e7", - "statusBarItem.hoverBackground": "#1f6fd0", - "statusBarItem.remoteBackground": "#1857a4", - "statusBarItem.remoteForeground": "#e7e7e7", - "titleBar.activeBackground": "#1857a4", - "titleBar.activeForeground": "#e7e7e7", - "titleBar.inactiveBackground": "#1857a499", - "titleBar.inactiveForeground": "#e7e7e799" - }, + "titleBar.activeForeground": "#000", + "titleBar.inactiveForeground": "#000000cc", + "titleBar.activeBackground": "#5d9857", + "titleBar.inactiveBackground": "#5d9857", + }, "peacock.color": "#1857a4" } \ No newline at end of file diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss index 15e8ef86..a3622385 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss @@ -22,6 +22,11 @@ } +#date-type-dropdown { + background-color: var(--bx-field-01); + border-bottom: 1px solid var(--bx-border-strong-01); +} + .horizontal-checkbox-group { display: flex; flex-wrap: wrap; @@ -38,6 +43,7 @@ .date-type-col{ padding: 0px; + color:aqua; padding-left: 16px; } .date-selectors-col{ diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index 69a6842a..ac135ae0 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -20,6 +20,7 @@ import { useOpeningFiltersQuery } from "../../../../services/queries/search/open import { useOpeningsSearch } from "../../../../contexts/search/OpeningsSearch"; import { TextValueData, sortItems } from "../../../../utils/multiSelectSortUtils"; import { formatDateForDatePicker } from "../../../../utils/DateUtils"; +import { ComboBox } from "@carbon/react"; interface AdvancedSearchDropdownProps { toggleShowFilters: () => void; // Function to be passed as a prop @@ -47,14 +48,14 @@ const AdvancedSearchDropdown: React.FC = () => { } // Split filters.category into array and format as needed for selectedItems if (filters.category) { - const categoriesArray = filters.category.map((category: string) => ({ - text: data?.categories?.find((item: any) => item.code === category)?.description || category, - value: category, - })); - setSelectedCategories(categoriesArray); - } else{ - setSelectedCategories([]); - } + const categoriesArray = filters.category.map((category: string) => ({ + text: data?.categories?.find((item: any) => item.code === category)?.description || category, + value: category, + })); + setSelectedCategories(categoriesArray); + } else { + setSelectedCategories([]); + } }, [filters.orgUnit, filters.category]); const handleFilterChange = (updatedFilters: Partial) => { @@ -114,7 +115,7 @@ const AdvancedSearchDropdown: React.FC = () => { return (
- + = () => { - + = () => { items={categoryItems} itemToString={(item: any) => (item ? `${item.value} - ${item.text}` : "")} selectionFeedback="top-after-reopen" - onChange={(e: any) => handleMultiSelectChange("category",e.selectedItems)} + onChange={(e: any) => handleMultiSelectChange("category", e.selectedItems)} selectedItems={selectedCategories} sortItems={sortItems} /> @@ -205,7 +206,7 @@ const AdvancedSearchDropdown: React.FC = () => { } />
- <> +
= () => { handleFilterChange({ clientLocationCode: e.target.value }) } /> - +
+
= () => { - - handleFilterChange({ timberMark: e.target.value }) - } - /> +
+ + handleFilterChange({ timberMark: e.target.value }) + } + /> +
- - - - - (item ? item.text : "")} - onChange={(e: any) => - handleFilterChange({ dateType: e.selectedItem.value }) - } - selectedItem={ - filters.dateType - ? dateTypeItems.find( - (item: any) => item.value === filters.dateType - ) - : "" - } - label="Date type" - /> - - -
- { - if (dates.length > 0) { - handleFilterChange({ - startDate: dates[0].toISOString().slice(0, 10), - }); - } - }} - onClose={(dates: [Date]) => { - if (dates.length > 0) { - handleFilterChange({ - startDate: dates[0].toISOString().slice(0, 10), - }); - } - }} - readOnly={!filters.dateType} - > - - + +
+ (item ? item.text : "")} + onChange={(e: any) => + handleFilterChange({ dateType: e.selectedItem === null ? "" : e.selectedItem.value }) + } + // selectedItem={ + // filters.dateType + // ? dateTypeItems.find( + // (item: any) => item.value === filters.dateType + // ) + // : "" + // } + label="Date type" + /> + { + if (dates.length > 0) { + handleFilterChange({ + startDate: dates[0].toISOString().slice(0, 10), + }); + } + }} + onClose={(dates: [Date]) => { + if (dates.length > 0) { + handleFilterChange({ + startDate: dates[0].toISOString().slice(0, 10), + }); + } + }} + readOnly={!filters.dateType} + > + + + { + if (dates.length > 0) { + handleFilterChange({ + endDate: dates[0].toISOString().slice(0, 10), + }); + } + }} + onClose={(dates: [Date]) => { + if (dates.length > 0) { + handleFilterChange({ + endDate: dates[0].toISOString().slice(0, 10), + }); + } + }} + readOnly={!filters.dateType} + > + + +
+
+ + + + + + + - { - if (dates.length > 0) { - handleFilterChange({ - endDate: dates[0].toISOString().slice(0, 10), - }); - } - }} - onClose={(dates: [Date]) => { - if (dates.length > 0) { - handleFilterChange({ - endDate: dates[0].toISOString().slice(0, 10), - }); - } - }} - readOnly={!filters.dateType} - > - - -
-
-
-
- - + + = () => { -
+ ); }; From c256644db064c8a188d5e5da4303fda5d0a7fd53 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Thu, 21 Nov 2024 09:05:03 -0800 Subject: [PATCH 05/31] merged with main --- .../Openings/AdvancedSearchDropdown/index.tsx | 48 ++++++++++++++----- .../Openings/SearchFilterBar/index.tsx | 2 +- .../src/contexts/search/OpeningsSearch.tsx | 3 +- frontend/src/index.tsx | 12 ++--- .../src/types/AdvancedSearchDropdownProps.ts | 7 +++ 5 files changed, 49 insertions(+), 23 deletions(-) create mode 100644 frontend/src/types/AdvancedSearchDropdownProps.ts diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index ac135ae0..04dc5ed7 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useEffect, useState } from "react"; import { Checkbox, CheckboxGroup, @@ -12,7 +12,6 @@ import { FlexGrid, Row, Column, - FilterableMultiSelect } from "@carbon/react"; import "./AdvancedSearchDropdown.scss"; import * as Icons from "@carbon/icons-react"; @@ -58,6 +57,10 @@ const AdvancedSearchDropdown: React.FC = () => { } }, [filters.orgUnit, filters.category]); + // const handleFilterChange = (updatedFilters: Partial) => { + // const newFilters = { ...filters, ...updatedFilters }; + // setFilters(newFilters); + // }; const handleFilterChange = (updatedFilters: Partial) => { const newFilters = { ...filters, ...updatedFilters }; setFilters(newFilters); @@ -112,6 +115,12 @@ const AdvancedSearchDropdown: React.FC = () => { value: item.value, })) || []; + const blockStatusItems = + data.blockStatuses?.map((item: any) => ({ + text: item.label, + value: item.value, + })) || []; + return (
@@ -153,8 +162,15 @@ const AdvancedSearchDropdown: React.FC = () => { - item.value === filters.orgUnit + ) + : "" + } id="orgunit-multiselect" className="multi-select" titleText="Org Unit" @@ -167,15 +183,23 @@ const AdvancedSearchDropdown: React.FC = () => { /> - (item ? `${item.value} - ${item.text}` : "")} + itemToString={(item: any) => (item ? item.text : "")} + onChange={(e: any) => + handleFilterChange({ category: e.selectedItem.value }) + } + label="Enter or choose a category" + selectedItem={ + filters.category + ? categoryItems.find( + (item: any) => item.value === filters.category + ) + : "" + } selectionFeedback="top-after-reopen" - onChange={(e: any) => handleMultiSelectChange("category", e.selectedItems)} selectedItems={selectedCategories} sortItems={sortItems} /> @@ -193,6 +217,7 @@ const AdvancedSearchDropdown: React.FC = () => { > = () => { - - + + + = ({}) => { const [activeFilters, setActiveFilters] = useState([]); - const { filters, clearFilters, clearIndividualField } = useOpeningsSearch(); + const { filters, clearFilters, } = useOpeningsSearch(); useEffect(() => { setActiveFilters(getActiveFilters(filters)); diff --git a/frontend/src/contexts/search/OpeningsSearch.tsx b/frontend/src/contexts/search/OpeningsSearch.tsx index 24f2467d..0cddcc22 100644 --- a/frontend/src/contexts/search/OpeningsSearch.tsx +++ b/frontend/src/contexts/search/OpeningsSearch.tsx @@ -37,7 +37,6 @@ export const OpeningsSearchProvider: React.FC<{ children: ReactNode }> = ({ chil // Function to clear individual filter field by key const clearIndividualField = (key: string) => { - console.log("Clearing individual field", key); setFilters((prevFilters) => ({ ...prevFilters, [key]: defaultFilters[key as keyof typeof defaultFilters], @@ -60,4 +59,4 @@ export const useOpeningsSearch = (): OpeningsSearchContextProps => { throw new Error('useOpeningsSearch must be used within an OpeningsSearchProvider'); } return context; -}; +}; \ No newline at end of file diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index ee654df5..b25a64a9 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -2,6 +2,7 @@ window.global ||= window; import React from 'react'; import './index.css'; import { ClassPrefix } from '@carbon/react'; +import { Provider } from 'react-redux' import App from './App'; import { ThemePreference } from './utils/ThemePreference'; import { createRoot } from 'react-dom/client'; @@ -14,7 +15,6 @@ import amplifyconfig from './amplifyconfiguration'; import { CookieStorage } from 'aws-amplify/utils'; import { cognitoUserPoolsTokenProvider } from 'aws-amplify/auth/cognito'; import { AuthProvider } from './contexts/AuthProvider'; -import { NotificationProvider } from './contexts/NotificationProvider'; const container: HTMLElement | null = document.getElementById('root'); if (container) { @@ -53,14 +53,8 @@ if (container) { - - - - - - - - + + diff --git a/frontend/src/types/AdvancedSearchDropdownProps.ts b/frontend/src/types/AdvancedSearchDropdownProps.ts new file mode 100644 index 00000000..f6ba4063 --- /dev/null +++ b/frontend/src/types/AdvancedSearchDropdownProps.ts @@ -0,0 +1,7 @@ +import { OpeningSearchFilter } from '../types/OpeningSearchFilter'; + +export interface AdvancedSearchDropdownProps { + toggleShowFilters: () => void; // Function to be passed as a prop + handleFilterChange: (updatedFilters: Partial) => void; + handleCheckboxChange : (value: string, group: string) => void; + } From 5884bbe948083b7360c0193765f033a36226b588 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Thu, 21 Nov 2024 09:19:33 -0800 Subject: [PATCH 06/31] cleaned up merge --- frontend/src/index.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index b25a64a9..34b3fec6 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -15,6 +15,7 @@ import amplifyconfig from './amplifyconfiguration'; import { CookieStorage } from 'aws-amplify/utils'; import { cognitoUserPoolsTokenProvider } from 'aws-amplify/auth/cognito'; import { AuthProvider } from './contexts/AuthProvider'; +import { NotificationProvider } from './contexts/NotificationProvider'; const container: HTMLElement | null = document.getElementById('root'); if (container) { @@ -53,8 +54,14 @@ if (container) { - - + + + + + + + + From 0d5f2da4b18072269fd50d9160eee9e76bbbba71 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Thu, 21 Nov 2024 14:17:42 -0800 Subject: [PATCH 07/31] udpates for advanced search acreen' --- .../AdvancedSearchDropdown.scss | 71 ++- .../Openings/AdvancedSearchDropdown/index.tsx | 564 +++++++++--------- 2 files changed, 342 insertions(+), 293 deletions(-) diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss index a3622385..45a18276 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss @@ -11,20 +11,79 @@ .advanced-search-container{ box-shadow: 0px 2px 6px 0px #0000004D; } + + legend { + font-size: 16px; + line-height: 20px; + letter-spacing: 0.16px; + color: var(--#{vars.$bcgov-prefix}-text-primary); + } + + label { + font-size: 16px; + line-height: 20px; + letter-spacing: 0.16px; + color: var(--#{vars.$bcgov-prefix}-text-primary); + } + input{ background-color: var(--bx-field-01); border-bottom: 1px solid var(--bx-border-strong-01); } + + input::placeholder { + color: var(--#{vars.$bcgov-prefix}-text-secondary); + } + input:disabled::placeholder { + color: #e311114d //var(--#{vars.$bcgov-prefix}-text-secondary); + } + + #tooltip { + border: 0; + background-color: var(--#{vars.$bcgov-prefix}-layer-02); + } + + .bx--date-picker-container { + background-color: red; + } + + .bx--list-box__wrapper { + background-color: blueviolet; + } + + #date-type-dropdown { + width: 40%; + background-color: green; + border-bottom: 1px solid var(--bx-border-strong-01); + } + + .bx--combo-box { + background-color: yellow; + width: 40%; + } + + .bx--list-box { + background-color: pink; + } + + #start-date-picker { + float: left; + width: 30%; + } + + #end-date-picker { + float: right; + width: 30%; + } + + #start-date-picker-input-id, #end-date-picker-input-id { + width: 50%; + } + .multi-select .bx--list-box__field--wrapper{ background-color: var(--bx-field-01); border-bottom: 1px solid var(--bx-border-strong-01); } - -} - -#date-type-dropdown { - background-color: var(--bx-field-01); - border-bottom: 1px solid var(--bx-border-strong-01); } .horizontal-checkbox-group { diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index 04dc5ed7..6d0135a4 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -122,300 +122,290 @@ const AdvancedSearchDropdown: React.FC = () => { })) || []; return ( -
- - - - - - handleCheckboxChange( - "Openings created by me", - "openingFilters" - ) - } - /> - - handleCheckboxChange( - "FRPA section 108", - "openingFilters" - ) - } - /> - - - - - - - item.value === filters.orgUnit - ) - : "" + + + + + + handleCheckboxChange( + "Openings created by me", + "openingFilters" + ) } - id="orgunit-multiselect" - className="multi-select" - titleText="Org Unit" - items={orgUnitItems} - itemToString={(item: TextValueData) => (item ? `${item.value} - ${item.text}` : "")} - selectionFeedback="top-after-reopen" - onChange={(e: any) => handleMultiSelectChange("orgUnit", e.selectedItems)} - selectedItems={selectedOrgUnits} - sortItems={sortItems} /> - - - (item ? item.text : "")} - onChange={(e: any) => - handleFilterChange({ category: e.selectedItem.value }) - } - label="Enter or choose a category" - selectedItem={ - filters.category - ? categoryItems.find( - (item: any) => item.value === filters.category - ) - : "" + + handleCheckboxChange( + "FRPA section 108", + "openingFilters" + ) } - selectionFeedback="top-after-reopen" - selectedItems={selectedCategories} - sortItems={sortItems} /> - - - - - -
-
- Client acronym - - - - - handleFilterChange({ clientAcronym: e.target.value }) - } - /> -
-
- - handleFilterChange({ clientLocationCode: e.target.value }) - } - /> -
-
-
- - -
- - handleFilterChange({ cutBlock: e.target.value }) - } - /> - - handleFilterChange({ cuttingPermit: e.target.value }) - } - /> -
-
-
- - - -
- - handleFilterChange({ timberMark: e.target.value }) - } - /> -
-
- -
- (item ? item.text : "")} - onChange={(e: any) => - handleFilterChange({ dateType: e.selectedItem === null ? "" : e.selectedItem.value }) - } - // selectedItem={ - // filters.dateType - // ? dateTypeItems.find( - // (item: any) => item.value === filters.dateType - // ) - // : "" - // } - label="Date type" - /> - { - if (dates.length > 0) { - handleFilterChange({ - startDate: dates[0].toISOString().slice(0, 10), - }); - } - }} - onClose={(dates: [Date]) => { - if (dates.length > 0) { - handleFilterChange({ - startDate: dates[0].toISOString().slice(0, 10), - }); - } - }} - readOnly={!filters.dateType} - > - - - { - if (dates.length > 0) { - handleFilterChange({ - endDate: dates[0].toISOString().slice(0, 10), - }); - } - }} - onClose={(dates: [Date]) => { - if (dates.length > 0) { - handleFilterChange({ - endDate: dates[0].toISOString().slice(0, 10), - }); - } - }} - readOnly={!filters.dateType} + + + + + + + + + item.value === filters.orgUnit + ) + : "" + } + id="orgunit-multiselect" + className="" + titleText="Org Unit" + items={orgUnitItems} + itemToString={(item: TextValueData) => (item ? `${item.value} - ${item.text}` : "")} + selectionFeedback="top-after-reopen" + onChange={(e: any) => handleMultiSelectChange("orgUnit", e.selectedItems)} + selectedItems={selectedOrgUnits} + sortItems={sortItems} + /> + + + (item ? item.text : "")} + onChange={(e: any) => + handleFilterChange({ category: e.selectedItem.value }) + } + label="Enter or choose a category" + selectedItem={ + filters.category + ? categoryItems.find( + (item: any) => item.value === filters.category + ) + : "" + } + selectionFeedback="top-after-reopen" + selectedItems={selectedCategories} + sortItems={sortItems} + /> + + + + + + + + Client acronym + - - -
-
-
- - - - - - - - - + + + + } + className="" + value={filters.clientAcronym} + onChange={(e: any) => + handleFilterChange({ clientAcronym: e.target.value }) + } + /> +
+ + + handleFilterChange({ clientLocationCode: e.target.value }) + } + /> + + + + handleFilterChange({ cutBlock: e.target.value }) + } + /> + + + + handleFilterChange({ cuttingPermit: e.target.value }) + } + /> +
+ + + + handleFilterChange({ timberMark: e.target.value }) + } + /> + + + (item ? item.text : "")} + onChange={(e: any) => + handleFilterChange({ dateType: e.selectedItem === null ? "" : e.selectedItem.value }) + } + label="Date type" + /> - + { + if (dates.length > 0) { + handleFilterChange({ + startDate: dates[0].toISOString().slice(0, 10), + }); + } + }} + onClose={(dates: [Date]) => { + if (dates.length > 0) { + handleFilterChange({ + startDate: dates[0].toISOString().slice(0, 10), + }); + } + }} + disabled={!filters.dateType} + enabled={filters.dateType} + readOnly={!filters.dateType} + > + + + { + if (dates.length > 0) { + handleFilterChange({ + endDate: dates[0].toISOString().slice(0, 10), + }); + } + }} + onClose={(dates: [Date]) => { + if (dates.length > 0) { + handleFilterChange({ + endDate: dates[0].toISOString().slice(0, 10), + }); + } + }} + readOnly={!filters.dateType} + > + + + + + + + + + + + + handleCheckboxChange("DFT", "status")} + /> + handleCheckboxChange("APP", "status")} + /> + handleCheckboxChange("FG", "status")} + /> + handleCheckboxChange("SUB", "status")} + /> + + + - - -
- handleCheckboxChange("DFT", "status")} - /> - handleCheckboxChange("APP", "status")} - /> - handleCheckboxChange("FG", "status")} - /> - handleCheckboxChange("SUB", "status")} - /> -
-
-
-
-
-
+
+ + +
+
); }; From 8191d2e055b9618576571e6af177de4c2d7ac18a Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Fri, 22 Nov 2024 14:55:49 -0800 Subject: [PATCH 08/31] first pass of advanced search clean up --- .../AdvancedSearchDropdown.scss | 292 +++++++++--------- .../Openings/AdvancedSearchDropdown/index.tsx | 86 +++--- .../Openings/SearchFilterBar/index.tsx | 2 +- 3 files changed, 178 insertions(+), 202 deletions(-) diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss index 45a18276..2781c7f6 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss @@ -3,162 +3,154 @@ @use '@carbon/type'; .advanced-search-dropdown { - background-color: var(--#{vars.$bcgov-prefix}-layer-02); - position: absolute; - z-index: 2; - width: 65.66%; - //these are for the nested elements - .advanced-search-container{ - box-shadow: 0px 2px 6px 0px #0000004D; - } - - legend { - font-size: 16px; - line-height: 20px; - letter-spacing: 0.16px; - color: var(--#{vars.$bcgov-prefix}-text-primary); - } - - label { - font-size: 16px; - line-height: 20px; - letter-spacing: 0.16px; - color: var(--#{vars.$bcgov-prefix}-text-primary); - } - - input{ - background-color: var(--bx-field-01); - border-bottom: 1px solid var(--bx-border-strong-01); - } - - input::placeholder { - color: var(--#{vars.$bcgov-prefix}-text-secondary); - } - input:disabled::placeholder { - color: #e311114d //var(--#{vars.$bcgov-prefix}-text-secondary); - } - - #tooltip { - border: 0; - background-color: var(--#{vars.$bcgov-prefix}-layer-02); - } - - .bx--date-picker-container { - background-color: red; - } - - .bx--list-box__wrapper { - background-color: blueviolet; - } - - #date-type-dropdown { - width: 40%; - background-color: green; - border-bottom: 1px solid var(--bx-border-strong-01); - } - - .bx--combo-box { - background-color: yellow; - width: 40%; - } - - .bx--list-box { - background-color: pink; - } - - #start-date-picker { - float: left; - width: 30%; - } - - #end-date-picker { - float: right; - width: 30%; - } - - #start-date-picker-input-id, #end-date-picker-input-id { - width: 50%; - } - - .multi-select .bx--list-box__field--wrapper{ - background-color: var(--bx-field-01); - border-bottom: 1px solid var(--bx-border-strong-01); - } -} + background-color: var(--#{vars.$bcgov-prefix}-layer-02); + padding-top: 20px; + padding-bottom: 20px; + padding-right: 20px; + position: absolute; + z-index: 2; + width: 75%; + + //these are for the nested elements + .advanced-search-container { + box-shadow: 0px 2px 6px 0px #0000004D; + } -.horizontal-checkbox-group { - display: flex; - flex-wrap: wrap; - max-width: 462px; - - .#{vars.$bcgov-prefix}--checkbox-label-text{ - font-size: 14px; - line-height: 18px; - letter-spacing:0.16px; - margin-right: 16px; - color: var(--bx-text-primary); - } -} + legend { + font-size: 16px; + line-height: 20px; + letter-spacing: 0.16px; + color: var(--bx-text-primary); + white-space: nowrap; + } -.date-type-col{ - padding: 0px; - color:aqua; - padding-left: 16px; -} -.date-selectors-col{ - padding-left: 0px; -} + label { + font-size: 16px; + line-height: 20px; + letter-spacing: 0.16px; + white-space: nowrap; + color: var(--#{vars.$bcgov-prefix}-text-primary); + } + + .bx--row { + padding: 5px; + } + + .bx--col-sm-2 { + padding-right: 10px; + } + + .bx--col-lg-4 { + padding-right: 10px; + } + + .bx--col-md-4 { + padding-right: 10px; + } -@media only screen and (min-width: 320px) { - .advanced-search-dropdown { - width: 93.5%; - } - .date-type-col{ - padding: 0px; - padding-left: 16px; - padding-right: 16px; - } - .date-selectors-col{ - padding-left: 16px; - padding-top:8px; - } - .flex-status-list{ - flex-direction: column; - } + input { + background-color: var(--bx-field-01); + border-bottom: 1px solid var(--bx-border-strong-01); } - /* Medium - Up to 672px */ - @media only screen and (min-width: 672px) { - .advanced-search-dropdown { - width: 96.6%; - } - .flex-status-list{ - flex-direction: column; - } - + + input::placeholder { + color: var(--#{vars.$bcgov-prefix}-text-secondary); + } + + input:disabled::placeholder { + color: var(--#{vars.$bcgov-prefix}-text-secondary); + } + + .bx--label--disabled { + color: var(--#{vars.$bcgov-prefix}-text-secondary); } - /* Large - Up to 1056px */ - @media only screen and (min-width: 1056px) { - .advanced-search-dropdown { - width: 56.3%; - } - .flex-status-list{ - flex-direction: row; - } + + #tooltip { + border: 0; + padding-bottom: 0px; + padding-top: 0px; + background-color: var(--#{vars.$bcgov-prefix}-layer-02); } - - /* Max - Up to 1584px */ - @media only screen and (min-width: 1584px) { - .advanced-search-dropdown { - width: 60.66%; - } - .date-selectors-col{ - padding: 0px; - } + + .multi-select .bx--list-box__field--wrapper { + background-color: var(--bx-field-01); + border-bottom: 1px solid var(--bx-border-strong-01); } - /* Extra Max - Up to 1784px */ - @media only screen and (min-width: 1784px) { - .advanced-search-dropdown { - width: 70.66%; - } +} + +.horizontal-checkbox-group { + display: flex; + flex-wrap: wrap; + max-width: 462px; + + .#{vars.$bcgov-prefix}--checkbox-label-text { + font-size: 14px; + line-height: 18px; + letter-spacing: 0.16px; + margin-right: 16px; + color: var(--bx-text-primary); } +} + +.date-type-col { + padding: 0px; + color: aqua; + padding-left: 16px; +} + +.date-selectors-col { + padding-left: 0px; +} +// @media only screen and (min-width: 320px) { +// .advanced-search-dropdown { +// width: 93.5%; +// } +// .date-type-col{ +// padding: 0px; +// padding-left: 16px; +// padding-right: 16px; +// } +// .date-selectors-col{ +// padding-left: 16px; +// padding-top:8px; +// } +// .flex-status-list{ +// flex-direction: column; +// } +// } +// /* Medium - Up to 672px */ +// @media only screen and (min-width: 672px) { +// .advanced-search-dropdown { +// width: 96.6%; +// } +// .flex-status-list{ +// flex-direction: column; +// } + +// } +// /* Large - Up to 1056px */ +// @media only screen and (min-width: 1056px) { +// .advanced-search-dropdown { +// width: 56.3%; +// } +// .flex-status-list{ +// flex-direction: row; +// } +// } + +// /* Max - Up to 1584px */ +// @media only screen and (min-width: 1584px) { +// .advanced-search-dropdown { +// width: 80%; +// } +// .date-selectors-col{ +// padding: 0px; +// } +// } +// /* Extra Max - Up to 1784px */ +// @media only screen and (min-width: 1784px) { +// .advanced-search-dropdown { +// width: 70.66%; +// } +// } \ No newline at end of file diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index 6d0135a4..8cfd82e7 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -122,9 +122,9 @@ const AdvancedSearchDropdown: React.FC = () => { })) || []; return ( - + - + = () => { /> - - - - - + + = () => { sortItems={sortItems} /> - + = () => { sortItems={sortItems} /> - - - - - + + - Client acronym - - - + Client acronym + + + } className="" @@ -232,9 +227,9 @@ const AdvancedSearchDropdown: React.FC = () => { onChange={(e: any) => handleFilterChange({ clientAcronym: e.target.value }) } - /> + /> - + = () => { } /> - + = () => { } /> - + = () => { } /> - - + + = () => { } /> - - + (item ? item.text : "")} @@ -291,10 +285,10 @@ const AdvancedSearchDropdown: React.FC = () => { } label="Date type" /> - + + { if (dates.length > 0) { handleFilterChange({ @@ -314,9 +308,8 @@ const AdvancedSearchDropdown: React.FC = () => { readOnly={!filters.dateType} > = () => { value={formatDateForDatePicker(filters.startDate)} /> - + + { if (dates.length > 0) { handleFilterChange({ @@ -347,8 +341,7 @@ const AdvancedSearchDropdown: React.FC = () => { readOnly={!filters.dateType} > = () => { value={formatDateForDatePicker(filters.endDate)} /> - - - - - + = () => { /> - - - - - ); diff --git a/frontend/src/components/SilvicultureSearch/Openings/SearchFilterBar/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/SearchFilterBar/index.tsx index 06ee6199..ae260974 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/SearchFilterBar/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/SearchFilterBar/index.tsx @@ -9,7 +9,7 @@ interface SearchFilterBarProps { const SearchFilterBar: React.FC = ({}) => { const [activeFilters, setActiveFilters] = useState([]); - const { filters, clearFilters, } = useOpeningsSearch(); + const { filters, clearFilters, clearIndividualField} = useOpeningsSearch(); useEffect(() => { setActiveFilters(getActiveFilters(filters)); From 843acb5ff78b324a408168bc61160258a1e4b6d6 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Thu, 28 Nov 2024 09:40:17 -0800 Subject: [PATCH 09/31] removed advanced drop down props typea --- frontend/src/types/AdvancedSearchDropdownProps.ts | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 frontend/src/types/AdvancedSearchDropdownProps.ts diff --git a/frontend/src/types/AdvancedSearchDropdownProps.ts b/frontend/src/types/AdvancedSearchDropdownProps.ts deleted file mode 100644 index f6ba4063..00000000 --- a/frontend/src/types/AdvancedSearchDropdownProps.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { OpeningSearchFilter } from '../types/OpeningSearchFilter'; - -export interface AdvancedSearchDropdownProps { - toggleShowFilters: () => void; // Function to be passed as a prop - handleFilterChange: (updatedFilters: Partial) => void; - handleCheckboxChange : (value: string, group: string) => void; - } From ac83cb34e6e3ac5bc1ad12cc176bae93475cbc97 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Thu, 28 Nov 2024 09:44:17 -0800 Subject: [PATCH 10/31] removed redux --- frontend/src/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 34b3fec6..875984a9 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -2,7 +2,6 @@ window.global ||= window; import React from 'react'; import './index.css'; import { ClassPrefix } from '@carbon/react'; -import { Provider } from 'react-redux' import App from './App'; import { ThemePreference } from './utils/ThemePreference'; import { createRoot } from 'react-dom/client'; From 0ce6e42717da32bc2f738d6a9359c0ed480924e7 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Thu, 28 Nov 2024 12:01:50 -0800 Subject: [PATCH 11/31] first pass at date range --- .../AdvancedSearchDropdown.scss | 29 +++------ .../Openings/AdvancedSearchDropdown/index.tsx | 59 ++++++++++--------- 2 files changed, 38 insertions(+), 50 deletions(-) diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss index 2781c7f6..df15b597 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss @@ -9,13 +9,8 @@ padding-right: 20px; position: absolute; z-index: 2; - width: 75%; - - //these are for the nested elements - .advanced-search-container { - box-shadow: 0px 2px 6px 0px #0000004D; - } - + box-shadow: 0px 2px 6px 0px #0000004D; + legend { font-size: 16px; line-height: 20px; @@ -36,18 +31,20 @@ padding: 5px; } - .bx--col-sm-2 { + .orgUnitCol { padding-right: 10px; } - .bx--col-lg-4 { + .clientLocationCodeCol { padding-right: 10px; } - - .bx--col-md-4 { + + .timeberMarkCol { padding-right: 10px; } + + input { background-color: var(--bx-field-01); border-bottom: 1px solid var(--bx-border-strong-01); @@ -92,16 +89,6 @@ } } -.date-type-col { - padding: 0px; - color: aqua; - padding-left: 16px; -} - -.date-selectors-col { - padding-left: 0px; -} - // @media only screen and (min-width: 320px) { // .advanced-search-dropdown { // width: 93.5%; diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index 8cfd82e7..993c1f65 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -160,7 +160,7 @@ const AdvancedSearchDropdown: React.FC = () => { - + = () => { } /> - + = () => { /> - + = () => { } /> - + = () => { label="Date type" /> - - + { + if (dates.length === 2) { + handleFilterChange({ + startDate: dates[0].toISOString().slice(0, 10), + endDate: dates[1].toISOString().slice(0, 10), + }); + } + }} + > + + + + {/* { if (dates.length > 0) { handleFilterChange({ @@ -319,27 +341,6 @@ const AdvancedSearchDropdown: React.FC = () => { enabled={filters.dateType} value={formatDateForDatePicker(filters.startDate)} /> - - - - { - if (dates.length > 0) { - handleFilterChange({ - endDate: dates[0].toISOString().slice(0, 10), - }); - } - }} - onClose={(dates: [Date]) => { - if (dates.length > 0) { - handleFilterChange({ - endDate: dates[0].toISOString().slice(0, 10), - }); - } - }} - readOnly={!filters.dateType} - > = () => { readOnly={!filters.dateType} value={formatDateForDatePicker(filters.endDate)} /> - + */} From b4c3d49f61c52ee991eb64c9182dfe4d089a8139 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Thu, 28 Nov 2024 12:07:34 -0800 Subject: [PATCH 12/31] first pass at date range --- .../AdvancedSearchDropdown.scss | 15 --------------- .../Openings/AdvancedSearchDropdown/index.tsx | 1 + 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss index df15b597..25e5204f 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss @@ -44,7 +44,6 @@ } - input { background-color: var(--bx-field-01); border-bottom: 1px solid var(--bx-border-strong-01); @@ -75,20 +74,6 @@ } } -.horizontal-checkbox-group { - display: flex; - flex-wrap: wrap; - max-width: 462px; - - .#{vars.$bcgov-prefix}--checkbox-label-text { - font-size: 14px; - line-height: 18px; - letter-spacing: 0.16px; - margin-right: 16px; - color: var(--bx-text-primary); - } -} - // @media only screen and (min-width: 320px) { // .advanced-search-dropdown { // width: 93.5%; diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index 993c1f65..8cacec12 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -280,6 +280,7 @@ const AdvancedSearchDropdown: React.FC = () => { titleText="Date type" items={dateTypeItems} itemToString={(item: any) => (item ? item.text : "")} + onChange={(e: any) => handleFilterChange({ dateType: e.selectedItem === null ? "" : e.selectedItem.value }) } From d0d05b49f340b1831d47369b2a56180035ddf72c Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Fri, 29 Nov 2024 08:24:26 -0800 Subject: [PATCH 13/31] fied reviewed comments --- backend/openshift.deploy.yml | 2 +- .../SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/backend/openshift.deploy.yml b/backend/openshift.deploy.yml index 803637c2..9c35799b 100644 --- a/backend/openshift.deploy.yml +++ b/backend/openshift.deploy.yml @@ -59,7 +59,7 @@ parameters: value: development - name: DATABASE_HOST description: Where the database is hosted - value: 142.34.84.58 #nrcdb03.bcgov + value: nrcdb03.bcgov - name: DATABASE_PORT description: The port to be used for the connection to the database value: "1543" diff --git a/frontend/src/components/SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx index 4e5ed0e6..7d178604 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx @@ -6,7 +6,6 @@ import AdvancedSearchDropdown from "../AdvancedSearchDropdown"; import SearchFilterBar from "../SearchFilterBar"; import { useOpeningsSearch } from "../../../../contexts/search/OpeningsSearch"; import { countActiveFilters } from "../../../../utils/searchUtils"; -import { callbackify } from "util"; import { c } from "vite/dist/node/types.d-aGj9QkWt"; interface IOpeningsSearchBar { From b095d6e1fb611ac2a2b4b0a6f864a373d16ce495 Mon Sep 17 00:00:00 2001 From: Paulo Gomes da Cruz Junior Date: Mon, 2 Dec 2024 07:15:06 -0800 Subject: [PATCH 14/31] chore: removed import --- .../SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/components/SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx index 7d178604..c3be5dc2 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/OpeningsSearchBar/index.tsx @@ -6,7 +6,6 @@ import AdvancedSearchDropdown from "../AdvancedSearchDropdown"; import SearchFilterBar from "../SearchFilterBar"; import { useOpeningsSearch } from "../../../../contexts/search/OpeningsSearch"; import { countActiveFilters } from "../../../../utils/searchUtils"; -import { c } from "vite/dist/node/types.d-aGj9QkWt"; interface IOpeningsSearchBar { onSearchClick: () => void; From cfe59954f8467c357da75c07172af19042bae7c1 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Tue, 3 Dec 2024 09:42:54 -0800 Subject: [PATCH 15/31] added for local dev --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index bb5d13c7..9b5f523b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -54,7 +54,7 @@ services: - $HOME/zscaler-certs:/certs working_dir: /app environment: - DATABASE_HOST: ${DATABASE_HOST} + DATABASE_HOST: ${DATABASE_HOST} #nrcdb03.bcgov DATABASE_PORT: "1543" DATABASE_USER: ${DATABASE_USER} DATABASE_PASSWORD: ${DATABASE_PASSWORD} @@ -90,7 +90,7 @@ services: wiremock: image: "wiremock/wiremock:latest" container_name: forest-client-api-stub - ports: ["9000:9000","9001:9001"] + ports: ["9002:9000","9001:9001"] volumes: - ./stub/:/home/wiremock/ entrypoint: ["/docker-entrypoint.sh", "--enable-stub-cors","--global-response-templating","--port","9000","--https-port","9001","--verbose"] \ No newline at end of file From 57d94d5b02a736df6bbbb6e31ac8e7b67e1b2639 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Tue, 3 Dec 2024 12:51:22 -0800 Subject: [PATCH 16/31] merged from main --- docker-compose.yml | 17 +- .../AutocompleteClientLocation/index.tsx | 141 +++--- .../AdvancedSearchDropdown.scss | 32 +- .../Openings/AdvancedSearchDropdown/index.tsx | 458 ++++++++---------- 4 files changed, 315 insertions(+), 333 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 9b5f523b..41ac1eea 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -48,7 +48,8 @@ services: entrypoint: sh -c './startup.sh' #image: maven:3.9.6-amazoncorretto-21 image: maven:3.9.9-eclipse-temurin-17 - network_mode: host + # network_mode: host + ports: [8080:8080] volumes: - ./backend:/app - $HOME/zscaler-certs:/certs @@ -62,7 +63,7 @@ services: ORACLEDB_KEYSTORE: /app/jssecacerts ORACLEDB_SECRET: changeit AWS_COGNITO_ISSUER_URI: https://cognito-idp.ca-central-1.amazonaws.com/ca-central-1_t2HSZBHur - POSTGRES_HOST: localhost + POSTGRES_HOST: database DASHBOARD_JOB_IDIR_USERS: ${DASHBOARD_JOB_IDIR_USERS} <<: *db-vars <<: *backend @@ -72,12 +73,12 @@ services: environment: <<: *db-vars volumes: ["/pgdata"] - ports: ["${POSTGRES_EXPOSED_PORT}:5432"] #changed to 5433 to avoid conflict with local postgres - # healthcheck: - # test: pg_isready -U nr-silva - # interval: 5s - # timeout: 5s - # retries: 5 + ports: ["5432:5432"] + healthcheck: + test: pg_isready -U nr-silva + interval: 5s + timeout: 5s + retries: 5 image: postgis/postgis:13-master backend-native: diff --git a/frontend/src/components/AutocompleteClientLocation/index.tsx b/frontend/src/components/AutocompleteClientLocation/index.tsx index e5df98e0..a46a9dd0 100644 --- a/frontend/src/components/AutocompleteClientLocation/index.tsx +++ b/frontend/src/components/AutocompleteClientLocation/index.tsx @@ -1,11 +1,11 @@ import React, { useEffect, useState, useImperativeHandle, forwardRef } from "react"; -import { ComboBox } from "@carbon/react"; +import { ComboBox, FlexGrid, Row, Column } from "@carbon/react"; import { useAutocomplete } from "../../contexts/AutocompleteProvider"; -import { +import { fetchClientsByNameAcronymNumber, fetchClientLocations, ForestClientAutocomplete, - ForestClientLocation + ForestClientLocation } from "../../services/OpeningClientLocationService"; interface AutocompleteProps { @@ -13,7 +13,7 @@ interface AutocompleteProps { label: string, } -interface AutocompleteComboboxProps{ +interface AutocompleteComboboxProps { selectedItem: AutocompleteProps } @@ -41,17 +41,17 @@ export const skipConditions = { export const fetchValues = async (query: string, key: string) => { // If there is no query, return an empty array - if(!key || !query) return []; - + if (!key || !query) return []; + // For clients, it will do the autocomplete search based on the name, acronym, or number if (key === "clients") { const response = await fetchClientsByNameAcronymNumber(query); const apiresponse = response; return apiresponse.map((item: ForestClientAutocomplete) => ({ id: item.id, - label: `${item.name}, ${item.id}, ${item.acronym? item.acronym : ''}` + label: `${item.name}, ${item.id}, ${item.acronym ? item.acronym : ''}` })); - } + } // For locations, it will just load the value based on the selected client id if (key === "locations") { @@ -67,67 +67,70 @@ export const fetchValues = async (query: string, key: string) => { }; const AutocompleteClientLocation: React.ForwardRefExoticComponent> = forwardRef( - ({ setValue }, ref) => - { - const { options, fetchOptions, updateOptions } = useAutocomplete(); - const [isActive, setIsActive] = useState(false); - const [location, setLocation] = useState(null); - const [client, setClient] = useState(null); - - const clearClient = () => { - updateOptions("locations", []); - updateOptions("clients", []); - setClient(null); - setValue(null); - setIsActive(false); - setLocation(null); - }; - - const handleClientChange = (autocompleteEvent: AutocompleteComboboxProps) => { - - const selectedItem = autocompleteEvent.selectedItem; - if (selectedItem) { - setIsActive(true); - setClient(selectedItem); - fetchOptions(selectedItem.id, "locations"); - }else{ - clearClient(); - } - }; - - useImperativeHandle(ref, () => ({ - reset: () => setLocation(null) - })); - - useEffect(() => { - setValue(location?.id ?? null); - }, [location]); - - return ( -
- fetchOptions(value, "clients")} - onChange={handleClientChange} - itemToElement={(item: AutocompleteProps) => item.label} - helperText="Search by client name, number or acronym" - items={options["clients"] || []} - titleText="Client" /> - - setLocation(item.selectedItem)} - itemToElement={(item: AutocompleteProps) => item.label} - items={options["locations"] || [{ id: "", label: "No results found" }]} - titleText="Location code" /> -
- ); -}); + ({ setValue }, ref) => { + const { options, fetchOptions, updateOptions } = useAutocomplete(); + const [isActive, setIsActive] = useState(false); + const [location, setLocation] = useState(null); + const [client, setClient] = useState(null); + + const clearClient = () => { + updateOptions("locations", []); + updateOptions("clients", []); + setClient(null); + setValue(null); + setIsActive(false); + setLocation(null); + }; + + const handleClientChange = (autocompleteEvent: AutocompleteComboboxProps) => { + + const selectedItem = autocompleteEvent.selectedItem; + if (selectedItem) { + setIsActive(true); + setClient(selectedItem); + fetchOptions(selectedItem.id, "locations"); + } else { + clearClient(); + } + }; + + useImperativeHandle(ref, () => ({ + reset: () => setLocation(null) + })); + + useEffect(() => { + setValue(location?.id ?? null); + }, [location]); + + return ( + + + + fetchOptions(value, "clients")} + onChange={handleClientChange} + itemToElement={(item: AutocompleteProps) => item.label} + helperText="Search by client name, number or acronym" + items={options["clients"] || []} + titleText="Client" /> + + + setLocation(item.selectedItem)} + itemToElement={(item: AutocompleteProps) => item.label} + items={options["locations"] || [{ id: "", label: "No results found" }]} + titleText="Location code" /> + + + + + ); + }); AutocompleteClientLocation.displayName = "AutocompleteClientLocation"; diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss index 25e5204f..bfe21e94 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss @@ -10,6 +10,11 @@ position: absolute; z-index: 2; box-shadow: 0px 2px 6px 0px #0000004D; + + .autoClientLocation { + padding-left: 10px; + padding-right: 0px; + } legend { font-size: 16px; @@ -31,18 +36,29 @@ padding: 5px; } - .orgUnitCol { + .bx--col-md-3 { padding-right: 10px; } - .clientLocationCodeCol { - padding-right: 10px; + .orgUnitCol { + padding-right: 15px; } - + .timeberMarkCol { - padding-right: 10px; + padding-right: 15px; + } + + .cutBlock { + padding-top: 6px; } + .cuttingPermit { + padding-top: 6px; + } + + .clientLocation { + padding-right: 5px; + } input { background-color: var(--bx-field-01); @@ -61,12 +77,6 @@ color: var(--#{vars.$bcgov-prefix}-text-secondary); } - #tooltip { - border: 0; - padding-bottom: 0px; - padding-top: 0px; - background-color: var(--#{vars.$bcgov-prefix}-layer-02); - } .multi-select .bx--list-box__field--wrapper { background-color: var(--bx-field-01); diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index 6baf0bfd..2abdce18 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -8,6 +8,7 @@ import { DatePickerInput, Loading, FlexGrid, + FilterableMultiSelect, Row, Column , ComboBox } from "@carbon/react"; @@ -17,13 +18,13 @@ import { useOpeningsSearch } from "../../../../contexts/search/OpeningsSearch"; import { TextValueData, sortItems } from "../../../../utils/multiSelectSortUtils"; import { formatDateForDatePicker } from "../../../../utils/DateUtils"; import { AutocompleteProvider } from "../../../../contexts/AutocompleteProvider"; -import AutocompleteClientLocation, { skipConditions, fetchValues, AutocompleteComponentRefProps} from "../../../AutocompleteClientLocation"; +import AutocompleteClientLocation, { skipConditions, fetchValues, AutocompleteComponentRefProps } from "../../../AutocompleteClientLocation"; interface AdvancedSearchDropdownProps { toggleShowFilters: () => void; // Function to be passed as a prop } -const AdvancedSearchDropdown: React.FC = () => { +const AdvancedSearchDropdown: React.FC = () => { const { filters, setFilters, setIndividualClearFieldFunctions } = useOpeningsSearch(); const { data, isLoading, isError } = useOpeningFiltersQuery(); @@ -58,24 +59,13 @@ const AdvancedSearchDropdown: React.FC = () => { useEffect(() => { - // In here, we're defining the function that will be called when the user clicks on the "Clear" button - // The idea is to keep the autocomplete component clear of any ties to the opening search context - setIndividualClearFieldFunctions((previousIndividualFilters) => ({ - ...previousIndividualFilters, - clientLocationCode: () => autoCompleteRef.current?.reset() - })); - },[]); - - useEffect(() => { - - // In here, we're defining the function that will be called when the user clicks on the "Clear" button - // The idea is to keep the autocomplete component clear of any ties to the opening search context - setIndividualClearFieldFunctions((previousIndividualFilters) => ({ - ...previousIndividualFilters, - clientLocationCode: () => autoCompleteRef.current?.reset() - })); - },[]); - + // In here, we're defining the function that will be called when the user clicks on the "Clear" button + // The idea is to keep the autocomplete component clear of any ties to the opening search context + setIndividualClearFieldFunctions((previousIndividualFilters) => ({ + ...previousIndividualFilters, + clientLocationCode: () => autoCompleteRef.current?.reset() + })); + }, []); const handleFilterChange = (updatedFilters: Partial) => { setFilters({ ...filters, ...updatedFilters }); @@ -99,7 +89,7 @@ const AdvancedSearchDropdown: React.FC = () => { handleFilterChange({ [group]: updatedGroup }); }; - + if (isLoading) { return ; } @@ -137,47 +127,46 @@ const AdvancedSearchDropdown: React.FC = () => { })) || []; return ( -
- - - - - - handleCheckboxChange( - "Openings created by me", - "openingFilters" - ) - } - /> - - handleCheckboxChange( - "FRPA section 108", - "openingFilters" - ) - } - /> - - - - - - - + + + + + handleCheckboxChange( + "Openings created by me", + "openingFilters" + ) + } + /> + + handleCheckboxChange( + "FRPA section 108", + "openingFilters" + ) + } + /> + + + + + + = () => { onChange={(e: any) => handleMultiSelectChange("orgUnit", e.selectedItems)} selectedItems={selectedOrgUnits} sortItems={sortItems} - /> - - - + + + = () => { items={categoryItems} itemToString={(item: any) => (item ? `${item.value} - ${item.text}` : "")} selectionFeedback="top-after-reopen" - onChange={(e: any) => handleMultiSelectChange("category",e.selectedItems)} + onChange={(e: any) => handleMultiSelectChange("category", e.selectedItems)} selectedItems={selectedCategories} sortItems={sortItems} - /> - - - - - - - handleFilterChange({ clientLocationCode: value })} + /> + + + + + + handleFilterChange({ clientLocationCode: value })} ref={autoCompleteRef} - /> - - - -
- + /> + + + + handleFilterChange({ cutBlock: e.target.value }) - } - /> - + } + /> + + + handleFilterChange({ cuttingPermit: e.target.value }) - } - /> -
-
-
+ } + /> +
+
- - - + + - handleFilterChange({ timberMark: e.target.value }) + handleFilterChange({ timberMark: e.target.value }) } - /> - - - - - - (item ? item.text : "")} - onChange={(e: any) => - handleFilterChange({ dateType: e.selectedItem.value }) - } - selectedItem={ - filters.dateType - ? dateTypeItems.find( - (item: any) => item.value === filters.dateType - ) - : "" - } - label="Date type" - /> - - -
- { - if (dates.length > 0) { - handleFilterChange({ - startDate: dates[0].toISOString().slice(0, 10) - }); - } - }} - onClose={(dates: [Date]) => { - if (dates.length > 0) { - handleFilterChange({ - startDate: dates[0].toISOString().slice(0, 10) - }); - } - }} - readOnly={!filters.dateType} - > - - + /> + + + (item ? item.text : "")} - { - if (dates.length > 0) { - handleFilterChange({ - endDate: dates[0].toISOString().slice(0, 10) - }); - } - }} - onClose={(dates: [Date]) => { - if (dates.length > 0) { - handleFilterChange({ - endDate: dates[0].toISOString().slice(0, 10) - }); - } - }} - readOnly={!filters.dateType} - > - - -
-
-
-
-
-
- - - - + handleFilterChange({ dateType: e.selectedItem === null ? "" : e.selectedItem.value }) + } + label="Date type" + /> + + + { + if (dates.length > 0) { + handleFilterChange({ + startDate: dates[0].toISOString().slice(0, 10), + }); + } + }} + onClose={(dates: [Date]) => { + if (dates.length > 0) { + handleFilterChange({ + startDate: dates[0].toISOString().slice(0, 10), + }); + } + }} + disabled={!filters.dateType} + enabled={filters.dateType} + readOnly={!filters.dateType} + > + + + + + + + + -
- handleCheckboxChange("DFT", "status")} - /> - handleCheckboxChange("APP", "status")} - /> - handleCheckboxChange("FG", "status")} - /> - handleCheckboxChange("SUB", "status")} - /> -
-
-
-
-
-
+ > + handleCheckboxChange("AMG", "status")} + /> + handleCheckboxChange("AMD", "status")} + /> + handleCheckboxChange("APP", "status")} + /> + handleCheckboxChange("DFT", "status")} + /> + handleCheckboxChange("FG", "status")} + /> + handleCheckboxChange("RMD", "status")} + /> + handleCheckboxChange("RET", "status")} + /> + handleCheckboxChange("SUB", "status")} + /> + + +
+ +
); }; From 218a878544359e67cadca20de8466d60774f3acb Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Tue, 3 Dec 2024 13:04:12 -0800 Subject: [PATCH 17/31] updates for look and fell of date-picker --- .../Openings/AdvancedSearchDropdown/index.tsx | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index 2abdce18..76244a66 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -1,8 +1,7 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useState, useRef } from "react"; import { Checkbox, CheckboxGroup, - Dropdown, TextInput, DatePicker, DatePickerInput, @@ -120,12 +119,6 @@ const AdvancedSearchDropdown: React.FC = () => { value: item.value })) || []; - const blockStatusItems = - data.blockStatuses?.map((item: any) => ({ - text: item.label, - value: item.value - })) || []; - return ( @@ -233,7 +226,6 @@ const AdvancedSearchDropdown: React.FC = () => { @@ -246,7 +238,6 @@ const AdvancedSearchDropdown: React.FC = () => { titleText="Date type" items={dateTypeItems} itemToString={(item: any) => (item ? item.text : "")} - onChange={(e: any) => handleFilterChange({ dateType: e.selectedItem === null ? "" : e.selectedItem.value }) } @@ -259,14 +250,14 @@ const AdvancedSearchDropdown: React.FC = () => { onChange={(dates: [Date]) => { if (dates.length > 0) { handleFilterChange({ - startDate: dates[0].toISOString().slice(0, 10), + startDate: dates[0].toISOString().slice(0, 10) }); } }} onClose={(dates: [Date]) => { if (dates.length > 0) { handleFilterChange({ - startDate: dates[0].toISOString().slice(0, 10), + startDate: dates[0].toISOString().slice(0, 10) }); } }} From a6aec9a10e1579aed77d83ef50568e77ad77fb0b Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Tue, 3 Dec 2024 14:35:31 -0800 Subject: [PATCH 18/31] latest updates to advanced search dropdown --- .../AutocompleteClientLocation/index.tsx | 5 +-- .../components/OpeningsSearchTable/index.tsx | 6 +-- .../AdvancedSearchDropdown.scss | 39 +++++++++++++------ .../Openings/AdvancedSearchDropdown/index.tsx | 6 +-- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/frontend/src/components/AutocompleteClientLocation/index.tsx b/frontend/src/components/AutocompleteClientLocation/index.tsx index a46a9dd0..46082a9e 100644 --- a/frontend/src/components/AutocompleteClientLocation/index.tsx +++ b/frontend/src/components/AutocompleteClientLocation/index.tsx @@ -105,7 +105,7 @@ const AutocompleteClientLocation: React.ForwardRefExoticComponent - + - setLocation(item.selectedItem)} @@ -126,7 +126,6 @@ const AutocompleteClientLocation: React.ForwardRefExoticComponent - ); diff --git a/frontend/src/components/OpeningsSearchTable/index.tsx b/frontend/src/components/OpeningsSearchTable/index.tsx index e066896c..fc3616ff 100644 --- a/frontend/src/components/OpeningsSearchTable/index.tsx +++ b/frontend/src/components/OpeningsSearchTable/index.tsx @@ -62,7 +62,7 @@ const OpeningsSearchTable: React.FC = ({ }; const clickViewAction = useCallback((id: string) => { - console.log(`Clicked view on id ${id}`); + //console.log(`Clicked view on id ${id}`); }, []); const selectRowEvent = useCallback((openingId: string, selected: boolean) => { @@ -72,7 +72,7 @@ const OpeningsSearchTable: React.FC = ({ }, []); const batchActionClick = (selectedRows: any[]) => () => { - console.log('Batch action clicked with selected rows:', selectedRows); + //console.log('Batch action clicked with selected rows:', selectedRows); // Add your logic to handle batch actions here }; @@ -96,7 +96,7 @@ const OpeningsSearchTable: React.FC = ({ selectedRows, getTableProps, getTableContainerProps, - selectRow, + selectRow }:{ rows: any[], headers: any[], diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss index bfe21e94..a244e06b 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss @@ -17,7 +17,7 @@ } legend { - font-size: 16px; + font-size: 1rem; line-height: 20px; letter-spacing: 0.16px; color: var(--bx-text-primary); @@ -25,15 +25,19 @@ } label { - font-size: 16px; + font-size: 1rem; line-height: 20px; letter-spacing: 0.16px; white-space: nowrap; color: var(--#{vars.$bcgov-prefix}-text-primary); } + .startEndDateCol { + padding-top: 5px; + } + .bx--row { - padding: 5px; + padding: 10px; } .bx--col-md-3 { @@ -41,23 +45,27 @@ } .orgUnitCol { - padding-right: 15px; + padding-right: 2rem; + } + + .locationCodeCombo { + width:96% } .timeberMarkCol { - padding-right: 15px; + padding-right: 2rem; } .cutBlock { - padding-top: 6px; + padding-top: 10px; } .cuttingPermit { - padding-top: 6px; + padding-top: 10px; } - .clientLocation { - padding-right: 5px; + .clientLocationCol { + padding-right: 2rem; } input { @@ -76,12 +84,21 @@ .bx--label--disabled { color: var(--#{vars.$bcgov-prefix}-text-secondary); } - - + .bx--text-input { + color: var(--#{vars.$bcgov-prefix}-text-secondary); + } .multi-select .bx--list-box__field--wrapper { background-color: var(--bx-field-01); border-bottom: 1px solid var(--bx-border-strong-01); } + + .bx--date-picker--range .bx--date-picker-container, .bx--date-picker--range .bx--date-picker__input { + width: 90% + } + + .bx--date-picker__input[readonly] { + width: 90%; + } } // @media only screen and (min-width: 320px) { diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index 76244a66..ecf6881f 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -33,7 +33,7 @@ const AdvancedSearchDropdown: React.FC = () => { const autoCompleteRef = useRef(null); useEffect(() => { - console.log("Use Effect in child is being called.", filters); + //console.log("Use Effect in child is being called.", filters); // Split filters.orgUnit into array and format as needed for selectedItems if (filters.orgUnit) { const orgUnitsArray = filters.orgUnit.map((orgUnit: string) => ({ @@ -188,7 +188,7 @@ const AdvancedSearchDropdown: React.FC = () => { - + handleFilterChange({ clientLocationCode: value })} @@ -233,7 +233,7 @@ const AdvancedSearchDropdown: React.FC = () => { } /> - + Date: Wed, 4 Dec 2024 16:24:23 -0800 Subject: [PATCH 19/31] clear filters fix --- frontend/src/contexts/search/OpeningsSearch.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frontend/src/contexts/search/OpeningsSearch.tsx b/frontend/src/contexts/search/OpeningsSearch.tsx index 76973654..5f116ee9 100644 --- a/frontend/src/contexts/search/OpeningsSearch.tsx +++ b/frontend/src/contexts/search/OpeningsSearch.tsx @@ -30,7 +30,7 @@ export const OpeningsSearchProvider: React.FC<{ children: ReactNode }> = ({ chil timberMark: "", dateType: null as string | null, openingFilters: [] as string[], - blockStatuses: [] as string[], + blockStatuses: [] as string[] }; const [filters, setFilters] = useState(defaultFilters); @@ -47,11 +47,10 @@ export const OpeningsSearchProvider: React.FC<{ children: ReactNode }> = ({ chil }; const clearFilters = () => { - setFilters(defaultFilters); - Object.keys(defaultFilters).forEach((key) => { individualClearFieldFunctions[key] && individualClearFieldFunctions[key](); }); + setFilters(defaultFilters); }; From e29f657f166e11260cccaddadd99d5f2ca720a76 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Fri, 6 Dec 2024 10:24:41 -0800 Subject: [PATCH 20/31] force repromosion --- .../Openings/AdvancedSearchDropdown/index.tsx | 2 +- frontend/src/contexts/search/OpeningsSearch.tsx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index ecf6881f..a9990a88 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -265,7 +265,7 @@ const AdvancedSearchDropdown: React.FC = () => { enabled={filters.dateType} readOnly={!filters.dateType} > - = ({ chil Object.keys(defaultFilters).forEach((key) => { individualClearFieldFunctions[key] && individualClearFieldFunctions[key](); }); + setFilters(defaultFilters); }; From 4bd252b70092c6a0bd81841f9afb9b101089e391 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Fri, 6 Dec 2024 13:15:56 -0800 Subject: [PATCH 21/31] tweaks to size and form placement --- .../AdvancedSearchDropdown.scss | 39 ++- .../Openings/AdvancedSearchDropdown/index.tsx | 250 +++++++++--------- 2 files changed, 143 insertions(+), 146 deletions(-) diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss index a244e06b..52466269 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss @@ -15,25 +15,29 @@ padding-left: 10px; padding-right: 0px; } - + legend { - font-size: 1rem; - line-height: 20px; + font-size: 12px; + line-height: 16px; letter-spacing: 0.16px; color: var(--bx-text-primary); white-space: nowrap; } label { - font-size: 1rem; - line-height: 20px; + font-size: 12px; + line-height: 16px; letter-spacing: 0.16px; white-space: nowrap; color: var(--#{vars.$bcgov-prefix}-text-primary); - } + } - .startEndDateCol { - padding-top: 5px; + .bx--label--disabled { + color: var(--#{vars.$bcgov-prefix}-text-secondary); + } + + .bx--text-input { + color: var(--#{vars.$bcgov-prefix}-text-secondary); } .bx--row { @@ -49,7 +53,7 @@ } .locationCodeCombo { - width:96% + width: 96% } .timeberMarkCol { @@ -57,11 +61,11 @@ } .cutBlock { - padding-top: 10px; + padding-top: 12px; } .cuttingPermit { - padding-top: 10px; + padding-top: 12px; } .clientLocationCol { @@ -81,23 +85,18 @@ color: var(--#{vars.$bcgov-prefix}-text-secondary); } - .bx--label--disabled { - color: var(--#{vars.$bcgov-prefix}-text-secondary); - } - .bx--text-input { - color: var(--#{vars.$bcgov-prefix}-text-secondary); - } .multi-select .bx--list-box__field--wrapper { background-color: var(--bx-field-01); border-bottom: 1px solid var(--bx-border-strong-01); } - .bx--date-picker--range .bx--date-picker-container, .bx--date-picker--range .bx--date-picker__input { - width: 90% + .bx--date-picker--range .bx--date-picker-container, + .bx--date-picker--range .bx--date-picker__input { + width: 95% } .bx--date-picker__input[readonly] { - width: 90%; + width: 95%; } } diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index a9990a88..ec238f13 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -10,7 +10,8 @@ import { FilterableMultiSelect, Row, Column -, ComboBox } from "@carbon/react"; + , ComboBox +} from "@carbon/react"; import "./AdvancedSearchDropdown.scss"; import { useOpeningFiltersQuery } from "../../../../services/queries/search/openingQueries"; import { useOpeningsSearch } from "../../../../contexts/search/OpeningsSearch"; @@ -67,6 +68,10 @@ const AdvancedSearchDropdown: React.FC = () => { }, []); const handleFilterChange = (updatedFilters: Partial) => { + if (updatedFilters.dateType === "") { + updatedFilters.startDate = null as Date | null; + updatedFilters.endDate = null as Date | null; + } setFilters({ ...filters, ...updatedFilters }); }; @@ -160,30 +165,30 @@ const AdvancedSearchDropdown: React.FC = () => { (item ? `${item.value} - ${item.text}` : "")} - selectionFeedback="top-after-reopen" - onChange={(e: any) => handleMultiSelectChange("orgUnit", e.selectedItems)} - selectedItems={selectedOrgUnits} - sortItems={sortItems} + label="Enter or choose an org unit" + id="orgunit-multiselect" + className="multi-select" + titleText="Org Unit" + items={orgUnitItems} + itemToString={(item: TextValueData) => (item ? `${item.value} - ${item.text}` : "")} + selectionFeedback="top-after-reopen" + onChange={(e: any) => handleMultiSelectChange("orgUnit", e.selectedItems)} + selectedItems={selectedOrgUnits} + sortItems={sortItems} /> (item ? `${item.value} - ${item.text}` : "")} - selectionFeedback="top-after-reopen" - onChange={(e: any) => handleMultiSelectChange("category", e.selectedItems)} - selectedItems={selectedCategories} - sortItems={sortItems} + label="Enter or choose a category" + id="category-multiselect" + className="multi-select" + titleText="Category" + items={categoryItems} + itemToString={(item: any) => (item ? `${item.value} - ${item.text}` : "")} + selectionFeedback="top-after-reopen" + onChange={(e: any) => handleMultiSelectChange("category", e.selectedItems)} + selectedItems={selectedCategories} + sortItems={sortItems} /> @@ -191,33 +196,33 @@ const AdvancedSearchDropdown: React.FC = () => { handleFilterChange({ clientLocationCode: value })} - ref={autoCompleteRef} + setValue={(value: string | null) => handleFilterChange({ clientLocationCode: value })} + ref={autoCompleteRef} /> - handleFilterChange({ cutBlock: e.target.value }) - } + id="text-input-2" + className="cutBlock" + type="text" + labelText="Cut block" + value={filters.cutBlock} + onChange={(e: any) => + handleFilterChange({ cutBlock: e.target.value }) + } /> - handleFilterChange({ cuttingPermit: e.target.value }) - } + id="text-input-3" + className="cuttingPermit" + labelText="Cutting permit" + type="text" + value={filters.cuttingPermit} + onChange={(e: any) => + handleFilterChange({ cuttingPermit: e.target.value }) + } /> @@ -225,70 +230,63 @@ const AdvancedSearchDropdown: React.FC = () => { - handleFilterChange({ timberMark: e.target.value }) - } + id="timber-mark-input" + labelText="Timber mark" + value={filters.timberMark} + onChange={(e: any) => + handleFilterChange({ timberMark: e.target.value }) + } /> (item ? item.text : "")} - onChange={(e: any) => - handleFilterChange({ dateType: e.selectedItem === null ? "" : e.selectedItem.value }) - } - label="Date type" + titleText="Date type" + items={dateTypeItems} + itemToString={(item: any) => (item ? item.text : "")} + onChange={(e: any) => + handleFilterChange({ dateType: e.selectedItem === null ? "" : e.selectedItem.value }) + } + label="Date type" /> { - if (dates.length > 0) { - handleFilterChange({ - startDate: dates[0].toISOString().slice(0, 10) - }); - } - }} - onClose={(dates: [Date]) => { - if (dates.length > 0) { - handleFilterChange({ - startDate: dates[0].toISOString().slice(0, 10) - }); - } - }} - disabled={!filters.dateType} - enabled={filters.dateType} - readOnly={!filters.dateType} + datePickerType="range" + onChange={(dates: [Date]) => { + if (dates.length > 0) { + + handleFilterChange({ + startDate: dates[0].toISOString().slice(0, 10), + endDate: dates[1].toISOString().slice(0, 10) + }); + } + }} + onClose={(dates: [Date]) => { + if (dates.length > 0) { + handleFilterChange({ + startDate: dates[0].toISOString().slice(0, 10), + endDate: dates[1].toISOString().slice(0, 10) + }); + } + }} + disabled={!filters.dateType} + // enabled={filters.dateType} + // readOnly={!filters.dateType} > - @@ -296,56 +294,56 @@ const AdvancedSearchDropdown: React.FC = () => { handleCheckboxChange("AMG", "status")} + labelText={`AMG - Amalgamate`} + id="checkbox-label-amg" + checked={filters.status.includes("AMG")} + onChange={() => handleCheckboxChange("AMG", "status")} /> handleCheckboxChange("AMD", "status")} + labelText={`AMD - Amended`} + id="checkbox-label-amd" + checked={filters.status.includes("AMD")} + onChange={() => handleCheckboxChange("AMD", "status")} /> handleCheckboxChange("APP", "status")} + labelText={`APP - Approved`} + id="checkbox-label-app" + checked={filters.status.includes("APP")} + onChange={() => handleCheckboxChange("APP", "status")} /> handleCheckboxChange("DFT", "status")} + labelText={`DFT - Draft`} + id="checkbox-label-dft" + checked={filters.status.includes("DFT")} + onChange={() => handleCheckboxChange("DFT", "status")} /> handleCheckboxChange("FG", "status")} + labelText={`FG - Free Growing`} + id="checkbox-label-fg" + checked={filters.status.includes("FG")} + onChange={() => handleCheckboxChange("FG", "status")} /> handleCheckboxChange("RMD", "status")} + labelText={`RMD - Removed`} + id="checkbox-label-rmd" + checked={filters.status.includes("RMD")} + onChange={() => handleCheckboxChange("RMD", "status")} /> handleCheckboxChange("RET", "status")} + labelText={`RET - Retired`} + id="checkbox-label-ret" + checked={filters.status.includes("RET")} + onChange={() => handleCheckboxChange("RET", "status")} /> handleCheckboxChange("SUB", "status")} + labelText={`SUB - Submitted`} + id="checkbox-label-sub" + checked={filters.status.includes("SUB")} + onChange={() => handleCheckboxChange("SUB", "status")} /> From 16f9b012a1514cb1a575c9e68d9c353463fe10a4 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Fri, 6 Dec 2024 13:24:03 -0800 Subject: [PATCH 22/31] added null checks for endDate --- .../Openings/AdvancedSearchDropdown/index.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index ec238f13..a13af674 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -254,10 +254,9 @@ const AdvancedSearchDropdown: React.FC = () => { datePickerType="range" onChange={(dates: [Date]) => { if (dates.length > 0) { - handleFilterChange({ startDate: dates[0].toISOString().slice(0, 10), - endDate: dates[1].toISOString().slice(0, 10) + endDate: dates[1] ? dates[1].toISOString().slice(0, 10) : null }); } }} @@ -265,7 +264,7 @@ const AdvancedSearchDropdown: React.FC = () => { if (dates.length > 0) { handleFilterChange({ startDate: dates[0].toISOString().slice(0, 10), - endDate: dates[1].toISOString().slice(0, 10) + endDate: dates[1] ? dates[1].toISOString().slice(0, 10) : null }); } }} From d79ce203a9eefc0e68546dddaa4e5cf06afdadf6 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Fri, 6 Dec 2024 13:36:40 -0800 Subject: [PATCH 23/31] turned strict null checks off\ --- frontend/tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 7bc6583f..f5bf9bee 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -12,6 +12,7 @@ "esModuleInterop": true, "allowSyntheticDefaultImports": true, "strict": true, + "strictNullChecks": false, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, "module": "esnext", From 12769312a28690d6cf7da6da045b04e727b5d2c6 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Fri, 6 Dec 2024 13:40:47 -0800 Subject: [PATCH 24/31] reverted strict null --- frontend/tsconfig.json | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index f5bf9bee..7bc6583f 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -12,7 +12,6 @@ "esModuleInterop": true, "allowSyntheticDefaultImports": true, "strict": true, - "strictNullChecks": false, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, "module": "esnext", From bb230515cd53e7b8d85210cf87bb4ea5095a0992 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Fri, 6 Dec 2024 13:44:45 -0800 Subject: [PATCH 25/31] fixed date handler --- .../Openings/AdvancedSearchDropdown/index.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index a13af674..4607f851 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -252,7 +252,7 @@ const AdvancedSearchDropdown: React.FC = () => { { + onChange={(dates: [Date, Date]) => { if (dates.length > 0) { handleFilterChange({ startDate: dates[0].toISOString().slice(0, 10), @@ -260,7 +260,7 @@ const AdvancedSearchDropdown: React.FC = () => { }); } }} - onClose={(dates: [Date]) => { + onClose={(dates: [Date, Date]) => { if (dates.length > 0) { handleFilterChange({ startDate: dates[0].toISOString().slice(0, 10), @@ -269,8 +269,6 @@ const AdvancedSearchDropdown: React.FC = () => { } }} disabled={!filters.dateType} - // enabled={filters.dateType} - // readOnly={!filters.dateType} > = () => { labelText="End Date" placeholder="yyyy/MM/dd" disabled={!filters.dateType} - // enabled={filters.dateType} - // readOnly={!filters.dateType} value={formatDateForDatePicker(filters.endDate)} /> From 36092334162500ca876038f7fa1501635871f689 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Fri, 6 Dec 2024 13:54:52 -0800 Subject: [PATCH 26/31] fixes to unlock dates --- .../SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index 4607f851..a393d040 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -274,7 +274,6 @@ const AdvancedSearchDropdown: React.FC = () => { labelText="Start Date" placeholder="yyyy/MM/dd" disabled={!filters.dateType} - // enabled={filters.dateType} value={formatDateForDatePicker(filters.startDate)} /> Date: Mon, 9 Dec 2024 11:15:17 -0800 Subject: [PATCH 27/31] fix for combo box bug --- .../Openings/AdvancedSearchDropdown/index.tsx | 52 ++++++++++++------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index a393d040..9194a0a9 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -9,8 +9,8 @@ import { FlexGrid, FilterableMultiSelect, Row, - Column - , ComboBox + Column, + ComboBox } from "@carbon/react"; import "./AdvancedSearchDropdown.scss"; import { useOpeningFiltersQuery } from "../../../../services/queries/search/openingQueries"; @@ -31,8 +31,27 @@ const AdvancedSearchDropdown: React.FC = () => { // Initialize selected items for OrgUnit MultiSelect based on existing filters const [selectedOrgUnits, setSelectedOrgUnits] = useState([]); const [selectedCategories, setSelectedCategories] = useState([]); + const [dateTypeValue, setDateTypeValue] = useState(null); const autoCompleteRef = useRef(null); + const categoryItems = + data?.categories?.map((item: any) => ({ + text: item.description, + value: item.code + })) || []; + + const orgUnitItems = + data?.orgUnits?.map((item: any) => ({ + text: item.orgUnitName, + value: item.orgUnitCode + })) || []; + + const dateTypeItems = + data?.dateTypes?.map((item: any) => ({ + text: item.label, + value: item.value + })) || []; + useEffect(() => { //console.log("Use Effect in child is being called.", filters); // Split filters.orgUnit into array and format as needed for selectedItems @@ -67,6 +86,17 @@ const AdvancedSearchDropdown: React.FC = () => { })); }, []); + useEffect(() => { + // We use the useEffect to do a lookup on the clients options + // It will fill with the autocomplete triggering the fetchOptions + const selectedItem = dateTypeItems?.find((item: any) => item.text === dateTypeValue) || null; + + if (selectedItem) { + handleFilterChange({ dateType: selectedItem.value }); + } + + }, [dateTypeValue]); + const handleFilterChange = (updatedFilters: Partial) => { if (updatedFilters.dateType === "") { updatedFilters.startDate = null as Date | null; @@ -106,23 +136,6 @@ const AdvancedSearchDropdown: React.FC = () => { ); } - const categoryItems = - data.categories?.map((item: any) => ({ - text: item.description, - value: item.code - })) || []; - - const orgUnitItems = - data.orgUnits?.map((item: any) => ({ - text: item.orgUnitName, - value: item.orgUnitCode - })) || []; - - const dateTypeItems = - data.dateTypes?.map((item: any) => ({ - text: item.label, - value: item.value - })) || []; return ( @@ -243,6 +256,7 @@ const AdvancedSearchDropdown: React.FC = () => { titleText="Date type" items={dateTypeItems} itemToString={(item: any) => (item ? item.text : "")} + onInputChange={setDateTypeValue} onChange={(e: any) => handleFilterChange({ dateType: e.selectedItem === null ? "" : e.selectedItem.value }) } From be49395e534ad6079849a14ac984df45c112d0cb Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Tue, 17 Dec 2024 09:26:32 -0800 Subject: [PATCH 28/31] fix for dattypecol --- .../Openings/AdvancedSearchDropdown/index.tsx | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index 9194a0a9..a46285af 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -19,11 +19,17 @@ import { TextValueData, sortItems } from "../../../../utils/multiSelectSortUtils import { formatDateForDatePicker } from "../../../../utils/DateUtils"; import { AutocompleteProvider } from "../../../../contexts/AutocompleteProvider"; import AutocompleteClientLocation, { skipConditions, fetchValues, AutocompleteComponentRefProps } from "../../../AutocompleteClientLocation"; +import { setDate } from "date-fns"; interface AdvancedSearchDropdownProps { toggleShowFilters: () => void; // Function to be passed as a prop } +interface TextValueProps { + text: string; + value: string; +} + const AdvancedSearchDropdown: React.FC = () => { const { filters, setFilters, setIndividualClearFieldFunctions } = useOpeningsSearch(); const { data, isLoading, isError } = useOpeningFiltersQuery(); @@ -32,6 +38,7 @@ const AdvancedSearchDropdown: React.FC = () => { const [selectedOrgUnits, setSelectedOrgUnits] = useState([]); const [selectedCategories, setSelectedCategories] = useState([]); const [dateTypeValue, setDateTypeValue] = useState(null); + const [dateTypeItem, setDateTypeItem] = useState(null); const autoCompleteRef = useRef(null); const categoryItems = @@ -76,13 +83,23 @@ const AdvancedSearchDropdown: React.FC = () => { } }, [filters.orgUnit, filters.category]); - useEffect(() => { + const clearDates = () => { + handleFilterChange({ + startDate: null, + endDate: null, + dateType: "" + }); + setDateTypeValue(null); + setDateTypeItem(null); + }; + useEffect(() => { // In here, we're defining the function that will be called when the user clicks on the "Clear" button // The idea is to keep the autocomplete component clear of any ties to the opening search context setIndividualClearFieldFunctions((previousIndividualFilters) => ({ ...previousIndividualFilters, - clientLocationCode: () => autoCompleteRef.current?.reset() + clientLocationCode: () => autoCompleteRef.current?.reset(), + startDate: clearDates })); }, []); @@ -92,6 +109,7 @@ const AdvancedSearchDropdown: React.FC = () => { const selectedItem = dateTypeItems?.find((item: any) => item.text === dateTypeValue) || null; if (selectedItem) { + setDateTypeItem(selectedItem); handleFilterChange({ dateType: selectedItem.value }); } @@ -257,6 +275,7 @@ const AdvancedSearchDropdown: React.FC = () => { items={dateTypeItems} itemToString={(item: any) => (item ? item.text : "")} onInputChange={setDateTypeValue} + selectedItem={dateTypeItem} onChange={(e: any) => handleFilterChange({ dateType: e.selectedItem === null ? "" : e.selectedItem.value }) } @@ -361,4 +380,4 @@ const AdvancedSearchDropdown: React.FC = () => { ); }; -export default AdvancedSearchDropdown; +export default AdvancedSearchDropdown; \ No newline at end of file From 98e0b6fd1b9993bfb150f395decaeb1a3a2b544d Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Wed, 18 Dec 2024 10:28:17 -0800 Subject: [PATCH 29/31] fix to clear filters --- .../SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index a46285af..b1b08dd4 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -91,6 +91,7 @@ const AdvancedSearchDropdown: React.FC = () => { }); setDateTypeValue(null); setDateTypeItem(null); + setFilters({ ...filters, startDate: null, endDate: null, dateType: "" }); }; useEffect(() => { From 90ad7abdc42c44e31501d433542090d85f1235d4 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Mon, 6 Jan 2025 11:04:35 -0800 Subject: [PATCH 30/31] switched date picker to combobox --- .../Openings/AdvancedSearchDropdown/index.tsx | 76 ++++++++++--------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx index f87abab4..c6b8608d 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -1,17 +1,17 @@ -import React, { useEffect, useState, useRef } from "react"; +import React, { useState, useEffect, useRef } from "react"; import { Checkbox, CheckboxGroup, + Dropdown, TextInput, DatePicker, DatePickerInput, Loading, FlexGrid, - FilterableMultiSelect, Row, Column, - ComboBox -} from "@carbon/react"; + FilterableMultiSelect +, ComboBox } from "@carbon/react"; import "./AdvancedSearchDropdown.scss"; import { useOpeningFiltersQuery } from "../../../../services/queries/search/openingQueries"; import { useOpeningsSearch } from "../../../../contexts/search/OpeningsSearch"; @@ -25,20 +25,13 @@ interface AdvancedSearchDropdownProps { toggleShowFilters: () => void; // Function to be passed as a prop } -interface TextValueProps { - text: string; - value: string; -} - -const AdvancedSearchDropdown: React.FC = () => { +const AdvancedSearchDropdown: React.FC = () => { const { filters, setFilters, setIndividualClearFieldFunctions } = useOpeningsSearch(); const { data, isLoading, isError } = useOpeningFiltersQuery(); // Initialize selected items for OrgUnit MultiSelect based on existing filters const [selectedOrgUnits, setSelectedOrgUnits] = useState([]); const [selectedCategories, setSelectedCategories] = useState([]); - const [dateTypeValue, setDateTypeValue] = useState(null); - const [dateTypeItem, setDateTypeItem] = useState(null); const autoCompleteRef = useRef(null); const [dateRange, setDateRange] = useState([]); @@ -48,7 +41,6 @@ const AdvancedSearchDropdown: React.FC = () => { } useEffect(() => { - //console.log("Use Effect in child is being called.", filters); // Split filters.orgUnit into array and format as needed for selectedItems if (filters.orgUnit) { const orgUnitsArray = filters.orgUnit.map((orgUnit: string) => ({ @@ -61,27 +53,16 @@ const AdvancedSearchDropdown: React.FC = () => { } // Split filters.category into array and format as needed for selectedItems if (filters.category) { - const categoriesArray = filters.category.map((category: string) => ({ - text: data?.categories?.find((item: any) => item.code === category)?.description || category, - value: category - })); - setSelectedCategories(categoriesArray); - } else { - setSelectedCategories([]); - } + const categoriesArray = filters.category.map((category: string) => ({ + text: data?.categories?.find((item: any) => item.code === category)?.description || category, + value: category + })); + setSelectedCategories(categoriesArray); + } else{ + setSelectedCategories([]); + } }, [filters.orgUnit, filters.category]); - const clearDates = () => { - handleFilterChange({ - startDate: null, - endDate: null, - dateType: "" - }); - setDateTypeValue(null); - setDateTypeItem(null); - setFilters({ ...filters, startDate: null, endDate: null, dateType: "" }); - }; - useEffect(() => { // In here, we're defining the function that will be called when the user clicks on the "Clear" button // The idea is to keep the autocomplete component clear of any ties to the opening search context @@ -96,6 +77,7 @@ const AdvancedSearchDropdown: React.FC = () => { },[]); const handleFilterChange = (updatedFilters: Partial) => { + setFilters({ ...filters, ...updatedFilters }); }; @@ -125,7 +107,7 @@ const AdvancedSearchDropdown: React.FC = () => { handleFilterChange({ [group]: updatedGroup }); }; - + if (isLoading) { return ; } @@ -138,6 +120,28 @@ const AdvancedSearchDropdown: React.FC = () => { ); } + const onDateTypeChange = ({ selectedItem }: { selectedItem: { value: string } | null }) => { + dateRange && setDateRange([]); + handleFilterChange({ dateType: selectedItem?.value, startDate: undefined, endDate: undefined }); + } + + const categoryItems = + data.categories?.map((item: any) => ({ + text: item.description, + value: item.code + })) || []; + + const orgUnitItems = + data.orgUnits?.map((item: any) => ({ + text: item.orgUnitName, + value: item.orgUnitCode + })) || []; + + const dateTypeItems = + data.dateTypes?.map((item: any) => ({ + text: item.label, + value: item.value + })) || []; return (
@@ -264,14 +268,12 @@ const AdvancedSearchDropdown: React.FC = () => { max={5} className="date-type-col mt-sm-2 mt-lg-0" > - (item ? item.text : "")} - onChange={(e: any) => - handleFilterChange({ dateType: e.selectedItem.value }) - } + onChange={onDateTypeChange} selectedItem={ filters.dateType ? dateTypeItems.find( From 24aed3b99d053593885a58b0bc1c078a5f6842d0 Mon Sep 17 00:00:00 2001 From: Greg Pascucci Date: Mon, 6 Jan 2025 12:19:58 -0800 Subject: [PATCH 31/31] removed extra clear filters line --- frontend/src/contexts/search/OpeningsSearch.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/frontend/src/contexts/search/OpeningsSearch.tsx b/frontend/src/contexts/search/OpeningsSearch.tsx index 1af13a5b..b5cb1e2e 100644 --- a/frontend/src/contexts/search/OpeningsSearch.tsx +++ b/frontend/src/contexts/search/OpeningsSearch.tsx @@ -35,9 +35,6 @@ export const OpeningsSearchProvider: React.FC<{ children: ReactNode }> = ({ chil openingFiltersKeys.forEach((key) => { individualClearFieldFunctions[key] && individualClearFieldFunctions[key](); }); - - setFilters(defaultFilters); - }; return (