Skip to content
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
23d9e36
Add Footer component and header tests
dileepapeiris Jan 31, 2026
e9a431a
Update component import paths and tests
dileepapeiris Jan 31, 2026
873ee5e
Add ProjectCard components
dileepapeiris Jan 31, 2026
40e380c
Remove projectCard unit tests
dileepapeiris Jan 31, 2026
16c46d9
Remove project card components
dileepapeiris Jan 31, 2026
b37bec1
Add unit tests for header components
dileepapeiris Jan 31, 2026
972b92a
Remove sideNavBar components and tests
dileepapeiris Jan 31, 2026
439c8f9
Remove Footer component and header tests
dileepapeiris Jan 31, 2026
f28a21f
Remove header components
dileepapeiris Jan 31, 2026
e769ef3
Remove project card and user profile components
dileepapeiris Jan 31, 2026
6f24159
Add SubscriptionWidget and update Header tests
dileepapeiris Jan 31, 2026
f97fe6a
Add header components for customer portal
dileepapeiris Jan 31, 2026
e93510f
Add header components and sidebar tests
dileepapeiris Jan 31, 2026
7a23b1e
Add SideBar component and project card tests
dileepapeiris Jan 31, 2026
a1bbb31
Add ProjectCard component and tests
dileepapeiris Jan 31, 2026
3eb8d9c
Add ProjectCardActions component
dileepapeiris Jan 31, 2026
c90cfd5
Show project key in ProjectSwitcher
dileepapeiris Jan 31, 2026
9274773
Auto-fetch remaining project pages
dileepapeiris Jan 31, 2026
5289811
Use object for expandedMenus in AppLayout test
dileepapeiris Jan 31, 2026
8ea1b67
Memoize mock defaults in ProjectCard
dileepapeiris Jan 31, 2026
28ebf05
Merge branch 'customer-portal-milestone-1' into feat/add-project-sele…
dileepapeiris Feb 2, 2026
a1cd2c8
Use 'ID' in logger warning message
dileepapeiris Feb 4, 2026
61bdb40
Merge remote-tracking branch 'origin/customer-portal-milestone-1' int…
dileepapeiris Feb 4, 2026
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
3 changes: 3 additions & 0 deletions apps/customer-portal/backend/constants.bal
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ const ERR_MSG_CASE_ACCESS_FORBIDDEN = "Access to the requested case is forbidden
const ERR_MSG_FETCHING_PROJECT_DETAILS = "Error retrieving project details!";
const ERR_MSG_PROJECT_ID_EMPTY = "Project ID cannot be empty!";
const ERR_MSG_CASE_ID_EMPTY = "Case ID cannot be empty!";
const ERR_LIMIT_OFFSET_INVALID = "Limit must be between 1 and 50. Offset must be a non-negative integer!";
const ERR_MSG_UNAUTHORIZED_ACCESS = "You're not authorized to access this service. Please sign in again." +
"If the issue continues, contact support.";

// Default Pagination Values
public const int DEFAULT_OFFSET = 0;
Expand Down
2 changes: 1 addition & 1 deletion apps/customer-portal/backend/modules/entity/constants.bal
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@

# Default pagination values.
const DEFAULT_OFFSET = 0;
const DEFAULT_LIMIT = 10;
const DEFAULT_LIMIT = 20;
27 changes: 19 additions & 8 deletions apps/customer-portal/backend/modules/entity/entity.bal
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ public isolated function getUserBasicInfo(string email, string idToken) returns
#
# + idToken - ID token for authorization
# + projectId - Unique ID of the project
# + return - Project details or error
public isolated function getProject(string idToken, string projectId) returns ProjectDetailsResponse|error {
# + return - Project response or error
public isolated function getProject(string idToken, string projectId) returns ProjectResponse|error {
return csEntityClient->/projects/[projectId].get(generateHeaders(idToken));
}

Expand All @@ -37,12 +37,12 @@ public isolated function getProject(string idToken, string projectId) returns Pr
# + idToken - ID token for authorization
# + payload - Payload for searching projects
# + return - Projects response or error
public isolated function searchProjects(string idToken, ProjectPayload payload) returns ProjectsResponse|error {
public isolated function searchProjects(string idToken, ProjectSearchPayload payload) returns ProjectsResponse|error {
return csEntityClient->/projects/search.post(payload, generateHeaders(idToken));
}

# Get project activity statistics by ID.
#
#
# + idToken - ID token for authorization
# + id - Unique ID of the project
# + return - Project statistics or error
Expand All @@ -51,7 +51,7 @@ public isolated function getProjectActivityStats(string idToken, string id) retu
}

# Get cases statistics of a project by ID.
#
#
# + idToken - ID token for authorization
# + id - Unique ID of the project
# + return - Project cases statistics or error
Expand All @@ -60,7 +60,7 @@ public isolated function getCaseStatsForProject(string idToken, string id) retur
}

# Get chats statistics of a project by ID.
#
#
# + idToken - ID token for authorization
# + id - Unique ID of the project
# + return - Project chats statistics or error
Expand All @@ -69,7 +69,7 @@ public isolated function getChatStatsForProject(string idToken, string id) retur
}

# Get deployments statistics of a project by ID.
#
#
# + idToken - ID token for authorization
# + id - Unique ID of the project
# + return - Project deployments statistics or error
Expand Down Expand Up @@ -110,6 +110,17 @@ public isolated function getCaseMetadata(string idToken) returns CaseMetadataRes
# + idToken - ID token for authorization
# + payload - Comment request payload
# + return - Comments response or error
public isolated function searchComments(string idToken, CommentRequestPayload payload) returns CommentsResponse|error {
public isolated function searchComments(string idToken, ReferenceSearchPayload payload) returns CommentsResponse|error {
return csEntityClient->/comments/search.post(payload, generateHeaders(idToken));
}

# Search attachments.
#
# + idToken - ID token for authorization
# + payload - Attachment request payload
# + return - Attachments response or error
public isolated function searchAttachments(string idToken, ReferenceSearchPayload payload)
returns AttachmentsResponse|error {

return csEntityClient->/attachments/search.post(payload, generateHeaders(idToken));
}
72 changes: 51 additions & 21 deletions apps/customer-portal/backend/modules/entity/types.bal
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ public type UserResponse record {|
string id;
# Email address
string email;
# First name
string firstName;
# Last name
string lastName;
# First name
string? firstName;
# Time zone
string? timeZone;
json...;
Expand All @@ -79,8 +79,8 @@ public type Project record {|
json...;
|};

# Request body for searching projects.
public type ProjectPayload record {|
# Payload for searching projects.
public type ProjectSearchPayload record {|
# Pagination details
Pagination pagination = {};
|};
Expand All @@ -95,20 +95,18 @@ public type ProjectsResponse record {|
json...;
|};

# Project details information.
public type ProjectDetailsResponse record {|
# Project information.
public type ProjectResponse record {|
*Project;
# Project type
string 'type;
# SLA status
string slaStatus;
# Subscription information
ProjectSubscription? subscription;
Subscription? subscription;
json...;
|};

# Project subscription information.
public type ProjectSubscription record {|
public type Subscription record {|
# Subscription start date
string? startDate;
# Subscription end date
Expand Down Expand Up @@ -237,11 +235,11 @@ public type SortBy record {|

# Case metadata response.
public type CaseMetadataResponse record {|
# List of available case states
# List of available case states (eg: Open, Closed, etc.)
ChoiceListItem[] states;
# List of available case severities
# List of available case severities (eg: S0, S1, etc.)
ChoiceListItem[] severities;
# List of available case types
# List of available case types (eg: Incident, Service Request, etc.)
ReferenceTableItem[] caseTypes;
json...;
|};
Expand All @@ -254,6 +252,8 @@ public type ProjectStatsResponse record {|
decimal billableHours;
# System health status
string systemHealth;
# SLA status
string slaStatus;
json...;
|};

Expand All @@ -270,8 +270,8 @@ public type ActiveCaseCount record {|
json...;
|};

# Outstanding incidents count breakdown.
public type OutstandingIncidentsCount record {|
# Outstanding cases count breakdown.
public type OutstandingCasesCount record {|
# Medium severity count
int medium;
# High severity count
Expand Down Expand Up @@ -302,8 +302,8 @@ public type ProjectCaseStatsResponse record {|
decimal averageResponseTime;
# Active case count breakdown
ActiveCaseCount activeCount;
# Outstanding incidents count breakdown
OutstandingIncidentsCount outstandingIncidentsCount;
# Outstanding cases count breakdown
OutstandingCasesCount outstandingCasesCount;
# Resolved case count breakdown
ResolvedCaseCount resolvedCount;
json...;
Expand Down Expand Up @@ -332,7 +332,7 @@ public type ProjectDeploymentStatsResponse record {|
public type Comment record {|
# ID
string id;
# Reference ID associated with the comment
# Reference ID associated with the comment(query ID, incident ID, service request ID, etc.)
string referenceId;
# Content of the comment
string content;
Expand All @@ -357,10 +357,40 @@ public type CommentsResponse record {|
json...;
|};

# Request payload for searching comments.
public type CommentRequestPayload record {|
# Reference ID to filter comments
# Reference search payload to search comments, attachments, etc.
public type ReferenceSearchPayload record {|
# Reference ID to filter related resources(query ID, incident ID, service request ID, etc.)
string referenceId;
# Pagination details
Pagination pagination?;
|};

# Attachment data.
public type Attachment record {|
# ID of the attachment
string id;
# Reference ID associated with the attachment(query ID, incident ID, service request ID, etc.)
string referenceId;
# File name
string name;
# MIME type of the file
string 'type;
# File size in bytes
string sizeBytes;
# User who created the attachment
string createdBy;
# Created date and time
string createdOn;
# Download URL
string downloadUrl;
json...;
|};

# Attachments response.
public type AttachmentsResponse record {|
# List of attachments
Attachment[] attachments;
# Total records count
int totalRecords;
*Pagination;
|};
28 changes: 25 additions & 3 deletions apps/customer-portal/backend/modules/entity/utils.bal
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@
isolated function generateHeaders(string token) returns map<string|string[]> => {"x-user-id-token": token};

# Get comments for a given entity ID with pagination.
#
#
# + idToken - ID token for authorization
# + id - Entity ID to filter comments
# + limit - Number of comments to retrieve
# + offset - Offset for pagination
# + return - Comments response or error
public isolated function getComments(string idToken, string id, int? 'limit, int? offset) returns CommentsResponse|error {
CommentRequestPayload payload = {
public isolated function getComments(string idToken, string id, int? 'limit, int? offset)
returns CommentsResponse|error {

ReferenceSearchPayload payload = {
referenceId: id,
pagination: {
'limit: 'limit ?: DEFAULT_LIMIT,
Expand All @@ -37,3 +39,23 @@ public isolated function getComments(string idToken, string id, int? 'limit, int
};
return searchComments(idToken, payload);
}

# Get attachments for a given entity ID with pagination.
#
# + idToken - ID token for authorization
# + id - Entity ID to filter attachments
# + limit - Number of attachments to retrieve
# + offset - Offset for pagination
# + return - Attachments response or error
public isolated function getAttachments(string idToken, string id, int? 'limit, int? offset)
returns AttachmentsResponse|error {

ReferenceSearchPayload payload = {
referenceId: id,
pagination: {
'limit: 'limit ?: DEFAULT_LIMIT,
offset: offset ?: DEFAULT_OFFSET
}
};
return searchAttachments(idToken, payload);
}
Loading