import { MetaDataProps, ProviderGroup } from "./components"; import { FilterOption } from "./filters"; import { NodeKind, OrganizationNodeResource, OrganizationResource, OrganizationType, } from "./organizations"; import { ProviderProps } from "./providers"; import { ScanScheduleSummary } from "./scans"; export const PROVIDERS_ROW_TYPE = { ORGANIZATION: "organization", PROVIDER: "provider", } as const; export type ProvidersRowType = (typeof PROVIDERS_ROW_TYPE)[keyof typeof PROVIDERS_ROW_TYPE]; export const PROVIDERS_GROUP_KIND = { ORGANIZATION: "organization", ORGANIZATION_UNIT: "organization-unit", } as const; export type ProvidersGroupKind = (typeof PROVIDERS_GROUP_KIND)[keyof typeof PROVIDERS_GROUP_KIND]; export const HIERARCHY_STATUS = { AVAILABLE: "available", UNAVAILABLE: "unavailable", } as const; export type HierarchyStatus = (typeof HIERARCHY_STATUS)[keyof typeof HIERARCHY_STATUS]; export const PROVIDERS_PAGE_FILTER = { PROVIDER: "provider__in", PROVIDER_TYPE: "provider_type__in", STATUS: "connected", } as const; export type ProvidersPageFilter = (typeof PROVIDERS_PAGE_FILTER)[keyof typeof PROVIDERS_PAGE_FILTER]; export interface ProviderTableRelationshipData { id: string; type: string; } export interface ProviderTableRelationshipRef { data: ProviderTableRelationshipData | null; } export type ProviderTableRelationships = ProviderProps["relationships"] & { organization?: ProviderTableRelationshipRef; // Canonical provider→node relationship, plus deprecated aliases tolerated // during the transition window. organization_node?: ProviderTableRelationshipRef; organization_unit?: ProviderTableRelationshipRef; organizational_unit?: ProviderTableRelationshipRef; }; export interface ProvidersProviderRow extends Omit { rowType: typeof PROVIDERS_ROW_TYPE.PROVIDER; relationships: ProviderTableRelationships; groupNames: string[]; hasSchedule: boolean; /** Cadence/next-run summary when the provider has a configured schedule. */ scheduleSummary?: ScanScheduleSummary; /** Completed-at timestamp for the provider's last scan when exposed by API. */ lastScanAt?: string | null; subRows?: ProvidersTableRow[]; } export interface ProvidersOrganizationRow { id: string; rowType: typeof PROVIDERS_ROW_TYPE.ORGANIZATION; groupKind: ProvidersGroupKind; orgType: OrganizationType; kind?: NodeKind; name: string; externalId: string | null; parentExternalId: string | null; organizationId: string | null; providerCount: number; providerIds: string[]; subRows: ProvidersTableRow[]; } export type ProvidersTableRow = ProvidersOrganizationRow | ProvidersProviderRow; export interface ProvidersTableRowsInput { isCloud: boolean; organizations: OrganizationResource[]; organizationNodes: OrganizationNodeResource[]; providers: ProvidersProviderRow[]; } export interface ProvidersAccountsViewData { filters: FilterOption[]; metadata?: MetaDataProps; providers: ProviderProps[]; providerGroups: ProviderGroup[]; rows: ProvidersTableRow[]; /** `unavailable` when the hierarchy fetch failed (drives the degraded notice). */ hierarchyStatus: HierarchyStatus; } export function isProvidersOrganizationRow( row: ProvidersTableRow, ): row is ProvidersOrganizationRow { return row.rowType === PROVIDERS_ROW_TYPE.ORGANIZATION; } export function isProvidersProviderRow( row: ProvidersTableRow, ): row is ProvidersProviderRow { return row.rowType === PROVIDERS_ROW_TYPE.PROVIDER; }