Skip to content

Commit

Permalink
frontend: Add new CR instances view
Browse files Browse the repository at this point in the history
These changes add a new view to show all instances for Custom Resources,
even if the user doesn't have the the role to list CRDs for all
namespaces.

The majority of this patch is based on work by Guilhane
<guilhane.bourgoin@orange.com>.

fixes: #1962

Co-authored-by: guilhane <guilhane.bourgoin@orange.com>
Co-authored-by: Oleksandr Dubenko <oldubenko@microsoft.com>

Signed-off-by: guilhane <guilhane.bourgoin@orange.com>
Signed-off-by: Joaquim Rocha <joaquim.rocha@microsoft.com>
  • Loading branch information
joaquimrocha committed Oct 2, 2024
1 parent 9b6968a commit f374e6c
Show file tree
Hide file tree
Showing 13 changed files with 218 additions and 5 deletions.
6 changes: 5 additions & 1 deletion app/electron/locales/de/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@
"Start Speaking": "Sprechen starten",
"Stop Speaking": "Sprechen stoppen",
"View": "Ansicht",
"Reload": "Neu laden",
"Toggle Developer Tools": "Entwicklertools umschalten",
"Reset Zoom": "Zoom zurücksetzen",
"Zoom In": "Vergrößern",
"Zoom Out": "Verkleinern",
"Toggle Fullscreen": "Vollbild umschalten",
"Navigate": "",
"Reload": "Neu laden",
"Go to Home": "",
"Go Back": "",
"Go Forward": "",
"Window": "Fenster",
"Minimize": "Minimieren",
"Bring All to Front": "Alle nach vorne bringen",
Expand Down
6 changes: 5 additions & 1 deletion app/electron/locales/en/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@
"Start Speaking": "Start Speaking",
"Stop Speaking": "Stop Speaking",
"View": "View",
"Reload": "Reload",
"Toggle Developer Tools": "Toggle Developer Tools",
"Reset Zoom": "Reset Zoom",
"Zoom In": "Zoom In",
"Zoom Out": "Zoom Out",
"Toggle Fullscreen": "Toggle Fullscreen",
"Navigate": "",
"Reload": "Reload",
"Go to Home": "",
"Go Back": "",
"Go Forward": "",
"Window": "Window",
"Minimize": "Minimize",
"Bring All to Front": "Bring All to Front",
Expand Down
6 changes: 5 additions & 1 deletion app/electron/locales/es/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@
"Start Speaking": "Iniciar locución",
"Stop Speaking": "Parar locución",
"View": "Ver",
"Reload": "Recargar",
"Toggle Developer Tools": "Alternar Herr. Desarrollo",
"Reset Zoom": "Tamaño real",
"Zoom In": "Ampliar",
"Zoom Out": "Reducir",
"Toggle Fullscreen": "Alternar pantalla completa",
"Navigate": "",
"Reload": "Recargar",
"Go to Home": "",
"Go Back": "",
"Go Forward": "",
"Window": "Ventana",
"Minimize": "Minimizar",
"Bring All to Front": "Traer todo al frente",
Expand Down
6 changes: 5 additions & 1 deletion app/electron/locales/fr/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@
"Start Speaking": "Commencer à parler",
"Stop Speaking": "Arrêter de parler",
"View": "Vue",
"Reload": "Recharger",
"Toggle Developer Tools": "Basculer les outils de développement",
"Reset Zoom": "Réinitialiser le zoom",
"Zoom In": "Zoomer",
"Zoom Out": "Dézoomer",
"Toggle Fullscreen": "Basculer en plein écran",
"Navigate": "",
"Reload": "Recharger",
"Go to Home": "",
"Go Back": "",
"Go Forward": "",
"Window": "Fenêtre",
"Minimize": "Minimiser",
"Bring All to Front": "Tout ramener au premier plan",
Expand Down
6 changes: 5 additions & 1 deletion app/electron/locales/pt/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@
"Start Speaking": "Iniciar fala",
"Stop Speaking": "Para fala",
"View": "Ver",
"Reload": "Recarregar",
"Toggle Developer Tools": "Alternar ferr. desenv.",
"Reset Zoom": "Tamanho real",
"Zoom In": "Ampliar",
"Zoom Out": "Reduzir",
"Toggle Fullscreen": "Alternar ecrã completo",
"Navigate": "",
"Reload": "Recarregar",
"Go to Home": "",
"Go Back": "",
"Go Forward": "",
"Window": "Janela",
"Minimize": "Minimizar",
"Bring All to Front": "Passar tudo para a frente",
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/components/Sidebar/prepareRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,12 @@ function prepareRoutes(
name: 'crds',
label: t('glossary|Custom Resources'),
icon: 'mdi:puzzle',
subList: [
{
name: 'crs',
label: t('translation|Instances'),
},
],
},
];

Expand Down
149 changes: 149 additions & 0 deletions frontend/src/components/crd/CustomResourceInstancesList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { Alert, AlertTitle } from '@mui/material';
import { useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { KubeObject } from '../../lib/k8s/cluster';
import CRD from '../../lib/k8s/crd';
import { Link, Loader, SectionBox, ShowHideLabel } from '../common/';
import Empty from '../common/EmptyContent';
import { ResourceListView } from '../common/Resource';

function CrInstancesView({ crds }: { crds: CRD[]; key: string }) {
const { t } = useTranslation(['glossary', 'translation']);

const crdInfo = useMemo(() => crds.map(crd => crd.makeCRClass()), [crds]);
const queries = crdInfo.map(cr => cr.useList());
const [isWarningClosed, setIsWarningClosed] = useState(false);

const { crInstancesList, getCRDForCR, isLoading, crdsFailedToLoad, allFailed } = useMemo(() => {
const isLoading = queries.some(it => it.isLoading || it.isFetching);

// Collect the names of CRD that failed to load lists
const crdsFailedToLoad: string[] = [];
queries.forEach((it, i) => {
if (it.isError) {
crdsFailedToLoad.push(crds[i].metadata.name);
}
});

// Create a map to be able to link to CRD by CR kind
const crKindToCRDMap = queries.reduce((acc, { items }, index) => {
if (items?.[0]) {
acc[items[0].kind] = crds[index];
}
return acc;
}, {} as Record<string, CRD>);
const getCRDForCR = (cr: KubeObject) => crKindToCRDMap[cr.kind];

return {
crInstancesList: queries.flatMap(it => it.items ?? []),
getCRDForCR,
isLoading,
crdsFailedToLoad,
allFailed: crdsFailedToLoad.length === queries.length,
};
}, queries);

if (isLoading) {
return <Loader title={t('translation|Loading custom resource instances')} />;
}

if (crInstancesList.length === 0) {
return <Empty>{t('translation|No custom resources instances found.')}</Empty>;
}

return (
<SectionBox backLink>
{crdsFailedToLoad.length > 0 && !allFailed && !isWarningClosed && (
<Alert
severity="warning"
variant="outlined"
onClose={() => setIsWarningClosed(true)}
sx={theme => ({ margin: theme.spacing(2, 2, 0, 2) })}
>
<AlertTitle>{t('translation|Failed to load custom resource instances')}</AlertTitle>
<ShowHideLabel>{crdsFailedToLoad.join(', ')}</ShowHideLabel>
</Alert>
)}
<ResourceListView
title="Custom Resource Instances"
headerProps={{
noNamespaceFilter: false,
}}
errorMessage={
allFailed ? t('translation|Failed to load custom resource instances') : undefined
}
data={crInstancesList}
columns={[
{
label: 'Instance name',
getValue: cr => {
return cr.metadata.name;
},
render: cr => {
return (
<Link
routeName="customresource"
params={{
crName: cr.metadata.name,
crd: getCRDForCR(cr).metadata.name,
namespace: cr.metadata.namespace ?? '-',
}}
>
{cr.metadata.name}
</Link>
);
},
},
{
label: 'CRD',
getValue: cr => {
return cr.kind;
},
render: cr => {
return (
<Link
routeName="crd"
params={{
name: getCRDForCR(cr).metadata.name,
}}
>
{cr.kind}
</Link>
);
},
},
{
label: 'Categories',
getValue: cr => {
const categories = getCRDForCR(cr).jsonData!.status.acceptedNames.categories;
return categories !== undefined ? categories.toString().split(',').join(', ') : '';
},
},
'namespace',
'age',
]}
/>
</SectionBox>
);
}

export function CrInstanceList() {
const { t } = useTranslation(['glossary', 'translation']);
const { items: crds, error: crdsError, isLoading: isLoadingCRDs } = CRD.useList();

if (crdsError) {
return (
<Empty color="error">
{t('translation|Error getting custom resource definitions: {{ errorMessage }}', {
errorMessage: crdsError,
})}
</Empty>
);
}

if (isLoadingCRDs || !crds) {
return <Loader title={t('translation|Loading custom resource definitions')} />;
}

return <CrInstancesView key={crds.map(it => it.metadata.name).join(',')} crds={crds} />;
}
6 changes: 6 additions & 0 deletions frontend/src/i18n/locales/de/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,11 @@
"Error getting custom resource definition {{ crdName }}: {{ errorMessage }}": "Fehler beim Abrufen der benutzerdefinierten Ressourcendefinition {{ crdName }}: {{ errorMessage }}",
"Loading custom resource details": "Laden von benutzerdefinierten Ressourcendetails",
"Error getting custom resource {{ crName }}: {{ errorMessage }}": "Fehler beim Abrufen der benutzerdefinierten Ressource {{ crName }}: {{ errorMessage }}",
"Loading custom resource instances": "",
"No custom resources instances found.": "",
"Failed to load custom resource instances": "",
"Error getting custom resource definitions: {{ errorMessage }}": "",
"Loading custom resource definitions": "",
"Loading custom resource definition": "Laden der Custom Resource Definition",
"No custom resources found": "Keine benutzerdefinierten Ressourcen gefunden",
"Loading resource definition details": "Lade Details zur Ressourcendefinition",
Expand Down Expand Up @@ -379,6 +384,7 @@
"Main Navigation": "Hauptnavigation",
"Navigation Tabs": "Navigationstabs",
"General": "",
"Instances": "",
"Collapse Sidebar": "Seitenleiste einklappen",
"Navigation": "Navigation",
"Cluster version upgraded to {{ gitVersion }}": "Cluster-Version auf {{ gitVersion }} aktualisiert",
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,11 @@
"Error getting custom resource definition {{ crdName }}: {{ errorMessage }}": "Error getting custom resource definition {{ crdName }}: {{ errorMessage }}",
"Loading custom resource details": "Loading custom resource details",
"Error getting custom resource {{ crName }}: {{ errorMessage }}": "Error getting custom resource {{ crName }}: {{ errorMessage }}",
"Loading custom resource instances": "Loading custom resource instances",
"No custom resources instances found.": "No custom resources instances found.",
"Failed to load custom resource instances": "Failed to load custom resource instances",
"Error getting custom resource definitions: {{ errorMessage }}": "Error getting custom resource definitions: {{ errorMessage }}",
"Loading custom resource definitions": "Loading custom resource definitions",
"Loading custom resource definition": "Loading custom resource definition",
"No custom resources found": "No custom resources found",
"Loading resource definition details": "Loading resource definition details",
Expand Down Expand Up @@ -379,6 +384,7 @@
"Main Navigation": "Main Navigation",
"Navigation Tabs": "Navigation Tabs",
"General": "General",
"Instances": "Instances",
"Collapse Sidebar": "Collapse Sidebar",
"Navigation": "Navigation",
"Cluster version upgraded to {{ gitVersion }}": "Cluster version upgraded to {{ gitVersion }}",
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/i18n/locales/es/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,11 @@
"Error getting custom resource definition {{ crdName }}: {{ errorMessage }}": "Error al obtener la definición de recurso personalizado {{ crdName }}: {{ errorMessage }}",
"Loading custom resource details": "Cargando detalles del recurso personalizado",
"Error getting custom resource {{ crName }}: {{ errorMessage }}": "Error al obtener recurso personalizado {{ crName }}: {{ errorMessage }}",
"Loading custom resource instances": "",
"No custom resources instances found.": "",
"Failed to load custom resource instances": "",
"Error getting custom resource definitions: {{ errorMessage }}": "",
"Loading custom resource definitions": "",
"Loading custom resource definition": "Cargando custom resource definition",
"No custom resources found": "No se encontraron custom resources",
"Loading resource definition details": "Cargando detalles de la definición del recurso",
Expand Down Expand Up @@ -380,6 +385,7 @@
"Main Navigation": "Navegación principal",
"Navigation Tabs": "Pestañas de navegación",
"General": "",
"Instances": "",
"Collapse Sidebar": "Contraer barra lateral",
"Navigation": "Navegación",
"Cluster version upgraded to {{ gitVersion }}": "Versión del cluster actualizada a {{ gitVersion }}",
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/i18n/locales/fr/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,11 @@
"Error getting custom resource definition {{ crdName }}: {{ errorMessage }}": "Erreur lors de l'obtention de la définition de la ressource personnalisée {{ crdName }} : {{ errorMessage }}",
"Loading custom resource details": "Chargement des détails des ressources personnalisées",
"Error getting custom resource {{ crName }}: {{ errorMessage }}": "Erreur lors de l'obtention de la ressource personnalisée {{ crName }} : {{ errorMessage }}",
"Loading custom resource instances": "",
"No custom resources instances found.": "",
"Failed to load custom resource instances": "",
"Error getting custom resource definitions: {{ errorMessage }}": "",
"Loading custom resource definitions": "",
"Loading custom resource definition": "Chargement de la définition de la ressource personnalisée",
"No custom resources found": "Aucune ressource personnalisée trouvée",
"Loading resource definition details": "Chargement des détails de la définition des ressources",
Expand Down Expand Up @@ -380,6 +385,7 @@
"Main Navigation": "Navigation principale",
"Navigation Tabs": "Onglets de navigation",
"General": "",
"Instances": "",
"Collapse Sidebar": "Réduire la barre latérale",
"Navigation": "Navigation",
"Cluster version upgraded to {{ gitVersion }}": "Version du cluster mise à jour vers {{ gitVersion }}",
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/i18n/locales/pt/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,11 @@
"Error getting custom resource definition {{ crdName }}: {{ errorMessage }}": "Erro ao obter a \"custom resource definition\" {{ crdName }}: {{ errorMessage }}",
"Loading custom resource details": "A carregar detalhes da \"custom resource\"",
"Error getting custom resource {{ crName }}: {{ errorMessage }}": "Erro ao obter \"custom resource\" {{ crName }}: {{ errorMessage }}",
"Loading custom resource instances": "",
"No custom resources instances found.": "",
"Failed to load custom resource instances": "",
"Error getting custom resource definitions: {{ errorMessage }}": "",
"Loading custom resource definitions": "",
"Loading custom resource definition": "A carregar \"custom resource definition\"",
"No custom resources found": "Não foram encontrados \"custom resources\"",
"Loading resource definition details": "A carregar os detalhes de definição do recurso",
Expand Down Expand Up @@ -380,6 +385,7 @@
"Main Navigation": "Navegação Principal",
"Navigation Tabs": "Separadores de Navegação",
"General": "",
"Instances": "",
"Collapse Sidebar": "Encolher Barra Lateral",
"Navigation": "Navegação",
"Cluster version upgraded to {{ gitVersion }}": "Versão do cluster actualizada para {{ gitVersion }}",
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/lib/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { PageGrid } from '../components/common/Resource/Resource';
import ConfigDetails from '../components/configmap/Details';
import ConfigMapList from '../components/configmap/List';
import CustomResourceDetails from '../components/crd/CustomResourceDetails';
import { CrInstanceList } from '../components/crd/CustomResourceInstancesList';
import CustomResourceList from '../components/crd/CustomResourceList';
import CustomResourceDefinitionDetails from '../components/crd/Details';
import CustomResourceDefinitionList from '../components/crd/List';
Expand Down Expand Up @@ -654,6 +655,13 @@ const defaultRoutes: {
sidebar: 'crds',
component: () => <CustomResourceList />,
},
crs: {
path: '/crs',
exact: true,
name: 'CRInstances',
sidebar: 'crs',
component: () => <CrInstanceList />,
},
notifications: {
path: '/notifications',
exact: true,
Expand Down

0 comments on commit f374e6c

Please sign in to comment.