Merge pull request #27851 from overleaf/slg-group-member-pricing-js-to-ts

[web] Migrate group-member-pricing.jsx to tsx

GitOrigin-RevId: f5fd95939f6af5dfaedb1fafeecec04ceb6612f6
This commit is contained in:
Simon Gardner
2025-08-18 11:48:53 +01:00
committed by Copybot
parent eac4a5cb13
commit ccd770f433
3 changed files with 66 additions and 1 deletions

View File

@@ -44,7 +44,10 @@ import {
} from '../../../types/settings-page'
import { SuggestedLanguage } from '../../../types/system-message'
import type { TeamInvite } from '../../../types/team-invite'
import { GroupPlans } from '../../../types/subscription/dashboard/group-plans'
import {
GroupPlans,
GroupPlansData,
} from '../../../types/subscription/dashboard/group-plans'
import {
GroupSSOLinkingStatus,
SSOConfig,
@@ -125,6 +128,7 @@ export interface Meta {
'ol-groupId': string
'ol-groupName': string
'ol-groupPlans': GroupPlans
'ol-groupPlansData': GroupPlansData
'ol-groupPolicy': GroupPolicy
'ol-groupSSOActive': boolean
'ol-groupSSOConfig'?: SSOConfig

View File

@@ -1,3 +1,7 @@
// this import fails linting in CI if from '@ol-types/utils' so as a temporary workaround we'll use the relative path
import { mkLiteralUnionTypeguard } from '../../utils'
import { CurrencyCode } from '../currency'
export type GroupPlans = {
plans: {
display: string
@@ -5,3 +9,28 @@ export type GroupPlans = {
}[]
sizes: string[]
}
export const planTypeGroup = ['collaborator', 'professional'] as const
export type PlanTypeGroup = (typeof planTypeGroup)[number]
export const isPlanTypeGroup = mkLiteralUnionTypeguard(planTypeGroup)
export const planUsageType = ['enterprise', 'educational'] as const
export type PlanUsageType = (typeof planUsageType)[number]
export const isPlanUsageType = mkLiteralUnionTypeguard(planUsageType)
export const licenseSize = ['2', '3', '4', '5', '10', '20'] as const
export type LicenseSize = (typeof licenseSize)[number]
export const isLicenseSize = mkLiteralUnionTypeguard(licenseSize)
export type LicensePrice = {
price_in_cents: number
additional_license_legacy_price_in_cents: number
}
export type PlanPriceByLicenseSize = Record<LicenseSize, LicensePrice>
export type PlanByCurrencyCode = Record<CurrencyCode, PlanPriceByLicenseSize>
export type PlansByPlanTypeGroup = Record<PlanTypeGroup, PlanByCurrencyCode>
export type GroupPlansData = Record<PlanUsageType, PlansByPlanTypeGroup>

View File

@@ -20,3 +20,35 @@ export type DeepPartial<T> = Partial<{ [P in keyof T]: DeepPartial<T[P]> }>
export type MergeAndOverride<Parent, Own> = Own & Omit<Parent, keyof Own>
export type Keys<T extends object> = (keyof T)[]
/**
* Helper to create type guards for literal unions
*
* @example
* ```ts
* const fruit = ['apple', 'banana', 'cherry'] as const;
* type Fruit = typeof fruit[number];
* const isFruit = mkLiteralUnionTypeguard(fruit);
*
* // Usage example:
* function eatFood(food: unknown[]) {
* food.forEach(item => {
* if (isFruit(item)) {
* eatFruit(item)
* } else {
* console.log(`Not fruit ${item}`)
* }
* })
* }
* eatFood(['banana', 'pizza'])
* ```
*
* @param xs A readonly tuple of allowed values (strings, numbers, or symbols).
* @returns A type guard function `(value: unknown) => value is T[number]`.
*/
export function mkLiteralUnionTypeguard<
const T extends readonly (string | number | symbol)[],
>(xs: T) {
return (v: unknown): v is T[number] =>
(xs as readonly (string | number | symbol)[]).includes(v as any)
}