{% extends 'clean_base.axml' %} {% from 'actions.axml' import pagination %} {% set modal_name = 'Gists' %} {% macro gistctrl() %} { gists: [], total: 0, pages: 1, page: 1, pagination: 25, loading: false, isFiltering: false, previewing: null, previewIDE: null, gistSearch: '', originSearch: '', destinationSearch: '', eventSearch: '', actionSearch: '', workspaceSearch: '', statusFilter: '', whenFilter: '', selected: {}, bulkCount: null, bulkRunning: false, busy: null, showConfirm: false, buildQuery(page){ let q = `/v1/gists?pagination=${this.pagination}&page=${page || this.page}`; if(this.gistSearch) q += `&gist=${encodeURIComponent(this.gistSearch)}`; if(this.originSearch) q += `&origin=${encodeURIComponent(this.originSearch)}`; if(this.destinationSearch) q += `&destination=${encodeURIComponent(this.destinationSearch)}`; if(this.eventSearch) q += `&event=${encodeURIComponent(this.eventSearch)}`; if(this.actionSearch) q += `&action=${encodeURIComponent(this.actionSearch)}`; if(this.workspaceSearch) q += `&workspace=${encodeURIComponent(this.workspaceSearch)}`; if(this.statusFilter) q += `&status=${this.statusFilter}`; if(this.whenFilter) q += `&timeline=${this.whenFilter}`; return q; }, filterQuery(){ let q = ''; if(this.gistSearch) q += `&gist=${encodeURIComponent(this.gistSearch)}`; if(this.originSearch) q += `&origin=${encodeURIComponent(this.originSearch)}`; if(this.destinationSearch) q += `&destination=${encodeURIComponent(this.destinationSearch)}`; if(this.eventSearch) q += `&event=${encodeURIComponent(this.eventSearch)}`; if(this.actionSearch) q += `&action=${encodeURIComponent(this.actionSearch)}`; if(this.workspaceSearch) q += `&workspace=${encodeURIComponent(this.workspaceSearch)}`; if(this.statusFilter) q += `&status=${this.statusFilter}`; if(this.whenFilter) q += `&timeline=${this.whenFilter}`; return q; }, load(showSpinner){ if(showSpinner) this.loading = true; fetch(this.buildQuery()) .then(r => r.json()) .then(data => { this.gists = data.data || []; this.total = data.total || 0; this.pages = data.pages || 1; this.loading = false; }) .catch(() => { this.loading = false; ShowFeedback('error', 'Failed to fetch gists'); }); }, fetchAll(){ this.load(true); }, refreshPage(){ this.load(false); }, pageDown(){ if(this.page <= 1) return; this.page -= 1; this.fetchAll(); }, pageUp(){ if(this.page >= this.pages) return; this.page += 1; this.fetchAll(); }, applyFilters(){ this.page = 1; this.isFiltering = true; this.fetchAll(); }, clearFilters(){ this.gistSearch=''; this.originSearch=''; this.destinationSearch=''; this.eventSearch=''; this.actionSearch=''; this.workspaceSearch=''; this.statusFilter=''; this.whenFilter=''; this.isFiltering = false; this.page = 1; this.fetchAll(); }, statusClass(s){ return { delivered: 'success', failed: 'danger', retrying: 'warning', pending: '' }[s] || ''; }, truncate(text, max){ if(!text) return ''; return text.length > max ? text.slice(0, max) + '...' : text; }, toggle(id){ this.selected[id] = !this.selected[id]; }, selectedIds(){ return Object.keys(this.selected).filter(k => this.selected[k]); }, anySelected(){ return this.selectedIds().length > 0; }, clearSelection(){ this.selected = {}; }, replayOne(id){ this.busy = id; fetch(`/v1/regists/${id}`, { method: 'POST', credentials: 'include' }) .then(async r => { if(!r.ok) throw await r.json().catch(() => ({})); return r.json(); }) .then(data => { if(data.delivered) ShowFeedback('success', `Gist ${id} replayed — delivered (${data.status_code})`); else ShowFeedback('warning', `Gist ${id} replayed but still failing${data.status_code ? ' ('+data.status_code+')' : ''}`); this.refreshPage(); }) .catch(err => ShowFeedback('error', err?.error || 'Replay failed')) .finally(() => { this.busy = null; }); }, requeueOne(id){ this.busy = id; fetch(`/v1/requeues?gist=${id}`, { method: 'POST', credentials: 'include' }) .then(async r => { if(!r.ok) throw await r.json().catch(() => ({})); return r.json(); }) .then(data => { ShowFeedback('success', `Gist ${id} requeued — daemon will retry it`); this.refreshPage(); }) .catch(err => ShowFeedback('error', err?.error || 'Requeue failed')) .finally(() => { this.busy = null; }); }, askBulk(){ let q = this.filterQuery(); if(!this.statusFilter) q += '&status=failed'; // bulk defaults to failed fetch(`/v1/regists?dummy=1${q}`, { credentials: 'include' }) .then(r => r.json()) .then(data => { this.bulkCount = data.count || 0; this.showConfirm = true; }) .catch(() => ShowFeedback('error', 'Could not compute replay count')); }, runBulk(){ let q = this.filterQuery(); if(!this.statusFilter) q += '&status=failed'; this.bulkRunning = true; fetch(`/v1/regists?dummy=1${q}`, { method: 'POST', credentials: 'include' }) .then(r => r.json()) .then(data => { this.bulkRunning = false; this.showConfirm = false; this.bulkCount = null; ShowFeedback('success', `Replayed ${data.total}: ${data.succeeded} delivered, ${data.still_failing} still failing`); this.refreshPage(); }) .catch(() => { this.bulkRunning = false; ShowFeedback('error', 'Bulk replay failed'); }); }, requeueFiltered(){ let q = this.filterQuery(); if(!this.statusFilter) q += '&status=failed'; fetch(`/v1/requeues?dummy=1${q}`, { method: 'POST', credentials: 'include' }) .then(r => r.json()) .then(data => { ShowFeedback('info', `${data.requeued} deliveries requeued for the daemon`); this.refreshPage(); }) .catch(() => ShowFeedback('error', 'Requeue failed')); }, openPreview(gist){ this.previewing = gist; this.$nextTick(() => { const el = document.getElementById('gist-payload-ide'); if(!el) return; this.previewIDE = ace.edit(el); this.previewIDE.session.setMode('ace/mode/json'); const dark = document.documentElement.getAttribute('data-bs-theme') === 'dark'; this.previewIDE.setTheme(dark ? 'ace/theme/one_dark' : 'ace/theme/chrome'); this.previewIDE.setOptions({ readOnly: true, fontSize: 13, showPrintMargin: false, wrap: true, tabSize: 2 }); this.previewIDE.setValue(prettyJson(gist.payload || {})); this.previewIDE.clearSelection(); }); } } {% endmacro %} {% block easel %}
tag
bolt
upload
download
corporate_fare
ID Status Action Workspace Publisher → Subscriber Endpoint Attempts Code Last error Last attempt Actions
Rows:
{% endblock %}