diff --git a/services/web/frontend/js/utils/meta.ts b/services/web/frontend/js/utils/meta.ts index 762cea1e63..6c3fac675a 100644 --- a/services/web/frontend/js/utils/meta.ts +++ b/services/web/frontend/js/utils/meta.ts @@ -72,6 +72,7 @@ export interface Meta { 'ol-cannot-reactivate-subscription': boolean 'ol-cannot-use-ai': boolean 'ol-chatEnabled': boolean + 'ol-compilesUserContentDomain': string 'ol-countryCode': PricingFormState['country'] 'ol-couponCode': PricingFormState['coupon'] 'ol-createdAt': Date @@ -163,9 +164,11 @@ export interface Meta { 'ol-postCheckoutRedirect': string 'ol-postUrl': string 'ol-prefetchedProjectsBlob': GetProjectsResponseBody | undefined + 'ol-preventCompileOnLoad'?: boolean 'ol-primaryEmail': { email: string; confirmed: boolean } 'ol-project': any // TODO 'ol-projectHistoryBlobsEnabled': boolean + 'ol-projectName': string 'ol-projectSyncSuccessMessage': string 'ol-projectTags': Tag[] 'ol-project_id': string @@ -232,6 +235,22 @@ export interface Meta { 'ol-wsUrl': string } +type DeepPartial = + T extends Record ? { [P in keyof T]?: DeepPartial } : T + +export type PartialMeta = DeepPartial + +export type MetaAttributesCache< + K extends keyof PartialMeta = keyof PartialMeta, +> = Map + +export type MetaTag = { + [K in keyof Meta]: { + name: K + value: Meta[K] + } +}[keyof Meta] + // cache for parsed values window.metaAttributesCache = window.metaAttributesCache || new Map() diff --git a/services/web/frontend/stories/hooks/use-meta.tsx b/services/web/frontend/stories/hooks/use-meta.tsx index 398af6789e..0ebbe9f29f 100644 --- a/services/web/frontend/stories/hooks/use-meta.tsx +++ b/services/web/frontend/stories/hooks/use-meta.tsx @@ -1,14 +1,10 @@ -import type { Meta } from '@/utils/meta' - -type DeepPartial = T extends object - ? { [P in keyof T]?: DeepPartial } - : T +import { PartialMeta } from '@/utils/meta' /** * Set values on window.metaAttributesCache, for use in Storybook stories */ -export const useMeta = (meta: DeepPartial) => { +export const useMeta = (meta: PartialMeta) => { for (const [key, value] of Object.entries(meta)) { - window.metaAttributesCache.set(key, value) + window.metaAttributesCache.set(key as keyof PartialMeta, value) } } diff --git a/services/web/frontend/stories/loading/loading.stories.tsx b/services/web/frontend/stories/loading/loading.stories.tsx index 0a643d7224..b4c9068737 100644 --- a/services/web/frontend/stories/loading/loading.stories.tsx +++ b/services/web/frontend/stories/loading/loading.stories.tsx @@ -2,6 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react' import { LoadingUI } from '@/features/ide-react/components/loading' import { EditorProviders } from '../../../test/frontend/helpers/editor-providers' import { bsVersionDecorator } from '../../../.storybook/utils/with-bootstrap-switcher' +import { PartialMeta } from '@/utils/meta' const meta: Meta = { title: 'Loading Page / Loading', @@ -35,7 +36,7 @@ const errorMessages = { export const LoadingPage: Story = { render: args => { for (const [key, value] of Object.entries(errorMessages)) { - window.metaAttributesCache.set(`ol-${key}`, value) + window.metaAttributesCache.set(`ol-${key}` as keyof PartialMeta, value) } return ( diff --git a/services/web/test/frontend/features/group-management/components/add-seats.spec.tsx b/services/web/test/frontend/features/group-management/components/add-seats.spec.tsx index 5ccc611769..4110a5d0c2 100644 --- a/services/web/test/frontend/features/group-management/components/add-seats.spec.tsx +++ b/services/web/test/frontend/features/group-management/components/add-seats.spec.tsx @@ -11,10 +11,6 @@ describe('', function () { cy.window().then(win => { win.metaAttributesCache.set('ol-groupName', 'My Awesome Team') win.metaAttributesCache.set('ol-subscriptionId', '123') - win.metaAttributesCache.set( - 'ol-subscriptionEndsAt', - '2025-01-01T12:00:00.000Z' - ) win.metaAttributesCache.set('ol-totalLicenses', this.totalLicenses) win.metaAttributesCache.set('ol-isProfessional', false) }) diff --git a/services/web/test/frontend/features/subscription/components/dashboard/institution-memberships.test.tsx b/services/web/test/frontend/features/subscription/components/dashboard/institution-memberships.test.tsx index 7471c36d09..b880464588 100644 --- a/services/web/test/frontend/features/subscription/components/dashboard/institution-memberships.test.tsx +++ b/services/web/test/frontend/features/subscription/components/dashboard/institution-memberships.test.tsx @@ -5,8 +5,9 @@ import { cleanUpContext, renderWithSubscriptionDashContext, } from '../../helpers/render-with-subscription-dash-context' +import { Institution } from '../../../../../../types/institution' -const memberships = [ +const memberships: Institution[] = [ { id: 9258, name: 'Test University', @@ -16,6 +17,7 @@ const memberships = [ ssoBeta: false, ssoEnabled: false, maxConfirmationMonths: 6, + writefullCommonsAccount: false, }, { id: 9259, @@ -26,6 +28,7 @@ const memberships = [ ssoBeta: false, ssoEnabled: true, maxConfirmationMonths: 12, + writefullCommonsAccount: false, }, ] diff --git a/services/web/test/frontend/features/subscription/components/dashboard/states/active/active.test.tsx b/services/web/test/frontend/features/subscription/components/dashboard/states/active/active.test.tsx index df8192030f..be8f3ba87c 100644 --- a/services/web/test/frontend/features/subscription/components/dashboard/states/active/active.test.tsx +++ b/services/web/test/frontend/features/subscription/components/dashboard/states/active/active.test.tsx @@ -22,6 +22,7 @@ import { subscriptionUpdateUrl, } from '../../../../../../../../frontend/js/features/subscription/data/subscription-url' import * as useLocationModule from '../../../../../../../../frontend/js/shared/hooks/use-location' +import { MetaTag } from '@/utils/meta' describe('', function () { let sendMBSpy: sinon.SinonSpy @@ -318,9 +319,9 @@ describe('', function () { }) describe('extend trial', function () { - const canExtend = { + const canExtend: MetaTag = { name: 'ol-userCanExtendTrial', - value: 'true', + value: true, } const cancelButtonText = 'No thanks, I still want to cancel' const extendTrialButtonText = 'I’ll take it!' diff --git a/services/web/test/frontend/features/subscription/components/dashboard/states/active/change-plan/change-plan.test.tsx b/services/web/test/frontend/features/subscription/components/dashboard/states/active/change-plan/change-plan.test.tsx index 5bca8c03d9..979a87743b 100644 --- a/services/web/test/frontend/features/subscription/components/dashboard/states/active/change-plan/change-plan.test.tsx +++ b/services/web/test/frontend/features/subscription/components/dashboard/states/active/change-plan/change-plan.test.tsx @@ -23,8 +23,6 @@ import { renderActiveSubscription } from '../../../../../helpers/render-active-s import * as useLocationModule from '../../../../../../../../../frontend/js/shared/hooks/use-location' describe('', function () { - const plansMetaTag = { name: 'ol-plans', value: plans } - let reloadStub: sinon.SinonStub beforeEach(function () { @@ -83,7 +81,7 @@ describe('', function () { { metaTags: [ { name: 'ol-subscription', value: annualActiveSubscription }, - plansMetaTag, + { name: 'ol-plans', value: plans }, ], } ) diff --git a/services/web/test/frontend/features/subscription/components/successful-subscription/successful-subscription.test.tsx b/services/web/test/frontend/features/subscription/components/successful-subscription/successful-subscription.test.tsx index d3be3acae4..58828bebe3 100644 --- a/services/web/test/frontend/features/subscription/components/successful-subscription/successful-subscription.test.tsx +++ b/services/web/test/frontend/features/subscription/components/successful-subscription/successful-subscription.test.tsx @@ -3,22 +3,22 @@ import { screen, within } from '@testing-library/react' import SuccessfulSubscription from '../../../../../../frontend/js/features/subscription/components/successful-subscription/successful-subscription' import { renderWithSubscriptionDashContext } from '../../helpers/render-with-subscription-dash-context' import { annualActiveSubscription } from '../../fixtures/subscriptions' +import { ExposedSettings } from '../../../../../../types/exposed-settings' describe('successful subscription page', function () { it('renders the invoices link', function () { const adminEmail = 'foo@example.com' - const options = { + renderWithSubscriptionDashContext(, { metaTags: [ { name: 'ol-ExposedSettings', value: { adminEmail, - }, + } as ExposedSettings, }, { name: 'ol-subscription', value: annualActiveSubscription }, ], - } - renderWithSubscriptionDashContext(, options) + }) screen.getByRole('heading', { name: /thanks for subscribing/i }) const alert = screen.getByRole('alert') diff --git a/services/web/test/frontend/features/subscription/helpers/render-active-subscription.tsx b/services/web/test/frontend/features/subscription/helpers/render-active-subscription.tsx index f790dac2dd..19566a8945 100644 --- a/services/web/test/frontend/features/subscription/helpers/render-active-subscription.tsx +++ b/services/web/test/frontend/features/subscription/helpers/render-active-subscription.tsx @@ -2,30 +2,31 @@ import { ActiveSubscription } from '../../../../../frontend/js/features/subscrip import { RecurlySubscription } from '../../../../../types/subscription/dashboard/subscription' import { groupPlans, plans } from '../fixtures/plans' import { renderWithSubscriptionDashContext } from './render-with-subscription-dash-context' +import { MetaTag } from '@/utils/meta' +import { CurrencyCode } from '../../../../../types/subscription/currency' export function renderActiveSubscription( subscription: RecurlySubscription, - tags: { name: string; value: string | object | Array }[] = [], - currencyCode?: string + tags: MetaTag[] = [], + currencyCode?: CurrencyCode ) { - const renderOptions = { - currencyCode, - metaTags: [ - ...tags, - { name: 'ol-plans', value: plans }, - { - name: 'ol-groupPlans', - value: groupPlans, - }, - { name: 'ol-subscription', value: subscription }, - { - name: 'ol-recommendedCurrency', - value: currencyCode || 'USD', - }, - ], - } renderWithSubscriptionDashContext( , - renderOptions + { + currencyCode, + metaTags: [ + ...tags, + { name: 'ol-plans', value: plans }, + { + name: 'ol-groupPlans', + value: groupPlans, + }, + { name: 'ol-subscription', value: subscription }, + { + name: 'ol-recommendedCurrency', + value: currencyCode || 'USD', + }, + ], + } ) } diff --git a/services/web/test/frontend/features/subscription/helpers/render-with-subscription-dash-context.tsx b/services/web/test/frontend/features/subscription/helpers/render-with-subscription-dash-context.tsx index f3603d484a..38a5d7c021 100644 --- a/services/web/test/frontend/features/subscription/helpers/render-with-subscription-dash-context.tsx +++ b/services/web/test/frontend/features/subscription/helpers/render-with-subscription-dash-context.tsx @@ -4,14 +4,12 @@ import { SubscriptionDashboardProvider } from '../../../../../frontend/js/featur import { groupPriceByUsageTypeAndSize, plans } from '../fixtures/plans' import fetchMock from 'fetch-mock' import { SplitTestProvider } from '@/shared/context/split-test-context' +import { MetaTag } from '@/utils/meta' export function renderWithSubscriptionDashContext( component: React.ReactElement, options?: { - metaTags?: { - name: string - value: string | object | Array | boolean - }[] + metaTags?: MetaTag[] recurlyNotLoaded?: boolean queryingRecurly?: boolean currencyCode?: string @@ -28,7 +26,7 @@ export function renderWithSubscriptionDashContext( ) options?.metaTags?.forEach(tag => - window.metaAttributesCache.set(tag.name, tag.value) + window.metaAttributesCache.set(tag!.name, tag!.value) ) window.metaAttributesCache.set('ol-user', {}) diff --git a/services/web/types/window.ts b/services/web/types/window.ts index 4096958005..2a17efeb13 100644 --- a/services/web/types/window.ts +++ b/services/web/types/window.ts @@ -1,10 +1,11 @@ import 'recurly__recurly-js' import { ScopeValueStore } from './ide/scope-value-store' +import { MetaAttributesCache } from '@/utils/meta' declare global { // eslint-disable-next-line no-unused-vars interface Window { - metaAttributesCache: Map + metaAttributesCache: MetaAttributesCache _ide: Record & { $scope: Record & { pdf?: {