diff --git a/actions/azurestorage.js b/actions/azurestorage.js index a9b5a512..0dce1c94 100644 --- a/actions/azurestorage.js +++ b/actions/azurestorage.js @@ -521,10 +521,123 @@ export const uploadFile = async (formContent, containerName, foldername) => { const containerClient = new ContainerClient(sasUrl); const files = formContent; + let blobResponseArr = []; //console.log(...formContent); console.log("files...", files, Object.keys(files).length, foldername); + for (const prop in files) { + console.log(`files[${prop}] = ${files[prop][0].size}`); + const blobName = foldername + "/files/" + files[prop][0].fieldName; + + console.log(blobName); + const blockBlobClient = containerClient.getBlockBlobClient(blobName); + const uploadBlobResponse = await blockBlobClient + .uploadFile(files[prop][0].path, files[prop].size) + .then((data) => { + console.log( + "////////////////////////\nfile name:", + files[prop][0].fieldName, + "\n////////////////////////////" + ); + console.log(data); + + let whichLocation = + files[prop][0].fieldName.indexOf("_Statement_of_Case") > + 0 || + files[prop][0].fieldName.indexOf("_-_Statement_of_Case") > + 0 || + files[prop][0].fieldName.indexOf("_-_Application_Form") > + 0 || + files[prop][0].fieldName.indexOf( + "_-_Site_Ownership_Certificate" + ) > 0 || + files[prop][0].fieldName.indexOf("_-_Decision_Notice") > + 0 || + files[prop][0].fieldName.indexOf("_-_Site_Location_Plan") > + 0 || + files[prop][0].fieldName.indexOf( + "_-_Plans_Drawing_Documents" + ) > 0 || + files[prop][0].fieldName.indexOf( + "_-_Additional_Plans_Drawings_Documents" + ) > 0 || + files[prop][0].fieldName.indexOf( + "_-_Design_and_Access_Statement" + ) > 0 || + files[prop][0].fieldName.indexOf( + "_-_NSB_LPA_Additional_Documents" + ) > 0 || + files[prop][0].fieldName.indexOf("_-_LPA_Correspondence") > + 0 || + files[prop][0].fieldName.indexOf( + "_-_LPA_Original_Permission" + ) > 0 || + files[prop][0].fieldName.indexOf( + "_-_LPA's_Registration_Letter" + ) > 0 || + files[prop][0].fieldName.indexOf( + +"_-_Environmental_Statement" + ) > 0 || + files[prop][0].fieldName.indexOf("_-_Cost_of_Application") > + 0 || + files[prop][0].fieldName.indexOf( + "_-_Other_Relevant_Material" + ) > 0 || + files[prop][0].fieldName.indexOf( + "_-_S106_Agreement_or_Unilateral_Undertaking" > 0 + ) + ? "846040000" + : files[prop][0].fieldName.indexOf("_IP_") > 0 + ? "846040005" + : files[prop][0].fieldName.indexOf("_Statement_") > 0 + ? "846040002" + : files[prop][0].fieldName.indexOf("_Questionnaire_") > + 0 + ? "846040001" + : files[prop][0].fieldName.indexOf("_Comments_") > 0 + ? "846040003" + : files[prop][0].fieldName.indexOf("_Impact_") > 0 + ? "846040001" + : "846040000"; + + const tags = { + containerid: containerName, + caseID: foldername.split("/")[0], + documentType: files[prop][0].fieldName.split(".")[1], + blobType: "RepresentationFile", + ishareLocation: whichLocation, + }; + const withTags = blockBlobClient.setTags(tags); + const withMeta = blockBlobClient.setMetadata(tags); + + console.log( + `Uploaded block blob ${files[prop][0].fieldName} successfully` + //uploadBlobResponse.requestId + ); + + blobResponseArr.push({ file: files[prop][0].fieldName }); + }); + } + + return blobResponseArr; +}; + +export const uploadSingleFile = async ( + formContent, + containerName, + foldername +) => { + const containerToken = await createContainerSas(containerName); + const sasUrl = `${STORAGE_PATH}/${containerName}?${containerToken}`; + const containerClient = new ContainerClient(sasUrl); + + const files = formContent; + + //console.log(...formContent); + console.log("files...", files, Object.keys(files).length, foldername); + let blobResponseArr = []; + for (const prop in files) { console.log(`files[${prop}] = ${files[prop][0].size}`); const blobName = foldername + "/files/" + files[prop][0].fieldName; @@ -534,6 +647,17 @@ export const uploadFile = async (formContent, containerName, foldername) => { const uploadBlobResponse = await blockBlobClient.uploadFile( files[prop][0].path, files[prop].size + // { + // blobHTTPHeaders: { + // blobContentType: "application/octet-stream", + // }, + // onProgress: (progress) => { + // // Log upload progress, you can emit this back to the client + // console.log( + // `Progress: ${progress.loadedBytes} bytes uploaded` + // ); + // }, + // } ); console.log( @@ -600,7 +724,12 @@ export const uploadFile = async (formContent, containerName, foldername) => { `Uploaded block blob ${files[prop][0].fieldName} successfully`, uploadBlobResponse.requestId ); + + blobResponseArr.push({ file: files[prop][0].fieldName }); + // return uploadBlobResponse; } + + return blobResponseArr; }; export const uploadRepFiles = async ( diff --git a/actions/index.js b/actions/index.js index bdca89ae..e25949f9 100644 --- a/actions/index.js +++ b/actions/index.js @@ -1497,6 +1497,44 @@ export const uploadFiles = async ( } }; +export const uploadSingleFile = async (filesObj, containerID, casefolderID) => { + let files = filesObj; + + //console.log(formValues); + var formData = new FormData(); + formData.append("containerID", containerID); + formData.append("casefolderID", casefolderID); + + // files.forEach((file) => formData.append("files", file)); + + for (let i = 0; i < files.length; i++) { + console.log(files.length); + // for (let j = 0; j < files[i].length; j++) { + // console.log("upload files:", files[i][j].name); + formData.append(files[i].name, files[i]); + // } + } + + //console.log(formData); + + var queryUrl = "/api/file/uploadsinglefile"; + + const config = { + method: "post", + url: queryUrl, + data: formData, + headers: { "content-type": "multipart/form-data" }, + }; + + //console.log(config); + try { + const res = await axios(config); + return res.data; + } catch (error) { + consoleLogger(error); + } +}; + export const uploadRepFiles = async ( formValues, filesObj, diff --git a/components/case/representation/index.js b/components/case/representation/index.js index 708eeb8d..b79aba93 100644 --- a/components/case/representation/index.js +++ b/components/case/representation/index.js @@ -92,6 +92,13 @@ let MakeRepresentation = (props) => { let questionnaireCount = updateQuestionnaireCount(); + const isLPA = + props.props.accountDetails.accountDetails[ + "pinswg_typeofinvolvement@OData.Community.Display.V1.FormattedValue" + ] == "LPA" + ? true + : false; + const setRepFileName = (values) => { //console.log("---------------\n", values); if ( @@ -167,35 +174,36 @@ let MakeRepresentation = (props) => { day + "-" + ("0" + repDate.getHours()).slice(-2) + + ":" + ("0" + repDate.getMinutes()).slice(-2) + + ":" + ("0" + repDate.getSeconds()).slice(-2) + + ":" + "_-_" + repCap + "_-_" + repType + "_-_" + - values.lastname.replace( - /[\s~`!@#$%^&*(){}\[\];:"'<,.>?\/\\|_+=-]/g, - "" - ) + - "_" + - values.firstname.replace( - /[\s~`!@#$%^&*(){}\[\];:"'<,.>?\/\\|_+=-]/g, - "" - ), + (isLPA + ? values.onBehalfOfLPA.replace( + /[\s~`!@#$%^&*(){}\[\];:"'<,.>?\/\\|_+=-]/g, + "" + ) + : values.lastname.replace( + /[\s~`!@#$%^&*(){}\[\];:"'<,.>?\/\\|_+=-]/g, + "" + ) + + "_" + + values.firstname.replace( + /[\s~`!@#$%^&*(){}\[\];:"'<,.>?\/\\|_+=-]/g, + "" + )), }); } return values; }; - const isLPA = - props.props.accountDetails.accountDetails[ - "pinswg_typeofinvolvement@OData.Community.Display.V1.FormattedValue" - ] == "LPA" - ? true - : false; - isLPA && setRepresentationCapacity("lpa"); currentType == "searchResultsObj" diff --git a/components/case/representation/representationAgent.js b/components/case/representation/representationAgent.js index dc4f5109..a7abdbf3 100644 --- a/components/case/representation/representationAgent.js +++ b/components/case/representation/representationAgent.js @@ -142,7 +142,7 @@ const RepAgent = (props) => { className="govuk-fieldset" aria-describedby="commentBox-hint" > -
@@ -150,7 +150,7 @@ const RepAgent = (props) => { "myrepresentations:comments-set-out-label" )} : -
+ */}
{ className="govuk-fieldset" aria-describedby="commentBox-hint" > -
@@ -129,7 +129,7 @@ const RepAppellant = (props) => { "myrepresentations:comments-set-out-label" )} : -
+
*/}
{ className="govuk-fieldset" aria-describedby="commentBox-hint" > -
@@ -153,7 +153,7 @@ const RepInterestedPartyPerson = (props) => { "myrepresentations:comments-set-out-label" )} : -
+
*/}
{ className="govuk-fieldset" aria-describedby="commentBox-hint" > -
@@ -282,7 +282,7 @@ let RepLPA = (props) => { "myrepresentations:comments-set-out-label" )} : -
+
*/}
{ className="govuk-fieldset" aria-describedby="commentBox-hint" > -
+ {/*
{t("myrepresentations:comments-set-out-label")}: -
+
*/}
{ className="govuk-fieldset" aria-describedby="commentBox-hint" > -
+ {/*
{t("myrepresentations:comments-set-out-label")}: -
+
*/}
import("react-quill-new"), { ssr: false }); +import { useStore as store, useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; + const RenderTextfield = ({ id, className, @@ -1736,6 +1746,8 @@ export function FileUploadField(props) { fileList={props.fileList} setFilesForAppeal={props.setFilesForAppeal} containerID={props.containerID} + uploadCount={props.uploadCount} + setFileCount={props.setFileCount} /> ); @@ -1935,10 +1947,41 @@ const RenderFileUpload = (field) => { return arr.filter((obj) => Object.keys(obj).length > 0); } + const [errorMessage, setErrorMessage] = useState(null); + const [rejectedFiles, setRejectedFiles] = useState([]); // Store rejected files + + const [completedUploadFiles, setCompletedUploadFiles] = useState(false); + const [uploadCountMessage, setUploadCountMessage] = useState(""); + + const handleDropRejected = (fileRejections) => { + const errors = fileRejections + .map(({ file, errors }) => { + return errors.map((error) => { + if (error.code === "file-too-large") { + return `${file.name} is too large. Please upload a smaller file.`; + } + if (error.code === "file-invalid-type") { + return `${file.name} has an invalid type. Please upload an image.`; + } + return `${file.name} is invalid.`; + }); + }) + .flat(); // Flatten the errors array + + setRejectedFiles(errors); // Store the error messages for rejected files + }; + + // Handle accepted files (clear error message when files are accepted) + const handleDropAccepted = () => { + setErrorMessage(null); // Clear any previous error messages when files are accepted + setRejectedFiles([]); // Clear any previously rejected file errorsss + }; + return ( <> { [".xlsx"], }} onDrop={(filesToUpload, e) => { + setCompletedUploadFiles(false); const renamedAcceptedFiles = filesToUpload.map( (file) => new File( @@ -1965,7 +2009,25 @@ const RenderFileUpload = (field) => { ) ); field.input.onChange(renamedAcceptedFiles); + + setUploadCountMessage(renamedAcceptedFiles.length); + + console.log("werwerw"); + field.setFileCount( + field.uploadCount + renamedAcceptedFiles.length + ); + + uploadSingleFile( + renamedAcceptedFiles, + field.containerID, + field.ticketnumber + ).then((data) => { + console.log(data); + setCompletedUploadFiles(true); + }); }} + onDropRejected={handleDropRejected} + onDropAccepted={handleDropAccepted} > {({ getRootProps, getInputProps }) => ( <> @@ -1986,15 +2048,40 @@ const RenderFileUpload = (field) => { )
- + {/* */} + {uploadCountMessage > 0 && + completedUploadFiles == false && ( +
+ Uploading {uploadCountMessage} files{" "} +
+ )} + {completedUploadFiles > 0 && ( +
+ {uploadCountMessage} files completed{" "} +
+ )} )} + {rejectedFiles.length > 0 && ( +
+
    + {rejectedFiles.map((error, index) => ( +
  • {error}
  • + ))} +
+
+ )} {field.meta.touched && field.meta.error && ( {field.meta.error} )} - {} + {filesList.length > 0 && + (completedUploadFiles ? ( + "Done" + ) : ( +

Uploading

+ ))} {files && Array.isArray(files) && ( <> {/* {(files = removeEmptyObjects(files))} */} @@ -2020,7 +2107,19 @@ const RenderFileUpload = (field) => { width="50" /> - {file.name}( ({bytesToSize(file.size)}) + {file.name} ({bytesToSize(file.size)}){" "} +
+
+ {completedUploadFiles ? ( +

+ Upload complete +

+ ) : ( +

+ Uploading... +

+ )} +
) diff --git a/components/newappeal/buildfield.js b/components/newappeal/buildfield.js index 16c5590a..d23e9d96 100644 --- a/components/newappeal/buildfield.js +++ b/components/newappeal/buildfield.js @@ -214,6 +214,9 @@ export default function BuildField(props) { props.props.props.props.accountDetails .containerID } + uploadCount={props.uploadCount} + setFileCount={props.props.setFileCount} + setUploadCount={props.setUploadCount} />
); diff --git a/components/newappeal/buildrow.js b/components/newappeal/buildrow.js index fa314249..1919a103 100644 --- a/components/newappeal/buildrow.js +++ b/components/newappeal/buildrow.js @@ -16,6 +16,11 @@ export default function BuildRow(props) { sectionCount, onSubmit, mandatoryFieldsData, + setUploadCount, + uploadCount, + setFileCount, + completedUploadFilesCount, + setCompletedUploadFilesCount, } = props; const parser = new DOMParser(); @@ -127,6 +132,9 @@ export default function BuildRow(props) { } mandatoryFieldsData={mandatoryFieldsData} documentTypeCode={documentTypeCode} + setFileCount={setFileCount} + setUploadCount={setUploadCount} + uploadCount={uploadCount} /> ); } else { diff --git a/components/newappeal/buildsection.js b/components/newappeal/buildsection.js index 31fd9f3d..19a95cc3 100644 --- a/components/newappeal/buildsection.js +++ b/components/newappeal/buildsection.js @@ -11,6 +11,7 @@ import { setDocumentsList, setFilesForAppeal, setNewAppealProgress, + setFileCount, } from "../../store/appealType/action"; import { getFormCollectionByID, getProgressObj } from "../utils"; import BuildRow from "./buildrow"; @@ -21,8 +22,14 @@ import BuildProgress from "./buildprogress"; let BuildSection = (props) => { const [currentSectionSelected, setCurrentSectionSelected] = useState(1); const [pickupWhereLeftOff, setPickupWhereLeftOff] = useState(true); - const [savingStatus, setSavingStatus] = useState(false); + const [allFilesUploaded, setAllFilesuploaded] = useState(false); + const [showCompletedUploadFiles, setShowCompletedUploadFiles] = + useState(false); + const [completedUploadFiles, setCompletedUploadFiles] = useState(false); + const [uploadCount, setUploadCount] = useState(0); + const [completedUploadFilesCount, setCompletedUploadFilesCount] = + useState(0); let { t } = useTranslation(); @@ -91,7 +98,7 @@ let BuildSection = (props) => { const handleParam = (setValue) => (e) => setValue(e.target.value); - const uploadAppealFiles = (values) => { + const uploadAppealFiles = async (values) => { // get filelists from values object let fileListObj = _.filter(values, function (v, key) { return _.includes(key, "pinswg_fileUpload"); @@ -110,14 +117,14 @@ let BuildSection = (props) => { // _.includes(key, "pinswg_fileUpload") == true && delete dataObj[key]; // } - uploadFiles( + await uploadFiles( dataObj, fileListObj, props.props.accountDetails.containerID, props.props.appealType.caseReference.ticketnumber ).then((data) => { - //console.log("hello", data); - + console.log("hello", data); + setCompletedUploadFiles(true); return data; }); }; @@ -166,122 +173,143 @@ let BuildSection = (props) => { setSavingStatus(useSaveStatus); - uploadAppealFiles(values); - // console.log( - // "\n////////////////////////\n appeal pdf payload", - // values, - // props.props.accountDetails.containerID, - // props.appealType.caseReference.ticketnumber, - // props.appealType, - // "\n////////////////////////\n" - // ); + setShowCompletedUploadFiles(true); - // let pdfObj = values; + uploadAppealFiles(values) + .then((data) => { + // console.log( + // "\n////////////////////////\n appeal pdf payload", + // values, + // props.props.accountDetails.containerID, + // props.appealType.caseReference.ticketnumber, + // props.appealType, + // "\n////////////////////////\n" + // ); - // Object.assign(pdfObj, { - // "containerID": props.props.accountDetails.containerID, - // "casefolderID": props.appealType.caseReference.ticketnumber, - // }); + // let pdfObj = values; - // generateAppealPDF( - // pdfObj, - // props.props.accountDetails.containerID, - // props.appealType.caseReference.ticketnumber, - // router.query.appealtypes, - // props.appealType.fileList - // ), + // Object.assign(pdfObj, { + // "containerID": props.props.accountDetails.containerID, + // "casefolderID": props.appealType.caseReference.ticketnumber, + // }); - props.setNewAppealProgress( - getProgressObj(formXML, titleList, mandatoryFieldsData, props) - ); + // generateAppealPDF( + // pdfObj, + // props.props.accountDetails.containerID, + // props.appealType.caseReference.ticketnumber, + // router.query.appealtypes, + // props.appealType.fileList + // ), - let appTypeCollection = getFormCollectionByID( - props.appealType.appealTypeID - ); - let updateBindAppealTypeToIncident = - appTypeCollection.NavigationProperty; + props.setNewAppealProgress( + getProgressObj( + formXML, + titleList, + mandatoryFieldsData, + props + ) + ); - Object.assign(updateBody, { - "pinswg_appealcasetype": props.appealType.appealTypeID, - "pinswg_Appellant@odata.bind": - "/contacts(" + props.props.accountDetails.loggedinUserId + ")", - "pinswg_name": props.appealType.caseReference.ticketnumber, - [updateBindAppealTypeToIncident + "@odata.bind"]: - "/incidents(" + incidentId + ")", - }); + let appTypeCollection = getFormCollectionByID( + props.appealType.appealTypeID + ); + let updateBindAppealTypeToIncident = + appTypeCollection.NavigationProperty; - updateBody = JSON.stringify(updateBody); - updateBody = updateBody.replace(/:"Yes"/gm, `:true`); - updateBody = updateBody.replace(/:"No"/gm, `:false`); - updateBody = JSON.parse(updateBody); + Object.assign(updateBody, { + "pinswg_appealcasetype": props.appealType.appealTypeID, + "pinswg_Appellant@odata.bind": + "/contacts(" + + props.props.accountDetails.loggedinUserId + + ")", + "pinswg_name": props.appealType.caseReference.ticketnumber, + [updateBindAppealTypeToIncident + "@odata.bind"]: + "/incidents(" + incidentId + ")", + }); - Object.keys(updateBody).forEach((key) => { - if (updateBody[key] === null) { - delete updateBody[key]; - } - if (key.indexOf("_") == 0) { - delete updateBody[key]; - } - }); + updateBody = JSON.stringify(updateBody); + updateBody = updateBody.replace(/:"Yes"/gm, `:true`); + updateBody = updateBody.replace(/:"No"/gm, `:false`); + updateBody = JSON.parse(updateBody); - //console.log(updateBody); + Object.keys(updateBody).forEach((key) => { + if (updateBody[key] === null) { + delete updateBody[key]; + } + if (key.indexOf("_") == 0) { + delete updateBody[key]; + } + }); - let updateFormCollection = appTypeCollection.LogicalCollectionName; - let primaryAttribute = appTypeCollection.PrimaryIdAttribute; + //console.log(updateBody); - const reference = "PEDW-PARTIAL"; - const templateId = "021b0a7b-df00-41f1-b94e-c269bee98c75"; - const templateIdCY = "f3c4a56b-bfb8-4d39-97dd-888df3062b0a"; - const emailAddress = props.props.accountDetails.loggedinUserEmail; - const personalisation = { - "caseReference": props.appealType.caseReference.ticketnumber, - "emailAddress": props.props.accountDetails.loggedinUserEmail, - "returnLink": - props.props.url + - (router.locale != "en" ? "/cy/fymhorth/" : "/myportal/") + - appTypeCollection.UrlName + - "?lpa=" + - props.appealType.appealLPA + - "&apt=" + - appTypeCollection.appealTypeID + - "&casereference=" + - props.appealType.caseReference.ticketnumber + - "&inid=" + - props.appealType.caseReference.incidentid, - "linkExpiry": 10 * 60, - }; + let updateFormCollection = + appTypeCollection.LogicalCollectionName; + let primaryAttribute = appTypeCollection.PrimaryIdAttribute; - // console.log( - // "/////////////////////////////////", - // "returnLink:", - // props.props.url + - // (router.locale != "en" ? "/cy/fymhorth/" : "/myportal/") + - // appTypeCollection.UrlName + - // "?lpa=" + - // props.appealType.appealLPA + - // "&apt=" + - // appTypeCollection.appealTypeID + - // "&casereference=" + - // props.appealType.caseReference.ticketnumber + - // "&inid=" + - // props.appealType.caseReference.incidentid, - // "/////////////////////////////////" - // ); + const reference = "PEDW-PARTIAL"; + const templateId = "021b0a7b-df00-41f1-b94e-c269bee98c75"; + const templateIdCY = "f3c4a56b-bfb8-4d39-97dd-888df3062b0a"; + const emailAddress = + props.props.accountDetails.loggedinUserEmail; + const personalisation = { + "caseReference": + props.appealType.caseReference.ticketnumber, + "emailAddress": + props.props.accountDetails.loggedinUserEmail, + "returnLink": + props.props.url + + (router.locale != "en" + ? "/cy/fymhorth/" + : "/myportal/") + + appTypeCollection.UrlName + + "?lpa=" + + props.appealType.appealLPA + + "&apt=" + + appTypeCollection.appealTypeID + + "&casereference=" + + props.appealType.caseReference.ticketnumber + + "&inid=" + + props.appealType.caseReference.incidentid, + "linkExpiry": 10 * 60, + }; - sendSavedEmail == true && - sendEmail( - router.locale != "en" ? templateIdCY : templateId, - emailAddress, - personalisation, - reference - ); + // console.log( + // "/////////////////////////////////", + // "returnLink:", + // props.props.url + + // (router.locale != "en" ? "/cy/fymhorth/" : "/myportal/") + + // appTypeCollection.UrlName + + // "?lpa=" + + // props.appealType.appealLPA + + // "&apt=" + + // appTypeCollection.appealTypeID + + // "&casereference=" + + // props.appealType.caseReference.ticketnumber + + // "&inid=" + + // props.appealType.caseReference.incidentid, + // "/////////////////////////////////" + // ); + }) + .then(() => { + sendSavedEmail == true && + sendEmail( + router.locale != "en" ? templateIdCY : templateId, + emailAddress, + personalisation, + reference + ); - useSaveStatus && - router.replace( - router.locale != "en" - ? "/" + router.locale + "/myportal" - : "/myportal" - ); + useSaveStatus && + router.replace( + router.locale != "en" + ? "/" + router.locale + "/myportal" + : "/myportal" + ); + }) + .then(() => { + setCompletedUploadFiles(true); + }); }; const onHandleSubmit = (values) => { @@ -335,9 +363,11 @@ let BuildSection = (props) => { delete valuesObj["_pinswg_appellant_value"]; //console.log("has errors:", props.invalid); - props.invalid == false && updateCaseProgress(valuesObj, false, false); - - setCurrentSection(currentSection + 1); + props.invalid == false && + updateCaseProgress(valuesObj, false, false).then((data) => { + console.log(data); + setCurrentSection(currentSection + 1); + }); }; const [hasErrors, setHasErrors] = useState(""); @@ -406,6 +436,16 @@ let BuildSection = (props) => { ); }; + const hasUploadFiles = () => { + const formArr = props.props.form["appealForm"].values; + const prefix = "pinswg_fileUpload"; + const hasFiles = Object.keys(formArr).some((key) => + key.startsWith(prefix) + ); + + return hasFiles; + }; + return (
@@ -429,6 +469,15 @@ let BuildSection = (props) => { onSubmit={onSubmit} mandatoryFieldsData={mandatoryFieldsData} props={props} + allFilesUploaded={allFilesUploaded} + setAllFilesuploaded={setAllFilesuploaded} + setFileCount={setFileCount} + setUploadCount={setUploadCount} + uploadCount={uploadCount} + completedUploadFilesCount={completedUploadFilesCount} + setCompletedUploadFilesCount={ + setCompletedUploadFilesCount + } />
@@ -523,13 +572,18 @@ let BuildSection = (props) => { )} {props.sectionCount == currentSection ? ( <> +
+ {showCompletedUploadFiles + ? "UPlodeding, pleas ewait " + : ""} +
{savingStatus ? ( @@ -655,6 +709,9 @@ const mapDispatchToProps = (dispatch) => { setNewAppealProgress: (progressObj) => { dispatch(setNewAppealProgress(progressObj)); }, + setFileCount: (fileCount) => { + dispatch(setFileCount(fileCount)); + }, }; }; diff --git a/components/utils/index.js b/components/utils/index.js index 7fe78f93..4b0276cb 100644 --- a/components/utils/index.js +++ b/components/utils/index.js @@ -506,7 +506,6 @@ export const getDetailsProxy = (resultsObj, detailsType) => { export const getDocumentTypeFromFilename = (filename) => { var doctypeCode = "000000"; - console.log(filename); if (typeof filename != "undefined") { if (filename.indexOf("_-_Statement_of_Case") > 0) diff --git a/data/formsxml/planningappeals78.xml b/data/formsxml/planningappeals78.xml index 152b63bf..ba1c3d05 100644 --- a/data/formsxml/planningappeals78.xml +++ b/data/formsxml/planningappeals78.xml @@ -146,7 +146,7 @@ - @@ -158,7 +158,7 @@ - diff --git a/locales/cy/myrepresentations.json b/locales/cy/myrepresentations.json index 15aed4c3..e0b6dcfc 100644 --- a/locales/cy/myrepresentations.json +++ b/locales/cy/myrepresentations.json @@ -14,15 +14,15 @@ "representation-from-an-appellant-heading": "Sylwadau gan Apelydd", "representation-from-an-interested-person-heading": "Sylwadau gan Barti/Unigolyn â Buddiant", "kind-of-rep-label": "Pa fath o sylw ydych chi'n ei wneud?", - "enter-comment-label": "Gallwch nodi eich sylwadau yn y gofod a ddarperir neu atodi dogfen ar wahân.", + "enter-comment-label": "Gallwch roi eich cynrychioliad yn y gofod a ddarparwyd neu atodi dogfen ar wahân.", "comments-set-out-label": "Mae fy sylwadau wedi'u nodi yn", "publish-policy-label": "Sylwch y gallai'r holl sylwadau gael eu cyhoeddi yn unol â'n Polisi Cyhoeddi. Os bydd eich sylw yn cynnwys unrhyw wybodaeth sensitif neu wybodaeth a allai fod yn ddifenwol, efallai y caiff ei olygu cyn ei gyhoeddi. Os yw'n cynnwys deunydd hiliol, enllibus neu sarhaus, caiff ei ddychwelyd atoch a gofynnir i chi ddarparu fersiwn ddiwygiedig.", "questionnaire-publish-policy-label": "Sylwch y gallai'r holl ddogfennau holiadur gael eu cyhoeddi yn unol â'n Polisi Cyhoeddi. Os bydd eich holiadur yn cynnwys unrhyw wybodaeth sensitif neu wybodaeth a allai fod yn ddifenwol, efallai y caiff ei olygu cyn ei gyhoeddi", "add-files-label": "Ychwanegwch eich ffeiliau", "fileupload-drop-label": "Llusgwch a gollyngwch eich ffeiliau yma.", "fileupload-file-list-label": "Dim ond ffeiliau .pdf, .doc, .docx, .xlsx, .tif, .tiff, .jpeg, .jpg neu .zip a dderbynnir", - "capacity-para-one": "Mae'r ffurflen hon yn eich galluogi i gyflwyno sylwadau ar achos i Benderfyniadau Cynllunio ac Amgylchedd Cymru.", - "capacity-para-two": "Sylwch fod angen i bartïon â buddiant wneud sylwadau o fewn yr amserlen. Mae'r amserlen i'w gweld ar y dudalen \"Crynodeb o'r Achos\". Gallai sylwadau a gyflwynir ar ôl y dyddiad hwn gael eu hystyried yn annilys.", + "capacity-para-one": "Mae'r ffurflen hon yn eich galluogi i gyflwyno sylwadau ar achos i Benderfyniadau Cynllunio ac Amgylchedd Cymru", + "capacity-para-two": "Sylwch fod angen cyflwyno sylwadau gan bartïon â diddordeb o fewn yr amserlen. Mae hwn i'w weld ar y dudalen \"Crynodeb Achos\" flaenorol. Gall sylwadau a gyflwynir ar ôl y dyddiad hwn gael eu hystyried yn annilys.", "capacity-select-your-details": "Eich manylion", "capacity-select-what-capacity-label": "Ym mha rinwedd ydych chi am gyflwyno sylwadau ar yr achos hwn?", "capacity-options-arr-appellant": "Apelydd", diff --git a/locales/en/case.json b/locales/en/case.json index 848635bf..531d5f51 100644 --- a/locales/en/case.json +++ b/locales/en/case.json @@ -86,7 +86,7 @@ "representation-representation-type": "What kind of representation are you making?", "representation-onbehalfof": "Are you acting on behalf of a company, group or organisation", "representation-onbehalfof-details": "Name of the company/group/organisation", - "representation-comments": "Comments", + "representation-comments": "Representation", "representation-files": "Relevant files", "representation-period-ended-on-label": "Representation Period ended on ", "stop-watching-case-link": "Stop watching this case", diff --git a/locales/en/myrepresentations.json b/locales/en/myrepresentations.json index 7f5aca3c..240e9ac8 100644 --- a/locales/en/myrepresentations.json +++ b/locales/en/myrepresentations.json @@ -14,15 +14,15 @@ "representation-from-an-appellant-heading": "Representation from an Appellant", "representation-from-an-interested-person-heading": "Representation from an Interested Party/Person", "kind-of-rep-label": "What kind of representation are you making?", - "enter-comment-label": "You can enter your comments in the space provided or attach a separate document.", + "enter-comment-label": "You can enter your representation in the space provided or attach a separate document.", "comments-set-out-label": "My comments are set out in", "publish-policy-label": "Please note that all representations may be published in line with our Publishing Policy. Should your representation include any sensitive information or potentially defamatory information, it may be redacted before publishing. If it contains racist, libellous or offensive content it will be returned to you and you will be asked to provide an amended version.", "questionnaire-publish-policy-label": "Please note that all questionnaire documents may be published in line with our Publishing Policy. Should your questionnaire include any sensitive information or potentially defamatory information, it may be redacted before publishing", "add-files-label": "Add your files", "fileupload-drop-label": "Drag and drop your files here.", "fileupload-file-list-label": "Only .pdf, .doc, .docx, .xlsx, .tif, .tiff, .jpeg, .jpg or .zip files will be accepted", - "capacity-para-one": "This form enables you to submit comments on a case to Planning and Environment Decisions Wales.", - "capacity-para-two": "Please note that comments from interested parties need to be made within the timetable. This can be found on the previous \"Case Summary\" page. Comments submitted after this date may be considered invalid.", + "capacity-para-one": "This form enables you to submit representations on a case to Planning and Environment Decisions Wales.", + "capacity-para-two": "Please note that representations from interested parties need to be made within the timetable. This can be found on the previous \"Case Summary\" page. Comments submitted after this date may be considered invalid.", "capacity-select-your-details": "Your details", "capacity-select-what-capacity-label": "In what capacity do you wish to make representations on this case?", "capacity-options-arr-appellant": "Appellant", @@ -211,7 +211,7 @@ "statement-statement-label": "Statement", "statement-list-of-attached-files-label": "List of attached files", "statement-supporting-documents-header": "Supporting documents", - "statement-comments-header": "Comments", + "statement-comments-header": "Representation", "statement-case-details-header": "Case details", "statement-declaration-header": "Declaration", "statement-signed-label": "Signed", diff --git a/locales/en/newappeal.json b/locales/en/newappeal.json index 1c6b73ce..c50f2ff9 100644 --- a/locales/en/newappeal.json +++ b/locales/en/newappeal.json @@ -65,7 +65,7 @@ "new-appeal-introduction-warning-bullet-two": "provide all essential supporting documents within the appeal period", "new-appeal-development-description-hint": "Enter details of the proposed development from the planning application form. If the application was revised while it was with the LPA enter details of the revised scheme and enclose a copy of the LPA’s agreement to the change.", "new-appeal-dateofapplication-hint": "This is the date that you submitted the original application to the local planning authority. This form is not able to process appeals with application dates older than five years. If your application was made more than five years ago then please contact the office for help.", - "new-appeal-dateoflpadecision-hint": "This is the date that the LPA issued their decision on your application. Please note, this is not the date you received the decision, rather the date written on the decision. This form in not able to process appeals with a decision date older than 6 months. If your decision was issued more than 6 months ago then you may have run out of time to appeal. Please contact the office for help.", + "new-appeal-dateoflpadecision-hint": "This is the date that the LPA issued their decision on your application. Please note, this is not the date you received the decision, rather the date written on the decision. This form is not able to process appeals with a decision date older than 6 months. If your decision was issued more than 6 months ago then you may have run out of time to appeal. Please contact the office for help.", "new-appeal-ownership-hint": "We need to know who owns the appeal site or part of it, and that all owners know you have made an appeal. Use the guidance notes to complete this section.", "new-appeal-ownership-option-NA": "Not applicable", "new-appeal-ownership-option-A": "Certificate A - (for sole owners of the appeal site). I certify that, on the day 21 days before the date of this appeal, nobody except the appellant, was the owner (see the guidance leaflet for a definition) of any part of the land to which the appeal relates", diff --git a/pages/api/file/upload.js b/pages/api/file/upload.js index d5e20f05..6bd36e0e 100644 --- a/pages/api/file/upload.js +++ b/pages/api/file/upload.js @@ -32,18 +32,26 @@ ApiProxy.post(async (req, res) => { //createContainer(containerID).then((containerName) => { console.log("does this get folder name:", containerID, casefolderID); + repOrAppeal ? createRepBlob(appealData, containerID, casefolderID).then((data) => { Object.keys(req.files).length > 0 && - uploadFile(req.files, containerID, casefolderID); + uploadFile(req.files, containerID, casefolderID).then( + (data) => { + return res.status(200).json({ data }); + } + ); }) : createBlob(appealData, containerID, casefolderID).then((data) => { Object.keys(req.files).length > 0 && - uploadFile(req.files, containerID, casefolderID); + uploadFile(req.files, containerID, casefolderID).then( + (data) => { + return res.status(200).json({ data }); + } + ); }); //}); - return res.status(200).json({ data: "success" }); // } else { // return res.status(400).json(); // } diff --git a/pages/api/file/uploadsinglefile.js b/pages/api/file/uploadsinglefile.js new file mode 100644 index 00000000..fd349f1a --- /dev/null +++ b/pages/api/file/uploadsinglefile.js @@ -0,0 +1,51 @@ +import { + createBlob, + createRepBlob, + uploadSingleFile, +} from "../../../actions/azurestorage"; + +import nextConnect from "next-connect"; +import middleware from "../middleware/middleware"; + +const ApiProxy = nextConnect(); +ApiProxy.use(middleware); + +ApiProxy.post(async (req, res) => { + var checkHash = req.query.hash; + console.log(JSON.stringify(req.body)); + console.log(JSON.stringify(req.body.appealData)); + console.log(req.files); + + const containerID = req.body.containerID[0]; + const casefolderID = req.body.casefolderID[0]; + + console.log("there are files:", Object.keys(req.files).length); + + // var checkquerypath = "/api/file/upload"; + + //console.log(hashAPIPath(checkquerypath), checkHash); + //console.log(hashAPIPath(checkquerypath) == "?hash=" + checkHash); + + // if (hashAPIPath(checkquerypath) == "?hash=" + checkHash) { + //createContainer(containerID).then((containerName) => { + + console.log("does this get folder name:", containerID, casefolderID); + + uploadSingleFile(req.files, containerID, casefolderID).then((data) => { + return res.status(200).json({ data }); + }); + + //}); + + // } else { + // return res.status(400).json(); + // } +}); + +export const config = { + api: { + bodyParser: false, + }, +}; + +export default ApiProxy; diff --git a/store/appealType/action.js b/store/appealType/action.js index 1f9a6037..34ba914e 100644 --- a/store/appealType/action.js +++ b/store/appealType/action.js @@ -11,6 +11,7 @@ export const appealTypeDataActionTypes = { SETDOCUMENTLIST: "SETDOCUMENTLIST", SETFILELIST: "SETFILELIST", SETNEWAPPEALPROGRESS: "SETNEWAPPEALPROGRESS", + SETFILECOUNT: "SETFILECOUNT", }; export const getAppealTypeObj = () => (dispatch) => { @@ -86,3 +87,10 @@ export const setNewAppealProgress = (progress) => (dispatch) => { progress: progress, }); }; + +export const setFileCount = (fileCount) => (dispatch) => { + return dispatch({ + type: appealTypeDataActionTypes.SETFILECOUNT, + fileCount: fileCount, + }); +}; diff --git a/store/appealType/reducer.js b/store/appealType/reducer.js index 060cf079..1cea7576 100644 --- a/store/appealType/reducer.js +++ b/store/appealType/reducer.js @@ -10,6 +10,7 @@ const appealTypeDataInitialState = { formComplete: "false", documentList: {}, fileList: [], + fileCount: 0, progress: [], }; @@ -60,6 +61,11 @@ export default function reducer(state = appealTypeDataInitialState, action) { ...state, fileList: action.fileList, }; + case appealTypeDataActionTypes.SETFILECOUNT: + return { + ...state, + fileCount: action.fileCount, + }; case appealTypeDataActionTypes.SETNEWAPPEALPROGRESS: return { ...state,