@salesforce/ui-bundle-template-app-react-sample-b2x 1.120.3 → 1.120.6

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 CHANGED
@@ -3,6 +3,33 @@
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.120.6](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.120.5...v1.120.6) (2026-04-07)
7
+
8
+ **Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
9
+
10
+
11
+
12
+
13
+
14
+ ## [1.120.5](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.120.4...v1.120.5) (2026-04-07)
15
+
16
+ **Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
17
+
18
+
19
+
20
+
21
+
22
+ ## [1.120.4](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.120.3...v1.120.4) (2026-04-07)
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * make tenant owner of own record ([#414](https://github.com/salesforce-experience-platform-emu/webapps/issues/414)) ([bf1f289](https://github.com/salesforce-experience-platform-emu/webapps/commit/bf1f289a8d56a381adde51e642e67db38099f193))
28
+
29
+
30
+
31
+
32
+
6
33
  ## [1.120.3](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.120.2...v1.120.3) (2026-04-02)
7
34
 
8
35
  **Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
package/dist/README.md CHANGED
@@ -29,20 +29,25 @@ A property rental sample React UI Bundle for Salesforce Experience Cloud. Demons
29
29
 
30
30
  ## What's Included
31
31
 
32
- | Path | Description |
33
- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
34
- | `force-app/main/default/uiBundles/propertyrentalapp/` | React UI Bundle (source, config, tests) |
35
- | `force-app/main/default/objects/` | 17 custom objects — `Agent__c`, `Application__c`, `KPI_Snapshot__c`, `Lease__c`, `Maintenance_Request__c`, `Maintenance_Worker__c`, `Notification__c`, `Payment__c`, `Property__c`, `Property_Cost__c`, `Property_Feature__c`, `Property_Image__c`, `Property_Listing__c`, `Property_Management_Company__c`, `Property_Owner__c`, `Property_Sale__c`, `Tenant__c` |
36
- | `force-app/main/default/layouts/` | Page layouts for each custom object |
37
- | `force-app/main/default/permissionsets/` | `Property_Management_Access` (full admin access) and `Tenant_Maintenance_Access` (scoped tenant access) |
38
- | `force-app/main/default/classes/` | Apex classes `MaintenanceRequestTriggerHandler`, `TenantTriggerHandler`, `UIBundleAuthUtils`, `UIBundleChangePassword`, `UIBundleForgotPassword`, `UIBundleLogin`, `UIBundleAppRegistration` |
39
- | `force-app/main/default/triggers/` | Apex triggers `MaintenanceRequestTrigger`, `TenantTrigger` |
40
- | `force-app/main/default/cspTrustedSites/` | CSP trusted sites for external resources (Google Fonts, Pexels, Unsplash, GitHub Avatars, OpenStreetMap, Open-Meteo) |
41
- | `force-app/main/default/data/` | Sample data (JSON) for all objects, importable via `sf data import tree` |
42
- | `force-app/main/default/digitalExperienceConfigs/` | Experience Cloud site configuration |
43
- | `force-app/main/default/digitalExperiences/` | Experience Cloud site definition |
44
- | `force-app/main/default/networks/` | Experience Cloud network metadata |
45
- | `force-app/main/default/sites/` | Salesforce Sites configuration |
32
+ ```
33
+ force-app/main/default/
34
+ ├── classes/ # Apex Logic: Triggers, Auth, and Registration
35
+ │ ├── MaintenanceRequestTriggerHandler.cls
36
+ │ ├── TenantTriggerHandler.cls
37
+ │ └── UIBundle (Auth, Login, Registration, etc.)
38
+ ├── cspTrustedSites/ # External resource security (Maps, Fonts, Avatars)
39
+ ├── data/ # Sample JSON data for "sf data import tree"
40
+ ├── digitalExperienceConfigs/ # Experience Cloud site configurations
41
+ ├── digitalExperiences/ # Experience Cloud site definitions
42
+ ├── layouts/ # Page layouts for all 17 custom objects
43
+ ├── networks/ # Experience Cloud network metadata
44
+ ├── objects/ # 17 Custom Objects (Property, Tenant, Lease, etc.)
45
+ ├── permissionsets/ # Access: Property_Management (Admin) & Tenant (Scoped)
46
+ ├── sites/ # Salesforce Sites configuration
47
+ ├── triggers/ # Apex Triggers: MaintenanceRequest & Tenant
48
+ └── uiBundles/
49
+ └── propertyrentalapp/ # React UI Bundle (source, config, tests)
50
+ ```
46
51
 
47
52
  ---
48
53
 
@@ -462,7 +467,7 @@ By default, Salesforce does not expose any records to guest users. You must crea
462
467
  2. Scroll to the **Property Sharing Rules** section and click **New**.
463
468
  3. Configure the rule:
464
469
  - **Label**: `Available Properties for Guest Users`
465
- - **Rule Type**: Select **Based on criteria**
470
+ - **Rule Type**: Select **Guest user access, based on criteria**
466
471
  - **Criteria**: `Status Equals Available` (adjust the field and value to match your data model)
467
472
  - **Share with**: Select **Guests of the Property Rental App site** (the guest user group for your Experience Cloud site)
468
473
  - **Access Level**: `Read Only`
@@ -473,7 +478,7 @@ By default, Salesforce does not expose any records to guest users. You must crea
473
478
  Repeat the same steps in the **Property Listing Sharing Rules** section:
474
479
 
475
480
  - **Label**: `Available Property Listings for Guest Users`
476
- - **Rule Type**: `Based on criteria`
481
+ - **Rule Type**: `Guest user access, based on criteria`
477
482
  - **Criteria**: Match listings you want to expose (e.g., `Status Equals Active`)
478
483
  - **Share with**: `Guests of the Property Rental App site`
479
484
  - **Access Level**: `Read Only`
@@ -0,0 +1,9 @@
1
+ {
2
+ "permsetAssignments": {
3
+ "defaultAssignee": "skip",
4
+ "assignments": {
5
+ "Property_Management_Access": { "assignee": "currentUser" },
6
+ "Tenant_Maintenance_Access": { "assignee": "currentUser" }
7
+ }
8
+ }
9
+ }
@@ -18,8 +18,8 @@
18
18
  "graphql:schema": "node scripts/get-graphql-schema.mjs"
19
19
  },
20
20
  "dependencies": {
21
- "@salesforce/sdk-data": "^1.120.3",
22
- "@salesforce/ui-bundle": "^1.120.3",
21
+ "@salesforce/sdk-data": "^1.120.6",
22
+ "@salesforce/ui-bundle": "^1.120.6",
23
23
  "@tailwindcss/vite": "^4.1.17",
24
24
  "class-variance-authority": "^0.7.1",
25
25
  "clsx": "^2.1.1",
@@ -50,7 +50,7 @@
50
50
  "@graphql-eslint/eslint-plugin": "^4.1.0",
51
51
  "@graphql-tools/utils": "^11.0.0",
52
52
  "@playwright/test": "^1.49.0",
53
- "@salesforce/vite-plugin-ui-bundle": "^1.120.3",
53
+ "@salesforce/vite-plugin-ui-bundle": "^1.120.6",
54
54
  "@testing-library/jest-dom": "^6.6.3",
55
55
  "@testing-library/react": "^16.1.0",
56
56
  "@testing-library/user-event": "^14.5.2",
@@ -73,5 +73,8 @@
73
73
  "vite": "^7.2.4",
74
74
  "vite-plugin-graphql-codegen": "^3.6.3",
75
75
  "vitest": "^4.0.17"
76
+ },
77
+ "overrides": {
78
+ "lodash": "^4.18.1"
76
79
  }
77
80
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@salesforce/webapp-template-base-sfdx-project-experimental",
3
- "version": "1.120.3",
3
+ "version": "1.120.6",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@salesforce/webapp-template-base-sfdx-project-experimental",
9
- "version": "1.120.3",
9
+ "version": "1.120.6",
10
10
  "license": "SEE LICENSE IN LICENSE.txt",
11
11
  "devDependencies": {
12
12
  "@lwc/eslint-plugin-lwc": "^3.3.0",
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/ui-bundle-template-base-sfdx-project",
3
- "version": "1.120.3",
3
+ "version": "1.120.6",
4
4
  "description": "Base SFDX project template",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "publishConfig": {
@@ -0,0 +1,6 @@
1
+ {
2
+ "permsetAssignments": {
3
+ "defaultAssignee": "currentUser",
4
+ "assignments": {}
5
+ }
6
+ }
@@ -14,10 +14,22 @@
14
14
  * 1. login — sf org login web only if org not already connected (skip with --skip-login)
15
15
  * 2. uiBundle — (all UI bundles) npm install && npm run build so dist exists for deploy (skip with --skip-ui-bundle-build)
16
16
  * 3. deploy — sf project deploy start --target-org <alias> (requires dist for entity deployment)
17
- * 4. permset — sf org assign permset for each *.permissionset-meta.xml (skip with --skip-permset; override via --permset-name)
17
+ * 4. permset — assign permsets per org-setup.config.json (skip with --skip-permset; override via --permset-name)
18
18
  * 5. data — prepare unique fields + sf data import tree (skipped if no data dir/plan)
19
19
  * 6. graphql — (in UI bundle) npm run graphql:schema then npm run graphql:codegen
20
20
  * 7. dev — (in UI bundle) npm run dev — launch dev server (skip with --skip-dev)
21
+ *
22
+ * Permset assignment config (scripts/org-setup.config.json):
23
+ * {
24
+ * "permsetAssignments": {
25
+ * "defaultAssignee": "currentUser",
26
+ * "assignments": {
27
+ * "Guest_Permset": { "assignee": "guest@mysite.example.com" },
28
+ * "Internal_Only": { "assignee": "skip" }
29
+ * }
30
+ * }
31
+ * }
32
+ * Assignee values: "currentUser" (default), "skip", or a specific username.
21
33
  */
22
34
 
23
35
  import { spawnSync } from 'node:child_process';
@@ -127,6 +139,20 @@ Options:
127
139
  --skip-dev Do not launch the dev server at the end
128
140
  -y, --yes Skip interactive step picker; run all enabled steps immediately
129
141
  -h, --help Show this help
142
+
143
+ Permset config (scripts/org-setup.config.json):
144
+ Control per-permset assignment via a config file. Example:
145
+ {
146
+ "permsetAssignments": {
147
+ "defaultAssignee": "currentUser",
148
+ "assignments": {
149
+ "Guest_Permset": { "assignee": "guest@mysite.example.com" },
150
+ "Internal_Only": { "assignee": "skip" }
151
+ }
152
+ }
153
+ }
154
+ Assignee values: "currentUser" (default), "skip", or a specific username.
155
+ Without this file, all discovered permsets are assigned to the current user.
130
156
  `);
131
157
  process.exit(0);
132
158
  }
@@ -181,6 +207,51 @@ function discoverPermissionSetNames() {
181
207
  return names.sort();
182
208
  }
183
209
 
210
+ /**
211
+ * Load permset assignment configuration from org-setup.config.json.
212
+ *
213
+ * Config shape:
214
+ * {
215
+ * "permsetAssignments": {
216
+ * "defaultAssignee": "currentUser", // "currentUser" (default) or "skip"
217
+ * "assignments": {
218
+ * "My_Guest_Permset": { "assignee": "guest@mysite.example.com" },
219
+ * "Internal_Only": { "assignee": "skip" }
220
+ * }
221
+ * }
222
+ * }
223
+ *
224
+ * Assignee values:
225
+ * "currentUser" — assign to the user running the script (default)
226
+ * "skip" — do not assign this permset
227
+ * "<username>" — assign to a specific user via --on-behalf-of
228
+ *
229
+ * Returns { defaultAssignee: string, assignments: Record<string, { assignee: string }> }
230
+ */
231
+ function loadPermsetConfig() {
232
+ const configPath = resolve(__dirname, 'org-setup.config.json');
233
+ const defaults = { defaultAssignee: 'currentUser', assignments: {} };
234
+ if (!existsSync(configPath)) return defaults;
235
+ try {
236
+ const raw = JSON.parse(readFileSync(configPath, 'utf8'));
237
+ const section = raw?.permsetAssignments;
238
+ if (!section) return defaults;
239
+ return {
240
+ defaultAssignee: section.defaultAssignee || 'currentUser',
241
+ assignments: section.assignments || {},
242
+ };
243
+ } catch (err) {
244
+ console.warn(`Warning: failed to parse org-setup.config.json: ${err.message}; using defaults.`);
245
+ return defaults;
246
+ }
247
+ }
248
+
249
+ /** Resolve the effective assignee for a given permset name. */
250
+ function resolveAssignee(permsetName, permsetConfig) {
251
+ const override = permsetConfig.assignments[permsetName];
252
+ return override?.assignee || permsetConfig.defaultAssignee;
253
+ }
254
+
184
255
  function isOrgConnected(targetOrg) {
185
256
  const result = spawnSync('sf', ['org', 'display', '--target-org', targetOrg, '--json'], {
186
257
  cwd: ROOT,
@@ -422,28 +493,35 @@ async function main() {
422
493
  }
423
494
 
424
495
  if (!skipPermset) {
496
+ const permsetConfig = loadPermsetConfig();
425
497
  if (permsetNames.length === 0) {
426
498
  console.log('\n--- Assign permission sets ---');
427
499
  console.log('No permission sets found under permissionsets/ and none passed via --permset-name; skipping.');
428
500
  } else {
429
501
  console.log('\n--- Assign permission sets ---');
430
502
  for (const permsetName of permsetNames) {
431
- const permsetResult = spawnSync(
432
- 'sf',
433
- ['org', 'assign', 'permset', '--name', permsetName, '--target-org', targetOrg],
434
- {
435
- cwd: ROOT,
436
- stdio: 'pipe',
437
- shell: true,
438
- }
439
- );
503
+ const assignee = resolveAssignee(permsetName, permsetConfig);
504
+ if (assignee === 'skip') {
505
+ console.log(`Permission set "${permsetName}" skipped (config).`);
506
+ continue;
507
+ }
508
+ const sfArgs = ['org', 'assign', 'permset', '--name', permsetName, '--target-org', targetOrg];
509
+ if (assignee !== 'currentUser') {
510
+ sfArgs.push('--on-behalf-of', assignee);
511
+ }
512
+ const assigneeLabel = assignee === 'currentUser' ? 'current user' : assignee;
513
+ const permsetResult = spawnSync('sf', sfArgs, {
514
+ cwd: ROOT,
515
+ stdio: 'pipe',
516
+ shell: true,
517
+ });
440
518
  if (permsetResult.status === 0) {
441
- console.log(`Permission set "${permsetName}" assigned.`);
519
+ console.log(`Permission set "${permsetName}" assigned to ${assigneeLabel}.`);
442
520
  } else {
443
521
  const out =
444
522
  (permsetResult.stderr?.toString() || '') + (permsetResult.stdout?.toString() || '');
445
523
  if (out.includes('Duplicate') && out.includes('PermissionSet')) {
446
- console.log(`Permission set "${permsetName}" already assigned; skipping.`);
524
+ console.log(`Permission set "${permsetName}" already assigned to ${assigneeLabel}; skipping.`);
447
525
  } else if (out.includes('not found') && out.includes('target org')) {
448
526
  console.log(`Permission set "${permsetName}" not in org; skipping.`);
449
527
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/ui-bundle-template-app-react-sample-b2x",
3
- "version": "1.120.3",
3
+ "version": "1.120.6",
4
4
  "description": "Salesforce sample property rental React app",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "author": "",