# Tanzu Deployer UI - Angular Frontend

A modern, dark-themed Angular 19.1 frontend for deploying applications to Tanzu/Cloud Foundry environments.

## Features

- ✅ **Modern Dark Theme**: Sleek GitHub-inspired dark UI with blue/purple gradients
- ✅ **Simple Form Interface**: Easy-to-use deployment form with all Tanzu configuration fields
- ✅ **Modern File Upload**: Beautiful drag-and-drop style file upload buttons with SVG icons
- ✅ **Chunked File Upload**: Handles large JAR files using Base64-encoded chunks (compatible with Java proxy)
- ✅ **Real-time Progress**: Visual progress bar showing upload and deployment status
- ✅ **Live Logs**: Collapsible terminal-style output window displaying deployment logs
- ✅ **Responsive Design**: Works seamlessly on desktop, tablet, and mobile devices
- ✅ **Secure**: Password fields are masked, follows Angular security best practices
- ✅ **Configurable**: Environment-based configuration for all settings
- ✅ **Production Ready**: Includes nginx configuration and Helm chart for K8s deployment

## Configuration

All application settings are managed via environment files:

**`src/environments/environment.ts`** (Development):
```typescript
export const environment = {
  production: false,
  apiBase: '/api/cf',              // API endpoint base URL
  chunkSize: 1048576,              // Chunk size in bytes (1MB)
  enableSslValidation: false,      // Show/hide SSL validation checkbox
  pollInterval: 5000,              // Poll interval in milliseconds
  maxPollAttempts: 120,            // Max polling attempts (10 minutes)
  defaultLogsExpanded: true,       // Logs expanded by default
  showDebugInfo: false             // Show debug information
};
```

**`src/environments/environment.prod.ts`** (Production):
- Same structure as development
- Used when building with `--configuration production`

### Customizing Configuration

To customize the application behavior:

1. Edit `src/environments/environment.ts` for development
2. Edit `src/environments/environment.prod.ts` for production
3. Rebuild the application

**Common Customizations:**

- **Enable SSL Validation Checkbox**: Set `enableSslValidation: true`
- **Change Chunk Size**: Set `chunkSize: 2097152` (2MB)
- **Increase Poll Time**: Set `maxPollAttempts: 240` (20 minutes)
- **Change API Endpoint**: Set `apiBase: 'https://api.example.com/cf'`

## Quick Start

### Local Development

1. **Install dependencies:**
   ```bash
   npm install
   ```

2. **Start development server:**
   ```bash
   npm start
   ```

3. **Open browser:**
   Navigate to `http://localhost:4200`

### Build for Production

```bash
npm run build:prod
```

Built files will be in `dist/cf-deployer-ui/browser/`

## Docker Deployment

### Build Docker Image

```bash
docker build -t cf-deployer-ui:latest .
```

### Run Docker Container

```bash
docker run -d \
  -p 8080:80 \
  -e BACKEND_URL=http://cf-deployer-backend:8080 \
  --name cf-deployer-ui \
  cf-deployer-ui:latest
```

**Environment Variables:**
- `BACKEND_URL`: URL of the CF Deployer backend API (default: `http://localhost:8080`)

## Kubernetes Deployment

### Prerequisites

- Kubernetes cluster
- Helm 3.x installed
- Docker image pushed to registry

### Deploy with Helm

1. **Update values.yaml:**
   ```yaml
   image:
     repository: your-registry/cf-deployer-ui
     tag: "1.0.0"

   backend:
     url: "http://cf-deployer-backend:8080"

   ingress:
     enabled: true
     hosts:
       - host: cf-deployer.example.com
         paths:
           - path: /
             pathType: Prefix
   ```

2. **Install the chart:**
   ```bash
   helm install cf-deployer-ui ./helm
   ```

3. **Upgrade the chart:**
   ```bash
   helm upgrade cf-deployer-ui ./helm
   ```

4. **Uninstall:**
   ```bash
   helm uninstall cf-deployer-ui
   ```

### Helm Configuration Options

| Parameter | Description | Default |
|-----------|-------------|---------|
| `replicaCount` | Number of replicas | `2` |
| `image.repository` | Docker image repository | `cf-deployer-ui` |
| `image.tag` | Docker image tag | `latest` |
| `service.type` | Kubernetes service type | `ClusterIP` |
| `service.port` | Service port | `80` |
| `backend.url` | Backend API URL | `http://cf-deployer-backend:8080` |
| `ingress.enabled` | Enable ingress | `false` |
| `resources.limits.cpu` | CPU limit | `500m` |
| `resources.limits.memory` | Memory limit | `512Mi` |

## Usage

### Deployment Flow

1. **Fill in Cloud Foundry Details:**
   - API Endpoint (e.g., `https://api.cf.example.com`)
   - Username and Password
   - Organization and Space
   - Application Name
   - Skip SSL Validation (if needed)

2. **Select Files:**
   - JAR File: Your application JAR
   - Manifest File: Cloud Foundry manifest.yml

3. **Deploy:**
   - Click "Deploy to Cloud Foundry"
   - Watch progress bar and logs
   - Wait for completion

### Screenshots

**Main Form:**
- Clean, responsive form with all required fields
- File upload with size display
- SSL validation checkbox

**Progress Tracking:**
- Visual progress bar (0-100%)
- Current step indicator
- Status badges (IN_PROGRESS, COMPLETED, FAILED)

**Logs Output:**
- Collapsible terminal-style output
- Timestamped log entries
- Auto-scroll to latest logs

## Architecture

### How It Works

The frontend mimics the behavior of `deploy-chunked-simple.sh`:

1. **Initialize Upload Session:**
   ```
   POST /api/cf/upload/init
   → Returns uploadSessionId
   ```

2. **Upload Files in Chunks:**
   - Splits files into 1MB chunks
   - Base64 encodes each chunk (for Java proxy compatibility)
   - Uploads via:
     ```
     POST /api/cf/upload/chunk?uploadSessionId=...&fileType=...&chunkIndex=...&totalChunks=...&fileName=...
     Headers: Content-Type: text/plain, X-Chunk-Encoding: base64
     Body: Base64 chunk data
     ```

3. **Finalize Upload:**
   ```
   POST /api/cf/upload/finalize?uploadSessionId=...&async=true
   ```

4. **Poll Deployment Status:**
   ```
   GET /api/cf/deployment/status/{uploadSessionId}
   (Every 5 seconds until COMPLETED or FAILED)
   ```

### Why Base64 Encoding?

The frontend sends chunks as Base64-encoded text because:
- It goes through a Java proxy that reads `@RequestBody String`
- Binary data gets corrupted when read as String
- Base64 ensures safe text transport through the proxy
- Backend automatically decodes Base64 back to binary

## Project Structure

```
frontend/
├── src/
│   ├── app/
│   │   ├── app.component.ts       # Main component with form logic
│   │   ├── app.component.html     # Template with form UI
│   │   ├── app.component.css      # Component styles
│   │   └── deploy.service.ts      # API service
│   ├── index.html                 # Main HTML file
│   ├── main.ts                    # Bootstrap file
│   └── styles.css                 # Global styles
├── helm/                          # Helm chart
│   ├── Chart.yaml
│   ├── values.yaml
│   └── templates/
│       ├── deployment.yaml
│       ├── service.yaml
│       ├── ingress.yaml
│       └── _helpers.tpl
├── nginx.conf                     # nginx configuration
├── Dockerfile                     # Multi-stage Docker build
├── angular.json                   # Angular CLI configuration
├── package.json                   # NPM dependencies
└── tsconfig.json                  # TypeScript configuration
```

## Development

### Prerequisites

- Node.js 20.x or higher
- npm 10.x or higher
- Angular CLI 19.x

### Install Angular CLI

```bash
npm install -g @angular/cli@19
```

### Code Structure

**app.component.ts:**
- Handles form state and validation
- Manages file uploads and chunking
- Polls deployment status
- Updates progress and logs

**deploy.service.ts:**
- Encapsulates all HTTP API calls
- Returns RxJS Observables converted to Promises
- Handles Base64 encoding headers

**Styling:**
- Responsive grid layout
- Mobile-first design
- Terminal-style logs with custom scrollbar
- Gradient progress bar

## Troubleshooting

### CORS Errors

If you see CORS errors in the browser console:

1. **Development:** Configure proxy in `angular.json`:
   ```json
   {
     "serve": {
       "options": {
         "proxyConfig": "proxy.conf.json"
       }
     }
   }
   ```

   Create `proxy.conf.json`:
   ```json
   {
     "/api": {
       "target": "http://localhost:8080",
       "secure": false
     }
   }
   ```

2. **Production:** nginx handles proxying (already configured)

### File Upload Fails

- Check that backend is running and accessible
- Verify `BACKEND_URL` environment variable
- Check browser console for error messages
- Enable DEBUG_MODE in backend to see detailed logs

### Deployment Timeout

- Default timeout is 10 minutes (120 attempts × 5 seconds)
- Increase `maxAttempts` in `pollDeploymentStatus()` if needed
- Check backend logs for actual deployment status

## Browser Support

- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
- Mobile browsers (iOS Safari, Chrome Android)

## License

MIT License - see main project README
