Merged PR 2068: Set portal to readonly

Related work items: #21227
This commit is contained in:
Robert Bond
2026-01-30 10:24:07 +00:00
9 changed files with 329 additions and 190 deletions
+1
View File
@@ -41,6 +41,7 @@ const Case = (props) => {
docsOffline={props.props.docsOffline}
documentDetailsObj={props.documentDetailsObj}
showFilteredDocs={props.showFilteredDocs}
showLoginCheck={props.showLoginCheck}
/>
{showRepresentations == true && (
<RepresentationList
+78 -72
View File
@@ -88,8 +88,10 @@ const CaseSummary = (props) => {
ticketnumber,
} = props;
const showLoginCheck =
currentType == "directResultsObj" ? "true" : currentView.showLogin;
// const showLoginCheck =
// currentType == "directResultsObj" ? "true" : currentView.showLogin;
let showLoginCheck = props.showLoginCheck;
const { data: session, status } = useSession();
const [isModalOpen, setIsModalOpen] = useState(false);
@@ -154,10 +156,10 @@ const CaseSummary = (props) => {
.then((data) => data)
.then(() => {
getWatchedCasesProxy(loggedInUser).then((data) => {
setWatchedCases(data),
(setWatchedCases(data),
getDetailsProxy(data, "myWatchedCases").then((data) => {
setWatchedCasesDetails(data);
});
}));
});
});
@@ -184,12 +186,12 @@ const CaseSummary = (props) => {
.then((data) => data)
.then(() => {
getWatchedCasesProxy(cookies.pinsUser).then((data) => {
setWatchedCases(data),
(setWatchedCases(data),
getDetailsProxy(data, "myWatchedCases").then(
(data) => {
setWatchedCasesDetails(data);
}
);
},
));
});
});
};
@@ -295,16 +297,18 @@ const CaseSummary = (props) => {
{getFormCollectionByID(
appealTypeID ||
setCaseQueryObj.value[0]
.pinswg_appealcasetype
.pinswg_appealcasetype,
).PrimaryIdAttribute == "pinswg_dnsid"
? t("case:summary-applicantonly-label")
: getFormCollectionByID(
appealTypeID ||
setCaseQueryObj.value[0]
.pinswg_appealcasetype
.pinswg_appealcasetype,
).PrimaryIdAttribute ==
"pinswg_nonvalidationid"
? t("case:summary-appellantonly-label")
? t(
"case:summary-appellantonly-label",
)
: t("case:summary-applicant-label")}
</dt>
<dd className="govuk-summary-list__value">
@@ -320,7 +324,7 @@ const CaseSummary = (props) => {
{detailsObj.pinswg_agentcontactname != null &&
(_.has(
detailsObj,
"pinswg_agentcontactname"
"pinswg_agentcontactname",
) ? (
<div className="govuk-summary-list__row">
<dt className="govuk-summary-list__key">
@@ -329,7 +333,7 @@ const CaseSummary = (props) => {
<dd className="govuk-summary-list__value">
{_.has(
detailsObj,
"pinswg_agentcontactname"
"pinswg_agentcontactname",
)
? detailsObj.pinswg_agentcontactname
: ""}
@@ -346,44 +350,44 @@ const CaseSummary = (props) => {
{getFormCollectionByID(
appealTypeID ||
setCaseQueryObj.value[0]
.pinswg_appealcasetype
.pinswg_appealcasetype,
).PrimaryIdAttribute == "pinswg_dnsid"
? detailsObj.pinswg_projectlocation !=
null
? detailsObj.pinswg_projectlocation.indexOf(
";"
";",
) < 0
? detailsObj.pinswg_projectlocation
: router.locale == "cy"
? detailsObj.pinswg_projectlocation.split(
";"
";",
)[1]
: detailsObj.pinswg_projectlocation.split(
";"
";",
)[0]
: ""
: ""}
{_.has(
detailsObj,
"pinswg_siteaddressline1"
"pinswg_siteaddressline1",
)
? detailsObj.pinswg_siteaddressline1
: ""}
{_.has(
detailsObj,
"pinswg_siteaddressline1"
"pinswg_siteaddressline1",
) &&
detailsObj.pinswg_siteaddressline1 !=
null && <br />}
{_.has(
detailsObj,
"pinswg_siteaddressline2"
"pinswg_siteaddressline2",
)
? detailsObj.pinswg_siteaddressline2
: ""}
{_.has(
detailsObj,
"pinswg_siteaddressline2"
"pinswg_siteaddressline2",
) &&
detailsObj.pinswg_siteaddressline2 !=
null && <br />}
@@ -392,25 +396,25 @@ const CaseSummary = (props) => {
: ""}
{_.has(
detailsObj,
"pinswg_siteaddresstown"
"pinswg_siteaddresstown",
) &&
detailsObj.pinswg_siteaddresstown !=
null && <br />}
{_.has(
detailsObj,
"pinswg_siteaddresscounty"
"pinswg_siteaddresscounty",
)
? detailsObj.pinswg_siteaddresscounty
: ""}
{_.has(
detailsObj,
"pinswg_siteaddresscounty"
"pinswg_siteaddresscounty",
) &&
detailsObj.pinswg_siteaddresscounty !=
null && <br />}
{_.has(
detailsObj,
"pinswg_siteaddresspostcode"
"pinswg_siteaddresspostcode",
)
? detailsObj.pinswg_siteaddresspostcode
: ""}
@@ -425,9 +429,11 @@ const CaseSummary = (props) => {
{casesObj.description.indexOf(";") < 0
? casesObj.description
: router.locale == "cy"
? casesObj.description.split(";")[1]
? casesObj.description.split(
";",
)[1]
: casesObj.description.split(
";"
";",
)[0]}
</dd>
</div>
@@ -453,7 +459,7 @@ const CaseSummary = (props) => {
"pinswg_casestage@OData.Community.Display.V1.FormattedValue"
] ||
t(
"case:summary-no-date-entered-label"
"case:summary-no-date-entered-label",
)}
</dd>
</div>
@@ -480,24 +486,24 @@ const CaseSummary = (props) => {
{(_.has(detailsObj, "pinswg_startdate") ||
_.has(
detailsObj,
"pinswg_applicationacceptedasvalid"
"pinswg_applicationacceptedasvalid",
) ||
_.has(
detailsObj,
"pinswg_startdates"
"pinswg_startdates",
)) &&
showReps(
detailsObj.pinswg_startdate ||
detailsObj.pinswg_startdates ||
detailsObj.pinswg_applicationacceptedasvalid,
detailsObj.pinswg_finalcommentsduedate ||
detailsObj.pinswg_endofrepresentationperiod
detailsObj.pinswg_endofrepresentationperiod,
) && (
<>
{showRepButton(
props.currentView
.caseReference
.appealType
.appealType,
) ? (
<>
{ShowDocLinks ? (
@@ -513,7 +519,7 @@ const CaseSummary = (props) => {
Notice
</span>
{t(
"case:docsoffline-reps-label"
"case:docsoffline-reps-label",
)}
</strong>
</div>
@@ -539,7 +545,7 @@ const CaseSummary = (props) => {
className="govuk-button"
>
{t(
"case:summary-make-representation-label"
"case:summary-make-representation-label",
)}
</Link>
)}
@@ -551,7 +557,7 @@ const CaseSummary = (props) => {
className="govuk-button govuk-button--secondary"
>
{t(
"case:summary-back-button-label"
"case:summary-back-button-label",
)}
</a>
</>
@@ -571,7 +577,7 @@ const CaseSummary = (props) => {
{
startDate:
formatDates(
detailsObj.pinswg_startdate
detailsObj.pinswg_startdate,
),
endDate:
props
@@ -580,27 +586,27 @@ const CaseSummary = (props) => {
.appealType ==
846040019
? formatDates(
detailsObj.pinswg_statementduedate
detailsObj.pinswg_statementduedate,
)
: formatDates(
detailsObj.pinswg_finalcommentsduedate
detailsObj.pinswg_finalcommentsduedate,
),
}
},
)}
<br />{" "}
{t(
"case:representation-date-passed-additional-label"
"case:representation-date-passed-additional-label",
)}{" "}
<Link
href={
"mailto:" +
t(
"home:login-contact-email"
"home:login-contact-email",
)
}
>
{t(
"home:login-contact-email"
"home:login-contact-email",
)}
</Link>
</p>
@@ -614,40 +620,40 @@ const CaseSummary = (props) => {
{session &&
(isWatchedCase(
props.currentView.caseReference
.incidentid
.incidentid,
).length >
0 ==
true ? (
<button
className="govuk-link watchCase"
onClick={() => {
confirm(
(confirm(
t(
"case:you-have-stopped-watching-label"
"case:you-have-stopped-watching-label",
) +
props
.currentView
.caseReference
.currentReference +
"?"
"?",
) &&
deleteItem(
isWatchedCase(
props
.currentView
.caseReference
.incidentid
.incidentid,
)[0]
.pinswg_watchlistid,
"watchedCases"
"watchedCases",
),
setCurrentView({
"viewName":
"Watched Cases",
"viewKey":
"watchedCases",
});
}));
setCurrentReference({
"ticketnumber":
props
@@ -675,11 +681,11 @@ const CaseSummary = (props) => {
});
}}
title={t(
"case:stop-watching-case-link"
"case:stop-watching-case-link",
)}
>
{t(
"case:stop-watching-case-link"
"case:stop-watching-case-link",
)}{" "}
</button>
) : (
@@ -689,14 +695,14 @@ const CaseSummary = (props) => {
onClick={() => {
confirm(
t(
"case:you-are-watching-label"
"case:you-are-watching-label",
) +
" " +
props
.currentView
.caseReference
.currentReference +
"?"
"?",
) &&
selectWatchedCase(
props
@@ -709,12 +715,12 @@ const CaseSummary = (props) => {
props
.currentView
.caseReference
.appealType
.appealType,
);
}}
>
{t(
"case:watch-this-case-link"
"case:watch-this-case-link",
)}
</button>
{/* <button
@@ -732,13 +738,13 @@ const CaseSummary = (props) => {
<button
className="govuk-link watchCase"
onClick={() => {
confirm(
(confirm(
"Trying to watch case " +
props
.currentView
.caseReference
.currentReference +
"\n\nYou will now be prompted to sign in"
"\n\nYou will now be prompted to sign in",
) &&
// signIn("email", {
// callbackUrl:
@@ -763,16 +769,16 @@ const CaseSummary = (props) => {
path: "/",
expires:
expDate,
}
},
),
signIn();
signIn());
}}
title={t(
"case:watch-this-case-link"
"case:watch-this-case-link",
)}
>
{t(
"case:watch-this-case-link"
"case:watch-this-case-link",
)}
</button>
{/* <button
@@ -794,19 +800,19 @@ const CaseSummary = (props) => {
null) &&
showRepsEnded(
detailsObj.pinswg_startdate,
detailsObj.pinswg_finalcommentsduedate
detailsObj.pinswg_finalcommentsduedate,
) && (
<div className="govuk-body">
{t(
"case:representation-period-ended-on-label"
"case:representation-period-ended-on-label",
)}
{props.currentView.caseReference
.appealType == 846040019
? formatDates(
detailsObj.pinswg_statementduedate
detailsObj.pinswg_statementduedate,
)
: formatDates(
detailsObj.pinswg_finalcommentsduedate
detailsObj.pinswg_finalcommentsduedate,
)}
</div>
)}
@@ -844,12 +850,12 @@ const CaseSummary = (props) => {
</div>
</div>
</div>
{showLoginCheck == "true" && (
{(showLoginCheck === "true" || showLoginCheck === true) && (
<div className="govuk-grid-row">
<div className="govuk-grid-column-full">
<div className="govuk-button-group">
{noRepresentationLink.includes(
router.pathname
router.pathname,
) == true ? (
""
) : ShowDocLinks ? (
@@ -874,7 +880,7 @@ const CaseSummary = (props) => {
className="govuk-button"
>
{t(
"case:summary-make-representation-label"
"case:summary-make-representation-label",
)}
</Link>
</div>
@@ -898,7 +904,7 @@ const CaseSummary = (props) => {
function showSummary(casesObj, detailsObj) {
let appealIDObj = getFormCollectionByID(
appealTypeID || setCaseQueryObj.value[0].pinswg_appealcasetype
appealTypeID || setCaseQueryObj.value[0].pinswg_appealcasetype,
).PrimaryIdAttribute;
switch (appealIDObj) {
@@ -1187,7 +1193,7 @@ const CaseSummary = (props) => {
useEffect(() => {
const linkCaseObj = async () => {
let docObj = await getLinkedCases(
incidentid || setCaseQueryObj.value[0].incidentid
incidentid || setCaseQueryObj.value[0].incidentid,
).then((data) => {
//console.log(data);
setCurrentLinkedCases(data);
@@ -1286,7 +1292,7 @@ const CaseSummary = (props) => {
? showReps(
props.searchDetailsObj[0].value[0].pinswg_startdate,
props.searchDetailsObj[0].value[0]
.pinswg_finalcommentsduedate
.pinswg_finalcommentsduedate,
)
: true;
@@ -1305,7 +1311,7 @@ const CaseSummary = (props) => {
case 846040019:
return showReps(
props.searchDetailsObj[0].value[0].pinswg_startdate,
props.searchDetailsObj[0].value[0].pinswg_statementduedate
props.searchDetailsObj[0].value[0].pinswg_statementduedate,
);
default:
@@ -1325,7 +1331,7 @@ const CaseSummary = (props) => {
selectWatchedCase(
props.accountDetails.accountDetails.contactid,
incidentid,
appealTypeID
appealTypeID,
);
destroyCookie({}, "pedwWatchCase", { path: "/" });
}
+5 -4
View File
@@ -53,6 +53,7 @@ const Header = (props) => {
"/myportal/advancedsearch",
"/myportal/advancedsearchresults",
"/myportal/case/[ticketnumber]",
"/status",
];
const hasContactLink = [
@@ -73,14 +74,14 @@ const Header = (props) => {
const handleLogout = () => {
console.info("////////////\n" + "logout" + "\n////////////");
window.localStorage.clear(),
(window.localStorage.clear(),
destroyCookie(null, "next-auth.csrf-token", { path: "/" }),
destroyCookie(null, "next-auth.callback-url", { path: "/" }),
destroyCookie(null, "pedw_locale", { path: "/" }),
destroyCookie(null, "pinsUser", { path: "/" }),
signOut({
callbackUrl: locale == "cy" ? "/cy/allgofnodi" : "/logout",
});
}));
};
return (
@@ -242,7 +243,7 @@ const Header = (props) => {
Object.keys(router.query)
.map(
(key) =>
key + "=" + router.query[key]
key + "=" + router.query[key],
)
.join("&")
: router.pathname
@@ -268,7 +269,7 @@ const Header = (props) => {
locale == "en" ? "cy" : "en",
{
path: "/",
}
},
);
}}
>
+1 -10
View File
@@ -22,18 +22,9 @@ const MainHome = (props) => {
<div className="govuk-grid-row">
<div className="govuk-grid-column-full">
<div className="flex-container grid-row govuk-body ">
{showLogin != "true" && (
<>
<LoginSoon />
<CaseSearch />
</>
)}
{showLogin == "true" && (
<>
<CaseSearch />
<Login session={session} siteurl={siteurl} />
</>
)}{" "}
{/* <CaseComment /> */}
{/* <Dns /> */}
</div>
+75 -3
View File
@@ -1,20 +1,28 @@
import useTranslation from "next-translate/useTranslation";
import router from "next/router";
import Link from "next/link";
import CaseNoticeBanner from "./case/caseNoticeBanner";
export default function ServiceBanner(props) {
let { t, lang } = useTranslation();
const showSigninFromEnv = false;
const showNoticeFromEnv = true;
// keep backwards-compat with existing usage
const showSignin = props?.noSignin === true ? false : showSigninFromEnv;
const signInButton = () => {
router.push(
`${
router.locale == "cy" ? "/awd/mewngofnodi" : "/auth/signin"
}?callbackUrl=${encodeURIComponent(
window.location.href
)}&error=EmailSignin`
window.location.href,
)}&error=EmailSignin`,
);
};
return (
<>
<div className="servicebanner">
<h1>
<img
@@ -31,7 +39,8 @@ export default function ServiceBanner(props) {
alt="Planning casework"
/>
</h1>
{props.noSignin != true && (
{showSignin && props.noSignin != true && (
<div className="serviceBanner_userDetails">
<button
onClick={() => signInButton()}
@@ -42,5 +51,68 @@ export default function ServiceBanner(props) {
</div>
)}
</div>
{showNoticeFromEnv && (
<div>
<div
className="govuk-warning-text noticebanner govuk-!-margin-bottom-0"
key={1}
>
<strong className="govuk-warning-text__text">
<span className="govuk-visually-hidden">
Announcement
</span>
</strong>
<div>
<div className=" govuk-body-s">
<h2 className="govuk-heading-s">
{router.locale == "cy"
? "Cyhoeddiad"
: "Announcement"}
</h2>
</div>
<div className="govuk-body-s">
{router.locale == "cy" ? (
<>
<p>
Oherwydd gwaith cynnal a chadw
hanfodol, rydym yn disgwyl rhywfaint
o darfu ar ein gwasanaethau Porth
Gwaith Achos rhwng 9-13 Chwefror
2026.{" "}
</p>
<p>
Ymddiheurwn am yr anghyfleustra. Am
ymholiadau brys yn ystod y cyfnod
hwn, cysylltwch â{" "}
<a href="mailto:pedw.gwaithachos@llyw.cymru">
pedw.gwaithachos@llyw.cymru
</a>
</p>
</>
) : (
<>
<p>
Due to essential maintenance, we are
expecting some disruption to our
Casework Portal services between
9-13 February 2026.
</p>
<p>
We apologise for the inconvenience.
For urgent enquries during this time
please contact{" "}
<a href="mailto:pedw.casework@gov.wales">
pedw.casework@gov.wales
</a>
</p>
</>
)}
</div>
</div>
</div>
</div>
)}
</>
);
}
+10 -8
View File
@@ -53,7 +53,9 @@ const SignIn = (props) => {
<div className="govuk-body-m">
<legend className="govuk-fieldset__legend govuk-fieldset__legend--l">
<h1 className="govuk-fieldset__heading govuk-heading-m">
{t("auth:auth-page-title")}{" "}
{t(
"auth:auth-page-title",
)}{" "}
</h1>
</legend>
@@ -91,7 +93,7 @@ const SignIn = (props) => {
htmlFor="email"
>
{t(
"auth:auth-email-label"
"auth:auth-email-label",
)}
</label>
@@ -111,7 +113,7 @@ const SignIn = (props) => {
}
>
{t(
"auth:auth-signin-button-label"
"auth:auth-signin-button-label",
)}
</button>
</div>
@@ -132,10 +134,10 @@ const SignIn = (props) => {
};
export async function getServerSideProps(context) {
if (process.env.SHOWLOGIN == false) {
if (process.env.SHOWLOGIN === "false" || process.env.SHOWLOGIN === false) {
return {
redirect: {
destination: "/404",
destination: "/status",
permanent: false,
},
};
@@ -146,7 +148,7 @@ export async function getServerSideProps(context) {
"\n//////////////////////\n",
"Sign in callbackurl: " + context.query.callbackUrl,
context.locale,
"\n//////////////////////\n"
"\n//////////////////////\n",
);
let formURL = context.req.headers.host;
//console.log("formUrl:", formURL);
@@ -176,7 +178,7 @@ export async function getServerSideProps(context) {
// Append the query parameters to the new URL
params.forEach((value, key) =>
toUrlObj.searchParams.append(key, value)
toUrlObj.searchParams.append(key, value),
);
return toUrlObj.toString(); // Return the full new URL as a string
@@ -185,7 +187,7 @@ export async function getServerSideProps(context) {
typeof context.query.callbackUrl != "undefined" &&
(formURL = appendParamsAndPathToNewUrl(
context.query.callbackUrl,
formURL
formURL,
));
//formURL = appendParamsAndPathToNewUrl(context.query.callbackUrl, formURL);
+3 -3
View File
@@ -236,10 +236,10 @@ export async function getServerSideProps(context) {
};
}
if (process.env.SHOWLOGIN == false) {
if (process.env.SHOWLOGIN === "false" || process.env.SHOWLOGIN === false) {
return {
redirect: {
destination: "/404",
destination: "/status",
permanent: false,
},
};
@@ -250,7 +250,7 @@ export async function getServerSideProps(context) {
"\n//////////////////////\n",
"Sign in callbackurl: " + context.req.headers.host,
context.locale,
csrfToken + "\n//////////////////////\n"
csrfToken + "\n//////////////////////\n",
);
let formURL = context.req.headers.host;
console.log("formUrl:", formURL);
+6 -5
View File
@@ -102,7 +102,7 @@ const CaseHome = (props) => {
representationsObj={
props.searchResultsObj.representationsObj
}
showLoginCheck={true}
showLoginCheck={props.showLoginCheck}
messagesObj={props.messagesObj}
showFilteredDocs={props.showFilteredDocs}
showMaps={props.showMaps}
@@ -170,7 +170,7 @@ export const getServerSideProps = wrapper.getServerSideProps(
console.log(
searchResultsObj["@odata.count"] > 1 ||
searchResultsObj["@odata.count"] < 1
searchResultsObj["@odata.count"] < 1,
);
if (searchResultsObj["@odata.count"] < 1) {
@@ -211,7 +211,7 @@ export const getServerSideProps = wrapper.getServerSideProps(
searchDetailsObj[0].value[0]
.pinswg_specialistcaseprocess
: "",
})
}),
);
}
}
@@ -225,13 +225,14 @@ export const getServerSideProps = wrapper.getServerSideProps(
currentType: "directResultsObj",
docsOffline: process.env.DOCAPI_OFFLINE || false,
messagesObj: await getCaseMessage(
searchResultsObj.value[0].incidentid
searchResultsObj.value[0].incidentid,
),
showFilteredDocs: process.env.SHOWFILTERDOCS || false,
showMaps: process.env.SHOWMAPS,
showLoginCheck: process.env.SHOWLOGIIN || true,
},
};
}
},
);
const mapStateToProps = (state) => {
+70 -5
View File
@@ -1,28 +1,93 @@
import useTranslation from "next-translate/useTranslation";
import Head from "next/head";
import CookieBanner from "../components/cookieBanner";
import Header from "../components/header";
import Footer from "../components/footer";
import router from "next/router";
const FourOhFour = (props) => {
const StatusPage = (props) => {
let { t, lang } = useTranslation();
const { footerLinks, pages } = props;
return (
<div>
<Head>
<title>Status Up</title>
<title>Site Status</title>
</Head>
<div id="page_wrapper">
<CookieBanner />
<Header />
<div className="govuk-width-container govuk-!-padding-bottom-9">
<main className="govuk-main-wrapper govuk-!-padding-top-9 govuk-!-padding-bottom-9">
<div className="govuk-grid-row">
<div className="govuk-grid-column-two-thirds ">
<h1>Status Up</h1>
<div
className="govuk-warning-text noticebanner govuk-!-margin-bottom-0"
key={1}
>
<strong className="govuk-warning-text__text">
<span className="govuk-visually-hidden">
Announcement
</span>
</strong>
<div>
<div className=" govuk-body-s">
<h2 className="govuk-heading-s">
{router.locale == "cy"
? "Cyhoeddiad"
: "Announcement"}
</h2>
</div>
<div className="govuk-body-s">
{router.locale == "cy" ? (
<>
<p>
Oherwydd gwaith cynnal a
chadw hanfodol, rydym yn
disgwyl rhywfaint o darfu ar
ein gwasanaethau Porth
Gwaith Achos rhwng 9-13
Chwefror 2026.{" "}
</p>
<p>
Ymddiheurwn am yr
anghyfleustra. Am ymholiadau
brys yn ystod y cyfnod hwn,
cysylltwch â{" "}
<a href="mailto:pedw.gwaithachos@llyw.cymru">
pedw.gwaithachos@llyw.cymru
</a>
</p>
</>
) : (
<>
<p>
Due to essential
maintenance, we are
expecting some disruption to
our Casework Portal services
between 9-13 February 2026.
</p>
<p>
We apologise for the
inconvenience. For urgent
enquries during this time
please contact{" "}
<a href="mailto:pedw.casework@gov.wales">
pedw.casework@gov.wales
</a>
</p>
</>
)}
</div>
</div>
</div>
</div>
</main>
</div>
<Footer footerLinks={footerLinks} ticketnumber={props} />
</div>
</div>
);
};
export default FourOhFour;
export default StatusPage;