@block-auth.io/angular 0.1.1 → 0.2.0
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/.turbo/turbo-build.log +7 -7
- package/.turbo/turbo-lint.log +4 -4
- package/.turbo/turbo-test.log +1216 -82
- package/.turbo/turbo-typecheck.log +19 -4
- package/CHANGELOG.md +13 -0
- package/package.json +2 -2
- package/src/lib/components/dds/dropdown-profile-btn.component.ts +13 -28
- package/src/lib/components/dds/dropdown-profile.component.test.ts +14 -2
- package/src/lib/components/dds/dropdown-profile.component.ts +25 -19
- package/src/lib/components/txns/internals/permissions-required-modal.component.test.ts +16 -3
- package/src/lib/components/txns/internals/permissions-required-modal.component.ts +24 -16
- package/src/lib/components/txns/internals/solicited-data-modal.component.test.ts +37 -5
- package/src/lib/components/txns/internals/solicited-data-modal.component.ts +98 -65
- package/src/lib/components/txns/internals/txn-error.component.test.ts +33 -6
- package/src/lib/components/txns/internals/txn-error.component.ts +52 -29
- package/src/lib/components/txns/internals/txn.component.test.ts +63 -16
- package/src/lib/components/txns/internals/txn.component.ts +141 -61
- package/src/lib/components/txns/txns-overview.component.ts +109 -91
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
output,
|
|
9
9
|
signal,
|
|
10
10
|
} from '@angular/core';
|
|
11
|
+
import { $locale, t as translate, type TextKey } from '@block-auth.io/core';
|
|
12
|
+
import { injectStore } from '../../../inject-store';
|
|
11
13
|
import { injectBlockAuthClient } from '../../../provide-block-auth';
|
|
12
14
|
import { ArrowIconComponent } from '../../../primitives/arrow-icon.component';
|
|
13
15
|
import { LifetimeSliderBaseComponent } from '../../../primitives/lifetime-slider-base.component';
|
|
@@ -42,16 +44,22 @@ interface TxnPreParams {
|
|
|
42
44
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
43
45
|
imports: [ArrowIconComponent, LifetimeSliderBaseComponent],
|
|
44
46
|
template: `
|
|
45
|
-
<div
|
|
46
|
-
|
|
47
|
+
<div
|
|
48
|
+
class="bas-flex bas-h-full bas-w-full bas-flex-col bas-items-center bas-justify-between"
|
|
49
|
+
>
|
|
50
|
+
<div
|
|
51
|
+
class="bal-ba-transition-3 bas-flex bas-w-full bas-flex-col bas-gap-8 bas-pt-2"
|
|
52
|
+
>
|
|
47
53
|
<div
|
|
48
54
|
class="bal-ba-outline-none bas-grid bas-h-[30px] bas-cursor-pointer bas-grid-cols-[65px_auto_65px] bas-items-center bas-justify-center bas-gap-2"
|
|
49
55
|
(click)="permissionsRequiredClicked.emit()"
|
|
50
56
|
>
|
|
51
57
|
<ba-arrow-icon direction="right" />
|
|
52
58
|
<div class="bas-flex bas-h-full bas-w-full bas-items-end">
|
|
53
|
-
<p
|
|
54
|
-
|
|
59
|
+
<p
|
|
60
|
+
class="bas-m-0 bas-text-center bas-text-lg bas-font-medium bas-text-[var(--bal-primary-900)]"
|
|
61
|
+
>
|
|
62
|
+
{{ permissionsRequiredTxtResolved() }}
|
|
55
63
|
</p>
|
|
56
64
|
</div>
|
|
57
65
|
<ba-arrow-icon direction="left" />
|
|
@@ -60,12 +68,16 @@ interface TxnPreParams {
|
|
|
60
68
|
<div
|
|
61
69
|
[class]="
|
|
62
70
|
'bas-grid bas-h-[30px] bas-grid-cols-[65px_auto_65px] bas-items-center bas-justify-center bas-gap-2 ' +
|
|
63
|
-
(hasSolicitedData()
|
|
71
|
+
(hasSolicitedData()
|
|
72
|
+
? 'bas-cursor-pointer'
|
|
73
|
+
: 'bas-cursor-not-allowed bas-opacity-40')
|
|
64
74
|
"
|
|
65
75
|
(click)="onSolicitedDataClick()"
|
|
66
76
|
>
|
|
67
77
|
<ba-arrow-icon direction="right" />
|
|
68
|
-
<div
|
|
78
|
+
<div
|
|
79
|
+
class="bas-flex bas-h-full bas-w-full bas-items-end bas-justify-center"
|
|
80
|
+
>
|
|
69
81
|
<p
|
|
70
82
|
[class]="
|
|
71
83
|
'bas-m-0 bas-text-center bas-text-lg bas-transition-colors ' +
|
|
@@ -74,7 +86,7 @@ interface TxnPreParams {
|
|
|
74
86
|
: 'bas-text-slate-400')
|
|
75
87
|
"
|
|
76
88
|
>
|
|
77
|
-
{{
|
|
89
|
+
{{ solicitedDataTxtResolved() }}
|
|
78
90
|
</p>
|
|
79
91
|
</div>
|
|
80
92
|
<ba-arrow-icon direction="left" />
|
|
@@ -82,40 +94,55 @@ interface TxnPreParams {
|
|
|
82
94
|
</div>
|
|
83
95
|
|
|
84
96
|
@if (!showLifetime()) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
97
|
+
<button
|
|
98
|
+
type="button"
|
|
99
|
+
id="btn-configure-session-time"
|
|
100
|
+
class="bal-ba-transition-2 bas-flex bas-w-full bas-cursor-pointer bas-flex-row bas-items-end bas-justify-center bas-gap-2 bas-border-0 bas-bg-transparent bas-text-[--bal-primary-700] hover:bas-text-[--bal-primary-900]"
|
|
101
|
+
(click)="showLifetime.set(true)"
|
|
102
|
+
>
|
|
103
|
+
<p class="bas-m-0 bas-text-center bas-text-base">
|
|
104
|
+
{{ configureSessionTimeTxtResolved() }}
|
|
105
|
+
</p>
|
|
106
|
+
<svg
|
|
107
|
+
class="bas-h-5 bas-w-5"
|
|
108
|
+
viewBox="0 0 24 24"
|
|
109
|
+
fill="none"
|
|
110
|
+
stroke="currentColor"
|
|
111
|
+
stroke-width="1.8"
|
|
112
|
+
aria-hidden="true"
|
|
90
113
|
>
|
|
91
|
-
<
|
|
92
|
-
<
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
114
|
+
<circle cx="12" cy="12" r="9" />
|
|
115
|
+
<path
|
|
116
|
+
d="M12 7v5l3 2"
|
|
117
|
+
stroke-linecap="round"
|
|
118
|
+
stroke-linejoin="round"
|
|
119
|
+
/>
|
|
120
|
+
</svg>
|
|
121
|
+
</button>
|
|
97
122
|
} @else {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
<ba-lifetime-slider-base
|
|
124
|
+
id="txn-lifetime-slider"
|
|
125
|
+
[sliderValue]="lifetimeSign()"
|
|
126
|
+
[step]="1"
|
|
127
|
+
[min]="minLifetime()"
|
|
128
|
+
[max]="maxLifetime()"
|
|
129
|
+
[timeInputValue]="lifetimeTimeValue()"
|
|
130
|
+
[isOpen]="isTimePickerOpen()"
|
|
131
|
+
[isTimePickerInsideModal]="true"
|
|
132
|
+
modalId="txns-overview"
|
|
133
|
+
timePickerDropdownDirection="up"
|
|
134
|
+
classNames="bas-grid bas-h-auto bas-w-full bas-items-center bas-gap-3 bas-grid-cols-[152px_1fr]"
|
|
135
|
+
timePickerContainerClassNames="bas-flex bas-w-full bas-items-center bas-justify-center"
|
|
136
|
+
(sliderValueChanged)="onLifetimeValueChanged($event)"
|
|
137
|
+
(timeChanged)="onLifetimeValueChanged($event)"
|
|
138
|
+
(isOpenChange)="isTimePickerOpen.set($event)"
|
|
139
|
+
(toggleTimerDropdown)="toggleTimerDropdown()"
|
|
140
|
+
/>
|
|
116
141
|
}
|
|
117
142
|
|
|
118
|
-
<div
|
|
143
|
+
<div
|
|
144
|
+
class="bal-ba-transition-3 bas-flex bas-w-full bas-flex-col bas-gap-8 bas-pb-4"
|
|
145
|
+
>
|
|
119
146
|
<div
|
|
120
147
|
data-testid="txn-pptc-toggle"
|
|
121
148
|
[class]="
|
|
@@ -139,21 +166,29 @@ interface TxnPreParams {
|
|
|
139
166
|
class="bal-ba-checkbox-animated-input bal-ba-outline-none bas-peer bas-hidden"
|
|
140
167
|
(change)="pptcAccepted.set(!pptcAccepted())"
|
|
141
168
|
/>
|
|
142
|
-
<span
|
|
169
|
+
<span
|
|
170
|
+
class="bal-ba-input-check bal-ba-input-check-big bal-ba-transition-3 bas-relative bas-top-0 bas-inline-block bas-h-[25px] bas-w-[25px] bas-cursor-pointer bas-rounded-[4px] bas-border-2 bas-border-solid bas-border-[#c2c6c8] group-hover:bas-border-[#61a5c2] peer-checked:bas-border-2 peer-checked:bas-border-solid peer-checked:bas-border-[var(--bal-primary-600)] peer-checked:bas-bg-[var(--bal-primary-600)] peer-disabled:bas-cursor-not-allowed peer-disabled:bas-opacity-50"
|
|
171
|
+
></span>
|
|
143
172
|
</label>
|
|
144
173
|
</div>
|
|
145
|
-
<div
|
|
174
|
+
<div
|
|
175
|
+
class="bas-flex bas-flex-col bas-gap-0.5 bas-text-sm bas-text-[var(--bal-primary-500)] group-hover:bas-text-[var(--bal-primary-800)]"
|
|
176
|
+
>
|
|
146
177
|
<div class="bas-flex bas-flex-row bas-items-center bas-gap-1">
|
|
147
|
-
<p class="bal-ba-transition-2 bas-m-0 bas-cursor-default">
|
|
178
|
+
<p class="bal-ba-transition-2 bas-m-0 bas-cursor-default">
|
|
179
|
+
{{ iAuthorizeTheTxtResolved() }}
|
|
180
|
+
</p>
|
|
148
181
|
<button
|
|
149
182
|
type="button"
|
|
150
183
|
data-testid="btn-privacy-policy"
|
|
151
184
|
class="bal-ba-transition-2 bas-flex bas-h-full bas-cursor-pointer bas-items-center bas-border-none bas-bg-transparent bas-p-0 bas-pb-[1px] bas-text-sm bas-text-[var(--bal-primary-700)] bas-underline group-hover:bas-text-[var(--bal-primary-900)]"
|
|
152
185
|
(click)="openPrivacyPolicy()"
|
|
153
186
|
>
|
|
154
|
-
{{
|
|
187
|
+
{{ privacyPolicyTxtResolved() }}
|
|
155
188
|
</button>
|
|
156
|
-
<p class="bal-ba-transition-2 bas-m-0 bas-cursor-default">
|
|
189
|
+
<p class="bal-ba-transition-2 bas-m-0 bas-cursor-default">
|
|
190
|
+
{{ andTheTxtResolved() }}
|
|
191
|
+
</p>
|
|
157
192
|
</div>
|
|
158
193
|
<button
|
|
159
194
|
type="button"
|
|
@@ -161,19 +196,23 @@ interface TxnPreParams {
|
|
|
161
196
|
class="bal-ba-transition-2 bas-flex bas-h-full bas-w-fit bas-cursor-pointer bas-items-center bas-border-none bas-bg-transparent bas-p-0 bas-pb-[1px] bas-text-sm bas-text-[var(--bal-primary-700)] bas-underline group-hover:bas-text-[var(--bal-primary-900)]"
|
|
162
197
|
(click)="openTermsAndConditions()"
|
|
163
198
|
>
|
|
164
|
-
{{
|
|
199
|
+
{{ termsAndConditionsTxtResolved() }}
|
|
165
200
|
</button>
|
|
166
201
|
</div>
|
|
167
202
|
</div>
|
|
168
|
-
<div
|
|
203
|
+
<div
|
|
204
|
+
class="bas-flex bas-w-full bas-flex-row bas-items-center bas-justify-between bas-gap-2"
|
|
205
|
+
>
|
|
169
206
|
<button
|
|
170
207
|
type="button"
|
|
171
208
|
id="btn-txn-reject"
|
|
172
209
|
class="bal-ba-ring-base bal-ba-ring bal-ba-transition-2 bas-group bas-relative bas-box-border bas-flex bas-flex-row bas-gap-2 bas-items-center bas-overflow-hidden bas-bg-transparent bal-ba-hover-ring-slate-400 bal-ba-focus-ring-slate-400 bas-h-[42px] bas-px-2.5 bas-py-0 disabled:bas-cursor-not-allowed disabled:bas-opacity-50 bal-ba-hover-ring-2 bas-cursor-pointer bal-ba-focus-ring-2 focus:bas-opacity-90 bal-ba-focus-ring-offset-0 bas-w-full bas-justify-center bas-border-2 bas-border-slate-400 bas-rounded-md bas-border-solid"
|
|
173
210
|
(click)="onTxnRejectClicked()"
|
|
174
211
|
>
|
|
175
|
-
<span
|
|
176
|
-
|
|
212
|
+
<span
|
|
213
|
+
class="bal-ba-transition-2 bas-text-center bas-text-base bas-font-medium bas-text-slate-600 group-hover:bas-text-slate-800 bas-flex bas-h-full bas-items-center"
|
|
214
|
+
>
|
|
215
|
+
{{ rejectTxtResolved() }}
|
|
177
216
|
</span>
|
|
178
217
|
</button>
|
|
179
218
|
<button
|
|
@@ -183,8 +222,10 @@ interface TxnPreParams {
|
|
|
183
222
|
class="bal-ba-ring-base bal-ba-ring bal-ba-transition-2 bas-group bas-relative bas-box-border bas-flex bas-flex-row bas-gap-2 bas-items-center bas-overflow-hidden bas-bg-[#38b000] hover:bas-bg-[#329e00] bal-ba-hover-ring-green-500 bal-ba-focus-ring-green-500 bas-h-[42px] bas-px-2.5 bas-py-0 disabled:bas-cursor-not-allowed disabled:bas-opacity-50 bal-ba-hover-ring-2 bas-cursor-pointer bal-ba-focus-ring-2 focus:bas-opacity-90 bal-ba-focus-ring-offset-2 bal-ba-hover-ring-offset-2 bas-w-full bas-justify-center bas-border-none bas-rounded-md"
|
|
184
223
|
(click)="onTxnAcceptClicked()"
|
|
185
224
|
>
|
|
186
|
-
<span
|
|
187
|
-
|
|
225
|
+
<span
|
|
226
|
+
class="bal-ba-transition-2 bas-text-white bas-text-center bas-text-base bas-font-medium bas-flex bas-h-full bas-items-center"
|
|
227
|
+
>
|
|
228
|
+
{{ acceptTxtResolved() }}
|
|
188
229
|
</span>
|
|
189
230
|
</button>
|
|
190
231
|
</div>
|
|
@@ -193,15 +234,15 @@ interface TxnPreParams {
|
|
|
193
234
|
`,
|
|
194
235
|
})
|
|
195
236
|
export class TxnComponent {
|
|
196
|
-
permissionsRequiredTxt = input(
|
|
197
|
-
solicitedDataTxt = input(
|
|
198
|
-
rejectTxt = input(
|
|
199
|
-
acceptTxt = input(
|
|
200
|
-
iAuthorizeTheTxt = input(
|
|
201
|
-
privacyPolicyTxt = input(
|
|
202
|
-
andTheTxt = input(
|
|
203
|
-
termsAndConditionsTxt = input(
|
|
204
|
-
configureSessionTimeTxt = input(
|
|
237
|
+
permissionsRequiredTxt = input<string>();
|
|
238
|
+
solicitedDataTxt = input<string>();
|
|
239
|
+
rejectTxt = input<string>();
|
|
240
|
+
acceptTxt = input<string>();
|
|
241
|
+
iAuthorizeTheTxt = input<string>();
|
|
242
|
+
privacyPolicyTxt = input<string>();
|
|
243
|
+
andTheTxt = input<string>();
|
|
244
|
+
termsAndConditionsTxt = input<string>();
|
|
245
|
+
configureSessionTimeTxt = input<string>();
|
|
205
246
|
hasSolicitedData = input(false);
|
|
206
247
|
allRequiredFilled = input(true);
|
|
207
248
|
closeTxns = input<() => void>(() => {});
|
|
@@ -218,13 +259,49 @@ export class TxnComponent {
|
|
|
218
259
|
solicitedDataClicked = output<void>();
|
|
219
260
|
|
|
220
261
|
private readonly client = injectBlockAuthClient();
|
|
262
|
+
private readonly locale = injectStore($locale);
|
|
263
|
+
protected t = (key: TextKey): string => translate(key, this.locale());
|
|
264
|
+
|
|
265
|
+
protected readonly permissionsRequiredTxtResolved = computed(
|
|
266
|
+
() => this.permissionsRequiredTxt() ?? this.t('permissionsRequired'),
|
|
267
|
+
);
|
|
268
|
+
protected readonly solicitedDataTxtResolved = computed(
|
|
269
|
+
() => this.solicitedDataTxt() ?? this.t('solicitedData'),
|
|
270
|
+
);
|
|
271
|
+
protected readonly rejectTxtResolved = computed(
|
|
272
|
+
() => this.rejectTxt() ?? this.t('reject'),
|
|
273
|
+
);
|
|
274
|
+
protected readonly acceptTxtResolved = computed(
|
|
275
|
+
() => this.acceptTxt() ?? this.t('accept'),
|
|
276
|
+
);
|
|
277
|
+
protected readonly iAuthorizeTheTxtResolved = computed(
|
|
278
|
+
() => this.iAuthorizeTheTxt() ?? this.t('iAuthorizeThe'),
|
|
279
|
+
);
|
|
280
|
+
protected readonly privacyPolicyTxtResolved = computed(
|
|
281
|
+
() => this.privacyPolicyTxt() ?? this.t('privacyPolicy'),
|
|
282
|
+
);
|
|
283
|
+
protected readonly andTheTxtResolved = computed(
|
|
284
|
+
() => this.andTheTxt() ?? this.t('andThe'),
|
|
285
|
+
);
|
|
286
|
+
protected readonly termsAndConditionsTxtResolved = computed(
|
|
287
|
+
() => this.termsAndConditionsTxt() ?? this.t('termsAndConditions'),
|
|
288
|
+
);
|
|
289
|
+
protected readonly configureSessionTimeTxtResolved = computed(
|
|
290
|
+
() => this.configureSessionTimeTxt() ?? this.t('configureSessionTime'),
|
|
291
|
+
);
|
|
221
292
|
|
|
222
293
|
protected readonly pptcAccepted = signal(false);
|
|
223
294
|
protected readonly showLifetime = signal(false);
|
|
224
295
|
|
|
225
|
-
private readonly lifetimeData = computed(
|
|
226
|
-
|
|
227
|
-
|
|
296
|
+
private readonly lifetimeData = computed(
|
|
297
|
+
() => this.selectedTxnPreParams().lifetime ?? {},
|
|
298
|
+
);
|
|
299
|
+
protected readonly minLifetime = computed(
|
|
300
|
+
() => this.lifetimeData().min ?? 10,
|
|
301
|
+
);
|
|
302
|
+
protected readonly maxLifetime = computed(
|
|
303
|
+
() => this.lifetimeData().max ?? 29100,
|
|
304
|
+
);
|
|
228
305
|
protected readonly lifetimeSign = signal(this.lifetime());
|
|
229
306
|
// El TimePicker refleja `lifetimeSign` como string HH:MM:SS; tanto el slider
|
|
230
307
|
// como el picker reportan en segundos, así un único handler mantiene ambos
|
|
@@ -288,7 +365,10 @@ export class TxnComponent {
|
|
|
288
365
|
if (!preParams.appKey) return this.addError()('no_app_key_found');
|
|
289
366
|
if (!preParams.to) return this.addError()('no_contract_address_found');
|
|
290
367
|
this.client.state.$ui.setKey('isAcceptingTxn', true);
|
|
291
|
-
this.client.txns.accept({
|
|
368
|
+
this.client.txns.accept({
|
|
369
|
+
lifetime: this.lifetimeSign(),
|
|
370
|
+
userParams: this.userParamValues(),
|
|
371
|
+
});
|
|
292
372
|
// Auto-close after 4s if txns are cleared (matches original behaviour).
|
|
293
373
|
this.autoCloseTimeout = setTimeout(() => {
|
|
294
374
|
const requests = this.client.state.$ws.get().requests;
|
|
@@ -6,19 +6,23 @@ import {
|
|
|
6
6
|
input,
|
|
7
7
|
signal,
|
|
8
8
|
} from '@angular/core';
|
|
9
|
+
import { $locale, t as translate, type TextKey } from '@block-auth.io/core';
|
|
9
10
|
import { injectBlockAuthClient } from '../../provide-block-auth';
|
|
10
11
|
import { injectStore } from '../../inject-store';
|
|
11
12
|
import { TxnComponent } from './internals/txn.component';
|
|
12
13
|
import { TxnTypeComponent } from './internals/txn-type.component';
|
|
13
14
|
import { TxnErrorComponent } from './internals/txn-error.component';
|
|
14
15
|
import { PermissionsRequiredModalComponent } from './internals/permissions-required-modal.component';
|
|
15
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
SolicitedDataModalComponent,
|
|
18
|
+
type ParamChange,
|
|
19
|
+
} from './internals/solicited-data-modal.component';
|
|
16
20
|
|
|
17
21
|
// Orquestador de txns: lee las solicitudes pendientes de `$ws.requests` y la
|
|
18
22
|
// config de UI de `$ui.uiConfig` (vía injectStore). Se conserva la navegación
|
|
19
23
|
// prev/next, la composición de overlays permisos/datos-solicitados, la
|
|
20
24
|
// derivación de required/optional params desde `uiConfig` y las clases `bas-`.
|
|
21
|
-
// Se elimina
|
|
25
|
+
// Se elimina los wrappers framer-motion.
|
|
22
26
|
interface TxnPreParams {
|
|
23
27
|
iconUrl?: string;
|
|
24
28
|
domain?: string;
|
|
@@ -31,14 +35,16 @@ interface TxnPreParams {
|
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
const accountShort = (addr: string | null | undefined): string =>
|
|
34
|
-
addr && addr.length > 10
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
addr && addr.length > 10
|
|
39
|
+
? `${addr.slice(0, 6)}…${addr.slice(-4)}`
|
|
40
|
+
: addr ?? '';
|
|
41
|
+
|
|
42
|
+
const TXN_ERROR_TEXT_KEYS: Record<string, TextKey> = {
|
|
43
|
+
no_transactions_found: 'noTransactionsFound',
|
|
44
|
+
no_app_key_found: 'noAppKeyFound',
|
|
45
|
+
no_contract_address_found: 'noContractAddressFound',
|
|
46
|
+
no_transactions_params_found: 'noTransactionsParamsFound',
|
|
47
|
+
unknown: 'somethingWentWrong',
|
|
42
48
|
};
|
|
43
49
|
|
|
44
50
|
@Component({
|
|
@@ -58,79 +64,80 @@ const TXN_ERROR_TEXTS: Record<string, string> = {
|
|
|
58
64
|
class="bas-flex bas-box-border bas-relative bas-h-full bas-w-full bas-gap-6 bas-flex-col bas-items-center bas-p-6 bas-font-medium bas-justify-center"
|
|
59
65
|
>
|
|
60
66
|
@if (isEmpty() && isSigning()) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
<ba-txn-error
|
|
68
|
+
[errorMessageTxt]="t('noTransactionsFound')"
|
|
69
|
+
errorMessageSlug="no_transactions_found"
|
|
70
|
+
[closeTxns]="closeTxns()"
|
|
71
|
+
[isCountdown]="false"
|
|
72
|
+
/>
|
|
67
73
|
} @else if (!isEmpty() && error().value) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
<ba-txn-error
|
|
75
|
+
[errorMessageTxt]="errorText()"
|
|
76
|
+
[errorMessageSlug]="error().messageSlug"
|
|
77
|
+
[closeTxns]="closeTxns()"
|
|
78
|
+
[isCountdown]="false"
|
|
79
|
+
/>
|
|
80
|
+
} @else if (!isEmpty()) {
|
|
81
|
+
<div class="bas-flex bas-flex-col bas-items-center bas-gap-3">
|
|
82
|
+
<img
|
|
83
|
+
[src]="
|
|
84
|
+
preParams().iconUrl ||
|
|
85
|
+
'https://dashboard.block-auth.io/img/blockauth_logo.png'
|
|
86
|
+
"
|
|
87
|
+
class="bas-h-16"
|
|
88
|
+
alt="app logo"
|
|
89
|
+
/>
|
|
90
|
+
<h2 class="bas-m-0 bas-text-base bas-text-[var(--bal-primary-600)]">
|
|
91
|
+
{{ preParams().domain || 'dashboard.block-auth.io' }}
|
|
92
|
+
</h2>
|
|
93
|
+
<p class="bas-m-0 bas-text-lg bas-text-[var(--bal-primary-800)]">
|
|
94
|
+
{{ preParams().appName || 'Block-Auth' }}
|
|
95
|
+
<span class="bas-text-base bas-text-[var(--bal-primary-500)]">{{
|
|
96
|
+
t('solicitsTo')
|
|
97
|
+
}}</span>
|
|
98
|
+
{{ accountShort(did()) }}
|
|
99
|
+
</p>
|
|
100
|
+
</div>
|
|
101
|
+
<ba-txn-type
|
|
102
|
+
[txnType]="preParams().txnType || t('login')"
|
|
103
|
+
[txnsLength]="txns().length"
|
|
104
|
+
(prevTxnClicked)="onPrevTxnClicked()"
|
|
105
|
+
(nextTxnClicked)="onNextTxnClicked()"
|
|
106
|
+
/>
|
|
107
|
+
<div class="bas-h-[334px] bas-w-full bas-max-w-[330px]">
|
|
108
|
+
<ba-txn
|
|
109
|
+
[hasSolicitedData]="hasSolicitedData()"
|
|
110
|
+
[allRequiredFilled]="allRequiredFilled()"
|
|
71
111
|
[closeTxns]="closeTxns()"
|
|
72
|
-
[
|
|
112
|
+
[selectedTxnPreParams]="preParams()"
|
|
113
|
+
[userParamValues]="userParamValues()"
|
|
114
|
+
[addError]="addError"
|
|
115
|
+
(permissionsRequiredClicked)="showPermissions.set(true)"
|
|
116
|
+
(solicitedDataClicked)="showSolicitedData.set(true)"
|
|
73
117
|
/>
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
[
|
|
92
|
-
[
|
|
93
|
-
(
|
|
94
|
-
(
|
|
118
|
+
</div>
|
|
119
|
+
} @if (showPermissions()) {
|
|
120
|
+
<div
|
|
121
|
+
class="bal-ba-transition-2 bal-ba-backdrop-blur-base bal-ba-backdrop-blur-sm bas-absolute bas-z-30 bas-box-border bas-h-full bas-w-full"
|
|
122
|
+
(click)="showPermissions.set(false)"
|
|
123
|
+
></div>
|
|
124
|
+
<div class="bas-absolute bas-top-44 bas-z-40">
|
|
125
|
+
<ba-permissions-required-modal />
|
|
126
|
+
</div>
|
|
127
|
+
} @if (showSolicitedData()) {
|
|
128
|
+
<div
|
|
129
|
+
class="bal-ba-transition-2 bal-ba-backdrop-blur-base bal-ba-backdrop-blur-sm bas-absolute bas-z-30 bas-box-border bas-h-full bas-w-full"
|
|
130
|
+
(click)="showSolicitedData.set(false)"
|
|
131
|
+
></div>
|
|
132
|
+
<div class="bas-absolute bas-top-32 bas-z-40">
|
|
133
|
+
<ba-solicited-data-modal
|
|
134
|
+
[requiredParams]="requiredParams()"
|
|
135
|
+
[optionalParams]="optionalParams()"
|
|
136
|
+
[userParamValues]="userParamValues()"
|
|
137
|
+
(paramChange)="handleParamChange($event)"
|
|
138
|
+
(validationChange)="allRequiredFilled.set($event)"
|
|
95
139
|
/>
|
|
96
|
-
|
|
97
|
-
<ba-txn
|
|
98
|
-
[hasSolicitedData]="hasSolicitedData()"
|
|
99
|
-
[allRequiredFilled]="allRequiredFilled()"
|
|
100
|
-
[closeTxns]="closeTxns()"
|
|
101
|
-
[selectedTxnPreParams]="preParams()"
|
|
102
|
-
[userParamValues]="userParamValues()"
|
|
103
|
-
[addError]="addError"
|
|
104
|
-
(permissionsRequiredClicked)="showPermissions.set(true)"
|
|
105
|
-
(solicitedDataClicked)="showSolicitedData.set(true)"
|
|
106
|
-
/>
|
|
107
|
-
</div>
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
@if (showPermissions()) {
|
|
111
|
-
<div
|
|
112
|
-
class="bal-ba-transition-2 bal-ba-backdrop-blur-base bal-ba-backdrop-blur-sm bas-absolute bas-z-30 bas-box-border bas-h-full bas-w-full"
|
|
113
|
-
(click)="showPermissions.set(false)"
|
|
114
|
-
></div>
|
|
115
|
-
<div class="bas-absolute bas-top-44 bas-z-40">
|
|
116
|
-
<ba-permissions-required-modal />
|
|
117
|
-
</div>
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
@if (showSolicitedData()) {
|
|
121
|
-
<div
|
|
122
|
-
class="bal-ba-transition-2 bal-ba-backdrop-blur-base bal-ba-backdrop-blur-sm bas-absolute bas-z-30 bas-box-border bas-h-full bas-w-full"
|
|
123
|
-
(click)="showSolicitedData.set(false)"
|
|
124
|
-
></div>
|
|
125
|
-
<div class="bas-absolute bas-top-32 bas-z-40">
|
|
126
|
-
<ba-solicited-data-modal
|
|
127
|
-
[requiredParams]="requiredParams()"
|
|
128
|
-
[optionalParams]="optionalParams()"
|
|
129
|
-
[userParamValues]="userParamValues()"
|
|
130
|
-
(paramChange)="handleParamChange($event)"
|
|
131
|
-
(validationChange)="allRequiredFilled.set($event)"
|
|
132
|
-
/>
|
|
133
|
-
</div>
|
|
140
|
+
</div>
|
|
134
141
|
}
|
|
135
142
|
</div>
|
|
136
143
|
`,
|
|
@@ -141,6 +148,8 @@ export class TxnsOverviewComponent {
|
|
|
141
148
|
private readonly client = injectBlockAuthClient();
|
|
142
149
|
private readonly ws = injectStore(this.client.state.$ws);
|
|
143
150
|
private readonly ui = injectStore(this.client.state.$ui);
|
|
151
|
+
private readonly locale = injectStore($locale);
|
|
152
|
+
protected t = (key: TextKey): string => translate(key, this.locale());
|
|
144
153
|
|
|
145
154
|
protected readonly accountShort = accountShort;
|
|
146
155
|
|
|
@@ -158,8 +167,11 @@ export class TxnsOverviewComponent {
|
|
|
158
167
|
protected readonly did = computed(() => this.ws().did);
|
|
159
168
|
protected readonly isSigning = computed(() => this.ui().isSigning);
|
|
160
169
|
protected readonly isEmpty = computed(() => this.txns().length === 0);
|
|
161
|
-
protected readonly errorText = computed(
|
|
162
|
-
|
|
170
|
+
protected readonly errorText = computed(() =>
|
|
171
|
+
this.t(
|
|
172
|
+
TXN_ERROR_TEXT_KEYS[this.error().messageSlug] ??
|
|
173
|
+
TXN_ERROR_TEXT_KEYS['unknown'],
|
|
174
|
+
),
|
|
163
175
|
);
|
|
164
176
|
|
|
165
177
|
private readonly selectedTxn = computed(
|
|
@@ -177,22 +189,28 @@ export class TxnsOverviewComponent {
|
|
|
177
189
|
|
|
178
190
|
private readonly requiredOptionalParams = computed(() => {
|
|
179
191
|
const cfg =
|
|
180
|
-
(this.ui().uiConfig as { config?: Record<string, unknown> } | null)
|
|
192
|
+
(this.ui().uiConfig as { config?: Record<string, unknown> } | null)
|
|
193
|
+
?.config ?? {};
|
|
181
194
|
const required: string[] = [];
|
|
182
195
|
const optional: string[] = [];
|
|
183
|
-
const kycMode = (cfg['modules'] as { kyc?: { mode?: string } } | undefined)
|
|
196
|
+
const kycMode = (cfg['modules'] as { kyc?: { mode?: string } } | undefined)
|
|
197
|
+
?.kyc?.mode;
|
|
184
198
|
if (kycMode === 'required') required.push('modules-kyc');
|
|
185
199
|
else if (kycMode === 'optional') optional.push('modules-kyc');
|
|
186
|
-
Object.entries(
|
|
187
|
-
([
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
);
|
|
200
|
+
Object.entries(
|
|
201
|
+
(cfg['params'] as Record<string, { mode?: string }>) || {},
|
|
202
|
+
).forEach(([slug, paramCfg]) => {
|
|
203
|
+
if (paramCfg.mode === 'required') required.push(slug);
|
|
204
|
+
else if (paramCfg.mode === 'optional') optional.push(slug);
|
|
205
|
+
});
|
|
192
206
|
return { requiredParams: required, optionalParams: optional };
|
|
193
207
|
});
|
|
194
|
-
protected readonly requiredParams = computed(
|
|
195
|
-
|
|
208
|
+
protected readonly requiredParams = computed(
|
|
209
|
+
() => this.requiredOptionalParams().requiredParams,
|
|
210
|
+
);
|
|
211
|
+
protected readonly optionalParams = computed(
|
|
212
|
+
() => this.requiredOptionalParams().optionalParams,
|
|
213
|
+
);
|
|
196
214
|
protected readonly hasSolicitedData = computed(
|
|
197
215
|
() => this.requiredParams().length > 0 || this.optionalParams().length > 0,
|
|
198
216
|
);
|