@saasquatch/mint-components 1.9.2-3 → 1.9.3

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.
Files changed (73) hide show
  1. package/dist/cjs/{ShadowViewAddon-1d7d274f.js → ShadowViewAddon-5fe15ad2.js} +6 -3
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/mint-components.cjs.js +1 -1
  4. package/dist/cjs/sqm-big-stat_38.cjs.entry.js +22 -3
  5. package/dist/cjs/sqm-empty_4.cjs.entry.js +17 -3
  6. package/dist/cjs/sqm-rewards-table_9.cjs.entry.js +4 -2
  7. package/dist/cjs/sqm-stencilbook.cjs.entry.js +57 -3
  8. package/dist/collection/components/sqm-empty/EmptyState.stories.js +2 -0
  9. package/dist/collection/components/sqm-empty/sqm-empty-view.js +15 -2
  10. package/dist/collection/components/sqm-empty/sqm-empty.js +24 -1
  11. package/dist/collection/components/sqm-leaderboard/Leaderboard.stories.js +31 -0
  12. package/dist/collection/components/sqm-leaderboard/sqm-leaderboard-view.js +6 -3
  13. package/dist/collection/components/sqm-leaderboard/sqm-leaderboard.js +46 -1
  14. package/dist/collection/components/sqm-leaderboard/useLeaderboard.js +5 -2
  15. package/dist/collection/components/sqm-popup-container/sqm-popup-container.js +6 -0
  16. package/dist/collection/components/sqm-portal-footer/sqm-portal-footer.js +8 -0
  17. package/dist/collection/components/sqm-rewards-table/RewardsTable.stories.js +8 -1
  18. package/dist/collection/components/sqm-rewards-table/RewardsTableCell.stories.js +13 -0
  19. package/dist/collection/components/sqm-rewards-table/cells/sqm-rewards-table-source-cell.js +21 -2
  20. package/dist/collection/components/sqm-titled-section/sqm-titled-section.js +8 -3
  21. package/dist/esm/{ShadowViewAddon-b04465af.js → ShadowViewAddon-b2de2d8f.js} +6 -3
  22. package/dist/esm/loader.js +1 -1
  23. package/dist/esm/mint-components.js +1 -1
  24. package/dist/esm/sqm-big-stat_38.entry.js +22 -3
  25. package/dist/esm/sqm-empty_4.entry.js +17 -3
  26. package/dist/esm/sqm-rewards-table_9.entry.js +4 -2
  27. package/dist/esm/sqm-stencilbook.entry.js +57 -3
  28. package/dist/esm-es5/ShadowViewAddon-b2de2d8f.js +1 -0
  29. package/dist/esm-es5/loader.js +1 -1
  30. package/dist/esm-es5/mint-components.js +1 -1
  31. package/dist/esm-es5/sqm-big-stat_38.entry.js +1 -1
  32. package/dist/esm-es5/sqm-empty_4.entry.js +1 -1
  33. package/dist/esm-es5/sqm-rewards-table_9.entry.js +1 -1
  34. package/dist/esm-es5/sqm-stencilbook.entry.js +1 -1
  35. package/dist/mint-components/mint-components.esm.js +1 -1
  36. package/dist/mint-components/p-00b937ab.system.entry.js +1 -0
  37. package/dist/mint-components/p-0bdfc00e.system.entry.js +1 -0
  38. package/dist/mint-components/p-14f1f79b.entry.js +187 -0
  39. package/dist/mint-components/p-6ffed27b.system.js +1 -1
  40. package/dist/mint-components/{p-a8c90696.system.entry.js → p-7fda77ac.system.entry.js} +1 -1
  41. package/dist/mint-components/p-855eeedd.system.entry.js +1 -0
  42. package/dist/mint-components/p-be00e478.entry.js +1 -0
  43. package/dist/mint-components/{p-3ba7f54e.entry.js → p-c0500993.entry.js} +2 -2
  44. package/dist/mint-components/{p-4869e1d6.js → p-de2aa147.js} +1 -1
  45. package/dist/mint-components/p-e98fe050.system.js +1 -0
  46. package/dist/mint-components/{p-0a0ec6a8.entry.js → p-eac38c5e.entry.js} +2 -2
  47. package/dist/types/components/sqm-empty/sqm-empty-view.d.ts +2 -0
  48. package/dist/types/components/sqm-empty/sqm-empty.d.ts +5 -0
  49. package/dist/types/components/sqm-leaderboard/Leaderboard.stories.d.ts +1 -0
  50. package/dist/types/components/sqm-leaderboard/sqm-leaderboard-view.d.ts +2 -0
  51. package/dist/types/components/sqm-leaderboard/sqm-leaderboard.d.ts +13 -0
  52. package/dist/types/components/sqm-leaderboard/useLeaderboard.d.ts +1 -0
  53. package/dist/types/components/sqm-popup-container/sqm-popup-container.d.ts +2 -0
  54. package/dist/types/components/sqm-portal-footer/sqm-portal-footer.d.ts +2 -0
  55. package/dist/types/components/sqm-rewards-table/RewardsTableCell.stories.d.ts +1 -0
  56. package/dist/types/components/sqm-rewards-table/cells/sqm-rewards-table-source-cell.d.ts +1 -0
  57. package/dist/types/components/sqm-titled-section/sqm-titled-section.d.ts +2 -1
  58. package/dist/types/components.d.ts +35 -3
  59. package/dist/types/global/android.d.ts +7 -0
  60. package/dist/types/global/demo.d.ts +2 -0
  61. package/dist/types/stories/features.d.ts +4 -0
  62. package/dist/types/stories/templates.d.ts +4 -0
  63. package/docs/docs.docx +0 -0
  64. package/docs/raisins.json +1 -1
  65. package/grapesjs/grapesjs.js +1 -1
  66. package/package.json +3 -2
  67. package/dist/esm-es5/ShadowViewAddon-b04465af.js +0 -1
  68. package/dist/mint-components/p-2574a651.system.entry.js +0 -1
  69. package/dist/mint-components/p-59bc9a2d.entry.js +0 -187
  70. package/dist/mint-components/p-6cddd2fc.system.entry.js +0 -1
  71. package/dist/mint-components/p-6d2a23e7.system.entry.js +0 -1
  72. package/dist/mint-components/p-c53a801b.system.js +0 -1
  73. package/dist/mint-components/p-ce72e90a.entry.js +0 -1
@@ -28,7 +28,7 @@ const sqmPortalProfileView = require('./sqm-portal-profile-view-04239bdf.js');
28
28
  require('./utilities-d1a46070.js');
29
29
  const sqmPortalResetPasswordView = require('./sqm-portal-reset-password-view-96f329ed.js');
30
30
  const sqmPortalVerifyEmailView = require('./sqm-portal-verify-email-view-7ffcc0d4.js');
31
- const ShadowViewAddon = require('./ShadowViewAddon-1d7d274f.js');
31
+ const ShadowViewAddon = require('./ShadowViewAddon-5fe15ad2.js');
32
32
  const sqmPortalContainerView = require('./sqm-portal-container-view-5fb2ad49.js');
33
33
  const sqmInvoiceTableView = require('./sqm-invoice-table-view-7660f329.js');
34
34
 
@@ -1583,6 +1583,7 @@ const Empty = () => {
1583
1583
  };
1584
1584
  const defaultElements = {
1585
1585
  empty: (index.h("sqm-empty", { "empty-state-image": "https://res.cloudinary.com/saasquatch/image/upload/v1644360953/squatch-assets/empty_leaderboard2.png", "empty-state-header": "View your rank in the leaderboard", "empty-state-text": "Be the first to refer a friend and reach the top of the leaderboard" })),
1586
+ essentials: (index.h("sqm-empty", { "empty-state-image": "https://res.cloudinary.com/saasquatch/image/upload/v1715360191/squatch-assets/Leaderboard_Not_Available.svg", "empty-state-header": "Leaderboards aren\u2019t available on your plan", "empty-state-text": "Contact {supportText} to upgrade your plan and start leveraging gamification in your program.", "support-text": "Support" })),
1586
1587
  loadingstate: (index.h("slot", { name: "loading" },
1587
1588
  index.h("table", null, [...Array(10)].map(() => {
1588
1589
  return (index.h("tr", null,
@@ -1595,6 +1596,7 @@ const SlottedIntoComponent = () => {
1595
1596
  states: {
1596
1597
  loading: false,
1597
1598
  hasLeaders: false,
1599
+ isEssentials: false,
1598
1600
  styles: {
1599
1601
  ...defaultStyles,
1600
1602
  },
@@ -1811,7 +1813,7 @@ const BigStat = /*#__PURE__*/Object.freeze({
1811
1813
  MultipleStats: MultipleStats
1812
1814
  });
1813
1815
 
1814
- const scenario$4 = "@owner:noah\n@author:noah\nFeature: Leaderboard\n\n\tThe leaderboard supports three main cases\n\t- Top Started Referrers\n\t- Top Converted Referrers\n\t- Top Point Earners\n\tTo display these different types of leaderboards it uses the backends pre-canned options.\n\tThe backend supports filtering on programId and interval, programId is sourced from program context.\n\n\tBackground: A user exists\n\t\tGiven a user\n\t\tAnd they are viewing the leaderboard\n\n\t@motivating\n\tScenario Outline: Two types of referrals leaderboards can be displayed\n\t\tGiven a leaderboard has prop \"leaderboard-type\" with <value>\n\t\tAnd there are started referrals on the tenant\n\t\tAnd there are started converted on the tenant\n\t\tWhen the user views the leaderboard\n\t\tThen they see the referral <referralType> leaderboard\n\t\tExamples:\n\t\t\t| value | referralType |\n\t\t\t| topStartedReferrers | started |\n\t\t\t| topConvertedReferrers | converted |\n\n\t@motivating\n\tScenario: The top point earners leaderboard can be displayed\n\t\tGiven a leaderboard has prop \"leaderboard-type\" with value \"topPointEarners\"\n\t\tAnd there are users with points\n\t\tWhen the user views the leaderboard\n\t\tThen they see the top point earners leaderboard\n\t\tAnd text values are displayed for point counts\n\n\t@minutia\n\tScenario Outline: Reward pretty value is used on the top point earners leaderboard\n\t\tGiven top point earners leaderboard\n\t\tAnd the \"POINT\" reward unit has a pretty value for the following locales\n\t\t\t| locale |\n\t\t\t| en |\n\t\t\t| fr |\n\t\t\t| tr |\n\t\tWhen the user views the leaderboard\n\t\tAnd they have <locale>\n\t\tThen they see the translated pretty value in the stat value column\n\n\t@motivating\n\tScenario Outline: Program Context is used by default to filter leaderboard results\n\t\tGiven a <leaderboardType> leaderboard loaded with program context for \"my-program\"\n\t\tWhen the user views the leaderboard\n\t\tThen they only see <results> from \"my-program\"\n\t\tExamples:\n\t\t\t| leaderboardType | results |\n\t\t\t| topStartedReferrers | started referrals |\n\t\t\t| topConvertedReferrers | converted referrals |\n\t\t\t| topPointEarners | points earned |\n\n\t@motivating\n\tScenario Outline: Program Id context can be overwritten with a prop\n\t\tGiven a <leaderboardType> leaderboard has prop \"program-Id\" with value \"my-test-program\"\n\t\tWhen the user views the leaderboard\n\t\tThen they only see <results> from \"my-test-program\"\n\t\tExamples:\n\t\t\t| leaderboardType | results |\n\t\t\t| topStartedReferrers | started referrals |\n\t\t\t| topConvertedReferrers | converted referrals |\n\t\t\t| topPointEarners | points earned |\n\n\t@motivating\n\tScenario Outline: Global leaderboards can be displayed by clearing program context\n\t\t#This is important for clients with use cases like StaffTracks global points leaderboard\n\t\t#This can also be done with a program section in a similar manner\n\t\tGiven a <leaderboardType> leaderboard has prop \"program-Id\" with value \"\"\n\t\tWhen the user views the leaderboard\n\t\tThen they see global <results>\n\t\tExamples:\n\t\t\t| leaderboardType | results |\n\t\t\t| topStartedReferrers | started referrals |\n\t\t\t| topConvertedReferrers | converted referrals |\n\t\t\t| topPointEarners | points earned |\n\n\t@motivating\n\tScenario: Leaderboard results are shown in descending order\n\t\tGiven there are leaderboard results\n\t\tWhen the user views the leaderboard\n\t\tThen they see up to the 10 top leaderboard results\n\t\tAnd leaderboard is in descending order\n\n\t@motivating\n\tScenario Outline: Leaderboard results can be filtered with a time interval\n\t\tGiven a <leaderboardType> leaderboard\n\t\tAnd it has prop \"interval\" with value \"2021-11-02T07:00:00.000Z/2021-11-07T07:00:00.000Z\"\n\t\tWhen the user views the leaderboard\n\t\tThen they only see <results> from within \"2021-11-02T07:00:00.000Z/2021-11-07T07:00:00.000Z\"\n\t\tExamples:\n\t\t\t| leaderboardType | results |\n\t\t\t| topStartedReferrers | started referrals |\n\t\t\t| topConvertedReferrers | converted referrals |\n\t\t\t| topPointEarners | points earned |\n\n\t@motivating\n\tScenario Outline: Leaderboard rank type can be configured\n\t\tGiven a leaderboard has prop \"rank-type\" with <value>\n\t\tWhen the user views the leaderboard\n\t\tThen their leaderboard rank is their <rank>\n\t\tExamples:\n\t\t\t| value | rank |\n\t\t\t| rowNumber | row number |\n\t\t\t| denseRank | dense rank |\n\t\t\t| rank | rank |\n\n\t@minutia\n\tScenario Outline: The max number of leaderboard rows displayed can be configured but defaults to 10\n\t\tGiven a leaderboard has prop \"max-rows\" with <value>\n\t\tAnd the leaderboard has <resultCount>\n\t\tWhen the user views the leaderboard\n\t\tThen they see <number> rows\n\t\tExamples:\n\t\t\t| value | resultCount | number |\n\t\t\t| | 10 | 10 |\n\t\t\t| 5 | 10 | 5 |\n\t\t\t| 3 | 1 | 1 |\n\t\t\t| 25 | 15 | 15 |\n\n\t@minutiae\n\t@ui\n\tScenario: Leaderboards with no results show an empty state\n\t\tGiven a leaderboard has no results\n\t\tWhen the user views the leaderboard\n\t\tThen an empty state is dislayed\n\t\tAnd they see an image of a leaderboard\n\t\tAnd below they see \"View your rank in the leaderboard\"\n\t\tAnd below they see \"Be the first to refer a friend and reach the top of the leaderboard\"\n\t\tAnd the text is center aligned\n\n\t@minutiae\n\t@ui\n\tScenario: A custom empty state can be provided\n\t\tGiven a leaderboard has no results\n\t\tWhen the user views the leaderboard\n\t\tThen the contents of the \"empty\" slot are displayed\n\n\t@minutiae\n\t@ui\n\tScenario: Leaderboard headings can be customized\n\t\tGiven a leaderboard\n\t\tAnd it has the following props\n\t\t\t| prop | value |\n\t\t\t| rankheading | Place |\n\t\t\t| usersheading | Customer |\n\t\t\t| statsheading | Referral Count |\n\t\t\t| show-rank | true |\n\t\tWhen the user views the leaderboard\n\t\tThen they see the following columns with headings\n\t\t\t| column | heading |\n\t\t\t| rank | Place |\n\t\t\t| user | Customer |\n\t\t\t| stat | Referral Count |\n\n\t@motivating\n\t@ui\n\tScenario Outline: Leaderboard rank can be hidden or shown\n\t\tGiven a leaderboard\n\t\tAnd it has prop \"show-rank\" with <propValue>\n\t\tWhen the user views the leaderboard\n\t\tThen they <maySee> the rank column\n\t\tExamples:\n\t\t\t| propValue | maySee |\n\t\t\t| true | see |\n\t\t\t| false | don't see |\n\t\t\t| | don't see |\n\n\t@motivating\n\t@ui\n\tScenario: Users in the top 10 of the leaderboard results see their leaderboard row highlighted\n\t\tGiven a user in the top 10 of the leaderboard results\n\t\tWhen they view the leaderboard\n\t\tThen they see the row with their name highlighted with brand colour\n\n\t@motivating\n\t@ui\n\tScenario Outline: Users not in the top 10 leaderboard results can see their progress at the bottom of the leaderboard\n\t\tGiven a user <mayHave> completed actions counted by the leaderboard\n\t\tAnd they are not in the top 10 leaderboard results\n\t\tAnd the leaderboard has prop \"show-user\" with <value>\n\t\tWhen they view the leaderboard\n\t\tThen they <maySee> \"...\" under the top 10 leaderboard results\n\t\tAnd under \"...\" they <maySee> a row highlighted with brand colour\n\t\tAnd they <maySee> their name\n\t\tAnd they <maySee> their leaderboard value\n\t\tAnd they <maySeeRank>\n\t\tExamples:\n\t\t\t| mayHave | value | maySee | maySeeRank |\n\t\t\t| has | true | see | see their rank |\n\t\t\t| hasn't | true | see | don't see their rank |\n\t\t\t| N/A | false | don't see | don't see their rank |\n\t\t\t| hasn't | | see | don't see their rank |\n\n\t@minutiae\n\tScenario: Users without names are displayed as an \"Anonymous User\"\n\t\tGiven a user\n\t\tAnd they do not have a first name\n\t\tAnd they do not have a last initial\n\t\tWhen they view the leaderboard\n\t\tThen they see the user displayed as \"Anonymous User\"\n\n\t@minutiae\n\tScenario Outline: If a user only has a first or last name, then only that is displayed\n\t\tGiven a user\n\t\tAnd they only have a <name>\n\t\tWhen they view the leaderboard\n\t\tThen they only see their <name>\n\t\tExamples:\n\t\t\t| name |\n\t\t\t| firstName |\n\t\t\t| lastName |";
1816
+ const scenario$4 = "@owner:noah @author:noah\nFeature: Leaderboard\n\tThe leaderboard supports three main cases\n\t- Top Started Referrers\n\t- Top Converted Referrers\n\t- Top Point Earners\n\tTo display these different types of leaderboards it uses the backends pre-canned options.\n\tThe backend supports filtering on programId and interval, programId is sourced from program context.\n\n Background: A user exists\n Given a user\n And they are viewing the leaderboard\n\n @motivating\n Scenario Outline: Two types of referrals leaderboards can be displayed\n Given a leaderboard has prop \"leaderboard-type\" with <value>\n And there are started referrals on the tenant\n And there are started converted on the tenant\n When the user views the leaderboard\n Then they see the referral <referralType> leaderboard\n\n Examples:\n | value | referralType |\n | topStartedReferrers | started |\n | topConvertedReferrers | converted |\n\n @motivating\n Scenario: The top point earners leaderboard can be displayed\n Given a leaderboard has prop \"leaderboard-type\" with value \"topPointEarners\"\n And there are users with points\n When the user views the leaderboard\n Then they see the top point earners leaderboard\n And text values are displayed for point counts\n\n @minutia\n Scenario Outline: Reward pretty value is used on the top point earners leaderboard\n Given top point earners leaderboard\n And the \"POINT\" reward unit has a pretty value for the following locales\n | locale |\n | en |\n | fr |\n | tr |\n When the user views the leaderboard\n And they have <locale>\n Then they see the translated pretty value in the stat value column\n\n @motivating\n Scenario Outline: Program Context is used by default to filter leaderboard results\n Given a <leaderboardType> leaderboard loaded with program context for \"my-program\"\n When the user views the leaderboard\n Then they only see <results> from \"my-program\"\n\n Examples:\n | leaderboardType | results |\n | topStartedReferrers | started referrals |\n | topConvertedReferrers | converted referrals |\n | topPointEarners | points earned |\n\n @motivating\n Scenario Outline: Program Id context can be overwritten with a prop\n Given a <leaderboardType> leaderboard has prop \"program-Id\" with value \"my-test-program\"\n When the user views the leaderboard\n Then they only see <results> from \"my-test-program\"\n\n Examples:\n | leaderboardType | results |\n | topStartedReferrers | started referrals |\n | topConvertedReferrers | converted referrals |\n | topPointEarners | points earned |\n\n @motivating\n Scenario Outline: Global leaderboards can be displayed by clearing program context\n\t\t#This is important for clients with use cases like StaffTracks global points leaderboard\n\t\t#This can also be done with a program section in a similar manner\n Given a <leaderboardType> leaderboard has prop \"program-Id\" with value \"\"\n When the user views the leaderboard\n Then they see global <results>\n\n Examples:\n | leaderboardType | results |\n | topStartedReferrers | started referrals |\n | topConvertedReferrers | converted referrals |\n | topPointEarners | points earned |\n\n @motivating\n Scenario: Leaderboard results are shown in descending order\n Given there are leaderboard results\n When the user views the leaderboard\n Then they see up to the 10 top leaderboard results\n And leaderboard is in descending order\n\n @motivating\n Scenario Outline: Leaderboard results can be filtered with a time interval\n Given a <leaderboardType> leaderboard\n And it has prop \"interval\" with value \"2021-11-02T07:00:00.000Z/2021-11-07T07:00:00.000Z\"\n When the user views the leaderboard\n Then they only see <results> from within \"2021-11-02T07:00:00.000Z/2021-11-07T07:00:00.000Z\"\n\n Examples:\n | leaderboardType | results |\n | topStartedReferrers | started referrals |\n | topConvertedReferrers | converted referrals |\n | topPointEarners | points earned |\n\n @motivating\n Scenario Outline: Leaderboard rank type can be configured\n Given a leaderboard has prop \"rank-type\" with <value>\n When the user views the leaderboard\n Then their leaderboard rank is their <rank>\n\n Examples:\n | value | rank |\n | rowNumber | row number |\n | denseRank | dense rank |\n | rank | rank |\n\n @minutia\n Scenario Outline: The max number of leaderboard rows displayed can be configured but defaults to 10\n Given a leaderboard has prop \"max-rows\" with <value>\n And the leaderboard has <resultCount>\n When the user views the leaderboard\n Then they see <number> rows\n\n Examples:\n | value | resultCount | number |\n | | 10 | 10 |\n | 5 | 10 | 5 |\n | 3 | 1 | 1 |\n | 25 | 15 | 15 |\n\n @minutiae @ui\n Scenario: Leaderboards with no results show an empty state\n Given a leaderboard has no results\n When the user views the leaderboard\n Then an empty state is dislayed\n And they see an image of a leaderboard\n And below they see \"View your rank in the leaderboard\"\n And below they see \"Be the first to refer a friend and reach the top of the leaderboard\"\n And the text is center aligned\n\n @minutiae @ui\n Scenario: A custom empty state can be provided\n Given a leaderboard has no results\n When the user views the leaderboard\n Then the contents of the \"empty\" slot are displayed\n\n @minutiae @ui\n Scenario: User is on Essentials plan\n Given the user has an Essentials plan\n When they view the leaderboard\n Then a message telling them to upgrade their plan appears:\n \"\"\"\n Contact Support to upgrade your plan and start leveraging\n gamification in your program.\n \"\"\"\n And an empty table image is displayed\n\n @minutiae @ui\n Scenario: Leaderboard headings can be customized\n Given a leaderboard\n And it has the following props\n | prop | value |\n | rankheading | Place |\n | usersheading | Customer |\n | statsheading | Referral Count |\n | show-rank | true |\n When the user views the leaderboard\n Then they see the following columns with headings\n | column | heading |\n | rank | Place |\n | user | Customer |\n | stat | Referral Count |\n\n @motivating @ui\n Scenario Outline: Leaderboard rank can be hidden or shown\n Given a leaderboard\n And it has prop \"show-rank\" with <propValue>\n When the user views the leaderboard\n Then they <maySee> the rank column\n\n Examples:\n | propValue | maySee |\n | true | see |\n | false | don't see |\n | | don't see |\n\n @motivating @ui\n Scenario: Users in the top 10 of the leaderboard results see their leaderboard row highlighted\n Given a user in the top 10 of the leaderboard results\n When they view the leaderboard\n Then they see the row with their name highlighted with brand colour\n\n @motivating @ui\n Scenario Outline: Users not in the top 10 leaderboard results can see their progress at the bottom of the leaderboard\n Given a user <mayHave> completed actions counted by the leaderboard\n And they are not in the top 10 leaderboard results\n And the leaderboard has prop \"show-user\" with <value>\n When they view the leaderboard\n Then they <maySee> \"...\" under the top 10 leaderboard results\n And under \"...\" they <maySee> a row highlighted with brand colour\n And they <maySee> their name\n And they <maySee> their leaderboard value\n And they <maySeeRank>\n\n Examples:\n | mayHave | value | maySee | maySeeRank |\n | has | true | see | see their rank |\n | hasn't | true | see | don't see their rank |\n | N/A | false | don't see | don't see their rank |\n | hasn't | | see | don't see their rank |\n\n @minutiae\n Scenario: Users without names are displayed as an \"Anonymous User\"\n Given a user\n And they do not have a first name\n And they do not have a last initial\n When they view the leaderboard\n Then they see the user displayed as \"Anonymous User\"\n\n @minutiae\n Scenario Outline: If a user only has a first or last name, then only that is displayed\n Given a user\n And they only have a <name>\n When they view the leaderboard\n Then they only see their <name>\n\n Examples:\n | name |\n | firstName |\n | lastName |\n";
1815
1817
 
1816
1818
  const Leaderboard_stories = {
1817
1819
  title: "Components/Leaderboard",
@@ -1969,8 +1971,10 @@ const defaultStyles$1 = {
1969
1971
  rankheading: "Rank",
1970
1972
  anonymousUser: "Anonymous User",
1971
1973
  };
1974
+ const link = index.h("a", null, "Support");
1972
1975
  const defaultElements$1 = {
1973
1976
  empty: (index.h("sqm-empty", { "empty-state-image": "https://res.cloudinary.com/saasquatch/image/upload/v1644360953/squatch-assets/empty_leaderboard2.png", "empty-state-header": "View your rank in the leaderboard", "empty-state-text": "Be the first to refer a friend and reach the top of the leaderboard" })),
1977
+ essentials: (index.h("sqm-empty", { "empty-state-image": "https://res.cloudinary.com/saasquatch/image/upload/v1715360191/squatch-assets/Leaderboard_Not_Available.svg", "empty-state-header": "Leaderboards aren\u2019t available on your plan", "empty-state-text": "Contact {supportText} to upgrade your plan and start leveraging gamification in your program.", "support-text": "Support" })),
1974
1978
  loadingstate: (index.h("slot", { name: "loading" },
1975
1979
  index.h("table", null, [...Array(10)].map(() => {
1976
1980
  return (index.h("tr", null,
@@ -2005,6 +2009,34 @@ const Empty$1 = () => {
2005
2009
  };
2006
2010
  return index.h(ShadowViewAddon.LeaderboardView, Object.assign({}, props));
2007
2011
  };
2012
+ const Essentials = () => {
2013
+ const props = {
2014
+ states: {
2015
+ loading: false,
2016
+ isEssentials: true,
2017
+ hasLeaders: false,
2018
+ styles: {
2019
+ ...defaultStyles$1,
2020
+ },
2021
+ },
2022
+ data: {
2023
+ rankType: "rowNumber",
2024
+ leaderboard: [],
2025
+ rowNumber: 10,
2026
+ viewerRank: {
2027
+ firstName: "Kutay",
2028
+ lastInitial: "C",
2029
+ textValue: "8",
2030
+ rowNumber: 11,
2031
+ rank: 23,
2032
+ },
2033
+ },
2034
+ elements: {
2035
+ ...defaultElements$1,
2036
+ },
2037
+ };
2038
+ return index.h(ShadowViewAddon.LeaderboardView, Object.assign({}, props));
2039
+ };
2008
2040
  const Loading = () => {
2009
2041
  const props = {
2010
2042
  states: {
@@ -2298,6 +2330,7 @@ const Leaderboard = /*#__PURE__*/Object.freeze({
2298
2330
  __proto__: null,
2299
2331
  'default': Leaderboard_stories,
2300
2332
  Empty: Empty$1,
2333
+ Essentials: Essentials,
2301
2334
  Loading: Loading,
2302
2335
  One: One,
2303
2336
  Five: Five,
@@ -11600,7 +11633,7 @@ const scenario2 = "@author:derek\n@owner:derek\nFeature: Reward Table reward Col
11600
11633
 
11601
11634
  const scenario3 = "@author:derek @owner:derek\nFeature: Reward Table Status Column\n Shows the status of each reward\n\n Background: \n Given the status column is included in the reward table\n\n @motivating @ui\n Scenario Outline: The title of the status column is configurable\n Given the \"column-title\" prop is set to <value>\n Then the status column is shown with <columnTitle>\n\n Examples: \n | value | columnTitle |\n | Status | |\n | My column title | My column title |\n\n @motivating @ui\n Scenario Outline: The status column displays the status of each reward\n Given a user\n And they have a <status> reward\n When they view the reward table\n Then the status of their reward is displayed in <pillColour> pill with <text>\n\n Examples: \n | status | text | pillColour |\n | AVAILABLE | Available | Green |\n | CANCELLED | Cancelled | Red |\n | PENDING | Pending | Orange |\n | EXPIRED | Expired | Red |\n | REDEEMED | Redeemed | Blue |\n | PENDING_REVIEW | Pending | Orange |\n | PAYOUT_TRANSFERRED | Payout Approved | blue |\n | PAYOUT_NOT_YET_DUE | Payout Approved | blue |\n | PAYOUT_OVERDUE | Payout Failed | Red |\n | PAYOUT_REVERSED | Payout Cancelled | Red |\n | PENDING_TAX_REVIEW | Pending | Orange |\n | PENDING_NEW_TAX_FORM | Pending | Orange |\n | PENDING_TAX_SUBMISSION | Pending | Orange |\n | PENDING_PARTNER_CREATION | Pending | Orange |\n | DENIED | Denied | Red |\n\n @motivating\n Scenario Outline: Reward status related information is displayed under status pills\n Given a user\n And they have a <reward>\n And their program is\n When they view the reward table\n Then they see their reward\n And under the pill is <text>\n And the date is localized to the users locale\n\n Examples: \n | reward | text |\n | available reward with an expiry date | localized expiry date in format \"Month-Day-Year\" |\n | redeemed reward | localized redemption date in format \"Month-Day-Year\" |\n | expired reward | localized expired date in format \"Month-Day-Year\" |\n | cancelled reward | localized cancelled date in format \"Month-Day-Year\" |\n | pending reward with a end date | localized pending for date in format \"Month-Day-Year\" |\n | pending reward due to W9 | W-9 required |\n | pending reward due to fufillment error | Fulfillment error |\n | reward pending review of referral | Pending review |\n | pending reward due to no connected Impact partner | Complete your tax and cash payout setup to receive your rewards. |\n | pending reward due to an invalid tax document | Invalid tax form. Submit a new form to receive your rewards. |\n | pending reward due to user required to submit a tax document | Submit your tax documents to receive your rewards. |\n | pending reward due to tax document being in review | Awaiting tax form review. |\n | reward whose payout failed | Payout failed due to a fulfillment issue and is currently being retried. |\n | reward whose payout was approved | Reward approved for payout and was scheduled for payment based on your settings. |\n | reward whose payout was cancelled | If you think this is a mistake, contact our Support team. |\n | cancelled reward from denied referral | Flagged as fraud |\n\n @minutia\n Scenario Outline: Tax-related reward statuses are based on the user's Impact tax connection\n Given a user\n And they are in a program that has Impact tax handling enabled\n And they have at least one pending reward\n And the reward's pending reasons include \"PAYOUT_CONFIGURATION_MISSING\"\n Then the status description will be\n \"\"\"\n Complete your tax and cash payout setup to receive your rewards.\n \"\"\"\n\n @motivating\n Scenario Outline: Statuses can be customized\n Given the \"status-text\" prop is \"{status, select, AVAILABLE {Redeem me!} CANCELLED {Unavailable} PENDING {Coming soon!} EXPIRED {Past due} REDEEMED {Spent} PENDING_REVIEW {Pending Review!} PAYOUT_SENT {Payout Sent!} PAYOUT_FAILED {Payout Failed!} PENDING_TAX_REVIEW {Pending Tax Review!} PENDING_NEW_TAX_FORM {Pending new tax form!} PENDING_TAX_SUBMISSION {Pending tax submission!} PENDING_PARTNER_CREATION {Pending partner creation!} DENIED {Unlucky!}}\"\n And a user\n And they have a <status> reward\n When they view the reward table\n Then the status of their reward is displayed in <pillColour> pill with <text>\n\n Examples: \n | status | text | pillColour |\n | AVAILABLE | Redeem me! | Green |\n | CANCELLED | Unavailable | Red |\n | PENDING | Coming soon! | Orange |\n | EXPIRED | Past due | Red |\n | REDEEMED | Spent | Blue |\n | PENDING_REVIEW | Pending Review! | Orange |\n | PAYOUT_TRANSFERRED | Payout Approved! | Blue |\n | PAYOUT_NOT_YET_DUE | Payout Approved! | Blue |\n | PAYOUT_OVERDUE | Payout Failed! | Red |\n | PAYOUT_REVERSED | Payout Cancelled! | Red |\n | DENIED | Unlucky! | Red |\n\n @minutia @ui\n Scenario: Expiry status date text can be configured\n Given the \"expiry-text\" prop has <value>\n And a user with an available reward with an expiry date\n When they view the reward table\n Then they see <text> under the Available Status pill\n\n Examples: \n | value | text |\n | | Expires on <EXPIRY DATE> |\n | Redeem before | Redeem before <EXPIRY DATE> |\n";
11602
11635
 
11603
- const scenario4 = "@author:derek\n@owner:derek\nFeature: Reward Table Source Column\n\n Shows the source of each reward\n\n @motivating\n @ui\n Scenario Outline: The title of the source column is configurable\n Given the \"column-title\" prop is set to <value>\n Then the source column is shown with <columnTitle>\n Examples:\n | value | columnTitle |\n | Source | |\n | My column title | My column title |\n\n @motivating\n @ui\n Scenario: The source column displays manual if the reward is caused by a manual action\n Given a user with a \"MANUAL\" reward\n When they view the rewards table\n Then the source of their reward is displayed as \"Manual\"\n\n @motivating\n @ui\n Scenario: The source column displays the program name if the reward is caused automatically by a program\n Given a user with a \"AUTOMATED\" program reward\n And the program has name \"Loyalty Program\"\n When they view the rewards table\n Then the source of their reward is displayed as \"Loyalty Program\"\n\n @motivating\n @ui\n Scenario Outline: The source column displays customizable reward exchange text with amount if the reward is caused by reward exchange\n Given the \"reward-exchange-text\" prop is <propValue>\n And a user with a \"MANUAL\" reward\n But it was created by a reward exchange\n Then they view the rewards table\n Then the source displays <exchangeText>\n And under it displays the following\n | prettyRedeemedCredit → prettyValue |\n Examples:\n | propValue | exchangeText |\n | | Reward Exchange |\n | Exchanged | Exchanged |\n\n @motivating\n @ui\n Scenario Outline: The source column displays customizable referral information if the reward is from a referral\n Given the \"reward-source-text\" prop is <propValue>\n And a user with a referral reward\n And that reward has <rewardSource>\n When they view the rewards table\n Then then source displays <referralText>\n And under it displays the full name of the <referralUser>\n Examples:\n | propValue | rewardSource | referralText | referralUser |\n | | REFERRED | Referred by | referrer user |\n | | FRIEND_SIGNUP | Referral to | referred user |\n | {rewardSource, select, FRIEND_SIGNUP {You Referred} REFERRED {Referred you} other {}} | REFERRED | Referred you | referrer user |\n | {rewardSource, select, FRIEND_SIGNUP {You Referred} REFERRED {Referred you} other {}} | FRIEND_SIGNUP | You Referred | referred user |\n\n @motivating\n @ui\n Scenario Outline: The source column displays the existing name for a referral if either the first name or last name does not exist\n Given a user with a referral reward\n And referral user exists\n And referral user has <name>\n But referral user has no <otherName>\n When they view the rewards table\n Then referral user's name is displayed as <name>\n Examples:\n | name | otherName |\n | first.name | last.name |\n | last.name | first.name |\n\n @motivating\n @ui\n Scenario Outline: The source column displays referral as \"Anonymous User\" if the referral user has no names\n Given a user with a referral reward\n And that reward has <rewardSource>\n And the <referralUser> has no first name\n And the <referralUser> has no last name\n When they view the rewards table\n Then then source displays <sourceText>\n And under it displays \"Anonymous User\"\n Examples:\n | rewardSource | referralUser | sourceText |\n | FRIEND_SIGNUP | referrer | Referral to |\n | REFERRED | referred user | Referred by |\n\n @motivating\n @ui\n Scenario Outline: The source column displays referral as \"Deleted User\" if the referral user is deleted in the system\n Given a user with a referral reward\n And that reward has <rewardSource>\n But <referral> user was deleted\n When they view the rewards table\n Then the source displays <sourceText>\n And under it displays \"Deleted User\"\n Examples:\n | rewardSource | referral | sourceText |\n | \"FRIEND_SIGNUP\" | referrer | Referral to |\n | \"REFERRED\" | referred | Referred by |\n\n @minutia\n @ui\n Scenario Outline: Name fallbacks for referral users without names are customizable\n Given <prop> with <value>\n And a user with a referral reward\n But the referral user <hadAction>\n When they view the rewards table\n Then the source displays <value> as the referral user\n Examples:\n | prop | value | hadAction |\n | deleted-user | Former Customer | was deleted |\n | anonymous-user | Nameless User | had first and last name deleted |\n\n @motivating\n Scenario Outline: Source text can be customized\n Given the \"reward-source-text\" prop is \"{rewardSource, select, MANUAL {Support} AUTOMATED {Loyalty Program} other {}}\"\n And a user with a <rewardSource> reward\n When they view the rewards table\n Then the source is <sourceText>\n Examples:\n | rewardSource | sourceText |\n | MANUAL | Support |\n | AUTOMATED | Loyalty Program |";
11636
+ const scenario4 = "@author:derek @owner:derek\nFeature: Reward Table Source Column\n Shows the source of each reward\n\n @motivating @ui\n Scenario Outline: The title of the source column is configurable\n Given the \"column-title\" prop is set to <value>\n Then the source column is shown with <columnTitle>\n\n Examples:\n | value | columnTitle |\n | Source | |\n | My column title | My column title |\n\n @motivating @ui\n Scenario: The source column displays manual if the reward is caused by a manual action\n Given a user with a \"MANUAL\" reward\n When they view the rewards table\n Then the source of their reward is displayed as \"Manual\"\n\n @motivating @ui\n Scenario: The source column displays the program name if the reward is caused automatically by a program\n Given a user with a \"AUTOMATED\" program reward\n And the program has name \"Loyalty Program\"\n When they view the rewards table\n Then the source of their reward is displayed as \"Loyalty Program\"\n\n @motivating @ui\n Scenario Outline: The source column displays customizable reward exchange text with amount if the reward is caused by reward exchange\n Given the \"reward-exchange-text\" prop is <propValue>\n And a user with a \"MANUAL\" reward\n But it was created by a reward exchange\n Then they view the rewards table\n Then the source displays <exchangeText>\n And under it displays the following\n | prettyRedeemedCredit → prettyValue |\n\n Examples:\n | propValue | exchangeText |\n | | Reward Exchange |\n | Exchanged | Exchanged |\n\n @motivating @ui\n Scenario Outline: The source column displays customizable referral information if the reward is from a referral\n Given the \"reward-source-text\" prop is <propValue>\n And a user with a referral reward\n And that reward has <rewardSource>\n When they view the rewards table\n Then then source displays <referralText>\n And under it displays the full name of the <referralUser>\n\n Examples:\n | propValue | rewardSource | referralText | referralUser |\n | | REFERRED | Referred by | referrer user |\n | | FRIEND_SIGNUP | Referral to | referred user |\n | {rewardSource, select, FRIEND_SIGNUP {You Referred} REFERRED {Referred you} other {}} | REFERRED | Referred you | referrer user |\n | {rewardSource, select, FRIEND_SIGNUP {You Referred} REFERRED {Referred you} other {}} | FRIEND_SIGNUP | You Referred | referred user |\n\n @motivating @ui\n Scenario Outline: The source column displays the existing name for a referral if either the first name or last name does not exist\n Given a user with a referral reward\n And referral user exists\n And referral user has <name>\n But referral user has no <otherName>\n When they view the rewards table\n Then referral user's name is displayed as <name>\n\n Examples:\n | name | otherName |\n | first.name | last.name |\n | last.name | first.name |\n\n @motivating @ui\n Scenario Outline: The source column displays referral as \"Anonymous User\" if the referral user has no names\n Given a user with a referral reward\n And that reward has <rewardSource>\n And the <referralUser> has no first name\n And the <referralUser> has no last name\n When they view the rewards table\n Then then source displays <sourceText>\n And under it displays \"Anonymous User\"\n\n Examples:\n | rewardSource | referralUser | sourceText |\n | FRIEND_SIGNUP | referrer | Referral to |\n | REFERRED | referred user | Referred by |\n\n @motivating @ui\n Scenario Outline: The source column displays referral as \"Deleted User\" if the referral user is deleted in the system\n Given a user with a referral reward\n And that reward has <rewardSource>\n But <referral> user was deleted\n When they view the rewards table\n Then the source displays <sourceText>\n And under it displays \"Deleted User\"\n\n Examples:\n | rewardSource | referral | sourceText |\n | \"FRIEND_SIGNUP\" | referrer | Referral to |\n | \"REFERRED\" | referred | Referred by |\n# AL: TODO DELETED REFERRAL SPEC\n\n @motivating @ui\n Scenario Outline: The source column displays referral as \"Deleted referral\" if the referral user is deleted in the system\n Given a user with a referral reward\n And that reward has <rewardSource>\n But <referral> user was deleted\n When they view the rewards table\n Then the source displays <sourceText>\n And under it displays \"Deleted referral\"\n\n Examples:\n | rewardSource | referral | sourceText |\n | \"FRIEND_SIGNUP\" | referrer | Referral to |\n | \"REFERRED\" | referred | Referred by |\n\n @minutia @ui\n Scenario Outline: Name fallbacks for referral users without names are customizable\n Given <prop> with <value>\n And a user with a referral reward\n But the referral user <hadAction>\n When they view the rewards table\n Then the source displays <value> as the referral user\n\n Examples:\n | prop | value | hadAction |\n | deleted-user | Former Customer | was deleted |\n | anonymous-user | Nameless User | had first and last name deleted |\n\n @motivating\n Scenario Outline: Source text can be customized\n Given the \"reward-source-text\" prop is \"{rewardSource, select, MANUAL {Support} AUTOMATED {Loyalty Program} other {}}\"\n And a user with a <rewardSource> reward\n When they view the rewards table\n Then the source is <sourceText>\n\n Examples:\n | rewardSource | sourceText |\n | MANUAL | Support |\n | AUTOMATED | Loyalty Program |\n";
11604
11637
 
11605
11638
  const scenario$r = scenario1 + scenario2 + scenario3 + scenario4;
11606
11639
  const RewardsTableCell_stories = {
@@ -11800,6 +11833,12 @@ const referred = (user = null) => {
11800
11833
  },
11801
11834
  };
11802
11835
  };
11836
+ const deletedReferral = () => {
11837
+ return {
11838
+ rewardSource: "REFERRED",
11839
+ referral: null,
11840
+ };
11841
+ };
11803
11842
  const SourceCellReferral = () => {
11804
11843
  return (index.h("sqm-rewards-table-source-cell", { reward: { ...rewardsData$1, ...referral(johnDoe) }, referralText: "Referral to" }));
11805
11844
  };
@@ -11816,6 +11855,13 @@ const SourceCellAnonymousUser = () => {
11816
11855
  const SourceCellDeletedUser = () => {
11817
11856
  return (index.h("sqm-rewards-table-source-cell", { reward: { ...rewardsData$1, ...referral(null) }, referralText: "Referral to", deletedUserText: "Deleted User" }));
11818
11857
  };
11858
+ const SourceCellDeletedReferral = () => {
11859
+ return (
11860
+ // AL: TODO
11861
+ index.h("sqm-rewards-table-source-cell", {
11862
+ //@ts-ignore
11863
+ reward: { ...rewardsData$1, ...deletedReferral() }, referralText: "Referral to", deletedReferralText: "Deleted Referral" }));
11864
+ };
11819
11865
  const StatusCellAvailable = () => {
11820
11866
  return (index.h("sqm-rewards-table-status-cell", { statusText: "Available", reward: rewardsData$1 }));
11821
11867
  };
@@ -12018,6 +12064,7 @@ const RewardsTableCell = /*#__PURE__*/Object.freeze({
12018
12064
  SourceCellReferred: SourceCellReferred,
12019
12065
  SourceCellAnonymousUser: SourceCellAnonymousUser,
12020
12066
  SourceCellDeletedUser: SourceCellDeletedUser,
12067
+ SourceCellDeletedReferral: SourceCellDeletedReferral,
12021
12068
  StatusCellAvailable: StatusCellAvailable,
12022
12069
  StatusCellAvailableExpiry: StatusCellAvailableExpiry,
12023
12070
  StatusCellRedeemed: StatusCellRedeemed,
@@ -12110,6 +12157,12 @@ const r_expired = [
12110
12157
  index.h(SourceCellReferred, null),
12111
12158
  index.h(DateCell$1, null),
12112
12159
  ];
12160
+ const r_deleted = [
12161
+ index.h(RewardsCellCreditCancelled, null),
12162
+ index.h(StatusCellCancelled, null),
12163
+ index.h(SourceCellDeletedReferral, null),
12164
+ index.h(DateCell$1, null),
12165
+ ];
12113
12166
  const r_cancelled = [
12114
12167
  index.h(RewardsCellCreditCancelled, null),
12115
12168
  index.h(StatusCellCancelled, null),
@@ -12193,6 +12246,7 @@ const RewardsTable = () => {
12193
12246
  r_available,
12194
12247
  r_redeemed,
12195
12248
  r_cancelled,
12249
+ r_deleted,
12196
12250
  r_expired,
12197
12251
  r_denied,
12198
12252
  r_pending_review,
@@ -16,6 +16,7 @@ export const Empty = () => {
16
16
  };
17
17
  const defaultElements = {
18
18
  empty: (h("sqm-empty", { "empty-state-image": "https://res.cloudinary.com/saasquatch/image/upload/v1644360953/squatch-assets/empty_leaderboard2.png", "empty-state-header": "View your rank in the leaderboard", "empty-state-text": "Be the first to refer a friend and reach the top of the leaderboard" })),
19
+ essentials: (h("sqm-empty", { "empty-state-image": "https://res.cloudinary.com/saasquatch/image/upload/v1715360191/squatch-assets/Leaderboard_Not_Available.svg", "empty-state-header": "Leaderboards aren\u2019t available on your plan", "empty-state-text": "Contact {supportText} to upgrade your plan and start leveraging gamification in your program.", "support-text": "Support" })),
19
20
  loadingstate: (h("slot", { name: "loading" },
20
21
  h("table", null, [...Array(10)].map(() => {
21
22
  return (h("tr", null,
@@ -28,6 +29,7 @@ export const SlottedIntoComponent = () => {
28
29
  states: {
29
30
  loading: false,
30
31
  hasLeaders: false,
32
+ isEssentials: false,
31
33
  styles: {
32
34
  ...defaultStyles,
33
35
  },
@@ -1,11 +1,24 @@
1
1
  import { h } from "@stencil/core";
2
+ import { intl } from "../../global/global";
2
3
  export function EmptyStateView(props) {
3
- const { emptyStateHeader, emptyStateImage, emptyStateText } = props;
4
+ const { emptyStateHeader, emptyStateImage, emptyStateText, supportText, missingFeature = "", } = props;
4
5
  return (h("sqm-portal-container", { padding: "large", gap: "medium", part: "sqm-base" },
5
6
  h("img", { style: { height: "100px", margin: "auto" }, src: emptyStateImage }),
6
7
  h("sqm-titled-section", { style: { maxHeight: "400px" }, "label-margin": "xxx-small", "text-align": "center" },
7
8
  h("sqm-text", { slot: "label" },
8
9
  h("p", { part: "header-text" }, emptyStateHeader)),
9
10
  h("sqm-text", { slot: "content" },
10
- h("p", { part: "description-text", style: { color: "var(--sl-color-gray-500)" } }, emptyStateText)))));
11
+ h("p", { part: "description-text", innerHTML: "", style: { color: "var(--sl-color-gray-500)" } }, intl.formatMessage({
12
+ id: "emptyStateText",
13
+ defaultMessage: emptyStateText,
14
+ }, {
15
+ supportText: (h("a", { target: "_blank", href: `mailto:saasquatch-support@impact.com?subject=Next steps for ${missingFeature} feature&body=Hi Support Team, %0D%0A
16
+ %0D%0A
17
+ I am interested to learn more about the ${missingFeature} feature. Please let me know the next steps to access this feature, including any necessary plan upgrades.%0D%0A
18
+ %0D%0A
19
+ - Feature Interested In: ${missingFeature}%0D%0A
20
+ - Company Name: [Please fill out your company name here]%0D%0A
21
+ %0D%0A
22
+ Thank you` }, supportText)),
23
+ }))))));
11
24
  }
@@ -7,7 +7,7 @@ import { EmptyStateView } from "./sqm-empty-view";
7
7
  export class Empty {
8
8
  render() {
9
9
  return (h(Host, { slot: "empty" },
10
- h(EmptyStateView, { emptyStateImage: this.emptyStateImage, emptyStateHeader: this.emptyStateHeader, emptyStateText: this.emptyStateText })));
10
+ h(EmptyStateView, { emptyStateImage: this.emptyStateImage, emptyStateHeader: this.emptyStateHeader, emptyStateText: this.emptyStateText, supportText: this.supportText })));
11
11
  }
12
12
  static get is() { return "sqm-empty"; }
13
13
  static get encapsulation() { return "shadow"; }
@@ -80,6 +80,29 @@ export class Empty {
80
80
  },
81
81
  "attribute": "empty-state-text",
82
82
  "reflect": false
83
+ },
84
+ "supportText": {
85
+ "type": "string",
86
+ "mutable": false,
87
+ "complexType": {
88
+ "original": "string",
89
+ "resolved": "string",
90
+ "references": {}
91
+ },
92
+ "required": false,
93
+ "optional": true,
94
+ "docs": {
95
+ "tags": [{
96
+ "text": "Description",
97
+ "name": "uiName"
98
+ }, {
99
+ "text": "textArea",
100
+ "name": "uiWidget"
101
+ }],
102
+ "text": ""
103
+ },
104
+ "attribute": "support-text",
105
+ "reflect": false
83
106
  }
84
107
  }; }
85
108
  }
@@ -157,8 +157,11 @@ const defaultStyles = {
157
157
  rankheading: "Rank",
158
158
  anonymousUser: "Anonymous User",
159
159
  };
160
+ const link = h("a", null, "Support");
161
+ const tag = "Contact" + link + "about upgrading your plan";
160
162
  const defaultElements = {
161
163
  empty: (h("sqm-empty", { "empty-state-image": "https://res.cloudinary.com/saasquatch/image/upload/v1644360953/squatch-assets/empty_leaderboard2.png", "empty-state-header": "View your rank in the leaderboard", "empty-state-text": "Be the first to refer a friend and reach the top of the leaderboard" })),
164
+ essentials: (h("sqm-empty", { "empty-state-image": "https://res.cloudinary.com/saasquatch/image/upload/v1715360191/squatch-assets/Leaderboard_Not_Available.svg", "empty-state-header": "Leaderboards aren\u2019t available on your plan", "empty-state-text": "Contact {supportText} to upgrade your plan and start leveraging gamification in your program.", "support-text": "Support" })),
162
165
  loadingstate: (h("slot", { name: "loading" },
163
166
  h("table", null, [...Array(10)].map(() => {
164
167
  return (h("tr", null,
@@ -193,6 +196,34 @@ export const Empty = () => {
193
196
  };
194
197
  return h(LeaderboardView, Object.assign({}, props));
195
198
  };
199
+ export const Essentials = () => {
200
+ const props = {
201
+ states: {
202
+ loading: false,
203
+ isEssentials: true,
204
+ hasLeaders: false,
205
+ styles: {
206
+ ...defaultStyles,
207
+ },
208
+ },
209
+ data: {
210
+ rankType: "rowNumber",
211
+ leaderboard: [],
212
+ rowNumber: 10,
213
+ viewerRank: {
214
+ firstName: "Kutay",
215
+ lastInitial: "C",
216
+ textValue: "8",
217
+ rowNumber: 11,
218
+ rank: 23,
219
+ },
220
+ },
221
+ elements: {
222
+ ...defaultElements,
223
+ },
224
+ };
225
+ return h(LeaderboardView, Object.assign({}, props));
226
+ };
196
227
  export const Loading = () => {
197
228
  const props = {
198
229
  states: {
@@ -44,9 +44,9 @@ const style = {
44
44
  const sheet = createStyleSheet(style);
45
45
  const styleString = sheet.toString();
46
46
  const vanillaStyle = `
47
- :host{
48
- display: block;
49
- }
47
+ :host{
48
+ display: block;
49
+ }
50
50
  `;
51
51
  export function LeaderboardView(props) {
52
52
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
@@ -58,6 +58,8 @@ export function LeaderboardView(props) {
58
58
  styleString,
59
59
  vanillaStyle),
60
60
  elements.loadingstate));
61
+ if (states.isEssentials)
62
+ return elements.essentials;
61
63
  if (!states.hasLeaders)
62
64
  return elements.empty;
63
65
  let userSeenFlag = false;
@@ -65,6 +67,7 @@ export function LeaderboardView(props) {
65
67
  h("style", { type: "text/css" },
66
68
  styleString,
67
69
  vanillaStyle),
70
+ h("div", null, "Leaderboards"),
68
71
  h("table", { part: "sqm-table" },
69
72
  h("tr", null,
70
73
  styles.showRank && h("th", { class: "Rank" }, styles.rankheading),
@@ -8,6 +8,12 @@ import { useLeaderboard } from "./useLeaderboard";
8
8
  /**
9
9
  * @uiName Leaderboard
10
10
  * @slots [{"name":"empty", "title":"Empty State"}]
11
+ * @requiredFeatures ["LEADERBOARDS"]
12
+ * @exampleGroup Leaderboard
13
+ * @example Referral Started Leaderboard - <sqm-leaderboard usersheading="Referrer" statsheading="Referrals" rank-type="rank" leaderboard-type="topStartedReferrers" rankheading="Rank" show-rank="true"><sqm-empty empty-state-image="https://res.cloudinary.com/saasquatch/image/upload/v1644360953/squatch-assets/empty_leaderboard2.png" empty-state-header="View your rank in the leaderboard" empty-state-text="Be the first to refer a friend and reach the top of the leaderboard" ></sqm-empty></sqm-leaderboard>
14
+ * @example Referral Converted Leaderboard - <sqm-leaderboard usersheading="Referrer" statsheading="Referrals" rank-type="rank" leaderboard-type="topConvertedReferrers" rankheading="Rank" show-rank="true"><sqm-empty empty-state-image="https://res.cloudinary.com/saasquatch/image/upload/v1644360953/squatch-assets/empty_leaderboard2.png" empty-state-header="View your rank in the leaderboard" empty-state-text="Be the first to refer a friend and reach the top of the leaderboard" ></sqm-empty></sqm-leaderboard>
15
+ * @example Points Earned Leaderboard - <sqm-leaderboard usersheading="Name" statsheading="Points" rank-type="rank" leaderboard-type="topPointEarners" rankheading="Rank" show-rank="true"><sqm-empty empty-state-image="https://res.cloudinary.com/saasquatch/image/upload/v1644360953/squatch-assets/empty_leaderboard2.png" empty-state-header="View your rank in the leaderboard" empty-state-text="Be the first to refer a friend and reach the top of the leaderboard" ></sqm-empty></sqm-leaderboard>
16
+ * @featureTooltip <div>Motivate your participants by gamifying your program. Contact <a href="mailto:saasquatch-support%40impact.com?subject=Next steps for Leaderboards feature&body=Hi Support Team, %0D%0A%0D%0A I am interested in learning more about how Leaderboards can support the growth of our referral program. Please connect me with a program strategy manager to discuss this feature further, and determine the next steps.%0D%0A%0D%0A%0D%0AThank you,%0D%0A[Add your name here]">Support</a> to upgrade your plan and add a leaderboard.</div>
11
17
  */
12
18
  export class Leaderboard {
13
19
  constructor() {
@@ -18,6 +24,13 @@ export class Leaderboard {
18
24
  * @default
19
25
  */
20
26
  this.hideViewer = false;
27
+ /**
28
+ * Hides the leaderboard if user is on Essentials plan
29
+ *
30
+ * @uiName Hide viewing user
31
+ * @default
32
+ */
33
+ this.isEssentials = false;
21
34
  /**
22
35
  * Title displayed for users without names
23
36
  * @uiName Unknown user text
@@ -37,6 +50,7 @@ export class Leaderboard {
37
50
  render() {
38
51
  const props = {
39
52
  empty: h(EmptySlot, null),
53
+ essentials: h(EssentialsSlot, null),
40
54
  loadingstate: h(LoadingSlot, null),
41
55
  usersheading: this.usersheading,
42
56
  statsheading: this.statsheading,
@@ -49,6 +63,7 @@ export class Leaderboard {
49
63
  interval: this.interval,
50
64
  hideViewer: this.hideViewer,
51
65
  showRank: this.showRank,
66
+ isEssentials: this.isEssentials,
52
67
  };
53
68
  const demoProps = { ...props, demoData: this.demoData };
54
69
  const viewprops = isDemo()
@@ -186,6 +201,30 @@ export class Leaderboard {
186
201
  "reflect": false,
187
202
  "defaultValue": "false"
188
203
  },
204
+ "isEssentials": {
205
+ "type": "boolean",
206
+ "mutable": false,
207
+ "complexType": {
208
+ "original": "boolean",
209
+ "resolved": "boolean",
210
+ "references": {}
211
+ },
212
+ "required": false,
213
+ "optional": true,
214
+ "docs": {
215
+ "tags": [{
216
+ "text": "Hide viewing user",
217
+ "name": "uiName"
218
+ }, {
219
+ "text": undefined,
220
+ "name": "default"
221
+ }],
222
+ "text": "Hides the leaderboard if user is on Essentials plan"
223
+ },
224
+ "attribute": "is-essentials",
225
+ "reflect": false,
226
+ "defaultValue": "false"
227
+ },
189
228
  "rankType": {
190
229
  "type": "string",
191
230
  "mutable": false,
@@ -320,7 +359,7 @@ export class Leaderboard {
320
359
  "mutable": false,
321
360
  "complexType": {
322
361
  "original": "DemoData<LeaderboardViewProps>",
323
- "resolved": "{ states?: { loading: boolean; hasLeaders: boolean; styles: { usersheading: string; statsheading: string; rankheading?: string; showRank?: boolean; hideViewer?: boolean; anonymousUser?: string; }; }; data?: { rankType: string; leaderboard: { textValue: string; rank: number; firstName: string; lastInitial: string; rowNumber: number; }[]; viewerRank?: { textValue: string; rank: number; firstName: string; lastInitial: string; rowNumber: number; }; }; elements?: { empty: VNode; loadingstate: VNode; }; }",
362
+ "resolved": "{ states?: { loading: boolean; hasLeaders: boolean; isEssentials?: boolean; styles: { usersheading: string; statsheading: string; rankheading?: string; showRank?: boolean; hideViewer?: boolean; anonymousUser?: string; }; }; data?: { rankType: string; leaderboard: { textValue: string; rank: number; firstName: string; lastInitial: string; rowNumber: number; }[]; viewerRank?: { textValue: string; rank: number; firstName: string; lastInitial: string; rowNumber: number; }; }; elements?: { empty: VNode; essentials: VNode; loadingstate: VNode; }; }",
324
363
  "references": {
325
364
  "DemoData": {
326
365
  "location": "import",
@@ -354,6 +393,10 @@ function EmptySlot() {
354
393
  return (h("slot", { name: "empty" },
355
394
  h("sqm-empty", { "empty-state-image": "https://res.cloudinary.com/saasquatch/image/upload/v1644360953/squatch-assets/empty_leaderboard2.png", "empty-state-header": "View your rank in the leaderboard", "empty-state-text": "Be the first to refer a friend and reach the top of the leaderboard" })));
356
395
  }
396
+ function EssentialsSlot() {
397
+ return (h("slot", { name: "essentials" },
398
+ h("sqm-empty", { "empty-state-image": "https://res.cloudinary.com/saasquatch/image/upload/v1715360191/squatch-assets/Leaderboard_Not_Available.svg", "empty-state-header": "Leaderboards aren\u2019t available on your plan", "empty-state-text": "Contact {supportText} to upgrade your plan and start leveraging gamification in your program.", "support-text": "Support", "missing-feature": "Leaderboards" })));
399
+ }
357
400
  function LoadingSlot() {
358
401
  return (h("slot", { name: "loading" },
359
402
  h("table", null, [...Array(10)].map(() => {
@@ -403,6 +446,7 @@ function useLeaderboardDemo(props) {
403
446
  states: {
404
447
  loading: false,
405
448
  hasLeaders: true,
449
+ isEssentials: false,
406
450
  styles: {
407
451
  usersheading: props.usersheading
408
452
  ? props.usersheading
@@ -424,6 +468,7 @@ function useLeaderboardDemo(props) {
424
468
  },
425
469
  elements: {
426
470
  empty: h(EmptySlot, null),
471
+ essentials: h(EssentialsSlot, null),
427
472
  loadingstate: h(LoadingSlot, null),
428
473
  },
429
474
  }, props.demoData || {}, { arrayMerge: (_, a) => a });
@@ -43,7 +43,7 @@ const GET_RANK = gql `
43
43
  }
44
44
  `;
45
45
  export function useLeaderboard(props) {
46
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
46
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
47
47
  const programIdContext = useProgramId();
48
48
  // Default to context, overriden by props
49
49
  const programId = (_a = props.programId) !== null && _a !== void 0 ? _a : programIdContext;
@@ -67,7 +67,7 @@ export function useLeaderboard(props) {
67
67
  if (props.maxRows > 0) {
68
68
  variables["limit"] = props.maxRows;
69
69
  }
70
- const { data: leaderboardData, loading: loadingLeaderboard } = useQuery(GET_LEADERBOARD, variables, !(user === null || user === void 0 ? void 0 : user.jwt));
70
+ const { data: leaderboardData, loading: loadingLeaderboard, errors: leaderboardErrors, } = useQuery(GET_LEADERBOARD, variables, !(user === null || user === void 0 ? void 0 : user.jwt));
71
71
  const { data: rankData } = useQuery(GET_RANK, variables, !(user === null || user === void 0 ? void 0 : user.jwt));
72
72
  const leaderboardRows = (_b = leaderboardData === null || leaderboardData === void 0 ? void 0 : leaderboardData.userLeaderboard) === null || _b === void 0 ? void 0 : _b.rows;
73
73
  const flattenedLeaderboard = getFlattenedLeaderboard(leaderboardRows);
@@ -96,6 +96,8 @@ export function useLeaderboard(props) {
96
96
  return {
97
97
  states: {
98
98
  loading: loadingLeaderboard,
99
+ // Show feature enforcement if request was forbidden
100
+ isEssentials: ((_l = leaderboardErrors === null || leaderboardErrors === void 0 ? void 0 : leaderboardErrors.response) === null || _l === void 0 ? void 0 : _l.status) === 403,
99
101
  hasLeaders: (sortedLeaderboard === null || sortedLeaderboard === void 0 ? void 0 : sortedLeaderboard.length) > 0,
100
102
  styles: props,
101
103
  },
@@ -106,6 +108,7 @@ export function useLeaderboard(props) {
106
108
  },
107
109
  elements: {
108
110
  empty: props.empty,
111
+ essentials: props.essentials,
109
112
  loadingstate: props.loadingstate,
110
113
  },
111
114
  };
@@ -45,6 +45,12 @@ export class PopupContainer {
45
45
  "tags": [{
46
46
  "text": "Show powered by",
47
47
  "name": "uiName"
48
+ }, {
49
+ "text": "[\"CUSTOM_BRANDING\"]",
50
+ "name": "requiredFeatures"
51
+ }, {
52
+ "text": "<div>Integrate your brand identity further by removing impact.com\u2019s branding from your widget. Contact <a href=\"mailto:saasquatch-support%40impact.com?subject=Next steps for Custom Branding feature&body=Hi Support Team, %0D%0A%0D%0A I am interested in learning more about how Custom Branding can support the growth of our referral program. Please connect me with a program strategy manager to discuss this feature further, and determine the next steps.%0D%0A%0D%0A%0D%0AThank you,%0D%0A[Add your name here]\">Support</a> to upgrade your plan</div>",
53
+ "name": "featureTooltip"
48
54
  }],
49
55
  "text": "Show Powered by Impact.com link"
50
56
  },
@@ -23,6 +23,8 @@ export class PortalFooter {
23
23
  this.supportText = "For program support, contact {email}";
24
24
  /**
25
25
  * @uiName Hide powered by Impact.com
26
+ * @requiredFeatures ["CUSTOM_BRANDING"]
27
+ * @featureTooltip <div>Integrate your brand identity further by removing impact.com’s branding from your widget. Contact <a href="mailto:saasquatch-support%40impact.com?subject=Next steps for Custom Branding feature&body=Hi Support Team, %0D%0A%0D%0A I am interested in learning more about how Custom Branding can support the growth of our referral program. Please connect me with a program strategy manager to discuss this feature further, and determine the next steps.%0D%0A%0D%0A%0D%0AThank you,%0D%0A[Add your name here]">Support</a> to upgrade your plan</div>
26
28
  */
27
29
  this.hidePoweredBy = false;
28
30
  /**
@@ -227,6 +229,12 @@ export class PortalFooter {
227
229
  "tags": [{
228
230
  "text": "Hide powered by Impact.com",
229
231
  "name": "uiName"
232
+ }, {
233
+ "text": "[\"CUSTOM_BRANDING\"]",
234
+ "name": "requiredFeatures"
235
+ }, {
236
+ "text": "<div>Integrate your brand identity further by removing impact.com\u2019s branding from your widget. Contact <a href=\"mailto:saasquatch-support%40impact.com?subject=Next steps for Custom Branding feature&body=Hi Support Team, %0D%0A%0D%0A I am interested in learning more about how Custom Branding can support the growth of our referral program. Please connect me with a program strategy manager to discuss this feature further, and determine the next steps.%0D%0A%0D%0A%0D%0AThank you,%0D%0A[Add your name here]\">Support</a> to upgrade your plan</div>",
237
+ "name": "featureTooltip"
230
238
  }],
231
239
  "text": ""
232
240
  },
@@ -1,6 +1,6 @@
1
1
  import { h } from "@stencil/core";
2
2
  import { GenericTableView } from "../../tables/GenericTableView";
3
- import { DateCell, RewardsCellCreditCancelled, RewardsCellCreditFull, RewardsCellCreditLong, RewardsCellCreditPartial, RewardsCellCreditRedeemed, RewardsCellFueltank, RewardsCellFueltankLong, SourceCellDeletedUser, SourceCellManual, SourceCellReferral, SourceCellReferred, StatusCellAvailable, StatusCellAvailableExpiry, StatusCellCancelled, StatusCellPending, StatusCellPendingUnhandled, StatusCellRedeemed, StatusCellDenied, StatusCellPendingReview, StatusCellPayoutSent, StatusCellPayoutFailed, StatusCellPendingNewTaxForm, StatusCellPendingPartnerCreation, StatusCellPendingTaxReview, StatusCellPendingTaxSubmission, } from "./RewardsTableCell.stories";
3
+ import { DateCell, RewardsCellCreditCancelled, RewardsCellCreditFull, RewardsCellCreditLong, RewardsCellCreditPartial, RewardsCellCreditRedeemed, RewardsCellFueltank, RewardsCellFueltankLong, SourceCellDeletedUser, SourceCellDeletedReferral, SourceCellManual, SourceCellReferral, SourceCellReferred, StatusCellAvailable, StatusCellAvailableExpiry, StatusCellCancelled, StatusCellPending, StatusCellPendingUnhandled, StatusCellRedeemed, StatusCellDenied, StatusCellPendingReview, StatusCellPayoutSent, StatusCellPayoutFailed, StatusCellPendingNewTaxForm, StatusCellPendingPartnerCreation, StatusCellPendingTaxReview, StatusCellPendingTaxSubmission, } from "./RewardsTableCell.stories";
4
4
  import scenario from "./rewards-table.feature";
5
5
  export default {
6
6
  title: "Components/Rewards Table",
@@ -69,6 +69,12 @@ const r_expired = [
69
69
  h(SourceCellReferred, null),
70
70
  h(DateCell, null),
71
71
  ];
72
+ const r_deleted = [
73
+ h(RewardsCellCreditCancelled, null),
74
+ h(StatusCellCancelled, null),
75
+ h(SourceCellDeletedReferral, null),
76
+ h(DateCell, null),
77
+ ];
72
78
  const r_cancelled = [
73
79
  h(RewardsCellCreditCancelled, null),
74
80
  h(StatusCellCancelled, null),
@@ -152,6 +158,7 @@ export const RewardsTable = () => {
152
158
  r_available,
153
159
  r_redeemed,
154
160
  r_cancelled,
161
+ r_deleted,
155
162
  r_expired,
156
163
  r_denied,
157
164
  r_pending_review,