Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
ccd46f6
GA-203 track the `mo-new-cases` feature toggle key to hide or show th…
Mar 14, 2024
2a5b7a7
Create a cases page for the new cases flow
Mar 14, 2024
2069060
WIP cases container component
Mar 14, 2024
f841255
GA-206 Add cases filter component
Mar 15, 2024
09ba297
GA-206 track and populate filter selection from session storage
Mar 15, 2024
9e1ff08
WIP: create a results table component to display case data
Mar 18, 2024
3802e24
WIP Add new route for case sharing and update filter type enum
Mar 20, 2024
dd0adb9
Refactor routes and constants
Mar 25, 2024
01cfeca
Update nodejs version to 3.1.0 in Chart.yaml
Mar 27, 2024
66a1663
Refactor case sharing component and filter component
Mar 28, 2024
4644964
Merge branch 'master' into GA-213-exui-new-cases-flow
Josh-HMCTS Sep 9, 2024
3dcbddf
Merge branch 'master' into GA-213-exui-new-cases-flow
Josh-HMCTS Oct 18, 2024
45d877e
unassigned cases flow
Josh-HMCTS Nov 8, 2024
898835d
fix loading spinner so it sticks to scrolled page
Josh-HMCTS Jan 31, 2025
b4813b8
Update store to support all types, optimise page load, add dynamic pa…
Josh-HMCTS Jan 31, 2025
b56c6cd
WIP
Josh-HMCTS Feb 18, 2025
98d6de8
Merge branch 'master' into GA-213-exui-new-cases-flow
Josh-HMCTS Jun 3, 2025
6ebdd42
fix tests
Josh-HMCTS Jun 4, 2025
4076654
test deploying ccd stack with MO
Josh-HMCTS Jun 4, 2025
4e7a3ac
Bumping chart version/ fixing aliases
hmcts-jenkins-j-to-z[bot] Jun 4, 2025
e0b561c
Merge branch 'master' into GA-213-exui-new-cases-flow
Josh-HMCTS Jun 4, 2025
d852a56
lint
Josh-HMCTS Jun 4, 2025
047b737
config updates
Josh-HMCTS Jun 4, 2025
120081b
add serets to jenking cnp
Josh-HMCTS Jun 4, 2025
42929de
remove postgresurl
Josh-HMCTS Jun 4, 2025
87bea57
update config
Josh-HMCTS Jun 4, 2025
c152b31
use different config
Josh-HMCTS Jun 4, 2025
0ba27d6
up chart
Josh-HMCTS Jun 4, 2025
2e577a2
add secret
Josh-HMCTS Jun 4, 2025
93fb7ac
remove duplicated java in chart
Josh-HMCTS Jun 4, 2025
a4061e3
update configs
Josh-HMCTS Jun 4, 2025
a27e617
Bumping chart version/ fixing aliases
hmcts-jenkins-j-to-z[bot] Jun 4, 2025
aa0a15b
remove secret from jenkin cnp
Josh-HMCTS Jun 4, 2025
496e3ce
update secrets
Josh-HMCTS Jun 4, 2025
f6e5bc9
try deploy postgres as part of PR
Josh-HMCTS Jun 5, 2025
2ae9cee
remove 2nd mo image
Josh-HMCTS Jun 5, 2025
137b07e
update to use xui-preview postgres
Josh-HMCTS Jun 5, 2025
07e5f46
disable EM
Josh-HMCTS Jun 5, 2025
8eb8694
add mc secrets for mc pods
Josh-HMCTS Jun 5, 2025
b73647f
revert integration env changes
Josh-HMCTS Jun 5, 2025
f1121b8
Bumping chart version/ fixing aliases
hmcts-jenkins-j-to-z[bot] Jun 5, 2025
c855341
cve
Josh-HMCTS Jun 23, 2025
3193491
updates to page flow
Josh-HMCTS Jul 3, 2025
64545d7
update config object for cases
Josh-HMCTS Jul 4, 2025
d3442cf
Merge branch 'master' into GA-213-exui-new-cases-flow
Josh-HMCTS Jul 4, 2025
165247b
cve
Josh-HMCTS Jul 4, 2025
a724a9e
lint
Josh-HMCTS Jul 4, 2025
62a7000
add log
Josh-HMCTS Jul 4, 2025
73df9f1
fix custom env var.json
Josh-HMCTS Jul 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Jenkinsfile_CNP
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,4 @@ withPipeline(type, product, component) {
])
}

}
}
10 changes: 8 additions & 2 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@
"src/styles.scss"
],
"scripts": [],
"sourceMap": true
"sourceMap": true,
"vendorChunk": true,
"extractLicenses": false,
"buildOptimizer": false,
"optimization": false,
"namedChunks": true
},
"configurations": {
"production": {
Expand Down Expand Up @@ -74,7 +79,8 @@
"production": {
"buildTarget": "rpx-xui-manage-organisations:build:production"
}
}
},
"defaultConfiguration": ""
},
"serveTest": {
"builder": "@angular-devkit/build-angular:dev-server",
Expand Down
70 changes: 64 additions & 6 deletions api/caaCaseTypes/caaCaseTypes.util.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { CaaCasesPageType } from '../caaCases/enums';
import { searchCasesString } from './caaCaseTypes.constants';
import { getConfigValue } from '../configuration';
import { UNASSIGNED_CASE_TYPES } from '../configuration/references';

export function getRequestBody(organisationID: string, caaCasesPageType: string, caaCasesFilterValue?: string | string[]) {
const organisationAssignedUsersKey = `supplementary_data.orgs_assigned_users.${organisationID}`;
const newCasesKey = `supplementary_data.new_case.${organisationID}`;
const reference = 'reference.keyword';
const caseReferenceFilter: any[] = [];

if (caaCasesFilterValue) {
if (Array.isArray(caaCasesFilterValue)) {
caaCasesFilterValue.forEach((caseReference) => {
Expand All @@ -31,14 +33,45 @@ export function getRequestBody(organisationID: string, caaCasesPageType: string,
},
{
bool: {
...(caaCasesPageType === CaaCasesPageType.AssignedCases && {
...((caaCasesPageType === CaaCasesPageType.AssignedCases && !caaCasesFilterValue) && {
must: [
{ range: { [organisationAssignedUsersKey]: { gt: 0 } } }
{ range: { [organisationAssignedUsersKey]: { gt: 0 } } },
{
bool: {
should: [
{ bool: { must_not: { exists: { field: newCasesKey } } } },
{ term: { [newCasesKey]: false } }
],
minimum_should_match: 1
}
}
]
}),
...(caaCasesPageType === CaaCasesPageType.UnassignedCases && {
must_not: [
{ range: { [organisationAssignedUsersKey]: { gt: 0 } } }
...((caaCasesPageType === CaaCasesPageType.UnassignedCases && !caaCasesFilterValue) && {
must: [
{
bool: {
should: [
{ term: { [organisationAssignedUsersKey]: 0 } },
{ bool: { must_not: { exists: { field: organisationAssignedUsersKey } } } }
],
minimum_should_match: 1
}
},
{
bool: {
should: [
{ term: { [newCasesKey]: false } },
{ bool: { must_not: { exists: { field: newCasesKey } } } }
],
minimum_should_match: 1
}
}
]
}),
...((caaCasesPageType === CaaCasesPageType.NewCasesToAccept && !caaCasesFilterValue) && {
must: [
{ term: { [newCasesKey]: true } }
]
})
}
Expand Down Expand Up @@ -68,3 +101,28 @@ export function getRequestBody(organisationID: string, caaCasesPageType: string,
export function getApiPath(ccdPath: string, caseTypes: string) {
return `${ccdPath}${searchCasesString}${caseTypes}`;
}

function setupCaseConfig() {
const unassignedCaseConfig = getConfigValue(UNASSIGNED_CASE_TYPES);
const caseConfig = unassignedCaseConfig.split('|').reduce((acc, entry) => {
const [caseType, newCases, groupAccess] = entry.split(',');
acc[caseType] = {
new_cases: newCases === 'true',
group_access: groupAccess === 'true'
};
return acc;
}, {} as Record<string, { new_cases: boolean; group_access: boolean }>);
return caseConfig;
}

export function addCaseConfiguration(response) {
const resData = response.data;
const unassignedCaseConfig = setupCaseConfig();
console.log(unassignedCaseConfig);
resData.case_types_results.forEach((caseTypeResult) => {
const { case_type_id } = caseTypeResult;
if (unassignedCaseConfig[case_type_id]) {
caseTypeResult.caseConfig = unassignedCaseConfig[case_type_id];
}
});
}
3 changes: 2 additions & 1 deletion api/caaCaseTypes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { RoleAssignmentResponse } from '../caaCases/models/roleAssignmentRespons
import { getConfigValue } from '../configuration';
import { CASE_TYPES, SERVICES_MCA_PROXY_API_PATH } from '../configuration/references';
import { EnhancedRequest } from '../models/enhanced-request.interface';
import { getApiPath, getRequestBody } from './caaCaseTypes.util';
import { getApiPath, getRequestBody, addCaseConfiguration } from './caaCaseTypes.util';

export async function handleCaaCaseTypes(req: EnhancedRequest, res: Response, next: NextFunction) {
const caaCasesPageType = req.query.caaCasesPageType as string;
Expand All @@ -31,6 +31,7 @@ export async function handleCaaCaseTypes(req: EnhancedRequest, res: Response, ne
const payload = getRequestBody(orgId, caaCasesPageType, caaCasesFilterValue);

const response = await req.http.post(path, payload);
addCaseConfiguration(response);
res.send(response.data);
} catch (error) {
res.status(500).send({
Expand Down
50 changes: 42 additions & 8 deletions api/caaCases/caaCases.util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { caseAssignment, caseId, caseTypeStr } from './caaCases.constants';
import { CaaCasesPageType } from './enums';
import { CaaCasesFilterType, CaaCasesPageType } from './enums';
import { CaaCases, CaseHeader, CcdCase, CcdCaseData, CcdColumnConfig } from './interfaces';

export function getApiPath(ccdPath: string, caseTypeId: string) {
Expand All @@ -17,11 +17,14 @@ export function mapCcdCases(caseType: string, ccdCase: CcdCase): CaaCases {
};
}

export function getRequestBody(organisationID: string, pageNo: number, pageSize: number, caaCasesPageType: string, caaCasesFilterValue?: string | string[]) {
export function getRequestBody(organisationID: string, pageNo: number, pageSize: number, caaCasesPageType: string, caseFilterType: string, caaCasesFilterValue?: string | string[]) {
const organisationAssignedUsersKey = `supplementary_data.orgs_assigned_users.${organisationID}`;
const newCasesKey = `supplementary_data.new_case.${organisationID}`;
const reference = 'reference.keyword';
const caseReferenceFilter: any[] = [];

if (caseFilterType === CaaCasesFilterType.NewCasesToAccept){
caaCasesPageType = CaaCasesPageType.NewCasesToAccept;
}
if (caaCasesFilterValue) {
if (Array.isArray(caaCasesFilterValue)) {
caaCasesFilterValue.forEach((caseReference) => {
Expand All @@ -46,14 +49,45 @@ export function getRequestBody(organisationID: string, pageNo: number, pageSize:
},
{
bool: {
...(caaCasesPageType === CaaCasesPageType.AssignedCases && {
...((caaCasesPageType === CaaCasesPageType.AssignedCases && !caaCasesFilterValue) && {
must: [
{ range: { [organisationAssignedUsersKey]: { gt: 0 } } },
{
bool: {
should: [
{ bool: { must_not: { exists: { field: newCasesKey } } } },
{ term: { [newCasesKey]: false } }
],
minimum_should_match: 1
}
}
]
}),
...((caaCasesPageType === CaaCasesPageType.UnassignedCases && !caaCasesFilterValue) && {
must: [
{ range: { [organisationAssignedUsersKey]: { gt: 0 } } }
{
bool: {
should: [
{ term: { [organisationAssignedUsersKey]: 0 } },
{ bool: { must_not: { exists: { field: organisationAssignedUsersKey } } } }
],
minimum_should_match: 1
}
},
{
bool: {
should: [
{ bool: { must_not: { exists: { field: newCasesKey } } } },
{ term: { [newCasesKey]: false } }
],
minimum_should_match: 1
}
}
]
}),
...(caaCasesPageType === CaaCasesPageType.UnassignedCases && {
must_not: [
{ range: { [organisationAssignedUsersKey]: { gt: 0 } } }
...((caaCasesPageType === CaaCasesPageType.NewCasesToAccept && !caaCasesFilterValue) && {
must: [
{ term: { [newCasesKey]: true } }
]
})
}
Expand Down
15 changes: 9 additions & 6 deletions api/caaCases/enums/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
export enum CaaCasesPageType {
AssignedCases = 'assigned-cases',
UnassignedCases = 'unassigned-cases',
AssignedCases = 'assigned-cases',
UnassignedCases = 'unassigned-cases',
NewCasesToAccept = 'new-cases',
}

export enum CaaCasesFilterType {
AllAssignees = 'all-assignees',
AssigneeName = 'assignee-name',
CaseReferenceNumber = 'case-reference-number',
None = 'none',
AllAssignees = 'all-assignees',
AssigneeName = 'assignee-name',
CaseReferenceNumber = 'case-reference-number',
NewCasesToAccept = 'new-cases-to-accept',
UnassignedCases = 'unassigned-cases',
None = 'none',
}
4 changes: 2 additions & 2 deletions api/caaCases/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export async function handleCaaCases(req: EnhancedRequest, res: Response, next:
const fromNo: number = page * size;

let caaCasesFilterValue: string | string[] = req.query.caaCasesFilterValue as string;

const caseFilterType = req.query.caaCasesFilterType as string;
try {
if (caaCasesFilterType === CaaCasesFilterType.AssigneeName) {
const roleAssignments = await handleRoleAssignments(req, next);
Expand All @@ -36,7 +36,7 @@ export async function handleCaaCases(req: EnhancedRequest, res: Response, next:
res.status(errReport.apiStatusCode).send(errReport);
}

const payload = getRequestBody(orgId, fromNo, size, caaCasesPageType, caaCasesFilterValue);
const payload = getRequestBody(orgId, fromNo, size, caaCasesPageType, caseFilterType, caaCasesFilterValue);

const response = await req.http.post(path, payload);
if (!objectContainsOnlySafeCharacters(response.data)) {
Expand Down
7 changes: 7 additions & 0 deletions api/caseshare/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,10 @@ export async function assignCasesToUsers(req: EnhancedRequest, res: Response) {
}
return realAPI.assignCases(req, res);
}

export async function acceptNewCasesForOrg(req: EnhancedRequest, res: Response) {
// if (stub) {
// return stubAPI.acceptNewCases(req, res);
// }
return realAPI.acceptNewCases(req, res);
}
30 changes: 29 additions & 1 deletion api/caseshare/real-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AxiosResponse } from 'axios';
import { NextFunction, Response } from 'express';
import { handleDelete, handleGet, handlePost } from '../common/crudService';
import { getConfigValue } from '../configuration';
import { SERVICES_MCA_PROXY_API_PATH, SERVICES_RD_PROFESSIONAL_API_PATH } from '../configuration/references';
import { SERVICES_CCD_DATA_STORE_API_PATH, SERVICES_MCA_PROXY_API_PATH, SERVICES_RD_PROFESSIONAL_API_PATH } from '../configuration/references';
import { EnhancedRequest } from '../models/enhanced-request.interface';
import { ccdToUserDetails, prdToUserDetails } from './dtos/user-dto';
import { CaseAssigneeMappingModel } from './models/case-assignee-mapping.model';
Expand All @@ -13,6 +13,7 @@ import { UserDetails } from './models/user-details.model';

const prdUrl: string = getConfigValue(SERVICES_RD_PROFESSIONAL_API_PATH);
const ccdUrl: string = getConfigValue(SERVICES_MCA_PROXY_API_PATH);
const ccdDsUrl: string = getConfigValue(SERVICES_CCD_DATA_STORE_API_PATH);

export async function getUsers(req: EnhancedRequest, res: Response, next: NextFunction): Promise<Response> {
try {
Expand Down Expand Up @@ -47,6 +48,33 @@ export async function getCases(req: EnhancedRequest, res: Response, next: NextFu
}
}

export async function acceptNewCases(req: EnhancedRequest, res: Response): Promise<Response> {
const casesToAccept = req.body.sharedCases;
const orgIdentifier = req.body.orgIdentifier;
const caseIdsToAccept: string[] = [];
for (const sharedCase of casesToAccept) {
if (sharedCase.caseId) {
caseIdsToAccept.push(sharedCase.caseId);
}
}
const path = `${ccdDsUrl}/cases/supplementary-data`;
const postData = {
'cases': caseIdsToAccept,
'supplementary_data_updates': {
'$set': {
[`new_case.${orgIdentifier}`]: false
}
}
};
try {
const { status, data }: {status: number, data: any} = await handlePost(path, postData, req);
return res.status(status).send(data);
} catch (err) {
// console.log(err);
res.status(500);
}
}

export async function assignCases(req: EnhancedRequest, res: Response): Promise<Response> {
const shareCases: SharedCase[] = req.body.sharedCases.slice();

Expand Down
1 change: 1 addition & 0 deletions api/caseshare/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ router.get('/users', restAPI.getUsers);
router.get('/cases', restAPI.getCases);
router.post('/case-assignments', restAPI.assignCasesToUsers);
router.get('/case-assignments', restAPI.getCases);
router.post('/case-users', restAPI.acceptNewCasesForOrg);
1 change: 1 addition & 0 deletions api/configuration/references.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export const REDIS_KEY_PREFIX = 'redis.prefix';
export const SESSION_TIMEOUTS = 'sessionTimeouts';

export const CASE_TYPES = 'caseTypes';
export const UNASSIGNED_CASE_TYPES = 'unassignedCaseTypes';

// PACT
export const PACT_BROKER_URL = 'pact.brokerUrl';
Expand Down
4 changes: 2 additions & 2 deletions charts/xui-mo-webapp/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apiVersion: v2
name: xui-mo-webapp
home: https://github.com/hmcts/rpx-xui-manage-organisations
version: 1.1.18
version: 1.1.19
description: Expert UI
maintainers:
- name: HMCTS RPX XUI
Expand All @@ -16,4 +16,4 @@ dependencies:
- name: idam-pr
version: ~2.3.0
repository: 'oci://hmctspublic.azurecr.io/helm'
condition: idam-pr.enabled
condition: idam-pr.enabled
2 changes: 1 addition & 1 deletion charts/xui-mo-webapp/values.preview.template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ idam-pr:
enabled: true
redirect_uris:
XUIMO:
- https://${SERVICE_FQDN}/oauth2/callback
- https://${SERVICE_FQDN}/oauth2/callback
1 change: 1 addition & 0 deletions config/custom-environment-variables.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"__format": "json"
},
"caseTypes": "CASE_TYPES",
"unassignedCaseTypes": "UNASSIGNED_CASE_TYPES",
"secrets": {
"rpx": {
"appinsights-instrumentationkey-mo": "APPINSIGHTS_INSTRUMENTATIONKEY",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
"@hmcts/media-viewer": "4.1.0",
"@hmcts/nodejs-healthcheck": "1.7.0",
"@hmcts/properties-volume": "0.0.13",
"@hmcts/rpx-xui-common-lib": "2.1.1",
"@hmcts/rpx-xui-common-lib": "2.1.0-uc-rc1",
"@hmcts/rpx-xui-node-lib": "2.30.6",
"@ng-idle/core": "^14.0.0",
"@ng-idle/keepalive": "^14.0.0",
Expand Down
1 change: 1 addition & 0 deletions src/app/app-initializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export function initApplication(store: Store<fromApp.State>): VoidFunction {
store.dispatch(new fromApp.LoadFeatureToggleConfig([AppConstants.FEATURE_NAMES.feeAccount,
AppConstants.FEATURE_NAMES.editUserPermissions,
AppConstants.FEATURE_NAMES.caaMenuItems,
AppConstants.FEATURE_NAMES.newCasesItems,
AppConstants.FEATURE_NAMES.newRegisterOrg]));

store.pipe(
Expand Down
Loading