Skip to content
Merged
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
373 changes: 338 additions & 35 deletions src/App.tsx

Large diffs are not rendered by default.

58 changes: 55 additions & 3 deletions src/components/DeploymentForm.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { Plus, Minus, Server, Settings, Database, Key, Trash2, Copy, Globe, Shield, FileText } from 'lucide-react';
import type { DeploymentConfig, Container, ConfigMap, Secret, EnvVar } from '../types';
import { Plus, Minus, Server, Settings, Database, Key, Trash2, Copy, Globe, Shield, FileText, Users, X } from 'lucide-react';
import type { DeploymentConfig, Container, ConfigMap, Secret, EnvVar, ServiceAccount } from '../types';

interface DeploymentFormProps {
config: DeploymentConfig;
onChange: (config: DeploymentConfig) => void;
availableNamespaces: string[];
availableConfigMaps: ConfigMap[];
availableSecrets: Secret[];
availableServiceAccounts: ServiceAccount[];
onNavigateToServiceAccounts?: () => void;
}

export function DeploymentForm({ config, onChange, availableNamespaces, availableConfigMaps, availableSecrets }: DeploymentFormProps) {
export function DeploymentForm({ config, onChange, availableNamespaces, availableConfigMaps, availableSecrets, availableServiceAccounts, onNavigateToServiceAccounts }: DeploymentFormProps) {
const updateConfig = (updates: Partial<DeploymentConfig>) => {
onChange({ ...config, ...updates });
};
Expand Down Expand Up @@ -330,6 +332,56 @@ export function DeploymentForm({ config, onChange, availableNamespaces, availabl
))}
</select>
</div>

<div className="sm:col-span-2">
<div className="flex items-center justify-between mb-2">
<label className="block text-sm font-medium text-gray-700">
Service Account
</label>
{onNavigateToServiceAccounts && (
<button
type="button"
onClick={onNavigateToServiceAccounts}
className="inline-flex items-center px-2 py-1 text-xs bg-cyan-600 text-white rounded hover:bg-cyan-700 transition-colors duration-200"
>
<Plus className="w-3 h-3 mr-1" />
New Service Account
</button>
)}
</div>
<div className="flex space-x-2">
<select
value={config.serviceAccount || ''}
onChange={(e) => updateConfig({ serviceAccount: e.target.value || undefined })}
className="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm sm:text-base"
>
<option value="">Default (no service account)</option>
{availableServiceAccounts
.filter(sa => sa.namespace === config.namespace)
.map(serviceAccount => (
<option key={serviceAccount.name} value={serviceAccount.name}>
{serviceAccount.name}
</option>
))}
</select>
{config.serviceAccount && (
<button
type="button"
onClick={() => updateConfig({ serviceAccount: undefined })}
className="px-3 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 focus:ring-2 focus:ring-red-500 focus:border-transparent text-sm transition-colors duration-200"
title="Remove service account"
>
<X className="w-4 h-4 text-gray-500 hover:text-red-600" />
</button>
)}
</div>
{config.serviceAccount && (
<div className="mt-2 flex items-center space-x-2 text-xs text-gray-600">
<Users className="w-3 h-3 text-cyan-500" />
<span>Using service account: {config.serviceAccount}</span>
</div>
)}
</div>
</div>
</div>

Expand Down
12 changes: 12 additions & 0 deletions src/components/KubernetesIcons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,16 @@ export const K8sPodIcon: React.FC<IconProps> = ({ className = "w-4 h-4" }) => (
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2L4 6V18L12 22L20 18V6L12 2ZM12 4.21L17.37 7L12 9.83L6.63 7L12 4.21ZM6 16.89L5 16.35V8.17L11 11.15V19.29L6 16.89ZM13 19.29V11.15L19 8.17V16.35L18 16.89L13 19.29Z" fill="currentColor"/>
</svg>
);

export const K8sSecurityIcon: React.FC<IconProps> = ({ className = "w-4 h-4" }) => (
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12,1L3,5V11C3,16.55 6.84,21.74 12,23C17.16,21.74 21,16.55 21,11V5L12,1M12,7C13.4,7 14.8,8.6 14.8,10V11H16V16H8V11H9.2V10C9.2,8.6 10.6,7 12,7M12,8.2C11.2,8.2 10.4,8.7 10.4,10V11H13.6V10C13.6,8.7 12.8,8.2 12,8.2Z" fill="currentColor"/>
</svg>
);

export const K8sServiceAccountIcon: React.FC<IconProps> = ({ className = "w-4 h-4" }) => (
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2C13.1 2 14 2.9 14 4C14 5.1 13.1 6 12 6C10.9 6 10 5.1 10 4C10 2.9 10.9 2 12 2ZM21 9V7L15 5.5C14.8 4.1 13.9 2.9 12.6 2.2L11.2 5.6C11.5 5.8 11.7 6.1 11.8 6.5L17.5 7.5C17.3 7.2 17.1 6.9 16.8 6.7L21 9ZM3 9L7.2 6.7C6.9 6.9 6.7 7.2 6.5 7.5L12.2 6.5C12.3 6.1 12.5 5.8 12.8 5.6L11.4 2.2C10.1 2.9 9.2 4.1 9 5.5L3 7V9ZM9 13C9 15.8 11.2 18 14 18S19 15.8 19 13V11H17V13C17 14.7 15.7 16 14 16S11 14.7 11 13V11H9V13ZM5 13C5 15.8 7.2 18 10 18S15 15.8 15 13V11H13V13C13 14.7 11.7 16 10 16S7 14.7 7 13V11H5V13Z" fill="currentColor"/>
</svg>
);
Loading