@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.
@@ -951,8 +951,8 @@
951
951
  const notificationsEnabled = !window.notificationsDisabled;
952
952
  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";
953
953
  const algoliaSearchAuth = {
954
- 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,
955
- 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
954
+ 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,
955
+ 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
956
956
  };
957
957
  const joltPromise = React.useMemo(() => {
958
958
  return resolveJoltPromise({
@@ -3465,40 +3465,44 @@
3465
3465
  return fragment ? `${base}#${fragment}` : base;
3466
3466
  }
3467
3467
 
3468
- const handleSearchSelect = (hit, indexName) => {
3469
- const appName = indexName.split("_")[1];
3470
- const zendeskUrl = `https://${appName}.zendesk.com/hc/${hit.locale.locale}/articles/${hit.id}`;
3471
- const newTab = window.open(zendeskUrl, "_blank");
3468
+ // The article heading lives in the deepest populated hierarchy level (lvl0 is
3469
+ // always "Planning Center").
3470
+ 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) || "";
3471
+ const handleSearchSelect = hit => {
3472
+ // `url` is always absolute (it is also the basis of objectID), so open it
3473
+ // directly. Bail out defensively if a record somehow arrives without one.
3474
+ if (!(hit === null || hit === void 0 ? void 0 : hit.url)) return;
3475
+ const newTab = window.open(hit.url, "_blank");
3472
3476
  if (newTab) {
3473
3477
  newTab.focus();
3474
3478
  }
3475
3479
  };
3480
+ // Mirrors @planningcenter/tapestry-react's Logo registry.
3481
+ 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"]);
3476
3482
  const HeadingIcon = ({
3477
- sectionName,
3478
- currentAppName
3483
+ currentAppName,
3484
+ product
3479
3485
  }) => {
3480
- const lowerCaseSectionName = sectionName.toLowerCase();
3481
- if (lowerCaseSectionName === "account information" || lowerCaseSectionName === "recent updates") {
3482
- return /*#__PURE__*/React.createElement(tapestryReact.Icon, {
3483
- name: lowerCaseSectionName === "account information" ? "general.cogPerson" : "general.outlinedGenericFile",
3484
- color: "foregroundSecondary"
3485
- });
3486
- } else if (currentAppName === "Accounts") {
3486
+ const appName = product || currentAppName;
3487
+ if (!appName) return null;
3488
+ const logoName = appName.toLowerCase().replace(/\s+/g, "-");
3489
+ // Accounts has no tapestry Logo, so use the cog icon
3490
+ if (logoName === "accounts") {
3487
3491
  return /*#__PURE__*/React.createElement(tapestryReact.Icon, {
3488
3492
  name: "general.cog",
3489
3493
  color: "foregroundSecondary"
3490
3494
  });
3491
- } else {
3492
- return /*#__PURE__*/React.createElement(tapestryReact.StackView, {
3493
- width: 2,
3494
- height: 2
3495
- }, /*#__PURE__*/React.createElement(tapestryReact.Logo, {
3496
- name: currentAppName.toLowerCase().replace(/[\s]/, "-"),
3497
- size: "sm",
3498
- theme: "color",
3499
- markOnly: true
3500
- }));
3501
3495
  }
3496
+ if (!VALID_LOGO_NAMES.has(logoName)) return null;
3497
+ return /*#__PURE__*/React.createElement(tapestryReact.StackView, {
3498
+ width: 2,
3499
+ height: 2
3500
+ }, /*#__PURE__*/React.createElement(tapestryReact.Logo, {
3501
+ name: logoName,
3502
+ size: "sm",
3503
+ theme: "color",
3504
+ markOnly: true
3505
+ }));
3502
3506
  };
3503
3507
  const HitResult = ({
3504
3508
  hit,
@@ -3513,11 +3517,10 @@
3513
3517
  color: "neutralDarker",
3514
3518
  size: 4,
3515
3519
  whiteSpace: "normal"
3516
- }, hit.title));
3520
+ }, hitTitle(hit.hierarchy)));
3517
3521
  };
3518
3522
  const CustomSearchBox = ({
3519
- currentAppName,
3520
- indexName
3523
+ currentAppName
3521
3524
  }) => {
3522
3525
  const {
3523
3526
  query,
@@ -3528,7 +3531,10 @@
3528
3531
  results
3529
3532
  } = reactInstantsearchCore.useHits();
3530
3533
  const groups = results === null || results === void 0 ? void 0 : results.hits.reduce((acc, hit) => {
3531
- const key = hit.category.title;
3534
+ // A result with no url can't be opened, so don't render it at all.
3535
+ if (!hit.url) return acc;
3536
+ // Fall back so a record without a product never yields an "undefined" heading.
3537
+ const key = hit.product || currentAppName || "Other";
3532
3538
  if (!acc[key]) {
3533
3539
  acc[key] = [];
3534
3540
  }
@@ -3550,7 +3556,7 @@
3550
3556
  name: "general.search"
3551
3557
  }),
3552
3558
  onChange: e => setQuery(e.target.value),
3553
- onSelect: selectedValue => handleSearchSelect(selectedValue, indexName),
3559
+ onSelect: selectedValue => handleSearchSelect(selectedValue),
3554
3560
  placement: "bottom-start"
3555
3561
  }, !hits.length && (/*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(tapestryReact.StackView, {
3556
3562
  axis: "horizontal",
@@ -3562,7 +3568,7 @@
3562
3568
  size: 4,
3563
3569
  whiteSpace: "normal"
3564
3570
  }, "No results match your search")))), groups && Object.keys(groups).map(key => {
3565
- const hits = groups[key];
3571
+ const groupHits = groups[key];
3566
3572
  return /*#__PURE__*/React.createElement(React.Fragment, {
3567
3573
  key: key
3568
3574
  }, resultIndex > 0 && /*#__PURE__*/React.createElement(tapestryReact.Divider, {
@@ -3575,12 +3581,12 @@
3575
3581
  paddingVertical: 1
3576
3582
  }, /*#__PURE__*/React.createElement(HeadingIcon, {
3577
3583
  currentAppName: currentAppName,
3578
- sectionName: key
3584
+ product: key
3579
3585
  }), /*#__PURE__*/React.createElement(tapestryReact.Text, {
3580
3586
  size: 5,
3581
3587
  color: "foregroundSecondary",
3582
3588
  fontWeight: 500
3583
- }, key)), hits.map(hit => (/*#__PURE__*/React.createElement(HitResult, {
3589
+ }, key)), groupHits.map(hit => (/*#__PURE__*/React.createElement(HitResult, {
3584
3590
  key: hit.objectID,
3585
3591
  hit: hit,
3586
3592
  index: resultIndex++
@@ -3588,8 +3594,8 @@
3588
3594
  })));
3589
3595
  };
3590
3596
 
3597
+ const HELP_CENTER_INDEX = "help_center_english";
3591
3598
  const DocumentationSearch = ({
3592
- indexName,
3593
3599
  currentAppName
3594
3600
  }) => {
3595
3601
  const {
@@ -3600,13 +3606,13 @@
3600
3606
  } = useStore();
3601
3607
  const searchClient = algoliasearch(algoliaApplicationId, algoliaSearchOnlyApiKey);
3602
3608
  return /*#__PURE__*/React.createElement(reactInstantsearchCore.InstantSearch, {
3603
- indexName: indexName,
3609
+ indexName: HELP_CENTER_INDEX,
3604
3610
  searchClient: searchClient
3605
3611
  }, /*#__PURE__*/React.createElement(reactInstantsearchCore.Configure, {
3606
- hitsPerPage: 5
3612
+ hitsPerPage: 5,
3613
+ optionalFilters: currentAppName ? [`product:${currentAppName}`] : undefined
3607
3614
  }), /*#__PURE__*/React.createElement(CustomSearchBox, {
3608
- currentAppName: currentAppName,
3609
- indexName: indexName
3615
+ currentAppName: currentAppName
3610
3616
  }));
3611
3617
  };
3612
3618
 
@@ -3717,9 +3723,6 @@
3717
3723
  properties: {
3718
3724
  currentAppName: {
3719
3725
  type: String
3720
- },
3721
- indexName: {
3722
- type: String
3723
3726
  }
3724
3727
  }
3725
3728
  },