diff --git a/actions/index.js b/actions/index.js index 50b6ecaa..74bb1ba7 100644 --- a/actions/index.js +++ b/actions/index.js @@ -1073,6 +1073,12 @@ export const patchCase = async (incidentid) => { }; export const getCase = (incidentID) => { + // console.log( + // "////////////// ------" + + // BASE_URL + + // "/api/endpoint/getcase_api?incidentID=" + + // incidentID + // ); return axios .get(BASE_URL + "/api/endpoint/getcase_api?incidentID=" + incidentID) .then((res) => { diff --git a/components/case.js b/components/case.js index 09b602c3..ab83efee 100644 --- a/components/case.js +++ b/components/case.js @@ -36,6 +36,7 @@ const Case = (props) => { searchString={props.searchString} incidentid={props.incidentid} showMap={props.showMap} + showLoginCheck={props.showLoginCheck} /> { onHandleSubmit={onHandleSubmit} currentView={currentView} setSubmitBack={setSubmitBack} + props={props} /> ); break; @@ -144,6 +145,7 @@ let MakeRepresentation = (props) => { onHandleSubmit={onHandleSubmit} currentView={currentView} setSubmitBack={setSubmitBack} + props={props} /> ); break; @@ -160,6 +162,7 @@ let MakeRepresentation = (props) => { onHandleSubmit={onHandleSubmit} currentView={currentView} setSubmitBack={setSubmitBack} + props={props} /> ); break; @@ -176,6 +179,7 @@ let MakeRepresentation = (props) => { onHandleSubmit={onHandleSubmit} currentView={currentView} setSubmitBack={setSubmitBack} + props={props} /> ); break; @@ -204,16 +208,18 @@ let MakeRepresentation = (props) => { setRepresentationSubmit={setRepresentationSubmit} currentView={currentView} setSubmitBack={setSubmitBack} + props={props} /> ); } }; const onHandleSubmit = (values) => { - console.log( - values.representationCapacity, - currentView.representationCapacity - ); + // console.log( + // values, + // values.representationCapacity, + // currentView.representationCapacity + // ); // console.log(_.isEmpty(currentView.representationCapacity)); // console.log( @@ -228,15 +234,22 @@ let MakeRepresentation = (props) => { .replace(/(\band|[\s\-\+\(\)\,\&])/g, "") .toLowerCase() ) - : setRepresentationSubmit(true); + : setRepresentationSubmit("true"); + + window.alert(`You submitted:\n\n${JSON.stringify(values, null, 2)}`); }; const repForm = props.props.form; + // console.log( + // "waht is representationSubmit:", + // currentView.representationSubmit + // ); + return (
- {representationSubmit == true ? ( + {currentView.representationSubmit == "true" ? ( { ) : ( <> {!session ? ( - + <> +
+

+ Some text in here to explain about + raising a representation and why logging + in +

+
+ + ) : ( <>

diff --git a/components/case/representation/representationAppellant.js b/components/case/representation/representationAppellant.js index 927c1edc..8a4f4807 100644 --- a/components/case/representation/representationAppellant.js +++ b/components/case/representation/representationAppellant.js @@ -3,17 +3,20 @@ import { connect } from "react-redux"; import { useRouter } from "next/router"; import useTranslation from "next-translate/useTranslation"; import { Field, reduxForm, reset } from "redux-form"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; + import { RenderPickList, RenderTextfield, RenderRadioList, RenderMultiline, + RenderFileUpload, } from "./representationElements"; import { useDropzone } from "react-dropzone"; -import { - setRepresentationCapacity, - setRepresentationSubmit, -} from "../../../store/currentView/action"; +// import { +// setRepresentationCapacity, +// setRepresentationSubmit, +// } from "../../../store/currentView/action"; const RepAppellant = (props) => { let { t } = useTranslation(); @@ -28,11 +31,8 @@ const RepAppellant = (props) => { currentView, } = props; const { acceptedFiles, getRootProps, getInputProps } = useDropzone(); - const files = acceptedFiles.map((file) => ( -
  • - {file.path} - {file.size} bytes -
  • - )); + + // console.log(props); return (
    @@ -141,7 +141,6 @@ const RepAppellant = (props) => { className="govuk-checkboxes__input" id="documentBox" name="documentBox" - value="email" data-aria-controls="documentBox" type="checkbox" component={RenderTextfield} @@ -174,25 +173,28 @@ const RepAppellant = (props) => { } id="conditional-documentBox" > -
    -
    -
    - -

    - Drag and drop files here or - click to select files -

    -
    - -
    -
    +

    + {props.label}{" "} +

    +

    @@ -208,13 +210,13 @@ const RepAppellant = (props) => { Continue {/* { - setRepresentationSubmit(false); - }} - className="govuk-button" - > - Continue - */} + onClick={() => { + setRepresentationSubmit(true); + }} + className="govuk-button" + > + Continue ww + */} { setRepresentationCapacity(); diff --git a/components/case/representation/representationComplete.js b/components/case/representation/representationComplete.js index b05e74e9..6900d915 100644 --- a/components/case/representation/representationComplete.js +++ b/components/case/representation/representationComplete.js @@ -39,10 +39,10 @@ const RepComplete = (props) => { return (
    -
    -

    +
    +

    Submission of Representation -

    +

    Thank you for submitting your representation(s) using the Appeals Casework Portal. diff --git a/components/case/representation/representationCompleteSubmit.js b/components/case/representation/representationCompleteSubmit.js index 0cd6acaa..6a501fa9 100644 --- a/components/case/representation/representationCompleteSubmit.js +++ b/components/case/representation/representationCompleteSubmit.js @@ -45,8 +45,8 @@ const RepCompleteSubmit = (props) => { ) : (

    -
    -

    Submit

    +
    +

    Submit

    The gathering and subsequent processing of the personal data supplied by you in this form, is diff --git a/components/case/representation/representationElements.js b/components/case/representation/representationElements.js index a4fb778b..7613869e 100644 --- a/components/case/representation/representationElements.js +++ b/components/case/representation/representationElements.js @@ -1,6 +1,13 @@ -import { Field, reduxForm } from "redux-form"; +import { Field, Fields, reduxForm } from "redux-form"; import router from "next/router"; -import React, { useState } from "react"; +import React, { useState, useMemo } from "react"; +import useTranslation from "next-translate/useTranslation"; +import jsonpath from "jsonpath"; +import Dropzone, { useDropzone } from "react-dropzone"; + +import dynamic from "next/dynamic"; +const ReactQuill = dynamic(() => import("react-quill"), { ssr: false }); +import "react-quill/dist/quill.snow.css"; export const RenderRadioList = ({ datafieldname, @@ -149,14 +156,40 @@ export const RenderMultiline = ({ meta: { touched, error }, ...custom }) => { + const [editValue, setEditValue] = useState( + input.value != null ? input.value : "" + ); + + const changeEdit = (valStr) => { + setEditValue(valStr); + input.onChange(valStr); + }; + + var modules = { + toolbar: [ + [{ "header": [1, 2, false] }], + ["bold", "italic", "underline", "blockquote"], + [{ "list": "ordered" }, { "list": "bullet" }], + ["clean"], + ], + }; + return ( <> + ); @@ -192,3 +225,339 @@ export function MultiLinefield(props) {

    ); } + +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", +}; + +const activeStyle = { + borderColor: "#2196f3", +}; + +const acceptStyle = { + borderColor: "#00e676", +}; + +const rejectStyle = { + borderColor: "#ff1744", +}; + +export const RenderFileUpload = (field) => { + const files = field.input.value; + let { t } = useTranslation(); + + 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; + default: + return "/assets/images/documenttypes/txt.png"; + break; + } + }; + + const getThumbnailIconByExtension = (blobName) => { + let fileType = blobName.slice(blobName.lastIndexOf(".") + 1); + + switch (fileType) { + case "html": + return "/assets/images/documenttypes/html.png"; + break; + case "txt": + return "/assets/images/documenttypes/txt.png"; + break; + case "doc": + return "/assets/images/documenttypes/doc.png"; + break; + case "pdf": + return "/assets/images/documenttypes/pdf.png"; + break; + case "docx": + return "/assets/images/documenttypes/docx.png"; + break; + case "csv": + return "/assets/images/documenttypes/csv.png"; + break; + case "xlsx": + return "/assets/images/documenttypes/xlsx.png"; + break; + + case "zip": + return "/assets/images/documenttypes/zip.png"; + break; + case "jpeg": + case "jpg": + return "/assets/images/documenttypes/jpg.png"; + case "png": + return "/assets/images/documenttypes/png.png"; + break; + default: + return "/assets/images/documenttypes/txt.png"; + break; + } + }; + + const getDocumentType = (docCode) => { + switch (docCode) { + case "000001": + return "000001"; + break; + case "000002": + return "000002"; + break; + case "000003": + return "000003"; + break; + case "000004": + return "000004"; + break; + case "000005": + return "000005"; + break; + case "000006": + return "000006"; + break; + case "000007": + return "000007"; + break; + case "000008": + return "000008"; + break; + case "000009": + return "000009"; + break; + case "000010": + return "000010"; + break; + case "000011": + return "000011"; + break; + case "000012": + return "000012"; + break; + case "000013": + return "000013"; + break; + case "000014": + return "000014"; + break; + case "000015": + return "000015"; + break; + + default: + return "000000"; + } + }; + + const filelistObj = field.fileList || {}; + + const blobList = jsonpath.query( + filelistObj, + "$..[?(@.documentType=='" + field.documentTypeCode + "')]" + ); + + const deleteThisBlob = async ( + containerName, + blobName, + deleteblobhash, + getblobshash, + casefolderID + ) => { + //console.log(containerName, blobName, deleteblobhash); + deleteBlob(containerName, blobName, deleteblobhash, casefolderID) + .then((data) => data) + .then(() => { + getFilesFromBlobHashed( + containerName, + getblobshash, + casefolderID + ).then((newfilelist) => field.setFilesForAppeal(newfilelist)); + }); + }; + + return ( + <> + { + const renamedAcceptedFiles = filesToUpload.map( + (file) => + new File( + [file], + `${getDocumentType(field.documentTypeCode)}_${ + file.name + }`, + { + type: file.type, + } + ) + ); + field.input.onChange(renamedAcceptedFiles); + }} + > + {({ getRootProps, getInputProps }) => ( + <> + {/* {field.hint != false && ( +
    ss{t(field.hint)}
    + )} +
    */} +
    +
    + {" "} + +
    + {t( + "newappeal:new-appeal-fileupload-drop-label" + )} +
    + + ( + {t( + "newappeal:new-appeal-fileupload-file-list-label" + )} + ) + +
    + +
    + + )} +
    + {field.meta.touched && field.meta.error && ( + {field.meta.error} + )} + {files && Array.isArray(files) && ( +
      + {files.map((file, i) => ( +
      + {file.name} + + {file.name} ({bytesToSize(file.size)}) + +
      + ))} +
    + )} + {blobList.map((blob, i) => ( +
    + ))}{" "} + + ); +}; diff --git a/components/case/representation/representationInterestedPartyPerson.js b/components/case/representation/representationInterestedPartyPerson.js index 024dfefb..fb4b6088 100644 --- a/components/case/representation/representationInterestedPartyPerson.js +++ b/components/case/representation/representationInterestedPartyPerson.js @@ -294,7 +294,14 @@ const RepInterestedPartyPerson = (props) => {
    - + + {/* { setRepresentationSubmit(true); @@ -211,7 +218,7 @@ const RepLandOwner = (props) => { > Continue - + */} { setRepresentationCapacity(); diff --git a/components/case/summary.js b/components/case/summary.js index e31cb51c..0fe5c377 100644 --- a/components/case/summary.js +++ b/components/case/summary.js @@ -65,6 +65,9 @@ const CaseSummary = (props) => { showMap, } = props; + const { data: session, status } = useSession(); + //console.log("session status:", status, session); + const noRepresentationLink = ["/dnsdetails", "/dns/[developmentName]"]; let setCaseQueryObj = props[currentType]; @@ -276,8 +279,12 @@ const CaseSummary = (props) => {
    - {noRepresentationLink.includes(router.pathname) == - true ? ( + {props.currentView.caseReference.showreps == + "false" ? ( + "" + ) : noRepresentationLink.includes( + router.pathname + ) == true ? ( "" ) : ( @@ -706,8 +713,6 @@ const CaseSummary = (props) => { ); } - const { data: session, status } = useSession(); - //console.log("session status:", status, session); return ( <> {showDetailsBlock} diff --git a/components/representation.js b/components/representation.js index e202abf4..b54dcb66 100644 --- a/components/representation.js +++ b/components/representation.js @@ -4,7 +4,7 @@ import { useContext } from "react"; import useTranslation from "next-translate/useTranslation"; import Summary from "./case/representation"; -const CaseSummary = (props) => { +const CaseRepresentation = (props) => { let { t } = useTranslation(); const router = useRouter(); @@ -35,4 +35,4 @@ const CaseSummary = (props) => { ); }; -export default CaseSummary; +export default CaseRepresentation; diff --git a/components/search/dnssearchresults.js b/components/search/dnssearchresults.js index 9c1995ed..1146d4dc 100644 --- a/components/search/dnssearchresults.js +++ b/components/search/dnssearchresults.js @@ -547,11 +547,11 @@ const DNSSearchResults = (props) => { }} title="Stop watching this case" > - − + ) : ( { selectWatchedCase( cookies.pinsUser, @@ -565,7 +565,7 @@ const DNSSearchResults = (props) => { }} title="Watch this case" > - + + )} diff --git a/components/search/searchresults.js b/components/search/searchresults.js index 5fa56b46..5ccd6ce2 100644 --- a/components/search/searchresults.js +++ b/components/search/searchresults.js @@ -306,6 +306,8 @@ const SearchResults = (props) => { item.incidentid, "appealType": item.pinswg_appealcasetype, + "showreps": + props.showLoginCheck, }); }} > diff --git a/components/searchresults.js b/components/searchresults.js index 359ef547..ec39b08b 100644 --- a/components/searchresults.js +++ b/components/searchresults.js @@ -51,7 +51,7 @@ export default function Search(props) { myportal={myportal} watchedCases={watchedCases} isLinkedCase={isLinkedCase} - showLoginCheck + showLoginCheck={showLoginCheck} />
    diff --git a/package.json b/package.json index 9f9a9e12..066480ee 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "react-idle-timer": "^4.6.4", "react-leaflet": "^3.2.5", "react-loading-overlay": "^1.0.1", + "react-quill": "^2.0.0", "react-redux": "^7.2.6", "react-xml-parser": "^1.1.8", "redux-form": "^8.3.8", diff --git a/pages/api/endpoint/getcase_api.js b/pages/api/endpoint/getcase_api.js index da248bf6..11f92b68 100644 --- a/pages/api/endpoint/getcase_api.js +++ b/pages/api/endpoint/getcase_api.js @@ -24,7 +24,12 @@ const hashAPIPath = (queryPath) => { export default async function ApiProxy(req, res) { var incidentID = req.query.incidentID; var token = await getToken(); - var queryUrl = "incidents(" + incidentID + ")?$select=ticketnumber,title"; + var queryUrl = + "incidents(" + + incidentID + + ")?$select=ticketnumber,title,pinswg_appealcasetype"; + + //console.log(WEBAPI_URL + queryUrl + hashAPIPath(queryUrl)); return axios .get( diff --git a/pages/api/endpoint/getmyrepresentations_api.js b/pages/api/endpoint/getmyrepresentations_api.js index 635f0ed3..657d7d7b 100644 --- a/pages/api/endpoint/getmyrepresentations_api.js +++ b/pages/api/endpoint/getmyrepresentations_api.js @@ -26,6 +26,8 @@ export default async function ApiProxy(req, res) { loggedInUserId + "&$count=true&$orderby=createdon desc"; + //console.log(WEBAPI_URL + queryUrl + hashAPIPath(queryUrl)); + return axios .get( WEBAPI_URL + queryUrl + hashAPIPath(queryUrl), diff --git a/pages/api/endpoint/getportalmoduledetails_api.js b/pages/api/endpoint/getportalmoduledetails_api.js index 5b1455eb..4445f074 100644 --- a/pages/api/endpoint/getportalmoduledetails_api.js +++ b/pages/api/endpoint/getportalmoduledetails_api.js @@ -23,7 +23,7 @@ export default async function ApiProxy(req, res) { var caseReference = req.query.caseReference.split("'").join("''"); var token = await getToken(); - //console.log("the case:", caseReference); + //console.log("the case:", req.query, caseReference); var queryUrl = appealType + @@ -33,7 +33,7 @@ export default async function ApiProxy(req, res) { queryUrl = queryUrl + getSelectQuery(appealType); - //console.log("test:", queryUrl); + //console.log("test:", WEBAPI_URL + queryUrl + hashAPIPath(queryUrl)); return axios .get( diff --git a/pages/case/index.js b/pages/case/index.js index ab348b69..4ef5396b 100644 --- a/pages/case/index.js +++ b/pages/case/index.js @@ -8,7 +8,7 @@ import CookieBanner from "../../components/cookieBanner"; import Footer from "../../components/footer"; import Header from "../../components/header"; -const Home = (props) => { +const CaseHome = (props) => { const { footerLinks, pages } = props; let { t, lang } = useTranslation(); @@ -66,6 +66,7 @@ const Home = (props) => { representationsObj={ props.searchResultsObj.representationsObj } + showLoginCheck={props.showLoginCheck} />
    @@ -88,7 +89,8 @@ const mapStateToProps = (state) => { watchedCases: state.watchedCases, myRepresentations: state.myRepresentations, awaitingSubmission: state.awaitingSubmission, + showLoginCheck: process.env.SHOWLOGIN || false, }; }; -export default connect(mapStateToProps)(Home); +export default connect(mapStateToProps)(CaseHome); diff --git a/pages/myportal/index.js b/pages/myportal/index.js index 32eeb868..284fbc01 100644 --- a/pages/myportal/index.js +++ b/pages/myportal/index.js @@ -12,6 +12,8 @@ import { getPersonalAccount, getPortalModuleDetails, getWatchedCases, + consoleLogger, + getCase, } from "../../actions"; import { createContainer } from "../../actions/azurestorage"; import { getProviderConfig } from "../../actions/govgateway"; @@ -255,9 +257,23 @@ export const getServerSideProps = wrapper.getServerSideProps( ); const getDetails = (resultsObj, detailsType) => { - //console.log(detailsType); let detailsArr = []; resultsObj = resultsObj.value; + + if (detailsType == "myRepresentations") { + const repsObj = resultsObj.map((searchDetail, index) => { + detailsArr.push( + getCase(searchDetail["_pinswg_case_value"]).then((data) => { + return getPortalModuleDetails( + getFormCollectionByID(data.pinswg_appealcasetype) + .LogicalCollectionName, + data.ticketnumber + ); + }) + ); + }); + } + const detailsObj = resultsObj.map((searchDetail, index) => { if (searchDetail.pinswg_appealcasetype == null) { console.log( diff --git a/pages/searchresults.js b/pages/searchresults.js index b0680248..af40d80c 100644 --- a/pages/searchresults.js +++ b/pages/searchresults.js @@ -18,7 +18,7 @@ import { wrapper } from "../store/store"; import _ from "lodash"; const Home = (props) => { - const { footerLinks, pages, isLinkedCase } = props; + const { footerLinks, pages, isLinkedCase, showLoginCheck } = props; let { t, lang } = useTranslation(); const router = useRouter(); @@ -106,7 +106,7 @@ const Home = (props) => { searchString={props.search.searchString} searchResultsObj={props.searchResultsObj} isLinkedCase={isLinkedCase} - showLoginCheck + showLoginCheck={showLoginCheck} />