From 9bade255a218227b587e7196ee931adc040c3331 Mon Sep 17 00:00:00 2001 From: Celia Amador Date: Mon, 20 Apr 2026 10:28:10 +0200 Subject: [PATCH 1/2] EDM-3512: Display cli artifacts by tool --- libs/i18n/locales/en/translation.json | 8 +- .../Masthead/CommandLineToolsPage.tsx | 102 +++++++++++++----- libs/ui-components/src/types/extraTypes.ts | 6 ++ 3 files changed, 87 insertions(+), 29 deletions(-) diff --git a/libs/i18n/locales/en/translation.json b/libs/i18n/locales/en/translation.json index 9c158f3db..d0d8ad0c1 100644 --- a/libs/i18n/locales/en/translation.json +++ b/libs/i18n/locales/en/translation.json @@ -1272,12 +1272,16 @@ "Never share your service account token. It provides full access to your Kubernetes cluster resources.": "Never share your service account token. It provides full access to your Kubernetes cluster resources.", "Authenticating...": "Authenticating...", "Login": "Login", + "Download for {{ os }} for {{ arch }}": "Download for {{ os }} for {{ arch }}", "No {{ productName }} command line tools were found for this deployment at this time.": "No {{ productName }} command line tools were found for this deployment at this time.", "Could not list the {{ productName }} command line tools": "Could not list the {{ productName }} command line tools", - "Download flightctl CLI for {{ os }} for {{ arch }}": "Download flightctl CLI for {{ os }} for {{ arch }}", + "flightctl Command Line Interface (CLI)": "flightctl Command Line Interface (CLI)", + "Use the flightctl CLI to manage your edge resources, such as devices and fleets, from a terminal.": "Use the flightctl CLI to manage your edge resources, such as devices and fleets, from a terminal.", + "flightctl-restore Command Line Interface (CLI)": "flightctl-restore Command Line Interface (CLI)", + "Use the flightctl-restore CLI to prepare devices after restoring the system from a backup.": "Use the flightctl-restore CLI to prepare devices after restoring the system from a backup.", "Red Hat Edge Manager": "Red Hat Edge Manager", "Flight Control": "Flight Control", - "With the {{ productName }} command line interface, you can manage your fleets, devices and repositories from a terminal.": "With the {{ productName }} command line interface, you can manage your fleets, devices and repositories from a terminal.", + "With the {{ productName }} command line interface tools, you can manage your fleets, devices and repositories from a terminal.": "With the {{ productName }} command line interface tools, you can manage your fleets, devices and repositories from a terminal.", "Command line tools are not available for download in this {{ productName }} installation.": "Command line tools are not available for download in this {{ productName }} installation.", "System default": "System default", "Light": "Light", diff --git a/libs/ui-components/src/components/Masthead/CommandLineToolsPage.tsx b/libs/ui-components/src/components/Masthead/CommandLineToolsPage.tsx index 981ce9f39..550c2d91c 100644 --- a/libs/ui-components/src/components/Masthead/CommandLineToolsPage.tsx +++ b/libs/ui-components/src/components/Masthead/CommandLineToolsPage.tsx @@ -16,7 +16,7 @@ import ExternalLinkAltIcon from '@patternfly/react-icons/dist/js/icons/external- import { useTranslation } from '../../hooks/useTranslation'; import { useAppContext } from '../../hooks/useAppContext'; import { getErrorMessage } from '../../utils/error'; -import { CliArtifactsResponse } from '../../types/extraTypes'; +import { CliArtifactTool, CliArtifactsResponse } from '../../types/extraTypes'; type CommandLineToolsContentProps = { productName: string; @@ -32,6 +32,47 @@ const getArtifactUrl = (baseUrl: string, artifact: CommandLineArtifact) => { return `${normalizedBaseUrl}/${artifact.arch}/${artifact.os}/${artifact.filename}`; }; +const ArtifactDownloadList = ({ baseUrl, items }: { baseUrl: string; items: CommandLineArtifact[] }) => { + const { t } = useTranslation(); + return ( + + {items.map((cliArtifact) => { + const linkText = t('Download for {{ os }} for {{ arch }}', { + os: cliArtifact.os, + arch: cliArtifact.arch, + }); + return ( + + + + ); + })} + + ); +}; + +const getArtifactTool = (artifact: CommandLineArtifact) => { + if (!artifact.tool) { + // Handle backward compatibility with older artifacts before "tool" was added + return artifact.filename.includes('flightctl-restore') + ? CliArtifactTool.FlightctlRestore + : CliArtifactTool.Flightctl; + } + return artifact.tool; +}; + const CommandLineToolsContent = ({ productName, loading, @@ -65,32 +106,39 @@ const CommandLineToolsContent = ({ ); } + const baseUrl = artifactsResponse?.baseUrl || ''; + const mainCliArtifacts = cliArtifacts.filter((a) => getArtifactTool(a) === CliArtifactTool.Flightctl); + const restoreCliArtifacts = cliArtifacts.filter((a) => getArtifactTool(a) === CliArtifactTool.FlightctlRestore); + return ( - - {cliArtifacts.map((cliArtifact) => { - const linkText = t('Download flightctl CLI for {{ os }} for {{ arch }}', { - os: cliArtifact.os, - arch: cliArtifact.arch, - }); - return ( - - - - ); - })} - + + {mainCliArtifacts.length > 0 ? ( + <> + + {t('flightctl Command Line Interface (CLI)')} + + + {t('Use the flightctl CLI to manage your edge resources, such as devices and fleets, from a terminal.')} + + + + + + ) : null} + {restoreCliArtifacts.length > 0 ? ( + <> + + {t('flightctl-restore Command Line Interface (CLI)')} + + + {t('Use the flightctl-restore CLI to prepare devices after restoring the system from a backup.')} + + + + + + ) : null} + ); }; @@ -141,7 +189,7 @@ const CommandLineToolsPage = () => { {t( - 'With the {{ productName }} command line interface, you can manage your fleets, devices and repositories from a terminal.', + 'With the {{ productName }} command line interface tools, you can manage your fleets, devices and repositories from a terminal.', { productName, }, diff --git a/libs/ui-components/src/types/extraTypes.ts b/libs/ui-components/src/types/extraTypes.ts index 5cb87d862..b22940543 100644 --- a/libs/ui-components/src/types/extraTypes.ts +++ b/libs/ui-components/src/types/extraTypes.ts @@ -55,11 +55,17 @@ export const isFleet = (resource: ResourceSync | Fleet): resource is Fleet => re // We use the fixed type to get proper Typescript checks for the field export type InlineApplicationFileFixed = FileContent & RelativePath; +export enum CliArtifactTool { + Flightctl = 'flightctl', + FlightctlRestore = 'flightctl-restore', +} + type CliArtifact = { os: string; arch: string; filename: string; sha256: string; + tool?: CliArtifactTool; }; export type CliArtifactsResponse = { From 2453a62a97cf830fb960990de2b3a80008df36f2 Mon Sep 17 00:00:00 2001 From: Celia Amador Date: Thu, 30 Apr 2026 14:54:07 +0200 Subject: [PATCH 2/2] EDM-3512: Unify displaying the CLI tools with OCP console --- libs/i18n/locales/en/translation.json | 9 +- .../Masthead/CommandLineToolsPage.tsx | 101 ++++-------------- .../src/hooks/useCliArtifacts.ts | 68 ++++++++++++ libs/ui-components/src/types/extraTypes.ts | 6 +- libs/ui-components/src/utils/cliArtifacts.ts | 67 ++++++++++++ 5 files changed, 166 insertions(+), 85 deletions(-) create mode 100644 libs/ui-components/src/hooks/useCliArtifacts.ts create mode 100644 libs/ui-components/src/utils/cliArtifacts.ts diff --git a/libs/i18n/locales/en/translation.json b/libs/i18n/locales/en/translation.json index d0d8ad0c1..86eb9120e 100644 --- a/libs/i18n/locales/en/translation.json +++ b/libs/i18n/locales/en/translation.json @@ -1272,16 +1272,14 @@ "Never share your service account token. It provides full access to your Kubernetes cluster resources.": "Never share your service account token. It provides full access to your Kubernetes cluster resources.", "Authenticating...": "Authenticating...", "Login": "Login", - "Download for {{ os }} for {{ arch }}": "Download for {{ os }} for {{ arch }}", "No {{ productName }} command line tools were found for this deployment at this time.": "No {{ productName }} command line tools were found for this deployment at this time.", "Could not list the {{ productName }} command line tools": "Could not list the {{ productName }} command line tools", "flightctl Command Line Interface (CLI)": "flightctl Command Line Interface (CLI)", - "Use the flightctl CLI to manage your edge resources, such as devices and fleets, from a terminal.": "Use the flightctl CLI to manage your edge resources, such as devices and fleets, from a terminal.", + "flightctl is the command-line interface for managing {{ productName }} fleets, devices, and workloads.": "flightctl is the command-line interface for managing {{ productName }} fleets, devices, and workloads.", "flightctl-restore Command Line Interface (CLI)": "flightctl-restore Command Line Interface (CLI)", - "Use the flightctl-restore CLI to prepare devices after restoring the system from a backup.": "Use the flightctl-restore CLI to prepare devices after restoring the system from a backup.", + "flightctl-restore prepares devices after database restoration. Use when restoring {{ productName }} from backup.": "flightctl-restore prepares devices after database restoration. Use when restoring {{ productName }} from backup.", "Red Hat Edge Manager": "Red Hat Edge Manager", "Flight Control": "Flight Control", - "With the {{ productName }} command line interface tools, you can manage your fleets, devices and repositories from a terminal.": "With the {{ productName }} command line interface tools, you can manage your fleets, devices and repositories from a terminal.", "Command line tools are not available for download in this {{ productName }} installation.": "Command line tools are not available for download in this {{ productName }} installation.", "System default": "System default", "Light": "Light", @@ -1559,6 +1557,9 @@ "OpenShift": "OpenShift", "Kubernetes": "Kubernetes", "Ansible Automation Platform": "Ansible Automation Platform", + "Download flightctl for Mac ({{ arch }})": "Download flightctl for Mac ({{ arch }})", + "Download flightctl for Linux ({{ arch }})": "Download flightctl for Linux ({{ arch }})", + "Download flightctl for Windows ({{ arch }})": "Download flightctl for Windows ({{ arch }})", "{{count}} years ago_one": "{{count}} year ago", "{{count}} years ago_other": "{{count}} years ago", "{{count}} months ago_one": "{{count}} month ago", diff --git a/libs/ui-components/src/components/Masthead/CommandLineToolsPage.tsx b/libs/ui-components/src/components/Masthead/CommandLineToolsPage.tsx index 550c2d91c..a314c7b91 100644 --- a/libs/ui-components/src/components/Masthead/CommandLineToolsPage.tsx +++ b/libs/ui-components/src/components/Masthead/CommandLineToolsPage.tsx @@ -15,32 +15,23 @@ import ExternalLinkAltIcon from '@patternfly/react-icons/dist/js/icons/external- import { useTranslation } from '../../hooks/useTranslation'; import { useAppContext } from '../../hooks/useAppContext'; -import { getErrorMessage } from '../../utils/error'; -import { CliArtifactTool, CliArtifactsResponse } from '../../types/extraTypes'; +import { CliArtifactsDisplayResponse, useCliArtifacts } from '../../hooks/useCliArtifacts'; +import { CliArtifact } from '../../types/extraTypes'; +import { getArtifactDownloadLabel, getArtifactUrl } from '../../utils/cliArtifacts'; type CommandLineToolsContentProps = { productName: string; loading: boolean; loadError?: string; - artifactsResponse?: CliArtifactsResponse; + artifactsResponse?: CliArtifactsDisplayResponse; }; -type CommandLineArtifact = CliArtifactsResponse['artifacts'][0]; - -const getArtifactUrl = (baseUrl: string, artifact: CommandLineArtifact) => { - const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl; - return `${normalizedBaseUrl}/${artifact.arch}/${artifact.os}/${artifact.filename}`; -}; - -const ArtifactDownloadList = ({ baseUrl, items }: { baseUrl: string; items: CommandLineArtifact[] }) => { +const ArtifactDownloadList = ({ baseUrl, items }: { baseUrl: string; items: CliArtifact[] }) => { const { t } = useTranslation(); return ( {items.map((cliArtifact) => { - const linkText = t('Download for {{ os }} for {{ arch }}', { - os: cliArtifact.os, - arch: cliArtifact.arch, - }); + const linkText = getArtifactDownloadLabel(cliArtifact, t); return (