- Add deployment-name branding to titles, mastheads, and OG tags - Share one grant delivery-state query with lineage across grants surfaces - Show pool status/usage, org owners, and config readiness - Make billing views projection-aware with recency and sync vocabulary - Guard FedWiki creation without domains and render route-aware 404s
108 lines
5.4 KiB
HTML
108 lines
5.4 KiB
HTML
<!-- Integrations landing — registry-driven list of every registered
|
|
integration (all provider kinds, so payments integrations appear
|
|
alongside provisioning ones). Adding a conforming integration
|
|
populates this with no edit here. Browse-only except the
|
|
unrecognized-override cleanup, which is confirm-modal-gated. -->
|
|
<h1 class="mb-1">Integrations</h1>
|
|
<p class="text-muted">External services this deployment integrates with. <span class="fw-semibold">Manage</span> opens an integration's own admin page; <span class="fw-semibold">Settings</span> edits its runtime configuration. Kind says what the integration does for members: a <em>provisioning</em> integration creates and manages member resources, a <em>payment</em> integration handles billing. Registry status is an operator-managed record, not a live health or connectivity check; Configuration reflects whether the required keys below actually resolve to a value.</p>
|
|
|
|
{{ if .Error }}
|
|
<div class="alert alert-danger" role="alert"><strong>Error:</strong> {{ .Error }}</div>
|
|
{{ else if eq (len .Integrations) 0 }}
|
|
<div class="text-center py-5">
|
|
<p class="text-muted mb-0">No integrations registered.</p>
|
|
</div>
|
|
{{ else }}
|
|
<div class="table-responsive">
|
|
<table class="table table-hover align-middle">
|
|
<thead>
|
|
<tr>
|
|
<th>Integration</th>
|
|
<th>Registry status</th>
|
|
<th>Configuration</th>
|
|
<th>Kind</th>
|
|
<th>Operations</th>
|
|
<th>Resource keys</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{ range .Integrations }}
|
|
<tr>
|
|
<td>
|
|
<span class="fw-semibold">{{ .DisplayName }}</span>
|
|
<span class="text-muted small ms-1">{{ .Slug }}</span>
|
|
</td>
|
|
<td>
|
|
{{ if eq .Status "active" }}
|
|
<span class="badge text-bg-success">Active</span>
|
|
{{ else }}
|
|
<span class="badge text-bg-secondary">{{ .Status }}</span>
|
|
{{ end }}
|
|
</td>
|
|
<td>
|
|
{{ if not .Configured }}
|
|
<span class="badge text-bg-warning" {{ if .MissingKeysText }}title="Missing: {{ .MissingKeysText }}"{{ end }}>Not configured</span>
|
|
{{ else }}
|
|
<span class="text-muted small">—</span>
|
|
{{ end }}
|
|
</td>
|
|
<td><span class="text-capitalize">{{ .Kind }}</span></td>
|
|
<td>
|
|
{{ range .Operations }}<span class="badge text-bg-light border me-1">{{ . }}</span>{{ end }}
|
|
{{ if eq (len .Operations) 0 }}<span class="text-muted small">—</span>{{ end }}
|
|
</td>
|
|
<td>
|
|
{{ range .ResourceKeys }}<code class="small me-1">{{ . }}</code>{{ end }}
|
|
{{ if eq (len .ResourceKeys) 0 }}<span class="text-muted small">—</span>{{ end }}
|
|
</td>
|
|
<td class="text-end text-nowrap">
|
|
{{ if .SurfacePath }}
|
|
<a href="{{ .SurfacePath }}" class="btn btn-sm btn-outline-primary">Manage</a>
|
|
{{ end }}
|
|
{{ if .SettingsPath }}
|
|
<a href="{{ .SettingsPath }}" class="btn btn-sm btn-outline-secondary">Settings</a>
|
|
{{ end }}
|
|
{{ if and (not .SurfacePath) (not .SettingsPath) }}
|
|
<span class="text-muted small">—</span>
|
|
{{ end }}
|
|
</td>
|
|
</tr>
|
|
{{ end }}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<p class="text-muted small mt-2">{{ len .Integrations }} integration(s) · driven by the provider registry. Non-secret settings can be overridden from each Settings page; secrets stay in the environment.</p>
|
|
{{ end }}
|
|
|
|
{{ if .Orphans }}
|
|
<h2 class="h5 mt-4">Unrecognized overrides</h2>
|
|
<p class="text-muted small">Stored configuration overrides whose key matches no installed integration — left behind by a removed integration or a retired key. They have no effect; remove them when no longer wanted.</p>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm align-middle">
|
|
<thead><tr><th>Key</th><th>Value</th><th></th></tr></thead>
|
|
<tbody>
|
|
{{ range .Orphans }}
|
|
<tr>
|
|
<td><code>{{ .Key }}</code></td>
|
|
<td><code>{{ .Value }}</code></td>
|
|
<td class="text-end">
|
|
<button type="button" class="btn btn-sm btn-outline-danger"
|
|
data-bs-toggle="modal"
|
|
data-bs-target="#confirmActionModal"
|
|
data-action-url="{{ routeURL "/operator/integrations/config-orphans/{key}" .Key }}"
|
|
data-action-method="delete"
|
|
data-action-target="#operator-body"
|
|
data-action-title="Delete stored override"
|
|
data-action-body="Delete the stored override for {{ .Key }}? It has no effect; this only removes the leftover row."
|
|
data-action-confirm-label="Delete override">
|
|
Delete
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
{{ end }}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{{ end }}
|