diff --git a/backend/startup.sh b/backend/startup.sh index bce161f3a..a8f5c27c5 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 d85fd7a3f..41ac1eea7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -48,13 +48,14 @@ 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 working_dir: /app environment: - DATABASE_HOST: nrcdb03.bcgov + DATABASE_HOST: ${DATABASE_HOST} #nrcdb03.bcgov DATABASE_PORT: "1543" DATABASE_USER: ${DATABASE_USER} DATABASE_PASSWORD: ${DATABASE_PASSWORD} @@ -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 @@ -74,7 +75,7 @@ services: volumes: ["/pgdata"] ports: ["5432:5432"] healthcheck: - test: pg_isready -U postgres + test: pg_isready -U nr-silva interval: 5s timeout: 5s retries: 5 @@ -90,7 +91,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 diff --git a/frontend/src/components/AutocompleteClientLocation/index.tsx b/frontend/src/components/AutocompleteClientLocation/index.tsx index 205b338a1..134bdde41 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 } @@ -42,17 +42,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") { diff --git a/frontend/src/components/OpeningsSearchTable/index.tsx b/frontend/src/components/OpeningsSearchTable/index.tsx index e066896c2..fc3616ff4 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 15e8ef866..524662697 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/AdvancedSearchDropdown.scss @@ -3,97 +3,152 @@ @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; - } - input{ - background-color: var(--bx-field-01); - border-bottom: 1px solid var(--bx-border-strong-01); - } - .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; + box-shadow: 0px 2px 6px 0px #0000004D; -} + .autoClientLocation { + padding-left: 10px; + padding-right: 0px; + } -.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: 12px; + line-height: 16px; + letter-spacing: 0.16px; + color: var(--bx-text-primary); + white-space: nowrap; + } -.date-type-col{ - padding: 0px; - padding-left: 16px; -} -.date-selectors-col{ - padding-left: 0px; -} + label { + font-size: 12px; + line-height: 16px; + letter-spacing: 0.16px; + white-space: nowrap; + color: var(--#{vars.$bcgov-prefix}-text-primary); + } + + .bx--label--disabled { + color: var(--#{vars.$bcgov-prefix}-text-secondary); + } + + .bx--text-input { + color: var(--#{vars.$bcgov-prefix}-text-secondary); + } + + .bx--row { + padding: 10px; + } + + .bx--col-md-3 { + padding-right: 10px; + } + + .orgUnitCol { + padding-right: 2rem; + } + + .locationCodeCombo { + width: 96% + } + + .timeberMarkCol { + padding-right: 2rem; + } + + .cutBlock { + padding-top: 12px; + } + + .cuttingPermit { + padding-top: 12px; + } + + .clientLocationCol { + padding-right: 2rem; + } + + 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: 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); + } -@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: 60.66%; - } - .date-selectors-col{ - padding: 0px; - } - } - /* Extra Max - Up to 1784px */ - @media only screen and (min-width: 1784px) { - .advanced-search-dropdown { - width: 70.66%; - } + .bx--date-picker--range .bx--date-picker-container, + .bx--date-picker--range .bx--date-picker__input { + width: 95% } + .bx--date-picker__input[readonly] { + width: 95%; + } +} + +// @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 ecdf66c01..c6b8608d2 100644 --- a/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx +++ b/frontend/src/components/SilvicultureSearch/Openings/AdvancedSearchDropdown/index.tsx @@ -11,7 +11,7 @@ import { Row, Column, FilterableMultiSelect -} from "@carbon/react"; +, ComboBox } from "@carbon/react"; import "./AdvancedSearchDropdown.scss"; import { useOpeningFiltersQuery } from "../../../../services/queries/search/openingQueries"; import { useOpeningsSearch } from "../../../../contexts/search/OpeningsSearch"; @@ -45,7 +45,7 @@ const AdvancedSearchDropdown: React.FC = () => { if (filters.orgUnit) { const orgUnitsArray = filters.orgUnit.map((orgUnit: string) => ({ text: data?.orgUnits?.find((item: any) => item.orgUnitCode === orgUnit)?.orgUnitName || orgUnit, - value: orgUnit, + value: orgUnit })); setSelectedOrgUnits(orgUnitsArray); } else { @@ -55,7 +55,7 @@ const AdvancedSearchDropdown: React.FC = () => { if (filters.category) { const categoriesArray = filters.category.map((category: string) => ({ text: data?.categories?.find((item: any) => item.code === category)?.description || category, - value: category, + value: category })); setSelectedCategories(categoriesArray); } else{ @@ -77,6 +77,7 @@ const AdvancedSearchDropdown: React.FC = () => { },[]); const handleFilterChange = (updatedFilters: Partial) => { + setFilters({ ...filters, ...updatedFilters }); }; @@ -119,22 +120,27 @@ 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, + value: item.code })) || []; const orgUnitItems = data.orgUnits?.map((item: any) => ({ text: item.orgUnitName, - value: item.orgUnitCode, + value: item.orgUnitCode })) || []; const dateTypeItems = data.dateTypes?.map((item: any) => ({ text: item.label, - value: item.value, + value: item.value })) || []; return ( @@ -262,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( @@ -384,4 +388,4 @@ const AdvancedSearchDropdown: React.FC = () => { ); }; -export default AdvancedSearchDropdown; +export default AdvancedSearchDropdown; \ No newline at end of file diff --git a/frontend/src/components/SilvicultureSearch/Openings/SearchFilterBar/index.tsx b/frontend/src/components/SilvicultureSearch/Openings/SearchFilterBar/index.tsx index 040385395..ae260974f 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, clearIndividualField } = useOpeningsSearch(); + const { filters, clearFilters, clearIndividualField} = useOpeningsSearch(); useEffect(() => { setActiveFilters(getActiveFilters(filters)); diff --git a/frontend/src/contexts/search/OpeningsSearch.tsx b/frontend/src/contexts/search/OpeningsSearch.tsx index 2a244d940..b5cb1e2e0 100644 --- a/frontend/src/contexts/search/OpeningsSearch.tsx +++ b/frontend/src/contexts/search/OpeningsSearch.tsx @@ -35,7 +35,6 @@ export const OpeningsSearchProvider: React.FC<{ children: ReactNode }> = ({ chil openingFiltersKeys.forEach((key) => { individualClearFieldFunctions[key] && individualClearFieldFunctions[key](); }); - }; return ( @@ -52,4 +51,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 ee654df5a..875984a98 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -53,7 +53,7 @@ if (container) { - +