@planningcenter/topbar 11.2.5 → 12.0.0-qa-834.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
 
@@ -3614,6 +3620,19 @@
3614
3620
  LoadingIndicator: LoadingIndicator$1,
3615
3621
  StackView: StackView$1
3616
3622
  } = addOns.components;
3623
+ function CalendlyWidget({
3624
+ url,
3625
+ pageSettings,
3626
+ prefill,
3627
+ styles
3628
+ }) {
3629
+ return url ? (/*#__PURE__*/React.createElement(reactCalendly.InlineWidget, {
3630
+ url: url,
3631
+ pageSettings: pageSettings,
3632
+ prefill: prefill,
3633
+ styles: styles
3634
+ })) : null;
3635
+ }
3617
3636
  function HelpdeskComponent({
3618
3637
  appName,
3619
3638
  closeDrawer,
@@ -3682,14 +3701,68 @@
3682
3701
  spacing: 1
3683
3702
  }, /*#__PURE__*/React.createElement(DrawerHeading, null, "Help and support"), /*#__PURE__*/React.createElement(LoadingIndicator$1, null)))),
3684
3703
  additionalComponents: {
3685
- // @ts-expect-error TODO: Relax type specification in add-ons-js to not require children
3686
- CalendlyWidget: reactCalendly.InlineWidget,
3687
- DocumentationSearch,
3688
- DrawerHeader,
3704
+ CalendlyWidget: {
3705
+ component: CalendlyWidget,
3706
+ properties: {
3707
+ pageSettings: {
3708
+ attribute: false
3709
+ },
3710
+ prefill: {
3711
+ attribute: false
3712
+ },
3713
+ styles: {
3714
+ attribute: false
3715
+ },
3716
+ url: {
3717
+ type: String
3718
+ }
3719
+ }
3720
+ },
3721
+ DocumentationSearch: {
3722
+ component: DocumentationSearch,
3723
+ properties: {
3724
+ currentAppName: {
3725
+ type: String
3726
+ },
3727
+ indexName: {
3728
+ type: String
3729
+ }
3730
+ }
3731
+ },
3732
+ DrawerHeader: {
3733
+ component: DrawerHeader,
3734
+ properties: {
3735
+ closeDrawer: {
3736
+ event: false
3737
+ }
3738
+ }
3739
+ },
3689
3740
  DrawerHeading,
3690
- PicobotIframe,
3741
+ PicobotIframe: {
3742
+ component: PicobotIframe,
3743
+ properties: {
3744
+ currentPath: {
3745
+ attribute: false
3746
+ },
3747
+ onChangePath: {
3748
+ event: false,
3749
+ type: Function
3750
+ },
3751
+ onMessage: {
3752
+ event: false,
3753
+ type: Function
3754
+ }
3755
+ }
3756
+ },
3691
3757
  ScrollContainer,
3692
- SwitchView
3758
+ SwitchView: {
3759
+ component: SwitchView,
3760
+ properties: {
3761
+ activeIndex: {
3762
+ type: Number
3763
+ }
3764
+ }
3765
+ }
3693
3766
  },
3694
3767
  args: {
3695
3768
  appName,
@@ -4293,8 +4366,13 @@
4293
4366
  function NavLinkWithBadge({
4294
4367
  children,
4295
4368
  badge,
4296
- onClick,
4297
- ...rest
4369
+ borderBottomColor,
4370
+ borderBottomStyle,
4371
+ borderBottomWidth,
4372
+ color,
4373
+ fontSize,
4374
+ fontWeight,
4375
+ onClick
4298
4376
  }) {
4299
4377
  return /*#__PURE__*/React.createElement(tapestryReact.StackView, {
4300
4378
  as: "button",
@@ -4304,7 +4382,14 @@
4304
4382
  paddingBottom: 0.75,
4305
4383
  onClick: () => onClick(),
4306
4384
  spacing: 1,
4307
- ...rest
4385
+ ...{
4386
+ borderBottomColor,
4387
+ borderBottomStyle,
4388
+ borderBottomWidth,
4389
+ color,
4390
+ fontSize,
4391
+ fontWeight
4392
+ }
4308
4393
  }, children, badge && /*#__PURE__*/React.createElement(tapestryReact.Badge, {
4309
4394
  size: "sm",
4310
4395
  fontWeight: "600",
@@ -4356,11 +4441,55 @@
4356
4441
  spacing: 1
4357
4442
  }, /*#__PURE__*/React.createElement(DrawerHeading, null, "To do"), /*#__PURE__*/React.createElement(LoadingIndicator, null)))),
4358
4443
  additionalComponents: {
4359
- DrawerHeader,
4444
+ DrawerHeader: {
4445
+ component: DrawerHeader,
4446
+ properties: {
4447
+ closeDrawer: {
4448
+ event: false,
4449
+ type: Function
4450
+ }
4451
+ }
4452
+ },
4360
4453
  DrawerHeading,
4361
- NavLinkWithBadge,
4454
+ NavLinkWithBadge: {
4455
+ component: NavLinkWithBadge,
4456
+ properties: {
4457
+ badge: {
4458
+ attribute: false
4459
+ },
4460
+ borderBottomColor: {
4461
+ type: String
4462
+ },
4463
+ borderBottomStyle: {
4464
+ type: String
4465
+ },
4466
+ borderBottomWidth: {
4467
+ type: String
4468
+ },
4469
+ color: {
4470
+ type: String
4471
+ },
4472
+ fontSize: {
4473
+ attribute: false
4474
+ },
4475
+ fontWeight: {
4476
+ attribute: false
4477
+ },
4478
+ onClick: {
4479
+ event: false,
4480
+ type: Function
4481
+ }
4482
+ }
4483
+ },
4362
4484
  ScrollContainer,
4363
- SwitchView
4485
+ SwitchView: {
4486
+ component: SwitchView,
4487
+ properties: {
4488
+ activeIndex: {
4489
+ type: Number
4490
+ }
4491
+ }
4492
+ }
4364
4493
  },
4365
4494
  args: {
4366
4495
  closeDrawer,