flare / flare-ui /src /app /dialogs /api-edit-dialog /api-edit-dialog.component.html
ciyidogan's picture
Update flare-ui/src/app/dialogs/api-edit-dialog/api-edit-dialog.component.html
9b053d5 verified
raw
history blame
13.8 kB
<h2 mat-dialog-title>
{{ data.mode === 'create' ? 'Create New API' : data.mode === 'duplicate' ? 'Duplicate API' : 'Edit API' }}
</h2>
<mat-dialog-content>
<form [formGroup]="form">
<mat-tab-group>
<!-- General Tab -->
<mat-tab label="General">
<div class="tab-content">
<mat-form-field appearance="outline" class="full-width">
<mat-label>Name*</mat-label>
<input matInput formControlName="name"
placeholder="e.g., book_flight_api"
[readonly]="data.mode === 'edit'">
<mat-hint>Use only letters, numbers, and underscores</mat-hint>
<mat-error *ngIf="form.get('name')?.hasError('required')">Name is required</mat-error>
<mat-error *ngIf="form.get('name')?.hasError('pattern')">Invalid characters in name</mat-error>
</mat-form-field>
<mat-form-field appearance="outline" class="full-width">
<mat-label>URL*</mat-label>
<input matInput formControlName="url"
placeholder="https://api.example.com/endpoint">
<mat-error *ngIf="form.get('url')?.hasError('required')">URL is required</mat-error>
<mat-error *ngIf="form.get('url')?.hasError('pattern')">Invalid URL format</mat-error>
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label>Method*</mat-label>
<mat-select formControlName="method">
<mat-option *ngFor="let method of httpMethods" [value]="method">
{{ method }}
</mat-option>
</mat-select>
</mat-form-field>
<div class="form-section">
<label class="section-label">Body Template:</label>
<div class="json-editor">
<textarea formControlName="body_template"
placeholder='{"key": "value"}'
rows="8"
class="json-textarea"></textarea>
<div class="template-helpers">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<mat-icon>help_outline</mat-icon>
Template Variables
</mat-panel-title>
</mat-expansion-panel-header>
<div class="template-list">
<mat-chip *ngFor="let templateVar of templateVariables"
(click)="insertTemplateVariable('body_template', templateVar.key)">
{{ templateVar.key }}
</mat-chip>
</div>
</mat-expansion-panel>
</div>
<button mat-button type="button"
(click)="validateJSON('body_template')"
[color]="validateJSON('body_template') ? 'primary' : 'warn'">
<mat-icon>check_circle</mat-icon>
Validate JSON
</button>
</div>
</div>
<mat-form-field appearance="outline">
<mat-label>Timeout (seconds)*</mat-label>
<input matInput type="number" formControlName="timeout_seconds">
<mat-error *ngIf="form.get('timeout_seconds')?.hasError('required')">Timeout is required</mat-error>
<mat-error *ngIf="form.get('timeout_seconds')?.hasError('min')">Minimum 1 second</mat-error>
<mat-error *ngIf="form.get('timeout_seconds')?.hasError('max')">Maximum 300 seconds</mat-error>
</mat-form-field>
<div class="form-section">
<h4>Retry Settings</h4>
<div formGroupName="retry" class="retry-settings">
<mat-form-field appearance="outline">
<mat-label>Retry Count*</mat-label>
<input matInput type="number" formControlName="retry_count">
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label>Backoff (seconds)*</mat-label>
<input matInput type="number" formControlName="backoff_seconds">
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label>Strategy*</mat-label>
<mat-select formControlName="strategy">
<mat-option value="static">Static</mat-option>
<mat-option value="exponential">Exponential</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<mat-form-field appearance="outline" class="full-width">
<mat-label>Response Prompt</mat-label>
<textarea matInput formControlName="response_prompt"
rows="4"
placeholder="Convert the API response to human-friendly text..."></textarea>
<mat-hint>Use {{'{{api_response}}'}} to reference the API response</mat-hint>
</mat-form-field>
<mat-form-field appearance="outline" class="full-width">
<mat-label>Proxy URL (Optional)</mat-label>
<input matInput formControlName="proxy"
placeholder="http://proxy.example.com:8080">
</mat-form-field>
</div>
</mat-tab>
<!-- Headers Tab -->
<mat-tab label="Headers">
<div class="tab-content">
<div class="headers-section">
<div class="section-header">
<h4>Request Headers</h4>
<button mat-raised-button color="primary" type="button" (click)="addHeader()">
<mat-icon>add</mat-icon>
Add Header
</button>
</div>
<div formArrayName="headers" class="headers-list">
<div *ngFor="let header of headers.controls; let i = index"
[formGroupName]="i"
class="header-row">
<mat-form-field appearance="outline">
<mat-label>Key</mat-label>
<input matInput formControlName="key" placeholder="Content-Type">
</mat-form-field>
<mat-form-field appearance="outline" class="header-value">
<mat-label>Value</mat-label>
<input matInput formControlName="value" placeholder="application/json">
</mat-form-field>
<button mat-icon-button color="warn" type="button" (click)="removeHeader(i)">
<mat-icon>delete</mat-icon>
</button>
</div>
</div>
<div *ngIf="headers.length === 0" class="empty-state">
<mat-icon>info</mat-icon>
<p>No headers defined. Click "Add Header" to create one.</p>
</div>
<div class="template-helpers">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<mat-icon>help_outline</mat-icon>
Common Headers
</mat-panel-title>
</mat-expansion-panel-header>
<div class="common-headers">
<p><strong>Content-Type:</strong> application/json</p>
<p><strong>Authorization:</strong> Bearer {{'{{auth_tokens.api_name.token}}'}}</p>
<p><strong>Accept:</strong> application/json</p>
</div>
</mat-expansion-panel>
</div>
</div>
</div>
</mat-tab>
<!-- Auth Tab -->
<mat-tab label="Auth">
<div class="tab-content">
<div formGroupName="auth">
<mat-checkbox formControlName="enabled">
Enable Authentication
</mat-checkbox>
<div *ngIf="form.get('auth.enabled')?.value" class="auth-settings">
<mat-form-field appearance="outline" class="full-width">
<mat-label>Token Endpoint*</mat-label>
<input matInput formControlName="token_endpoint"
placeholder="https://api.example.com/auth">
<mat-error *ngIf="form.get('auth.token_endpoint')?.hasError('required')">
Token endpoint is required when auth is enabled
</mat-error>
</mat-form-field>
<mat-form-field appearance="outline" class="full-width">
<mat-label>Response Token Path*</mat-label>
<input matInput formControlName="response_token_path"
placeholder="access_token or data.token">
<mat-hint>JSON path to extract token from response (e.g., data.token)</mat-hint>
<mat-error *ngIf="form.get('auth.response_token_path')?.hasError('required')">
Token path is required when auth is enabled
</mat-error>
</mat-form-field>
<div class="form-section">
<label class="section-label">Token Request Body:</label>
<div class="json-editor">
<textarea formControlName="token_request_body"
placeholder='{"grant_type": "client_credentials"}'
rows="4"
class="json-textarea"></textarea>
<button mat-button type="button"
(click)="validateJSON('auth.token_request_body')"
[color]="validateJSON('auth.token_request_body') ? 'primary' : 'warn'">
<mat-icon>check_circle</mat-icon>
Validate JSON
</button>
</div>
</div>
<mat-divider></mat-divider>
<h4>Token Refresh (Optional)</h4>
<mat-form-field appearance="outline" class="full-width">
<mat-label>Token Refresh Endpoint</mat-label>
<input matInput formControlName="token_refresh_endpoint"
placeholder="https://api.example.com/refresh">
</mat-form-field>
<div class="form-section" *ngIf="form.get('auth.token_refresh_endpoint')?.value">
<label class="section-label">Token Refresh Body:</label>
<div class="json-editor">
<textarea formControlName="token_refresh_body"
placeholder='{"refresh_token": "value"}'
rows="4"
class="json-textarea"></textarea>
<button mat-button type="button"
(click)="validateJSON('auth.token_refresh_body')"
[color]="validateJSON('auth.token_refresh_body') ? 'primary' : 'warn'">
<mat-icon>check_circle</mat-icon>
Validate JSON
</button>
</div>
</div>
</div>
</div>
</div>
</mat-tab>
<!-- Test Tab -->
<mat-tab label="Test">
<div class="tab-content">
<div class="test-section">
<h4>Test API Configuration</h4>
<p>Test your API with sample data before saving.</p>
<div class="test-info">
<mat-chip-listbox>
<mat-chip-option selected>{{ form.get('method')?.value || 'POST' }}</mat-chip-option>
<mat-chip-option>{{ form.get('url')?.value || 'No URL set' }}</mat-chip-option>
</mat-chip-listbox>
</div>
<button mat-raised-button color="accent"
(click)="testAPI()"
[disabled]="testing || !form.get('url')?.valid">
<mat-icon>play_arrow</mat-icon>
{{ testing ? 'Testing...' : 'Send Test Request' }}
</button>
<div *ngIf="testResult" class="test-result">
<h4>Test Result:</h4>
<div class="result-status" [class.success]="testResult.success" [class.error]="!testResult.success">
<mat-icon>{{ testResult.success ? 'check_circle' : 'error' }}</mat-icon>
<span>{{ testResult.success ? 'Success' : 'Failed' }}</span>
<span *ngIf="testResult.status_code" class="status-code">
Status: {{ testResult.status_code }}
</span>
<span *ngIf="testResult.response_time_ms" class="response-time">
Time: {{ testResult.response_time_ms }}ms
</span>
</div>
<div *ngIf="testResult.error" class="error-message">
<mat-icon>error_outline</mat-icon>
{{ testResult.error }}
</div>
<div *ngIf="testResult.headers" class="response-section">
<h5>Response Headers:</h5>
<pre>{{ testResult.headers | json }}</pre>
</div>
<div *ngIf="testResult.body" class="response-section">
<h5>Response Body:</h5>
<pre>{{ testResult.body }}</pre>
</div>
</div>
<div class="test-note">
<mat-icon>info</mat-icon>
<p>Note: Test requests use placeholder values for template variables.</p>
</div>
</div>
</div>
</mat-tab>
</mat-tab-group>
</form>
</mat-dialog-content>
<mat-dialog-actions align="end">
<button mat-button (click)="cancel()">Cancel</button>
<button mat-raised-button color="primary"
(click)="save()"
[disabled]="form.invalid || saving">
{{ saving ? 'Saving...' : 'Save' }}
</button>
</mat-dialog-actions>