@meddleware/dao-ui 0.1.18 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +28 -6
- package/src/App.vue +7 -3
- package/src/DaoView.vue +8 -16
- package/src/components/ProposalRow.vue +63 -36
- package/src/composables/useDaoEvents.ts +3 -2
- package/src/composables/useEpoch.ts +3 -2
- package/src/composables/useGates.ts +4 -3
- package/src/composables/usePlatformConfig.ts +3 -2
- package/src/styles/qt.css +61 -231
- package/src/tabs/GovernanceTab.vue +42 -28
- package/src/tabs/HistoryTab.vue +76 -59
- package/src/tabs/OverviewTab.vue +38 -39
- package/src/tabs/ProposalsTab.vue +9 -14
- package/src/tabs/TreasuryTab.vue +23 -22
- package/src/components/DataTable.vue +0 -26
- package/src/components/Panel.vue +0 -13
- package/src/components/StatusBar.vue +0 -36
- package/src/components/TabBar.vue +0 -19
package/src/styles/qt.css
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
/*
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* dao-ui console — app-local utility classes.
|
|
3
|
+
*
|
|
4
|
+
* The structural primitives (panel, toolbar, status bar, data table, stat grid,
|
|
5
|
+
* badge, activity feed) now come from @meddleware/ui as scoped components
|
|
6
|
+
* (UiPanel, UiToolbar, UiStatusBar, UiDataTable, UiStatGrid/UiStatRow, UiBadge,
|
|
7
|
+
* UiActivityFeed/UiActivityItem). What remains here are small text/layout
|
|
8
|
+
* utilities that are specific to this console's tabs.
|
|
9
|
+
*
|
|
10
|
+
* Applied globally via DaoView.vue (so it works when embedded as a library).
|
|
6
11
|
*/
|
|
7
12
|
|
|
8
|
-
/* ──
|
|
13
|
+
/* ── Shell layout ────────────────────────────────────────────────────────── */
|
|
9
14
|
|
|
10
15
|
.dao-view {
|
|
11
16
|
display: flex;
|
|
@@ -16,48 +21,6 @@
|
|
|
16
21
|
color: var(--text);
|
|
17
22
|
}
|
|
18
23
|
|
|
19
|
-
/* ── Toolbar ─────────────────────────────────────────────────────────────── */
|
|
20
|
-
|
|
21
|
-
.dao-toolbar {
|
|
22
|
-
display: flex;
|
|
23
|
-
align-items: center;
|
|
24
|
-
gap: 4px;
|
|
25
|
-
padding: 4px 8px;
|
|
26
|
-
border-bottom: 1px solid var(--border);
|
|
27
|
-
background: var(--surface);
|
|
28
|
-
flex-shrink: 0;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.dao-toolbar__btn {
|
|
32
|
-
display: inline-flex;
|
|
33
|
-
align-items: center;
|
|
34
|
-
gap: 5px;
|
|
35
|
-
padding: 3px 10px;
|
|
36
|
-
height: 26px;
|
|
37
|
-
font-size: 0.8rem;
|
|
38
|
-
background: var(--lift);
|
|
39
|
-
border: 1px solid var(--border);
|
|
40
|
-
border-radius: 2px;
|
|
41
|
-
color: var(--text);
|
|
42
|
-
cursor: pointer;
|
|
43
|
-
white-space: nowrap;
|
|
44
|
-
transition: background 0.1s;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.dao-toolbar__btn:hover {
|
|
48
|
-
background: var(--surface);
|
|
49
|
-
border-color: var(--accent);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.dao-toolbar__sep {
|
|
53
|
-
width: 1px;
|
|
54
|
-
height: 18px;
|
|
55
|
-
background: var(--border);
|
|
56
|
-
margin: 0 4px;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/* ── Tab content area ────────────────────────────────────────────────────── */
|
|
60
|
-
|
|
61
24
|
.dao-content {
|
|
62
25
|
flex: 1;
|
|
63
26
|
overflow-y: auto;
|
|
@@ -65,108 +28,10 @@
|
|
|
65
28
|
background: var(--bg);
|
|
66
29
|
}
|
|
67
30
|
|
|
68
|
-
/* ── Status bar ──────────────────────────────────────────────────────────── */
|
|
69
|
-
|
|
70
|
-
.dao-statusbar {
|
|
71
|
-
display: flex;
|
|
72
|
-
align-items: center;
|
|
73
|
-
gap: 16px;
|
|
74
|
-
padding: 3px 12px;
|
|
75
|
-
font-size: 0.72rem;
|
|
76
|
-
color: var(--muted);
|
|
77
|
-
background: var(--surface);
|
|
78
|
-
border-top: 1px solid var(--border);
|
|
79
|
-
flex-shrink: 0;
|
|
80
|
-
font-family: var(--font-mono);
|
|
81
|
-
position: sticky;
|
|
82
|
-
bottom: 0;
|
|
83
|
-
z-index: 1;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
.dao-statusbar__dot {
|
|
87
|
-
display: inline-block;
|
|
88
|
-
width: 7px;
|
|
89
|
-
height: 7px;
|
|
90
|
-
border-radius: 50%;
|
|
91
|
-
margin-right: 4px;
|
|
92
|
-
flex-shrink: 0;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
.dao-statusbar__dot--ok { background: var(--ok); }
|
|
96
|
-
.dao-statusbar__dot--warn { background: #b08d2a; }
|
|
97
|
-
.dao-statusbar__dot--error { background: var(--danger); }
|
|
98
|
-
|
|
99
|
-
.dao-statusbar__item {
|
|
100
|
-
display: flex;
|
|
101
|
-
align-items: center;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
.dao-statusbar__sep {
|
|
105
|
-
color: var(--border);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/* ── Panel ───────────────────────────────────────────────────────────────── */
|
|
109
|
-
|
|
110
|
-
.dao-panel {
|
|
111
|
-
border: 1px solid var(--border);
|
|
112
|
-
border-radius: 2px;
|
|
113
|
-
background: var(--surface);
|
|
114
|
-
overflow: hidden;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
.dao-panel__head {
|
|
118
|
-
padding: 5px 10px;
|
|
119
|
-
font-size: 0.72rem;
|
|
120
|
-
font-weight: 600;
|
|
121
|
-
letter-spacing: 0.06em;
|
|
122
|
-
text-transform: uppercase;
|
|
123
|
-
color: var(--muted);
|
|
124
|
-
background: var(--lift);
|
|
125
|
-
border-bottom: 1px solid var(--border);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
.dao-panel__body {
|
|
129
|
-
padding: 10px;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/* ── Data table ──────────────────────────────────────────────────────────── */
|
|
133
|
-
|
|
134
|
-
.dao-table {
|
|
135
|
-
width: 100%;
|
|
136
|
-
border-collapse: collapse;
|
|
137
|
-
font-size: 0.8rem;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
.dao-table th {
|
|
141
|
-
text-align: left;
|
|
142
|
-
padding: 5px 8px;
|
|
143
|
-
font-size: 0.7rem;
|
|
144
|
-
font-weight: 600;
|
|
145
|
-
letter-spacing: 0.05em;
|
|
146
|
-
text-transform: uppercase;
|
|
147
|
-
color: var(--muted);
|
|
148
|
-
border-bottom: 1px solid var(--border);
|
|
149
|
-
white-space: nowrap;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
.dao-table td {
|
|
153
|
-
padding: 5px 8px;
|
|
154
|
-
border-bottom: 1px solid var(--border);
|
|
155
|
-
vertical-align: middle;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
.dao-table tr:last-child td {
|
|
159
|
-
border-bottom: none;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
.dao-table tr:nth-child(even) td {
|
|
163
|
-
background: var(--lift);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
31
|
/* ── Amount cells (monospace, right-aligned) ─────────────────────────────── */
|
|
167
32
|
|
|
168
33
|
.dao-amount {
|
|
169
|
-
font-family: var(--font-mono);
|
|
34
|
+
font-family: var(--mw-font-mono);
|
|
170
35
|
font-size: 0.8rem;
|
|
171
36
|
text-align: right;
|
|
172
37
|
white-space: nowrap;
|
|
@@ -176,26 +41,6 @@
|
|
|
176
41
|
color: var(--muted);
|
|
177
42
|
}
|
|
178
43
|
|
|
179
|
-
/* ── Stat grid (Overview key/value pairs) ────────────────────────────────── */
|
|
180
|
-
|
|
181
|
-
.dao-stat-grid {
|
|
182
|
-
display: grid;
|
|
183
|
-
grid-template-columns: auto 1fr;
|
|
184
|
-
gap: 3px 12px;
|
|
185
|
-
font-size: 0.8rem;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
.dao-stat-grid__label {
|
|
189
|
-
color: var(--muted);
|
|
190
|
-
white-space: nowrap;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
.dao-stat-grid__value {
|
|
194
|
-
font-family: var(--font-mono);
|
|
195
|
-
color: var(--text);
|
|
196
|
-
text-align: right;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
44
|
/* ── Two-column overview layout ──────────────────────────────────────────── */
|
|
200
45
|
|
|
201
46
|
.dao-overview-cols {
|
|
@@ -204,69 +49,38 @@
|
|
|
204
49
|
gap: 10px;
|
|
205
50
|
}
|
|
206
51
|
|
|
207
|
-
@media (
|
|
208
|
-
.dao-overview-cols {
|
|
52
|
+
@media (width <= 640px) {
|
|
53
|
+
.dao-overview-cols {
|
|
54
|
+
grid-template-columns: 1fr;
|
|
55
|
+
}
|
|
209
56
|
}
|
|
210
57
|
|
|
211
58
|
/* ── Proposal progress bar ───────────────────────────────────────────────── */
|
|
212
59
|
|
|
60
|
+
/* A native <progress>: engines paint the track/value with their own pseudo-elements. */
|
|
213
61
|
.dao-progress {
|
|
62
|
+
display: block;
|
|
63
|
+
width: 100%;
|
|
214
64
|
height: 6px;
|
|
65
|
+
margin: 3px 0;
|
|
66
|
+
appearance: none;
|
|
215
67
|
background: var(--lift);
|
|
216
68
|
border: 1px solid var(--border);
|
|
217
69
|
border-radius: 1px;
|
|
218
70
|
overflow: hidden;
|
|
219
|
-
margin: 3px 0;
|
|
220
71
|
}
|
|
221
72
|
|
|
222
|
-
.dao-
|
|
223
|
-
|
|
224
|
-
background: var(--accent);
|
|
225
|
-
transition: width 0.3s ease;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/* ── Activity feed ───────────────────────────────────────────────────────── */
|
|
229
|
-
|
|
230
|
-
.dao-feed {
|
|
231
|
-
list-style: none;
|
|
232
|
-
padding: 0;
|
|
233
|
-
margin: 0;
|
|
234
|
-
font-size: 0.78rem;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
.dao-feed__item {
|
|
238
|
-
display: flex;
|
|
239
|
-
align-items: flex-start;
|
|
240
|
-
gap: 8px;
|
|
241
|
-
padding: 4px 0;
|
|
242
|
-
border-bottom: 1px solid var(--border);
|
|
243
|
-
color: var(--muted);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
.dao-feed__item:last-child {
|
|
247
|
-
border-bottom: none;
|
|
73
|
+
.dao-progress::-webkit-progress-bar {
|
|
74
|
+
background: var(--lift);
|
|
248
75
|
}
|
|
249
76
|
|
|
250
|
-
.dao-
|
|
251
|
-
width: 6px;
|
|
252
|
-
height: 6px;
|
|
253
|
-
border-radius: 50%;
|
|
77
|
+
.dao-progress::-webkit-progress-value {
|
|
254
78
|
background: var(--accent);
|
|
255
|
-
|
|
256
|
-
flex-shrink: 0;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
.dao-feed__type {
|
|
260
|
-
color: var(--text);
|
|
261
|
-
font-weight: 500;
|
|
262
|
-
white-space: nowrap;
|
|
79
|
+
transition: width 0.3s ease;
|
|
263
80
|
}
|
|
264
81
|
|
|
265
|
-
.dao-
|
|
266
|
-
|
|
267
|
-
white-space: nowrap;
|
|
268
|
-
font-family: var(--font-mono);
|
|
269
|
-
font-size: 0.72rem;
|
|
82
|
+
.dao-progress::-moz-progress-bar {
|
|
83
|
+
background: var(--accent);
|
|
270
84
|
}
|
|
271
85
|
|
|
272
86
|
/* ── Info tooltip marker ─────────────────────────────────────────────────── */
|
|
@@ -299,31 +113,47 @@
|
|
|
299
113
|
margin-top: 10px;
|
|
300
114
|
}
|
|
301
115
|
|
|
302
|
-
/* ──
|
|
116
|
+
/* ── Layout utilities ────────────────────────────────────────────────────── */
|
|
117
|
+
|
|
118
|
+
/* Vertical stack of panels within a tab. */
|
|
119
|
+
.dao-stack {
|
|
120
|
+
display: flex;
|
|
121
|
+
flex-direction: column;
|
|
122
|
+
gap: 10px;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.dao-stack--tight {
|
|
126
|
+
gap: 8px;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* Key/value readouts stay compact rather than spanning a wide panel. */
|
|
130
|
+
.dao-stat-grid {
|
|
131
|
+
max-width: 480px;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* ── Misc text utilities ─────────────────────────────────────────────────── */
|
|
303
135
|
|
|
304
136
|
.dao-mono {
|
|
305
|
-
font-family: var(--font-mono);
|
|
137
|
+
font-family: var(--mw-font-mono);
|
|
306
138
|
font-size: 0.8rem;
|
|
307
139
|
}
|
|
308
140
|
|
|
309
|
-
.dao-
|
|
310
|
-
|
|
311
|
-
font-size: 0.78rem;
|
|
141
|
+
.dao-mono--sm {
|
|
142
|
+
font-size: 0.7rem;
|
|
312
143
|
}
|
|
313
144
|
|
|
314
|
-
.dao-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
letter-spacing: 0.04em;
|
|
321
|
-
text-transform: uppercase;
|
|
145
|
+
.dao-nowrap {
|
|
146
|
+
white-space: nowrap;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.dao-flush {
|
|
150
|
+
margin: 0;
|
|
322
151
|
}
|
|
323
152
|
|
|
324
|
-
.dao-
|
|
325
|
-
|
|
326
|
-
|
|
153
|
+
.dao-muted {
|
|
154
|
+
color: var(--muted);
|
|
155
|
+
font-size: 0.78rem;
|
|
156
|
+
}
|
|
327
157
|
|
|
328
158
|
.dao-section-title {
|
|
329
159
|
font-size: 0.72rem;
|
|
@@ -336,10 +166,10 @@
|
|
|
336
166
|
|
|
337
167
|
.dao-notice {
|
|
338
168
|
padding: 8px 10px;
|
|
339
|
-
border: 1px solid
|
|
169
|
+
border: 1px solid var(--warning);
|
|
340
170
|
border-radius: 2px;
|
|
341
|
-
background: color-mix(in srgb,
|
|
342
|
-
color:
|
|
171
|
+
background: color-mix(in srgb, var(--warning) 10%, transparent);
|
|
172
|
+
color: var(--warning);
|
|
343
173
|
font-size: 0.78rem;
|
|
344
174
|
margin-bottom: 10px;
|
|
345
175
|
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { ref, watch, computed } from 'vue'
|
|
3
|
-
import Panel from '../components/Panel.vue'
|
|
4
3
|
import { usePlatformConfig } from '../composables/usePlatformConfig.js'
|
|
5
4
|
import { useWallet, getSuiClient } from '../wallet.js'
|
|
6
5
|
import { PACKAGE_ID } from '../config.js'
|
|
7
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
CopyableAddress,
|
|
8
|
+
ExplorerLink,
|
|
9
|
+
suiExplorerUrl,
|
|
10
|
+
UiPanel,
|
|
11
|
+
UiStatGrid,
|
|
12
|
+
UiStatRow,
|
|
13
|
+
} from '@meddleware/ui'
|
|
8
14
|
import { NETWORK } from '../config.js'
|
|
9
15
|
|
|
10
16
|
const { config } = usePlatformConfig()
|
|
@@ -44,60 +50,55 @@ watch(
|
|
|
44
50
|
</script>
|
|
45
51
|
|
|
46
52
|
<template>
|
|
47
|
-
<div
|
|
48
|
-
<
|
|
49
|
-
<
|
|
50
|
-
<
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
<span class="dao-stat-grid__label">Max commission cap</span>
|
|
54
|
-
<span class="dao-stat-grid__value dao-mono">10.00% (1000 bps — on-chain hard cap)</span>
|
|
55
|
-
|
|
56
|
-
<span class="dao-stat-grid__label">Treasury address</span>
|
|
57
|
-
<span class="dao-stat-grid__value" style="text-align: left">
|
|
53
|
+
<div class="dao-stack gov">
|
|
54
|
+
<UiPanel title="Platform Parameters">
|
|
55
|
+
<UiStatGrid class="dao-stat-grid">
|
|
56
|
+
<UiStatRow label="Commission rate">{{ commissionPct }}</UiStatRow>
|
|
57
|
+
<UiStatRow label="Max commission cap">10.00% (1000 bps — on-chain hard cap)</UiStatRow>
|
|
58
|
+
<UiStatRow label="Treasury address" align="left">
|
|
58
59
|
<CopyableAddress v-if="config?.treasury" :address="config.treasury">
|
|
59
60
|
<ExplorerLink :href="suiExplorerUrl('account', config.treasury, NETWORK)" :value="config.treasury" />
|
|
60
61
|
</CopyableAddress>
|
|
61
|
-
<span v-else class="dao-mono
|
|
62
|
-
</
|
|
63
|
-
</
|
|
62
|
+
<span v-else class="dao-mono dao-mono--sm">—</span>
|
|
63
|
+
</UiStatRow>
|
|
64
|
+
</UiStatGrid>
|
|
64
65
|
|
|
65
|
-
<p class="dao-muted
|
|
66
|
+
<p class="dao-muted gov__footnote">
|
|
66
67
|
Parameters are governed by <code>PlatformAdminCap</code> on-chain.
|
|
67
68
|
Commission is charged on every NFT access purchase:
|
|
68
69
|
<code>commission_bps / 10000 × price</code> routes to treasury;
|
|
69
70
|
the remainder goes to the gate operator.
|
|
70
71
|
</p>
|
|
71
|
-
</
|
|
72
|
+
</UiPanel>
|
|
72
73
|
|
|
73
|
-
<
|
|
74
|
+
<UiPanel title="Admin Actions">
|
|
74
75
|
<!-- Not connected -->
|
|
75
76
|
<template v-if="!account">
|
|
76
|
-
<p class="dao-muted"
|
|
77
|
+
<p class="dao-muted">
|
|
77
78
|
Connect a wallet via the header to manage platform settings.
|
|
78
79
|
</p>
|
|
79
80
|
</template>
|
|
80
81
|
|
|
81
82
|
<!-- Connected, checking -->
|
|
82
83
|
<template v-else-if="capState === 'checking'">
|
|
83
|
-
<p class="dao-muted"
|
|
84
|
+
<p class="dao-muted">
|
|
84
85
|
Checking capabilities for {{ account.address.slice(0, 10) }}…
|
|
85
86
|
</p>
|
|
86
87
|
</template>
|
|
87
88
|
|
|
88
89
|
<!-- Connected, has PlatformAdminCap -->
|
|
89
90
|
<template v-else-if="capState === 'found'">
|
|
90
|
-
<p class="dao-muted"
|
|
91
|
-
<span
|
|
91
|
+
<p class="dao-muted">
|
|
92
|
+
<span class="gov__ok" aria-hidden="true">●</span>
|
|
92
93
|
<code>PlatformAdminCap</code> detected. Admin controls will appear here when implemented.
|
|
93
94
|
</p>
|
|
94
95
|
</template>
|
|
95
96
|
|
|
96
97
|
<!-- Connected, no cap -->
|
|
97
98
|
<template v-else-if="capState === 'not-found'">
|
|
98
|
-
<p class="dao-muted"
|
|
99
|
-
<span>●</span>
|
|
100
|
-
Connected: {{ account.address.slice(0, 10) }}…{{ account.address.slice(-6) }}<br
|
|
99
|
+
<p class="dao-muted">
|
|
100
|
+
<span aria-hidden="true">●</span>
|
|
101
|
+
Connected: {{ account.address.slice(0, 10) }}…{{ account.address.slice(-6) }}<br />
|
|
101
102
|
This wallet does not hold <code>PlatformAdminCap</code> or <code>DaoAdminCap</code>.
|
|
102
103
|
Privileged actions are not available.
|
|
103
104
|
</p>
|
|
@@ -105,10 +106,23 @@ watch(
|
|
|
105
106
|
|
|
106
107
|
<!-- Error -->
|
|
107
108
|
<template v-else-if="capState === 'error'">
|
|
108
|
-
<p class="dao-muted"
|
|
109
|
+
<p class="dao-muted">
|
|
109
110
|
Unable to verify capabilities. Check your connection and try again.
|
|
110
111
|
</p>
|
|
111
112
|
</template>
|
|
112
|
-
</
|
|
113
|
+
</UiPanel>
|
|
113
114
|
</div>
|
|
114
115
|
</template>
|
|
116
|
+
|
|
117
|
+
<style scoped>
|
|
118
|
+
.gov p {
|
|
119
|
+
margin: 0;
|
|
120
|
+
}
|
|
121
|
+
.gov .gov__footnote {
|
|
122
|
+
margin-top: 10px;
|
|
123
|
+
font-size: 0.72rem;
|
|
124
|
+
}
|
|
125
|
+
.gov__ok {
|
|
126
|
+
color: var(--ok);
|
|
127
|
+
}
|
|
128
|
+
</style>
|
package/src/tabs/HistoryTab.vue
CHANGED
|
@@ -2,9 +2,15 @@
|
|
|
2
2
|
// History tab: paginated on-chain access-gate event log (sold / used / burned) with
|
|
3
3
|
// per-row explorer links. Data comes from useDaoEvents (pruning-tolerant, merged feed).
|
|
4
4
|
import { ref, computed } from 'vue'
|
|
5
|
-
import DataTable from '../components/DataTable.vue'
|
|
6
5
|
import { useDaoEvents } from '../composables/useDaoEvents.js'
|
|
7
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
CopyableAddress,
|
|
8
|
+
ExplorerLink,
|
|
9
|
+
suiExplorerUrl,
|
|
10
|
+
UiDataTable,
|
|
11
|
+
UiBadge,
|
|
12
|
+
UiToolbarButton,
|
|
13
|
+
} from '@meddleware/ui'
|
|
8
14
|
import { NETWORK } from '../config.js'
|
|
9
15
|
import type { DaoEvent } from '../composables/useDaoEvents.js'
|
|
10
16
|
|
|
@@ -27,67 +33,78 @@ const eventLabel: Record<DaoEvent['type'], string> = {
|
|
|
27
33
|
AccessBurned: 'Access Burned',
|
|
28
34
|
}
|
|
29
35
|
|
|
36
|
+
function badgeVariant(type: DaoEvent['type']): 'active' | 'closed' {
|
|
37
|
+
return type === 'AccessMinted' ? 'active' : 'closed'
|
|
38
|
+
}
|
|
30
39
|
</script>
|
|
31
40
|
|
|
32
41
|
<template>
|
|
33
|
-
<
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
</div>
|
|
42
|
+
<header class="history__head">
|
|
43
|
+
<h2 class="dao-section-title">On-Chain Events</h2>
|
|
44
|
+
<UiToolbarButton :disabled="loading" @click="reload">
|
|
45
|
+
{{ loading ? 'Loading…' : 'Refresh' }}
|
|
46
|
+
</UiToolbarButton>
|
|
47
|
+
</header>
|
|
40
48
|
|
|
41
|
-
|
|
49
|
+
<p v-if="error" class="dao-muted">{{ error }}</p>
|
|
42
50
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
<td class="dao-mono" style="font-size: 0.72rem; white-space: nowrap">
|
|
79
|
-
<CopyableAddress :address="ev.txDigest" label="Copy transaction">
|
|
80
|
-
<ExplorerLink :href="suiExplorerUrl('txblock', ev.txDigest, NETWORK)" :value="ev.txDigest" />
|
|
81
|
-
</CopyableAddress>
|
|
82
|
-
</td>
|
|
83
|
-
</tr>
|
|
84
|
-
</DataTable>
|
|
85
|
-
<p v-else-if="!loading" class="dao-placeholder">No events found.</p>
|
|
51
|
+
<UiDataTable v-if="pageEvents.length || loading" :empty="'No events'">
|
|
52
|
+
<template #head>
|
|
53
|
+
<th>Type</th>
|
|
54
|
+
<th>
|
|
55
|
+
Address
|
|
56
|
+
<abbr class="dao-info" title="The wallet address associated with this event (recipient, creator, or initiator depending on event type). Click to view in explorer; click the copy icon to copy the full address.">?</abbr>
|
|
57
|
+
</th>
|
|
58
|
+
<th>
|
|
59
|
+
Block
|
|
60
|
+
<abbr class="dao-info" title="Sui checkpoint sequence number — equivalent to a block height in other blockchains. Each checkpoint finalizes a batch of transactions; higher numbers are more recent.">?</abbr>
|
|
61
|
+
</th>
|
|
62
|
+
<th>
|
|
63
|
+
Transaction
|
|
64
|
+
<abbr class="dao-info" title="Transaction digest — a unique identifier for the transaction that emitted this event. Click to view in explorer; click the copy icon to copy the full digest.">?</abbr>
|
|
65
|
+
</th>
|
|
66
|
+
</template>
|
|
67
|
+
<tr v-for="ev in pageEvents" :key="ev.txDigest">
|
|
68
|
+
<td><UiBadge :variant="badgeVariant(ev.type)">{{ eventLabel[ev.type] }}</UiBadge></td>
|
|
69
|
+
<td class="dao-mono history__cell history__cell--nowrap">
|
|
70
|
+
<CopyableAddress v-if="ev.address && ev.address !== 'undefined'" :address="ev.address">
|
|
71
|
+
<ExplorerLink :href="suiExplorerUrl('account', ev.address, NETWORK)" :value="ev.address" />
|
|
72
|
+
</CopyableAddress>
|
|
73
|
+
<span v-else>—</span>
|
|
74
|
+
</td>
|
|
75
|
+
<td class="dao-mono history__cell">
|
|
76
|
+
{{ ev.checkpoint ? '#' + ev.checkpoint : '—' }}
|
|
77
|
+
</td>
|
|
78
|
+
<td class="dao-mono history__cell history__cell--nowrap">
|
|
79
|
+
<CopyableAddress :address="ev.txDigest" label="Copy transaction">
|
|
80
|
+
<ExplorerLink :href="suiExplorerUrl('txblock', ev.txDigest, NETWORK)" :value="ev.txDigest" />
|
|
81
|
+
</CopyableAddress>
|
|
82
|
+
</td>
|
|
83
|
+
</tr>
|
|
84
|
+
</UiDataTable>
|
|
85
|
+
<p v-else-if="!loading" class="dao-placeholder">No events found.</p>
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
</div>
|
|
87
|
+
<nav v-if="totalPages > 1" class="dao-pagination" aria-label="Event pages">
|
|
88
|
+
<UiToolbarButton :disabled="page === 1" @click="prevPage">← Prev</UiToolbarButton>
|
|
89
|
+
<span class="dao-muted">Page {{ page }} / {{ totalPages }}</span>
|
|
90
|
+
<UiToolbarButton :disabled="page === totalPages" @click="nextPage">Next →</UiToolbarButton>
|
|
91
|
+
</nav>
|
|
93
92
|
</template>
|
|
93
|
+
|
|
94
|
+
<style scoped>
|
|
95
|
+
.history__head {
|
|
96
|
+
display: flex;
|
|
97
|
+
align-items: center;
|
|
98
|
+
justify-content: space-between;
|
|
99
|
+
margin-bottom: 8px;
|
|
100
|
+
}
|
|
101
|
+
.history__head .dao-section-title {
|
|
102
|
+
margin: 0;
|
|
103
|
+
}
|
|
104
|
+
.history__cell {
|
|
105
|
+
font-size: 0.72rem;
|
|
106
|
+
}
|
|
107
|
+
.history__cell--nowrap {
|
|
108
|
+
white-space: nowrap;
|
|
109
|
+
}
|
|
110
|
+
</style>
|