@salesforce/ui-bundle-template-app-react-sample-b2e 11.19.0 → 11.21.0
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/api/applications/applicationSearchService.ts +25 -43
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/api/maintenanceRequests/maintenanceRequestSearchService.ts +31 -65
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/api/maintenanceWorkers/maintenanceWorkerSearchService.ts +21 -43
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/api/properties/propertySearchService.ts +33 -53
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/components/applications/ApplicationCard.tsx +80 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/components/dashboard/GlobalSearchBar.tsx +2 -2
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/components/layout/VerticalNav.tsx +28 -18
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/components/maintenanceRequests/MaintenanceRequestCard.tsx +79 -52
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/components/maintenanceWorkers/WorkerCard.tsx +87 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/components/search/UnifiedSearch.tsx +213 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/api/distinctValuesService.ts +84 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/api/searchService.ts +71 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/MergedSearchResults.tsx +263 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/Search.tsx +185 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/SearchResults.tsx +77 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/SourceSection.tsx +166 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/controls/PaginationControls.tsx +185 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/controls/ScopeSelector.tsx +55 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/controls/SearchBar.tsx +55 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/controls/SortControl.tsx +62 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/filters/ActiveFilters.tsx +61 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/filters/DefaultFilterPanel.tsx +125 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/{object-search/components → search/components/filters}/FilterContext.tsx +7 -20
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/filters/inputs/BooleanFilter.tsx +50 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/filters/inputs/DateRangeFilter.tsx +160 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/filters/inputs/FilterFieldWrapper.tsx +26 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/filters/inputs/MultiSelectFilter.tsx +88 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/filters/inputs/NumericRangeFilter.tsx +78 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/filters/inputs/SelectFilter.tsx +46 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/filters/inputs/TextFilter.tsx +52 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/components/results/DefaultResultRow.tsx +109 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/config.json +83 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/{object-search → search}/hooks/useAsyncData.ts +3 -10
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/hooks/useDistinctValues.ts +59 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/hooks/useSearch.ts +703 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/index.ts +90 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/loadConfig.ts +14 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/queryBuilder.ts +156 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/types.ts +307 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/utils/debounce.ts +17 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/utils/fieldUtils.ts +14 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/utils/filterUtils.ts +285 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/search/utils/sortUtils.ts +34 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/lib/constants.ts +16 -29
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/lib/routeConfig.ts +1 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/lib/searchConfig.ts +190 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/pages/ApplicationSearch.tsx +8 -385
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/pages/Home.tsx +4 -2
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/pages/MaintenanceRequestSearch.tsx +8 -458
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/pages/MaintenanceWorkerSearch.tsx +8 -341
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/pages/PropertySearch.tsx +7 -243
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/pages/Search.tsx +16 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/routes.tsx +6 -0
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/tsconfig.tsbuildinfo +1 -1
- package/dist/package-lock.json +2 -2
- package/dist/package.json +1 -1
- package/package.json +2 -2
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/api/applications/query/distinctApplicationStatus.graphql +0 -19
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/api/applications/query/searchApplications.graphql +0 -65
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/api/maintenanceRequests/query/distinctMaintenanceRequestPriority.graphql +0 -19
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/api/maintenanceRequests/query/distinctMaintenanceRequestStatus.graphql +0 -19
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/api/maintenanceRequests/query/distinctMaintenanceRequestType.graphql +0 -19
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/api/maintenanceRequests/query/searchMaintenanceRequests.graphql +0 -82
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/api/maintenanceWorkers/query/distinctMaintenanceWorkerEmploymentType.graphql +0 -19
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/api/maintenanceWorkers/query/searchMaintenanceWorkers.graphql +0 -64
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/api/properties/query/distinctPropertyStatus.graphql +0 -19
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/api/properties/query/distinctPropertyType.graphql +0 -19
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/api/properties/query/searchProperties.graphql +0 -105
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/components/shared/ObjectSearchErrorState.tsx +0 -45
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/components/shared/UserAvatar.tsx +0 -35
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/__examples__/api/accountSearchService.ts +0 -46
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/__examples__/api/query/distinctAccountIndustries.graphql +0 -19
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/__examples__/api/query/distinctAccountTypes.graphql +0 -19
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/__examples__/api/query/getAccountDetail.graphql +0 -121
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/__examples__/api/query/searchAccounts.graphql +0 -51
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/__examples__/pages/AccountObjectDetailPage.tsx +0 -355
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/__examples__/pages/AccountSearch.tsx +0 -304
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/__examples__/pages/Home.tsx +0 -34
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/api/objectSearchService.ts +0 -82
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/components/ActiveFilters.tsx +0 -89
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/components/ObjectBreadcrumb.tsx +0 -66
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/components/PaginationControls.tsx +0 -109
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/components/SearchBar.tsx +0 -41
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/components/SortControl.tsx +0 -143
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/components/filters/BooleanFilter.tsx +0 -78
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/components/filters/DateFilter.tsx +0 -128
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/components/filters/DateRangeFilter.tsx +0 -70
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/components/filters/FilterFieldWrapper.tsx +0 -43
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/components/filters/MultiSelectFilter.tsx +0 -105
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/components/filters/NumericRangeFilter.tsx +0 -171
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/components/filters/SearchFilter.tsx +0 -52
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/components/filters/SelectFilter.tsx +0 -97
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/components/filters/TextFilter.tsx +0 -93
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/hooks/useDebouncedCallback.ts +0 -34
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/hooks/useObjectSearchParams.ts +0 -254
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/utils/debounce.ts +0 -25
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/utils/fieldUtils.ts +0 -29
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/utils/filterUtils.ts +0 -404
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/features/object-search/utils/sortUtils.ts +0 -38
- package/dist/force-app/main/default/uiBundles/propertymanagementapp/src/lib/filterUtils.ts +0 -11
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.21.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v11.20.0...v11.21.0) (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.20.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v11.19.0...v11.20.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.19.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v11.18.0...v11.19.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.21.0",
|
|
22
|
+
"@salesforce/ui-bundle": "^11.21.0",
|
|
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.21.0",
|
|
50
|
+
"@salesforce/vite-plugin-ui-bundle": "^11.21.0",
|
|
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,46 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
SearchApplicationsQuery,
|
|
11
|
-
SearchApplicationsQueryVariables,
|
|
12
|
-
DistinctApplicationStatusQuery,
|
|
13
|
-
} from "../graphql-operations-types";
|
|
1
|
+
/**
|
|
2
|
+
* Application search result types.
|
|
3
|
+
*
|
|
4
|
+
* Search itself is now driven by feature-react-search (see `lib/searchConfig.ts`),
|
|
5
|
+
* which builds and runs its GraphQL at runtime — there is no generated
|
|
6
|
+
* `SearchApplicationsQuery` operation type to derive from. This module declares the
|
|
7
|
+
* node shape that the result card and detail modal read, mirroring the Salesforce
|
|
8
|
+
* UI API field-wrapper shape (`{ value, displayValue }`).
|
|
9
|
+
*/
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
>;
|
|
11
|
+
/** A Salesforce UI API scalar field wrapper. */
|
|
12
|
+
type Field<T> = { value?: T | null; displayValue?: string | null } | null;
|
|
18
13
|
|
|
19
|
-
export
|
|
20
|
-
|
|
21
|
-
>;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return searchObjects<
|
|
34
|
-
ApplicationSearchResult,
|
|
35
|
-
SearchApplicationsQuery,
|
|
36
|
-
SearchApplicationsQueryVariables
|
|
37
|
-
>(SEARCH_QUERY, "Application__c", options);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export async function fetchDistinctApplicationStatus(): Promise<PicklistOption[]> {
|
|
41
|
-
return fetchDistinctValues<DistinctApplicationStatusQuery>(
|
|
42
|
-
DISTINCT_STATUS_QUERY,
|
|
43
|
-
"Application__c",
|
|
44
|
-
"Status__c",
|
|
45
|
-
);
|
|
14
|
+
export interface ApplicationSearchNode {
|
|
15
|
+
Id: string;
|
|
16
|
+
Name?: Field<string>;
|
|
17
|
+
Status__c?: Field<string>;
|
|
18
|
+
Start_Date__c?: Field<string>;
|
|
19
|
+
Employment__c?: Field<string>;
|
|
20
|
+
References__c?: Field<string>;
|
|
21
|
+
User__r?: {
|
|
22
|
+
Name?: Field<string>;
|
|
23
|
+
} | null;
|
|
24
|
+
Property__r?: {
|
|
25
|
+
Name?: Field<string>;
|
|
26
|
+
Address__c?: Field<string>;
|
|
27
|
+
} | null;
|
|
46
28
|
}
|
|
@@ -1,66 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
>;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
>;
|
|
31
|
-
|
|
32
|
-
export type { PicklistOption };
|
|
33
|
-
|
|
34
|
-
export async function searchMaintenanceRequests(
|
|
35
|
-
options: MaintenanceRequestSearchOptions = {},
|
|
36
|
-
): Promise<MaintenanceRequestSearchResult> {
|
|
37
|
-
return searchObjects<
|
|
38
|
-
MaintenanceRequestSearchResult,
|
|
39
|
-
SearchMaintenanceRequestsQuery,
|
|
40
|
-
SearchMaintenanceRequestsQueryVariables
|
|
41
|
-
>(SEARCH_QUERY, "Maintenance_Request__c", options);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export async function fetchDistinctMaintenanceRequestStatus(): Promise<PicklistOption[]> {
|
|
45
|
-
return fetchDistinctValues<DistinctMaintenanceRequestStatusQuery>(
|
|
46
|
-
DISTINCT_STATUS_QUERY,
|
|
47
|
-
"Maintenance_Request__c",
|
|
48
|
-
"Status__c",
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export async function fetchDistinctMaintenanceRequestType(): Promise<PicklistOption[]> {
|
|
53
|
-
return fetchDistinctValues<DistinctMaintenanceRequestTypeQuery>(
|
|
54
|
-
DISTINCT_TYPE_QUERY,
|
|
55
|
-
"Maintenance_Request__c",
|
|
56
|
-
"Type__c",
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export async function fetchDistinctMaintenanceRequestPriority(): Promise<PicklistOption[]> {
|
|
61
|
-
return fetchDistinctValues<DistinctMaintenanceRequestPriorityQuery>(
|
|
62
|
-
DISTINCT_PRIORITY_QUERY,
|
|
63
|
-
"Maintenance_Request__c",
|
|
64
|
-
"Priority__c",
|
|
65
|
-
);
|
|
1
|
+
/**
|
|
2
|
+
* Maintenance-request search result types.
|
|
3
|
+
*
|
|
4
|
+
* Search itself is now driven by feature-react-search (see `lib/searchConfig.ts`),
|
|
5
|
+
* which builds and runs its GraphQL at runtime — there is no generated
|
|
6
|
+
* `SearchMaintenanceRequestsQuery` operation type to derive from. This module
|
|
7
|
+
* declares the node shape that the result card and detail modal read, mirroring
|
|
8
|
+
* the Salesforce UI API field-wrapper shape (`{ value, displayValue }`).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** A Salesforce UI API scalar field wrapper. */
|
|
12
|
+
type Field<T> = { value?: T | null; displayValue?: string | null } | null;
|
|
13
|
+
|
|
14
|
+
export interface MaintenanceRequestSearchNode {
|
|
15
|
+
Id: string;
|
|
16
|
+
Name?: Field<string>;
|
|
17
|
+
Type__c?: Field<string>;
|
|
18
|
+
Priority__c?: Field<string>;
|
|
19
|
+
Status__c?: Field<string>;
|
|
20
|
+
Description__c?: Field<string>;
|
|
21
|
+
Scheduled__c?: Field<string>;
|
|
22
|
+
Property__r?: {
|
|
23
|
+
Name?: Field<string>;
|
|
24
|
+
Address__c?: Field<string>;
|
|
25
|
+
} | null;
|
|
26
|
+
Assigned_Worker__r?: {
|
|
27
|
+
Name?: Field<string>;
|
|
28
|
+
} | null;
|
|
29
|
+
User__r?: {
|
|
30
|
+
Name?: Field<string>;
|
|
31
|
+
} | null;
|
|
66
32
|
}
|
|
@@ -1,46 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
SearchMaintenanceWorkersQuery,
|
|
11
|
-
SearchMaintenanceWorkersQueryVariables,
|
|
12
|
-
DistinctMaintenanceWorkerEmploymentTypeQuery,
|
|
13
|
-
} from "../graphql-operations-types.js";
|
|
1
|
+
/**
|
|
2
|
+
* Maintenance-worker search result types.
|
|
3
|
+
*
|
|
4
|
+
* Search itself is now driven by feature-react-search (see `lib/searchConfig.ts`),
|
|
5
|
+
* which builds and runs its GraphQL at runtime — there is no generated
|
|
6
|
+
* `SearchMaintenanceWorkersQuery` operation type to derive from. This module
|
|
7
|
+
* declares the node shape that the result card and detail modal read, mirroring
|
|
8
|
+
* the Salesforce UI API field-wrapper shape (`{ value, displayValue }`).
|
|
9
|
+
*/
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
>;
|
|
11
|
+
/** A Salesforce UI API scalar field wrapper. */
|
|
12
|
+
type Field<T> = { value?: T | null; displayValue?: string | null } | null;
|
|
18
13
|
|
|
19
|
-
export
|
|
20
|
-
|
|
21
|
-
>;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
>;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
export async function searchMaintenanceWorkers(
|
|
31
|
-
options: MaintenanceWorkerSearchOptions = {},
|
|
32
|
-
): Promise<MaintenanceWorkerSearchResult> {
|
|
33
|
-
return searchObjects<
|
|
34
|
-
MaintenanceWorkerSearchResult,
|
|
35
|
-
SearchMaintenanceWorkersQuery,
|
|
36
|
-
SearchMaintenanceWorkersQueryVariables
|
|
37
|
-
>(SEARCH_QUERY, "Maintenance_Worker__c", options);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export async function fetchDistinctMaintenanceWorkerType(): Promise<PicklistOption[]> {
|
|
41
|
-
return fetchDistinctValues<DistinctMaintenanceWorkerEmploymentTypeQuery>(
|
|
42
|
-
DISTINCT_TYPE_QUERY,
|
|
43
|
-
"Maintenance_Worker__c",
|
|
44
|
-
"Employment_Type__c",
|
|
45
|
-
);
|
|
14
|
+
export interface MaintenanceWorkerSearchNode {
|
|
15
|
+
Id: string;
|
|
16
|
+
Name?: Field<string>;
|
|
17
|
+
Employment_Type__c?: Field<string>;
|
|
18
|
+
Type__c?: Field<string>;
|
|
19
|
+
Phone__c?: Field<string>;
|
|
20
|
+
Location__c?: Field<string>;
|
|
21
|
+
Rating__c?: Field<number>;
|
|
22
|
+
Hourly_Rate__c?: Field<number>;
|
|
23
|
+
IsActive__c?: Field<boolean>;
|
|
46
24
|
}
|
|
@@ -1,56 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import type {
|
|
11
|
-
SearchPropertiesQuery,
|
|
12
|
-
SearchPropertiesQueryVariables,
|
|
13
|
-
DistinctPropertyStatusQuery,
|
|
14
|
-
DistinctPropertyTypeQuery,
|
|
15
|
-
} from "../graphql-operations-types";
|
|
1
|
+
/**
|
|
2
|
+
* Property search result types.
|
|
3
|
+
*
|
|
4
|
+
* Search itself is now driven by feature-react-search (see `lib/searchConfig.ts`),
|
|
5
|
+
* which builds and runs its GraphQL at runtime — there is no generated
|
|
6
|
+
* `SearchPropertiesQuery` operation type to derive from. This module declares the
|
|
7
|
+
* node shape that the property result card and detail modal read, mirroring the
|
|
8
|
+
* Salesforce UI API field-wrapper shape (`{ value, displayValue }`).
|
|
9
|
+
*/
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
>;
|
|
11
|
+
/** A Salesforce UI API scalar field wrapper. */
|
|
12
|
+
type Field<T> = { value?: T | null; displayValue?: string | null } | null;
|
|
20
13
|
|
|
21
|
-
export
|
|
22
|
-
|
|
23
|
-
>;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
>;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return fetchDistinctValues<DistinctPropertyStatusQuery>(
|
|
44
|
-
DISTINCT_STATUS_QUERY,
|
|
45
|
-
"Property__c",
|
|
46
|
-
"Status__c",
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export async function fetchDistinctPropertyType(): Promise<PicklistOption[]> {
|
|
51
|
-
return fetchDistinctValues<DistinctPropertyTypeQuery>(
|
|
52
|
-
DISTINCT_TYPE_QUERY,
|
|
53
|
-
"Property__c",
|
|
54
|
-
"Type__c",
|
|
55
|
-
);
|
|
14
|
+
export interface PropertySearchNode {
|
|
15
|
+
Id: string;
|
|
16
|
+
Name?: Field<string>;
|
|
17
|
+
Address__c?: Field<string>;
|
|
18
|
+
Description__c?: Field<string>;
|
|
19
|
+
Type__c?: Field<string>;
|
|
20
|
+
Status__c?: Field<string>;
|
|
21
|
+
Hero_Image__c?: Field<string>;
|
|
22
|
+
Tour_URL__c?: Field<string>;
|
|
23
|
+
Features__c?: Field<string>;
|
|
24
|
+
Utilities__c?: Field<string>;
|
|
25
|
+
Available_Date__c?: Field<string>;
|
|
26
|
+
CreatedDate?: Field<string>;
|
|
27
|
+
Monthly_Rent__c?: Field<number>;
|
|
28
|
+
Bedrooms__c?: Field<number>;
|
|
29
|
+
Bathrooms__c?: Field<number>;
|
|
30
|
+
Sq_Ft__c?: Field<number>;
|
|
31
|
+
Year_Built__c?: Field<number>;
|
|
32
|
+
Deposit__c?: Field<number>;
|
|
33
|
+
Lease_Term__c?: Field<number>;
|
|
34
|
+
Parking__c?: Field<number>;
|
|
35
|
+
Pet_Friendly__c?: Field<boolean>;
|
|
56
36
|
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { FileText, User, Home, CalendarDays } from "lucide-react";
|
|
3
|
+
import type { ApplicationSearchNode } from "../../api/applications/applicationSearchService";
|
|
4
|
+
|
|
5
|
+
interface ApplicationCardProps {
|
|
6
|
+
application: ApplicationSearchNode;
|
|
7
|
+
onClick?: (application: ApplicationSearchNode) => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function statusColor(status: string): string {
|
|
11
|
+
const s = status.toLowerCase();
|
|
12
|
+
if (s.includes("approved")) return "bg-green-100 text-green-700";
|
|
13
|
+
if (s.includes("rejected")) return "bg-red-100 text-red-700";
|
|
14
|
+
if (s.includes("background")) return "bg-blue-100 text-blue-700";
|
|
15
|
+
if (s.includes("review")) return "bg-yellow-100 text-yellow-700";
|
|
16
|
+
return "bg-gray-100 text-gray-700";
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function formatDate(value: string | null | undefined): string | undefined {
|
|
20
|
+
if (!value) return undefined;
|
|
21
|
+
const date = new Date(value);
|
|
22
|
+
if (isNaN(date.getTime())) return undefined;
|
|
23
|
+
return date.toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric" });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const ApplicationCard: React.FC<ApplicationCardProps> = ({ application, onClick }) => {
|
|
27
|
+
const name = application.Name?.value || "Application";
|
|
28
|
+
const applicant = application.User__r?.Name?.value || "Unknown applicant";
|
|
29
|
+
const propertyName = application.Property__r?.Name?.value;
|
|
30
|
+
const propertyAddress = application.Property__r?.Address__c?.value;
|
|
31
|
+
const status = application.Status__c?.value || "Unknown";
|
|
32
|
+
const startDate = formatDate(application.Start_Date__c?.value);
|
|
33
|
+
|
|
34
|
+
const handleClick = () => onClick?.(application);
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<div
|
|
38
|
+
role="button"
|
|
39
|
+
tabIndex={0}
|
|
40
|
+
aria-label={name}
|
|
41
|
+
className="h-full bg-white rounded-lg shadow-md p-5 hover:shadow-lg transition-shadow cursor-pointer flex flex-col gap-3 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-purple focus-visible:ring-offset-2"
|
|
42
|
+
onClick={handleClick}
|
|
43
|
+
onKeyDown={(e) => {
|
|
44
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
45
|
+
e.preventDefault();
|
|
46
|
+
handleClick();
|
|
47
|
+
}
|
|
48
|
+
}}
|
|
49
|
+
>
|
|
50
|
+
<div className="flex items-start justify-between gap-2">
|
|
51
|
+
<div className="flex items-center gap-2 min-w-0">
|
|
52
|
+
<FileText className="w-5 h-5 text-purple-600 shrink-0" />
|
|
53
|
+
<h3 className="text-base font-semibold text-gray-900 truncate">{name}</h3>
|
|
54
|
+
</div>
|
|
55
|
+
<span
|
|
56
|
+
className={`shrink-0 px-2.5 py-0.5 rounded-full text-xs font-medium ${statusColor(status)}`}
|
|
57
|
+
>
|
|
58
|
+
{status}
|
|
59
|
+
</span>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<div className="mt-auto space-y-1 text-sm text-gray-600">
|
|
63
|
+
<div className="flex items-center gap-2">
|
|
64
|
+
<User className="w-4 h-4 text-gray-400 shrink-0" />
|
|
65
|
+
<span className="truncate">{applicant}</span>
|
|
66
|
+
</div>
|
|
67
|
+
<div className="flex items-center gap-2">
|
|
68
|
+
<Home className="w-4 h-4 text-gray-400 shrink-0" />
|
|
69
|
+
<span className="truncate">{propertyName || propertyAddress || "Unknown property"}</span>
|
|
70
|
+
</div>
|
|
71
|
+
{startDate && (
|
|
72
|
+
<div className="flex items-center gap-2">
|
|
73
|
+
<CalendarDays className="w-4 h-4 text-gray-400 shrink-0" />
|
|
74
|
+
<span className="truncate">Starts {startDate}</span>
|
|
75
|
+
</div>
|
|
76
|
+
)}
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
);
|
|
80
|
+
};
|
|
@@ -92,9 +92,9 @@ export function GlobalSearchBar({
|
|
|
92
92
|
type="button"
|
|
93
93
|
onClick={onBrowseAll}
|
|
94
94
|
className="px-4 py-3 text-sm font-medium text-[#372949] bg-white border border-gray-200 rounded-full shadow-sm hover:bg-gray-50 whitespace-nowrap"
|
|
95
|
-
aria-label={`Browse
|
|
95
|
+
aria-label={`Browse ${labelPlural}`}
|
|
96
96
|
>
|
|
97
|
-
Browse
|
|
97
|
+
Browse {labelPlural}
|
|
98
98
|
</button>
|
|
99
99
|
</div>
|
|
100
100
|
);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Link, useLocation } from "react-router";
|
|
3
|
+
import { Search as SearchIcon } from "lucide-react";
|
|
3
4
|
import dashboardIcon from "../../assets/icons/dashboard.svg";
|
|
4
5
|
import filesIcon from "../../assets/icons/files.svg";
|
|
5
6
|
import propertiesIcon from "../../assets/icons/properties.svg";
|
|
@@ -9,12 +10,14 @@ import { PATHS } from "../../lib/routeConfig";
|
|
|
9
10
|
|
|
10
11
|
interface NavItem {
|
|
11
12
|
path: string;
|
|
12
|
-
icon
|
|
13
|
+
/** Either an imported SVG asset URL or a lucide icon component. */
|
|
14
|
+
icon: string | React.ComponentType<{ className?: string }>;
|
|
13
15
|
label: string;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
const navItems: NavItem[] = [
|
|
17
19
|
{ path: PATHS.HOME, icon: dashboardIcon, label: "Dashboard" },
|
|
20
|
+
{ path: PATHS.SEARCH, icon: SearchIcon, label: "Search" },
|
|
18
21
|
{ path: PATHS.APPLICATIONS, icon: filesIcon, label: "Applications" },
|
|
19
22
|
{ path: PATHS.PROPERTIES, icon: propertiesIcon, label: "Properties" },
|
|
20
23
|
{ path: PATHS.MAINTENANCE_REQUESTS, icon: maintenanceIcon, label: "Maintenance Requests" },
|
|
@@ -37,23 +40,30 @@ export const VerticalNav: React.FC<VerticalNavProps> = ({ isOpen = false, onClos
|
|
|
37
40
|
};
|
|
38
41
|
|
|
39
42
|
const navContent = (handleClick?: () => void) =>
|
|
40
|
-
navItems.map((item) =>
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
isActive(item.path)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
43
|
+
navItems.map((item) => {
|
|
44
|
+
const Icon = typeof item.icon === "string" ? null : item.icon;
|
|
45
|
+
return (
|
|
46
|
+
<Link
|
|
47
|
+
key={item.path}
|
|
48
|
+
to={item.path}
|
|
49
|
+
onClick={handleClick}
|
|
50
|
+
aria-current={isActive(item.path) ? "page" : undefined}
|
|
51
|
+
className={`flex flex-col items-center justify-center gap-2 py-4 px-2 transition-colors ${
|
|
52
|
+
isActive(item.path)
|
|
53
|
+
? "bg-purple-100 text-purple-700 border-l-4 border-purple-700"
|
|
54
|
+
: "text-gray-600 hover:bg-gray-100 hover:text-gray-900"
|
|
55
|
+
}`}
|
|
56
|
+
title={item.label}
|
|
57
|
+
>
|
|
58
|
+
{Icon ? (
|
|
59
|
+
<Icon className="w-6 h-6" />
|
|
60
|
+
) : (
|
|
61
|
+
<img src={item.icon as string} alt="" className="w-6 h-6" />
|
|
62
|
+
)}
|
|
63
|
+
<span className="text-xs font-medium text-center">{item.label}</span>
|
|
64
|
+
</Link>
|
|
65
|
+
);
|
|
66
|
+
});
|
|
57
67
|
|
|
58
68
|
return (
|
|
59
69
|
<>
|