@planningcenter/topbar 12.0.0 → 12.1.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.
@@ -940,8 +940,8 @@ const AppsProvider = ({
940
940
  const notificationsEnabled = !window.notificationsDisabled;
941
941
  const organizationTimeZone = ((_k = (_j = topbarResponse === null || topbarResponse === void 0 ? void 0 : topbarResponse.data) === null || _j === void 0 ? void 0 : _j.attributes) === null || _k === void 0 ? void 0 : _k.org_time_zone) || "America/Los_Angeles";
942
942
  const algoliaSearchAuth = {
943
- algoliaApplicationId: (_m = (_l = topbarResponse === null || topbarResponse === void 0 ? void 0 : topbarResponse.data) === null || _l === void 0 ? void 0 : _l.attributes) === null || _m === void 0 ? void 0 : _m.algolia_application_identifier,
944
- algoliaSearchOnlyApiKey: (_p = (_o = topbarResponse === null || topbarResponse === void 0 ? void 0 : topbarResponse.data) === null || _o === void 0 ? void 0 : _o.attributes) === null || _p === void 0 ? void 0 : _p.algolia_search_key
943
+ algoliaApplicationId: (_m = (_l = topbarResponse === null || topbarResponse === void 0 ? void 0 : topbarResponse.data) === null || _l === void 0 ? void 0 : _l.attributes) === null || _m === void 0 ? void 0 : _m.algolia_help_center_application_identifier,
944
+ algoliaSearchOnlyApiKey: (_p = (_o = topbarResponse === null || topbarResponse === void 0 ? void 0 : topbarResponse.data) === null || _o === void 0 ? void 0 : _o.attributes) === null || _p === void 0 ? void 0 : _p.algolia_help_center_search_key
945
945
  };
946
946
  const joltPromise = useMemo(() => {
947
947
  return resolveJoltPromise({
@@ -3454,40 +3454,44 @@ function buildPicobotSrc(origin, path) {
3454
3454
  return fragment ? `${base}#${fragment}` : base;
3455
3455
  }
3456
3456
 
3457
- const handleSearchSelect = (hit, indexName) => {
3458
- const appName = indexName.split("_")[1];
3459
- const zendeskUrl = `https://${appName}.zendesk.com/hc/${hit.locale.locale}/articles/${hit.id}`;
3460
- const newTab = window.open(zendeskUrl, "_blank");
3457
+ // The article heading lives in the deepest populated hierarchy level (lvl0 is
3458
+ // always "Planning Center").
3459
+ const hitTitle = hierarchy => (hierarchy === null || hierarchy === void 0 ? void 0 : hierarchy.lvl6) || (hierarchy === null || hierarchy === void 0 ? void 0 : hierarchy.lvl5) || (hierarchy === null || hierarchy === void 0 ? void 0 : hierarchy.lvl4) || (hierarchy === null || hierarchy === void 0 ? void 0 : hierarchy.lvl3) || (hierarchy === null || hierarchy === void 0 ? void 0 : hierarchy.lvl2) || (hierarchy === null || hierarchy === void 0 ? void 0 : hierarchy.lvl1) || (hierarchy === null || hierarchy === void 0 ? void 0 : hierarchy.lvl0) || "";
3460
+ const handleSearchSelect = hit => {
3461
+ // `url` is always absolute (it is also the basis of objectID), so open it
3462
+ // directly. Bail out defensively if a record somehow arrives without one.
3463
+ if (!(hit === null || hit === void 0 ? void 0 : hit.url)) return;
3464
+ const newTab = window.open(hit.url, "_blank");
3461
3465
  if (newTab) {
3462
3466
  newTab.focus();
3463
3467
  }
3464
3468
  };
3469
+ // Mirrors @planningcenter/tapestry-react's Logo registry.
3470
+ const VALID_LOGO_NAMES = new Set(["api", "calendar", "check-ins", "church-center", "giving", "groups", "headcounts", "home", "login", "music-stand", "people", "planning-center", "publishing", "registrations", "services"]);
3465
3471
  const HeadingIcon = ({
3466
- sectionName,
3467
- currentAppName
3472
+ currentAppName,
3473
+ product
3468
3474
  }) => {
3469
- const lowerCaseSectionName = sectionName.toLowerCase();
3470
- if (lowerCaseSectionName === "account information" || lowerCaseSectionName === "recent updates") {
3471
- return /*#__PURE__*/React__default.createElement(Icon, {
3472
- name: lowerCaseSectionName === "account information" ? "general.cogPerson" : "general.outlinedGenericFile",
3473
- color: "foregroundSecondary"
3474
- });
3475
- } else if (currentAppName === "Accounts") {
3475
+ const appName = product || currentAppName;
3476
+ if (!appName) return null;
3477
+ const logoName = appName.toLowerCase().replace(/\s+/g, "-");
3478
+ // Accounts has no tapestry Logo, so use the cog icon
3479
+ if (logoName === "accounts") {
3476
3480
  return /*#__PURE__*/React__default.createElement(Icon, {
3477
3481
  name: "general.cog",
3478
3482
  color: "foregroundSecondary"
3479
3483
  });
3480
- } else {
3481
- return /*#__PURE__*/React__default.createElement(StackView$2, {
3482
- width: 2,
3483
- height: 2
3484
- }, /*#__PURE__*/React__default.createElement(Logo, {
3485
- name: currentAppName.toLowerCase().replace(/[\s]/, "-"),
3486
- size: "sm",
3487
- theme: "color",
3488
- markOnly: true
3489
- }));
3490
3484
  }
3485
+ if (!VALID_LOGO_NAMES.has(logoName)) return null;
3486
+ return /*#__PURE__*/React__default.createElement(StackView$2, {
3487
+ width: 2,
3488
+ height: 2
3489
+ }, /*#__PURE__*/React__default.createElement(Logo, {
3490
+ name: logoName,
3491
+ size: "sm",
3492
+ theme: "color",
3493
+ markOnly: true
3494
+ }));
3491
3495
  };
3492
3496
  const HitResult = ({
3493
3497
  hit,
@@ -3502,11 +3506,10 @@ const HitResult = ({
3502
3506
  color: "neutralDarker",
3503
3507
  size: 4,
3504
3508
  whiteSpace: "normal"
3505
- }, hit.title));
3509
+ }, hitTitle(hit.hierarchy)));
3506
3510
  };
3507
3511
  const CustomSearchBox = ({
3508
- currentAppName,
3509
- indexName
3512
+ currentAppName
3510
3513
  }) => {
3511
3514
  const {
3512
3515
  query,
@@ -3517,7 +3520,10 @@ const CustomSearchBox = ({
3517
3520
  results
3518
3521
  } = useHits();
3519
3522
  const groups = results === null || results === void 0 ? void 0 : results.hits.reduce((acc, hit) => {
3520
- const key = hit.category.title;
3523
+ // A result with no url can't be opened, so don't render it at all.
3524
+ if (!hit.url) return acc;
3525
+ // Fall back so a record without a product never yields an "undefined" heading.
3526
+ const key = hit.product || currentAppName || "Other";
3521
3527
  if (!acc[key]) {
3522
3528
  acc[key] = [];
3523
3529
  }
@@ -3539,7 +3545,7 @@ const CustomSearchBox = ({
3539
3545
  name: "general.search"
3540
3546
  }),
3541
3547
  onChange: e => setQuery(e.target.value),
3542
- onSelect: selectedValue => handleSearchSelect(selectedValue, indexName),
3548
+ onSelect: selectedValue => handleSearchSelect(selectedValue),
3543
3549
  placement: "bottom-start"
3544
3550
  }, !hits.length && (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(StackView$2, {
3545
3551
  axis: "horizontal",
@@ -3551,7 +3557,7 @@ const CustomSearchBox = ({
3551
3557
  size: 4,
3552
3558
  whiteSpace: "normal"
3553
3559
  }, "No results match your search")))), groups && Object.keys(groups).map(key => {
3554
- const hits = groups[key];
3560
+ const groupHits = groups[key];
3555
3561
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, {
3556
3562
  key: key
3557
3563
  }, resultIndex > 0 && /*#__PURE__*/React__default.createElement(Divider, {
@@ -3564,12 +3570,12 @@ const CustomSearchBox = ({
3564
3570
  paddingVertical: 1
3565
3571
  }, /*#__PURE__*/React__default.createElement(HeadingIcon, {
3566
3572
  currentAppName: currentAppName,
3567
- sectionName: key
3573
+ product: key
3568
3574
  }), /*#__PURE__*/React__default.createElement(Text, {
3569
3575
  size: 5,
3570
3576
  color: "foregroundSecondary",
3571
3577
  fontWeight: 500
3572
- }, key)), hits.map(hit => (/*#__PURE__*/React__default.createElement(HitResult, {
3578
+ }, key)), groupHits.map(hit => (/*#__PURE__*/React__default.createElement(HitResult, {
3573
3579
  key: hit.objectID,
3574
3580
  hit: hit,
3575
3581
  index: resultIndex++
@@ -3577,8 +3583,8 @@ const CustomSearchBox = ({
3577
3583
  })));
3578
3584
  };
3579
3585
 
3586
+ const HELP_CENTER_INDEX = "help_center_english";
3580
3587
  const DocumentationSearch = ({
3581
- indexName,
3582
3588
  currentAppName
3583
3589
  }) => {
3584
3590
  const {
@@ -3589,13 +3595,13 @@ const DocumentationSearch = ({
3589
3595
  } = useStore();
3590
3596
  const searchClient = algoliasearch(algoliaApplicationId, algoliaSearchOnlyApiKey);
3591
3597
  return /*#__PURE__*/React__default.createElement(InstantSearch, {
3592
- indexName: indexName,
3598
+ indexName: HELP_CENTER_INDEX,
3593
3599
  searchClient: searchClient
3594
3600
  }, /*#__PURE__*/React__default.createElement(Configure, {
3595
- hitsPerPage: 5
3601
+ hitsPerPage: 5,
3602
+ optionalFilters: currentAppName ? [`product:${currentAppName}`] : undefined
3596
3603
  }), /*#__PURE__*/React__default.createElement(CustomSearchBox, {
3597
- currentAppName: currentAppName,
3598
- indexName: indexName
3604
+ currentAppName: currentAppName
3599
3605
  }));
3600
3606
  };
3601
3607
 
@@ -3706,9 +3712,6 @@ function HelpdeskComponent({
3706
3712
  properties: {
3707
3713
  currentAppName: {
3708
3714
  type: String
3709
- },
3710
- indexName: {
3711
- type: String
3712
3715
  }
3713
3716
  }
3714
3717
  },