@salesforce/ui-bundle-template-app-react-sample-b2e 11.21.0 → 11.22.1
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/uiBundles/propertymanagementapp/package.json +4 -4
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/components/applications/ApplicationDetailsModal.tsx +17 -22
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/components/maintenanceRequests/MaintenanceDetailsModal.tsx +17 -22
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/controls/SortControl.tsx +1 -1
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/filters/inputs/FilterFieldWrapper.tsx +13 -1
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/filters/inputs/NumericRangeFilter.tsx +32 -2
- 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
|
+
## [11.22.1](https://github.com/salesforce-experience-platform-emu/webapps/compare/v11.22.0...v11.22.1) (2026-07-10)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [11.22.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v11.21.0...v11.22.0) (2026-07-10)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
6
22
|
## [11.21.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v11.20.0...v11.21.0) (2026-07-10)
|
|
7
23
|
|
|
8
24
|
**Note:** Version bump only for package @salesforce/ui-bundle-template-base-sfdx-project
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"graphql:schema": "node scripts/get-graphql-schema.mjs"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@salesforce/platform-sdk": "^11.
|
|
22
|
-
"@salesforce/ui-bundle": "^11.
|
|
21
|
+
"@salesforce/platform-sdk": "^11.22.1",
|
|
22
|
+
"@salesforce/ui-bundle": "^11.22.1",
|
|
23
23
|
"@tailwindcss/vite": "^4.1.17",
|
|
24
24
|
"class-variance-authority": "^0.7.1",
|
|
25
25
|
"clsx": "^2.1.1",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"@graphql-eslint/eslint-plugin": "^4.1.0",
|
|
47
47
|
"@graphql-tools/utils": "^11.0.0",
|
|
48
48
|
"@playwright/test": "^1.49.0",
|
|
49
|
-
"@salesforce/graphiti": "^11.
|
|
50
|
-
"@salesforce/vite-plugin-ui-bundle": "^11.
|
|
49
|
+
"@salesforce/graphiti": "^11.22.1",
|
|
50
|
+
"@salesforce/vite-plugin-ui-bundle": "^11.22.1",
|
|
51
51
|
"@testing-library/jest-dom": "^6.6.3",
|
|
52
52
|
"@testing-library/react": "^16.1.0",
|
|
53
53
|
"@testing-library/user-event": "^14.5.2",
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Dialog,
|
|
4
|
+
DialogContent,
|
|
5
|
+
DialogHeader,
|
|
6
|
+
DialogTitle,
|
|
7
|
+
DialogFooter,
|
|
8
|
+
} from "../ui/dialog";
|
|
3
9
|
import { Button } from "../ui/button";
|
|
4
10
|
import type { ApplicationSearchNode } from "../../api/applications/applicationSearchService";
|
|
5
11
|
|
|
@@ -39,8 +45,6 @@ export const ApplicationDetailsModal: React.FC<ApplicationDetailsModalProps> = (
|
|
|
39
45
|
}
|
|
40
46
|
};
|
|
41
47
|
|
|
42
|
-
if (!isOpen) return null;
|
|
43
|
-
|
|
44
48
|
const applicantName = application.User__r?.Name?.value || "Unknown";
|
|
45
49
|
const propertyName = application.Property__r?.Name?.value;
|
|
46
50
|
const propertyAddress = application.Property__r?.Address__c?.value || "";
|
|
@@ -48,22 +52,13 @@ export const ApplicationDetailsModal: React.FC<ApplicationDetailsModalProps> = (
|
|
|
48
52
|
const references = application.References__c?.value;
|
|
49
53
|
|
|
50
54
|
return (
|
|
51
|
-
<
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
<h2 className="text-xl font-semibold text-gray-900">Application Details</h2>
|
|
57
|
-
<button
|
|
58
|
-
onClick={onClose}
|
|
59
|
-
aria-label="Close"
|
|
60
|
-
className="text-gray-400 hover:text-gray-600 transition-colors"
|
|
61
|
-
>
|
|
62
|
-
<X className="w-6 h-6" aria-hidden="true" />
|
|
63
|
-
</button>
|
|
64
|
-
</div>
|
|
55
|
+
<Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>
|
|
56
|
+
<DialogContent className="sm:max-w-2xl max-h-[90vh] overflow-y-auto">
|
|
57
|
+
<DialogHeader>
|
|
58
|
+
<DialogTitle>Application Details</DialogTitle>
|
|
59
|
+
</DialogHeader>
|
|
65
60
|
|
|
66
|
-
<div className="
|
|
61
|
+
<div className="space-y-6">
|
|
67
62
|
<div>
|
|
68
63
|
<h3 className="text-sm font-semibold text-gray-500 uppercase tracking-wide mb-2">
|
|
69
64
|
Applicant
|
|
@@ -127,7 +122,7 @@ export const ApplicationDetailsModal: React.FC<ApplicationDetailsModalProps> = (
|
|
|
127
122
|
</div>
|
|
128
123
|
</div>
|
|
129
124
|
|
|
130
|
-
<
|
|
125
|
+
<DialogFooter>
|
|
131
126
|
<Button variant="outline" onClick={onClose} disabled={isSaving}>
|
|
132
127
|
Close
|
|
133
128
|
</Button>
|
|
@@ -140,8 +135,8 @@ export const ApplicationDetailsModal: React.FC<ApplicationDetailsModalProps> = (
|
|
|
140
135
|
{isSaving ? "Saving..." : "Save Changes"}
|
|
141
136
|
</Button>
|
|
142
137
|
)}
|
|
143
|
-
</
|
|
144
|
-
</
|
|
145
|
-
</
|
|
138
|
+
</DialogFooter>
|
|
139
|
+
</DialogContent>
|
|
140
|
+
</Dialog>
|
|
146
141
|
);
|
|
147
142
|
};
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Dialog,
|
|
4
|
+
DialogContent,
|
|
5
|
+
DialogHeader,
|
|
6
|
+
DialogTitle,
|
|
7
|
+
DialogFooter,
|
|
8
|
+
} from "../ui/dialog";
|
|
3
9
|
import { Button } from "../ui/button";
|
|
4
10
|
import { Badge } from "../ui/badge";
|
|
5
11
|
import type { MaintenanceRequestSearchNode } from "../../api/maintenanceRequests/maintenanceRequestSearchService";
|
|
@@ -53,8 +59,6 @@ export const MaintenanceDetailsModal: React.FC<MaintenanceDetailsModalProps> = (
|
|
|
53
59
|
}
|
|
54
60
|
};
|
|
55
61
|
|
|
56
|
-
if (!isOpen) return null;
|
|
57
|
-
|
|
58
62
|
const description = request.Description__c?.value || "";
|
|
59
63
|
const issueType = request.Type__c?.value || "General";
|
|
60
64
|
const propertyAddress = request.Property__r?.Address__c?.value || "Unknown Address";
|
|
@@ -64,22 +68,13 @@ export const MaintenanceDetailsModal: React.FC<MaintenanceDetailsModalProps> = (
|
|
|
64
68
|
const priority = request.Priority__c?.value;
|
|
65
69
|
|
|
66
70
|
return (
|
|
67
|
-
<
|
|
68
|
-
<
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
<h2 className="text-xl font-semibold text-gray-900">Maintenance Request Details</h2>
|
|
73
|
-
<button
|
|
74
|
-
onClick={onClose}
|
|
75
|
-
aria-label="Close"
|
|
76
|
-
className="text-gray-400 hover:text-gray-600 transition-colors"
|
|
77
|
-
>
|
|
78
|
-
<X className="w-6 h-6" aria-hidden="true" />
|
|
79
|
-
</button>
|
|
80
|
-
</div>
|
|
71
|
+
<Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>
|
|
72
|
+
<DialogContent className="sm:max-w-2xl max-h-[90vh] overflow-y-auto">
|
|
73
|
+
<DialogHeader>
|
|
74
|
+
<DialogTitle>Maintenance Request Details</DialogTitle>
|
|
75
|
+
</DialogHeader>
|
|
81
76
|
|
|
82
|
-
<div className="
|
|
77
|
+
<div className="space-y-6">
|
|
83
78
|
{/* Description */}
|
|
84
79
|
<div>
|
|
85
80
|
<h3 className="text-sm font-semibold text-gray-500 uppercase tracking-wide mb-2">
|
|
@@ -160,7 +155,7 @@ export const MaintenanceDetailsModal: React.FC<MaintenanceDetailsModalProps> = (
|
|
|
160
155
|
</div>
|
|
161
156
|
</div>
|
|
162
157
|
|
|
163
|
-
<
|
|
158
|
+
<DialogFooter>
|
|
164
159
|
<Button variant="outline" onClick={onClose} disabled={isSaving}>
|
|
165
160
|
Close
|
|
166
161
|
</Button>
|
|
@@ -173,9 +168,9 @@ export const MaintenanceDetailsModal: React.FC<MaintenanceDetailsModalProps> = (
|
|
|
173
168
|
{isSaving ? "Saving..." : "Save Changes"}
|
|
174
169
|
</Button>
|
|
175
170
|
)}
|
|
176
|
-
</
|
|
177
|
-
</
|
|
178
|
-
</
|
|
171
|
+
</DialogFooter>
|
|
172
|
+
</DialogContent>
|
|
173
|
+
</Dialog>
|
|
179
174
|
);
|
|
180
175
|
};
|
|
181
176
|
|
|
@@ -30,7 +30,7 @@ export function SortControl({ configs, sort, onSortChange, className }: SortCont
|
|
|
30
30
|
else onSortChange({ field: v, direction: sort?.direction ?? "ASC" });
|
|
31
31
|
}}
|
|
32
32
|
>
|
|
33
|
-
<SelectTrigger size="sm" className="w-[160px]">
|
|
33
|
+
<SelectTrigger size="sm" className="w-[160px]" aria-label="Sort by">
|
|
34
34
|
<SelectValue placeholder="Default" />
|
|
35
35
|
</SelectTrigger>
|
|
36
36
|
<SelectContent>
|
|
@@ -4,7 +4,9 @@ import { Label } from "../../../../../components/ui/label";
|
|
|
4
4
|
interface FilterFieldWrapperProps {
|
|
5
5
|
label: string;
|
|
6
6
|
htmlFor?: string;
|
|
7
|
+
errorId?: string;
|
|
7
8
|
helpText?: string;
|
|
9
|
+
error?: string;
|
|
8
10
|
className?: string;
|
|
9
11
|
children: ReactNode;
|
|
10
12
|
}
|
|
@@ -12,7 +14,9 @@ interface FilterFieldWrapperProps {
|
|
|
12
14
|
export function FilterFieldWrapper({
|
|
13
15
|
label,
|
|
14
16
|
htmlFor,
|
|
17
|
+
errorId,
|
|
15
18
|
helpText,
|
|
19
|
+
error,
|
|
16
20
|
className,
|
|
17
21
|
children,
|
|
18
22
|
}: FilterFieldWrapperProps) {
|
|
@@ -20,7 +24,15 @@ export function FilterFieldWrapper({
|
|
|
20
24
|
<div className={`space-y-1 ${className ?? ""}`}>
|
|
21
25
|
<Label htmlFor={htmlFor}>{label}</Label>
|
|
22
26
|
{children}
|
|
23
|
-
|
|
27
|
+
<div className="min-h-4">
|
|
28
|
+
{error ? (
|
|
29
|
+
<p id={errorId} role="alert" className="text-xs text-destructive">
|
|
30
|
+
{error}
|
|
31
|
+
</p>
|
|
32
|
+
) : (
|
|
33
|
+
helpText && <p className="text-xs text-muted-foreground">{helpText}</p>
|
|
34
|
+
)}
|
|
35
|
+
</div>
|
|
24
36
|
</div>
|
|
25
37
|
);
|
|
26
38
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect, useRef, useState } from "react";
|
|
1
|
+
import { useEffect, useId, useRef, useState } from "react";
|
|
2
2
|
import { Input } from "../../../../../components/ui/input";
|
|
3
3
|
import { useFilterField } from "../FilterContext";
|
|
4
4
|
import { FilterFieldWrapper } from "./FilterFieldWrapper";
|
|
@@ -14,6 +14,7 @@ interface NumericRangeFilterProps {
|
|
|
14
14
|
|
|
15
15
|
export function NumericRangeFilter({ field, label, helpText, min, max }: NumericRangeFilterProps) {
|
|
16
16
|
const { value, onChange } = useFilterField(field);
|
|
17
|
+
const errorId = useId();
|
|
17
18
|
const [draftMin, setDraftMin] = useState(value?.min ?? "");
|
|
18
19
|
const [draftMax, setDraftMax] = useState(value?.max ?? "");
|
|
19
20
|
|
|
@@ -44,8 +45,33 @@ export function NumericRangeFilter({ field, label, helpText, min, max }: Numeric
|
|
|
44
45
|
setDraftMax(value?.max ?? "");
|
|
45
46
|
}, [value?.min, value?.max]);
|
|
46
47
|
|
|
48
|
+
const isOutOfBounds = (v: string) => {
|
|
49
|
+
if (v === "") return false;
|
|
50
|
+
const n = Number(v);
|
|
51
|
+
return (min != null && n < min) || (max != null && n > max);
|
|
52
|
+
};
|
|
53
|
+
const minOutOfBounds = isOutOfBounds(draftMin);
|
|
54
|
+
const maxOutOfBounds = isOutOfBounds(draftMax);
|
|
55
|
+
const isRangeInverted = draftMin !== "" && draftMax !== "" && Number(draftMin) > Number(draftMax);
|
|
56
|
+
const hasError = minOutOfBounds || maxOutOfBounds || isRangeInverted;
|
|
57
|
+
|
|
58
|
+
const boundsLabel =
|
|
59
|
+
min != null && max != null
|
|
60
|
+
? `${min}–${max}`
|
|
61
|
+
: min != null
|
|
62
|
+
? `${min} or more`
|
|
63
|
+
: max != null
|
|
64
|
+
? `${max} or less`
|
|
65
|
+
: null;
|
|
66
|
+
|
|
67
|
+
const errorMessage = isRangeInverted
|
|
68
|
+
? "Min must not exceed max"
|
|
69
|
+
: (minOutOfBounds || maxOutOfBounds) && boundsLabel
|
|
70
|
+
? `Value must be between ${boundsLabel}`
|
|
71
|
+
: undefined;
|
|
72
|
+
|
|
47
73
|
return (
|
|
48
|
-
<FilterFieldWrapper label={label} helpText={helpText}>
|
|
74
|
+
<FilterFieldWrapper label={label} helpText={helpText} error={errorMessage} errorId={errorId}>
|
|
49
75
|
<div className="flex items-center gap-2">
|
|
50
76
|
<Input
|
|
51
77
|
type="number"
|
|
@@ -58,6 +84,8 @@ export function NumericRangeFilter({ field, label, helpText, min, max }: Numeric
|
|
|
58
84
|
debouncedRef.current?.(e.target.value, draftMax);
|
|
59
85
|
}}
|
|
60
86
|
aria-label={`${label} minimum`}
|
|
87
|
+
aria-invalid={hasError || undefined}
|
|
88
|
+
aria-describedby={hasError ? errorId : undefined}
|
|
61
89
|
/>
|
|
62
90
|
<span className="text-sm text-muted-foreground">–</span>
|
|
63
91
|
<Input
|
|
@@ -71,6 +99,8 @@ export function NumericRangeFilter({ field, label, helpText, min, max }: Numeric
|
|
|
71
99
|
debouncedRef.current?.(draftMin, e.target.value);
|
|
72
100
|
}}
|
|
73
101
|
aria-label={`${label} maximum`}
|
|
102
|
+
aria-invalid={hasError || undefined}
|
|
103
|
+
aria-describedby={hasError ? errorId : undefined}
|
|
74
104
|
/>
|
|
75
105
|
</div>
|
|
76
106
|
</FilterFieldWrapper>
|
package/dist/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/ui-bundle-template-base-sfdx-project",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.22.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@salesforce/ui-bundle-template-base-sfdx-project",
|
|
9
|
-
"version": "11.
|
|
9
|
+
"version": "11.22.1",
|
|
10
10
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"fast-xml-parser": "^5.9.3",
|
package/dist/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/ui-bundle-template-app-react-sample-b2e",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.22.1",
|
|
4
4
|
"description": "Salesforce sample property rental React app",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"author": "",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"clean": "rm -rf dist"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@salesforce/ui-bundle": "^11.
|
|
19
|
+
"@salesforce/ui-bundle": "^11.22.1",
|
|
20
20
|
"sonner": "^1.7.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|