{{ 'XP.Membership.AdminTitle' | translate: { Default: 'Membership Plans' } }}
{{ 'XP.Membership.AdminDescription' | translate : { Default: 'Configure current-scope membership plans, point allowances, and model usage rules.' } }}
@if (activeTab() === 'plans') { }
@if (activeTab() === 'plans') { @if (scopeStatus(); as status) {
@if (status.scope === 'organization') { {{ 'XP.Membership.OrganizationScope' | translate: { Default: 'Organization membership' } }} } @else { {{ 'XP.Membership.TenantScope' | translate: { Default: 'Tenant membership' } }} }
{{ scopeStatusLabel(status) }}
@if (status.scope === 'organization') { {{ 'XP.Membership.OrganizationScopeHint' | translate : { Default: 'Organization plans control organization local Copilot models. Tenant models are used only when this scope has no plan.' } }} } @else { {{ 'XP.Membership.TenantScopeHint' | translate: { Default: 'Tenant plans control tenant Copilot models and tenant fallback access.' } }} }
{{ 'XP.Membership.DefaultPlanLabel' | translate: { Default: 'Default plan' } }}
{{ scopeDefaultPlanLabel(status) }}
{{ 'XP.Membership.ActivePlans' | translate: { Default: 'Active plans' } }}
{{ activePlanCount() | number }} / {{ plans().length | number }}
{{ 'XP.Membership.ArchivedPlans' | translate: { Default: 'Archived plans' } }}
{{ archivedPlanCount() | number }}
@if (status.scope === 'organization') {
{{ 'XP.Membership.AssignedMembers' | translate: { Default: 'Assigned members' } }}
{{ status.assignedMemberCount ?? 0 | number }} / {{ status.activeMemberCount ?? 0 | number }}
}
@if (showScopeAction()) { }
}
{{ 'XP.Membership.PlanCatalog' | translate: { Default: 'Plan catalog' } }} {{ 'XP.Membership.PlanCatalogHint' | translate: { Default: 'Select a plan to review or edit its rules.' } }}
@if (loading()) { {{ 'XP.KEY_WORDS.Loading' | translate: { Default: 'Loading...' } }} }
@for (plan of plans(); track plan.id) {
{{ plan.name }}
{{ plan.code }}
@if (plan.isDefault) { {{ 'XP.Membership.DefaultPlan' | translate: { Default: 'Default' } }} } {{ 'XP.Membership.Level' | translate: { Default: 'Level' } }} {{ plan.level }} {{ 'XP.Membership.Statuses.' + plan.status | translate: { Default: plan.status } }}
{{ 'XP.Membership.Points' | translate: { Default: 'Points' } }}
@if (plan.includedPoints === null) { {{ 'XP.Membership.Unlimited' | translate: { Default: 'Unlimited' } }} } @else { {{ plan.includedPoints | number: '1.0-2' }} }
@if (plan.status === MembershipPlanStatusEnum.Archived) { } @else { }
} @empty {
{{ 'XP.Membership.NoPlans' | translate: { Default: 'No membership plans yet.' } }}
}
@if (editing()) {
{{ (draft.id ? 'XP.Membership.EditPlan' : 'XP.Membership.CreatePlan') | translate: { Default: draft.id ? 'Edit plan' : 'Create plan' } }} {{ 'XP.Membership.PlanFormHint' | translate: { Default: 'Define the point allowance, model access rules, and usage limits.' } }}
{{ 'XP.Membership.PlanIdentity' | translate: { Default: 'Plan identity' } }}
{{ 'XP.Membership.Code' | translate: { Default: 'Code' } }} {{ 'XP.Membership.Name' | translate: { Default: 'Name' } }} {{ 'XP.Membership.Level' | translate: { Default: 'Level' } }} @if (planForm.controls.level.invalid && planForm.controls.level.touched) { {{ 'XP.Membership.LevelValidation' | translate: { Default: 'Level must be a whole number of zero or greater.' } }} } {{ 'XP.Membership.Status' | translate: { Default: 'Status' } }} {{ 'XP.Membership.Statuses.active' | translate: { Default: 'Active' } }} {{ 'XP.Membership.Statuses.archived' | translate: { Default: 'Archived' } }}
{{ 'XP.Membership.SetDefaultPlan' | translate: { Default: 'Set as default plan' } }}
{{ 'XP.Membership.PointRules' | translate: { Default: 'Point rules' } }}
{{ 'XP.Membership.PointsPerPeriod' | translate: { Default: 'Points per period' } }} {{ 'XP.Membership.Unlimited' | translate: { Default: 'Unlimited' } }}
{{ 'XP.Membership.Description' | translate: { Default: 'Description' } }}
{{ 'XP.Membership.ModelUsageRules' | translate: { Default: 'Model access and usage rules' } }}
{{ 'XP.Membership.ModelUsageRulesHint' | translate : { Default: 'Choose available models and optionally customize settlement amount multipliers and usage limits.' } }}
{{ 'XP.Membership.AllowedModels' | translate: { Default: 'Allowed models' } }}
{{ 'XP.Membership.AllowedModelsHint' | translate: { Default: 'Choose which models members of this plan can use.' } }}
{{ 'XP.Membership.AllowAllModels' | translate: { Default: 'Allow all models' } }}
@if (!planForm.controls.allowAllModels.value) {
@for (option of allowedModelOptions(); track option.value) { {{ modelTargetLabel(option) }} } @if (!allowedModelOptions().length) {
{{ 'XP.Membership.NoModelsAvailable' | translate: { Default: 'No configured Copilot models are available in this scope.' } }}
}
}
{{ 'XP.Membership.ModelMultipliers' | translate: { Default: 'Settlement amount multipliers' } }}
{{ 'XP.Membership.ModelMultipliersHint' | translate : { Default: 'Multiply the settled model amount before converting it to points. The default multiplier is 1.' } }}
@if (modelMultipliers.length) {
@for (rule of modelMultipliers; track $index) {
}
} @else {
{{ 'XP.Membership.NoModelMultipliers' | translate: { Default: 'No custom multipliers. All models use a multiplier of 1.' } }}
}
{{ 'XP.Membership.RateLimits' | translate: { Default: 'Usage limits' } }}
{{ 'XP.Membership.RateLimitsHint' | translate : { Default: 'Limit the number of points members can consume within a period.' } }}
@if (rateLimits.length) {
@for (rule of rateLimits; track $index) {
}
} @else {
{{ 'XP.Membership.NoRateLimits' | translate: { Default: 'No additional usage limits.' } }}
}
} @else if (selectedPlan(); as plan) {
{{ plan.name }} @if (plan.isDefault) { {{ 'XP.Membership.DefaultPlan' | translate: { Default: 'Default' } }} }
{{ plan.code }}
@if (plan.status === MembershipPlanStatusEnum.Archived) { } @else { }
{{ 'XP.Membership.Level' | translate: { Default: 'Level' } }}
{{ plan.level }}
{{ 'XP.Membership.Status' | translate: { Default: 'Status' } }}
{{ 'XP.Membership.Statuses.' + plan.status | translate: { Default: plan.status } }}
{{ 'XP.Membership.PointsPerPeriod' | translate: { Default: 'Points per period' } }}
@if (plan.includedPoints === null) { {{ 'XP.Membership.Unlimited' | translate: { Default: 'Unlimited' } }} } @else { {{ plan.includedPoints | number: '1.0-2' }} }
@if (plan.description) {
{{ 'XP.Membership.Description' | translate: { Default: 'Description' } }}
{{ plan.description }}
}
{{ 'XP.Membership.AllowedModels' | translate: { Default: 'Allowed models' } }}
@if (allowedModelCount(plan)) { {{ allowedModelCount(plan) | number }} {{ 'XP.KEY_WORDS.Items' | translate: { Default: 'items' } }} } @else { {{ 'XP.Membership.AllModels' | translate: { Default: 'All models' } }} }
{{ 'XP.Membership.ModelMultipliers' | translate: { Default: 'Settlement amount multipliers' } }}
{{ modelMultiplierCount(plan) | number }} {{ 'XP.KEY_WORDS.Items' | translate: { Default: 'items' } }}
{{ 'XP.Membership.RateLimits' | translate: { Default: 'Rate limits' } }}
{{ rateLimitCount(plan) | number }} {{ 'XP.KEY_WORDS.Items' | translate: { Default: 'items' } }}
{{ 'XP.Membership.AssignedUsers' | translate: { Default: 'Assigned users' } }}
{{ 'XP.Membership.AssignedUsersHint' | translate: { Default: 'Active and paused users currently assigned to this plan.' } }}
@if (planMembers().length && migrationTargets().length) {
@for (target of migrationTargets(); track target.id) { {{ target.name }} }
}
@for (member of planMembers(); track member.id) {
{{ memberLabel(member) }}
@if (member.user?.email) {
{{ member.user.email }}
}
{{ 'XP.Membership.MemberStatuses.' + member.status | translate: { Default: member.status } }} {{ member.currentPeriodEnd | date: 'mediumDate' }}
} @empty {
@if (planMembersLoading()) { {{ 'XP.KEY_WORDS.Loading' | translate: { Default: 'Loading...' } }} } @else { {{ 'XP.Membership.NoAssignedUsers' | translate: { Default: 'No users are assigned to this plan.' } }} }
}
@if (planMemberCount() > planMemberPageSize()) { }
} @else {
{{ 'XP.Membership.NoPlanSelected' | translate: { Default: 'No plan selected' } }}
{{ 'XP.Membership.SelectPlanHint' | translate: { Default: 'Create a plan or select one from the catalog to manage it.' } }}
}
} @else {

{{ 'XP.Membership.UserManagement' | translate: { Default: 'User memberships' } }}

{{ 'XP.Membership.UserManagementHint' | translate : { Default: 'View every user in the current scope, including users without a membership, and apply common actions in batches.' } }}
{{ 'XP.Membership.SearchUsers' | translate: { Default: 'Search users' } }} {{ 'XP.Membership.Status' | translate: { Default: 'Status' } }} {{ 'XP.KEY_WORDS.All' | translate: { Default: 'All' } }} @for ( status of [ MembershipAdminUserStatusEnum.Active, MembershipAdminUserStatusEnum.Paused, MembershipAdminUserStatusEnum.Expired, MembershipAdminUserStatusEnum.Unassigned ]; track status ) { {{ 'XP.Membership.MemberStatuses.' + status | translate: { Default: status } }} } {{ 'XP.Membership.Plan' | translate: { Default: 'Plan' } }} {{ 'XP.KEY_WORDS.All' | translate: { Default: 'All' } }} @for (plan of plans(); track plan.id) { {{ plan.name }} } {{ 'XP.Membership.ExpiringBefore' | translate: { Default: 'Expiring before' } }}
@if (selectedUserCount()) {
{{ selectedUserCount() }} {{ 'XP.Membership.SelectedUsers' | translate: { count: selectedUserCount(), Default: selectedUserCount() + ' selected' } }}
{{ 'XP.Membership.BulkAction' | translate: { Default: 'Batch action' } }} @for ( action of [ MembershipBulkActionEnum.Assign, MembershipBulkActionEnum.Renew, MembershipBulkActionEnum.Pause, MembershipBulkActionEnum.Resume, MembershipBulkActionEnum.Revoke ]; track action ) { {{ 'XP.Membership.BulkActions.' + action | translate: { Default: action } }} } @if (bulkActionRequiresPlan()) { {{ 'XP.Membership.Plan' | translate: { Default: 'Plan' } }} @for (plan of plans(); track plan.id) { @if (plan.status === MembershipPlanStatusEnum.Active) { {{ plan.name }} } } {{ 'XP.Membership.RenewalMode' | translate: { Default: 'Renewal mode' } }} {{ 'XP.Membership.RenewalModes.auto' | translate: { Default: 'Auto renew' } }} {{ 'XP.Membership.RenewalModes.manual' | translate: { Default: 'Manual renew' } }} {{ 'XP.Membership.AssignNote' | translate: { Default: 'Assignment note' } }} }
}
@for (member of adminMembers(); track member.user.id) {
{{ adminMemberLabel(member) }}
{{ member.user.email || member.user.username }}
{{ member.membership?.plan?.name || '-' }}
@if (member.scheduledPeriodCount) {
{{ 'XP.Membership.UpcomingPeriodCount' | translate : { count: member.scheduledPeriodCount, Default: member.scheduledPeriodCount + ' upcoming' } }}
}
{{ 'XP.Membership.MemberStatuses.' + adminMemberStatus(member) | translate: { Default: adminMemberStatus(member) } }}
@if (!member.membership) { - } @else if (member.membership.pointsGranted === null) { {{ 'XP.Membership.Unlimited' | translate: { Default: 'Unlimited' } }} } @else { {{ adminMemberRemainingPoints(member) | number: '1.0-2' }} }
{{ member.membership?.currentPeriodEnd ? (member.membership?.currentPeriodEnd | date: 'mediumDate') : '-' }}
} @empty {
@if (adminMembersLoading()) { {{ 'XP.KEY_WORDS.Loading' | translate: { Default: 'Loading...' } }} } @else { {{ 'XP.Membership.NoUsersFound' | translate: { Default: 'No users match these filters.' } }} }
}
}