- Restructure operator sidebar into a flat task list with indented children; fold plan topology into plan ladders - Expand member catalog non-plan section to all published non-tier products; require recurring Stripe-mapped prices for purchase - Add operator domains placements and terminal-claims ledger; redirect /domains to the FedWiki Sites Domains anchor - Apply canonical vocabulary and chrome/form conventions; migrate seeded FedWiki Sites display name
103 lines
6.0 KiB
HTML
103 lines
6.0 KiB
HTML
<!-- Integration settings — one generic template for every installed
|
|
integration, rendered from its declared ConfigSpec. Non-secret keys
|
|
get an override form (stored in core.integration_config_overrides);
|
|
secret keys are environment-managed and never display a value.
|
|
Overrides apply on restart; the Pending-restart badge marks rows whose
|
|
stored state differs from the boot-effective value. -->
|
|
<div class="mb-2">
|
|
<a href="/operator/integrations">← Back to Integrations</a>
|
|
</div>
|
|
<div class="d-flex justify-content-between align-items-start flex-wrap gap-2 mb-1">
|
|
<h1 class="mb-0">{{ .DisplayName }} settings</h1>
|
|
{{ if .SurfacePath }}<a href="{{ .SurfacePath }}" class="btn btn-sm btn-outline-secondary">Admin page</a>{{ end }}
|
|
</div>
|
|
<p class="text-muted">Runtime configuration for the <code>{{ .Slug }}</code> integration. Each key uses its override if one is stored, otherwise the environment value, otherwise its default. Saved changes apply when the application restarts. Secret keys are managed via the environment and cannot be set here. All fields are required unless marked optional.</p>
|
|
|
|
<script defer src="/static/settings-flash.js"></script>
|
|
|
|
{{ if .Error }}
|
|
<div class="alert alert-danger" role="alert"><strong>Error{{ if .ErrorKey }} (<a href="#key-{{ .ErrorKey }}" class="alert-link">{{ .ErrorKey }}</a>){{ end }}:</strong> {{ .Error }}</div>
|
|
{{ end }}
|
|
{{ if .Saved }}
|
|
<div class="alert alert-success" role="alert">Override for <code>{{ .Saved }}</code> saved. It takes effect on the next restart.</div>
|
|
{{ end }}
|
|
{{ if .Cleared }}
|
|
<div class="alert alert-success" role="alert">Override for <code>{{ .Cleared }}</code> cleared. Resolution falls back to environment/default on the next restart.</div>
|
|
{{ end }}
|
|
|
|
<div class="table-responsive">
|
|
<table class="table align-middle">
|
|
<thead>
|
|
<tr>
|
|
<th>Key</th>
|
|
<th>Effective value</th>
|
|
<th>Source</th>
|
|
<th>Override</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{ range .Rows }}
|
|
<tr id="key-{{ .Key }}" {{ if eq .Key $.ErrorKey }}class="table-danger"{{ end }}>
|
|
<td>
|
|
<code>{{ .Key }}</code>
|
|
{{ if not .Required }}<span class="badge text-bg-light text-muted ms-1">Optional</span>{{ end }}
|
|
{{ if .PendingRestart }}<span class="badge text-bg-warning ms-1">Pending restart</span>{{ end }}
|
|
<div class="text-muted small">{{ .Usage }}</div>
|
|
</td>
|
|
{{ if .Secret }}
|
|
<td>
|
|
{{ if .SecretSet }}<span class="text-muted">Set <span aria-hidden="true">•••</span></span>
|
|
{{ else }}<span class="badge text-bg-light border">Not set</span>{{ end }}
|
|
</td>
|
|
<td><span class="badge text-bg-secondary">Managed via environment</span></td>
|
|
<td><span class="text-muted small">Set <code>{{ .Key }}</code> (or <code>{{ .Key }}-file</code>) in the environment.</span></td>
|
|
{{ else }}
|
|
<td>
|
|
{{ if .Effective }}<code>{{ .Effective }}</code>{{ else }}<span class="text-muted small">—</span>{{ end }}
|
|
</td>
|
|
<td>
|
|
{{ if eq .Source "override" }}<span class="badge text-bg-warning">Override</span>
|
|
{{ else if eq .Source "environment" }}<span class="badge text-bg-info">Environment</span>
|
|
{{ else }}<span class="badge text-bg-secondary">Default</span>{{ end }}
|
|
</td>
|
|
<td>
|
|
<form autocomplete="off" hx-post="{{ routeURL "/operator/integrations/{slug}/settings" $.Slug }}" hx-swap="none" class="d-flex gap-2 align-items-center">
|
|
<input type="hidden" name="key" value="{{ .Key }}">
|
|
{{ if eq .Kind "enum" }}
|
|
<select name="value" class="form-select form-select-sm" aria-label="Override value for {{ .Key }}">
|
|
{{ $sel := .Effective }}{{ if .HasOverride }}{{ $sel = .Override }}{{ end }}
|
|
{{ range .Enum }}
|
|
<option value="{{ . }}" {{ if eq . $sel }}selected{{ end }}>{{ . }}</option>
|
|
{{ end }}
|
|
</select>
|
|
{{ else if eq .Kind "bool" }}
|
|
<select name="value" class="form-select form-select-sm" aria-label="Override value for {{ .Key }}">
|
|
{{ $sel := .Effective }}{{ if .HasOverride }}{{ $sel = .Override }}{{ end }}
|
|
<option value="true" {{ if eq $sel "true" }}selected{{ end }}>true</option>
|
|
<option value="false" {{ if eq $sel "false" }}selected{{ end }}>false</option>
|
|
</select>
|
|
{{ else }}
|
|
<input autocomplete="off" type="text" name="value" class="form-control form-control-sm" value="{{ .Override }}"
|
|
placeholder="{{ .Effective }}"
|
|
aria-label="Override value for {{ .Key }}"
|
|
{{ if eq .Kind "list" }}title="Comma-separated list"{{ end }}>
|
|
{{ end }}
|
|
<button type="submit" name="action" value="save" class="btn btn-sm btn-outline-primary">Save</button>
|
|
{{ if .HasOverride }}
|
|
<button type="submit" name="action" value="clear" class="btn btn-sm btn-outline-secondary">Clear</button>
|
|
{{ end }}
|
|
</form>
|
|
{{ if .Warning }}
|
|
<div class="form-text text-warning-emphasis mt-1">{{ .Warning }}</div>
|
|
{{ end }}
|
|
{{ if eq .Key $.ErrorKey }}
|
|
<div class="invalid-feedback d-block">{{ $.Error }}</div>
|
|
{{ end }}
|
|
</td>
|
|
{{ end }}
|
|
</tr>
|
|
{{ end }}
|
|
</tbody>
|
|
</table>
|
|
</div>
|