@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.
@@ -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
 
@@ -3603,6 +3609,19 @@ const {
3603
3609
  LoadingIndicator: LoadingIndicator$1,
3604
3610
  StackView: StackView$1
3605
3611
  } = components;
3612
+ function CalendlyWidget({
3613
+ url,
3614
+ pageSettings,
3615
+ prefill,
3616
+ styles
3617
+ }) {
3618
+ return url ? (/*#__PURE__*/React__default.createElement(InlineWidget, {
3619
+ url: url,
3620
+ pageSettings: pageSettings,
3621
+ prefill: prefill,
3622
+ styles: styles
3623
+ })) : null;
3624
+ }
3606
3625
  function HelpdeskComponent({
3607
3626
  appName,
3608
3627
  closeDrawer,
@@ -3671,14 +3690,68 @@ function HelpdeskComponent({
3671
3690
  spacing: 1
3672
3691
  }, /*#__PURE__*/React__default.createElement(DrawerHeading, null, "Help and support"), /*#__PURE__*/React__default.createElement(LoadingIndicator$1, null)))),
3673
3692
  additionalComponents: {
3674
- // @ts-expect-error TODO: Relax type specification in add-ons-js to not require children
3675
- CalendlyWidget: InlineWidget,
3676
- DocumentationSearch,
3677
- DrawerHeader,
3693
+ CalendlyWidget: {
3694
+ component: CalendlyWidget,
3695
+ properties: {
3696
+ pageSettings: {
3697
+ attribute: false
3698
+ },
3699
+ prefill: {
3700
+ attribute: false
3701
+ },
3702
+ styles: {
3703
+ attribute: false
3704
+ },
3705
+ url: {
3706
+ type: String
3707
+ }
3708
+ }
3709
+ },
3710
+ DocumentationSearch: {
3711
+ component: DocumentationSearch,
3712
+ properties: {
3713
+ currentAppName: {
3714
+ type: String
3715
+ },
3716
+ indexName: {
3717
+ type: String
3718
+ }
3719
+ }
3720
+ },
3721
+ DrawerHeader: {
3722
+ component: DrawerHeader,
3723
+ properties: {
3724
+ closeDrawer: {
3725
+ event: false
3726
+ }
3727
+ }
3728
+ },
3678
3729
  DrawerHeading,
3679
- PicobotIframe,
3730
+ PicobotIframe: {
3731
+ component: PicobotIframe,
3732
+ properties: {
3733
+ currentPath: {
3734
+ attribute: false
3735
+ },
3736
+ onChangePath: {
3737
+ event: false,
3738
+ type: Function
3739
+ },
3740
+ onMessage: {
3741
+ event: false,
3742
+ type: Function
3743
+ }
3744
+ }
3745
+ },
3680
3746
  ScrollContainer,
3681
- SwitchView
3747
+ SwitchView: {
3748
+ component: SwitchView,
3749
+ properties: {
3750
+ activeIndex: {
3751
+ type: Number
3752
+ }
3753
+ }
3754
+ }
3682
3755
  },
3683
3756
  args: {
3684
3757
  appName,
@@ -4282,8 +4355,13 @@ const {
4282
4355
  function NavLinkWithBadge({
4283
4356
  children,
4284
4357
  badge,
4285
- onClick,
4286
- ...rest
4358
+ borderBottomColor,
4359
+ borderBottomStyle,
4360
+ borderBottomWidth,
4361
+ color,
4362
+ fontSize,
4363
+ fontWeight,
4364
+ onClick
4287
4365
  }) {
4288
4366
  return /*#__PURE__*/React__default.createElement(StackView$2, {
4289
4367
  as: "button",
@@ -4293,7 +4371,14 @@ function NavLinkWithBadge({
4293
4371
  paddingBottom: 0.75,
4294
4372
  onClick: () => onClick(),
4295
4373
  spacing: 1,
4296
- ...rest
4374
+ ...{
4375
+ borderBottomColor,
4376
+ borderBottomStyle,
4377
+ borderBottomWidth,
4378
+ color,
4379
+ fontSize,
4380
+ fontWeight
4381
+ }
4297
4382
  }, children, badge && /*#__PURE__*/React__default.createElement(Badge, {
4298
4383
  size: "sm",
4299
4384
  fontWeight: "600",
@@ -4345,11 +4430,55 @@ function TasksComponent({
4345
4430
  spacing: 1
4346
4431
  }, /*#__PURE__*/React__default.createElement(DrawerHeading, null, "To do"), /*#__PURE__*/React__default.createElement(LoadingIndicator, null)))),
4347
4432
  additionalComponents: {
4348
- DrawerHeader,
4433
+ DrawerHeader: {
4434
+ component: DrawerHeader,
4435
+ properties: {
4436
+ closeDrawer: {
4437
+ event: false,
4438
+ type: Function
4439
+ }
4440
+ }
4441
+ },
4349
4442
  DrawerHeading,
4350
- NavLinkWithBadge,
4443
+ NavLinkWithBadge: {
4444
+ component: NavLinkWithBadge,
4445
+ properties: {
4446
+ badge: {
4447
+ attribute: false
4448
+ },
4449
+ borderBottomColor: {
4450
+ type: String
4451
+ },
4452
+ borderBottomStyle: {
4453
+ type: String
4454
+ },
4455
+ borderBottomWidth: {
4456
+ type: String
4457
+ },
4458
+ color: {
4459
+ type: String
4460
+ },
4461
+ fontSize: {
4462
+ attribute: false
4463
+ },
4464
+ fontWeight: {
4465
+ attribute: false
4466
+ },
4467
+ onClick: {
4468
+ event: false,
4469
+ type: Function
4470
+ }
4471
+ }
4472
+ },
4351
4473
  ScrollContainer,
4352
- SwitchView
4474
+ SwitchView: {
4475
+ component: SwitchView,
4476
+ properties: {
4477
+ activeIndex: {
4478
+ type: Number
4479
+ }
4480
+ }
4481
+ }
4353
4482
  },
4354
4483
  args: {
4355
4484
  closeDrawer,