@salesforce/templates 66.6.2 → 66.7.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/lib/generators/projectGenerator.js +4 -4
- package/lib/generators/projectGenerator.js.map +1 -1
- package/lib/generators/{webApplicationGenerator.d.ts → uiBundleGenerator.d.ts} +2 -2
- package/lib/generators/{webApplicationGenerator.js → uiBundleGenerator.js} +23 -22
- package/lib/generators/uiBundleGenerator.js.map +1 -0
- package/lib/i18n/i18n.d.ts +1 -1
- package/lib/i18n/i18n.js +1 -1
- package/lib/i18n/i18n.js.map +1 -1
- package/lib/templates/project/reactexternalapp/AGENT.md +152 -46
- package/lib/templates/project/reactexternalapp/CHANGELOG.md +366 -208
- package/lib/templates/project/reactexternalapp/README.md +16 -16
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/CHANGELOG.md +1 -1
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/README.md +1 -1
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/eslint.config.js +13 -2
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package.json +3 -3
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/reactexternalapp.uibundle-meta.xml +8 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/scripts/get-graphql-schema.mjs +1 -1
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountSearch.tsx +15 -6
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/FilterContext.tsx +13 -3
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/BooleanFilter.tsx +9 -5
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateFilter.tsx +15 -8
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateRangeFilter.tsx +8 -7
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/FilterFieldWrapper.tsx +33 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/MultiSelectFilter.tsx +4 -5
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/NumericRangeFilter.tsx +118 -40
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SearchFilter.tsx +24 -11
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SelectFilter.tsx +9 -5
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/TextFilter.tsx +29 -12
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useDebouncedCallback.ts +34 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useObjectSearchParams.ts +10 -5
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/debounce.ts +4 -1
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/filterUtils.ts +24 -1
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/authentication/context/AuthContext.tsx +2 -2
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/authentication/hooks/useCountdownTimer.ts +1 -1
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/authentication/pages/Profile.tsx +3 -3
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/authentication/pages/Register.tsx +1 -1
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/authentication/sessionTimeout/SessionTimeoutValidator.tsx +12 -18
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/accountSearchService.ts +46 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountIndustries.graphql +19 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountTypes.graphql +19 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/query/getAccountDetail.graphql +121 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/query/searchAccounts.graphql +51 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/AccountObjectDetailPage.tsx +361 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/AccountSearch.tsx +305 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/Home.tsx +33 -11
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/routes.tsx +3 -3
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/vite.config.ts +1 -1
- package/lib/templates/project/reactexternalapp/_p_/_m_/classes/{WebAppAuthUtils.cls → UIBundleAuthUtils.cls} +1 -1
- package/lib/templates/project/reactexternalapp/_p_/_m_/classes/{WebAppChangePassword.cls → UIBundleChangePassword.cls} +2 -2
- package/lib/templates/project/reactexternalapp/_p_/_m_/classes/{WebAppForgotPassword.cls → UIBundleForgotPassword.cls} +2 -2
- package/lib/templates/project/reactexternalapp/_p_/_m_/classes/{WebAppLogin.cls → UIBundleLogin.cls} +6 -6
- package/lib/templates/project/reactexternalapp/_p_/_m_/classes/{WebAppRegistration.cls → UIBundleRegistration.cls} +10 -10
- package/lib/templates/project/reactexternalapp/_p_/_m_/networks/{reactexternalapp.network → reactexternalapp.network-meta.xml} +2 -2
- package/lib/templates/project/reactexternalapp/package.json +2 -2
- package/lib/templates/project/reactexternalapp/scripts/graphql-search.sh +4 -4
- package/lib/templates/project/reactexternalapp/scripts/setup-cli.mjs +51 -51
- package/lib/templates/project/reactexternalapp/scripts/sf-project-setup.mjs +16 -16
- package/lib/templates/project/reactinternalapp/AGENT.md +152 -46
- package/lib/templates/project/reactinternalapp/CHANGELOG.md +366 -208
- package/lib/templates/project/reactinternalapp/README.md +12 -12
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/CHANGELOG.md +1 -1
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/README.md +1 -1
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/eslint.config.js +13 -2
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/package.json +4 -4
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/reactinternalapp.uibundle-meta.xml +7 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/scripts/get-graphql-schema.mjs +1 -1
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountSearch.tsx +15 -6
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/FilterContext.tsx +13 -3
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/BooleanFilter.tsx +9 -5
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateFilter.tsx +15 -8
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateRangeFilter.tsx +8 -7
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/FilterFieldWrapper.tsx +33 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/MultiSelectFilter.tsx +4 -5
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/NumericRangeFilter.tsx +118 -40
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SearchFilter.tsx +24 -11
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SelectFilter.tsx +9 -5
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/TextFilter.tsx +29 -12
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useDebouncedCallback.ts +34 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useObjectSearchParams.ts +10 -5
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/debounce.ts +4 -1
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/filterUtils.ts +24 -1
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/accountSearchService.ts +46 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountIndustries.graphql +19 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountTypes.graphql +19 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/getAccountDetail.graphql +121 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/searchAccounts.graphql +51 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/AgentforceConversationClient.tsx +5 -2
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/pages/AccountObjectDetailPage.tsx +361 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/pages/AccountSearch.tsx +305 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/pages/Home.tsx +33 -11
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/routes.tsx +12 -1
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/types/conversation.ts +2 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/vite.config.ts +1 -1
- package/lib/templates/project/reactinternalapp/package.json +2 -2
- package/lib/templates/project/reactinternalapp/scripts/graphql-search.sh +4 -4
- package/lib/templates/project/reactinternalapp/scripts/setup-cli.mjs +51 -51
- package/lib/templates/project/reactinternalapp/scripts/sf-project-setup.mjs +16 -16
- package/lib/templates/{webapplication → uiBundles}/reactbasic/CHANGELOG.md +1 -1
- package/lib/templates/{webapplication → uiBundles}/reactbasic/README.md +10 -10
- package/lib/templates/{webapplication/reactbasic/_webapplication.webapplication-meta.xml → uiBundles/reactbasic/_uibundle.uibundle-meta.xml} +3 -3
- package/lib/templates/{webapplication → uiBundles}/reactbasic/eslint.config.js +13 -2
- package/lib/templates/{webapplication → uiBundles}/reactbasic/package.json +3 -3
- package/lib/templates/{webapplication → uiBundles}/reactbasic/scripts/get-graphql-schema.mjs +1 -1
- package/lib/templates/{webapplication → uiBundles}/reactbasic/vite.config.ts +1 -1
- package/lib/templates/uiBundles/webappbasic/README.md +15 -0
- package/lib/templates/{webapplication/webappbasic/_webapplication.webapplication-meta.xml → uiBundles/webappbasic/_uibundle.uibundle-meta.xml} +3 -3
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/utils/constants.d.ts +1 -0
- package/lib/utils/constants.js +2 -1
- package/lib/utils/constants.js.map +1 -1
- package/lib/utils/template-placeholders.d.ts +1 -1
- package/lib/utils/template-placeholders.js +11 -4
- package/lib/utils/template-placeholders.js.map +1 -1
- package/lib/utils/types.d.ts +5 -5
- package/lib/utils/types.js +3 -3
- package/lib/utils/types.js.map +1 -1
- package/lib/utils/{webappTemplateUtils.d.ts → uiBundleTemplateUtils.d.ts} +7 -5
- package/lib/utils/{webappTemplateUtils.js → uiBundleTemplateUtils.js} +15 -12
- package/lib/utils/uiBundleTemplateUtils.js.map +1 -0
- package/package.json +5 -5
- package/lib/generators/webApplicationGenerator.js.map +0 -1
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/reactexternalapp.webapplication-meta.xml +0 -7
- package/lib/templates/project/reactexternalapp/_r_/webapp-data.md +0 -353
- package/lib/templates/project/reactexternalapp/_r_/webapp-ui.md +0 -16
- package/lib/templates/project/reactexternalapp/package-lock.json +0 -9995
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/reactinternalapp.webapplication-meta.xml +0 -7
- package/lib/templates/project/reactinternalapp/_r_/webapp-data.md +0 -353
- package/lib/templates/project/reactinternalapp/_r_/webapp-ui.md +0 -16
- package/lib/templates/project/reactinternalapp/package-lock.json +0 -9995
- package/lib/templates/webapplication/reactbasic/e2e/app.spec.ts +0 -17
- package/lib/templates/webapplication/webappbasic/README.md +0 -15
- package/lib/utils/webappTemplateUtils.js.map +0 -1
- /package/lib/templates/project/reactexternalapp/_p_/_m_/_d_/_s_/{_a1_ → reactexternalapp1}/reactexternalapp1.digitalExperience-meta.xml +0 -0
- /package/lib/templates/project/reactexternalapp/_p_/_m_/_d_/_s_/{_a1_ → reactexternalapp1}/sfdc_cms__site/reactexternalapp1/_meta.json +0 -0
- /package/lib/templates/project/reactexternalapp/_p_/_m_/_d_/_s_/{_a1_ → reactexternalapp1}/sfdc_cms__site/reactexternalapp1/content.json +0 -0
- /package/lib/templates/project/reactexternalapp/_p_/_m_/{digitalExperienceConfigs/reactexternalapp1.digitalExperienceConfig → _dc_/reactexternalapp1.digitalExperienceConfig-meta.xml} +0 -0
- /package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/{webapplication.json → ui-bundle.json} +0 -0
- /package/lib/templates/project/reactexternalapp/_p_/_m_/classes/{WebAppAuthUtils.cls-meta.xml → UIBundleAuthUtils.cls-meta.xml} +0 -0
- /package/lib/templates/project/reactexternalapp/_p_/_m_/classes/{WebAppChangePassword.cls-meta.xml → UIBundleChangePassword.cls-meta.xml} +0 -0
- /package/lib/templates/project/reactexternalapp/_p_/_m_/classes/{WebAppForgotPassword.cls-meta.xml → UIBundleForgotPassword.cls-meta.xml} +0 -0
- /package/lib/templates/project/reactexternalapp/_p_/_m_/classes/{WebAppLogin.cls-meta.xml → UIBundleLogin.cls-meta.xml} +0 -0
- /package/lib/templates/project/reactexternalapp/_p_/_m_/classes/{WebAppRegistration.cls-meta.xml → UIBundleRegistration.cls-meta.xml} +0 -0
- /package/lib/templates/project/reactexternalapp/_p_/_m_/sites/{reactexternalapp.site → reactexternalapp.site-meta.xml} +0 -0
- /package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/{webapplication.json → ui-bundle.json} +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/.forceignore +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/.graphqlrc.yml +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/.prettierignore +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/.prettierrc +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/codegen.yml +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/components.json +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/index.html +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/playwright.config.ts +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/scripts/rewrite-e2e-assets.mjs +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/api/graphqlClient.ts +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/app.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/appLayout.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/assets/icons/book.svg +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/assets/icons/copy.svg +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/assets/icons/rocket.svg +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/assets/icons/star.svg +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/assets/images/codey-1.png +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/assets/images/codey-2.png +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/assets/images/codey-3.png +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/assets/images/vibe-codey.svg +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/alerts/status-alert.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/layouts/card-layout.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/alert.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/badge.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/breadcrumb.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/button.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/calendar.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/card.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/checkbox.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/collapsible.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/datePicker.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/dialog.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/field.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/index.ts +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/input.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/label.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/pagination.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/popover.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/select.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/separator.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/skeleton.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/sonner.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/spinner.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/table.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/components/ui/tabs.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/lib/utils.ts +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/navigationMenu.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/pages/Home.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/pages/NotFound.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/router-utils.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/routes.tsx +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/src/styles/global.css +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/tsconfig.json +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/tsconfig.node.json +0 -0
- /package/lib/templates/{webapplication/reactbasic/webapplication.json → uiBundles/reactbasic/ui-bundle.json} +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/vite-env.d.ts +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/vitest-env.d.ts +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/vitest.config.ts +0 -0
- /package/lib/templates/{webapplication → uiBundles}/reactbasic/vitest.setup.ts +0 -0
- /package/lib/templates/{webapplication → uiBundles}/webappbasic/src/index.html +0 -0
- /package/lib/templates/{webapplication/webappbasic/webapplication.json → uiBundles/webappbasic/ui-bundle.json} +0 -0
|
@@ -1,12 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { useNavigate } from "react-router";
|
|
3
|
+
import { SearchBar } from "../features/object-search/components/SearchBar";
|
|
4
|
+
import { Button } from "../components/ui/button";
|
|
5
|
+
|
|
6
|
+
export default function HomePage() {
|
|
7
|
+
const navigate = useNavigate();
|
|
8
|
+
const [text, setText] = useState("");
|
|
9
|
+
|
|
10
|
+
const handleSubmit = (e: React.SyntheticEvent<HTMLFormElement>) => {
|
|
11
|
+
e.preventDefault();
|
|
12
|
+
const params = text ? `?q=${encodeURIComponent(text)}` : "";
|
|
13
|
+
navigate(`/accounts${params}`);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div className="max-w-2xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
|
|
18
|
+
<div className="flex items-center gap-6 mb-6">
|
|
19
|
+
<h1 className="text-2xl font-bold">Account Search</h1>
|
|
20
|
+
<Button variant="outline" size="sm" onClick={() => navigate("/accounts")}>
|
|
21
|
+
Browse All Accounts
|
|
22
|
+
</Button>
|
|
23
|
+
</div>
|
|
24
|
+
<form onSubmit={handleSubmit} className="flex gap-2">
|
|
25
|
+
<SearchBar
|
|
26
|
+
placeholder="Search by name, phone, or industry..."
|
|
27
|
+
value={text}
|
|
28
|
+
handleChange={setText}
|
|
29
|
+
/>
|
|
30
|
+
<Button type="submit">Search</Button>
|
|
31
|
+
</form>
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
12
34
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { RouteObject } from 'react-router';
|
|
2
2
|
import AppLayout from './appLayout';
|
|
3
|
-
import Home from './
|
|
3
|
+
import Home from './pages/Home';
|
|
4
4
|
import NotFound from './pages/NotFound';
|
|
5
|
+
import AccountSearch from "./pages/AccountSearch";
|
|
6
|
+
import AccountObjectDetail from "./pages/AccountObjectDetailPage";
|
|
7
|
+
|
|
5
8
|
export const routes: RouteObject[] = [
|
|
6
9
|
{
|
|
7
10
|
path: "/",
|
|
@@ -15,6 +18,14 @@ export const routes: RouteObject[] = [
|
|
|
15
18
|
{
|
|
16
19
|
path: '*',
|
|
17
20
|
element: <NotFound />
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
path: "accounts/:recordId",
|
|
24
|
+
element: <AccountObjectDetail />
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
path: "accounts",
|
|
28
|
+
element: <AccountSearch />
|
|
18
29
|
}
|
|
19
30
|
]
|
|
20
31
|
}
|
|
@@ -18,6 +18,8 @@ export interface AgentforceConversationClientProps {
|
|
|
18
18
|
inline?: boolean;
|
|
19
19
|
/** Show/hide chat header. Defaults to true for floating; can only be set for inline mode. */
|
|
20
20
|
headerEnabled?: boolean;
|
|
21
|
+
/** Show/hide agent icon in the header. */
|
|
22
|
+
showHeaderIcon?: boolean;
|
|
21
23
|
/** Inline width. */
|
|
22
24
|
width?: string | number;
|
|
23
25
|
/** Inline height. */
|
|
@@ -4,7 +4,7 @@ import react from '@vitejs/plugin-react';
|
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import { resolve } from 'path';
|
|
6
6
|
import tailwindcss from '@tailwindcss/vite';
|
|
7
|
-
import salesforce from '@salesforce/vite-plugin-
|
|
7
|
+
import salesforce from '@salesforce/vite-plugin-ui-bundle';
|
|
8
8
|
import codegen from 'vite-plugin-graphql-codegen';
|
|
9
9
|
|
|
10
10
|
const schemaPath = resolve(__dirname, '../../../../../schema.graphql');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "@salesforce/
|
|
3
|
-
"version": "1.
|
|
2
|
+
"name": "@salesforce/ui-bundle-template-base-sfdx-project",
|
|
3
|
+
"version": "1.117.3",
|
|
4
4
|
"description": "Base SFDX project template",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"publishConfig": {
|
|
@@ -60,8 +60,8 @@ if [ ! -f "$SCHEMA" ]; then
|
|
|
60
60
|
echo "ERROR: schema.graphql not found at $SCHEMA"
|
|
61
61
|
echo " Make sure you are running from the SFDX project root, or pass the path explicitly:"
|
|
62
62
|
echo " bash $0 --schema <path/to/schema.graphql> <EntityName>"
|
|
63
|
-
echo " If the file is missing entirely, generate it from the
|
|
64
|
-
echo " cd force-app/main/default/
|
|
63
|
+
echo " If the file is missing entirely, generate it from the ui-bundle dir:"
|
|
64
|
+
echo " cd force-app/main/default/uiBundles/<app-name> && npm run graphql:schema"
|
|
65
65
|
exit 1
|
|
66
66
|
fi
|
|
67
67
|
|
|
@@ -73,8 +73,8 @@ fi
|
|
|
73
73
|
|
|
74
74
|
if [ ! -s "$SCHEMA" ]; then
|
|
75
75
|
echo "ERROR: schema.graphql is empty at $SCHEMA"
|
|
76
|
-
echo " Regenerate it from the
|
|
77
|
-
echo " cd force-app/main/default/
|
|
76
|
+
echo " Regenerate it from the ui-bundle dir:"
|
|
77
|
+
echo " cd force-app/main/default/uiBundles/<app-name> && npm run graphql:schema"
|
|
78
78
|
exit 1
|
|
79
79
|
fi
|
|
80
80
|
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* One-command setup: login, deploy, optional permset/data, GraphQL schema/codegen,
|
|
3
|
+
* One-command setup: login, deploy, optional permset/data, GraphQL schema/codegen, UI bundle build.
|
|
4
4
|
* Use this script to make setup easier for each app generated from this template.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
7
|
* node scripts/setup-cli.mjs --target-org <alias> # interactive step picker (all selected)
|
|
8
8
|
* node scripts/setup-cli.mjs --target-org <alias> --yes # skip picker, run all steps
|
|
9
9
|
* node scripts/setup-cli.mjs --target-org afv5 --skip-login
|
|
10
|
-
* node scripts/setup-cli.mjs --target-org afv5 --skip-data --skip-
|
|
11
|
-
* node scripts/setup-cli.mjs --target-org myorg --
|
|
10
|
+
* node scripts/setup-cli.mjs --target-org afv5 --skip-data --skip-ui-bundle-build
|
|
11
|
+
* node scripts/setup-cli.mjs --target-org myorg --ui-bundle-name my-app
|
|
12
12
|
*
|
|
13
13
|
* Steps (in order):
|
|
14
14
|
* 1. login — sf org login web only if org not already connected (skip with --skip-login)
|
|
15
|
-
* 2.
|
|
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
17
|
* 4. permset — sf org assign permset for each *.permissionset-meta.xml (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
|
-
* 6. graphql — (in
|
|
20
|
-
* 7. dev — (in
|
|
19
|
+
* 6. graphql — (in UI bundle) npm run graphql:schema then npm run graphql:codegen
|
|
20
|
+
* 7. dev — (in UI bundle) npm run dev — launch dev server (skip with --skip-dev)
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
import { spawnSync } from 'node:child_process';
|
|
@@ -44,14 +44,14 @@ function resolveSfdxSource() {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
const SFDX_SOURCE = resolveSfdxSource();
|
|
47
|
-
const
|
|
47
|
+
const UIBUNDLES_DIR = resolve(SFDX_SOURCE, 'uiBundles');
|
|
48
48
|
const DATA_DIR = resolve(SFDX_SOURCE, 'data');
|
|
49
49
|
const DATA_PLAN = resolve(SFDX_SOURCE, 'data/data-plan.json');
|
|
50
50
|
|
|
51
51
|
function parseArgs() {
|
|
52
52
|
const args = process.argv.slice(2);
|
|
53
53
|
let targetOrg = null;
|
|
54
|
-
let
|
|
54
|
+
let uiBundleName = null;
|
|
55
55
|
/** If non-empty, only these names are assigned; otherwise all discovered from the project. */
|
|
56
56
|
const permsetNamesExplicit = [];
|
|
57
57
|
let yes = false;
|
|
@@ -61,14 +61,14 @@ function parseArgs() {
|
|
|
61
61
|
skipPermset: false,
|
|
62
62
|
skipData: false,
|
|
63
63
|
skipGraphql: false,
|
|
64
|
-
|
|
64
|
+
skipUIBundleBuild: false,
|
|
65
65
|
skipDev: false,
|
|
66
66
|
};
|
|
67
67
|
for (let i = 0; i < args.length; i++) {
|
|
68
68
|
if (args[i] === '--target-org' && args[i + 1]) {
|
|
69
69
|
targetOrg = args[++i];
|
|
70
|
-
} else if (args[i] === '--
|
|
71
|
-
|
|
70
|
+
} else if (args[i] === '--ui-bundle-name' && args[i + 1]) {
|
|
71
|
+
uiBundleName = args[++i];
|
|
72
72
|
} else if (args[i] === '--permset-name' && args[i + 1]) {
|
|
73
73
|
permsetNamesExplicit.push(args[++i]);
|
|
74
74
|
} else if (args[i] === '--skip-login') flags.skipLogin = true;
|
|
@@ -76,7 +76,7 @@ function parseArgs() {
|
|
|
76
76
|
else if (args[i] === '--skip-permset') flags.skipPermset = true;
|
|
77
77
|
else if (args[i] === '--skip-data') flags.skipData = true;
|
|
78
78
|
else if (args[i] === '--skip-graphql') flags.skipGraphql = true;
|
|
79
|
-
else if (args[i] === '--skip-
|
|
79
|
+
else if (args[i] === '--skip-ui-bundle-build') flags.skipUIBundleBuild = true;
|
|
80
80
|
else if (args[i] === '--skip-dev') flags.skipDev = true;
|
|
81
81
|
else if (args[i] === '--yes' || args[i] === '-y') yes = true;
|
|
82
82
|
else if (args[i] === '--help' || args[i] === '-h') {
|
|
@@ -90,14 +90,14 @@ Required:
|
|
|
90
90
|
--target-org <alias> Target Salesforce org alias (e.g. myorg)
|
|
91
91
|
|
|
92
92
|
Options:
|
|
93
|
-
--
|
|
93
|
+
--ui-bundle-name <name> UI bundle folder name under uiBundles/ (default: auto-detect)
|
|
94
94
|
--permset-name <name> Assign only this permission set (repeatable). Default: all sets under permissionsets/
|
|
95
95
|
--skip-login Skip login step (login is auto-skipped if org is already connected)
|
|
96
96
|
--skip-deploy Do not deploy metadata
|
|
97
97
|
--skip-permset Do not assign permission set
|
|
98
98
|
--skip-data Do not prepare data or run data import
|
|
99
99
|
--skip-graphql Do not fetch schema or run GraphQL codegen
|
|
100
|
-
--skip-
|
|
100
|
+
--skip-ui-bundle-build Do not npm install / build the UI bundle
|
|
101
101
|
--skip-dev Do not launch the dev server at the end
|
|
102
102
|
-y, --yes Skip interactive step picker; run all enabled steps immediately
|
|
103
103
|
-h, --help Show this help
|
|
@@ -109,35 +109,35 @@ Options:
|
|
|
109
109
|
console.error('Error: --target-org <alias> is required.');
|
|
110
110
|
process.exit(1);
|
|
111
111
|
}
|
|
112
|
-
return { targetOrg,
|
|
112
|
+
return { targetOrg, uiBundleName, permsetNamesExplicit, yes, ...flags };
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
function
|
|
116
|
-
if (!existsSync(
|
|
117
|
-
console.error(`Error:
|
|
115
|
+
function discoverAllUIBundleDirs(uiBundleName) {
|
|
116
|
+
if (!existsSync(UIBUNDLES_DIR)) {
|
|
117
|
+
console.error(`Error: uiBundles directory not found: ${UIBUNDLES_DIR}`);
|
|
118
118
|
process.exit(1);
|
|
119
119
|
}
|
|
120
|
-
const entries = readdirSync(
|
|
120
|
+
const entries = readdirSync(UIBUNDLES_DIR, { withFileTypes: true });
|
|
121
121
|
const dirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith('.'));
|
|
122
122
|
if (dirs.length === 0) {
|
|
123
|
-
console.error(`Error: No
|
|
123
|
+
console.error(`Error: No UI bundle folder found under ${UIBUNDLES_DIR}`);
|
|
124
124
|
process.exit(1);
|
|
125
125
|
}
|
|
126
|
-
if (
|
|
127
|
-
const requested = dirs.find((d) => d.name ===
|
|
126
|
+
if (uiBundleName) {
|
|
127
|
+
const requested = dirs.find((d) => d.name === uiBundleName);
|
|
128
128
|
if (!requested) {
|
|
129
|
-
console.error(`Error:
|
|
129
|
+
console.error(`Error: UI bundle directory not found: ${uiBundleName}`);
|
|
130
130
|
process.exit(1);
|
|
131
131
|
}
|
|
132
|
-
return [resolve(
|
|
132
|
+
return [resolve(UIBUNDLES_DIR, requested.name)];
|
|
133
133
|
}
|
|
134
|
-
return dirs.map((d) => resolve(
|
|
134
|
+
return dirs.map((d) => resolve(UIBUNDLES_DIR, d.name));
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
function
|
|
138
|
-
const all =
|
|
139
|
-
if (all.length > 1 && !
|
|
140
|
-
console.log(`Multiple
|
|
137
|
+
function discoverUIBundleDir(uiBundleName) {
|
|
138
|
+
const all = discoverAllUIBundleDirs(uiBundleName);
|
|
139
|
+
if (all.length > 1 && !uiBundleName) {
|
|
140
|
+
console.log(`Multiple UI bundles found; using first: ${all[0].split(/[/\\]/).pop()}`);
|
|
141
141
|
}
|
|
142
142
|
return all[0];
|
|
143
143
|
}
|
|
@@ -294,7 +294,7 @@ function run(name, cmd, args, opts = {}) {
|
|
|
294
294
|
async function main() {
|
|
295
295
|
const {
|
|
296
296
|
targetOrg,
|
|
297
|
-
|
|
297
|
+
uiBundleName,
|
|
298
298
|
permsetNamesExplicit,
|
|
299
299
|
yes,
|
|
300
300
|
skipLogin: argSkipLogin,
|
|
@@ -302,7 +302,7 @@ async function main() {
|
|
|
302
302
|
skipPermset: argSkipPermset,
|
|
303
303
|
skipData: argSkipData,
|
|
304
304
|
skipGraphql: argSkipGraphql,
|
|
305
|
-
|
|
305
|
+
skipUIBundleBuild: argSkipUIBundleBuild,
|
|
306
306
|
skipDev: argSkipDev,
|
|
307
307
|
} = parseArgs();
|
|
308
308
|
|
|
@@ -319,7 +319,7 @@ async function main() {
|
|
|
319
319
|
|
|
320
320
|
const stepDefs = [
|
|
321
321
|
{ key: 'login', label: 'Login — org authentication', enabled: !argSkipLogin, available: true },
|
|
322
|
-
{ key: '
|
|
322
|
+
{ key: 'uiBundleBuild', label: 'UI Bundle Build — npm install + build (pre-deploy)', enabled: !argSkipUIBundleBuild, available: true },
|
|
323
323
|
{ key: 'deploy', label: 'Deploy — sf project deploy start', enabled: !argSkipDeploy, available: true },
|
|
324
324
|
{ key: 'permset', label: permsetStepLabel, enabled: !argSkipPermset, available: true },
|
|
325
325
|
{ key: 'data', label: 'Data — delete + import records via Apex', enabled: !argSkipData && hasDataPlan, available: hasDataPlan },
|
|
@@ -334,26 +334,26 @@ async function main() {
|
|
|
334
334
|
});
|
|
335
335
|
|
|
336
336
|
const skipLogin = !on.login;
|
|
337
|
-
const
|
|
337
|
+
const skipUIBundleBuild = !on.uiBundleBuild;
|
|
338
338
|
const skipDeploy = !on.deploy;
|
|
339
339
|
const skipPermset = !on.permset;
|
|
340
340
|
const skipData = !on.data;
|
|
341
341
|
const skipGraphql = !on.graphql;
|
|
342
342
|
const skipDev = !on.dev;
|
|
343
343
|
|
|
344
|
-
const
|
|
345
|
-
const
|
|
344
|
+
const needsUIBundle = !skipUIBundleBuild || !skipGraphql || !skipDev;
|
|
345
|
+
const uiBundleDir = needsUIBundle ? discoverUIBundleDir(uiBundleName) : null;
|
|
346
346
|
const doData = !skipData;
|
|
347
347
|
|
|
348
|
-
console.log('Setup — target org:', targetOrg, '|
|
|
348
|
+
console.log('Setup — target org:', targetOrg, '| UI bundle:', uiBundleDir ?? '(none)');
|
|
349
349
|
console.log(
|
|
350
|
-
'Steps: login=%s deploy=%s permset=%s data=%s graphql=%s
|
|
350
|
+
'Steps: login=%s deploy=%s permset=%s data=%s graphql=%s uiBundle=%s dev=%s',
|
|
351
351
|
!skipLogin,
|
|
352
352
|
!skipDeploy,
|
|
353
353
|
!skipPermset,
|
|
354
354
|
doData,
|
|
355
355
|
!skipGraphql,
|
|
356
|
-
!
|
|
356
|
+
!skipUIBundleBuild,
|
|
357
357
|
!skipDev
|
|
358
358
|
);
|
|
359
359
|
|
|
@@ -366,13 +366,13 @@ async function main() {
|
|
|
366
366
|
}
|
|
367
367
|
}
|
|
368
368
|
|
|
369
|
-
// Build all
|
|
370
|
-
if (!skipDeploy && !
|
|
371
|
-
const
|
|
372
|
-
for (const dir of
|
|
369
|
+
// Build all UI Bundles before deploy so dist exists for entity deployment
|
|
370
|
+
if (!skipDeploy && !skipUIBundleBuild) {
|
|
371
|
+
const allUIBundleDirs = discoverAllUIBundleDirs(uiBundleName);
|
|
372
|
+
for (const dir of allUIBundleDirs) {
|
|
373
373
|
const name = dir.split(/[/\\]/).pop();
|
|
374
|
-
run(`
|
|
375
|
-
run(`
|
|
374
|
+
run(`UI Bundle install (${name})`, 'npm', ['install'], { cwd: dir });
|
|
375
|
+
run(`UI Bundle build (${name})`, 'npm', ['run', 'build'], { cwd: dir });
|
|
376
376
|
}
|
|
377
377
|
}
|
|
378
378
|
|
|
@@ -535,25 +535,25 @@ async function main() {
|
|
|
535
535
|
if (existsSync(tmpApex)) unlinkSync(tmpApex);
|
|
536
536
|
}
|
|
537
537
|
|
|
538
|
-
if (!skipGraphql || !
|
|
539
|
-
run('
|
|
538
|
+
if (!skipGraphql || !skipUIBundleBuild) {
|
|
539
|
+
run('UI Bundle npm install', 'npm', ['install'], { cwd: uiBundleDir });
|
|
540
540
|
}
|
|
541
541
|
|
|
542
542
|
if (!skipGraphql) {
|
|
543
543
|
run('Set default org for schema', 'sf', ['config', 'set', 'target-org', targetOrg, '--global']);
|
|
544
|
-
run('GraphQL schema (introspect)', 'npm', ['run', 'graphql:schema'], { cwd:
|
|
545
|
-
run('GraphQL codegen', 'npm', ['run', 'graphql:codegen'], { cwd:
|
|
544
|
+
run('GraphQL schema (introspect)', 'npm', ['run', 'graphql:schema'], { cwd: uiBundleDir });
|
|
545
|
+
run('GraphQL codegen', 'npm', ['run', 'graphql:codegen'], { cwd: uiBundleDir });
|
|
546
546
|
}
|
|
547
547
|
|
|
548
|
-
if (!
|
|
549
|
-
run('
|
|
548
|
+
if (!skipUIBundleBuild) {
|
|
549
|
+
run('UI Bundle build', 'npm', ['run', 'build'], { cwd: uiBundleDir });
|
|
550
550
|
}
|
|
551
551
|
|
|
552
552
|
console.log('\n--- Setup complete ---');
|
|
553
553
|
|
|
554
554
|
if (!skipDev) {
|
|
555
555
|
console.log('\n--- Launching dev server (Ctrl+C to stop) ---\n');
|
|
556
|
-
run('Dev server', 'npm', ['run', 'dev'], { cwd:
|
|
556
|
+
run('Dev server', 'npm', ['run', 'dev'], { cwd: uiBundleDir });
|
|
557
557
|
}
|
|
558
558
|
}
|
|
559
559
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* Run from SFDX project root: install dependencies, build, and launch the dev server
|
|
4
|
-
* for the
|
|
4
|
+
* for the UI bundle in force-app/main/default/uiBundles/.
|
|
5
5
|
*
|
|
6
6
|
* Usage: npm run sf-project-setup
|
|
7
7
|
* (from the directory that contains force-app/ and sfdx-project.json)
|
|
@@ -15,7 +15,7 @@ import { readdirSync, existsSync, readFileSync } from 'node:fs';
|
|
|
15
15
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
16
16
|
const ROOT = resolve(__dirname, '..');
|
|
17
17
|
|
|
18
|
-
function
|
|
18
|
+
function resolveUIBundlesDir() {
|
|
19
19
|
const sfdxPath = resolve(ROOT, 'sfdx-project.json');
|
|
20
20
|
if (!existsSync(sfdxPath)) {
|
|
21
21
|
console.error('Error: sfdx-project.json not found at project root.');
|
|
@@ -27,25 +27,25 @@ function resolveWebapplicationsDir() {
|
|
|
27
27
|
console.error('Error: No packageDirectories[].path found in sfdx-project.json.');
|
|
28
28
|
process.exit(1);
|
|
29
29
|
}
|
|
30
|
-
return resolve(ROOT, pkgDir, 'main', 'default', '
|
|
30
|
+
return resolve(ROOT, pkgDir, 'main', 'default', 'uiBundles');
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
function
|
|
34
|
-
const
|
|
35
|
-
if (!existsSync(
|
|
36
|
-
console.error(`Error:
|
|
33
|
+
function discoverUIBundleDir() {
|
|
34
|
+
const uiBundlesDir = resolveUIBundlesDir();
|
|
35
|
+
if (!existsSync(uiBundlesDir)) {
|
|
36
|
+
console.error(`Error: uiBundles directory not found: ${uiBundlesDir}`);
|
|
37
37
|
process.exit(1);
|
|
38
38
|
}
|
|
39
|
-
const entries = readdirSync(
|
|
39
|
+
const entries = readdirSync(uiBundlesDir, { withFileTypes: true });
|
|
40
40
|
const dirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith('.'));
|
|
41
41
|
if (dirs.length === 0) {
|
|
42
|
-
console.error(`Error: No
|
|
42
|
+
console.error(`Error: No UI bundle folder found under ${uiBundlesDir}`);
|
|
43
43
|
process.exit(1);
|
|
44
44
|
}
|
|
45
45
|
if (dirs.length > 1) {
|
|
46
|
-
console.log(`Multiple
|
|
46
|
+
console.log(`Multiple UI bundles found; using first: ${dirs[0].name}`);
|
|
47
47
|
}
|
|
48
|
-
return resolve(
|
|
48
|
+
return resolve(uiBundlesDir, dirs[0].name);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
function run(label, cmd, args, opts) {
|
|
@@ -56,11 +56,11 @@ function run(label, cmd, args, opts) {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
const
|
|
59
|
+
const uiBundleDir = discoverUIBundleDir();
|
|
60
60
|
console.log('SFDX project root:', ROOT);
|
|
61
|
-
console.log('
|
|
61
|
+
console.log('UI bundle directory:', uiBundleDir);
|
|
62
62
|
|
|
63
|
-
run('npm install', 'npm', ['install'], { cwd:
|
|
64
|
-
run('npm run build', 'npm', ['run', 'build'], { cwd:
|
|
63
|
+
run('npm install', 'npm', ['install', '--registry', 'https://registry.npmjs.org/'], { cwd: uiBundleDir });
|
|
64
|
+
run('npm run build', 'npm', ['run', 'build'], { cwd: uiBundleDir });
|
|
65
65
|
console.log('\n--- Launching dev server (Ctrl+C to stop) ---\n');
|
|
66
|
-
run('npm run dev', 'npm', ['run', 'dev'], { cwd:
|
|
66
|
+
run('npm run dev', 'npm', ['run', 'dev'], { cwd: uiBundleDir });
|
|
@@ -7,4 +7,4 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|
|
7
7
|
|
|
8
8
|
### Features
|
|
9
9
|
|
|
10
|
-
- auto bump base react app versions and fix issue with base
|
|
10
|
+
- auto bump base react app versions and fix issue with base ui-bundle json ([#175](https://github.com/salesforce-experience-platform-emu/webapps/issues/175)) ([048b5a8](https://github.com/salesforce-experience-platform-emu/webapps/commit/048b5a8449c899fc923aeebc3c76bc5bf1c5e0d4))
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Base React App
|
|
2
2
|
|
|
3
|
-
Base React App is a template application that demonstrates how to build a React
|
|
3
|
+
Base React App is a template application that demonstrates how to build a React UI Bundle on the Salesforce platform with Vite, TypeScript, Tailwind, shadcn/ui, and the Salesforce UI Bundle SDK. It provides a minimal shell (home, 404), routing, and GraphQL codegen support so feature apps can extend it via the patches pipeline.
|
|
4
4
|
|
|
5
|
-
This
|
|
5
|
+
This UI Bundle lives inside an SFDX project. The project root is the directory that contains `force-app/` and `sfdx-project.json`. Run the commands in the sections below from the paths indicated.
|
|
6
6
|
|
|
7
7
|
## Table of contents
|
|
8
8
|
|
|
@@ -13,7 +13,7 @@ This web application lives inside an SFDX project. The project root is the direc
|
|
|
13
13
|
|
|
14
14
|
## Run (development)
|
|
15
15
|
|
|
16
|
-
From the
|
|
16
|
+
From the UI Bundle directory (`force-app/main/default/uiBundles/base-react-app`):
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
19
|
npm install
|
|
@@ -24,29 +24,29 @@ This starts the Vite dev server (e.g. http://localhost:5173). Use `npm run dev:d
|
|
|
24
24
|
|
|
25
25
|
## Build
|
|
26
26
|
|
|
27
|
-
From the
|
|
27
|
+
From the UI Bundle directory:
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
30
|
npm install
|
|
31
31
|
npm run build
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
The production build is written to `dist/` inside the
|
|
34
|
+
The production build is written to `dist/` inside the UI Bundle folder. Deploy using the steps in [Deploy](#deploy).
|
|
35
35
|
|
|
36
36
|
## Deploy
|
|
37
37
|
|
|
38
38
|
From the **SFDX project root** (the directory that contains `force-app/`):
|
|
39
39
|
|
|
40
|
-
1. Build the
|
|
40
|
+
1. Build the UI Bundle:
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
cd force-app/main/default/
|
|
43
|
+
cd force-app/main/default/uiBundles/base-react-app && npm install && npm run build && cd -
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
2. Deploy the
|
|
46
|
+
2. Deploy the UI Bundle only:
|
|
47
47
|
|
|
48
48
|
```bash
|
|
49
|
-
sf project deploy start --source-dir force-app/main/default/
|
|
49
|
+
sf project deploy start --source-dir force-app/main/default/ui-bundles --target-org <alias>
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
Or deploy all metadata:
|
|
@@ -59,7 +59,7 @@ From the **SFDX project root** (the directory that contains `force-app/`):
|
|
|
59
59
|
|
|
60
60
|
## Test
|
|
61
61
|
|
|
62
|
-
From the
|
|
62
|
+
From the UI Bundle directory:
|
|
63
63
|
|
|
64
64
|
```bash
|
|
65
65
|
npm install
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<
|
|
2
|
+
<UIBundle xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
3
3
|
<masterLabel><%= masterLabel %></masterLabel>
|
|
4
|
-
<description>A Salesforce
|
|
4
|
+
<description>A Salesforce UI Bundle.</description>
|
|
5
5
|
<isActive>true</isActive>
|
|
6
6
|
<version>1</version>
|
|
7
|
-
</
|
|
7
|
+
</UIBundle>
|
|
@@ -18,7 +18,12 @@ const schemaExists = existsSync(schemaPath);
|
|
|
18
18
|
const config = [
|
|
19
19
|
// Global ignores
|
|
20
20
|
{
|
|
21
|
-
ignores: [
|
|
21
|
+
ignores: [
|
|
22
|
+
'build/**/*',
|
|
23
|
+
'dist/**/*',
|
|
24
|
+
'coverage/**/*',
|
|
25
|
+
'src/api/graphql-operations-types.ts',
|
|
26
|
+
],
|
|
22
27
|
},
|
|
23
28
|
// Config files and build tools (first to avoid inheritance)
|
|
24
29
|
{
|
|
@@ -89,11 +94,17 @@ const config = [
|
|
|
89
94
|
'react/no-unescaped-entities': 'off',
|
|
90
95
|
'@typescript-eslint/no-unused-vars': [
|
|
91
96
|
'error',
|
|
92
|
-
{
|
|
97
|
+
{
|
|
98
|
+
argsIgnorePattern: '^_',
|
|
99
|
+
varsIgnorePattern: '^_',
|
|
100
|
+
caughtErrorsIgnorePattern: '^_',
|
|
101
|
+
ignoreRestSiblings: true,
|
|
102
|
+
},
|
|
93
103
|
],
|
|
94
104
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
95
105
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
96
106
|
'@typescript-eslint/no-explicit-any': 'off',
|
|
107
|
+
'react-hooks/set-state-in-effect': 'warn',
|
|
97
108
|
},
|
|
98
109
|
settings: {
|
|
99
110
|
react: {
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"graphql:schema": "node scripts/get-graphql-schema.mjs"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@salesforce/sdk-data": "^1.
|
|
19
|
-
"@salesforce/
|
|
18
|
+
"@salesforce/sdk-data": "^1.117.3",
|
|
19
|
+
"@salesforce/ui-bundle": "^1.117.3",
|
|
20
20
|
"@tailwindcss/vite": "^4.1.17",
|
|
21
21
|
"class-variance-authority": "^0.7.1",
|
|
22
22
|
"clsx": "^2.1.1",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@graphql-eslint/eslint-plugin": "^4.1.0",
|
|
42
42
|
"@graphql-tools/utils": "^11.0.0",
|
|
43
43
|
"@playwright/test": "^1.49.0",
|
|
44
|
-
"@salesforce/vite-plugin-
|
|
44
|
+
"@salesforce/vite-plugin-ui-bundle": "^1.117.3",
|
|
45
45
|
"@testing-library/jest-dom": "^6.6.3",
|
|
46
46
|
"@testing-library/react": "^16.1.0",
|
|
47
47
|
"@testing-library/user-event": "^14.5.2",
|
package/lib/templates/{webapplication → uiBundles}/reactbasic/scripts/get-graphql-schema.mjs
RENAMED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { writeFileSync } from 'node:fs';
|
|
12
12
|
import { resolve } from 'node:path';
|
|
13
|
-
import { getOrgInfo } from '@salesforce/
|
|
13
|
+
import { getOrgInfo } from '@salesforce/ui-bundle/app';
|
|
14
14
|
import { buildClientSchema, getIntrospectionQuery, printSchema } from 'graphql';
|
|
15
15
|
import { pruneSchema } from '@graphql-tools/utils';
|
|
16
16
|
|
|
@@ -4,7 +4,7 @@ import react from '@vitejs/plugin-react';
|
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import { resolve } from 'path';
|
|
6
6
|
import tailwindcss from '@tailwindcss/vite';
|
|
7
|
-
import salesforce from '@salesforce/vite-plugin-
|
|
7
|
+
import salesforce from '@salesforce/vite-plugin-ui-bundle';
|
|
8
8
|
import codegen from 'vite-plugin-graphql-codegen';
|
|
9
9
|
|
|
10
10
|
const schemaPath = resolve(__dirname, '../../../../../schema.graphql');
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Base Web App
|
|
2
|
+
|
|
3
|
+
Base Web App is a minimal UI Bundle template for the Salesforce platform. It provides a static HTML entry point and UI Bundle metadata so you can deploy a simple UI Bundle or use it as a starting point for a custom build. It does not include a framework; it is HTML and configuration only.
|
|
4
|
+
|
|
5
|
+
## Layout
|
|
6
|
+
|
|
7
|
+
This directory is the **UI Bundle payload**. It contains:
|
|
8
|
+
|
|
9
|
+
| Path | Description |
|
|
10
|
+
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
11
|
+
| `ui-bundle.json` | Web app config: `outputDir` (where the app content lives), routing, fallback. |
|
|
12
|
+
| `_uibundle.uibundle-meta.xml` | Salesforce UI Bundle metadata (label, description, version). |
|
|
13
|
+
| `src/` | **App content directory.** Matches `outputDir` in `ui-bundle.json`. Entry point is `src/index.html`; add other static assets (HTML, CSS, JS, images) under `src/` as needed. |
|
|
14
|
+
|
|
15
|
+
The nested `src/` is intentional: this folder holds the actual UI Bundle content (e.g. `index.html`). The platform uses `outputDir` from `ui-bundle.json` to know which subfolder contains the app.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<
|
|
2
|
+
<UIBundle xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
3
3
|
<masterLabel><%= masterLabel %></masterLabel>
|
|
4
|
-
<description>A Salesforce
|
|
4
|
+
<description>A Salesforce UI Bundle.</description>
|
|
5
5
|
<isActive>true</isActive>
|
|
6
6
|
<version>1</version>
|
|
7
|
-
</
|
|
7
|
+
</UIBundle>
|