@salesforce/webapp-template-app-react-sample-b2e-experimental 1.116.8 → 1.116.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CHANGELOG.md +16 -0
- package/dist/force-app/main/default/classes/MaintenanceRequestTriggerHandler.cls +9 -6
- package/dist/force-app/main/default/classes/TenantTriggerHandler.cls +8 -0
- package/dist/force-app/main/default/classes/TenantTriggerHandler_Test.cls +4 -0
- package/dist/force-app/main/default/objects/Maintenance_Request__c/fields/Type__c.field-meta.xml +20 -0
- package/dist/force-app/main/default/webapplications/propertymanagementapp/package.json +3 -3
- package/dist/force-app/main/default/webapplications/propertymanagementapp/src/api/applications/applications.ts +69 -2
- package/dist/force-app/main/default/webapplications/propertymanagementapp/src/api/applications/query/applicationForApproval.graphql +22 -0
- package/dist/force-app/main/default/webapplications/propertymanagementapp/src/api/applications/query/existingTenant.graphql +16 -0
- package/dist/force-app/main/default/webapplications/propertymanagementapp/src/api/applications/query/userByContact.graphql +13 -0
- package/dist/force-app/main/default/webapplications/propertymanagementapp/src/api/graphql-operations-types.ts +6706 -2317
- package/dist/force-app/main/default/webapplications/propertymanagementapp/src/pages/ApplicationSearch.tsx +7 -3
- package/dist/force-app/main/default/webapplications/propertymanagementapp/src/pages/MaintenanceRequestSearch.tsx +7 -3
- package/dist/package-lock.json +2 -2
- package/dist/package.json +1 -1
- package/package.json +2 -2
package/dist/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,22 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [1.116.10](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.116.9...v1.116.10) (2026-03-27)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [1.116.9](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.116.8...v1.116.9) (2026-03-27)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
6
22
|
## [1.116.8](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.116.7...v1.116.8) (2026-03-27)
|
|
7
23
|
|
|
8
24
|
**Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
public
|
|
1
|
+
public without sharing class MaintenanceRequestTriggerHandler {
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Handles before insert logic for Maintenance Request records
|
|
@@ -7,11 +7,14 @@ public with sharing class MaintenanceRequestTriggerHandler {
|
|
|
7
7
|
public static void handleBeforeInsert(List<Maintenance_Request__c> newRequests) {
|
|
8
8
|
// Map to store request type to worker type mappings
|
|
9
9
|
Map<String, String> requestTypeToWorkerType = new Map<String, String>{
|
|
10
|
-
'Plumbing'
|
|
11
|
-
'Electrical'
|
|
12
|
-
'HVAC'
|
|
13
|
-
'Appliance'
|
|
14
|
-
'
|
|
10
|
+
'Plumbing' => 'Plumbing',
|
|
11
|
+
'Electrical' => 'Electrical',
|
|
12
|
+
'HVAC' => 'HVAC (Heating & Cooling)',
|
|
13
|
+
'Appliance' => 'Appliance Repair',
|
|
14
|
+
'Carpentry' => 'General Carpentry',
|
|
15
|
+
'Landscaping' => 'Landscaping / Grounds',
|
|
16
|
+
'Cleaning' => 'Janitorial / Cleaning',
|
|
17
|
+
'Pest' => 'Pest Control'
|
|
15
18
|
};
|
|
16
19
|
|
|
17
20
|
// Collect unique worker types needed
|
|
@@ -29,7 +29,15 @@ public with sharing class TenantTriggerHandler {
|
|
|
29
29
|
if (userIds.isEmpty()) {
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
+
assignTenantMaintenanceAccessAsync(new List<Id>(userIds));
|
|
33
|
+
}
|
|
32
34
|
|
|
35
|
+
@future
|
|
36
|
+
private static void assignTenantMaintenanceAccessAsync(List<Id> userIdsList) {
|
|
37
|
+
Set<Id> userIds = new Set<Id>(userIdsList);
|
|
38
|
+
if (userIds.isEmpty()) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
33
41
|
List<PermissionSet> permSets = [
|
|
34
42
|
SELECT Id
|
|
35
43
|
FROM PermissionSet
|
|
@@ -73,7 +73,9 @@ private class TenantTriggerHandler_Test {
|
|
|
73
73
|
static void testNoDuplicateAssign() {
|
|
74
74
|
Id runAsUserId = UserInfo.getUserId();
|
|
75
75
|
Tenant__c tenant = new Tenant__c(User__c = runAsUserId);
|
|
76
|
+
Test.startTest();
|
|
76
77
|
insert tenant;
|
|
78
|
+
Test.stopTest();
|
|
77
79
|
|
|
78
80
|
Integer countBefore = [
|
|
79
81
|
SELECT COUNT()
|
|
@@ -82,8 +84,10 @@ private class TenantTriggerHandler_Test {
|
|
|
82
84
|
AND PermissionSet.Name = 'Tenant_Maintenance_Access'
|
|
83
85
|
];
|
|
84
86
|
|
|
87
|
+
Test.startTest();
|
|
85
88
|
tenant.Status__c = 'Active';
|
|
86
89
|
update tenant;
|
|
90
|
+
Test.stopTest();
|
|
87
91
|
|
|
88
92
|
Integer countAfter = [
|
|
89
93
|
SELECT COUNT()
|
package/dist/force-app/main/default/objects/Maintenance_Request__c/fields/Type__c.field-meta.xml
CHANGED
|
@@ -32,11 +32,31 @@
|
|
|
32
32
|
<default>false</default>
|
|
33
33
|
<label>Appliance</label>
|
|
34
34
|
</value>
|
|
35
|
+
<value>
|
|
36
|
+
<fullName>Carpentry</fullName>
|
|
37
|
+
<default>false</default>
|
|
38
|
+
<label>Carpentry</label>
|
|
39
|
+
</value>
|
|
40
|
+
<value>
|
|
41
|
+
<fullName>Landscaping</fullName>
|
|
42
|
+
<default>false</default>
|
|
43
|
+
<label>Landscaping</label>
|
|
44
|
+
</value>
|
|
45
|
+
<value>
|
|
46
|
+
<fullName>Cleaning</fullName>
|
|
47
|
+
<default>false</default>
|
|
48
|
+
<label>Cleaning</label>
|
|
49
|
+
</value>
|
|
35
50
|
<value>
|
|
36
51
|
<fullName>Pest</fullName>
|
|
37
52
|
<default>false</default>
|
|
38
53
|
<label>Pest Control</label>
|
|
39
54
|
</value>
|
|
55
|
+
<value>
|
|
56
|
+
<fullName>Other</fullName>
|
|
57
|
+
<default>false</default>
|
|
58
|
+
<label>Other</label>
|
|
59
|
+
</value>
|
|
40
60
|
</valueSetDefinition>
|
|
41
61
|
</valueSet>
|
|
42
62
|
</CustomField>
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"graphql:schema": "node scripts/get-graphql-schema.mjs"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@salesforce/sdk-data": "^1.116.
|
|
19
|
-
"@salesforce/webapp-experimental": "^1.116.
|
|
18
|
+
"@salesforce/sdk-data": "^1.116.10",
|
|
19
|
+
"@salesforce/webapp-experimental": "^1.116.10",
|
|
20
20
|
"@tailwindcss/vite": "^4.1.17",
|
|
21
21
|
"class-variance-authority": "^0.7.1",
|
|
22
22
|
"clsx": "^2.1.1",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"@graphql-eslint/eslint-plugin": "^4.1.0",
|
|
44
44
|
"@graphql-tools/utils": "^11.0.0",
|
|
45
45
|
"@playwright/test": "^1.49.0",
|
|
46
|
-
"@salesforce/vite-plugin-webapp-experimental": "^1.116.
|
|
46
|
+
"@salesforce/vite-plugin-webapp-experimental": "^1.116.10",
|
|
47
47
|
"@testing-library/jest-dom": "^6.6.3",
|
|
48
48
|
"@testing-library/react": "^16.1.0",
|
|
49
49
|
"@testing-library/user-event": "^14.5.2",
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import GET_APPLICATIONS from "./query/getApplications.graphql?raw";
|
|
2
2
|
import UPDATE_APPLICATION_STATUS from "./query/updateApplicationStatus.graphql?raw";
|
|
3
|
+
import APPLICATION_FOR_APPROVAL_QUERY from "./query/applicationForApproval.graphql?raw";
|
|
4
|
+
import USER_BY_CONTACT_QUERY from "./query/userByContact.graphql?raw";
|
|
5
|
+
import EXISTING_TENANT_QUERY from "./query/existingTenant.graphql?raw";
|
|
6
|
+
import { createRecord } from "@salesforce/webapp-experimental/api";
|
|
3
7
|
import type {
|
|
4
8
|
GetApplicationsQuery,
|
|
5
|
-
UpdateApplicationStatusMutationVariables,
|
|
6
|
-
UpdateApplicationStatusMutation,
|
|
7
9
|
GetApplicationsQueryVariables,
|
|
10
|
+
UpdateApplicationStatusMutation,
|
|
11
|
+
UpdateApplicationStatusMutationVariables,
|
|
12
|
+
ApplicationForApprovalQuery,
|
|
13
|
+
ApplicationForApprovalQueryVariables,
|
|
14
|
+
UserByContactQuery,
|
|
15
|
+
UserByContactQueryVariables,
|
|
16
|
+
ExistingTenantQuery,
|
|
17
|
+
ExistingTenantQueryVariables,
|
|
8
18
|
} from "../graphql-operations-types.js";
|
|
9
19
|
import { executeGraphQL } from "../graphqlClient.js";
|
|
10
20
|
|
|
@@ -14,6 +24,8 @@ export type ApplicationNode = NonNullable<
|
|
|
14
24
|
>[number]
|
|
15
25
|
>["node"];
|
|
16
26
|
|
|
27
|
+
const TENANT_OBJECT_API_NAME = "Tenant__c";
|
|
28
|
+
|
|
17
29
|
export async function getApplications(): Promise<NonNullable<ApplicationNode>[]> {
|
|
18
30
|
try {
|
|
19
31
|
const data = await executeGraphQL<GetApplicationsQuery, GetApplicationsQueryVariables>(
|
|
@@ -34,6 +46,11 @@ export async function updateApplicationStatus(
|
|
|
34
46
|
applicationId: string,
|
|
35
47
|
status: string,
|
|
36
48
|
): Promise<boolean> {
|
|
49
|
+
const normalizedStatus = status.trim().toLowerCase();
|
|
50
|
+
if (normalizedStatus === "approved") {
|
|
51
|
+
await ensureTenantForApprovedApplication(applicationId);
|
|
52
|
+
}
|
|
53
|
+
|
|
37
54
|
const variables: UpdateApplicationStatusMutationVariables = {
|
|
38
55
|
input: {
|
|
39
56
|
Id: applicationId,
|
|
@@ -53,3 +70,53 @@ export async function updateApplicationStatus(
|
|
|
53
70
|
return false;
|
|
54
71
|
}
|
|
55
72
|
}
|
|
73
|
+
|
|
74
|
+
async function ensureTenantForApprovedApplication(applicationId: string): Promise<void> {
|
|
75
|
+
const appData = await executeGraphQL<
|
|
76
|
+
ApplicationForApprovalQuery,
|
|
77
|
+
ApplicationForApprovalQueryVariables
|
|
78
|
+
>(APPLICATION_FOR_APPROVAL_QUERY, { applicationId });
|
|
79
|
+
const applicationNode = appData.uiapi?.query?.Application__c?.edges?.[0]?.node;
|
|
80
|
+
if (!applicationNode) {
|
|
81
|
+
throw new Error("Application record not found.");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const contactId = applicationNode.User__c?.value ?? null;
|
|
85
|
+
const propertyId = applicationNode.Property__c?.value ?? null;
|
|
86
|
+
const startDate = applicationNode.Start_Date__c?.value ?? null;
|
|
87
|
+
|
|
88
|
+
if (!contactId || !propertyId) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const userData = await executeGraphQL<UserByContactQuery, UserByContactQueryVariables>(
|
|
93
|
+
USER_BY_CONTACT_QUERY,
|
|
94
|
+
{ contactId },
|
|
95
|
+
);
|
|
96
|
+
const userId = userData.uiapi?.query?.User?.edges?.[0]?.node?.Id ?? null;
|
|
97
|
+
if (!userId) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const existingTenantData = await executeGraphQL<
|
|
102
|
+
ExistingTenantQuery,
|
|
103
|
+
ExistingTenantQueryVariables
|
|
104
|
+
>(EXISTING_TENANT_QUERY, {
|
|
105
|
+
userId,
|
|
106
|
+
propertyId,
|
|
107
|
+
});
|
|
108
|
+
const existingTenantId = existingTenantData.uiapi?.query?.Tenant__c?.edges?.[0]?.node?.Id ?? null;
|
|
109
|
+
if (existingTenantId) return;
|
|
110
|
+
|
|
111
|
+
const tenantFields: Record<string, unknown> = {
|
|
112
|
+
User__c: userId,
|
|
113
|
+
Property__c: propertyId,
|
|
114
|
+
User_Status__c: "Tenant",
|
|
115
|
+
Status__c: "Active",
|
|
116
|
+
};
|
|
117
|
+
if (startDate) {
|
|
118
|
+
tenantFields.Start_Date__c = String(startDate);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
await createRecord(TENANT_OBJECT_API_NAME, tenantFields);
|
|
122
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
query ApplicationForApproval($applicationId: ID!) {
|
|
2
|
+
uiapi {
|
|
3
|
+
query {
|
|
4
|
+
Application__c(where: { Id: { eq: $applicationId } }, first: 1) {
|
|
5
|
+
edges {
|
|
6
|
+
node {
|
|
7
|
+
Id
|
|
8
|
+
User__c @optional {
|
|
9
|
+
value
|
|
10
|
+
}
|
|
11
|
+
Property__c @optional {
|
|
12
|
+
value
|
|
13
|
+
}
|
|
14
|
+
Start_Date__c @optional {
|
|
15
|
+
value
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|