Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions radius/locales/en/translation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
{
"Error loading application": "Error loading application",
"Application Not Found": "Application Not Found",
"The application \"{{applicationName}}\" could not be found.": "The application \"{{applicationName}}\" could not be found.",
"Back": "Back",
"General Information": "General Information",
"Name": "Name",
"Type": "Type",
"Location": "Location",
"Provisioning State": "Provisioning State",
"Unknown": "Unknown",
"Environment & Compute": "Environment & Compute",
"Environment": "Environment",
"Compute Kind": "Compute Kind",
"Namespace": "Namespace",
"Resources ({{count}})_one": "Resources ({{count}})",
"Resources ({{count}})_other": "Resources ({{count}})",
"Error loading resources: {{message}}": "Error loading resources: {{message}}",
"No resources found for this application": "No resources found for this application",
"System Information": "System Information",
"Created At": "Created At",
"Created By": "Created By",
"Last Modified": "Last Modified",
"Last Modified By": "Last Modified By",
"Error loading applications": "Error loading applications",
"Applications ({{count}})_one": "Applications ({{count}})",
"Applications ({{count}})_other": "Applications ({{count}})",
"Created": "Created",
"Error loading environment": "Error loading environment",
"Environment Not Found": "Environment Not Found",
"The environment \"{{environmentName}}\" could not be found.": "The environment \"{{environmentName}}\" could not be found.",
"Overview": "Overview",
"Recipes ({{count}})_one": "Recipes ({{count}})",
"Recipes ({{count}})_other": "Recipes ({{count}})",
"Compute": "Compute",
"Kind": "Kind",
"Resource ID": "Resource ID",
"Providers": "Providers",
"No recipes registered for this environment": "No recipes registered for this environment",
"Resource Type": "Resource Type",
"Recipe Kind": "Recipe Kind",
"Recipe Location": "Recipe Location",
"No resources found for this environment": "No resources found for this environment",
"Error loading environments": "Error loading environments",
"Environments ({{count}})_one": "Environments ({{count}})",
"Environments ({{count}})_other": "Environments ({{count}})",
"Recipes": "Recipes",
"UCP API Version": "UCP API Version",
"The Radius UCP API version to use (e.g., 2023-10-01-preview)": "The Radius UCP API version to use (e.g., 2023-10-01-preview)",
"{{count}} Succeeded_one": "{{count}} Succeeded",
"{{count}} Succeeded_other": "{{count}} Succeeded",
"{{count}} Failed_one": "{{count}} Failed",
"{{count}} Failed_other": "{{count}} Failed",
"{{count}} Processing_one": "{{count}} Processing",
"{{count}} Processing_other": "{{count}} Processing",
"{{count}} Other_one": "{{count}} Other",
"{{count}} Other_other": "{{count}} Other",
"Error loading Radius resources": "Error loading Radius resources",
"Radius Overview": "Radius Overview",
"Environments": "Environments",
"Applications": "Applications",
"All Resources": "All Resources",
"Failed Resources": "Failed Resources",
"Provider": "Provider",
"Error loading Resource Types": "Error loading Resource Types",
"Resource Types": "Resource Types",
"Available Radius resource types from all providers": "Available Radius resource types from all providers",
"Resource Provider": "Resource Provider",
"API Versions": "API Versions",
"No {{title}} defined": "No {{title}} defined",
"Property": "Property",
"Description": "Description",
"Required": "Required",
"Enum: {{values}}": "Enum: {{values}}",
"Yes": "Yes",
"No": "No",
"Error loading Resource Type Details": "Error loading Resource Type Details",
"Resource Type Not Found": "Resource Type Not Found",
"The resource type \"{{decodedName}}\" could not be found.": "The resource type \"{{decodedName}}\" could not be found.",
"resource type tabs": "resource type tabs",
"Properties": "Properties",
"Output Properties": "Output Properties",
"Details": "Details",
"No description available": "No description available",
"Capabilities": "Capabilities",
"API Version: {{version}}": "API Version: {{version}}",
"No API versions available": "No API versions available",
"Resource Type JSON": "Resource Type JSON",
"Error loading resources": "Error loading resources",
"Resource Name": "Resource Name",
"Resource Group": "Resource Group",
"Application": "Application",
"Status": "Status",
"Error loading resource": "Error loading resource",
"Resource Not Found": "Resource Not Found",
"The resource could not be found.": "The resource could not be found.",
"Full Type": "Full Type",
"Application & Environment": "Application & Environment",
"Kubernetes Resource": "Kubernetes Resource",
"View Deployment": "View Deployment",
"View Pod": "View Pod",
"Additional Properties": "Additional Properties",
"Tags": "Tags"
}
5 changes: 5 additions & 0 deletions radius/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,10 @@
},
"devDependencies": {
"@kinvolk/headlamp-plugin": "^0.14.0"
},
"headlamp": {
"i18n": [
"en"
]
}
}
63 changes: 35 additions & 28 deletions radius/src/applications/ApplicationDetailView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/
import { Icon } from '@iconify/react';
import { useTranslation } from '@kinvolk/headlamp-plugin/lib';
import { Link, SectionBox, Table } from '@kinvolk/headlamp-plugin/lib/CommonComponents';
import { Box, Button, Chip, CircularProgress, Grid, Typography } from '@mui/material';
import { useParams } from 'react-router-dom';
Expand All @@ -40,6 +41,7 @@ interface ApplicationResourceCellProps {
* Shows detailed information about a specific Radius application
*/
export default function ApplicationDetailView() {
const { t } = useTranslation();
const { applicationName } = useParams<RouteParams>();
const [applications, error, loading] = useRadiusApplications();

Expand All @@ -64,7 +66,7 @@ export default function ApplicationDetailView() {
return (
<SectionBox sx={{ p: 3 }}>
<Typography color="error" variant="h6">
Error loading application
{t('Error loading application')}
</Typography>
<Typography color="error">{error.message}</Typography>
</SectionBox>
Expand All @@ -81,17 +83,17 @@ export default function ApplicationDetailView() {
return (
<SectionBox sx={{ p: 3 }}>
<Typography variant="h6" gutterBottom>
Application Not Found
{t('Application Not Found')}
</Typography>
<Typography color="textSecondary" gutterBottom>
The application "{applicationName}" could not be found.
{t('The application "{{applicationName}}" could not be found.', { applicationName })}
</Typography>
<Button
onClick={() => window.history.back()}
startIcon={<Icon icon="mdi:arrow-left" />}
sx={{ mt: 2 }}
>
Back
{t('Back')}
</Button>
</SectionBox>
);
Expand Down Expand Up @@ -136,6 +138,7 @@ function ApplicationContent({
application: UCPApplication;
environmentName: string;
}>) {
const { t } = useTranslation();
// Fetch resources for this application
const [resources, resourcesError, resourcesLoading] = useApplicationResources(application.id);

Expand All @@ -147,7 +150,7 @@ function ApplicationContent({
startIcon={<Icon icon="mdi:arrow-left" />}
sx={{ mb: 2 }}
>
Back
{t('Back')}
</Button>
<SectionBox sx={{ mb: 3 }}>
<Typography variant="h4" gutterBottom>
Expand All @@ -161,32 +164,32 @@ function ApplicationContent({
{/* Content */}
<Grid container spacing={3}>
<Grid item xs={12} md={6}>
<SectionBox title="General Information">
<SectionBox title={t('General Information')}>
<Box display="flex" flexDirection="column" gap={2}>
<Box>
<Typography variant="subtitle2" color="textSecondary">
Name
{t('Name')}
</Typography>
<Typography variant="body1">{application.name}</Typography>
</Box>
<Box>
<Typography variant="subtitle2" color="textSecondary">
Type
{t('Type')}
</Typography>
<Typography variant="body1">{application.type}</Typography>
</Box>
<Box>
<Typography variant="subtitle2" color="textSecondary">
Location
{t('Location')}
</Typography>
<Typography variant="body1">{application.location}</Typography>
</Box>
<Box>
<Typography variant="subtitle2" color="textSecondary">
Provisioning State
{t('Provisioning State')}
</Typography>
<Chip
label={application.properties.provisioningState || 'Unknown'}
label={application.properties.provisioningState || t('Unknown')}
color={
application.properties.provisioningState === 'Succeeded' ? 'success' : 'default'
}
Expand All @@ -198,11 +201,11 @@ function ApplicationContent({
</Grid>

<Grid item xs={12} md={6}>
<SectionBox title="Environment & Compute">
<SectionBox title={t('Environment & Compute')}>
<Box display="flex" flexDirection="column" gap={2}>
<Box>
<Typography variant="subtitle2" color="textSecondary">
Environment
{t('Environment')}
</Typography>
{environmentName === 'N/A' ? (
<Typography variant="body1">{environmentName}</Typography>
Expand All @@ -215,7 +218,7 @@ function ApplicationContent({
{application.properties.status?.compute?.kind && (
<Box>
<Typography variant="subtitle2" color="textSecondary">
Compute Kind
{t('Compute Kind')}
</Typography>
<Typography variant="body1">
{application.properties.status.compute.kind}
Expand All @@ -225,7 +228,7 @@ function ApplicationContent({
{application.properties.status?.compute?.namespace && (
<Box>
<Typography variant="subtitle2" color="textSecondary">
Namespace
{t('Namespace')}
</Typography>
<Typography variant="body1">
{application.properties.status.compute.namespace}
Expand All @@ -237,21 +240,23 @@ function ApplicationContent({
</Grid>
</Grid>

<SectionBox title={`Resources (${resources?.length || 0})`}>
<SectionBox title={t('Resources ({{count}})', { count: resources?.length || 0 })}>
{resourcesLoading && (
<Box display="flex" justifyContent="center" p={2}>
<CircularProgress size={24} />
</Box>
)}
{resourcesError && (
<Typography color="error">Error loading resources: {resourcesError.message}</Typography>
<Typography color="error">
{t('Error loading resources: {{message}}', { message: resourcesError.message })}
</Typography>
)}
{!resourcesLoading && !resourcesError && resources && resources.length > 0 ? (
<Table
data={resources}
columns={[
{
header: 'Name',
header: t('Name'),
accessorKey: 'name',
gridTemplate: 'auto',
Cell: ({ row }: { row: { original: UCPResource } }) => (
Expand All @@ -264,25 +269,25 @@ function ApplicationContent({
),
},
{
header: 'Type',
header: t('Type'),
accessorKey: 'type',
Cell: ({ row }: ApplicationResourceCellProps) => {
const resourceType = row.original.type.split('/').pop() || row.original.type;
return <Chip label={resourceType} size="small" />;
},
},
{
header: 'Namespace',
header: t('Namespace'),
accessorKey: 'namespace',
Cell: ({ row }: ApplicationResourceCellProps) =>
row.original.properties.status?.compute?.namespace || 'N/A',
},
{
header: 'Provisioning State',
header: t('Provisioning State'),
accessorKey: 'provisioningState',
Cell: ({ row }: ApplicationResourceCellProps) => (
<Chip
label={row.original.properties.provisioningState || 'Unknown'}
label={row.original.properties.provisioningState || t('Unknown')}
color={
row.original.properties.provisioningState === 'Succeeded'
? 'success'
Expand All @@ -297,18 +302,20 @@ function ApplicationContent({
) : (
!resourcesLoading &&
!resourcesError && (
<Typography color="textSecondary">No resources found for this application</Typography>
<Typography color="textSecondary">
{t('No resources found for this application')}
</Typography>
)
)}
</SectionBox>

{application.systemData && (
<SectionBox title="System Information">
<SectionBox title={t('System Information')}>
<Grid container spacing={2}>
{application.systemData.createdAt && (
<Grid item xs={12} sm={6}>
<Typography variant="subtitle2" color="textSecondary">
Created At
{t('Created At')}
</Typography>
<Typography variant="body2">
{new Date(application.systemData.createdAt).toLocaleString()}
Expand All @@ -318,15 +325,15 @@ function ApplicationContent({
{application.systemData.createdBy && (
<Grid item xs={12} sm={6}>
<Typography variant="subtitle2" color="textSecondary">
Created By
{t('Created By')}
</Typography>
<Typography variant="body2">{application.systemData.createdBy}</Typography>
</Grid>
)}
{application.systemData.lastModifiedAt && (
<Grid item xs={12} sm={6}>
<Typography variant="subtitle2" color="textSecondary">
Last Modified
{t('Last Modified')}
</Typography>
<Typography variant="body2">
{new Date(application.systemData.lastModifiedAt).toLocaleString()}
Expand All @@ -336,7 +343,7 @@ function ApplicationContent({
{application.systemData.lastModifiedBy && (
<Grid item xs={12} sm={6}>
<Typography variant="subtitle2" color="textSecondary">
Last Modified By
{t('Last Modified By')}
</Typography>
<Typography variant="body2">{application.systemData.lastModifiedBy}</Typography>
</Grid>
Expand Down
Loading
Loading