102 lines
3.9 KiB
HTML
102 lines
3.9 KiB
HTML
<div class="p-3 space-y-3">
|
|
@if (authorizationRequirements().length) {
|
|
<section class="space-y-3">
|
|
<div>
|
|
<div class="text-xs font-semibold uppercase tracking-wide text-slate-600">Provider Authorizations</div>
|
|
<div class="mt-1 text-[11px] text-slate-500">Provide the missing runtime credentials required by this execution.</div>
|
|
</div>
|
|
|
|
@for (requirement of authorizationRequirements(); track requirement.key) {
|
|
<div class="rounded-md border border-amber-200 bg-amber-50 p-3">
|
|
<div class="flex items-start justify-between gap-3">
|
|
<div class="min-w-0">
|
|
<div class="text-xs font-semibold text-slate-800">{{ requirement.provider }}</div>
|
|
<div class="mt-1 text-[11px] text-slate-500 break-all">{{ requirement.key }}</div>
|
|
</div>
|
|
<span class="rounded-full bg-white px-2 py-1 text-[10px] font-semibold uppercase tracking-wide text-amber-700">
|
|
{{ requirement.fieldName || 'authorization' }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="mt-2 text-xs text-slate-600">{{ requirement.description || 'Runtime authorization required.' }}</div>
|
|
|
|
@if (requirement.requiredBySteps.length) {
|
|
<div class="mt-2 text-[11px] text-slate-500">
|
|
Required by: {{ requirement.requiredBySteps.join(', ') }}
|
|
</div>
|
|
}
|
|
|
|
<div class="mt-3 flex items-start gap-2">
|
|
<input
|
|
class="form-control form-control-sm"
|
|
[type]="isAuthorizationVisible(requirement.key) ? 'text' : 'password'"
|
|
[readonly]="readOnly()"
|
|
[ngModel]="authorizationValue(requirement.key)"
|
|
(ngModelChange)="onAuthorizationValueChange(requirement, $event)" />
|
|
|
|
<button
|
|
type="button"
|
|
class="btn btn-outline-secondary btn-sm shrink-0"
|
|
[disabled]="readOnly()"
|
|
(click)="toggleAuthorizationVisibility(requirement.key, $event)">
|
|
{{ isAuthorizationVisible(requirement.key) ? 'Hide' : 'Show' }}
|
|
</button>
|
|
|
|
<button
|
|
type="button"
|
|
class="btn btn-primary btn-sm shrink-0"
|
|
[disabled]="!canSubmitAuthorization(requirement.key)"
|
|
(click)="submitAuthorization(requirement, $event)">
|
|
Save
|
|
</button>
|
|
</div>
|
|
|
|
@if (isAuthorizationSaving(requirement.key)) {
|
|
<div class="mt-2 text-[11px] text-blue-600">Saving authorization...</div>
|
|
}
|
|
@if (authorizationSavingError(requirement.key); as errorMessage) {
|
|
<div class="mt-2 text-[11px] text-red-600">{{ errorMessage }}</div>
|
|
}
|
|
</div>
|
|
}
|
|
</section>
|
|
}
|
|
|
|
@if (!editableInputs().length && !authorizationRequirements().length) {
|
|
<div class="text-xs text-slate-500">No manual inputs required.</div>
|
|
} @else {
|
|
@if (editableInputs().length) {
|
|
<div class="text-xs font-semibold uppercase tracking-wide text-slate-600">Manual Inputs</div>
|
|
}
|
|
@for (executionInput of editableInputs(); track executionInput.key) {
|
|
<div class="rounded-md border border-slate-200 bg-slate-50 p-2">
|
|
<div class="text-xs font-semibold text-slate-700 mb-1">{{ executionInput.label }}</div>
|
|
<div class="text-[10px] text-slate-500 mb-2">Type: {{ executionInput.type }}</div>
|
|
|
|
@if (isFileInput(executionInput)) {
|
|
<input
|
|
type="file"
|
|
class="form-control form-control-sm"
|
|
[disabled]="readOnly()"
|
|
(change)="onFileInputChange(executionInput, $event)" />
|
|
} @else {
|
|
<textarea
|
|
class="form-control form-control-sm"
|
|
rows="4"
|
|
[readonly]="readOnly()"
|
|
[ngModel]="executionInput.value"
|
|
(ngModelChange)="onTextInputChange(executionInput, $event)">
|
|
</textarea>
|
|
}
|
|
|
|
@if (isInputSaving(executionInput.key)) {
|
|
<div class="mt-2 text-[11px] text-blue-600">Saving...</div>
|
|
}
|
|
@if (inputSavingError(executionInput.key); as errorMessage) {
|
|
<div class="mt-2 text-[11px] text-red-600">{{ errorMessage }}</div>
|
|
}
|
|
</div>
|
|
}
|
|
}
|
|
</div>
|