From bc41924c85cd2d1671eb18b557b1e426995bf269 Mon Sep 17 00:00:00 2001 From: rdbsolutions Date: Thu, 7 Apr 2022 11:47:25 +0100 Subject: [PATCH] build fix and updated myportal layout --- .env.local | 3 + actions/govgateway.js | 26 +- actions/index.js | 18 + actions/selectQueryTypes.js | 2 +- components/breadcrumbs.js | 58 ++++ components/case/summaryTypes/pinswg_dnsid.js | 49 ++- components/dnssearchresults.js | 5 +- components/mapping/index.js | 43 +++ components/mapping/osm.js | 38 +++ components/myportal.js | 11 +- components/myportal/awaitingsubmission.js | 2 +- components/myportal/dns.js | 56 ++++ components/myportal/makenewappeal.js | 2 +- components/myportal/mycases.js | 2 +- components/myportal/myrepresentations.js | 2 +- components/myportal/searchcases.js | 2 +- components/myportal/topthree.js | 14 +- components/myportal/uploadFile.js | 313 ++++++++++++++++++ components/myportal/viewall.js | 4 +- components/myportal/watchedcases.js | 2 +- components/myportal/youraccount.js | 3 +- components/search/dnssearchresults.js | 307 ++++++++++++++++- i18n.js | 10 +- package.json | 9 +- pages/_document.js | 2 +- .../api/endpoint/getbasicdnsurlsearch_api.js | 2 +- pages/api/endpoint/getdnscoords_api.js | 41 +++ pages/dnsapplications.js | 5 +- pages/myportal/dnsapplications.js | 215 ++++++++++++ pages/myportal/dnsdetails.js | 91 +++++ pages/myportal/index.js | 1 + store/searchOutput/action.js | 8 + store/searchOutput/reducer.js | 6 + styles/sass/patterns/_card.scss | 10 +- styles/sass/welshgov/_application.scss | 4 + 35 files changed, 1308 insertions(+), 58 deletions(-) create mode 100644 components/mapping/index.js create mode 100644 components/mapping/osm.js create mode 100644 components/myportal/dns.js create mode 100644 components/myportal/uploadFile.js create mode 100644 pages/api/endpoint/getdnscoords_api.js create mode 100644 pages/myportal/dnsapplications.js create mode 100644 pages/myportal/dnsdetails.js diff --git a/.env.local b/.env.local index 4e0c3f45..7c6dfc02 100644 --- a/.env.local +++ b/.env.local @@ -47,6 +47,8 @@ RELAYPATH = "dev-pedw-hc" GOOGLE_TAG_MANAGER = GTM-T78CBC3 SHOWLOGIN = "true" SHOWREPRESENTATIONS = false +SHOWFILEUPLOAD = "false" +SHOWMAPS = "true" //BASIC_AUTH_CREDENTIALS = pinswg:password|pinswg2:password2 @@ -72,3 +74,4 @@ NEXT_PUBLIC_GG_REDIRECT_URI = "http://localhost:3000" API_ROOT = "http://localhost:3000" +GOOGLE_MAP_API_KEY = AIzaSyCzeVrHt544bp_72YCFkw21eDsmI2JEsQo \ No newline at end of file diff --git a/actions/govgateway.js b/actions/govgateway.js index 034f90a5..cf03784f 100644 --- a/actions/govgateway.js +++ b/actions/govgateway.js @@ -8,6 +8,19 @@ const WEBAPI_URL = process.env.RELAY_ROOT || "https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/"; +const azureHeaders = (access_token) => { + return { + headers: { + "OData-MaxVersion": "4.0", + "OData-Version": "4.0", + "Accept": "application/json;odata.metadata=none", + "Prefer": 'odata.include-annotations="*",return=representation', + "Content-Type": "application/json", + "Authorization": "Bearer " + access_token, + }, + }; +}; + export const getProviderConfig = () => { return axios .get(configEndpoint) @@ -78,19 +91,6 @@ export const getPortalLogin = (emailAddress, token) => { }); }; -const azureHeaders = (access_token) => { - return { - headers: { - "OData-MaxVersion": "4.0", - "OData-Version": "4.0", - "Accept": "application/json;odata.metadata=none", - "Prefer": 'odata.include-annotations="*",return=representation', - "Content-Type": "application/json", - "Authorization": "Bearer " + access_token, - }, - }; -}; - var Base64 = { _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", diff --git a/actions/index.js b/actions/index.js index 39f2bff3..8d110ab1 100644 --- a/actions/index.js +++ b/actions/index.js @@ -190,6 +190,24 @@ export const getBasicSearchPaged = ( }); }; +export const getDNSCoords = () => { + return axios + .get(BASE_URL + "/api/endpoint/getdnscoords_api") + .then((res) => { + //console.log(res.data); + return res.data; + }) + .catch((error) => { + let ErrResponse = { + value: [], + errorCode: error.response.status, + errorMsg: error.response.statusText, + }; + + return ErrResponse; + }); +}; + export const getDNSList = (searchString) => { return axios .get(BASE_URL + "/api/endpoint/getdnslist_api") diff --git a/actions/selectQueryTypes.js b/actions/selectQueryTypes.js index 20cd6641..bd5d87bd 100644 --- a/actions/selectQueryTypes.js +++ b/actions/selectQueryTypes.js @@ -19,7 +19,7 @@ export const getSelectQuery = (appealTypeName) => { case "pinswg_compulsorypurchaseorderses": return "&$select=_pinswg_appellant_value,pinswg_name,pinswg_siteaddresscounty,pinswg_siteaddressline1,pinswg_siteaddressline2,pinswg_siteaddresspostcode,pinswg_siteaddresstown,pinswg_casedecisiondate,pinswg_dateeventrequested,pinswg_decision,pinswg_finalcommentsduedate,pinswg_otherpartiesstatement,pinswg_procedure,pinswg_proofsofevidencewrittenstatementsofeviden,pinswg_questionnaireduedate,pinswg_relevantauthorityname,pinswg_startdate,statuscode"; case "pinswg_dnses": - return "&$select=_pinswg_appellant_value,pinswg_name,pinswg_addressline1,pinswg_addressline2,pinswg_postcode,pinswg_addresstown,_pinswg_associatedlpa_value,pinswg_addresscounty,pinswg_applicationacceptedasvalid,pinswg_applicationrejectedasinvalid,pinswg_choiceofprocedure,pinswg_confirmrequesttovaryapplication,pinswg_dateeventrequested,pinswg_dateofdecision,pinswg_dateofrequesttovarytheapplication,pinswg_dateofsubmissionofapplication,pinswg_dateprojectpublishedonwebsite,pinswg_deadlineforsubmissionofapplication,pinswg_decision,pinswg_endofrepresentationperiod,pinswg_inspectorreportsubmittedtowelshgovernment,pinswg_procedureconfirmed,pinswg_projectdescription,pinswg_projectlocation,pinswg_recommendation,pinswg_rejectrequesttovaryapplication,pinswg_reportdueby,pinswg_suspensiondates,pinswg_suspensionenddates,pinswg_suspensionstartdates,pinswg_validnoticeofintentiontosubmitanapplicati,pinswg_webaddress,pinswg_withdrawndate,pinswg_writtenacceptanceofnotification,statuscode,pinswg_casestage"; + return "&$select=pinswg_anticipatedgridreferenceeastingtext,pinswg_anticipatedgridreferencenorthingtext,_pinswg_appellant_value,pinswg_name,pinswg_addressline1,pinswg_addressline2,pinswg_postcode,pinswg_addresstown,_pinswg_associatedlpa_value,pinswg_addresscounty,pinswg_applicationacceptedasvalid,pinswg_applicationrejectedasinvalid,pinswg_choiceofprocedure,pinswg_confirmrequesttovaryapplication,pinswg_dateeventrequested,pinswg_dateofdecision,pinswg_dateofrequesttovarytheapplication,pinswg_dateofsubmissionofapplication,pinswg_dateprojectpublishedonwebsite,pinswg_deadlineforsubmissionofapplication,pinswg_decision,pinswg_endofrepresentationperiod,pinswg_inspectorreportsubmittedtowelshgovernment,pinswg_procedureconfirmed,pinswg_projectdescription,pinswg_projectlocation,pinswg_recommendation,pinswg_rejectrequesttovaryapplication,pinswg_reportdueby,pinswg_suspensiondates,pinswg_suspensionenddates,pinswg_suspensionstartdates,pinswg_validnoticeofintentiontosubmitanapplicati,pinswg_webaddress,pinswg_withdrawndate,pinswg_writtenacceptanceofnotification,statuscode,pinswg_casestage"; case "pinswg_electricityacts": return "&$select=_pinswg_appellant_value,pinswg_name,pinswg_addressline1,pinswg_addressline2,pinswg_postcode,pinswg_addresstown,_pinswg_associatedlpa_value,pinswg_applicationacceptedasvalid,pinswg_applicationrejectedasinvalid,pinswg_confirmrequesttovaryapplication,pinswg_dateeventrequested,pinswg_dateofrequesttovarytheapplication,pinswg_dateofsubmissionofapplication,pinswg_dateprojectpublishedonwebsite,pinswg_deadlineforsubmissionofapplication,pinswg_decision,pinswg_endofrepresentationperiod,pinswg_inspectorreportsubmittedtowelshgovernment,pinswg_procedureconfirmed,pinswg_projectlocation,pinswg_recommendation,pinswg_rejectrequesttovaryapplication,pinswg_reportdueby,pinswg_suspensiondates,pinswg_validnoticeofintentiontosubmitanapplicati,pinswg_webaddress,pinswg_withdrawndate,pinswg_writtenacceptanceofnotification,statuscode"; case "pinswg_householderappealhases": diff --git a/components/breadcrumbs.js b/components/breadcrumbs.js index 0e9982db..b381e99d 100644 --- a/components/breadcrumbs.js +++ b/components/breadcrumbs.js @@ -395,6 +395,64 @@ const Breadcrumbs = (props) => { ) : ( "" )} + + {router.pathname == "/myportal/dnsapplications" ? ( + <> + {" "} +
  • + + + {t("common:breadcrumb-my-portal")} + + +
  • +
  • + {t("dnsCommon:service-name")} +
  • + + ) : ( + "" + )} + {router.pathname == "/myportal/dnsdetails" ? ( + <> +
  • + + + {t("common:breadcrumb-my-portal")} + + +
  • +
  • + + + {t("dnsCommon:service-name")} + + +
  • +
  • + {t("common:breadcrumb-case-reference")}:{" "} + { + props.props.currentView.caseReference + .currentReference + } +
  • + + ) : ( + "" + )} + {router.pathname == "/case" ? ( <>
  • diff --git a/components/case/summaryTypes/pinswg_dnsid.js b/components/case/summaryTypes/pinswg_dnsid.js index 0855bf51..530f418b 100644 --- a/components/case/summaryTypes/pinswg_dnsid.js +++ b/components/case/summaryTypes/pinswg_dnsid.js @@ -1,21 +1,50 @@ import { useRouter } from "next/router"; +import Head from "next/head"; +import { useEffect, useRef, ReactElement } from "react"; + import useTranslation from "next-translate/useTranslation"; import jsonpath from "jsonpath"; -import _ from "lodash"; +import _, { round } from "lodash"; import transLookup from "../../../data/lookuptranslations.json"; +import GoogleMapComponent from "../../mapping/"; + +import OSPoint from "ospoint"; + const Pinswg_dnsid = (props) => { let { t } = useTranslation(); const { casesObj, detailsObj, formatDates, linkedCasesList } = props; const router = useRouter(); const { locale } = router; + const point = {}; + const siteCoords = {}; + let center = {}; + + point = new OSPoint( + detailsObj.pinswg_anticipatedgridreferencenorthingtext, + detailsObj.pinswg_anticipatedgridreferenceeastingtext + ); + siteCoords = point.toOSGB36(); + //console.log(siteCoords); + center = { + id: "", + lat: isNaN(parseFloat(siteCoords.latitude)) + ? 52.412272 + : parseFloat(siteCoords.latitude), + lng: isNaN(parseFloat(siteCoords.longitude)) + ? -3.437989 + : parseFloat(siteCoords.longitude), + }; + + const zoom = isNaN(parseFloat(siteCoords.latitude)) ? 7 : 12; + return ( <> {detailsObj.pinswg_projectdescription != null ? (
    -
    +

    {t("case:summary-project-details-label")}

    @@ -51,6 +80,22 @@ const Pinswg_dnsid = (props) => { : ""}

    */}
    + {/* {process.env.SHOWMAPS == "true" && ( */} +
    +
    + + {/* */} +
    +
    + {/* )} */}
    ) : ( diff --git a/components/dnssearchresults.js b/components/dnssearchresults.js index d75c3b3b..4b4f1943 100644 --- a/components/dnssearchresults.js +++ b/components/dnssearchresults.js @@ -7,7 +7,7 @@ import DNSSearchResults from "./search/dnssearchresults"; import CRMError from "./crmError"; export default function Search(props) { - const { searchString, searchResultsObj } = props; + const { searchString, searchResultsObj, myportal, watchedCases } = props; let { t } = useTranslation(); const router = useRouter(); @@ -39,6 +39,9 @@ export default function Search(props) { searchDetailsObj={ searchResultsObj.searchDetailsObj } + dnsCoords={searchResultsObj.dnsCoordsObj.value} + myportal={myportal} + watchedCases={watchedCases} />
    diff --git a/components/mapping/index.js b/components/mapping/index.js new file mode 100644 index 00000000..c218594d --- /dev/null +++ b/components/mapping/index.js @@ -0,0 +1,43 @@ +import GoogleMapReact from "google-map-react"; +const GoogleMapComponent = (props) => { + const { center, zoom } = props; + + let data = [center]; + + const ModelsMap = (map, maps) => { + //instantiate array that will hold your Json Data + let dataArray = []; + //push your Json Data in the array + { + data.map((markerJson) => dataArray.push(markerJson)); + } + + //Loop through the dataArray to create a marker per data using the coordinates in the json + for (let i = 0; i < dataArray.length; i++) { + let marker = new maps.Marker({ + position: { lat: dataArray[i].lat, lng: dataArray[i].lng }, + map, + label: dataArray[i].id, + }); + } + }; + return ( + ModelsMap(map, maps)} + > + ); +}; + +export default GoogleMapComponent; diff --git a/components/mapping/osm.js b/components/mapping/osm.js new file mode 100644 index 00000000..f06cda02 --- /dev/null +++ b/components/mapping/osm.js @@ -0,0 +1,38 @@ +import L from "leaflet"; +import { useRef, useMemo } from "react"; +import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet"; + +const OSMapComponent = (props) => { + const { center, zoom } = props; + const markerRef = useRef(null); + let data = [center]; + + // const ModelsMap = (map, maps) => { + // //instantiate array that will hold your Json Data + // let dataArray = []; + // //push your Json Data in the array + // { + // data.map((markerJson) => dataArray.push(markerJson)); + // } + + // //Loop through the dataArray to create a marker per data using the coordinates in the json + // for (let i = 0; i < dataArray.length; i++) { + // let marker = new maps.Marker({ + // position: { lat: dataArray[i].lat, lng: dataArray[i].lng }, + // map, + // label: dataArray[i].id, + // }); + // } + // }; + + return ( + + + + + hello + + + ); +}; +export default OSMapComponent; diff --git a/components/myportal.js b/components/myportal.js index 3dc240d4..0d919ee4 100644 --- a/components/myportal.js +++ b/components/myportal.js @@ -10,14 +10,17 @@ import MyRepresentations from "./myportal/myrepresentations"; import WatchedCases from "./myportal/watchedcases"; import YourAccount from "./myportal/youraccount"; import { parseCookies, setCookie, destroyCookie } from "nookies"; +import Dns from "./myportal/dns"; import IdleTimer from "react-idle-timer"; import TimeoutModal from "./timeout/timeoutmodal"; import { useState } from "react"; import TimeOut from "../components/timeout"; +import UploadFile from "./myportal/uploadFile"; const MyPortal = (props) => { + const { showFileUpload } = props; let { t } = useTranslation(); const router = useRouter(); @@ -110,18 +113,18 @@ const MyPortal = (props) => {
    - + + - -
    -
    + + {showFileUpload == "true" && }
    diff --git a/components/myportal/awaitingsubmission.js b/components/myportal/awaitingsubmission.js index 5c8351d4..88bff7e7 100644 --- a/components/myportal/awaitingsubmission.js +++ b/components/myportal/awaitingsubmission.js @@ -13,7 +13,7 @@ const AwaitingSubmission = (props) => { const { setCurrentView } = props; return ( -
    +

    {t("myportal:awatitingsubmission-card-title")} diff --git a/components/myportal/dns.js b/components/myportal/dns.js new file mode 100644 index 00000000..238490bf --- /dev/null +++ b/components/myportal/dns.js @@ -0,0 +1,56 @@ +import Link from "next/link"; +import { useState } from "react"; +import { useRouter } from "next/router"; +import useTranslation from "next-translate/useTranslation"; +import LoadingOverlay from "react-loading-overlay"; + +export default function Dns() { + let { t } = useTranslation(); + //const [showSpinnerState, setShowSpinnerState] = useState(false); + + const router = useRouter(); + const { locale } = router; + + // let spinnerState = () => { + // showSpinnerState == true + // ? setShowSpinnerState(false) + // : setShowSpinnerState(true); + // }; + return ( +
    +
    +

    + {t("home:dns-card-title")} +

    +
    +

    + {t("home:dns-card-paragraph")} +

    +
    + +
    + {/* */} +
    + ); +} diff --git a/components/myportal/makenewappeal.js b/components/myportal/makenewappeal.js index 74733e48..ad42d108 100644 --- a/components/myportal/makenewappeal.js +++ b/components/myportal/makenewappeal.js @@ -8,7 +8,7 @@ export default function MakeNewAppeal() { const router = useRouter(); const { locale } = router; return ( -
    +

    {t("myportal:makenewappeal-card-title")} diff --git a/components/myportal/mycases.js b/components/myportal/mycases.js index fc135af5..1b1ab822 100644 --- a/components/myportal/mycases.js +++ b/components/myportal/mycases.js @@ -12,7 +12,7 @@ const MyCases = (props) => { const { locale } = router; const { setCurrentView } = props; return ( -
    +

    {t("myportal:mycases-card-title")} diff --git a/components/myportal/myrepresentations.js b/components/myportal/myrepresentations.js index a513b38e..a4db29a8 100644 --- a/components/myportal/myrepresentations.js +++ b/components/myportal/myrepresentations.js @@ -13,7 +13,7 @@ const MyRepresentations = (props) => { const { setCurrentView } = props; return ( -
    +

    {t("myportal:myrepresentations-card-title")} diff --git a/components/myportal/searchcases.js b/components/myportal/searchcases.js index 941b27b1..552d756a 100644 --- a/components/myportal/searchcases.js +++ b/components/myportal/searchcases.js @@ -98,7 +98,7 @@ let CaseSearch = (props) => { return ( <> -
    +

    diff --git a/components/myportal/topthree.js b/components/myportal/topthree.js index 95c6ac98..6787d384 100644 --- a/components/myportal/topthree.js +++ b/components/myportal/topthree.js @@ -212,11 +212,17 @@ const TopThree = (props) => { ]} - {topThreeType == "awaitingSubmission" && - showTopThreeArr[key][ - "pinswg_appealcasetype@OData.Community.Display.V1.FormattedValue" - ]}

    + {(topThreeType == "awaitingSubmission" || + topThreeType == "watchedCases") && ( +
    + { + showTopThreeArr[key][ + "pinswg_appealcasetype@OData.Community.Display.V1.FormattedValue" + ] + } +
    + )} {topThreeType != "awaitingSubmission" ? (
    {t("myportal:case-address")}:{" "} diff --git a/components/myportal/uploadFile.js b/components/myportal/uploadFile.js new file mode 100644 index 00000000..a9901467 --- /dev/null +++ b/components/myportal/uploadFile.js @@ -0,0 +1,313 @@ +import Link from "next/link"; +import { useState, useMemo } from "react"; +import { useRouter } from "next/router"; +import useTranslation from "next-translate/useTranslation"; +import LoadingOverlay from "react-loading-overlay"; +import DropzoneComponent from "../newappeal/fileupload"; +import { Field, reduxForm } from "redux-form"; +import { connect } from "react-redux"; +import Dropzone, { useDropzone } from "react-dropzone"; +import { uploadFiles } from "../../actions"; + +const required = (errorMsg) => (value) => + value || typeof value === "number" ? undefined : errorMsg; + +export const minLength = (errorMsg) => (value) => + value && value.length < 4 + ? errorMsg //`Must be ${min} characters or more` + : undefined; + +const RenderTextfield = ({ + id, + className, + rows, + datafieldname, + name, + label, + input, + hint1, + hint2, + hint3, + meta: { touched, error }, + ...custom +}) => { + return ( + <> +
    +
    + +
    + +
    + + {touched && error && ( + + + Error: + {" "} + {error} + + )} +
    +
    + + ); +}; + +const baseStyle = { + display: "flex", + flexDirection: "column", + alignItems: "center", + padding: "20px", + borderWidth: 2, + borderRadius: 2, + borderColor: "#eeeeee", + borderStyle: "dashed", + backgroundColor: "#fafafa", + color: "#bdbdbd", + transition: "border .3s ease-in-out", + width: "80%", + margin: "20px auto 30px", +}; + +const activeStyle = { + borderColor: "#2196f3", +}; + +const acceptStyle = { + borderColor: "#00e676", +}; + +const rejectStyle = { + borderColor: "#ff1744", +}; +const RenderFileUpload = (field) => { + const files = field.input.value; + const style = useMemo( + () => ({ + ...baseStyle, + // ...(isDragActive ? activeStyle : {}), + // ...(isDragAccept ? acceptStyle : {}), + // ...(isDragReject ? rejectStyle : {}), + }), + [] + // [isDragActive, isDragReject, isDragAccept] + ); + const [filesList, setFilesList] = useState([]); + + const thumbs = filesList.map((file) => ( +
    + {file.name} -{" "} + + {file.name} ({file.size / 1024}kb) + +
    + )); + + function bytesToSize(bytes) { + var sizes = ["Bytes", "KB", "MB", "GB", "TB"]; + if (bytes == 0) return "0 Byte"; + var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))); + return Math.round(bytes / Math.pow(1024, i), 2) + " " + sizes[i]; + } + + const getThumbnailIcon = (fileObj, fileType) => { + switch (fileType) { + case "text/html": + return "/assets/images/documentTypes/html.png"; + break; + case "text/plain": + return "/assets/images/documentTypes/txt.png"; + break; + case "application/msword": + return "/assets/images/documentTypes/doc.png"; + break; + case "application/pdf": + return "/assets/images/documentTypes/pdf.png"; + break; + case "application/vnd.openxmlformats-officedocument.wordprocessingml.document": + return "/assets/images/documentTypes/docx.png"; + break; + case "text/csv": + return "/assets/images/documentTypes/csv.png"; + break; + case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": + return "/assets/images/documentTypes/xlsx.png"; + break; + + case "application/zip": + return "/assets/images/documentTypes/zip.png"; + break; + case "image/jpeg": + case "image/png": + return URL.createObjectURL(fileObj); + break; + } + }; + return ( +
    + + field.input.onChange(filesToUpload) + } + > + {({ getRootProps, getInputProps }) => ( +
    +
    +
    +
    + {" "} + +
    Drag and drop your files here.
    +
    + +
    +
    + )} +
    + + {field.meta.touched && field.meta.error && ( + {field.meta.error} + )} + {files && Array.isArray(files) && ( +
      + {files.map((file, i) => ( +
      + {file.name}{" "} + {" "} + + {file.name} ({bytesToSize(file.size)}) + +
      + ))} +
    + )} +
    + ); +}; + +let UploadFile = (props) => { + let { t } = useTranslation(); + //const [showSpinnerState, setShowSpinnerState] = useState(false); + const { handleSubmit, pristine, reset, submitting } = props; + + const router = useRouter(); + const { locale } = router; + + const onHandleSubmit = async (values) => { + //spinnerState(); + console.log(values); + + const uploadAction = await uploadFiles(values); + // router.push({ + // pathname: + // router.locale == "cy" + // ? "/fymhorth/canlyniadauchwilio" + // : "/myportal/searchresults", + // query: { q: values.basicSearch }, + // shallow: true, + // }); + }; + + return ( +
    +
    +

    Upload a file

    +
    +

    reqweqwe eqwe qwe qwe qwe

    +
    + +
    + +
    +
    + +
    +
    + +
    + +
    +
    + ); +}; + +const mapStateToProps = (state) => { + return { + currentView: state.currentView, + search: state.search, + searchResultsObj: state.searchResultsObj, + formData: state.formData, + appealType: state.appealType, + //form: state.form, + myCases: state.myCases, + watchedCases: state.watchedCases, + myRepresentations: state.myRepresentations, + awaitingSubmission: state.awaitingSubmission, + }; +}; + +const mapDispatchToProps = (dispatch) => { + return {}; +}; + +export default connect( + mapStateToProps, + mapDispatchToProps +)( + reduxForm({ + form: "uploadFileForm", + destroyOnUnmount: false, + })(UploadFile) +); diff --git a/components/myportal/viewall.js b/components/myportal/viewall.js index f3b50d4a..49b4cd58 100644 --- a/components/myportal/viewall.js +++ b/components/myportal/viewall.js @@ -121,7 +121,7 @@ const ViewAllResults = (props) => { {t("search:searchresults-site-address-label")}: - {getFormCollectionByID(appealTypeID).PrimaryIdAttribute == + {/* {getFormCollectionByID(appealTypeID).PrimaryIdAttribute == "pinswg_dnsid" ? detailsObj.pinswg_projectlocation != null ? detailsObj.pinswg_projectlocation.indexOf(";") < 0 @@ -134,7 +134,7 @@ const ViewAllResults = (props) => { ";" )[0] : "" - : ""} + : ""} */} {_.has(detailsObj, "pinswg_siteaddressline1") ? detailsObj.pinswg_siteaddressline1 : ""} diff --git a/components/myportal/watchedcases.js b/components/myportal/watchedcases.js index d02ea7c1..617ba86f 100644 --- a/components/myportal/watchedcases.js +++ b/components/myportal/watchedcases.js @@ -13,7 +13,7 @@ const WatchedCases = (props) => { const { setCurrentView } = props; return ( -
    +

    {t("myportal:watchedcases-card-title")} diff --git a/components/myportal/youraccount.js b/components/myportal/youraccount.js index afab86bc..4c933c42 100644 --- a/components/myportal/youraccount.js +++ b/components/myportal/youraccount.js @@ -26,8 +26,7 @@ export default function YourAccount() {

    -
    -
    +

    {t("myportal:changepassword-card-title")} diff --git a/components/search/dnssearchresults.js b/components/search/dnssearchresults.js index 3a7ad521..e9f3c952 100644 --- a/components/search/dnssearchresults.js +++ b/components/search/dnssearchresults.js @@ -18,12 +18,25 @@ import { setSearchResults, setSearchDetails, } from "../../store/searchOutput/action"; -import { getSearchDetailsPaged } from "../utils"; +import { getSearchDetailsPaged, getFormCollectionByID } from "../utils"; import { currentViewActionTypes, setCurrentReference, setCurrentPage, } from "../../store/currentView/action"; +import GoogleMapReact from "google-map-react"; +import { parseCookies, setCookie, destroyCookie } from "nookies"; +import { + setWatchedCases, + setWatchedCasesDetails, +} from "../../store/watchedCases/action"; +import { + createWatchedCases, + getWatchedCasesProxy, + getPortalModuleDetailsProxy, + deleteWatchedCases, +} from "../../actions"; +import OSPoint from "ospoint"; const DNSSearchResults = (props) => { const { @@ -35,6 +48,11 @@ const DNSSearchResults = (props) => { setSearchDetails, advancedSearch, setCurrentPage, + dnsCoords, + myportal, + watchedCases, + setWatchedCases, + setWatchedCasesDetails, } = props; let { t } = useTranslation(); @@ -46,6 +64,82 @@ const DNSSearchResults = (props) => { const [searchLoaded, setSearchLoaded] = useState(false); const [showSpinnerState, setShowSpinnerState] = useState(false); + let dataArray = []; + //push your Json Data in the array + + dnsCoords.map((item) => { + let point = new OSPoint( + item.pinswg_anticipatedgridreferencenorthingtext, + item.pinswg_anticipatedgridreferenceeastingtext + ); + let siteCoords = point.toOSGB36(); + //console.log(siteCoords); + //console.log(item); + dataArray.push({ + appellant: + item[ + "_pinswg_appellant_value@OData.Community.Display.V1.FormattedValue" + ], + name: item.pinswg_projectname, + lat: parseFloat(siteCoords.latitude), + lng: parseFloat(siteCoords.longitude), + title: item.pinswg_name, + }); + }); + + //console.log(dataArray); + + const ModelsMap = (map, maps) => { + //instantiate array that will hold your Json Data + //console.log("here"); + var prev_infowindow = false; + //Loop through the dataArray to create a marker per data using the coordinates in the json + console.log(dataArray.length); + for (let i = 0; i < dataArray.length; i++) { + const infowindow = new google.maps.InfoWindow({ + content: + "
    " + + (_.isEmpty(dataArray[i].name) + ? "" + : dataArray[i].name.indexOf(";") > 0 + ? router.locale == "cy" + ? dataArray[i].name.split(";")[1] + : dataArray[i].name.split(";")[0] + : dataArray[i].name) + + "
    " + + (dataArray[i].appellant != null + ? "
    " + dataArray[i].appellant + "
    " + : "") + + "
    " + + dataArray[i].title + + "
    ", + }); + let marker = new maps.Marker({ + position: { lat: dataArray[i].lat, lng: dataArray[i].lng }, + title: _.isEmpty(dataArray[i].name) + ? "" + : dataArray[i].name.indexOf(";") > 0 + ? router.locale == "cy" + ? dataArray[i].name.split(";")[1] + : dataArray[i].name.split(";")[0] + : dataArray[i].name, + map, + }); + marker.addListener("click", () => { + if (prev_infowindow) { + prev_infowindow.close(); + } + + prev_infowindow = infowindow; + infowindow.open({ + anchor: marker, + map, + shouldFocus: true, + }); + }); + } + }; + let spinnerState = () => { showSpinnerState == true ? setShowSpinnerState(false) @@ -56,6 +150,83 @@ const DNSSearchResults = (props) => { const [fieldSortState, setfieldSortState] = useState("asc"); const [selectedOption, setSelectedOption] = useState(10); + const cookies = parseCookies(); + + const selectWatchedCase = (loggedInUser, incidentID, appealType) => { + let updateBody = { + "pinswg_WatchedCase@odata.bind": "/incidents(" + incidentID + ")", + "pinswg_Contact@odata.bind": "/contacts(" + loggedInUser + ")", + "pinswg_appealcasetype": +appealType, + }; + + createWatchedCases(updateBody) + .then((data) => data) + .then(() => { + getWatchedCasesProxy(cookies.pinsUser).then((data) => { + setWatchedCases(data), + getDetails(data, "myWatchedCases").then((data) => { + setWatchedCasesDetails(data); + }); + }); + }); + }; + + const isWatchedCase = (whichIncident) => { + let isWatched = jsonpath.query( + watchedCases, + "$..value[?(@._pinswg_watchedcase_value=='" + whichIncident + "')]" + ); + + return isWatched; + }; + + const deleteItem = (caseID, topThreeType) => { + let cookies = parseCookies(); + topThreeType == "watchedCases" && + deleteWatchedCases(caseID) + .then((data) => data) + .then(() => { + getWatchedCasesProxy(cookies.pinsUser).then((data) => { + setWatchedCases(data), + getDetails(data, "myWatchedCases").then((data) => { + setWatchedCasesDetails(data); + }); + }); + }); + }; + + const getDetails = (resultsObj, detailsType) => { + //console.log(resultsObj); + let detailsArr = []; + resultsObj = resultsObj.value; + const detailsObj = resultsObj.map((searchDetail, index) => { + if (searchDetail.pinswg_appealcasetype == null) { + console.log( + detailsType != "myWatchedCases" + ? searchDetail.ticketnumber + : searchDetail[ + "_pinswg_watchedcase_value@OData.Community.Display.V1.FormattedValue" + ] + ); + } else { + detailsArr.push( + getPortalModuleDetailsProxy( + getFormCollectionByID( + searchDetail.pinswg_appealcasetype + ).LogicalCollectionName, + detailsType != "myWatchedCases" + ? searchDetail.ticketnumber + : searchDetail[ + "_pinswg_watchedcase_value@OData.Community.Display.V1.FormattedValue" + ] + ) + ); + } + }); + //console.log(detailsArr); + return Promise.all(detailsArr); + }; + const ResultsView = (resultsArr) => { return (
    @@ -107,6 +278,9 @@ const DNSSearchResults = (props) => { {t("search:searchresults-status-label")} + {myportal == true && ( +
    + )}
    {showSpinnerState == true ? ( @@ -143,8 +317,14 @@ const DNSSearchResults = (props) => { { "statuscode@OData.Community.Display.V1.FormattedValue" ] || "N/A"} + {myportal == true && ( +
    + {isWatchedCase(item.incidentid) + .length > + 0 == + true ? ( + { + deleteItem( + isWatchedCase( + item.incidentid + )[0] + .pinswg_watchlistid, + + "watchedCases" + ); + alert( + "You have stopped watching case " + + item.title + ); + }} + title="Stop watching this case" + > + − + + ) : ( + { + selectWatchedCase( + cookies.pinsUser, + item.incidentid, + item.pinswg_appealcasetype + ); + alert( + "You are watching case " + + item.title + ); + }} + title="Watch this case" + > + + + + )} +
    + )}

    ); }) @@ -391,23 +618,65 @@ const DNSSearchResults = (props) => { return ( <>
    -
    -

    - {t("dnsApplications:page-title")} -

    -

    - {t("dnsApplications:page-intro-paragraph-1")} -

    -
      -
    • {t("dnsApplications:page-intro-list-item-1")}
    • +
      +
      +

      + {t("dnsApplications:page-title")} +

      +

      + {t("dnsApplications:page-intro-paragraph-1")} +

      +
        +
      • + {" "} + {t("dnsApplications:page-intro-list-item-1")} +
      • -
      • {t("dnsApplications:page-intro-list-item-2")}
      • +
      • + {" "} + {t("dnsApplications:page-intro-list-item-2")} +
      • -
      • {t("dnsApplications:page-intro-list-item-3")}
      • -
      +
    • + {" "} + {t("dnsApplications:page-intro-list-item-3")} +
    • +
    +
    + + {/* {process.env.SHOWMAPS == "true" && ( */} +
    +
    + + ModelsMap(map, maps) + } + /> +
    +
    + {/* )} */}
    - {searchResultsObj["@odata.count"] > 5 && (
    @@ -463,6 +732,12 @@ const mapDispatchToProps = (dispatch) => { setSearchDetails: (searchDetailsObj) => { dispatch(setSearchDetails(searchDetailsObj)); }, + setWatchedCases: (watchedCases) => { + dispatch(setWatchedCases(watchedCases)); + }, + setWatchedCasesDetails: (watchedCasesDetails) => { + dispatch(setWatchedCasesDetails(watchedCasesDetails)); + }, setCurrentPage: (currentPage) => { dispatch(setCurrentPage(currentPage)); }, diff --git a/i18n.js b/i18n.js index ecf361e3..c548e141 100644 --- a/i18n.js +++ b/i18n.js @@ -11,12 +11,19 @@ module.exports = { "pages": { "*": ["common", "newappeal", "search"], "/": ["common", "home"], - "/myportal": ["myportal"], + "/myportal": ["myportal", "common", "home"], "/myportal/viewall": ["search"], "/myportal/advancedsearch": ["search", "myportal"], "/myportal/advancedsearchresults": ["search", "myportal"], "/myportal/searchresults": ["search", "myportal"], "/myportal/case": ["case"], + "/myportal/dnsapplications": ["search", "dnsCommon", "dnsApplications"], + "/myportal/dnsdetails": [ + "case", + "search", + "dnsCommon", + "dnsApplications", + ], "/advancedsearch": ["search", "myportal"], "/advancedsearchresults": ["search"], "/searchresults": ["search"], @@ -39,5 +46,6 @@ module.exports = { "/account/personaldetails": ["common", "search"], "/details-about-cookies": ["common", "cookies"], "/terms-and-conditions": ["common"], + "/account/passwordreset": ["common", "home"], }, }; diff --git a/package.json b/package.json index 24bb32e9..fdce8e9f 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "start": "node_modules/next/dist/bin/next start" }, "dependencies": { + "@googlemaps/react-wrapper": "^1.1.24", "@webdeb/next-styles": "^1.1.1", "applicationinsights": "^2.2.0", "axios": "^0.24.0", @@ -21,21 +22,26 @@ "dynamics-web-api": "^1.7.4", "express": "^4.17.2", "fs": "^0.0.1-security", + "google-map-react": "^2.1.10", "govuk-frontend": "3.13.0", "https": "^1.0.0", "hyco-https": "^1.4.5", "jsonpath": "^1.1.1", "jsonpath-plus": "^6.0.1", + "leaflet": "^1.7.1", + "leaflet-defaulticon-compatibility": "^0.1.1", "lodash": "^4.17.21", "moment": "^2.29.1", + "multer": "^1.4.4", "nanoid": "^3.2.0", "next": "^12.0.8", + "next-connect": "^0.12.2", "next-redux-wrapper": "^7.0.5", "next-translate": "^1.2.0", "nextjs-basic-auth-middleware": "^0.2.1", "nookies": "^2.5.2", + "ospoint": "^0.2.1", "path": "^0.12.7", - "pm2": "^5.1.2", "react": "17.0.2", "react-accessible-accordion": "^4.0.0", "react-autosuggest": "^10.1.0", @@ -44,6 +50,7 @@ "react-dom": "17.0.2", "react-dropzone": "^11.5.1", "react-idle-timer": "^4.6.4", + "react-leaflet": "^3.2.5", "react-loading-overlay": "^1.0.1", "react-redux": "^7.2.6", "react-xml-parser": "^1.1.8", diff --git a/pages/_document.js b/pages/_document.js index 32615699..8740d189 100644 --- a/pages/_document.js +++ b/pages/_document.js @@ -46,7 +46,7 @@ class MyDocument extends Document { csp += `base-uri 'self';`; csp += `form-action 'self';`; csp += `object-src 'self' data:;`; - csp += `script-src 'self' unsafe-inline https://www.googletagmanager.com 'nonce-${generatedNonce}' ${ + csp += `script-src 'self' unsafe-inline https://www.googletagmanager.com https://maps.googleapis.com 'nonce-${generatedNonce}' ${ process.env.NODE_ENV != "production" ? " 'unsafe-eval';" : " ;" }`; //csp += `img-src 'self' https://www.googletagmanager.com https://gov.wales https://www.google-analytics.com 'nonce-${generatedNonce}' data:;`; diff --git a/pages/api/endpoint/getbasicdnsurlsearch_api.js b/pages/api/endpoint/getbasicdnsurlsearch_api.js index b315494b..e4aa2c7f 100644 --- a/pages/api/endpoint/getbasicdnsurlsearch_api.js +++ b/pages/api/endpoint/getbasicdnsurlsearch_api.js @@ -32,7 +32,7 @@ export default async function ApiProxy(req, res) { searchString + "')) and pinswg_appealcasetype eq 846040011 and pinswg_publishtoweb eq true&$orderby=createdon desc&$count=true"; - // console.log("basic search ", queryUrl); + console.log("basic search ", queryUrl); var apiResponse = _.isEmpty(req.query) ? res.status(400).json() diff --git a/pages/api/endpoint/getdnscoords_api.js b/pages/api/endpoint/getdnscoords_api.js new file mode 100644 index 00000000..5bc94a88 --- /dev/null +++ b/pages/api/endpoint/getdnscoords_api.js @@ -0,0 +1,41 @@ +import axios from "axios"; +import CryptoJS from "crypto-js"; +import { getToken, azureHeadersPaged, azureHeaders } from "../../../actions"; + +const WORDKEY = process.env.HASHKEY; + +const WEBAPI_URL = + process.env.RELAY_ROOT || + "https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/"; + +const hashAPIPath = (queryPath) => { + var hashlink = CryptoJS.HmacSHA256( + queryPath, + CryptoJS.enc.Hex.parse(WORDKEY) + ); + hashlink = hashlink.toString(CryptoJS.enc.Hex); + + //return "&hash=" + hashlink; + + return (queryPath.indexOf("?") > -1 ? "&hash=" : "?hash=") + hashlink; +}; + +export default async function ApiProxy(req, res) { + var token = await getToken(); + + var queryUrl = + "pinswg_dnses?$select=pinswg_name,pinswg_anticipatedgridreferenceeastingtext,pinswg_anticipatedgridreferencenorthingtext,pinswg_projectname,pinswg_dnsid,_pinswg_associatedlpa_value,_pinswg_appellant_value&$filter=pinswg_anticipatedgridreferencenorthingtext ne null and pinswg_anticipatedgridreferenceeastingtext ne null&$count=true"; + + console.log("dns ", queryUrl); + return axios + .get( + WEBAPI_URL + queryUrl + hashAPIPath(queryUrl), + azureHeaders(token.access_token) + ) + .then(({ data }) => { + res.status(200).json(data); + }) + .catch(({ err }) => { + res.status(400).json(err); + }); +} diff --git a/pages/dnsapplications.js b/pages/dnsapplications.js index 7eae2e97..f5a85e83 100644 --- a/pages/dnsapplications.js +++ b/pages/dnsapplications.js @@ -2,7 +2,7 @@ import useTranslation from "next-translate/useTranslation"; import Head from "next/head"; import { useRouter } from "next/router"; import { connect } from "react-redux"; -import { getBasicDNSSearch } from "../actions"; +import { getBasicDNSSearch, getDNSCoords } from "../actions"; import Breadcrumbs from "../components/breadcrumbs"; import CookieBanner from "../components/cookieBanner"; import DNSSearchResults from "../components/dnssearchresults"; @@ -13,6 +13,7 @@ import { setSearch } from "../store/search/action"; import { setSearchDetails, setSearchResults, + setDNSCoords, } from "../store/searchOutput/action"; import { wrapper } from "../store/store"; @@ -129,9 +130,11 @@ export const getServerSideProps = wrapper.getServerSideProps( : searchResultsObj; const searchDetailsObj = await getSearchDetails(searchResultsObj); + const dnsCoords = await getDNSCoords(); store.dispatch(setSearchResults(searchResultsObj)); store.dispatch(setSearchDetails(searchDetailsObj)); store.dispatch(setSearch("DNS")); + store.dispatch(setDNSCoords(dnsCoords)); } ); diff --git a/pages/myportal/dnsapplications.js b/pages/myportal/dnsapplications.js new file mode 100644 index 00000000..c888d491 --- /dev/null +++ b/pages/myportal/dnsapplications.js @@ -0,0 +1,215 @@ +import useTranslation from "next-translate/useTranslation"; +import Head from "next/head"; +import { useRouter } from "next/router"; +import { connect } from "react-redux"; +import { + getBasicDNSSearch, + getDNSCoords, + getPortalModuleDetails, + getWatchedCases, +} from "../../actions"; + +import Breadcrumbs from "../../components/breadcrumbs"; +import CookieBanner from "../../components/cookieBanner"; +import DNSSearchResults from "../../components/dnssearchresults"; +import Footer from "../../components/footer"; +import Header from "../../components/header"; +import { + getSearchDetails, + getFormCollectionByID, +} from "../../components/utils"; +import { setSearch } from "../../store/search/action"; +import { + setSearchDetails, + setSearchResults, + setDNSCoords, +} from "../../store/searchOutput/action"; +import { wrapper } from "../../store/store"; +import { + setWatchedCases, + setWatchedCasesDetails, +} from "../../store/watchedCases/action"; + +const Home = (props) => { + const { footerLinks, pages, watchedCases } = props; + let { t, lang } = useTranslation(); + + const router = useRouter(); + const { locale } = router; + const { appealtypes } = router.query; + + return ( +
    + + + {t("search:page-title")} - {t("common:service-name")} + + <> + + + {/* If they have a Twitter Handle, include the meta details below */} + + + + + + + + + + + + + + + + +
    + +
    +
    + + +
    +
    +
    +
    + ); +}; + +export const getServerSideProps = wrapper.getServerSideProps( + (store) => + async ({ query, req, res }) => { + console.log("query-", query); + + const { cookies } = req; + + res.setHeader( + "Cache-Control", + "public, s-maxage=10, stale-while-revalidate=59" + ); + + let loggedInUser = cookies.pinsUser; + + let [searchResultsObj, watchedCases] = await Promise.all([ + await getBasicDNSSearch(), + await getWatchedCases(loggedInUser), + ]); + + searchResultsObj = + searchResultsObj.status == 502 + ? { + value: [], + errorCode: searchResultsObj.status, + errorMsg: searchResultsObj.statusText, + } + : searchResultsObj; + + const [searchDetailsObj, watchedCasesDetails] = await Promise.all([ + await getSearchDetails(searchResultsObj), + await getDetails(watchedCases, "myWatchedCases"), + ]); + const dnsCoords = await getDNSCoords(); + store.dispatch(setSearchResults(searchResultsObj)); + store.dispatch(setSearchDetails(searchDetailsObj)); + store.dispatch(setSearch("DNS")); + store.dispatch(setDNSCoords(dnsCoords)); + store.dispatch(setWatchedCases(watchedCases)); + store.dispatch(setWatchedCasesDetails(watchedCasesDetails)); + } +); + +const getDetails = (resultsObj, detailsType) => { + //console.log(resultsObj); + let detailsArr = []; + resultsObj = resultsObj.value; + const detailsObj = resultsObj.map((searchDetail, index) => { + if (searchDetail.pinswg_appealcasetype == null) { + console.log( + detailsType != "myWatchedCases" + ? searchDetail.ticketnumber + : searchDetail[ + "_pinswg_watchedcase_value@OData.Community.Display.V1.FormattedValue" + ] + ); + } else { + detailsArr.push( + getPortalModuleDetails( + getFormCollectionByID(searchDetail.pinswg_appealcasetype) + .LogicalCollectionName, + detailsType != "myWatchedCases" + ? searchDetail.ticketnumber + : searchDetail[ + "_pinswg_watchedcase_value@OData.Community.Display.V1.FormattedValue" + ] + ) + ); + } + }); + //console.log(detailsArr); + return Promise.all(detailsArr); +}; + +const mapStateToProps = (state) => { + return { + currentView: state.currentView, + search: state.search, + searchResultsObj: state.searchResultsObj, + formData: state.formData, + appealType: state.appealType, + form: state.form, + myCases: state.myCases, + watchedCases: state.watchedCases, + myRepresentations: state.myRepresentations, + awaitingSubmission: state.awaitingSubmission, + }; +}; + +export default connect(mapStateToProps)(Home); diff --git a/pages/myportal/dnsdetails.js b/pages/myportal/dnsdetails.js new file mode 100644 index 00000000..26108606 --- /dev/null +++ b/pages/myportal/dnsdetails.js @@ -0,0 +1,91 @@ +import useTranslation from "next-translate/useTranslation"; +import Head from "next/head"; +import { useRouter } from "next/router"; +import { connect } from "react-redux"; +import Breadcrumbs from "../../components/breadcrumbs"; +import Case from "../../components/case"; +import CookieBanner from "../../components/cookieBanner"; +import Footer from "../../components/footer"; +import Header from "../../components/header"; + +const Home = (props) => { + const { footerLinks, pages } = props; + let { t, lang } = useTranslation(); + + const router = useRouter(); + const { locale } = router; + const { appealtypes } = router.query; + + return ( +
    + + + {t("case:page-title")}:{" "} + {props.currentView.caseReference.currentReference}{" "} + {t("common:service-name")} + + +
    + +
    +
    + + +
    +
    +
    + ); +}; + +const mapStateToProps = (state) => { + //console.log(state); + + return { + currentView: state.currentView, + search: state.search, + searchResultsObj: state.searchResultsObj, + formData: state.formData, + appealType: state.appealType, + form: state.form, + myCases: state.myCases, + watchedCases: state.watchedCases, + myRepresentations: state.myRepresentations, + awaitingSubmission: state.awaitingSubmission, + }; +}; + +export default connect(mapStateToProps)(Home); diff --git a/pages/myportal/index.js b/pages/myportal/index.js index 28c7207a..b3f33595 100644 --- a/pages/myportal/index.js +++ b/pages/myportal/index.js @@ -37,6 +37,7 @@ import { setWatchedCases, setWatchedCasesDetails, } from "../../store/watchedCases/action"; +import { setCookie } from "nookies"; const Home = (props) => { const { diff --git a/store/searchOutput/action.js b/store/searchOutput/action.js index c4c1a60a..df2a1cf2 100644 --- a/store/searchOutput/action.js +++ b/store/searchOutput/action.js @@ -6,6 +6,7 @@ export const searchResultsActionTypes = { SETDOCUMENTDETAILS: "SETDOCUMENTDETAILS", SETDOCUMENTHISTORY: "SETDOCUMENTHISTORY", SETREPRESENTATIONS: "SETREPRESENTATIONS", + SETDNSCOORDS: "SETDNSCOORDS", }; export const getSearchResultshObj = () => (dispatch) => { @@ -47,3 +48,10 @@ export const setRepresentations = (representations) => (dispatch) => { representationsObj: representations, }); }; + +export const setDNSCoords = (dnsCoords) => (dispatch) => { + return dispatch({ + type: searchResultsActionTypes.SETDNSCOORDS, + dnsCoordsObj: dnsCoords, + }); +}; diff --git a/store/searchOutput/reducer.js b/store/searchOutput/reducer.js index 06217d2b..d65b798f 100644 --- a/store/searchOutput/reducer.js +++ b/store/searchOutput/reducer.js @@ -5,6 +5,7 @@ const searchResultsInitialState = { searchDetailsObj: {}, documentDetailsObj: {}, representationsObj: {}, + dnsCoordsObj: {}, }; export default function reducer(state = searchResultsInitialState, action) { @@ -30,6 +31,11 @@ export default function reducer(state = searchResultsInitialState, action) { ...state, representationsObj: action.representationsObj, }; + case searchResultsActionTypes.SETDNSCOORDS: + return { + ...state, + dnsCoordsObj: action.dnsCoordsObj, + }; default: return state; } diff --git a/styles/sass/patterns/_card.scss b/styles/sass/patterns/_card.scss index 3673f7b1..452eddf4 100644 --- a/styles/sass/patterns/_card.scss +++ b/styles/sass/patterns/_card.scss @@ -250,8 +250,14 @@ div.cardModuleItem:last-of-type { width: 95%; } - .cardModuleReference a { - display: block; + .cardModuleReference { + display: flex; + b { + min-width: 122px; + } + a { + margin-left: 10px; + } } .cardModuleRemoveCase { diff --git a/styles/sass/welshgov/_application.scss b/styles/sass/welshgov/_application.scss index d5075043..3a3432f6 100644 --- a/styles/sass/welshgov/_application.scss +++ b/styles/sass/welshgov/_application.scss @@ -1,3 +1,7 @@ +@import "leaflet/dist/leaflet.css"; +@import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css"; +// @import "leaflet-defaulticon-compatibility"; + html { scroll-behavior: smooth; }