@cratis/showrunner.boxoffice.react 0.0.0-stage → 1.11.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.
- package/Banners/NoLicense.tsx +36 -0
- package/Banners/SuspensionBanner.tsx +54 -0
- package/Banners/TrialBanner.tsx +30 -0
- package/Banners/bannerModels.ts +117 -0
- package/Banners/index.ts +7 -0
- package/Entitlements/EntitlementsContext.ts +17 -0
- package/Entitlements/RequiresModule.tsx +68 -0
- package/Entitlements/entitlementModel.ts +175 -0
- package/Entitlements/index.ts +9 -0
- package/Entitlements/moduleFilter.ts +23 -0
- package/Entitlements/requiresModuleModel.ts +44 -0
- package/Entitlements/useEntitlements.ts +25 -0
- package/Labels/BoxOfficeLabels.ts +239 -0
- package/Labels/defaultBoxOfficeLabels.ts +119 -0
- package/Labels/format.ts +13 -0
- package/Labels/index.ts +7 -0
- package/Labels/resolveLabels.ts +36 -0
- package/Plan/PlanPage.tsx +24 -0
- package/Plan/PlanView.tsx +80 -0
- package/Plan/index.ts +6 -0
- package/Plan/planModels.ts +127 -0
- package/Portal/PortalButton.tsx +48 -0
- package/Portal/index.ts +5 -0
- package/Portal/portalLinks.ts +32 -0
- package/Provider/BoxOfficeContext.ts +67 -0
- package/Provider/BoxOfficeProvider.tsx +96 -0
- package/Provider/index.ts +5 -0
- package/README.md +78 -2
- package/Seats/AssignSeatDialog.tsx +73 -0
- package/Seats/SeatsPage.tsx +85 -0
- package/Seats/SeatsView.tsx +108 -0
- package/Seats/index.ts +7 -0
- package/Seats/seatModels.ts +97 -0
- package/Usage/UsagePage.tsx +26 -0
- package/Usage/UsageView.tsx +94 -0
- package/Usage/index.ts +6 -0
- package/Usage/usageModels.ts +92 -0
- package/dist/cjs/Banners/NoLicense.d.ts +2 -0
- package/dist/cjs/Banners/NoLicense.d.ts.map +1 -0
- package/dist/cjs/Banners/NoLicense.js +50 -0
- package/dist/cjs/Banners/NoLicense.js.map +1 -0
- package/dist/cjs/Banners/SuspensionBanner.d.ts +7 -0
- package/dist/cjs/Banners/SuspensionBanner.d.ts.map +1 -0
- package/dist/cjs/Banners/SuspensionBanner.js +62 -0
- package/dist/cjs/Banners/SuspensionBanner.js.map +1 -0
- package/dist/cjs/Banners/TrialBanner.d.ts +2 -0
- package/dist/cjs/Banners/TrialBanner.d.ts.map +1 -0
- package/dist/cjs/Banners/TrialBanner.js +38 -0
- package/dist/cjs/Banners/TrialBanner.js.map +1 -0
- package/dist/cjs/Banners/bannerModels.d.ts +19 -0
- package/dist/cjs/Banners/bannerModels.d.ts.map +1 -0
- package/dist/cjs/Banners/bannerModels.js +101 -0
- package/dist/cjs/Banners/bannerModels.js.map +1 -0
- package/dist/cjs/Banners/index.d.ts +5 -0
- package/dist/cjs/Banners/index.d.ts.map +1 -0
- package/dist/cjs/Entitlements/EntitlementsContext.d.ts +4 -0
- package/dist/cjs/Entitlements/EntitlementsContext.d.ts.map +1 -0
- package/dist/cjs/Entitlements/EntitlementsContext.js +19 -0
- package/dist/cjs/Entitlements/EntitlementsContext.js.map +1 -0
- package/dist/cjs/Entitlements/RequiresModule.d.ts +9 -0
- package/dist/cjs/Entitlements/RequiresModule.d.ts.map +1 -0
- package/dist/cjs/Entitlements/RequiresModule.js +68 -0
- package/dist/cjs/Entitlements/RequiresModule.js.map +1 -0
- package/dist/cjs/Entitlements/entitlementModel.d.ts +25 -0
- package/dist/cjs/Entitlements/entitlementModel.d.ts.map +1 -0
- package/dist/cjs/Entitlements/entitlementModel.js +93 -0
- package/dist/cjs/Entitlements/entitlementModel.js.map +1 -0
- package/dist/cjs/Entitlements/index.d.ts +7 -0
- package/dist/cjs/Entitlements/index.d.ts.map +1 -0
- package/dist/cjs/Entitlements/moduleFilter.d.ts +6 -0
- package/dist/cjs/Entitlements/moduleFilter.d.ts.map +1 -0
- package/dist/cjs/Entitlements/moduleFilter.js +16 -0
- package/dist/cjs/Entitlements/moduleFilter.js.map +1 -0
- package/dist/cjs/Entitlements/requiresModuleModel.d.ts +10 -0
- package/dist/cjs/Entitlements/requiresModuleModel.d.ts.map +1 -0
- package/dist/cjs/Entitlements/requiresModuleModel.js +32 -0
- package/dist/cjs/Entitlements/requiresModuleModel.js.map +1 -0
- package/dist/cjs/Entitlements/useEntitlements.d.ts +5 -0
- package/dist/cjs/Entitlements/useEntitlements.d.ts.map +1 -0
- package/dist/cjs/Entitlements/useEntitlements.js +26 -0
- package/dist/cjs/Entitlements/useEntitlements.js.map +1 -0
- package/dist/cjs/Labels/BoxOfficeLabels.d.ts +116 -0
- package/dist/cjs/Labels/BoxOfficeLabels.d.ts.map +1 -0
- package/dist/cjs/Labels/defaultBoxOfficeLabels.d.ts +3 -0
- package/dist/cjs/Labels/defaultBoxOfficeLabels.d.ts.map +1 -0
- package/dist/cjs/Labels/defaultBoxOfficeLabels.js +120 -0
- package/dist/cjs/Labels/defaultBoxOfficeLabels.js.map +1 -0
- package/dist/cjs/Labels/format.d.ts +2 -0
- package/dist/cjs/Labels/format.d.ts.map +1 -0
- package/dist/cjs/Labels/format.js +15 -0
- package/dist/cjs/Labels/format.js.map +1 -0
- package/dist/cjs/Labels/index.d.ts +5 -0
- package/dist/cjs/Labels/index.d.ts.map +1 -0
- package/dist/cjs/Labels/resolveLabels.d.ts +3 -0
- package/dist/cjs/Labels/resolveLabels.d.ts.map +1 -0
- package/dist/cjs/Labels/resolveLabels.js +35 -0
- package/dist/cjs/Labels/resolveLabels.js.map +1 -0
- package/dist/cjs/Plan/PlanPage.d.ts +2 -0
- package/dist/cjs/Plan/PlanPage.d.ts.map +1 -0
- package/dist/cjs/Plan/PlanPage.js +24 -0
- package/dist/cjs/Plan/PlanPage.js.map +1 -0
- package/dist/cjs/Plan/PlanView.d.ts +10 -0
- package/dist/cjs/Plan/PlanView.d.ts.map +1 -0
- package/dist/cjs/Plan/PlanView.js +123 -0
- package/dist/cjs/Plan/PlanView.js.map +1 -0
- package/dist/cjs/Plan/index.d.ts +4 -0
- package/dist/cjs/Plan/index.d.ts.map +1 -0
- package/dist/cjs/Plan/planModels.d.ts +24 -0
- package/dist/cjs/Plan/planModels.d.ts.map +1 -0
- package/dist/cjs/Plan/planModels.js +83 -0
- package/dist/cjs/Plan/planModels.js.map +1 -0
- package/dist/cjs/Portal/PortalButton.d.ts +10 -0
- package/dist/cjs/Portal/PortalButton.d.ts.map +1 -0
- package/dist/cjs/Portal/PortalButton.js +37 -0
- package/dist/cjs/Portal/PortalButton.js.map +1 -0
- package/dist/cjs/Portal/index.d.ts +3 -0
- package/dist/cjs/Portal/index.d.ts.map +1 -0
- package/dist/cjs/Portal/portalLinks.d.ts +6 -0
- package/dist/cjs/Portal/portalLinks.d.ts.map +1 -0
- package/dist/cjs/Portal/portalLinks.js +34 -0
- package/dist/cjs/Portal/portalLinks.js.map +1 -0
- package/dist/cjs/Provider/BoxOfficeContext.d.ts +16 -0
- package/dist/cjs/Provider/BoxOfficeContext.d.ts.map +1 -0
- package/dist/cjs/Provider/BoxOfficeContext.js +34 -0
- package/dist/cjs/Provider/BoxOfficeContext.js.map +1 -0
- package/dist/cjs/Provider/BoxOfficeProvider.d.ts +15 -0
- package/dist/cjs/Provider/BoxOfficeProvider.d.ts.map +1 -0
- package/dist/cjs/Provider/BoxOfficeProvider.js +72 -0
- package/dist/cjs/Provider/BoxOfficeProvider.js.map +1 -0
- package/dist/cjs/Provider/index.d.ts +3 -0
- package/dist/cjs/Provider/index.d.ts.map +1 -0
- package/dist/cjs/Seats/AssignSeatDialog.d.ts +9 -0
- package/dist/cjs/Seats/AssignSeatDialog.d.ts.map +1 -0
- package/dist/cjs/Seats/AssignSeatDialog.js +99 -0
- package/dist/cjs/Seats/AssignSeatDialog.js.map +1 -0
- package/dist/cjs/Seats/SeatsPage.d.ts +2 -0
- package/dist/cjs/Seats/SeatsPage.d.ts.map +1 -0
- package/dist/cjs/Seats/SeatsPage.js +87 -0
- package/dist/cjs/Seats/SeatsPage.js.map +1 -0
- package/dist/cjs/Seats/SeatsView.d.ts +14 -0
- package/dist/cjs/Seats/SeatsView.d.ts.map +1 -0
- package/dist/cjs/Seats/SeatsView.js +111 -0
- package/dist/cjs/Seats/SeatsView.js.map +1 -0
- package/dist/cjs/Seats/index.d.ts +5 -0
- package/dist/cjs/Seats/index.d.ts.map +1 -0
- package/dist/cjs/Seats/seatModels.d.ts +23 -0
- package/dist/cjs/Seats/seatModels.d.ts.map +1 -0
- package/dist/cjs/Seats/seatModels.js +65 -0
- package/dist/cjs/Seats/seatModels.js.map +1 -0
- package/dist/cjs/Usage/UsagePage.d.ts +2 -0
- package/dist/cjs/Usage/UsagePage.d.ts.map +1 -0
- package/dist/cjs/Usage/UsagePage.js +26 -0
- package/dist/cjs/Usage/UsagePage.js.map +1 -0
- package/dist/cjs/Usage/UsageView.d.ts +9 -0
- package/dist/cjs/Usage/UsageView.d.ts.map +1 -0
- package/dist/cjs/Usage/UsageView.js +108 -0
- package/dist/cjs/Usage/UsageView.js.map +1 -0
- package/dist/cjs/Usage/index.d.ts +4 -0
- package/dist/cjs/Usage/index.d.ts.map +1 -0
- package/dist/cjs/Usage/usageModels.d.ts +17 -0
- package/dist/cjs/Usage/usageModels.d.ts.map +1 -0
- package/dist/cjs/Usage/usageModels.js +57 -0
- package/dist/cjs/Usage/usageModels.js.map +1 -0
- package/dist/cjs/formatting.d.ts +5 -0
- package/dist/cjs/formatting.d.ts.map +1 -0
- package/dist/cjs/formatting.js +46 -0
- package/dist/cjs/formatting.js.map +1 -0
- package/dist/cjs/index.d.ts +10 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +85 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/esm/Banners/NoLicense.d.ts +2 -0
- package/dist/esm/Banners/NoLicense.d.ts.map +1 -0
- package/dist/esm/Banners/NoLicense.js +48 -0
- package/dist/esm/Banners/NoLicense.js.map +1 -0
- package/dist/esm/Banners/SuspensionBanner.d.ts +7 -0
- package/dist/esm/Banners/SuspensionBanner.d.ts.map +1 -0
- package/dist/esm/Banners/SuspensionBanner.js +59 -0
- package/dist/esm/Banners/SuspensionBanner.js.map +1 -0
- package/dist/esm/Banners/TrialBanner.d.ts +2 -0
- package/dist/esm/Banners/TrialBanner.d.ts.map +1 -0
- package/dist/esm/Banners/TrialBanner.js +36 -0
- package/dist/esm/Banners/TrialBanner.js.map +1 -0
- package/dist/esm/Banners/bannerModels.d.ts +19 -0
- package/dist/esm/Banners/bannerModels.d.ts.map +1 -0
- package/dist/esm/Banners/bannerModels.js +96 -0
- package/dist/esm/Banners/bannerModels.js.map +1 -0
- package/dist/esm/Banners/index.d.ts +5 -0
- package/dist/esm/Banners/index.d.ts.map +1 -0
- package/dist/esm/Banners/index.js +5 -0
- package/dist/esm/Banners/index.js.map +1 -0
- package/dist/esm/Entitlements/EntitlementsContext.d.ts +4 -0
- package/dist/esm/Entitlements/EntitlementsContext.d.ts.map +1 -0
- package/dist/esm/Entitlements/EntitlementsContext.js +16 -0
- package/dist/esm/Entitlements/EntitlementsContext.js.map +1 -0
- package/dist/esm/Entitlements/RequiresModule.d.ts +9 -0
- package/dist/esm/Entitlements/RequiresModule.d.ts.map +1 -0
- package/dist/esm/Entitlements/RequiresModule.js +66 -0
- package/dist/esm/Entitlements/RequiresModule.js.map +1 -0
- package/dist/esm/Entitlements/entitlementModel.d.ts +25 -0
- package/dist/esm/Entitlements/entitlementModel.d.ts.map +1 -0
- package/dist/esm/Entitlements/entitlementModel.js +89 -0
- package/dist/esm/Entitlements/entitlementModel.js.map +1 -0
- package/dist/esm/Entitlements/index.d.ts +7 -0
- package/dist/esm/Entitlements/index.d.ts.map +1 -0
- package/dist/esm/Entitlements/index.js +7 -0
- package/dist/esm/Entitlements/index.js.map +1 -0
- package/dist/esm/Entitlements/moduleFilter.d.ts +6 -0
- package/dist/esm/Entitlements/moduleFilter.d.ts.map +1 -0
- package/dist/esm/Entitlements/moduleFilter.js +14 -0
- package/dist/esm/Entitlements/moduleFilter.js.map +1 -0
- package/dist/esm/Entitlements/requiresModuleModel.d.ts +10 -0
- package/dist/esm/Entitlements/requiresModuleModel.d.ts.map +1 -0
- package/dist/esm/Entitlements/requiresModuleModel.js +30 -0
- package/dist/esm/Entitlements/requiresModuleModel.js.map +1 -0
- package/dist/esm/Entitlements/useEntitlements.d.ts +5 -0
- package/dist/esm/Entitlements/useEntitlements.d.ts.map +1 -0
- package/dist/esm/Entitlements/useEntitlements.js +23 -0
- package/dist/esm/Entitlements/useEntitlements.js.map +1 -0
- package/dist/esm/Labels/BoxOfficeLabels.d.ts +116 -0
- package/dist/esm/Labels/BoxOfficeLabels.d.ts.map +1 -0
- package/dist/esm/Labels/BoxOfficeLabels.js +2 -0
- package/dist/esm/Labels/BoxOfficeLabels.js.map +1 -0
- package/dist/esm/Labels/defaultBoxOfficeLabels.d.ts +3 -0
- package/dist/esm/Labels/defaultBoxOfficeLabels.d.ts.map +1 -0
- package/dist/esm/Labels/defaultBoxOfficeLabels.js +118 -0
- package/dist/esm/Labels/defaultBoxOfficeLabels.js.map +1 -0
- package/dist/esm/Labels/format.d.ts +2 -0
- package/dist/esm/Labels/format.d.ts.map +1 -0
- package/dist/esm/Labels/format.js +13 -0
- package/dist/esm/Labels/format.js.map +1 -0
- package/dist/esm/Labels/index.d.ts +5 -0
- package/dist/esm/Labels/index.d.ts.map +1 -0
- package/dist/esm/Labels/index.js +5 -0
- package/dist/esm/Labels/index.js.map +1 -0
- package/dist/esm/Labels/resolveLabels.d.ts +3 -0
- package/dist/esm/Labels/resolveLabels.d.ts.map +1 -0
- package/dist/esm/Labels/resolveLabels.js +33 -0
- package/dist/esm/Labels/resolveLabels.js.map +1 -0
- package/dist/esm/Plan/PlanPage.d.ts +2 -0
- package/dist/esm/Plan/PlanPage.d.ts.map +1 -0
- package/dist/esm/Plan/PlanPage.js +22 -0
- package/dist/esm/Plan/PlanPage.js.map +1 -0
- package/dist/esm/Plan/PlanView.d.ts +10 -0
- package/dist/esm/Plan/PlanView.d.ts.map +1 -0
- package/dist/esm/Plan/PlanView.js +121 -0
- package/dist/esm/Plan/PlanView.js.map +1 -0
- package/dist/esm/Plan/index.d.ts +4 -0
- package/dist/esm/Plan/index.d.ts.map +1 -0
- package/dist/esm/Plan/index.js +4 -0
- package/dist/esm/Plan/index.js.map +1 -0
- package/dist/esm/Plan/planModels.d.ts +24 -0
- package/dist/esm/Plan/planModels.d.ts.map +1 -0
- package/dist/esm/Plan/planModels.js +78 -0
- package/dist/esm/Plan/planModels.js.map +1 -0
- package/dist/esm/Portal/PortalButton.d.ts +10 -0
- package/dist/esm/Portal/PortalButton.d.ts.map +1 -0
- package/dist/esm/Portal/PortalButton.js +35 -0
- package/dist/esm/Portal/PortalButton.js.map +1 -0
- package/dist/esm/Portal/index.d.ts +3 -0
- package/dist/esm/Portal/index.d.ts.map +1 -0
- package/dist/esm/Portal/index.js +3 -0
- package/dist/esm/Portal/index.js.map +1 -0
- package/dist/esm/Portal/portalLinks.d.ts +6 -0
- package/dist/esm/Portal/portalLinks.d.ts.map +1 -0
- package/dist/esm/Portal/portalLinks.js +31 -0
- package/dist/esm/Portal/portalLinks.js.map +1 -0
- package/dist/esm/Provider/BoxOfficeContext.d.ts +16 -0
- package/dist/esm/Provider/BoxOfficeContext.d.ts.map +1 -0
- package/dist/esm/Provider/BoxOfficeContext.js +29 -0
- package/dist/esm/Provider/BoxOfficeContext.js.map +1 -0
- package/dist/esm/Provider/BoxOfficeProvider.d.ts +15 -0
- package/dist/esm/Provider/BoxOfficeProvider.d.ts.map +1 -0
- package/dist/esm/Provider/BoxOfficeProvider.js +70 -0
- package/dist/esm/Provider/BoxOfficeProvider.js.map +1 -0
- package/dist/esm/Provider/index.d.ts +3 -0
- package/dist/esm/Provider/index.d.ts.map +1 -0
- package/dist/esm/Provider/index.js +3 -0
- package/dist/esm/Provider/index.js.map +1 -0
- package/dist/esm/Seats/AssignSeatDialog.d.ts +9 -0
- package/dist/esm/Seats/AssignSeatDialog.d.ts.map +1 -0
- package/dist/esm/Seats/AssignSeatDialog.js +97 -0
- package/dist/esm/Seats/AssignSeatDialog.js.map +1 -0
- package/dist/esm/Seats/SeatsPage.d.ts +2 -0
- package/dist/esm/Seats/SeatsPage.d.ts.map +1 -0
- package/dist/esm/Seats/SeatsPage.js +85 -0
- package/dist/esm/Seats/SeatsPage.js.map +1 -0
- package/dist/esm/Seats/SeatsView.d.ts +14 -0
- package/dist/esm/Seats/SeatsView.d.ts.map +1 -0
- package/dist/esm/Seats/SeatsView.js +109 -0
- package/dist/esm/Seats/SeatsView.js.map +1 -0
- package/dist/esm/Seats/index.d.ts +5 -0
- package/dist/esm/Seats/index.d.ts.map +1 -0
- package/dist/esm/Seats/index.js +5 -0
- package/dist/esm/Seats/index.js.map +1 -0
- package/dist/esm/Seats/seatModels.d.ts +23 -0
- package/dist/esm/Seats/seatModels.d.ts.map +1 -0
- package/dist/esm/Seats/seatModels.js +59 -0
- package/dist/esm/Seats/seatModels.js.map +1 -0
- package/dist/esm/Usage/UsagePage.d.ts +2 -0
- package/dist/esm/Usage/UsagePage.d.ts.map +1 -0
- package/dist/esm/Usage/UsagePage.js +24 -0
- package/dist/esm/Usage/UsagePage.js.map +1 -0
- package/dist/esm/Usage/UsageView.d.ts +9 -0
- package/dist/esm/Usage/UsageView.d.ts.map +1 -0
- package/dist/esm/Usage/UsageView.js +106 -0
- package/dist/esm/Usage/UsageView.js.map +1 -0
- package/dist/esm/Usage/index.d.ts +4 -0
- package/dist/esm/Usage/index.d.ts.map +1 -0
- package/dist/esm/Usage/index.js +4 -0
- package/dist/esm/Usage/index.js.map +1 -0
- package/dist/esm/Usage/usageModels.d.ts +17 -0
- package/dist/esm/Usage/usageModels.d.ts.map +1 -0
- package/dist/esm/Usage/usageModels.js +53 -0
- package/dist/esm/Usage/usageModels.js.map +1 -0
- package/dist/esm/formatting.d.ts +5 -0
- package/dist/esm/formatting.d.ts.map +1 -0
- package/dist/esm/formatting.js +42 -0
- package/dist/esm/formatting.js.map +1 -0
- package/dist/esm/index.d.ts +10 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +29 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/formatting.ts +41 -0
- package/index.ts +12 -0
- package/package.json +84 -4
- package/styles.css +166 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { Person, SeatHolding, SeatRoster } from '@cratis/showrunner.boxoffice';
|
|
5
|
+
|
|
6
|
+
/** Whether a seat is covered by what the tenant has bought. */
|
|
7
|
+
export type SeatCoverage = 'licensed' | 'overCapacity';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* One person's seat on the seats page.
|
|
11
|
+
*/
|
|
12
|
+
export interface SeatRow {
|
|
13
|
+
/** The seat. */
|
|
14
|
+
readonly holding: SeatHolding;
|
|
15
|
+
|
|
16
|
+
/** Whether the tenant's seats cover it. */
|
|
17
|
+
readonly coverage: SeatCoverage;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* What the seats page summarizes.
|
|
22
|
+
*/
|
|
23
|
+
export interface SeatSummary {
|
|
24
|
+
/** How many seats are held. */
|
|
25
|
+
readonly held: number;
|
|
26
|
+
|
|
27
|
+
/** How many seats the tenant has. */
|
|
28
|
+
readonly capacity: number;
|
|
29
|
+
|
|
30
|
+
/** How many people hold a seat the tenant has no room for. */
|
|
31
|
+
readonly over: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Lays out the seats the way the backend licenses them: the first people to be given a seat, in the order they were
|
|
36
|
+
* given them, are covered by the tenant's seats, and the rest are not.
|
|
37
|
+
* @param roster Who holds the seats.
|
|
38
|
+
* @param capacity How many seats the tenant has.
|
|
39
|
+
* @returns The seats, oldest first.
|
|
40
|
+
*/
|
|
41
|
+
export function seatRows(roster: SeatRoster | undefined, capacity: number): SeatRow[] {
|
|
42
|
+
const holdings = [...(roster?.holdings ?? [])].sort((a, b) => new Date(a.assignedAt).getTime() - new Date(b.assignedAt).getTime());
|
|
43
|
+
return holdings.map((holding, index) => ({ holding, coverage: index < Math.max(capacity, 0) ? 'licensed' : 'overCapacity' }));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Summarizes the seats.
|
|
48
|
+
* @param rows The seats from {@link seatRows}.
|
|
49
|
+
* @param capacity How many seats the tenant has.
|
|
50
|
+
* @returns The {@link SeatSummary}.
|
|
51
|
+
*/
|
|
52
|
+
export function seatSummary(rows: readonly SeatRow[], capacity: number): SeatSummary {
|
|
53
|
+
return { held: rows.length, capacity, over: rows.filter(_ => _.coverage === 'overCapacity').length };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* What the user types to assign a seat.
|
|
58
|
+
*/
|
|
59
|
+
export interface SeatPersonInput {
|
|
60
|
+
/** The identity provider that knows the person. */
|
|
61
|
+
identityProvider: string;
|
|
62
|
+
|
|
63
|
+
/** The person's subject at the identity provider. */
|
|
64
|
+
subject: string;
|
|
65
|
+
|
|
66
|
+
/** The person's name. */
|
|
67
|
+
name: string;
|
|
68
|
+
|
|
69
|
+
/** The person's email address. */
|
|
70
|
+
email: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** An empty {@link SeatPersonInput}. */
|
|
74
|
+
export const emptySeatPerson: SeatPersonInput = { identityProvider: '', subject: '', name: '', email: '' };
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Gets whether what the user typed can be assigned a seat.
|
|
78
|
+
* @param input What the user typed.
|
|
79
|
+
* @returns True when every field has something in it.
|
|
80
|
+
*/
|
|
81
|
+
export function isValidSeatPerson(input: SeatPersonInput): boolean {
|
|
82
|
+
return Object.values(input).every(value => value.trim().length > 0);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Makes the person a seat is assigned to.
|
|
87
|
+
* @param input What the user typed.
|
|
88
|
+
* @returns The {@link Person}.
|
|
89
|
+
*/
|
|
90
|
+
export function personOf(input: SeatPersonInput): Person {
|
|
91
|
+
const person = new Person();
|
|
92
|
+
person.identityProvider = input.identityProvider.trim();
|
|
93
|
+
person.identityProviderSubject = input.subject.trim();
|
|
94
|
+
person.name = input.name.trim();
|
|
95
|
+
person.email = input.email.trim();
|
|
96
|
+
return person;
|
|
97
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { CurrentUsage } from '@cratis/showrunner.boxoffice';
|
|
5
|
+
import { useBoxOfficeContext } from '../Provider/BoxOfficeContext.js';
|
|
6
|
+
import { meterUsageModel } from './usageModels.js';
|
|
7
|
+
import { UsageView } from './UsageView.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The usage page: what the tenant has used of each meter in the period it is in, against its allowance and budget. For
|
|
11
|
+
* the people who maintain the product; the backend refuses everyone else. Render it inside a
|
|
12
|
+
* {@link BoxOfficeProvider}.
|
|
13
|
+
*/
|
|
14
|
+
export const UsagePage = () => {
|
|
15
|
+
const { labels, locale } = useBoxOfficeContext();
|
|
16
|
+
const [usage] = CurrentUsage.use();
|
|
17
|
+
const meters = usage.isSuccess ? (usage.data ?? []).map(standing => meterUsageModel(standing, labels, locale)) : [];
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<UsageView
|
|
21
|
+
meters={meters}
|
|
22
|
+
isLoading={usage.isPerforming && !usage.isSuccess}
|
|
23
|
+
isUnauthorized={!usage.isAuthorized}
|
|
24
|
+
hasFailed={!usage.isPerforming && usage.isAuthorized && !usage.isSuccess} />
|
|
25
|
+
);
|
|
26
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { Column, DataTableCore, DataTableStatus } from '@cratis/components/DataTables';
|
|
5
|
+
import { ProgressBar, Tag } from '@cratis/components/Display';
|
|
6
|
+
import { format } from '../Labels/index.js';
|
|
7
|
+
import { useBoxOfficeContext } from '../Provider/BoxOfficeContext.js';
|
|
8
|
+
import { MeterUsageModel, UsageLevel } from './usageModels.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Props for {@link UsageView}.
|
|
12
|
+
*/
|
|
13
|
+
export interface UsageViewProps {
|
|
14
|
+
/** How each meter stands. */
|
|
15
|
+
meters: readonly MeterUsageModel[];
|
|
16
|
+
|
|
17
|
+
/** Whether the usage is still loading. */
|
|
18
|
+
isLoading?: boolean;
|
|
19
|
+
|
|
20
|
+
/** Whether the usage could not be loaded because the user may not see it. */
|
|
21
|
+
isUnauthorized?: boolean;
|
|
22
|
+
|
|
23
|
+
/** Whether the usage could not be loaded. */
|
|
24
|
+
hasFailed?: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const statusOf = (isLoading?: boolean, isUnauthorized?: boolean, hasFailed?: boolean) => {
|
|
28
|
+
if (isUnauthorized) {
|
|
29
|
+
return DataTableStatus.Unauthorized;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (hasFailed) {
|
|
33
|
+
return DataTableStatus.Failed;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return isLoading ? DataTableStatus.Loading : DataTableStatus.Ready;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* What a tenant has used of each meter in the period it is in, against its allowance and budget.
|
|
41
|
+
*/
|
|
42
|
+
export const UsageView = ({ meters, isLoading, isUnauthorized, hasFailed }: UsageViewProps) => {
|
|
43
|
+
const { labels } = useBoxOfficeContext();
|
|
44
|
+
const levelText: Record<UsageLevel, string | undefined> = {
|
|
45
|
+
ok: undefined,
|
|
46
|
+
warning: undefined,
|
|
47
|
+
atBudget: labels.usage.atBudget,
|
|
48
|
+
atAllowance: labels.usage.atAllowance
|
|
49
|
+
};
|
|
50
|
+
const showsConcurrency = meters.some(_ => _.standing.hasConcurrencyLimit);
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<section className='boxoffice-usage' aria-labelledby='boxoffice-usage-title'>
|
|
54
|
+
<header className='boxoffice-page__header'>
|
|
55
|
+
<h2 id='boxoffice-usage-title' className='boxoffice-page__title'>{labels.usage.title}</h2>
|
|
56
|
+
</header>
|
|
57
|
+
|
|
58
|
+
<DataTableCore<MeterUsageModel>
|
|
59
|
+
data={[...meters]}
|
|
60
|
+
dataKey='standing.meter'
|
|
61
|
+
status={statusOf(isLoading, isUnauthorized, hasFailed)}
|
|
62
|
+
emptyMessage={labels.usage.empty}
|
|
63
|
+
loadingMessage={labels.common.loading}
|
|
64
|
+
failureMessage={labels.common.failed}
|
|
65
|
+
unauthorizedMessage={labels.common.unauthorized}>
|
|
66
|
+
<Column<MeterUsageModel>
|
|
67
|
+
header={labels.usage.meterColumn}
|
|
68
|
+
body={meter => (
|
|
69
|
+
<span className='boxoffice-usage__meter'>
|
|
70
|
+
<strong>{meter.standing.name}</strong>
|
|
71
|
+
<span className='boxoffice-usage__period'>{meter.periodText}</span>
|
|
72
|
+
</span>
|
|
73
|
+
)} />
|
|
74
|
+
<Column<MeterUsageModel>
|
|
75
|
+
header={labels.usage.usedColumn}
|
|
76
|
+
body={meter => (
|
|
77
|
+
<span className={`boxoffice-usage__used boxoffice-usage__used--${meter.level}`}>
|
|
78
|
+
<span>{meter.usedText}</span>
|
|
79
|
+
{meter.standing.allowance > 0 && (
|
|
80
|
+
<ProgressBar
|
|
81
|
+
value={meter.percent}
|
|
82
|
+
showValue={false}
|
|
83
|
+
aria-label={format(labels.usage.progress, { meter: meter.standing.name })} />
|
|
84
|
+
)}
|
|
85
|
+
{levelText[meter.level] && <Tag severity={meter.level === 'atAllowance' ? 'danger' : 'warn'} value={levelText[meter.level]} />}
|
|
86
|
+
<span className='boxoffice-usage__overage'>{meter.overageText}</span>
|
|
87
|
+
</span>
|
|
88
|
+
)} />
|
|
89
|
+
<Column<MeterUsageModel> header={labels.usage.budgetColumn} body={meter => meter.budgetText} />
|
|
90
|
+
{showsConcurrency && <Column<MeterUsageModel> header={labels.usage.concurrencyColumn} body={meter => meter.concurrencyText} />}
|
|
91
|
+
</DataTableCore>
|
|
92
|
+
</section>
|
|
93
|
+
);
|
|
94
|
+
};
|
package/Usage/index.ts
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { AllowancePeriod, MeterStanding, OverageBehavior } from '@cratis/showrunner.boxoffice';
|
|
5
|
+
import { BoxOfficeLabels, format } from '../Labels/index.js';
|
|
6
|
+
import { formatDay, formatQuantity } from '../formatting.js';
|
|
7
|
+
|
|
8
|
+
/** How a meter stands against what it may use. */
|
|
9
|
+
export type UsageLevel = 'ok' | 'warning' | 'atBudget' | 'atAllowance';
|
|
10
|
+
|
|
11
|
+
/** The share of an allowance used from which a meter is shown as running out. */
|
|
12
|
+
export const usageWarningShare = 0.8;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* What the usage page shows for one meter.
|
|
16
|
+
*/
|
|
17
|
+
export interface MeterUsageModel {
|
|
18
|
+
/** The meter's standing. */
|
|
19
|
+
readonly standing: MeterStanding;
|
|
20
|
+
|
|
21
|
+
/** How much of the allowance is used, from 0 to 100; 0 when there is no allowance. */
|
|
22
|
+
readonly percent: number;
|
|
23
|
+
|
|
24
|
+
/** How the meter stands. */
|
|
25
|
+
readonly level: UsageLevel;
|
|
26
|
+
|
|
27
|
+
/** What is used against the allowance, in words. */
|
|
28
|
+
readonly usedText: string;
|
|
29
|
+
|
|
30
|
+
/** The allowance's period and when it starts over, in words. */
|
|
31
|
+
readonly periodText: string;
|
|
32
|
+
|
|
33
|
+
/** What happens beyond the allowance, in words. */
|
|
34
|
+
readonly overageText: string;
|
|
35
|
+
|
|
36
|
+
/** The budget, in words; nothing set when there is none. */
|
|
37
|
+
readonly budgetText: string;
|
|
38
|
+
|
|
39
|
+
/** The concurrency limit, in words; nothing set when there is none. */
|
|
40
|
+
readonly concurrencyText: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Works out how a meter stands.
|
|
45
|
+
* @param standing The meter's standing from the backend.
|
|
46
|
+
* @returns The {@link UsageLevel}.
|
|
47
|
+
*/
|
|
48
|
+
export function usageLevel(standing: MeterStanding): UsageLevel {
|
|
49
|
+
if (standing.allowance > 0 && standing.used >= standing.allowance) {
|
|
50
|
+
return 'atAllowance';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (standing.budget !== undefined && standing.budget !== null && standing.used >= standing.budget) {
|
|
54
|
+
return 'atBudget';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return standing.allowance > 0 && standing.used / standing.allowance >= usageWarningShare ? 'warning' : 'ok';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Lays out how a meter stands for the usage page.
|
|
62
|
+
* @param standing The meter's standing from the backend.
|
|
63
|
+
* @param labels The labels to show.
|
|
64
|
+
* @param locale The locale to format for; the browser's when not given.
|
|
65
|
+
* @returns The {@link MeterUsageModel}.
|
|
66
|
+
*/
|
|
67
|
+
export function meterUsageModel(standing: MeterStanding, labels: BoxOfficeLabels, locale?: string): MeterUsageModel {
|
|
68
|
+
const hasAllowance = standing.allowance > 0;
|
|
69
|
+
const period = standing.period === AllowancePeriod.month ? labels.usage.month : labels.usage.day;
|
|
70
|
+
const used = formatQuantity(standing.used, locale);
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
standing,
|
|
74
|
+
percent: hasAllowance ? Math.min(100, Math.round((standing.used / standing.allowance) * 100)) : 0,
|
|
75
|
+
level: usageLevel(standing),
|
|
76
|
+
usedText: hasAllowance
|
|
77
|
+
? format(labels.usage.usedOfAllowance, { used, allowance: formatQuantity(standing.allowance, locale), unit: standing.unit })
|
|
78
|
+
: format(labels.usage.noAllowance, { used, unit: standing.unit }),
|
|
79
|
+
periodText: hasAllowance
|
|
80
|
+
? `${period}, ${format(labels.usage.resets, { date: formatDay(standing.periodEnds, locale) })}`
|
|
81
|
+
: period,
|
|
82
|
+
overageText: standing.overage === OverageBehavior.park ? labels.usage.park : labels.usage.block,
|
|
83
|
+
budgetText: standing.budget !== undefined && standing.budget !== null
|
|
84
|
+
? `${formatQuantity(standing.budget, locale)} ${standing.unit}`
|
|
85
|
+
: labels.usage.notSet,
|
|
86
|
+
concurrencyText: !standing.hasConcurrencyLimit
|
|
87
|
+
? ''
|
|
88
|
+
: standing.concurrencyLimit !== undefined && standing.concurrencyLimit !== null
|
|
89
|
+
? formatQuantity(standing.concurrencyLimit, locale)
|
|
90
|
+
: labels.usage.notSet
|
|
91
|
+
};
|
|
92
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NoLicense.d.ts","sourceRoot":"","sources":["../../../Banners/NoLicense.tsx"],"names":[],"mappings":"AAeA,eAAO,MAAM,SAAS,0CAoBrB,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var Display = require('@cratis/components/Display');
|
|
5
|
+
var showrunner_boxoffice = require('@cratis/showrunner.boxoffice');
|
|
6
|
+
var EntitlementsContext = require('../Entitlements/EntitlementsContext.js');
|
|
7
|
+
var PortalButton = require('../Portal/PortalButton.js');
|
|
8
|
+
var BoxOfficeContext = require('../Provider/BoxOfficeContext.js');
|
|
9
|
+
var bannerModels = require('./bannerModels.js');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Tells a user who cannot use the product why, and what to do about it: the tenant is suspended, its trial ended, the
|
|
13
|
+
* user has no seat, or the tenant has more people with seats than it has bought. Nothing is shown to a user with a
|
|
14
|
+
* license. Render it where the application's content would be, or above it.
|
|
15
|
+
*/ const NoLicense = ()=>{
|
|
16
|
+
const entitlements = EntitlementsContext.useEntitlementsContext();
|
|
17
|
+
const { labels, seat } = BoxOfficeContext.useBoxOfficeContext();
|
|
18
|
+
const model = bannerModels.noLicenseModel(entitlements, seat, labels);
|
|
19
|
+
if (!model) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return /*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
23
|
+
className: "boxoffice-no-license",
|
|
24
|
+
"data-reason": model.reason,
|
|
25
|
+
children: [
|
|
26
|
+
/*#__PURE__*/ jsxRuntime.jsx(Display.Message, {
|
|
27
|
+
severity: model.reason === 'noSeat' || model.reason === 'overCapacity' ? 'warn' : 'error',
|
|
28
|
+
children: /*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
29
|
+
className: "boxoffice-banner__text",
|
|
30
|
+
children: [
|
|
31
|
+
/*#__PURE__*/ jsxRuntime.jsx("strong", {
|
|
32
|
+
children: model.title
|
|
33
|
+
}),
|
|
34
|
+
/*#__PURE__*/ jsxRuntime.jsx("span", {
|
|
35
|
+
children: model.text
|
|
36
|
+
})
|
|
37
|
+
]
|
|
38
|
+
})
|
|
39
|
+
}),
|
|
40
|
+
model.reason !== 'noSeat' && /*#__PURE__*/ jsxRuntime.jsx(PortalButton.PortalButton, {
|
|
41
|
+
intent: showrunner_boxoffice.PortalIntent.buy,
|
|
42
|
+
label: labels.noLicense.openPortal,
|
|
43
|
+
variant: "outline"
|
|
44
|
+
})
|
|
45
|
+
]
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
exports.NoLicense = NoLicense;
|
|
50
|
+
//# sourceMappingURL=NoLicense.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NoLicense.js","sources":["../../../Banners/NoLicense.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Message } from '@cratis/components/Display';\nimport { PortalIntent } from '@cratis/showrunner.boxoffice';\nimport { useEntitlementsContext } from '../Entitlements/EntitlementsContext.js';\nimport { PortalButton } from '../Portal/PortalButton.js';\nimport { useBoxOfficeContext } from '../Provider/BoxOfficeContext.js';\nimport { noLicenseModel } from './bannerModels.js';\n\n/**\n * Tells a user who cannot use the product why, and what to do about it: the tenant is suspended, its trial ended, the\n * user has no seat, or the tenant has more people with seats than it has bought. Nothing is shown to a user with a\n * license. Render it where the application's content would be, or above it.\n */\nexport const NoLicense = () => {\n const entitlements = useEntitlementsContext();\n const { labels, seat } = useBoxOfficeContext();\n const model = noLicenseModel(entitlements, seat, labels);\n\n if (!model) {\n return null;\n }\n\n return (\n <div className='boxoffice-no-license' data-reason={model.reason}>\n <Message severity={model.reason === 'noSeat' || model.reason === 'overCapacity' ? 'warn' : 'error'}>\n <div className='boxoffice-banner__text'>\n <strong>{model.title}</strong>\n <span>{model.text}</span>\n </div>\n </Message>\n {model.reason !== 'noSeat' && <PortalButton intent={PortalIntent.buy} label={labels.noLicense.openPortal} variant='outline' />}\n </div>\n );\n};\n"],"names":["NoLicense","entitlements","useEntitlementsContext","labels","seat","useBoxOfficeContext","model","noLicenseModel","_jsxs","div","className","data-reason","reason","_jsx","Message","severity","strong","title","span","text","PortalButton","intent","PortalIntent","buy","label","noLicense","openPortal","variant"],"mappings":";;;;;;;;;;AAUA;;;;UAKaA,SAAAA,GAAY,IAAA;AACrB,IAAA,MAAMC,YAAAA,GAAeC,0CAAAA,EAAAA;AACrB,IAAA,MAAM,EAAEC,MAAM,EAAEC,IAAI,EAAE,GAAGC,oCAAAA,EAAAA;IACzB,MAAMC,KAAAA,GAAQC,2BAAAA,CAAeN,YAAAA,EAAcG,IAAAA,EAAMD,MAAAA,CAAAA;AAEjD,IAAA,IAAI,CAACG,KAAAA,EAAO;QACR,OAAO,IAAA;AACX,IAAA;AAEA,IAAA,qBACIE,eAAA,CAACC,KAAAA,EAAAA;QAAIC,SAAAA,EAAU,sBAAA;AAAuBC,QAAAA,aAAAA,EAAaL,MAAMM,MAAM;;0BAC3DC,cAAA,CAACC,eAAAA,EAAAA;gBAAQC,QAAAA,EAAUT,KAAAA,CAAMM,MAAM,KAAK,QAAA,IAAYN,MAAMM,MAAM,KAAK,iBAAiB,MAAA,GAAS,OAAA;AACvF,gBAAA,QAAA,gBAAAJ,eAAA,CAACC,KAAAA,EAAAA;oBAAIC,SAAAA,EAAU,wBAAA;;sCACXG,cAAA,CAACG,QAAAA,EAAAA;AAAQV,4BAAAA,QAAAA,EAAAA,KAAAA,CAAMW;;sCACfJ,cAAA,CAACK,MAAAA,EAAAA;AAAMZ,4BAAAA,QAAAA,EAAAA,KAAAA,CAAMa;;;;;YAGpBb,KAAAA,CAAMM,MAAM,KAAK,QAAA,kBAAYC,cAAA,CAACO,yBAAAA,EAAAA;AAAaC,gBAAAA,MAAAA,EAAQC,kCAAaC,GAAG;gBAAEC,KAAAA,EAAOrB,MAAAA,CAAOsB,SAAS,CAACC,UAAU;gBAAEC,OAAAA,EAAQ;;;;AAG9H;;"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SuspensionCause } from '@cratis/showrunner.boxoffice';
|
|
2
|
+
export interface SuspensionBannerViewProps {
|
|
3
|
+
cause?: SuspensionCause;
|
|
4
|
+
}
|
|
5
|
+
export declare const SuspensionBannerView: ({ cause }: SuspensionBannerViewProps) => import("react").JSX.Element;
|
|
6
|
+
export declare const SuspensionBanner: () => import("react").JSX.Element | null;
|
|
7
|
+
//# sourceMappingURL=SuspensionBanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SuspensionBanner.d.ts","sourceRoot":"","sources":["../../../Banners/SuspensionBanner.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAiD,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAS9G,MAAM,WAAW,yBAAyB;IAEtC,KAAK,CAAC,EAAE,eAAe,CAAC;CAC3B;AAKD,eAAO,MAAM,oBAAoB,GAAI,WAAW,yBAAyB,gCAgBxE,CAAC;AAMF,eAAO,MAAM,gBAAgB,0CAU5B,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var Display = require('@cratis/components/Display');
|
|
5
|
+
var showrunner_boxoffice = require('@cratis/showrunner.boxoffice');
|
|
6
|
+
var EntitlementsContext = require('../Entitlements/EntitlementsContext.js');
|
|
7
|
+
var PortalButton = require('../Portal/PortalButton.js');
|
|
8
|
+
var BoxOfficeContext = require('../Provider/BoxOfficeContext.js');
|
|
9
|
+
var bannerModels = require('./bannerModels.js');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* What the suspension banner shows, for the cause it is given.
|
|
13
|
+
*/ const SuspensionBannerView = ({ cause })=>{
|
|
14
|
+
const labels = BoxOfficeContext.useBoxOfficeLabels();
|
|
15
|
+
const reason = bannerModels.suspensionReason(cause, labels);
|
|
16
|
+
return /*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
17
|
+
className: "boxoffice-banner",
|
|
18
|
+
children: [
|
|
19
|
+
/*#__PURE__*/ jsxRuntime.jsx(Display.Message, {
|
|
20
|
+
severity: "error",
|
|
21
|
+
children: /*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
22
|
+
className: "boxoffice-banner__text",
|
|
23
|
+
children: [
|
|
24
|
+
/*#__PURE__*/ jsxRuntime.jsx("strong", {
|
|
25
|
+
children: labels.suspension.title
|
|
26
|
+
}),
|
|
27
|
+
reason && /*#__PURE__*/ jsxRuntime.jsx("span", {
|
|
28
|
+
children: reason
|
|
29
|
+
}),
|
|
30
|
+
/*#__PURE__*/ jsxRuntime.jsx("span", {
|
|
31
|
+
children: labels.suspension.resolve
|
|
32
|
+
})
|
|
33
|
+
]
|
|
34
|
+
})
|
|
35
|
+
}),
|
|
36
|
+
/*#__PURE__*/ jsxRuntime.jsx(PortalButton.PortalButton, {
|
|
37
|
+
intent: showrunner_boxoffice.PortalIntent.buy,
|
|
38
|
+
label: labels.suspension.openPortal,
|
|
39
|
+
size: "small",
|
|
40
|
+
variant: "outline"
|
|
41
|
+
})
|
|
42
|
+
]
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Tells the user that the operator suspended the tenant and why, and that everything is read-only until it is lifted.
|
|
47
|
+
* Nothing is shown when the tenant is not suspended. Render it once, above the application's pages.
|
|
48
|
+
*/ const SuspensionBanner = ()=>{
|
|
49
|
+
const entitlements = EntitlementsContext.useEntitlementsContext();
|
|
50
|
+
const isSuspended = entitlements.readOnlyReason === showrunner_boxoffice.ReadOnlyReason.tenantSuspended;
|
|
51
|
+
const [standing] = showrunner_boxoffice.CurrentStanding.when(isSuspended).use();
|
|
52
|
+
if (!isSuspended) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return /*#__PURE__*/ jsxRuntime.jsx(SuspensionBannerView, {
|
|
56
|
+
cause: standing.isSuccess ? standing.data?.cause : undefined
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
exports.SuspensionBanner = SuspensionBanner;
|
|
61
|
+
exports.SuspensionBannerView = SuspensionBannerView;
|
|
62
|
+
//# sourceMappingURL=SuspensionBanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SuspensionBanner.js","sources":["../../../Banners/SuspensionBanner.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Message } from '@cratis/components/Display';\nimport { CurrentStanding, PortalIntent, ReadOnlyReason, SuspensionCause } from '@cratis/showrunner.boxoffice';\nimport { useEntitlementsContext } from '../Entitlements/EntitlementsContext.js';\nimport { PortalButton } from '../Portal/PortalButton.js';\nimport { useBoxOfficeLabels } from '../Provider/BoxOfficeContext.js';\nimport { suspensionReason } from './bannerModels.js';\n\n/**\n * Props for {@link SuspensionBannerView}.\n */\nexport interface SuspensionBannerViewProps {\n /** The cause the operator gave; the reason is left out when not known. */\n cause?: SuspensionCause;\n}\n\n/**\n * What the suspension banner shows, for the cause it is given.\n */\nexport const SuspensionBannerView = ({ cause }: SuspensionBannerViewProps) => {\n const labels = useBoxOfficeLabels();\n const reason = suspensionReason(cause, labels);\n\n return (\n <div className='boxoffice-banner'>\n <Message severity='error'>\n <div className='boxoffice-banner__text'>\n <strong>{labels.suspension.title}</strong>\n {reason && <span>{reason}</span>}\n <span>{labels.suspension.resolve}</span>\n </div>\n </Message>\n <PortalButton intent={PortalIntent.buy} label={labels.suspension.openPortal} size='small' variant='outline' />\n </div>\n );\n};\n\n/**\n * Tells the user that the operator suspended the tenant and why, and that everything is read-only until it is lifted.\n * Nothing is shown when the tenant is not suspended. Render it once, above the application's pages.\n */\nexport const SuspensionBanner = () => {\n const entitlements = useEntitlementsContext();\n const isSuspended = entitlements.readOnlyReason === ReadOnlyReason.tenantSuspended;\n const [standing] = CurrentStanding.when(isSuspended).use();\n\n if (!isSuspended) {\n return null;\n }\n\n return <SuspensionBannerView cause={standing.isSuccess ? standing.data?.cause : undefined} />;\n};\n"],"names":["SuspensionBannerView","cause","labels","useBoxOfficeLabels","reason","suspensionReason","_jsxs","div","className","_jsx","Message","severity","strong","suspension","title","span","resolve","PortalButton","intent","PortalIntent","buy","label","openPortal","size","variant","SuspensionBanner","entitlements","useEntitlementsContext","isSuspended","readOnlyReason","ReadOnlyReason","tenantSuspended","standing","CurrentStanding","when","use","isSuccess","data","undefined"],"mappings":";;;;;;;;;;AAkBA;;AAEC,IACM,MAAMA,oBAAAA,GAAuB,CAAC,EAAEC,KAAK,EAA6B,GAAA;AACrE,IAAA,MAAMC,MAAAA,GAASC,mCAAAA,EAAAA;IACf,MAAMC,MAAAA,GAASC,8BAAiBJ,KAAAA,EAAOC,MAAAA,CAAAA;AAEvC,IAAA,qBACII,eAAA,CAACC,KAAAA,EAAAA;QAAIC,SAAAA,EAAU,kBAAA;;0BACXC,cAAA,CAACC,eAAAA,EAAAA;gBAAQC,QAAAA,EAAS,OAAA;AACd,gBAAA,QAAA,gBAAAL,eAAA,CAACC,KAAAA,EAAAA;oBAAIC,SAAAA,EAAU,wBAAA;;sCACXC,cAAA,CAACG,QAAAA,EAAAA;sCAAQV,MAAAA,CAAOW,UAAU,CAACC;;AAC1BV,wBAAAA,MAAAA,kBAAUK,cAAA,CAACM,MAAAA,EAAAA;AAAMX,4BAAAA,QAAAA,EAAAA;;sCAClBK,cAAA,CAACM,MAAAA,EAAAA;sCAAMb,MAAAA,CAAOW,UAAU,CAACG;;;;;0BAGjCP,cAAA,CAACQ,yBAAAA,EAAAA;AAAaC,gBAAAA,MAAAA,EAAQC,kCAAaC,GAAG;gBAAEC,KAAAA,EAAOnB,MAAAA,CAAOW,UAAU,CAACS,UAAU;gBAAEC,IAAAA,EAAK,OAAA;gBAAQC,OAAAA,EAAQ;;;;AAG9G;AAEA;;;UAIaC,gBAAAA,GAAmB,IAAA;AAC5B,IAAA,MAAMC,YAAAA,GAAeC,0CAAAA,EAAAA;AACrB,IAAA,MAAMC,WAAAA,GAAcF,YAAAA,CAAaG,cAAc,KAAKC,oCAAeC,eAAe;AAClF,IAAA,MAAM,CAACC,QAAAA,CAAS,GAAGC,qCAAgBC,IAAI,CAACN,aAAaO,GAAG,EAAA;AAExD,IAAA,IAAI,CAACP,WAAAA,EAAa;QACd,OAAO,IAAA;AACX,IAAA;AAEA,IAAA,qBAAOnB,cAAA,CAACT,oBAAAA,EAAAA;AAAqBC,QAAAA,KAAAA,EAAO+B,SAASI,SAAS,GAAGJ,QAAAA,CAASK,IAAI,EAAEpC,KAAAA,GAAQqC;;AACpF;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrialBanner.d.ts","sourceRoot":"","sources":["../../../Banners/TrialBanner.tsx"],"names":[],"mappings":"AAcA,eAAO,MAAM,WAAW,0CAevB,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var Display = require('@cratis/components/Display');
|
|
5
|
+
var showrunner_boxoffice = require('@cratis/showrunner.boxoffice');
|
|
6
|
+
var EntitlementsContext = require('../Entitlements/EntitlementsContext.js');
|
|
7
|
+
var PortalButton = require('../Portal/PortalButton.js');
|
|
8
|
+
var BoxOfficeContext = require('../Provider/BoxOfficeContext.js');
|
|
9
|
+
var bannerModels = require('./bannerModels.js');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Tells the user how long the tenant's trial runs, or that it has closed, with a button to buy. Nothing is shown when
|
|
13
|
+
* the tenant is not on a trial. Render it once, above the application's pages.
|
|
14
|
+
*/ const TrialBanner = ()=>{
|
|
15
|
+
const entitlements = EntitlementsContext.useEntitlementsContext();
|
|
16
|
+
const labels = BoxOfficeContext.useBoxOfficeLabels();
|
|
17
|
+
const model = bannerModels.trialBannerModel(entitlements, labels);
|
|
18
|
+
if (!model) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
return /*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
22
|
+
className: "boxoffice-banner",
|
|
23
|
+
children: [
|
|
24
|
+
/*#__PURE__*/ jsxRuntime.jsx(Display.Message, {
|
|
25
|
+
severity: model.severity,
|
|
26
|
+
children: model.text
|
|
27
|
+
}),
|
|
28
|
+
/*#__PURE__*/ jsxRuntime.jsx(PortalButton.PortalButton, {
|
|
29
|
+
intent: showrunner_boxoffice.PortalIntent.buy,
|
|
30
|
+
label: labels.trialBanner.buy,
|
|
31
|
+
size: "small"
|
|
32
|
+
})
|
|
33
|
+
]
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
exports.TrialBanner = TrialBanner;
|
|
38
|
+
//# sourceMappingURL=TrialBanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrialBanner.js","sources":["../../../Banners/TrialBanner.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Message } from '@cratis/components/Display';\nimport { PortalIntent } from '@cratis/showrunner.boxoffice';\nimport { useEntitlementsContext } from '../Entitlements/EntitlementsContext.js';\nimport { PortalButton } from '../Portal/PortalButton.js';\nimport { useBoxOfficeLabels } from '../Provider/BoxOfficeContext.js';\nimport { trialBannerModel } from './bannerModels.js';\n\n/**\n * Tells the user how long the tenant's trial runs, or that it has closed, with a button to buy. Nothing is shown when\n * the tenant is not on a trial. Render it once, above the application's pages.\n */\nexport const TrialBanner = () => {\n const entitlements = useEntitlementsContext();\n const labels = useBoxOfficeLabels();\n const model = trialBannerModel(entitlements, labels);\n\n if (!model) {\n return null;\n }\n\n return (\n <div className='boxoffice-banner'>\n <Message severity={model.severity}>{model.text}</Message>\n <PortalButton intent={PortalIntent.buy} label={labels.trialBanner.buy} size='small' />\n </div>\n );\n};\n"],"names":["TrialBanner","entitlements","useEntitlementsContext","labels","useBoxOfficeLabels","model","trialBannerModel","_jsxs","div","className","_jsx","Message","severity","text","PortalButton","intent","PortalIntent","buy","label","trialBanner","size"],"mappings":";;;;;;;;;;AAUA;;;UAIaA,WAAAA,GAAc,IAAA;AACvB,IAAA,MAAMC,YAAAA,GAAeC,0CAAAA,EAAAA;AACrB,IAAA,MAAMC,MAAAA,GAASC,mCAAAA,EAAAA;IACf,MAAMC,KAAAA,GAAQC,8BAAiBL,YAAAA,EAAcE,MAAAA,CAAAA;AAE7C,IAAA,IAAI,CAACE,KAAAA,EAAO;QACR,OAAO,IAAA;AACX,IAAA;AAEA,IAAA,qBACIE,eAAA,CAACC,KAAAA,EAAAA;QAAIC,SAAAA,EAAU,kBAAA;;0BACXC,cAAA,CAACC,eAAAA,EAAAA;AAAQC,gBAAAA,QAAAA,EAAUP,MAAMO,QAAQ;AAAGP,gBAAAA,QAAAA,EAAAA,KAAAA,CAAMQ;;0BAC1CH,cAAA,CAACI,yBAAAA,EAAAA;AAAaC,gBAAAA,MAAAA,EAAQC,kCAAaC,GAAG;gBAAEC,KAAAA,EAAOf,MAAAA,CAAOgB,WAAW,CAACF,GAAG;gBAAEG,IAAAA,EAAK;;;;AAGxF;;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SeatStanding, SuspensionCause } from '@cratis/showrunner.boxoffice';
|
|
2
|
+
import { Entitlements } from '../Entitlements/entitlementModel.js';
|
|
3
|
+
import { BoxOfficeLabels } from '../Labels/index.js';
|
|
4
|
+
export type BannerSeverity = 'info' | 'warn' | 'error';
|
|
5
|
+
export interface TrialBannerModel {
|
|
6
|
+
readonly severity: BannerSeverity;
|
|
7
|
+
readonly text: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const trialWarningDays = 7;
|
|
10
|
+
export declare function trialBannerModel(entitlements: Entitlements, labels: BoxOfficeLabels): TrialBannerModel | undefined;
|
|
11
|
+
export declare function suspensionReason(cause: SuspensionCause | undefined, labels: BoxOfficeLabels): string;
|
|
12
|
+
export type NoLicenseReason = 'suspended' | 'trialClosed' | 'noSeat' | 'overCapacity';
|
|
13
|
+
export interface NoLicenseModel {
|
|
14
|
+
readonly reason: NoLicenseReason;
|
|
15
|
+
readonly title: string;
|
|
16
|
+
readonly text: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function noLicenseModel(entitlements: Entitlements, seat: SeatStanding | undefined, labels: BoxOfficeLabels): NoLicenseModel | undefined;
|
|
19
|
+
//# sourceMappingURL=bannerModels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bannerModels.d.ts","sourceRoot":"","sources":["../../../Banners/bannerModels.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,YAAY,EAAc,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACzG,OAAO,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACnE,OAAO,EAAE,eAAe,EAAU,MAAM,oBAAoB,CAAC;AAG7D,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAKvD,MAAM,WAAW,gBAAgB;IAE7B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAGlC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACzB;AAGD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAQlC,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,GAAG,gBAAgB,GAAG,SAAS,CAkBlH;AAQD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,MAAM,CAWpG;AAGD,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,aAAa,GAAG,QAAQ,GAAG,cAAc,CAAC;AAKtF,MAAM,WAAW,cAAc;IAE3B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IAGjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAGvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACzB;AAUD,wBAAgB,cAAc,CAAC,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,GAAG,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,cAAc,GAAG,SAAS,CAsB9I"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var showrunner_boxoffice = require('@cratis/showrunner.boxoffice');
|
|
4
|
+
var format = require('../Labels/format.js');
|
|
5
|
+
|
|
6
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
7
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
8
|
+
/** How many days before a trial ends the banner turns into a warning. */ const trialWarningDays = 7;
|
|
9
|
+
/**
|
|
10
|
+
* Works out what the trial banner says.
|
|
11
|
+
* @param entitlements What the tenant may do.
|
|
12
|
+
* @param labels The labels to show.
|
|
13
|
+
* @returns What to say; undefined when the tenant is not on a trial, or the trial is not what makes it read-only.
|
|
14
|
+
*/ function trialBannerModel(entitlements, labels) {
|
|
15
|
+
if (entitlements.state === 'trialClosed') {
|
|
16
|
+
return {
|
|
17
|
+
severity: 'error',
|
|
18
|
+
text: labels.trialBanner.closed
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
if (entitlements.state !== 'trial' || !entitlements.trial) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
const { daysLeft } = entitlements.trial;
|
|
25
|
+
if (daysLeft <= 0) {
|
|
26
|
+
return {
|
|
27
|
+
severity: 'warn',
|
|
28
|
+
text: labels.trialBanner.lastDay
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
severity: daysLeft <= trialWarningDays ? 'warn' : 'info',
|
|
33
|
+
text: format.format(labels.trialBanner.running, {
|
|
34
|
+
days: daysLeft
|
|
35
|
+
})
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Says why the operator suspended a tenant.
|
|
40
|
+
* @param cause The cause the operator gave.
|
|
41
|
+
* @param labels The labels to show.
|
|
42
|
+
* @returns The reason, in words.
|
|
43
|
+
*/ function suspensionReason(cause, labels) {
|
|
44
|
+
switch(cause){
|
|
45
|
+
case showrunner_boxoffice.SuspensionCause.trialEndedWithoutSeats:
|
|
46
|
+
return labels.suspension.trialEndedWithoutSeats;
|
|
47
|
+
case showrunner_boxoffice.SuspensionCause.paymentOverdue:
|
|
48
|
+
return labels.suspension.paymentOverdue;
|
|
49
|
+
case showrunner_boxoffice.SuspensionCause.administratorDecision:
|
|
50
|
+
return labels.suspension.administratorDecision;
|
|
51
|
+
default:
|
|
52
|
+
return '';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Works out whether the user has a license, and what to tell them if not. The tenant being read-only comes first,
|
|
57
|
+
* because it holds for everyone in it.
|
|
58
|
+
* @param entitlements What the tenant may do.
|
|
59
|
+
* @param seat Where the user stands with the tenant's seats; nothing while it loads.
|
|
60
|
+
* @param labels The labels to show.
|
|
61
|
+
* @returns What to tell the user; undefined when they have a license, or it is not known yet.
|
|
62
|
+
*/ function noLicenseModel(entitlements, seat, labels) {
|
|
63
|
+
if (entitlements.isLoading) {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
if (entitlements.readOnlyReason === showrunner_boxoffice.ReadOnlyReason.tenantSuspended) {
|
|
67
|
+
return {
|
|
68
|
+
reason: 'suspended',
|
|
69
|
+
title: labels.noLicense.suspendedTitle,
|
|
70
|
+
text: labels.noLicense.suspended
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (entitlements.readOnlyReason === showrunner_boxoffice.ReadOnlyReason.trialClosed) {
|
|
74
|
+
return {
|
|
75
|
+
reason: 'trialClosed',
|
|
76
|
+
title: labels.noLicense.trialClosedTitle,
|
|
77
|
+
text: labels.noLicense.trialClosed
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (seat?.status === showrunner_boxoffice.SeatStatus.noSeat) {
|
|
81
|
+
return {
|
|
82
|
+
reason: 'noSeat',
|
|
83
|
+
title: labels.noLicense.noSeatTitle,
|
|
84
|
+
text: labels.noLicense.noSeat
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (seat?.status === showrunner_boxoffice.SeatStatus.overCapacity) {
|
|
88
|
+
return {
|
|
89
|
+
reason: 'overCapacity',
|
|
90
|
+
title: labels.noLicense.overCapacityTitle,
|
|
91
|
+
text: labels.noLicense.overCapacity
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
exports.noLicenseModel = noLicenseModel;
|
|
98
|
+
exports.suspensionReason = suspensionReason;
|
|
99
|
+
exports.trialBannerModel = trialBannerModel;
|
|
100
|
+
exports.trialWarningDays = trialWarningDays;
|
|
101
|
+
//# sourceMappingURL=bannerModels.js.map
|