@replicated/portal-components 0.0.2 → 0.0.3
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/components/metadata/registry.json +83 -2
- package/components/metadata/registry.md +27 -2
- package/dist/actions/index.d.mts +566 -3
- package/dist/actions/index.d.ts +566 -3
- package/dist/actions/index.js +1853 -12
- package/dist/actions/index.js.map +1 -1
- package/dist/airgap-instances.d.mts +26 -0
- package/dist/airgap-instances.d.ts +26 -0
- package/dist/airgap-instances.js +354 -0
- package/dist/airgap-instances.js.map +1 -0
- package/dist/error-page.d.mts +14 -0
- package/dist/error-page.d.ts +14 -0
- package/dist/error-page.js +153 -0
- package/dist/error-page.js.map +1 -0
- package/dist/error.d.mts +15 -0
- package/dist/error.d.ts +15 -0
- package/dist/error.js +144 -0
- package/dist/error.js.map +1 -0
- package/dist/esm/actions/index.js +1816 -13
- package/dist/esm/actions/index.js.map +1 -1
- package/dist/esm/airgap-instances.js +352 -0
- package/dist/esm/airgap-instances.js.map +1 -0
- package/dist/esm/error-page.js +151 -0
- package/dist/esm/error-page.js.map +1 -0
- package/dist/esm/error.js +142 -0
- package/dist/esm/error.js.map +1 -0
- package/dist/esm/helm-install-wizard.js +1007 -0
- package/dist/esm/helm-install-wizard.js.map +1 -0
- package/dist/esm/index.js +2232 -155
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/install-actions.js +746 -0
- package/dist/esm/install-actions.js.map +1 -0
- package/dist/esm/install-card.js +115 -0
- package/dist/esm/install-card.js.map +1 -0
- package/dist/esm/install-targets.js +48 -0
- package/dist/esm/install-targets.js.map +1 -0
- package/dist/esm/instance-card.js +197 -0
- package/dist/esm/instance-card.js.map +1 -0
- package/dist/esm/join-team.js +218 -0
- package/dist/esm/join-team.js.map +1 -0
- package/dist/esm/license-card.js +131 -0
- package/dist/esm/license-card.js.map +1 -0
- package/dist/esm/license-details.js +667 -0
- package/dist/esm/license-details.js.map +1 -0
- package/dist/esm/linux-install-wizard.js +1083 -0
- package/dist/esm/linux-install-wizard.js.map +1 -0
- package/dist/esm/login.js +261 -0
- package/dist/esm/login.js.map +1 -0
- package/dist/esm/online-instance-list.js +287 -0
- package/dist/esm/online-instance-list.js.map +1 -0
- package/dist/esm/pending-installations.js +235 -0
- package/dist/esm/pending-installations.js.map +1 -0
- package/dist/esm/release-history-panel.js +100 -0
- package/dist/esm/release-history-panel.js.map +1 -0
- package/dist/esm/release-notes-card.js +23 -0
- package/dist/esm/release-notes-card.js.map +1 -0
- package/dist/esm/security-card.js +700 -0
- package/dist/esm/security-card.js.map +1 -0
- package/dist/esm/support-bundle-collection-card.js +170 -0
- package/dist/esm/support-bundle-collection-card.js.map +1 -0
- package/dist/esm/support-bundles-card.js +306 -0
- package/dist/esm/support-bundles-card.js.map +1 -0
- package/dist/esm/support-card.js +305 -0
- package/dist/esm/support-card.js.map +1 -0
- package/dist/esm/team-selection.js +117 -0
- package/dist/esm/team-selection.js.map +1 -0
- package/dist/esm/team-settings-card.js +78 -0
- package/dist/esm/team-settings-card.js.map +1 -0
- package/dist/esm/team-settings.js +136 -0
- package/dist/esm/team-settings.js.map +1 -0
- package/dist/esm/top-nav-user-menu.js +173 -0
- package/dist/esm/top-nav-user-menu.js.map +1 -0
- package/dist/esm/top-nav.js +398 -0
- package/dist/esm/top-nav.js.map +1 -0
- package/dist/esm/update-layout.js +405 -0
- package/dist/esm/update-layout.js.map +1 -0
- package/dist/esm/updates-card.js +85 -0
- package/dist/esm/updates-card.js.map +1 -0
- package/dist/esm/upload-support-bundle-modal.js +143 -0
- package/dist/esm/upload-support-bundle-modal.js.map +1 -0
- package/dist/esm/user-settings-card.js +21 -0
- package/dist/esm/user-settings-card.js.map +1 -0
- package/dist/esm/user-settings.js +368 -0
- package/dist/esm/user-settings.js.map +1 -0
- package/dist/esm/utils/index.js +170 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/helm-install-wizard.d.mts +38 -0
- package/dist/helm-install-wizard.d.ts +38 -0
- package/dist/helm-install-wizard.js +1011 -0
- package/dist/helm-install-wizard.js.map +1 -0
- package/dist/index.d.mts +11 -27
- package/dist/index.d.ts +11 -27
- package/dist/index.js +2258 -154
- package/dist/index.js.map +1 -1
- package/dist/install-B19AaKF_.d.mts +233 -0
- package/dist/install-Bi1qJ8Bu.d.ts +233 -0
- package/dist/install-actions.d.mts +141 -0
- package/dist/install-actions.d.ts +141 -0
- package/dist/install-actions.js +765 -0
- package/dist/install-actions.js.map +1 -0
- package/dist/install-card.d.mts +15 -0
- package/dist/install-card.d.ts +15 -0
- package/dist/install-card.js +117 -0
- package/dist/install-card.js.map +1 -0
- package/dist/install-targets.d.mts +19 -0
- package/dist/install-targets.d.ts +19 -0
- package/dist/install-targets.js +50 -0
- package/dist/install-targets.js.map +1 -0
- package/dist/instance-card.d.mts +22 -0
- package/dist/instance-card.d.ts +22 -0
- package/dist/instance-card.js +199 -0
- package/dist/instance-card.js.map +1 -0
- package/dist/join-team.d.mts +30 -0
- package/dist/join-team.d.ts +30 -0
- package/dist/join-team.js +220 -0
- package/dist/join-team.js.map +1 -0
- package/dist/license-card.d.mts +15 -0
- package/dist/license-card.d.ts +15 -0
- package/dist/license-card.js +133 -0
- package/dist/license-card.js.map +1 -0
- package/dist/license-details.d.mts +10 -0
- package/dist/license-details.d.ts +10 -0
- package/dist/license-details.js +669 -0
- package/dist/license-details.js.map +1 -0
- package/dist/linux-install-wizard.d.mts +66 -0
- package/dist/linux-install-wizard.d.ts +66 -0
- package/dist/linux-install-wizard.js +1093 -0
- package/dist/linux-install-wizard.js.map +1 -0
- package/dist/login.d.mts +37 -0
- package/dist/login.d.ts +37 -0
- package/dist/login.js +263 -0
- package/dist/login.js.map +1 -0
- package/dist/online-instance-list.d.mts +22 -0
- package/dist/online-instance-list.d.ts +22 -0
- package/dist/online-instance-list.js +289 -0
- package/dist/online-instance-list.js.map +1 -0
- package/dist/pending-installations.d.mts +15 -0
- package/dist/pending-installations.d.ts +15 -0
- package/dist/pending-installations.js +237 -0
- package/dist/pending-installations.js.map +1 -0
- package/dist/release-history-panel.d.mts +22 -0
- package/dist/release-history-panel.d.ts +22 -0
- package/dist/release-history-panel.js +102 -0
- package/dist/release-history-panel.js.map +1 -0
- package/dist/release-notes-card.d.mts +13 -0
- package/dist/release-notes-card.d.ts +13 -0
- package/dist/release-notes-card.js +25 -0
- package/dist/release-notes-card.js.map +1 -0
- package/dist/security-card.d.mts +73 -0
- package/dist/security-card.d.ts +73 -0
- package/dist/security-card.js +702 -0
- package/dist/security-card.js.map +1 -0
- package/dist/styles.css +1877 -194
- package/dist/support-bundle-collection-card.d.mts +20 -0
- package/dist/support-bundle-collection-card.d.ts +20 -0
- package/dist/support-bundle-collection-card.js +172 -0
- package/dist/support-bundle-collection-card.js.map +1 -0
- package/dist/support-bundles-card.d.mts +19 -0
- package/dist/support-bundles-card.d.ts +19 -0
- package/dist/support-bundles-card.js +308 -0
- package/dist/support-bundles-card.js.map +1 -0
- package/dist/support-card.d.mts +8 -0
- package/dist/support-card.d.ts +8 -0
- package/dist/support-card.js +307 -0
- package/dist/support-card.js.map +1 -0
- package/dist/team-selection.d.mts +23 -0
- package/dist/team-selection.d.ts +23 -0
- package/dist/team-selection.js +119 -0
- package/dist/team-selection.js.map +1 -0
- package/dist/team-settings-card-Dq1d9b5c.d.mts +14 -0
- package/dist/team-settings-card-Dq1d9b5c.d.ts +14 -0
- package/dist/team-settings-card.d.mts +2 -0
- package/dist/team-settings-card.d.ts +2 -0
- package/dist/team-settings-card.js +80 -0
- package/dist/team-settings-card.js.map +1 -0
- package/dist/team-settings.d.mts +25 -0
- package/dist/team-settings.d.ts +25 -0
- package/dist/team-settings.js +138 -0
- package/dist/team-settings.js.map +1 -0
- package/dist/top-nav-0mb1K_H0.d.mts +32 -0
- package/dist/top-nav-0mb1K_H0.d.ts +32 -0
- package/dist/top-nav-user-menu.d.mts +18 -0
- package/dist/top-nav-user-menu.d.ts +18 -0
- package/dist/top-nav-user-menu.js +175 -0
- package/dist/top-nav-user-menu.js.map +1 -0
- package/dist/top-nav.d.mts +3 -0
- package/dist/top-nav.d.ts +3 -0
- package/dist/top-nav.js +400 -0
- package/dist/top-nav.js.map +1 -0
- package/dist/update-layout.d.mts +12 -0
- package/dist/update-layout.d.ts +12 -0
- package/dist/update-layout.js +407 -0
- package/dist/update-layout.js.map +1 -0
- package/dist/updates-card-BbubBrVR.d.mts +18 -0
- package/dist/updates-card-BbubBrVR.d.ts +18 -0
- package/dist/updates-card.d.mts +2 -0
- package/dist/updates-card.d.ts +2 -0
- package/dist/updates-card.js +87 -0
- package/dist/updates-card.js.map +1 -0
- package/dist/upload-support-bundle-modal.d.mts +19 -0
- package/dist/upload-support-bundle-modal.d.ts +19 -0
- package/dist/upload-support-bundle-modal.js +145 -0
- package/dist/upload-support-bundle-modal.js.map +1 -0
- package/dist/user-settings-card.d.mts +8 -0
- package/dist/user-settings-card.d.ts +8 -0
- package/dist/user-settings-card.js +23 -0
- package/dist/user-settings-card.js.map +1 -0
- package/dist/user-settings.d.mts +47 -0
- package/dist/user-settings.d.ts +47 -0
- package/dist/user-settings.js +370 -0
- package/dist/user-settings.js.map +1 -0
- package/dist/utils/index.d.mts +70 -0
- package/dist/utils/index.d.ts +70 -0
- package/dist/utils/index.js +177 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +163 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/actions/instances.ts","../src/components/instance-card.tsx","../src/components/online-instance-list.tsx"],"names":["jsx","jsxs","useState"],"mappings":"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","file":"online-instance-list.js","sourcesContent":["/**\n * Instance-related server actions for the Update page.\n * \n * These actions handle fetching and managing instances including:\n * - Listing all instances (online and airgap)\n * - Fetching install options for instances\n * - Calculating update availability\n */\n\nimport { authenticatedFetch } from \"../utils/api-client\";\nimport { getApiOrigin, getCustomerIdFromToken } from \"./index\";\nimport type { PortalActionContext } from \"./index\";\nimport type { ChannelRelease, InstallOptions } from \"./install\";\nexport type { InstallOptions } from \"./install\";\n\n// =============================================================================\n// Types - Instance\n// =============================================================================\n\nexport type ResourceStatus = \"ready\" | \"updating\" | \"unknown\" | \"missing\" | \"unavailable\" | \"degraded\";\n\nexport interface ResourceState {\n kind: string;\n name: string;\n namespace: string;\n state: ResourceStatus;\n}\n\nexport interface InstanceTag {\n key: string;\n value: string;\n origin?: string;\n}\n\nexport interface Instance {\n id: string;\n firstCheckin: string;\n firstReadyAt?: string;\n lastCheckin: string;\n isAirgap: boolean;\n appStatus?: string;\n resourceStates?: ResourceState[];\n versionLabel?: string;\n channelId?: string;\n channelSequence?: number;\n serviceAccountId?: string;\n embeddedClusterId?: string;\n kotsInstallId?: string;\n kurlInstallId?: string;\n k8sVersion?: string;\n k8sDistribution?: string;\n tags?: InstanceTag[];\n}\n\nexport interface FetchInstancesInput {\n token: string;\n}\n\nexport interface FetchInstancesResult {\n instances: Instance[];\n online: Instance[];\n airgap: Instance[];\n}\n\n// =============================================================================\n// Types - Install Options by Instance\n// =============================================================================\n\nexport interface FetchInstallOptionsByInstanceIdsInput {\n token: string;\n instanceIds: string[];\n}\n\nexport interface FetchInstallOptionsByInstanceIdsResult {\n installOptions: InstallOptions[];\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/** 24 hours in milliseconds - threshold for active vs inactive instances */\nexport const ACTIVE_INSTANCE_THRESHOLD_MS = 24 * 60 * 60 * 1000;\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Determines if an instance is active based on last check-in time.\n * Active = last check-in within the last 24 hours.\n */\nexport function isInstanceActive(instance: Instance): boolean {\n if (!instance.lastCheckin) {\n return false;\n }\n const lastCheckinTime = new Date(instance.lastCheckin).getTime();\n const threshold = Date.now() - ACTIVE_INSTANCE_THRESHOLD_MS;\n return lastCheckinTime > threshold;\n}\n\n/**\n * Filters instances into active and inactive lists.\n */\nexport function filterActiveInactiveInstances(instances: Instance[]): {\n activeInstances: Instance[];\n inactiveInstances: Instance[];\n} {\n const activeInstances = instances.filter(isInstanceActive);\n const inactiveInstances = instances.filter((instance) => !isInstanceActive(instance));\n return { activeInstances, inactiveInstances };\n}\n\n/**\n * Gets the install type for an instance based on instance data and install options.\n */\nexport function getInstallType(\n instance: Instance,\n installOptions?: InstallOptions[]\n): \"helm\" | \"embedded cluster\" | null {\n const instanceHasNoInstallTypes =\n !instance.kotsInstallId &&\n !instance.kurlInstallId &&\n !instance.embeddedClusterId;\n const isManuallyCreatedAirgapInstance =\n instance.isAirgap && instanceHasNoInstallTypes;\n\n // Check for embedded cluster first - explicitly set\n if (instance.embeddedClusterId) {\n return \"embedded cluster\";\n }\n\n // Check for helm install with k8s info\n if (instanceHasNoInstallTypes && instance.k8sDistribution) {\n return \"helm\";\n }\n\n // Default fallback for ambiguous cases (manually created airgap without k8s info):\n // Check install options first, then assume embedded cluster\n if (isManuallyCreatedAirgapInstance && !instance.k8sDistribution) {\n if (installOptions) {\n const matchingInstallOption = installOptions.find(\n (option) => option.instance_id === instance.id\n );\n if (matchingInstallOption) {\n if (matchingInstallOption.install_type === \"helm\") {\n return \"helm\";\n }\n if (matchingInstallOption.install_type === \"linux\") {\n return \"embedded cluster\";\n }\n }\n }\n // Final fallback: assume embedded cluster\n return \"embedded cluster\";\n }\n\n return null;\n}\n\n/**\n * Calculates the number of available updates for an instance.\n */\nexport function calculateUpdatesForInstance(\n instance: Instance,\n channelReleases: ChannelRelease[]\n): number {\n if (!channelReleases || !Array.isArray(channelReleases)) {\n return 0;\n }\n\n const instanceChannelSequence = instance.channelSequence ?? 0;\n\n // Filter to matching channel and count releases with higher sequence\n const matchingReleases = channelReleases.filter(\n (release) => release.channelId === instance.channelId\n );\n\n return matchingReleases.filter(\n (release) => release.channelSequence > instanceChannelSequence\n ).length;\n}\n\n/**\n * Gets the instance name from tags or returns truncated ID.\n */\nexport function getInstanceName(instance: Instance): string {\n const nameTag = instance.tags?.find((tag) => tag.key === \"name\");\n return nameTag?.value || instance.id.slice(0, 7);\n}\n\n// =============================================================================\n// Actions\n// =============================================================================\n\n/**\n * Fetches all instances for the customer.\n * Returns instances split into online and airgap categories.\n */\nexport async function fetchInstances(\n input: FetchInstancesInput,\n context?: PortalActionContext\n): Promise<FetchInstancesResult> {\n const { token } = input;\n\n if (!token || typeof token !== \"string\") {\n throw new Error(\"fetchInstances requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const origin = getApiOrigin();\n\n const url = new URL(`${origin}/v3/instances`);\n url.searchParams.set(\"customer_id\", customerId);\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching instances via %s\", url.toString());\n }\n\n const response = await authenticatedFetch(url.toString(), {\n method: \"GET\",\n token,\n headers: {\n accept: \"application/json\"\n },\n signal: context?.signal\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `Instances request failed (${response.status} ${response.statusText}): ${errorText}`\n );\n }\n\n const payload = await response.json();\n const allInstances: Instance[] = payload.instances || [];\n\n // Split into online and airgap\n const online = allInstances.filter((instance) => !instance.isAirgap);\n const airgap = allInstances.filter((instance) => instance.isAirgap);\n\n return {\n instances: allInstances,\n online,\n airgap\n };\n}\n\n// =============================================================================\n// Types - Create Air Gap Instance\n// =============================================================================\n\nexport type AirgapInstanceStatus = \"unavailable\" | \"missing\";\n\nexport interface CreateAirgapInstanceInput {\n token: string;\n serviceAccountId: string;\n instanceName?: string;\n channelId: string;\n channelSequence: number;\n k8sVersion?: string;\n k8sDistribution?: string;\n appStatus?: AirgapInstanceStatus;\n}\n\nexport interface CreateAirgapInstanceResult {\n instanceId: string;\n licenseId: string;\n createdAt: string;\n lastActive: string;\n appFirstReadyAt: string | null;\n appStatus: string;\n isAirgap: boolean;\n channelId?: string;\n channelSequence?: number;\n k8sVersion?: string;\n k8sDistribution?: string;\n}\n\n/**\n * Creates an air gap instance record manually.\n * This is used when customers want to track air gap instances that can't check in.\n */\nexport async function createAirgapInstance(\n input: CreateAirgapInstanceInput,\n context?: PortalActionContext\n): Promise<CreateAirgapInstanceResult> {\n const {\n token,\n serviceAccountId,\n instanceName,\n channelId,\n channelSequence,\n k8sVersion,\n k8sDistribution,\n appStatus = \"missing\"\n } = input;\n\n if (!token || typeof token !== \"string\") {\n throw new Error(\"createAirgapInstance requires a session token\");\n }\n\n if (!serviceAccountId?.trim()) {\n throw new Error(\"Service account ID is required\");\n }\n\n if (!channelId?.trim()) {\n throw new Error(\"Channel ID is required\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const origin = getApiOrigin();\n\n const url = new URL(`${origin}/v3/instance/airgap`);\n url.searchParams.set(\"customer_id\", customerId);\n\n const body: Record<string, unknown> = {\n service_account_id: serviceAccountId.trim(),\n channel_id: channelId.trim(),\n channel_sequence: channelSequence,\n app_status: appStatus\n };\n\n if (instanceName?.trim()) {\n body.instance_name = instanceName.trim();\n }\n if (k8sVersion?.trim()) {\n body.k8s_version = k8sVersion.trim();\n }\n if (k8sDistribution?.trim()) {\n body.k8s_distribution = k8sDistribution.trim();\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] creating airgap instance via %s\", url.toString());\n }\n\n const response = await authenticatedFetch(url.toString(), {\n method: \"POST\",\n token,\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\"\n },\n body: JSON.stringify(body),\n signal: context?.signal\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = \"Failed to create airgap instance\";\n try {\n const errorData = JSON.parse(errorText);\n errorMessage = errorData.error || errorData.message || errorMessage;\n } catch {\n // Use default message\n }\n throw new Error(errorMessage);\n }\n\n const data = await response.json();\n \n return {\n instanceId: data.instance_id,\n licenseId: data.license_id,\n createdAt: data.created_at,\n lastActive: data.last_active,\n appFirstReadyAt: data.app_first_ready_at,\n appStatus: data.app_status,\n isAirgap: data.is_airgap,\n channelId: data.channel_id,\n channelSequence: data.channel_sequence,\n k8sVersion: data.k8s_version,\n k8sDistribution: data.k8s_distribution\n };\n}\n\n// =============================================================================\n// Types - Update Air Gap Instance\n// =============================================================================\n\nexport interface UpdateAirgapInstanceInput {\n token: string;\n instanceId: string;\n serviceAccountId?: string;\n channelId: string;\n channelSequence: number;\n}\n\nexport interface UpdateAirgapInstanceResult {\n success: boolean;\n}\n\n/**\n * Updates an air gap instance record (mark update complete).\n * This is called after completing an air gap update to update the instance version.\n */\nexport async function updateAirgapInstance(\n input: UpdateAirgapInstanceInput,\n context?: PortalActionContext\n): Promise<UpdateAirgapInstanceResult> {\n const {\n token,\n instanceId,\n serviceAccountId,\n channelId,\n channelSequence\n } = input;\n\n if (!token || typeof token !== \"string\") {\n throw new Error(\"updateAirgapInstance requires a session token\");\n }\n\n if (!instanceId?.trim()) {\n throw new Error(\"Instance ID is required\");\n }\n\n if (!channelId?.trim()) {\n throw new Error(\"Channel ID is required\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const origin = getApiOrigin();\n\n const url = new URL(`${origin}/v3/instance/airgap/${instanceId.trim()}`);\n url.searchParams.set(\"customer_id\", customerId);\n\n const body: Record<string, unknown> = {\n channel_id: channelId.trim(),\n channel_sequence: channelSequence\n };\n\n if (serviceAccountId?.trim()) {\n body.service_account_id = serviceAccountId.trim();\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] updating airgap instance via %s\", url.toString());\n }\n\n const response = await authenticatedFetch(url.toString(), {\n method: \"PATCH\",\n token,\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\"\n },\n body: JSON.stringify(body),\n signal: context?.signal\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = \"Failed to update airgap instance\";\n try {\n const errorData = JSON.parse(errorText);\n errorMessage = errorData.error || errorData.message || errorMessage;\n } catch {\n // Use default message\n }\n throw new Error(errorMessage);\n }\n\n return { success: true };\n}\n\n/**\n * Fetches install options for a batch of instance IDs.\n * Handles chunking automatically if more than 50 IDs are provided.\n */\nexport async function fetchInstallOptionsByInstanceIds(\n input: FetchInstallOptionsByInstanceIdsInput,\n context?: PortalActionContext\n): Promise<FetchInstallOptionsByInstanceIdsResult> {\n const { token, instanceIds } = input;\n\n if (!token || typeof token !== \"string\") {\n throw new Error(\"fetchInstallOptionsByInstanceIds requires a session token\");\n }\n\n if (!instanceIds || instanceIds.length === 0) {\n return { installOptions: [] };\n }\n\n const customerId = getCustomerIdFromToken(token);\n const origin = getApiOrigin();\n\n // Chunk instance IDs into groups of 50 (API limit)\n const chunks: string[][] = [];\n for (let i = 0; i < instanceIds.length; i += 50) {\n chunks.push(instanceIds.slice(i, i + 50));\n }\n\n const allInstallOptions: InstallOptions[] = [];\n\n for (const chunk of chunks) {\n if (chunk.length === 0) continue;\n\n // Build query string with multiple instance_id params\n const queryParams = chunk\n .map((id) => `instance_id=${encodeURIComponent(id)}`)\n .join(\"&\");\n\n const url = `${origin}/v3/customers/${customerId}/install-options?${queryParams}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching install options via %s\", url);\n }\n\n const response = await authenticatedFetch(url, {\n method: \"GET\",\n token,\n headers: {\n accept: \"application/json\"\n },\n signal: context?.signal\n });\n\n if (response.status === 404) {\n // No install options found for this chunk - continue\n continue;\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `Install options request failed (${response.status} ${response.statusText}): ${errorText}`\n );\n }\n\n const payload = await response.json();\n const options: InstallOptions[] = payload?.install_options || [];\n allInstallOptions.push(...options);\n }\n\n return { installOptions: allInstallOptions };\n}\n\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { type Instance, type InstallOptions, getInstallType, getInstanceName, calculateUpdatesForInstance } from \"../actions/instances\";\nimport type { ChannelRelease } from \"../actions/install\";\n\ninterface InstanceCardProps {\n instance: Instance;\n isActive: boolean;\n channelReleases?: ChannelRelease[];\n installOptions?: InstallOptions[];\n onUpdateClick?: (instanceId: string) => void;\n primaryColor?: string;\n}\n\n/**\n * Formats a date string to a human-readable format.\n */\nfunction formatDateTime(dateString?: string): string {\n if (!dateString) return \"N/A\";\n const date = new Date(dateString);\n return date.toLocaleDateString(\"en-US\", {\n month: \"numeric\",\n day: \"numeric\",\n year: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n hour12: true\n });\n}\n\n/**\n * Badge component for showing update count.\n */\nfunction UpdateBadge({ count }: { count: number }) {\n if (count <= 0) return null;\n return (\n <span className=\"ml-1.5 inline-flex h-5 w-5 items-center justify-center rounded-full bg-rose-500 text-xs font-medium text-white\">\n {count}\n </span>\n );\n}\n\n/**\n * Badge for resource status.\n */\nfunction StatusBadge({ status }: { status: string }) {\n const colorMap: Record<string, string> = {\n ready: \"bg-green-50 text-green-600\",\n updating: \"bg-green-50 text-green-600\",\n unknown: \"bg-blue-50 text-blue-500\",\n missing: \"bg-pink-50 text-pink-600\",\n unavailable: \"bg-pink-50 text-pink-600\",\n degraded: \"bg-yellow-50 text-yellow-600\"\n };\n\n const colorClass = colorMap[status] || \"bg-gray-50 text-gray-600\";\n\n return (\n <span className={`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium ${colorClass}`}>\n {status}\n <svg className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </span>\n );\n}\n\n/**\n * Instance card component for displaying an instance in the Update page.\n */\nexport function InstanceCard({\n instance,\n isActive,\n channelReleases = [],\n installOptions = [],\n onUpdateClick,\n primaryColor = \"#6366f1\"\n}: InstanceCardProps) {\n const [showInstanceId, setShowInstanceId] = useState(false);\n const [showTooltip, setShowTooltip] = useState(false);\n \n const instanceName = getInstanceName(instance);\n const installType = getInstallType(instance, installOptions);\n const availableUpdates = calculateUpdatesForInstance(instance, channelReleases);\n\n // Get the display text for the instance name/ID\n const displayText = showInstanceId \n ? instance.id.slice(0, 7)\n : instanceName || instance.id.slice(0, 7);\n\n // Get the tooltip text\n const getTooltipText = () => {\n if (instanceName) {\n return showInstanceId \n ? \"Click to show instance name\" \n : \"Click to show instance ID\";\n }\n return \"Instance ID\";\n };\n\n // Get overall resource status\n const getOverallStatus = () => {\n if (!instance.resourceStates || instance.resourceStates.length === 0) {\n return \"unknown\";\n }\n // Count states\n const stateCounts = instance.resourceStates.reduce((acc, resource) => {\n acc[resource.state] = (acc[resource.state] || 0) + 1;\n return acc;\n }, {} as Record<string, number>);\n \n // Return most common state\n let maxCount = 0;\n let maxStatus = \"unknown\";\n for (const [status, count] of Object.entries(stateCounts)) {\n if (count > maxCount) {\n maxCount = count;\n maxStatus = status;\n }\n }\n return maxStatus;\n };\n\n const overallStatus = getOverallStatus();\n\n const handleUpdateClick = () => {\n if (onUpdateClick) {\n onUpdateClick(instance.id);\n }\n };\n\n return (\n <div className=\"rounded-lg border border-gray-200 bg-white p-4\">\n <div className=\"grid grid-cols-[auto_1fr_auto] gap-3\">\n {/* Status indicator dot */}\n <div\n className={`mt-1.5 h-2 w-2 rounded-full ${\n isActive ? \"bg-green-400\" : \"bg-gray-300\"\n }`}\n />\n\n {/* Instance details */}\n <div className=\"flex flex-col gap-3\">\n {/* Instance name, version, badges, status */}\n <div className=\"flex h-min flex-wrap items-center gap-3\">\n <div className=\"relative\">\n <span \n className=\"text-sm font-medium text-gray-900 cursor-pointer hover:underline\"\n onClick={() => setShowInstanceId(!showInstanceId)}\n onMouseEnter={() => setShowTooltip(true)}\n onMouseLeave={() => setShowTooltip(false)}\n title={showInstanceId ? instance.id : instanceName || instance.id}\n >\n {displayText}\n </span>\n {showTooltip && (\n <div className=\"absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-2 py-1 text-xs text-white bg-gray-800 rounded whitespace-nowrap z-10\">\n {getTooltipText()}\n <div className=\"absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-gray-800\" />\n </div>\n )}\n </div>\n <span className=\"flex items-center gap-1 text-xs text-gray-600\">\n Version: {instance.versionLabel || \"Unknown\"}\n <UpdateBadge count={availableUpdates} />\n </span>\n {instance.isAirgap && (\n <span className=\"rounded-full bg-indigo-100 px-2 py-0.5 text-xs font-medium text-indigo-700\">\n air gap\n </span>\n )}\n {installType && (\n <span className=\"rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium text-gray-600\">\n {installType}\n </span>\n )}\n {instance.resourceStates && instance.resourceStates.length > 0 && (\n <StatusBadge status={overallStatus} />\n )}\n </div>\n\n {/* Check-in times */}\n <div className=\"flex flex-wrap gap-4\">\n <div className=\"flex items-center gap-1\">\n <span className=\"text-xs text-gray-500\">First check-in:</span>\n <span className=\"text-xs text-gray-600\">\n {formatDateTime(instance.firstCheckin)}\n </span>\n </div>\n <div className=\"flex items-center gap-1\">\n <span className=\"text-xs text-gray-500\">Last check-in:</span>\n <span className=\"text-xs text-gray-600\">\n {formatDateTime(instance.lastCheckin)}\n </span>\n </div>\n </div>\n\n {/* Tags (excluding name) */}\n {instance.tags && instance.tags.filter(tag => tag.key !== \"name\").length > 0 && (\n <div className=\"flex flex-wrap gap-2\">\n {instance.tags\n .filter(tag => tag.key !== \"name\")\n .map((tag) => (\n <span\n key={tag.key}\n className=\"rounded-md bg-gray-100 px-2 py-1 text-sm text-gray-600\"\n >\n {tag.value}\n </span>\n ))}\n </div>\n )}\n </div>\n\n {/* Update button */}\n {availableUpdates > 0 && (\n <div className=\"flex items-center\">\n <button\n onClick={handleUpdateClick}\n className=\"rounded px-4 py-1.5 text-sm font-medium text-white transition-opacity hover:opacity-90\"\n style={{ backgroundColor: primaryColor }}\n >\n Update available\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n\nInstanceCard.displayName = \"InstanceCard\";\n\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { type Instance, type InstallOptions, filterActiveInactiveInstances } from \"../actions/instances\";\nimport type { ChannelRelease } from \"../actions/install\";\nimport { InstanceCard } from \"./instance-card\";\n\ninterface OnlineInstanceListProps {\n instances?: Instance[];\n channelReleases?: ChannelRelease[];\n installOptions?: InstallOptions[];\n onUpdateClick?: (instanceId: string) => void;\n primaryColor?: string;\n /** @deprecated Use instances prop instead */\n activeCount?: number;\n /** @deprecated Use instances prop instead */\n inactiveCount?: number;\n}\n\nexport const OnlineInstanceList = ({\n instances = [],\n channelReleases = [],\n installOptions = [],\n onUpdateClick,\n primaryColor = \"#6366f1\",\n activeCount,\n inactiveCount\n}: OnlineInstanceListProps) => {\n const [showInactive, setShowInactive] = useState(false);\n\n // Filter active and inactive instances\n const { activeInstances, inactiveInstances } = filterActiveInactiveInstances(instances);\n\n // Use actual counts from instances, with fallback to deprecated props for backwards compatibility\n const activeTotal = activeCount ?? activeInstances.length;\n const inactiveTotal = inactiveCount ?? inactiveInstances.length;\n\n const hasInactiveInstances = inactiveTotal > 0;\n\n return (\n <div className=\"space-y-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <h2 className=\"mb-0 flex items-center gap-4 text-xl font-semibold text-gray-900\">\n Online instances\n <span className=\"text-sm font-semibold text-emerald-500\">\n {activeTotal} active\n </span>\n <span className=\"text-sm font-semibold text-rose-400\">\n {inactiveTotal} inactive\n </span>\n </h2>\n {hasInactiveInstances && (\n <button\n onClick={() => setShowInactive(!showInactive)}\n className=\"mb-0 cursor-pointer text-sm font-medium text-blue-500 hover:underline\"\n >\n {showInactive ? \"Hide inactive instances\" : \"Show inactive instances\"}\n </button>\n )}\n </div>\n\n {/* Instance lists */}\n <div className=\"space-y-6\">\n {/* Active instances section */}\n <div className=\"space-y-4\">\n <h3 className=\"text-sm font-medium text-gray-800\">\n Active\n <span className=\"ml-2 text-xs font-medium text-gray-400\">\n last 24 hours\n </span>\n </h3>\n\n {activeInstances.length === 0 ? (\n <div className=\"rounded-lg border border-gray-200 bg-white p-4 text-sm text-gray-500\">\n No active instances found\n </div>\n ) : (\n <div className=\"space-y-3\">\n {activeInstances.map((instance) => (\n <InstanceCard\n key={instance.id}\n instance={instance}\n isActive={true}\n channelReleases={channelReleases}\n installOptions={installOptions}\n onUpdateClick={onUpdateClick}\n primaryColor={primaryColor}\n />\n ))}\n </div>\n )}\n </div>\n\n {/* Inactive instances section */}\n {showInactive && inactiveInstances.length > 0 && (\n <div className=\"space-y-4\">\n <h3 className=\"text-sm font-medium text-gray-800\">Inactive</h3>\n <div className=\"space-y-3\">\n {inactiveInstances.map((instance) => (\n <InstanceCard\n key={instance.id}\n instance={instance}\n isActive={false}\n channelReleases={channelReleases}\n installOptions={installOptions}\n onUpdateClick={onUpdateClick}\n primaryColor={primaryColor}\n />\n ))}\n </div>\n </div>\n )}\n </div>\n </div>\n );\n};\n\nOnlineInstanceList.displayName = \"OnlineInstanceList\";\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { k as FetchPendingInstallationsResult, P as PendingInstallation } from './install-B19AaKF_.mjs';
|
|
3
|
+
import './actions/index.mjs';
|
|
4
|
+
|
|
5
|
+
interface PendingInstallationsProps {
|
|
6
|
+
fetchPendingInstallationsAction: () => Promise<FetchPendingInstallationsResult>;
|
|
7
|
+
initialInstallations?: PendingInstallation[];
|
|
8
|
+
pollIntervalMs?: number;
|
|
9
|
+
}
|
|
10
|
+
declare const PendingInstallations: {
|
|
11
|
+
({ fetchPendingInstallationsAction, initialInstallations, pollIntervalMs }: PendingInstallationsProps): react_jsx_runtime.JSX.Element | null;
|
|
12
|
+
displayName: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export { FetchPendingInstallationsResult, PendingInstallation, PendingInstallations, type PendingInstallationsProps };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { k as FetchPendingInstallationsResult, P as PendingInstallation } from './install-Bi1qJ8Bu.js';
|
|
3
|
+
import './actions/index.js';
|
|
4
|
+
|
|
5
|
+
interface PendingInstallationsProps {
|
|
6
|
+
fetchPendingInstallationsAction: () => Promise<FetchPendingInstallationsResult>;
|
|
7
|
+
initialInstallations?: PendingInstallation[];
|
|
8
|
+
pollIntervalMs?: number;
|
|
9
|
+
}
|
|
10
|
+
declare const PendingInstallations: {
|
|
11
|
+
({ fetchPendingInstallationsAction, initialInstallations, pollIntervalMs }: PendingInstallationsProps): react_jsx_runtime.JSX.Element | null;
|
|
12
|
+
displayName: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export { FetchPendingInstallationsResult, PendingInstallation, PendingInstallations, type PendingInstallationsProps };
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var react = require('react');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Enterprise Portal Components
|
|
9
|
+
* This file is generated by tsup. Do not edit manually.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
var ClockIcon = () => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
13
|
+
"svg",
|
|
14
|
+
{
|
|
15
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
16
|
+
viewBox: "0 0 24 24",
|
|
17
|
+
fill: "none",
|
|
18
|
+
stroke: "currentColor",
|
|
19
|
+
strokeWidth: "2",
|
|
20
|
+
strokeLinecap: "round",
|
|
21
|
+
strokeLinejoin: "round",
|
|
22
|
+
className: "h-6 w-6",
|
|
23
|
+
children: [
|
|
24
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
25
|
+
/* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "12 6 12 12 16 14" })
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
var TrashIcon = () => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
30
|
+
"svg",
|
|
31
|
+
{
|
|
32
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
33
|
+
viewBox: "0 0 24 24",
|
|
34
|
+
fill: "none",
|
|
35
|
+
stroke: "currentColor",
|
|
36
|
+
strokeWidth: "2",
|
|
37
|
+
strokeLinecap: "round",
|
|
38
|
+
strokeLinejoin: "round",
|
|
39
|
+
className: "h-5 w-5",
|
|
40
|
+
children: [
|
|
41
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 6h18" }),
|
|
42
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" }),
|
|
43
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" })
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
var ChevronRightIcon = () => /* @__PURE__ */ jsxRuntime.jsx(
|
|
48
|
+
"svg",
|
|
49
|
+
{
|
|
50
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
51
|
+
viewBox: "0 0 24 24",
|
|
52
|
+
fill: "none",
|
|
53
|
+
stroke: "currentColor",
|
|
54
|
+
strokeWidth: "2",
|
|
55
|
+
strokeLinecap: "round",
|
|
56
|
+
strokeLinejoin: "round",
|
|
57
|
+
className: "h-4 w-4",
|
|
58
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "9 18 15 12 9 6" })
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
var ArrowRightIcon = () => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
62
|
+
"svg",
|
|
63
|
+
{
|
|
64
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
65
|
+
viewBox: "0 0 24 24",
|
|
66
|
+
fill: "none",
|
|
67
|
+
stroke: "currentColor",
|
|
68
|
+
strokeWidth: "2",
|
|
69
|
+
strokeLinecap: "round",
|
|
70
|
+
strokeLinejoin: "round",
|
|
71
|
+
className: "h-4 w-4",
|
|
72
|
+
children: [
|
|
73
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
|
|
74
|
+
/* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "12 5 19 12 12 19" })
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
var formatTimeAgo = (dateString) => {
|
|
79
|
+
try {
|
|
80
|
+
const date = new Date(dateString);
|
|
81
|
+
const now = /* @__PURE__ */ new Date();
|
|
82
|
+
const seconds = Math.floor((now.getTime() - date.getTime()) / 1e3);
|
|
83
|
+
if (seconds < 60) return "just now";
|
|
84
|
+
if (seconds < 3600) {
|
|
85
|
+
const minutes = Math.floor(seconds / 60);
|
|
86
|
+
return `${minutes} ${minutes === 1 ? "minute" : "minutes"} ago`;
|
|
87
|
+
}
|
|
88
|
+
if (seconds < 86400) {
|
|
89
|
+
const hours = Math.floor(seconds / 3600);
|
|
90
|
+
return `${hours === 1 ? "an hour" : `${hours} hours`} ago`;
|
|
91
|
+
}
|
|
92
|
+
const days = Math.floor(seconds / 86400);
|
|
93
|
+
return `${days} ${days === 1 ? "day" : "days"} ago`;
|
|
94
|
+
} catch {
|
|
95
|
+
return dateString;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
var PendingInstallations = ({
|
|
99
|
+
fetchPendingInstallationsAction,
|
|
100
|
+
initialInstallations = [],
|
|
101
|
+
pollIntervalMs = 5e3
|
|
102
|
+
}) => {
|
|
103
|
+
const [installations, setInstallations] = react.useState(initialInstallations);
|
|
104
|
+
const [showAll, setShowAll] = react.useState(false);
|
|
105
|
+
react.useEffect(() => {
|
|
106
|
+
const fetchInstallations = async () => {
|
|
107
|
+
try {
|
|
108
|
+
const result = await fetchPendingInstallationsAction();
|
|
109
|
+
setInstallations(result.installations);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.error("[pending-installations] Failed to fetch pending installations", error);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
fetchInstallations();
|
|
115
|
+
if (!pollIntervalMs) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const intervalId = setInterval(fetchInstallations, pollIntervalMs);
|
|
119
|
+
return () => clearInterval(intervalId);
|
|
120
|
+
}, [fetchPendingInstallationsAction, pollIntervalMs]);
|
|
121
|
+
if (installations.length === 0) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
const firstInstallation = installations[0];
|
|
125
|
+
const remainingCount = installations.length - 1;
|
|
126
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-6 rounded-xl border border-orange-200 bg-orange-50 p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-4", children: [
|
|
127
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 text-orange-600", children: /* @__PURE__ */ jsxRuntime.jsx(ClockIcon, {}) }),
|
|
128
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 space-y-3", children: [
|
|
129
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4", children: [
|
|
130
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
|
|
131
|
+
/* @__PURE__ */ jsxRuntime.jsxs("h3", { className: "text-base font-semibold text-gray-900", children: [
|
|
132
|
+
"Pending installation: ",
|
|
133
|
+
firstInstallation.name,
|
|
134
|
+
" \u2022",
|
|
135
|
+
" ",
|
|
136
|
+
firstInstallation.method === "helm" ? "Helm" : "Linux",
|
|
137
|
+
" installation"
|
|
138
|
+
] }),
|
|
139
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-1 text-sm text-gray-600", children: [
|
|
140
|
+
"Started ",
|
|
141
|
+
formatTimeAgo(firstInstallation.startedAt),
|
|
142
|
+
" by ",
|
|
143
|
+
firstInstallation.startedBy
|
|
144
|
+
] }),
|
|
145
|
+
remainingCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
146
|
+
"button",
|
|
147
|
+
{
|
|
148
|
+
type: "button",
|
|
149
|
+
onClick: () => setShowAll(!showAll),
|
|
150
|
+
className: "mt-2 flex items-center gap-1 text-sm font-medium text-gray-700 hover:text-gray-900",
|
|
151
|
+
children: [
|
|
152
|
+
"View ",
|
|
153
|
+
remainingCount,
|
|
154
|
+
" more pending installation",
|
|
155
|
+
remainingCount !== 1 ? "s" : "",
|
|
156
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, {})
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
)
|
|
160
|
+
] }),
|
|
161
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
162
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
163
|
+
"button",
|
|
164
|
+
{
|
|
165
|
+
type: "button",
|
|
166
|
+
className: "rounded-lg p-2 text-red-600 transition hover:bg-red-100",
|
|
167
|
+
"aria-label": "Delete installation",
|
|
168
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(TrashIcon, {})
|
|
169
|
+
}
|
|
170
|
+
),
|
|
171
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
172
|
+
"a",
|
|
173
|
+
{
|
|
174
|
+
href: `/install?installOptionsId=${firstInstallation.id}&type=${firstInstallation.method}&step=2`,
|
|
175
|
+
className: "inline-flex items-center gap-2 rounded-lg bg-orange-200 px-4 py-2 text-sm font-semibold text-gray-900 transition hover:bg-orange-300",
|
|
176
|
+
children: [
|
|
177
|
+
"Continue installation",
|
|
178
|
+
/* @__PURE__ */ jsxRuntime.jsx(ArrowRightIcon, {})
|
|
179
|
+
]
|
|
180
|
+
}
|
|
181
|
+
)
|
|
182
|
+
] })
|
|
183
|
+
] }),
|
|
184
|
+
showAll && remainingCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 space-y-2 border-t border-orange-200 pt-4", children: installations.slice(1).map((installation) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
185
|
+
"div",
|
|
186
|
+
{
|
|
187
|
+
className: "flex items-center justify-between rounded-lg bg-white p-3",
|
|
188
|
+
children: [
|
|
189
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
190
|
+
/* @__PURE__ */ jsxRuntime.jsxs("h4", { className: "text-sm font-medium text-gray-900", children: [
|
|
191
|
+
installation.name,
|
|
192
|
+
" \u2022",
|
|
193
|
+
" ",
|
|
194
|
+
installation.method === "helm" ? "Helm" : "Linux",
|
|
195
|
+
" installation"
|
|
196
|
+
] }),
|
|
197
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-0.5 text-xs text-gray-600", children: [
|
|
198
|
+
"Started ",
|
|
199
|
+
formatTimeAgo(installation.startedAt),
|
|
200
|
+
" by ",
|
|
201
|
+
installation.startedBy
|
|
202
|
+
] })
|
|
203
|
+
] }),
|
|
204
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
205
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
206
|
+
"button",
|
|
207
|
+
{
|
|
208
|
+
type: "button",
|
|
209
|
+
className: "rounded-lg p-2 text-red-600 transition hover:bg-red-100",
|
|
210
|
+
"aria-label": "Delete installation",
|
|
211
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(TrashIcon, {})
|
|
212
|
+
}
|
|
213
|
+
),
|
|
214
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
215
|
+
"a",
|
|
216
|
+
{
|
|
217
|
+
href: `/install?installOptionsId=${installation.id}&type=${installation.method}&step=2`,
|
|
218
|
+
className: "inline-flex items-center gap-2 rounded-lg bg-orange-200 px-3 py-1.5 text-xs font-semibold text-gray-900 transition hover:bg-orange-300",
|
|
219
|
+
children: [
|
|
220
|
+
"Continue",
|
|
221
|
+
/* @__PURE__ */ jsxRuntime.jsx(ArrowRightIcon, {})
|
|
222
|
+
]
|
|
223
|
+
}
|
|
224
|
+
)
|
|
225
|
+
] })
|
|
226
|
+
]
|
|
227
|
+
},
|
|
228
|
+
installation.id
|
|
229
|
+
)) })
|
|
230
|
+
] })
|
|
231
|
+
] }) });
|
|
232
|
+
};
|
|
233
|
+
PendingInstallations.displayName = "PendingInstallations";
|
|
234
|
+
|
|
235
|
+
exports.PendingInstallations = PendingInstallations;
|
|
236
|
+
//# sourceMappingURL=pending-installations.js.map
|
|
237
|
+
//# sourceMappingURL=pending-installations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/pending-installations.tsx"],"names":["jsxs","jsx","useState","useEffect"],"mappings":"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","file":"pending-installations.js","sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport type { PendingInstallation, FetchPendingInstallationsResult } from \"../actions/install\";\n\nexport interface PendingInstallationsProps {\n fetchPendingInstallationsAction: () => Promise<FetchPendingInstallationsResult>;\n initialInstallations?: PendingInstallation[];\n pollIntervalMs?: number;\n}\n\nconst ClockIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"h-6 w-6\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <polyline points=\"12 6 12 12 16 14\" />\n </svg>\n);\n\nconst TrashIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"h-5 w-5\"\n >\n <path d=\"M3 6h18\" />\n <path d=\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\" />\n <path d=\"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\" />\n </svg>\n);\n\nconst ChevronRightIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"h-4 w-4\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n);\n\nconst ArrowRightIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"h-4 w-4\"\n >\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n <polyline points=\"12 5 19 12 12 19\" />\n </svg>\n);\n\nconst formatTimeAgo = (dateString: string): string => {\n try {\n const date = new Date(dateString);\n const now = new Date();\n const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);\n\n if (seconds < 60) return \"just now\";\n if (seconds < 3600) {\n const minutes = Math.floor(seconds / 60);\n return `${minutes} ${minutes === 1 ? \"minute\" : \"minutes\"} ago`;\n }\n if (seconds < 86400) {\n const hours = Math.floor(seconds / 3600);\n return `${hours === 1 ? \"an hour\" : `${hours} hours`} ago`;\n }\n const days = Math.floor(seconds / 86400);\n return `${days} ${days === 1 ? \"day\" : \"days\"} ago`;\n } catch {\n return dateString;\n }\n};\n\nexport const PendingInstallations = ({\n fetchPendingInstallationsAction,\n initialInstallations = [],\n pollIntervalMs = 5000\n}: PendingInstallationsProps) => {\n const [installations, setInstallations] = useState<PendingInstallation[]>(initialInstallations);\n const [showAll, setShowAll] = useState(false);\n\n useEffect(() => {\n const fetchInstallations = async () => {\n try {\n const result = await fetchPendingInstallationsAction();\n setInstallations(result.installations);\n } catch (error) {\n console.error(\"[pending-installations] Failed to fetch pending installations\", error);\n }\n };\n\n // Fetch immediately\n fetchInstallations();\n\n // Set up polling interval (skip if pollIntervalMs is 0 or falsy)\n if (!pollIntervalMs) {\n return;\n }\n const intervalId = setInterval(fetchInstallations, pollIntervalMs);\n\n // Cleanup on unmount\n return () => clearInterval(intervalId);\n }, [fetchPendingInstallationsAction, pollIntervalMs]);\n\n // Don't render if no pending installations\n if (installations.length === 0) {\n return null;\n }\n\n const firstInstallation = installations[0]!;\n const remainingCount = installations.length - 1;\n\n return (\n <div className=\"mb-6 rounded-xl border border-orange-200 bg-orange-50 p-6\">\n <div className=\"flex items-start gap-4\">\n <div className=\"flex-shrink-0 text-orange-600\">\n <ClockIcon />\n </div>\n <div className=\"flex-1 space-y-3\">\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"flex-1\">\n <h3 className=\"text-base font-semibold text-gray-900\">\n Pending installation: {firstInstallation.name} •{\" \"}\n {firstInstallation.method === \"helm\" ? \"Helm\" : \"Linux\"} installation\n </h3>\n <p className=\"mt-1 text-sm text-gray-600\">\n Started {formatTimeAgo(firstInstallation.startedAt)} by {firstInstallation.startedBy}\n </p>\n {remainingCount > 0 && (\n <button\n type=\"button\"\n onClick={() => setShowAll(!showAll)}\n className=\"mt-2 flex items-center gap-1 text-sm font-medium text-gray-700 hover:text-gray-900\"\n >\n View {remainingCount} more pending installation{remainingCount !== 1 ? \"s\" : \"\"}\n <ChevronRightIcon />\n </button>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n className=\"rounded-lg p-2 text-red-600 transition hover:bg-red-100\"\n aria-label=\"Delete installation\"\n >\n <TrashIcon />\n </button>\n <a\n href={`/install?installOptionsId=${firstInstallation.id}&type=${firstInstallation.method}&step=2`}\n className=\"inline-flex items-center gap-2 rounded-lg bg-orange-200 px-4 py-2 text-sm font-semibold text-gray-900 transition hover:bg-orange-300\"\n >\n Continue installation\n <ArrowRightIcon />\n </a>\n </div>\n </div>\n\n {showAll && remainingCount > 0 && (\n <div className=\"mt-4 space-y-2 border-t border-orange-200 pt-4\">\n {installations.slice(1).map((installation) => (\n <div\n key={installation.id}\n className=\"flex items-center justify-between rounded-lg bg-white p-3\"\n >\n <div>\n <h4 className=\"text-sm font-medium text-gray-900\">\n {installation.name} •{\" \"}\n {installation.method === \"helm\" ? \"Helm\" : \"Linux\"} installation\n </h4>\n <p className=\"mt-0.5 text-xs text-gray-600\">\n Started {formatTimeAgo(installation.startedAt)} by {installation.startedBy}\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n className=\"rounded-lg p-2 text-red-600 transition hover:bg-red-100\"\n aria-label=\"Delete installation\"\n >\n <TrashIcon />\n </button>\n <a\n href={`/install?installOptionsId=${installation.id}&type=${installation.method}&step=2`}\n className=\"inline-flex items-center gap-2 rounded-lg bg-orange-200 px-3 py-1.5 text-xs font-semibold text-gray-900 transition hover:bg-orange-300\"\n >\n Continue\n <ArrowRightIcon />\n </a>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n};\n\nPendingInstallations.displayName = \"PendingInstallations\";\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface ReleaseNotesSection {
|
|
4
|
+
title: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
items?: string[];
|
|
7
|
+
}
|
|
8
|
+
interface ReleaseEntry {
|
|
9
|
+
version: string;
|
|
10
|
+
channel: string;
|
|
11
|
+
releasedAt?: string;
|
|
12
|
+
sections: ReleaseNotesSection[];
|
|
13
|
+
}
|
|
14
|
+
interface ReleaseHistoryPanelProps {
|
|
15
|
+
releases: ReleaseEntry[];
|
|
16
|
+
}
|
|
17
|
+
declare const ReleaseHistoryPanel: {
|
|
18
|
+
({ releases }: ReleaseHistoryPanelProps): react_jsx_runtime.JSX.Element;
|
|
19
|
+
displayName: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { type ReleaseEntry, ReleaseHistoryPanel, type ReleaseNotesSection };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface ReleaseNotesSection {
|
|
4
|
+
title: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
items?: string[];
|
|
7
|
+
}
|
|
8
|
+
interface ReleaseEntry {
|
|
9
|
+
version: string;
|
|
10
|
+
channel: string;
|
|
11
|
+
releasedAt?: string;
|
|
12
|
+
sections: ReleaseNotesSection[];
|
|
13
|
+
}
|
|
14
|
+
interface ReleaseHistoryPanelProps {
|
|
15
|
+
releases: ReleaseEntry[];
|
|
16
|
+
}
|
|
17
|
+
declare const ReleaseHistoryPanel: {
|
|
18
|
+
({ releases }: ReleaseHistoryPanelProps): react_jsx_runtime.JSX.Element;
|
|
19
|
+
displayName: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { type ReleaseEntry, ReleaseHistoryPanel, type ReleaseNotesSection };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Enterprise Portal Components
|
|
8
|
+
* This file is generated by tsup. Do not edit manually.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
var ReleaseNotesCard = ({
|
|
12
|
+
title,
|
|
13
|
+
description,
|
|
14
|
+
items
|
|
15
|
+
}) => /* @__PURE__ */ jsxRuntime.jsxs("article", { className: "rounded-2xl border border-gray-100 bg-white p-6 shadow-sm", children: [
|
|
16
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { children: [
|
|
17
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-gray-900", children: title }),
|
|
18
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-gray-600", children: description }) : null
|
|
19
|
+
] }),
|
|
20
|
+
items?.length ? /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-4 list-disc space-y-2 pl-5 text-sm text-gray-700", children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: item }, item)) }) : null
|
|
21
|
+
] });
|
|
22
|
+
ReleaseNotesCard.displayName = "ReleaseNotesCard";
|
|
23
|
+
var listButtonClass = "flex w-full items-center justify-between rounded-xl px-4 py-3 text-left text-sm transition";
|
|
24
|
+
var ReleaseHistoryPanel = ({ releases }) => {
|
|
25
|
+
const [selectedIndex, setSelectedIndex] = react.useState(0);
|
|
26
|
+
react.useEffect(() => {
|
|
27
|
+
if (selectedIndex > releases.length - 1) {
|
|
28
|
+
setSelectedIndex(0);
|
|
29
|
+
}
|
|
30
|
+
}, [releases, selectedIndex]);
|
|
31
|
+
const activeRelease = releases[selectedIndex] ?? releases[0];
|
|
32
|
+
if (!releases.length) {
|
|
33
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-3xl border border-gray-100 bg-white p-8 text-center text-sm text-gray-500 shadow-[0_12px_30px_rgba(17,24,39,0.12)]", children: "No releases have been published yet." });
|
|
34
|
+
}
|
|
35
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6 lg:flex-row", children: [
|
|
36
|
+
/* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "lg:w-64", children: [
|
|
37
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-semibold uppercase tracking-wide text-gray-500", children: "Version History" }),
|
|
38
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 space-y-2", children: releases.map((release, index) => {
|
|
39
|
+
const isActive = index === selectedIndex;
|
|
40
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
41
|
+
"button",
|
|
42
|
+
{
|
|
43
|
+
type: "button",
|
|
44
|
+
onClick: () => setSelectedIndex(index),
|
|
45
|
+
className: `${listButtonClass} ${isActive ? "bg-indigo-100 text-indigo-600" : "text-gray-600 hover:bg-gray-50"}`,
|
|
46
|
+
children: [
|
|
47
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
|
|
48
|
+
"Version ",
|
|
49
|
+
release.version
|
|
50
|
+
] }),
|
|
51
|
+
release.releasedAt ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-400", children: new Date(release.releasedAt).toLocaleDateString() }) : null
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
`${release.version}-${index}`
|
|
55
|
+
);
|
|
56
|
+
}) })
|
|
57
|
+
] }),
|
|
58
|
+
/* @__PURE__ */ jsxRuntime.jsx("section", { className: "flex-1 space-y-6", children: activeRelease ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
59
|
+
"div",
|
|
60
|
+
{
|
|
61
|
+
className: "rounded-3xl border border-gray-100 bg-white p-8 shadow-[0_12px_30px_rgba(17,24,39,0.12)]",
|
|
62
|
+
children: [
|
|
63
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "space-y-1", children: [
|
|
64
|
+
/* @__PURE__ */ jsxRuntime.jsxs("h3", { className: "text-xl font-semibold text-gray-900", children: [
|
|
65
|
+
activeRelease.channel,
|
|
66
|
+
" ",
|
|
67
|
+
activeRelease.version
|
|
68
|
+
] }),
|
|
69
|
+
activeRelease.releasedAt ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-gray-500", children: [
|
|
70
|
+
new Date(activeRelease.releasedAt).toLocaleString("en-US", {
|
|
71
|
+
timeZone: "UTC",
|
|
72
|
+
year: "numeric",
|
|
73
|
+
month: "2-digit",
|
|
74
|
+
day: "2-digit",
|
|
75
|
+
hour: "2-digit",
|
|
76
|
+
minute: "2-digit",
|
|
77
|
+
second: "2-digit",
|
|
78
|
+
hour12: false
|
|
79
|
+
}),
|
|
80
|
+
" UTC"
|
|
81
|
+
] }) : null
|
|
82
|
+
] }),
|
|
83
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-6 space-y-6", children: activeRelease.sections.map((section) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
84
|
+
ReleaseNotesCard,
|
|
85
|
+
{
|
|
86
|
+
title: section.title,
|
|
87
|
+
description: section.description,
|
|
88
|
+
items: section.items
|
|
89
|
+
},
|
|
90
|
+
`${activeRelease.version}-${selectedIndex}-${section.title}`
|
|
91
|
+
)) })
|
|
92
|
+
]
|
|
93
|
+
},
|
|
94
|
+
`${activeRelease.version}-${selectedIndex}-${activeRelease.channel}`
|
|
95
|
+
) : null })
|
|
96
|
+
] });
|
|
97
|
+
};
|
|
98
|
+
ReleaseHistoryPanel.displayName = "ReleaseHistoryPanel";
|
|
99
|
+
|
|
100
|
+
exports.ReleaseHistoryPanel = ReleaseHistoryPanel;
|
|
101
|
+
//# sourceMappingURL=release-history-panel.js.map
|
|
102
|
+
//# sourceMappingURL=release-history-panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/release-notes-card.tsx","../src/components/release-history-panel.tsx"],"names":["jsxs","jsx","useState","useEffect"],"mappings":"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","file":"release-history-panel.js","sourcesContent":["\"use client\";\n\ninterface ReleaseNotesCardProps {\n title: string;\n description?: string;\n items?: string[];\n}\n\nexport const ReleaseNotesCard = ({\n title,\n description,\n items\n}: ReleaseNotesCardProps) => (\n <article className=\"rounded-2xl border border-gray-100 bg-white p-6 shadow-sm\">\n <header>\n <h3 className=\"text-lg font-semibold text-gray-900\">{title}</h3>\n {description ? (\n <p className=\"mt-2 text-sm text-gray-600\">{description}</p>\n ) : null}\n </header>\n {items?.length ? (\n <ul className=\"mt-4 list-disc space-y-2 pl-5 text-sm text-gray-700\">\n {items.map((item) => (\n <li key={item}>{item}</li>\n ))}\n </ul>\n ) : null}\n </article>\n);\n\nReleaseNotesCard.displayName = \"ReleaseNotesCard\";\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { ReleaseNotesCard } from \"./release-notes-card\";\n\nexport interface ReleaseNotesSection {\n title: string;\n description?: string;\n items?: string[];\n}\n\nexport interface ReleaseEntry {\n version: string;\n channel: string;\n releasedAt?: string;\n sections: ReleaseNotesSection[];\n}\n\ninterface ReleaseHistoryPanelProps {\n releases: ReleaseEntry[];\n}\n\nconst listButtonClass =\n \"flex w-full items-center justify-between rounded-xl px-4 py-3 text-left text-sm transition\";\n\nexport const ReleaseHistoryPanel = ({ releases }: ReleaseHistoryPanelProps) => {\n const [selectedIndex, setSelectedIndex] = useState(0);\n\n useEffect(() => {\n if (selectedIndex > releases.length - 1) {\n setSelectedIndex(0);\n }\n }, [releases, selectedIndex]);\n\n const activeRelease = releases[selectedIndex] ?? releases[0];\n\n if (!releases.length) {\n return (\n <div className=\"rounded-3xl border border-gray-100 bg-white p-8 text-center text-sm text-gray-500 shadow-[0_12px_30px_rgba(17,24,39,0.12)]\">\n No releases have been published yet.\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-6 lg:flex-row\">\n <nav className=\"lg:w-64\">\n <h2 className=\"text-sm font-semibold uppercase tracking-wide text-gray-500\">\n Version History\n </h2>\n <div className=\"mt-4 space-y-2\">\n {releases.map((release, index) => {\n const isActive = index === selectedIndex;\n return (\n <button\n key={`${release.version}-${index}`}\n type=\"button\"\n onClick={() => setSelectedIndex(index)}\n className={`${listButtonClass} ${\n isActive\n ? \"bg-indigo-100 text-indigo-600\"\n : \"text-gray-600 hover:bg-gray-50\"\n }`}\n >\n <span className=\"font-medium\">Version {release.version}</span>\n {release.releasedAt ? (\n <span className=\"text-xs text-gray-400\">\n {new Date(release.releasedAt).toLocaleDateString()}\n </span>\n ) : null}\n </button>\n );\n })}\n </div>\n </nav>\n <section className=\"flex-1 space-y-6\">\n {activeRelease ? (\n <div\n key={`${activeRelease.version}-${selectedIndex}-${activeRelease.channel}`}\n className=\"rounded-3xl border border-gray-100 bg-white p-8 shadow-[0_12px_30px_rgba(17,24,39,0.12)]\"\n >\n <header className=\"space-y-1\">\n <h3 className=\"text-xl font-semibold text-gray-900\">\n {activeRelease.channel} {activeRelease.version}\n </h3>\n {activeRelease.releasedAt ? (\n <p className=\"text-sm text-gray-500\">\n {new Date(activeRelease.releasedAt).toLocaleString(\"en-US\", {\n timeZone: \"UTC\",\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hour12: false\n })} UTC\n </p>\n ) : null}\n </header>\n <div className=\"mt-6 space-y-6\">\n {activeRelease.sections.map((section) => (\n <ReleaseNotesCard\n key={`${activeRelease.version}-${selectedIndex}-${section.title}`}\n title={section.title}\n description={section.description}\n items={section.items}\n />\n ))}\n </div>\n </div>\n ) : null}\n </section>\n </div>\n );\n};\n\nReleaseHistoryPanel.displayName = \"ReleaseHistoryPanel\";\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface ReleaseNotesCardProps {
|
|
4
|
+
title: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
items?: string[];
|
|
7
|
+
}
|
|
8
|
+
declare const ReleaseNotesCard: {
|
|
9
|
+
({ title, description, items }: ReleaseNotesCardProps): react_jsx_runtime.JSX.Element;
|
|
10
|
+
displayName: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { ReleaseNotesCard };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface ReleaseNotesCardProps {
|
|
4
|
+
title: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
items?: string[];
|
|
7
|
+
}
|
|
8
|
+
declare const ReleaseNotesCard: {
|
|
9
|
+
({ title, description, items }: ReleaseNotesCardProps): react_jsx_runtime.JSX.Element;
|
|
10
|
+
displayName: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { ReleaseNotesCard };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Enterprise Portal Components
|
|
7
|
+
* This file is generated by tsup. Do not edit manually.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var ReleaseNotesCard = ({
|
|
11
|
+
title,
|
|
12
|
+
description,
|
|
13
|
+
items
|
|
14
|
+
}) => /* @__PURE__ */ jsxRuntime.jsxs("article", { className: "rounded-2xl border border-gray-100 bg-white p-6 shadow-sm", children: [
|
|
15
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { children: [
|
|
16
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-gray-900", children: title }),
|
|
17
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-gray-600", children: description }) : null
|
|
18
|
+
] }),
|
|
19
|
+
items?.length ? /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-4 list-disc space-y-2 pl-5 text-sm text-gray-700", children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: item }, item)) }) : null
|
|
20
|
+
] });
|
|
21
|
+
ReleaseNotesCard.displayName = "ReleaseNotesCard";
|
|
22
|
+
|
|
23
|
+
exports.ReleaseNotesCard = ReleaseNotesCard;
|
|
24
|
+
//# sourceMappingURL=release-notes-card.js.map
|
|
25
|
+
//# sourceMappingURL=release-notes-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/release-notes-card.tsx"],"names":["jsxs","jsx"],"mappings":";;;;;;;;;AAQO,IAAM,mBAAmB,CAAC;AAAA,EAC/B,KAAA;AAAA,EACA,WAAA;AAAA,EACA;AACF,CAAA,qBACEA,eAAA,CAAC,SAAA,EAAA,EAAQ,SAAA,EAAU,2DAAA,EACjB,QAAA,EAAA;AAAA,kBAAAA,eAAA,CAAC,QAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,qCAAA,EAAuC,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,IAC1D,8BACCA,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,4BAAA,EAA8B,uBAAY,CAAA,GACrD;AAAA,GAAA,EACN,CAAA;AAAA,EACC,OAAO,MAAA,mBACNA,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,uDACX,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,oCACT,IAAA,EAAA,EAAe,QAAA,EAAA,IAAA,EAAA,EAAP,IAAY,CACtB,GACH,CAAA,GACE;AAAA,CAAA,EACN;AAGF,gBAAA,CAAiB,WAAA,GAAc,kBAAA","file":"release-notes-card.js","sourcesContent":["\"use client\";\n\ninterface ReleaseNotesCardProps {\n title: string;\n description?: string;\n items?: string[];\n}\n\nexport const ReleaseNotesCard = ({\n title,\n description,\n items\n}: ReleaseNotesCardProps) => (\n <article className=\"rounded-2xl border border-gray-100 bg-white p-6 shadow-sm\">\n <header>\n <h3 className=\"text-lg font-semibold text-gray-900\">{title}</h3>\n {description ? (\n <p className=\"mt-2 text-sm text-gray-600\">{description}</p>\n ) : null}\n </header>\n {items?.length ? (\n <ul className=\"mt-4 list-disc space-y-2 pl-5 text-sm text-gray-700\">\n {items.map((item) => (\n <li key={item}>{item}</li>\n ))}\n </ul>\n ) : null}\n </article>\n);\n\nReleaseNotesCard.displayName = \"ReleaseNotesCard\";\n"]}
|