valtech-components 2.0.995 → 2.0.997
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/esm2022/lib/components/organisms/notification-preferences-view/notification-preferences-view.component.mjs +667 -0
- package/esm2022/lib/components/organisms/notification-preferences-view/notification-preferences-view.i18n.mjs +71 -0
- package/esm2022/lib/components/organisms/notification-preferences-view/notification-preferences.routes.mjs +31 -0
- package/esm2022/lib/components/organisms/notification-preferences-view/types.mjs +2 -0
- package/esm2022/lib/components/organisms/organization-view/organization-view.component.mjs +1 -53
- package/esm2022/lib/components/organisms/organization-view/organization-view.i18n.mjs +1 -3
- package/esm2022/lib/components/organisms/permissions-view/permissions-view.component.mjs +511 -0
- package/esm2022/lib/components/organisms/permissions-view/permissions-view.i18n.mjs +116 -0
- package/esm2022/lib/components/organisms/permissions-view/permissions.routes.mjs +29 -0
- package/esm2022/lib/components/organisms/permissions-view/types.mjs +2 -0
- package/esm2022/lib/components/organisms/settings-hub/settings.routes.mjs +12 -1
- package/esm2022/lib/services/auth/auth.service.mjs +1 -14
- package/esm2022/lib/services/auth/types.mjs +1 -1
- package/esm2022/lib/services/org/org.service.mjs +1 -8
- package/esm2022/lib/services/org/permission-catalog.service.mjs +33 -0
- package/esm2022/lib/services/org/types.mjs +1 -1
- package/esm2022/lib/version.mjs +2 -2
- package/esm2022/public-api.mjs +8 -2
- package/fesm2022/valtech-components.mjs +1524 -541
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/organisms/notification-preferences-view/notification-preferences-view.component.d.ts +146 -0
- package/lib/components/organisms/notification-preferences-view/notification-preferences-view.i18n.d.ts +11 -0
- package/lib/components/organisms/notification-preferences-view/notification-preferences.routes.d.ts +26 -0
- package/lib/components/organisms/notification-preferences-view/types.d.ts +36 -0
- package/lib/components/organisms/organization-view/organization-view.component.d.ts +0 -3
- package/lib/components/organisms/permissions-view/permissions-view.component.d.ts +71 -0
- package/lib/components/organisms/permissions-view/permissions-view.i18n.d.ts +9 -0
- package/lib/components/organisms/permissions-view/permissions.routes.d.ts +24 -0
- package/lib/components/organisms/permissions-view/types.d.ts +26 -0
- package/lib/components/organisms/settings-hub/settings.routes.d.ts +15 -0
- package/lib/services/auth/auth.service.d.ts +1 -7
- package/lib/services/auth/types.d.ts +0 -23
- package/lib/services/org/org.service.d.ts +1 -6
- package/lib/services/org/permission-catalog.service.d.ts +34 -0
- package/lib/services/org/types.d.ts +0 -30
- package/lib/version.d.ts +1 -1
- package/package.json +1 -1
- package/public-api.d.ts +7 -1
- package/esm2022/lib/components/organisms/member-import-modal/member-import-modal.component.mjs +0 -313
- package/esm2022/lib/components/organisms/member-import-modal/member-import-modal.i18n.mjs +0 -63
- package/lib/components/organisms/member-import-modal/member-import-modal.component.d.ts +0 -47
- package/lib/components/organisms/member-import-modal/member-import-modal.i18n.d.ts +0 -6
package/esm2022/lib/components/organisms/member-import-modal/member-import-modal.component.mjs
DELETED
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
import { Component, computed, inject, Input, signal } from '@angular/core';
|
|
2
|
-
import { FormsModule } from '@angular/forms';
|
|
3
|
-
import { IonButton, IonButtons, IonCheckbox, IonContent, IonHeader, IonSelect, IonSelectOption, IonSpinner, IonTextarea, IonToolbar, } from '@ionic/angular/standalone';
|
|
4
|
-
import { DisplayComponent } from '../../atoms/display/display.component';
|
|
5
|
-
import { TextComponent } from '../../atoms/text/text.component';
|
|
6
|
-
import { TitleComponent } from '../../atoms/title/title.component';
|
|
7
|
-
import { I18nService } from '../../../services/i18n';
|
|
8
|
-
import { OrgService } from '../../../services/org/org.service';
|
|
9
|
-
import { MEMBER_IMPORT_MODAL_I18N } from './member-import-modal.i18n';
|
|
10
|
-
import * as i0 from "@angular/core";
|
|
11
|
-
import * as i1 from "@angular/forms";
|
|
12
|
-
const DEFAULT_NAMESPACE = 'Settings.ImportModal';
|
|
13
|
-
/**
|
|
14
|
-
* `val-member-import-modal` — panel de carga masiva de miembros (ADR-023 fase 6).
|
|
15
|
-
*
|
|
16
|
-
* El admin pega un CSV (`email,nombre,rol`); el modal lo parsea a filas y llama
|
|
17
|
-
* `OrgService.importMembers`. Muestra el resultado por-fila (partial success):
|
|
18
|
-
* `created` / `assigned` / `skipped` / `error`. Header canónico (Regla #5).
|
|
19
|
-
*
|
|
20
|
-
* Auto-registra defaults i18n (es/en) en `Settings.ImportModal`.
|
|
21
|
-
*/
|
|
22
|
-
export class MemberImportModalComponent {
|
|
23
|
-
constructor() {
|
|
24
|
-
this.i18n = inject(I18nService);
|
|
25
|
-
this.orgService = inject(OrgService);
|
|
26
|
-
/** Org destino del import. */
|
|
27
|
-
this.orgId = '';
|
|
28
|
-
/** Nombres de roles disponibles (para el hint). Opcional. */
|
|
29
|
-
this.availableRoles = [];
|
|
30
|
-
/** Namespace i18n. */
|
|
31
|
-
this.i18nNamespace = DEFAULT_NAMESPACE;
|
|
32
|
-
this.csv = '';
|
|
33
|
-
this.onConflict = 'assignRole';
|
|
34
|
-
this.sendActivation = true;
|
|
35
|
-
this.submitting = signal(false);
|
|
36
|
-
this.errorMsg = signal('');
|
|
37
|
-
this.results = signal(null);
|
|
38
|
-
this.rolesHint = computed(() => this.availableRoles.length ? `${this.t('rolesAvailable')} ${this.availableRoles.join(', ')}` : '');
|
|
39
|
-
this.summaryLabel = computed(() => {
|
|
40
|
-
const s = this.results()?.summary;
|
|
41
|
-
if (!s)
|
|
42
|
-
return this.t('summary');
|
|
43
|
-
return `${this.t('summary')}: ${s.created} ${this.t('created')} · ${s.assigned} ${this.t('assigned')} · ${s.skipped} ${this.t('skipped')} · ${s.failed} ${this.t('failed')}`;
|
|
44
|
-
});
|
|
45
|
-
if (!this.i18n.hasNamespace(DEFAULT_NAMESPACE)) {
|
|
46
|
-
this.i18n.registerContent(DEFAULT_NAMESPACE, MEMBER_IMPORT_MODAL_I18N);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
ngOnInit() {
|
|
50
|
-
if (!this.i18n.hasNamespace(this.i18nNamespace)) {
|
|
51
|
-
this.i18n.registerContent(this.i18nNamespace, MEMBER_IMPORT_MODAL_I18N);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
/** Parsea el CSV pegado a filas {email,name,roleName}. Tolera header. */
|
|
55
|
-
parseCsv() {
|
|
56
|
-
const rows = [];
|
|
57
|
-
for (const raw of this.csv.split(/\r?\n/)) {
|
|
58
|
-
const line = raw.trim();
|
|
59
|
-
if (!line)
|
|
60
|
-
continue;
|
|
61
|
-
const cols = line.split(',').map(c => c.trim());
|
|
62
|
-
const email = (cols[0] ?? '').toLowerCase();
|
|
63
|
-
// Saltar header (primera col "email") o líneas sin @.
|
|
64
|
-
if (!email || !email.includes('@'))
|
|
65
|
-
continue;
|
|
66
|
-
rows.push({ email, name: cols[1] ?? '', roleName: cols[2] ?? '' });
|
|
67
|
-
}
|
|
68
|
-
return rows;
|
|
69
|
-
}
|
|
70
|
-
submit() {
|
|
71
|
-
this.errorMsg.set('');
|
|
72
|
-
const users = this.parseCsv();
|
|
73
|
-
if (users.length === 0) {
|
|
74
|
-
this.errorMsg.set(this.t('noRows'));
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
if (users.some(u => !u.roleName)) {
|
|
78
|
-
this.errorMsg.set(this.t('parseError'));
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
this.submitting.set(true);
|
|
82
|
-
this.orgService
|
|
83
|
-
.importMembers(this.orgId, {
|
|
84
|
-
users,
|
|
85
|
-
onConflict: this.onConflict,
|
|
86
|
-
sendActivation: this.sendActivation,
|
|
87
|
-
})
|
|
88
|
-
.subscribe({
|
|
89
|
-
next: res => {
|
|
90
|
-
this.submitting.set(false);
|
|
91
|
-
this.results.set(res);
|
|
92
|
-
// Refrescar lista del consumer si hubo altas/asignaciones efectivas.
|
|
93
|
-
if (res.summary.created + res.summary.assigned > 0) {
|
|
94
|
-
this.onSuccess?.();
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
error: err => {
|
|
98
|
-
this.submitting.set(false);
|
|
99
|
-
this.errorMsg.set(err?.error?.message ?? this.t('genericError'));
|
|
100
|
-
},
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
statusLabel(r) {
|
|
104
|
-
const base = this.t(r.status === 'error' ? 'failed' : r.status);
|
|
105
|
-
if (r.status === 'created' && r.activation) {
|
|
106
|
-
return `${base} · ${this.t(r.activation === 'sent' ? 'activationSent' : 'activationPending')}`;
|
|
107
|
-
}
|
|
108
|
-
return base;
|
|
109
|
-
}
|
|
110
|
-
reset() {
|
|
111
|
-
this.csv = '';
|
|
112
|
-
this.errorMsg.set('');
|
|
113
|
-
this.results.set(null);
|
|
114
|
-
}
|
|
115
|
-
dismiss() {
|
|
116
|
-
this._modalRef?.dismiss(null, 'cancel');
|
|
117
|
-
}
|
|
118
|
-
t(key) {
|
|
119
|
-
return this.i18n.t(key, this.i18nNamespace);
|
|
120
|
-
}
|
|
121
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MemberImportModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
122
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MemberImportModalComponent, isStandalone: true, selector: "val-member-import-modal", inputs: { orgId: "orgId", availableRoles: "availableRoles", onSuccess: "onSuccess", _modalRef: "_modalRef", i18nNamespace: "i18nNamespace" }, ngImport: i0, template: `
|
|
123
|
-
<ion-header>
|
|
124
|
-
<ion-toolbar>
|
|
125
|
-
<ion-buttons slot="end">
|
|
126
|
-
<ion-button fill="clear" color="dark" (click)="dismiss()">
|
|
127
|
-
<strong>{{ t('close') }}</strong>
|
|
128
|
-
</ion-button>
|
|
129
|
-
</ion-buttons>
|
|
130
|
-
</ion-toolbar>
|
|
131
|
-
</ion-header>
|
|
132
|
-
|
|
133
|
-
<ion-content class="ion-padding">
|
|
134
|
-
<val-display [props]="{ content: t('title'), size: 'small', color: 'dark' }" />
|
|
135
|
-
|
|
136
|
-
@if (!results()) {
|
|
137
|
-
<val-title [props]="{ content: t('hint'), size: 'large', color: '', bold: false }" />
|
|
138
|
-
|
|
139
|
-
@if (rolesHint()) {
|
|
140
|
-
<val-text [props]="{ content: rolesHint(), size: 'small', color: 'medium', bold: false }" />
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
<ion-textarea
|
|
144
|
-
class="import-csv"
|
|
145
|
-
[autoGrow]="true"
|
|
146
|
-
[rows]="6"
|
|
147
|
-
[placeholder]="t('csvPlaceholder')"
|
|
148
|
-
[(ngModel)]="csv"
|
|
149
|
-
/>
|
|
150
|
-
|
|
151
|
-
<ion-select
|
|
152
|
-
class="import-conflict"
|
|
153
|
-
label="{{ t('onConflictLabel') }}"
|
|
154
|
-
labelPlacement="stacked"
|
|
155
|
-
interface="popover"
|
|
156
|
-
[(ngModel)]="onConflict"
|
|
157
|
-
>
|
|
158
|
-
<ion-select-option value="assignRole">{{ t('conflictAssign') }}</ion-select-option>
|
|
159
|
-
<ion-select-option value="skip">{{ t('conflictSkip') }}</ion-select-option>
|
|
160
|
-
<ion-select-option value="error">{{ t('conflictError') }}</ion-select-option>
|
|
161
|
-
</ion-select>
|
|
162
|
-
|
|
163
|
-
<ion-checkbox class="import-activation" labelPlacement="end" [(ngModel)]="sendActivation">
|
|
164
|
-
{{ t('sendActivation') }}
|
|
165
|
-
</ion-checkbox>
|
|
166
|
-
|
|
167
|
-
@if (errorMsg()) {
|
|
168
|
-
<p class="import-error">{{ errorMsg() }}</p>
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
<div class="import-actions">
|
|
172
|
-
<ion-button expand="block" color="dark" [disabled]="submitting()" (click)="submit()">
|
|
173
|
-
@if (submitting()) {
|
|
174
|
-
<ion-spinner name="dots" />
|
|
175
|
-
{{ t('submitting') }}
|
|
176
|
-
} @else {
|
|
177
|
-
{{ t('submit') }}
|
|
178
|
-
}
|
|
179
|
-
</ion-button>
|
|
180
|
-
</div>
|
|
181
|
-
} @else {
|
|
182
|
-
<!-- Resultados -->
|
|
183
|
-
<val-title [props]="{ content: summaryLabel(), size: 'large', color: '', bold: true }" />
|
|
184
|
-
<div class="import-results">
|
|
185
|
-
@for (r of results()!.results; track r.email) {
|
|
186
|
-
<div class="import-row import-row--{{ r.status }}">
|
|
187
|
-
<span class="import-row__email">{{ r.email }}</span>
|
|
188
|
-
<span class="import-row__status">{{ statusLabel(r) }}</span>
|
|
189
|
-
@if (r.reason) {
|
|
190
|
-
<span class="import-row__reason">{{ r.reason }}</span>
|
|
191
|
-
}
|
|
192
|
-
</div>
|
|
193
|
-
}
|
|
194
|
-
</div>
|
|
195
|
-
<div class="import-actions">
|
|
196
|
-
<ion-button expand="block" fill="outline" color="dark" (click)="reset()">
|
|
197
|
-
{{ t('again') }}
|
|
198
|
-
</ion-button>
|
|
199
|
-
</div>
|
|
200
|
-
}
|
|
201
|
-
</ion-content>
|
|
202
|
-
`, isInline: true, styles: ["val-display{display:block;margin-bottom:4px}val-title{display:block;margin-bottom:12px}.import-csv{--background: var(--ion-color-light);border-radius:10px;margin-bottom:16px;font-family:monospace;font-size:13px}.import-conflict{margin-bottom:12px}.import-activation{display:block;margin-bottom:16px;font-size:14px}.import-error{margin:0 0 12px;font-size:.875rem;color:var(--ion-color-danger, #c0392b)}.import-actions{margin-top:8px}.import-results{display:flex;flex-direction:column;gap:6px;margin:12px 0}.import-row{display:grid;grid-template-columns:1fr auto;grid-row-gap:2px;align-items:center;padding:10px 12px;border-radius:8px;border-left:3px solid var(--ion-color-medium);background:var(--ion-color-light);font-size:14px}.import-row--created{border-left-color:var(--ion-color-success, #2dd36f)}.import-row--assigned{border-left-color:var(--ion-color-primary, #7026df)}.import-row--skipped{border-left-color:var(--ion-color-medium, #92949c)}.import-row--error{border-left-color:var(--ion-color-danger, #c0392b)}.import-row__email{font-weight:600;color:var(--ion-color-dark)}.import-row__status{text-align:right;color:var(--ion-color-medium-shade, #6b6e76)}.import-row__reason{grid-column:1 / -1;font-size:12px;color:var(--ion-color-danger, #c0392b)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonTextarea, selector: "ion-textarea", inputs: ["autoGrow", "autocapitalize", "autofocus", "clearOnEdit", "color", "cols", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "maxlength", "minlength", "mode", "name", "placeholder", "readonly", "required", "rows", "shape", "spellcheck", "value", "wrap"] }, { kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "errorText", "helperText", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: DisplayComponent, selector: "val-display", inputs: ["props"] }, { kind: "component", type: TextComponent, selector: "val-text", inputs: ["props"] }, { kind: "component", type: TitleComponent, selector: "val-title", inputs: ["props"] }] }); }
|
|
203
|
-
}
|
|
204
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MemberImportModalComponent, decorators: [{
|
|
205
|
-
type: Component,
|
|
206
|
-
args: [{ selector: 'val-member-import-modal', standalone: true, imports: [
|
|
207
|
-
FormsModule,
|
|
208
|
-
IonHeader,
|
|
209
|
-
IonToolbar,
|
|
210
|
-
IonButtons,
|
|
211
|
-
IonButton,
|
|
212
|
-
IonContent,
|
|
213
|
-
IonTextarea,
|
|
214
|
-
IonSelect,
|
|
215
|
-
IonSelectOption,
|
|
216
|
-
IonCheckbox,
|
|
217
|
-
IonSpinner,
|
|
218
|
-
DisplayComponent,
|
|
219
|
-
TextComponent,
|
|
220
|
-
TitleComponent,
|
|
221
|
-
], template: `
|
|
222
|
-
<ion-header>
|
|
223
|
-
<ion-toolbar>
|
|
224
|
-
<ion-buttons slot="end">
|
|
225
|
-
<ion-button fill="clear" color="dark" (click)="dismiss()">
|
|
226
|
-
<strong>{{ t('close') }}</strong>
|
|
227
|
-
</ion-button>
|
|
228
|
-
</ion-buttons>
|
|
229
|
-
</ion-toolbar>
|
|
230
|
-
</ion-header>
|
|
231
|
-
|
|
232
|
-
<ion-content class="ion-padding">
|
|
233
|
-
<val-display [props]="{ content: t('title'), size: 'small', color: 'dark' }" />
|
|
234
|
-
|
|
235
|
-
@if (!results()) {
|
|
236
|
-
<val-title [props]="{ content: t('hint'), size: 'large', color: '', bold: false }" />
|
|
237
|
-
|
|
238
|
-
@if (rolesHint()) {
|
|
239
|
-
<val-text [props]="{ content: rolesHint(), size: 'small', color: 'medium', bold: false }" />
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
<ion-textarea
|
|
243
|
-
class="import-csv"
|
|
244
|
-
[autoGrow]="true"
|
|
245
|
-
[rows]="6"
|
|
246
|
-
[placeholder]="t('csvPlaceholder')"
|
|
247
|
-
[(ngModel)]="csv"
|
|
248
|
-
/>
|
|
249
|
-
|
|
250
|
-
<ion-select
|
|
251
|
-
class="import-conflict"
|
|
252
|
-
label="{{ t('onConflictLabel') }}"
|
|
253
|
-
labelPlacement="stacked"
|
|
254
|
-
interface="popover"
|
|
255
|
-
[(ngModel)]="onConflict"
|
|
256
|
-
>
|
|
257
|
-
<ion-select-option value="assignRole">{{ t('conflictAssign') }}</ion-select-option>
|
|
258
|
-
<ion-select-option value="skip">{{ t('conflictSkip') }}</ion-select-option>
|
|
259
|
-
<ion-select-option value="error">{{ t('conflictError') }}</ion-select-option>
|
|
260
|
-
</ion-select>
|
|
261
|
-
|
|
262
|
-
<ion-checkbox class="import-activation" labelPlacement="end" [(ngModel)]="sendActivation">
|
|
263
|
-
{{ t('sendActivation') }}
|
|
264
|
-
</ion-checkbox>
|
|
265
|
-
|
|
266
|
-
@if (errorMsg()) {
|
|
267
|
-
<p class="import-error">{{ errorMsg() }}</p>
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
<div class="import-actions">
|
|
271
|
-
<ion-button expand="block" color="dark" [disabled]="submitting()" (click)="submit()">
|
|
272
|
-
@if (submitting()) {
|
|
273
|
-
<ion-spinner name="dots" />
|
|
274
|
-
{{ t('submitting') }}
|
|
275
|
-
} @else {
|
|
276
|
-
{{ t('submit') }}
|
|
277
|
-
}
|
|
278
|
-
</ion-button>
|
|
279
|
-
</div>
|
|
280
|
-
} @else {
|
|
281
|
-
<!-- Resultados -->
|
|
282
|
-
<val-title [props]="{ content: summaryLabel(), size: 'large', color: '', bold: true }" />
|
|
283
|
-
<div class="import-results">
|
|
284
|
-
@for (r of results()!.results; track r.email) {
|
|
285
|
-
<div class="import-row import-row--{{ r.status }}">
|
|
286
|
-
<span class="import-row__email">{{ r.email }}</span>
|
|
287
|
-
<span class="import-row__status">{{ statusLabel(r) }}</span>
|
|
288
|
-
@if (r.reason) {
|
|
289
|
-
<span class="import-row__reason">{{ r.reason }}</span>
|
|
290
|
-
}
|
|
291
|
-
</div>
|
|
292
|
-
}
|
|
293
|
-
</div>
|
|
294
|
-
<div class="import-actions">
|
|
295
|
-
<ion-button expand="block" fill="outline" color="dark" (click)="reset()">
|
|
296
|
-
{{ t('again') }}
|
|
297
|
-
</ion-button>
|
|
298
|
-
</div>
|
|
299
|
-
}
|
|
300
|
-
</ion-content>
|
|
301
|
-
`, styles: ["val-display{display:block;margin-bottom:4px}val-title{display:block;margin-bottom:12px}.import-csv{--background: var(--ion-color-light);border-radius:10px;margin-bottom:16px;font-family:monospace;font-size:13px}.import-conflict{margin-bottom:12px}.import-activation{display:block;margin-bottom:16px;font-size:14px}.import-error{margin:0 0 12px;font-size:.875rem;color:var(--ion-color-danger, #c0392b)}.import-actions{margin-top:8px}.import-results{display:flex;flex-direction:column;gap:6px;margin:12px 0}.import-row{display:grid;grid-template-columns:1fr auto;grid-row-gap:2px;align-items:center;padding:10px 12px;border-radius:8px;border-left:3px solid var(--ion-color-medium);background:var(--ion-color-light);font-size:14px}.import-row--created{border-left-color:var(--ion-color-success, #2dd36f)}.import-row--assigned{border-left-color:var(--ion-color-primary, #7026df)}.import-row--skipped{border-left-color:var(--ion-color-medium, #92949c)}.import-row--error{border-left-color:var(--ion-color-danger, #c0392b)}.import-row__email{font-weight:600;color:var(--ion-color-dark)}.import-row__status{text-align:right;color:var(--ion-color-medium-shade, #6b6e76)}.import-row__reason{grid-column:1 / -1;font-size:12px;color:var(--ion-color-danger, #c0392b)}\n"] }]
|
|
302
|
-
}], ctorParameters: () => [], propDecorators: { orgId: [{
|
|
303
|
-
type: Input
|
|
304
|
-
}], availableRoles: [{
|
|
305
|
-
type: Input
|
|
306
|
-
}], onSuccess: [{
|
|
307
|
-
type: Input
|
|
308
|
-
}], _modalRef: [{
|
|
309
|
-
type: Input
|
|
310
|
-
}], i18nNamespace: [{
|
|
311
|
-
type: Input
|
|
312
|
-
}] } });
|
|
313
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtYmVyLWltcG9ydC1tb2RhbC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvb3JnYW5pc21zL21lbWJlci1pbXBvcnQtbW9kYWwvbWVtYmVyLWltcG9ydC1tb2RhbC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkYsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFDTCxTQUFTLEVBQ1QsVUFBVSxFQUNWLFdBQVcsRUFDWCxVQUFVLEVBQ1YsU0FBUyxFQUNULFNBQVMsRUFDVCxlQUFlLEVBQ2YsVUFBVSxFQUNWLFdBQVcsRUFDWCxVQUFVLEdBQ1gsTUFBTSwyQkFBMkIsQ0FBQztBQUVuQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUN6RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDaEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBRW5FLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFHL0QsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7OztBQUV0RSxNQUFNLGlCQUFpQixHQUFHLHNCQUFzQixDQUFDO0FBRWpEOzs7Ozs7OztHQVFHO0FBbUxILE1BQU0sT0FBTywwQkFBMEI7SUF1Q3JDO1FBdENRLFNBQUksR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDM0IsZUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUV4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LFNBQVM7c0JBQWpCLEtBQUs7Z0JBR0csU0FBUztzQkFBakIsS0FBSztnQkFHRyxhQUFhO3NCQUFyQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBjb21wdXRlZCwgaW5qZWN0LCBJbnB1dCwgT25Jbml0LCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtcbiAgSW9uQnV0dG9uLFxuICBJb25CdXR0b25zLFxuICBJb25DaGVja2JveCxcbiAgSW9uQ29udGVudCxcbiAgSW9uSGVhZGVyLFxuICBJb25TZWxlY3QsXG4gIElvblNlbGVjdE9wdGlvbixcbiAgSW9uU3Bpbm5lcixcbiAgSW9uVGV4dGFyZWEsXG4gIElvblRvb2xiYXIsXG59IGZyb20gJ0Bpb25pYy9hbmd1bGFyL3N0YW5kYWxvbmUnO1xuXG5pbXBvcnQgeyBEaXNwbGF5Q29tcG9uZW50IH0gZnJvbSAnLi4vLi4vYXRvbXMvZGlzcGxheS9kaXNwbGF5LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBUZXh0Q29tcG9uZW50IH0gZnJvbSAnLi4vLi4vYXRvbXMvdGV4dC90ZXh0LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBUaXRsZUNvbXBvbmVudCB9IGZyb20gJy4uLy4uL2F0b21zL3RpdGxlL3RpdGxlLmNvbXBvbmVudCc7XG5cbmltcG9ydCB7IEkxOG5TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvaTE4bic7XG5pbXBvcnQgeyBPcmdTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvb3JnL29yZy5zZXJ2aWNlJztcbmltcG9ydCB7IEltcG9ydE1lbWJlcnNSZXNwb25zZSwgSW1wb3J0T25Db25mbGljdCwgSW1wb3J0Um93UmVzdWx0LCBJbXBvcnRVc2VyUm93IH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvb3JnL3R5cGVzJztcblxuaW1wb3J0IHsgTUVNQkVSX0lNUE9SVF9NT0RBTF9JMThOIH0gZnJvbSAnLi9tZW1iZXItaW1wb3J0LW1vZGFsLmkxOG4nO1xuXG5jb25zdCBERUZBVUxUX05BTUVTUEFDRSA9ICdTZXR0aW5ncy5JbXBvcnRNb2RhbCc7XG5cbi8qKlxuICogYHZhbC1tZW1iZXItaW1wb3J0LW1vZGFsYCDigJQgcGFuZWwgZGUgY2FyZ2EgbWFzaXZhIGRlIG1pZW1icm9zIChBRFItMDIzIGZhc2UgNikuXG4gKlxuICogRWwgYWRtaW4gcGVnYSB1biBDU1YgKGBlbWFpbCxub21icmUscm9sYCk7IGVsIG1vZGFsIGxvIHBhcnNlYSBhIGZpbGFzIHkgbGxhbWFcbiAqIGBPcmdTZXJ2aWNlLmltcG9ydE1lbWJlcnNgLiBNdWVzdHJhIGVsIHJlc3VsdGFkbyBwb3ItZmlsYSAocGFydGlhbCBzdWNjZXNzKTpcbiAqIGBjcmVhdGVkYCAvIGBhc3NpZ25lZGAgLyBgc2tpcHBlZGAgLyBgZXJyb3JgLiBIZWFkZXIgY2Fuw7NuaWNvIChSZWdsYSAjNSkuXG4gKlxuICogQXV0by1yZWdpc3RyYSBkZWZhdWx0cyBpMThuIChlcy9lbikgZW4gYFNldHRpbmdzLkltcG9ydE1vZGFsYC5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndmFsLW1lbWJlci1pbXBvcnQtbW9kYWwnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgSW9uSGVhZGVyLFxuICAgIElvblRvb2xiYXIsXG4gICAgSW9uQnV0dG9ucyxcbiAgICBJb25CdXR0b24sXG4gICAgSW9uQ29udGVudCxcbiAgICBJb25UZXh0YXJlYSxcbiAgICBJb25TZWxlY3QsXG4gICAgSW9uU2VsZWN0T3B0aW9uLFxuICAgIElvbkNoZWNrYm94LFxuICAgIElvblNwaW5uZXIsXG4gICAgRGlzcGxheUNvbXBvbmVudCxcbiAgICBUZXh0Q29tcG9uZW50LFxuICAgIFRpdGxlQ29tcG9uZW50LFxuICBdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxpb24taGVhZGVyPlxuICAgICAgPGlvbi10b29sYmFyPlxuICAgICAgICA8aW9uLWJ1dHRvbnMgc2xvdD1cImVuZFwiPlxuICAgICAgICAgIDxpb24tYnV0dG9uIGZpbGw9XCJjbGVhclwiIGNvbG9yPVwiZGFya1wiIChjbGljayk9XCJkaXNtaXNzKClcIj5cbiAgICAgICAgICAgIDxzdHJvbmc+e3sgdCgnY2xvc2UnKSB9fTwvc3Ryb25nPlxuICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICAgICAgPC9pb24tYnV0dG9ucz5cbiAgICAgIDwvaW9uLXRvb2xiYXI+XG4gICAgPC9pb24taGVhZGVyPlxuXG4gICAgPGlvbi1jb250ZW50IGNsYXNzPVwiaW9uLXBhZGRpbmdcIj5cbiAgICAgIDx2YWwtZGlzcGxheSBbcHJvcHNdPVwieyBjb250ZW50OiB0KCd0aXRsZScpLCBzaXplOiAnc21hbGwnLCBjb2xvcjogJ2RhcmsnIH1cIiAvPlxuXG4gICAgICBAaWYgKCFyZXN1bHRzKCkpIHtcbiAgICAgICAgPHZhbC10aXRsZSBbcHJvcHNdPVwieyBjb250ZW50OiB0KCdoaW50JyksIHNpemU6ICdsYXJnZScsIGNvbG9yOiAnJywgYm9sZDogZmFsc2UgfVwiIC8+XG5cbiAgICAgICAgQGlmIChyb2xlc0hpbnQoKSkge1xuICAgICAgICAgIDx2YWwtdGV4dCBbcHJvcHNdPVwieyBjb250ZW50OiByb2xlc0hpbnQoKSwgc2l6ZTogJ3NtYWxsJywgY29sb3I6ICdtZWRpdW0nLCBib2xkOiBmYWxzZSB9XCIgLz5cbiAgICAgICAgfVxuXG4gICAgICAgIDxpb24tdGV4dGFyZWFcbiAgICAgICAgICBjbGFzcz1cImltcG9ydC1jc3ZcIlxuICAgICAgICAgIFthdXRvR3Jvd109XCJ0cnVlXCJcbiAgICAgICAgICBbcm93c109XCI2XCJcbiAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwidCgnY3N2UGxhY2Vob2xkZXInKVwiXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJjc3ZcIlxuICAgICAgICAvPlxuXG4gICAgICAgIDxpb24tc2VsZWN0XG4gICAgICAgICAgY2xhc3M9XCJpbXBvcnQtY29uZmxpY3RcIlxuICAgICAgICAgIGxhYmVsPVwie3sgdCgnb25Db25mbGljdExhYmVsJykgfX1cIlxuICAgICAgICAgIGxhYmVsUGxhY2VtZW50PVwic3RhY2tlZFwiXG4gICAgICAgICAgaW50ZXJmYWNlPVwicG9wb3ZlclwiXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJvbkNvbmZsaWN0XCJcbiAgICAgICAgPlxuICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cImFzc2lnblJvbGVcIj57eyB0KCdjb25mbGljdEFzc2lnbicpIH19PC9pb24tc2VsZWN0LW9wdGlvbj5cbiAgICAgICAgICA8aW9uLXNlbGVjdC1vcHRpb24gdmFsdWU9XCJza2lwXCI+e3sgdCgnY29uZmxpY3RTa2lwJykgfX08L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cImVycm9yXCI+e3sgdCgnY29uZmxpY3RFcnJvcicpIH19PC9pb24tc2VsZWN0LW9wdGlvbj5cbiAgICAgICAgPC9pb24tc2VsZWN0PlxuXG4gICAgICAgIDxpb24tY2hlY2tib3ggY2xhc3M9XCJpbXBvcnQtYWN0aXZhdGlvblwiIGxhYmVsUGxhY2VtZW50PVwiZW5kXCIgWyhuZ01vZGVsKV09XCJzZW5kQWN0aXZhdGlvblwiPlxuICAgICAgICAgIHt7IHQoJ3NlbmRBY3RpdmF0aW9uJykgfX1cbiAgICAgICAgPC9pb24tY2hlY2tib3g+XG5cbiAgICAgICAgQGlmIChlcnJvck1zZygpKSB7XG4gICAgICAgICAgPHAgY2xhc3M9XCJpbXBvcnQtZXJyb3JcIj57eyBlcnJvck1zZygpIH19PC9wPlxuICAgICAgICB9XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImltcG9ydC1hY3Rpb25zXCI+XG4gICAgICAgICAgPGlvbi1idXR0b24gZXhwYW5kPVwiYmxvY2tcIiBjb2xvcj1cImRhcmtcIiBbZGlzYWJsZWRdPVwic3VibWl0dGluZygpXCIgKGNsaWNrKT1cInN1Ym1pdCgpXCI+XG4gICAgICAgICAgICBAaWYgKHN1Ym1pdHRpbmcoKSkge1xuICAgICAgICAgICAgICA8aW9uLXNwaW5uZXIgbmFtZT1cImRvdHNcIiAvPlxuICAgICAgICAgICAgICAmbmJzcDt7eyB0KCdzdWJtaXR0aW5nJykgfX1cbiAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICB7eyB0KCdzdWJtaXQnKSB9fVxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICB9IEBlbHNlIHtcbiAgICAgICAgPCEtLSBSZXN1bHRhZG9zIC0tPlxuICAgICAgICA8dmFsLXRpdGxlIFtwcm9wc109XCJ7IGNvbnRlbnQ6IHN1bW1hcnlMYWJlbCgpLCBzaXplOiAnbGFyZ2UnLCBjb2xvcjogJycsIGJvbGQ6IHRydWUgfVwiIC8+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJpbXBvcnQtcmVzdWx0c1wiPlxuICAgICAgICAgIEBmb3IgKHIgb2YgcmVzdWx0cygpIS5yZXN1bHRzOyB0cmFjayByLmVtYWlsKSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW1wb3J0LXJvdyBpbXBvcnQtcm93LS17eyByLnN0YXR1cyB9fVwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImltcG9ydC1yb3dfX2VtYWlsXCI+e3sgci5lbWFpbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpbXBvcnQtcm93X19zdGF0dXNcIj57eyBzdGF0dXNMYWJlbChyKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgQGlmIChyLnJlYXNvbikge1xuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaW1wb3J0LXJvd19fcmVhc29uXCI+e3sgci5yZWFzb24gfX08L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJpbXBvcnQtYWN0aW9uc1wiPlxuICAgICAgICAgIDxpb24tYnV0dG9uIGV4cGFuZD1cImJsb2NrXCIgZmlsbD1cIm91dGxpbmVcIiBjb2xvcj1cImRhcmtcIiAoY2xpY2spPVwicmVzZXQoKVwiPlxuICAgICAgICAgICAge3sgdCgnYWdhaW4nKSB9fVxuICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG4gICAgPC9pb24tY29udGVudD5cbiAgYCxcbiAgc3R5bGVzOiBbXG4gICAgYFxuICAgICAgdmFsLWRpc3BsYXkge1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogNHB4O1xuICAgICAgfVxuICAgICAgdmFsLXRpdGxlIHtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgIG1hcmdpbi1ib3R0b206IDEycHg7XG4gICAgICB9XG4gICAgICAuaW1wb3J0LWNzdiB7XG4gICAgICAgIC0tYmFja2dyb3VuZDogdmFyKC0taW9uLWNvbG9yLWxpZ2h0KTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMTBweDtcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogMTZweDtcbiAgICAgICAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTtcbiAgICAgICAgZm9udC1zaXplOiAxM3B4O1xuICAgICAgfVxuICAgICAgLmltcG9ydC1jb25mbGljdCB7XG4gICAgICAgIG1hcmdpbi1ib3R0b206IDEycHg7XG4gICAgICB9XG4gICAgICAuaW1wb3J0LWFjdGl2YXRpb24ge1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogMTZweDtcbiAgICAgICAgZm9udC1zaXplOiAxNHB4O1xuICAgICAgfVxuICAgICAgLmltcG9ydC1lcnJvciB7XG4gICAgICAgIG1hcmdpbjogMCAwIDEycHggMDtcbiAgICAgICAgZm9udC1zaXplOiAwLjg3NXJlbTtcbiAgICAgICAgY29sb3I6IHZhcigtLWlvbi1jb2xvci1kYW5nZXIsICNjMDM5MmIpO1xuICAgICAgfVxuICAgICAgLmltcG9ydC1hY3Rpb25zIHtcbiAgICAgICAgbWFyZ2luLXRvcDogOHB4O1xuICAgICAgfVxuICAgICAgLmltcG9ydC1yZXN1bHRzIHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgICAgZ2FwOiA2cHg7XG4gICAgICAgIG1hcmdpbjogMTJweCAwO1xuICAgICAgfVxuICAgICAgLmltcG9ydC1yb3cge1xuICAgICAgICBkaXNwbGF5OiBncmlkO1xuICAgICAgICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IDFmciBhdXRvO1xuICAgICAgICBncmlkLXJvdy1nYXA6IDJweDtcbiAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgICAgcGFkZGluZzogMTBweCAxMnB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiA4cHg7XG4gICAgICAgIGJvcmRlci1sZWZ0OiAzcHggc29saWQgdmFyKC0taW9uLWNvbG9yLW1lZGl1bSk7XG4gICAgICAgIGJhY2tncm91bmQ6IHZhcigtLWlvbi1jb2xvci1saWdodCk7XG4gICAgICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAgIH1cbiAgICAgIC5pbXBvcnQtcm93LS1jcmVhdGVkIHtcbiAgICAgICAgYm9yZGVyLWxlZnQtY29sb3I6IHZhcigtLWlvbi1jb2xvci1zdWNjZXNzLCAjMmRkMzZmKTtcbiAgICAgIH1cbiAgICAgIC5pbXBvcnQtcm93LS1hc3NpZ25lZCB7XG4gICAgICAgIGJvcmRlci1sZWZ0LWNvbG9yOiB2YXIoLS1pb24tY29sb3ItcHJpbWFyeSwgIzcwMjZkZik7XG4gICAgICB9XG4gICAgICAuaW1wb3J0LXJvdy0tc2tpcHBlZCB7XG4gICAgICAgIGJvcmRlci1sZWZ0LWNvbG9yOiB2YXIoLS1pb24tY29sb3ItbWVkaXVtLCAjOTI5NDljKTtcbiAgICAgIH1cbiAgICAgIC5pbXBvcnQtcm93LS1lcnJvciB7XG4gICAgICAgIGJvcmRlci1sZWZ0LWNvbG9yOiB2YXIoLS1pb24tY29sb3ItZGFuZ2VyLCAjYzAzOTJiKTtcbiAgICAgIH1cbiAgICAgIC5pbXBvcnQtcm93X19lbWFpbCB7XG4gICAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgICAgIGNvbG9yOiB2YXIoLS1pb24tY29sb3ItZGFyayk7XG4gICAgICB9XG4gICAgICAuaW1wb3J0LXJvd19fc3RhdHVzIHtcbiAgICAgICAgdGV4dC1hbGlnbjogcmlnaHQ7XG4gICAgICAgIGNvbG9yOiB2YXIoLS1pb24tY29sb3ItbWVkaXVtLXNoYWRlLCAjNmI2ZTc2KTtcbiAgICAgIH1cbiAgICAgIC5pbXBvcnQtcm93X19yZWFzb24ge1xuICAgICAgICBncmlkLWNvbHVtbjogMSAvIC0xO1xuICAgICAgICBmb250LXNpemU6IDEycHg7XG4gICAgICAgIGNvbG9yOiB2YXIoLS1pb24tY29sb3ItZGFuZ2VyLCAjYzAzOTJiKTtcbiAgICAgIH1cbiAgICBgLFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBNZW1iZXJJbXBvcnRNb2RhbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIHByaXZhdGUgaTE4biA9IGluamVjdChJMThuU2VydmljZSk7XG4gIHByaXZhdGUgb3JnU2VydmljZSA9IGluamVjdChPcmdTZXJ2aWNlKTtcblxuICAvKiogT3JnIGRlc3Rpbm8gZGVsIGltcG9ydC4gKi9cbiAgQElucHV0KCkgb3JnSWQgPSAnJztcblxuICAvKiogTm9tYnJlcyBkZSByb2xlcyBkaXNwb25pYmxlcyAocGFyYSBlbCBoaW50KS4gT3BjaW9uYWwuICovXG4gIEBJbnB1dCgpIGF2YWlsYWJsZVJvbGVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIC8qKiBDYWxsYmFjayB0cmFzIHVuYSBpbXBvcnRhY2nDs24gZXhpdG9zYSAo4omlMSBmaWxhIHByb2Nlc2FkYSkg4oCUIHJlZnJlc2NhIGxhIGxpc3RhLiAqL1xuICBASW5wdXQoKSBvblN1Y2Nlc3M/OiAoKSA9PiB2b2lkO1xuXG4gIC8qKiBJbnllY3RhZG8gcG9yIGBNb2RhbFNlcnZpY2Uub3BlbmAuICovXG4gIEBJbnB1dCgpIF9tb2RhbFJlZj86IHsgZGlzbWlzczogKGRhdGE/OiB1bmtub3duLCByb2xlPzogc3RyaW5nKSA9PiB2b2lkIH07XG5cbiAgLyoqIE5hbWVzcGFjZSBpMThuLiAqL1xuICBASW5wdXQoKSBpMThuTmFtZXNwYWNlID0gREVGQVVMVF9OQU1FU1BBQ0U7XG5cbiAgY3N2ID0gJyc7XG4gIG9uQ29uZmxpY3Q6IEltcG9ydE9uQ29uZmxpY3QgPSAnYXNzaWduUm9sZSc7XG4gIHNlbmRBY3RpdmF0aW9uID0gdHJ1ZTtcblxuICByZWFkb25seSBzdWJtaXR0aW5nID0gc2lnbmFsKGZhbHNlKTtcbiAgcmVhZG9ubHkgZXJyb3JNc2cgPSBzaWduYWwoJycpO1xuICByZWFkb25seSByZXN1bHRzID0gc2lnbmFsPEltcG9ydE1lbWJlcnNSZXNwb25zZSB8IG51bGw+KG51bGwpO1xuXG4gIHJlYWRvbmx5IHJvbGVzSGludCA9IGNvbXB1dGVkKCgpID0+XG4gICAgdGhpcy5hdmFpbGFibGVSb2xlcy5sZW5ndGggPyBgJHt0aGlzLnQoJ3JvbGVzQXZhaWxhYmxlJyl9ICR7dGhpcy5hdmFpbGFibGVSb2xlcy5qb2luKCcsICcpfWAgOiAnJ1xuICApO1xuXG4gIHJlYWRvbmx5IHN1bW1hcnlMYWJlbCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBzID0gdGhpcy5yZXN1bHRzKCk/LnN1bW1hcnk7XG4gICAgaWYgKCFzKSByZXR1cm4gdGhpcy50KCdzdW1tYXJ5Jyk7XG4gICAgcmV0dXJuIGAke3RoaXMudCgnc3VtbWFyeScpfTogJHtzLmNyZWF0ZWR9ICR7dGhpcy50KCdjcmVhdGVkJyl9IMK3ICR7cy5hc3NpZ25lZH0gJHt0aGlzLnQoXG4gICAgICAnYXNzaWduZWQnXG4gICAgKX0gwrcgJHtzLnNraXBwZWR9ICR7dGhpcy50KCdza2lwcGVkJyl9IMK3ICR7cy5mYWlsZWR9ICR7dGhpcy50KCdmYWlsZWQnKX1gO1xuICB9KTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBpZiAoIXRoaXMuaTE4bi5oYXNOYW1lc3BhY2UoREVGQVVMVF9OQU1FU1BBQ0UpKSB7XG4gICAgICB0aGlzLmkxOG4ucmVnaXN0ZXJDb250ZW50KERFRkFVTFRfTkFNRVNQQUNFLCBNRU1CRVJfSU1QT1JUX01PREFMX0kxOE4pO1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pMThuLmhhc05hbWVzcGFjZSh0aGlzLmkxOG5OYW1lc3BhY2UpKSB7XG4gICAgICB0aGlzLmkxOG4ucmVnaXN0ZXJDb250ZW50KHRoaXMuaTE4bk5hbWVzcGFjZSwgTUVNQkVSX0lNUE9SVF9NT0RBTF9JMThOKTtcbiAgICB9XG4gIH1cblxuICAvKiogUGFyc2VhIGVsIENTViBwZWdhZG8gYSBmaWxhcyB7ZW1haWwsbmFtZSxyb2xlTmFtZX0uIFRvbGVyYSBoZWFkZXIuICovXG4gIHByaXZhdGUgcGFyc2VDc3YoKTogSW1wb3J0VXNlclJvd1tdIHtcbiAgICBjb25zdCByb3dzOiBJbXBvcnRVc2VyUm93W10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHJhdyBvZiB0aGlzLmNzdi5zcGxpdCgvXFxyP1xcbi8pKSB7XG4gICAgICBjb25zdCBsaW5lID0gcmF3LnRyaW0oKTtcbiAgICAgIGlmICghbGluZSkgY29udGludWU7XG4gICAgICBjb25zdCBjb2xzID0gbGluZS5zcGxpdCgnLCcpLm1hcChjID0+IGMudHJpbSgpKTtcbiAgICAgIGNvbnN0IGVtYWlsID0gKGNvbHNbMF0gPz8gJycpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAvLyBTYWx0YXIgaGVhZGVyIChwcmltZXJhIGNvbCBcImVtYWlsXCIpIG8gbMOtbmVhcyBzaW4gQC5cbiAgICAgIGlmICghZW1haWwgfHwgIWVtYWlsLmluY2x1ZGVzKCdAJykpIGNvbnRpbnVlO1xuICAgICAgcm93cy5wdXNoKHsgZW1haWwsIG5hbWU6IGNvbHNbMV0gPz8gJycsIHJvbGVOYW1lOiBjb2xzWzJdID8/ICcnIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcm93cztcbiAgfVxuXG4gIHN1Ym1pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmVycm9yTXNnLnNldCgnJyk7XG4gICAgY29uc3QgdXNlcnMgPSB0aGlzLnBhcnNlQ3N2KCk7XG4gICAgaWYgKHVzZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5lcnJvck1zZy5zZXQodGhpcy50KCdub1Jvd3MnKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh1c2Vycy5zb21lKHUgPT4gIXUucm9sZU5hbWUpKSB7XG4gICAgICB0aGlzLmVycm9yTXNnLnNldCh0aGlzLnQoJ3BhcnNlRXJyb3InKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zdWJtaXR0aW5nLnNldCh0cnVlKTtcbiAgICB0aGlzLm9yZ1NlcnZpY2VcbiAgICAgIC5pbXBvcnRNZW1iZXJzKHRoaXMub3JnSWQsIHtcbiAgICAgICAgdXNlcnMsXG4gICAgICAgIG9uQ29uZmxpY3Q6IHRoaXMub25Db25mbGljdCxcbiAgICAgICAgc2VuZEFjdGl2YXRpb246IHRoaXMuc2VuZEFjdGl2YXRpb24sXG4gICAgICB9KVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IHJlcyA9PiB7XG4gICAgICAgICAgdGhpcy5zdWJtaXR0aW5nLnNldChmYWxzZSk7XG4gICAgICAgICAgdGhpcy5yZXN1bHRzLnNldChyZXMpO1xuICAgICAgICAgIC8vIFJlZnJlc2NhciBsaXN0YSBkZWwgY29uc3VtZXIgc2kgaHVibyBhbHRhcy9hc2lnbmFjaW9uZXMgZWZlY3RpdmFzLlxuICAgICAgICAgIGlmIChyZXMuc3VtbWFyeS5jcmVhdGVkICsgcmVzLnN1bW1hcnkuYXNzaWduZWQgPiAwKSB7XG4gICAgICAgICAgICB0aGlzLm9uU3VjY2Vzcz8uKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogZXJyID0+IHtcbiAgICAgICAgICB0aGlzLnN1Ym1pdHRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgICB0aGlzLmVycm9yTXNnLnNldChlcnI/LmVycm9yPy5tZXNzYWdlID8/IHRoaXMudCgnZ2VuZXJpY0Vycm9yJykpO1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gIH1cblxuICBzdGF0dXNMYWJlbChyOiBJbXBvcnRSb3dSZXN1bHQpOiBzdHJpbmcge1xuICAgIGNvbnN0IGJhc2UgPSB0aGlzLnQoci5zdGF0dXMgPT09ICdlcnJvcicgPyAnZmFpbGVkJyA6IHIuc3RhdHVzKTtcbiAgICBpZiAoci5zdGF0dXMgPT09ICdjcmVhdGVkJyAmJiByLmFjdGl2YXRpb24pIHtcbiAgICAgIHJldHVybiBgJHtiYXNlfSDCtyAke3RoaXMudChyLmFjdGl2YXRpb24gPT09ICdzZW50JyA/ICdhY3RpdmF0aW9uU2VudCcgOiAnYWN0aXZhdGlvblBlbmRpbmcnKX1gO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZTtcbiAgfVxuXG4gIHJlc2V0KCk6IHZvaWQge1xuICAgIHRoaXMuY3N2ID0gJyc7XG4gICAgdGhpcy5lcnJvck1zZy5zZXQoJycpO1xuICAgIHRoaXMucmVzdWx0cy5zZXQobnVsbCk7XG4gIH1cblxuICBkaXNtaXNzKCk6IHZvaWQge1xuICAgIHRoaXMuX21vZGFsUmVmPy5kaXNtaXNzKG51bGwsICdjYW5jZWwnKTtcbiAgfVxuXG4gIHQoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmkxOG4udChrZXksIHRoaXMuaTE4bk5hbWVzcGFjZSk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Defaults i18n (es/en) embebidos en `val-member-import-modal` (ADR-023).
|
|
3
|
-
* Auto-registrados si el consumer no proveyó el namespace `Settings.ImportModal`.
|
|
4
|
-
*/
|
|
5
|
-
export const MEMBER_IMPORT_MODAL_I18N = {
|
|
6
|
-
es: {
|
|
7
|
-
title: 'Importar miembros',
|
|
8
|
-
hint: 'Pega un CSV con columnas: email, nombre, rol (una fila por persona).',
|
|
9
|
-
csvPlaceholder: 'email,nombre,rol\nana@x.com,Ana,editor\nbeto@x.com,Beto,viewer',
|
|
10
|
-
rolesAvailable: 'Roles disponibles:',
|
|
11
|
-
onConflictLabel: 'Si el email ya existe',
|
|
12
|
-
conflictAssign: 'Asignar el rol',
|
|
13
|
-
conflictSkip: 'Omitir',
|
|
14
|
-
conflictError: 'Marcar error',
|
|
15
|
-
sendActivation: 'Enviar email de activación a las cuentas nuevas',
|
|
16
|
-
submit: 'Importar',
|
|
17
|
-
submitting: 'Importando...',
|
|
18
|
-
parseError: 'No se pudo interpretar el CSV. Revisa el formato.',
|
|
19
|
-
noRows: 'Pega al menos una fila válida (email y rol).',
|
|
20
|
-
summary: 'Resumen',
|
|
21
|
-
created: 'creados',
|
|
22
|
-
assigned: 'asignados',
|
|
23
|
-
skipped: 'omitidos',
|
|
24
|
-
failed: 'con error',
|
|
25
|
-
colEmail: 'Email',
|
|
26
|
-
colStatus: 'Estado',
|
|
27
|
-
colDetail: 'Detalle',
|
|
28
|
-
activationSent: 'activación enviada',
|
|
29
|
-
activationPending: 'activación pendiente',
|
|
30
|
-
again: 'Importar otro lote',
|
|
31
|
-
close: 'Cerrar',
|
|
32
|
-
genericError: 'No se pudo completar la importación. Intenta de nuevo.',
|
|
33
|
-
},
|
|
34
|
-
en: {
|
|
35
|
-
title: 'Import members',
|
|
36
|
-
hint: 'Paste a CSV with columns: email, name, role (one row per person).',
|
|
37
|
-
csvPlaceholder: 'email,name,role\nana@x.com,Ana,editor\nbeto@x.com,Beto,viewer',
|
|
38
|
-
rolesAvailable: 'Available roles:',
|
|
39
|
-
onConflictLabel: 'If the email already exists',
|
|
40
|
-
conflictAssign: 'Assign the role',
|
|
41
|
-
conflictSkip: 'Skip',
|
|
42
|
-
conflictError: 'Mark as error',
|
|
43
|
-
sendActivation: 'Send activation email to new accounts',
|
|
44
|
-
submit: 'Import',
|
|
45
|
-
submitting: 'Importing...',
|
|
46
|
-
parseError: "Couldn't parse the CSV. Check the format.",
|
|
47
|
-
noRows: 'Paste at least one valid row (email and role).',
|
|
48
|
-
summary: 'Summary',
|
|
49
|
-
created: 'created',
|
|
50
|
-
assigned: 'assigned',
|
|
51
|
-
skipped: 'skipped',
|
|
52
|
-
failed: 'failed',
|
|
53
|
-
colEmail: 'Email',
|
|
54
|
-
colStatus: 'Status',
|
|
55
|
-
colDetail: 'Detail',
|
|
56
|
-
activationSent: 'activation sent',
|
|
57
|
-
activationPending: 'activation pending',
|
|
58
|
-
again: 'Import another batch',
|
|
59
|
-
close: 'Close',
|
|
60
|
-
genericError: "Couldn't complete the import. Try again.",
|
|
61
|
-
},
|
|
62
|
-
};
|
|
63
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtYmVyLWltcG9ydC1tb2RhbC5pMThuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9jb21wb25lbnRzL29yZ2FuaXNtcy9tZW1iZXItaW1wb3J0LW1vZGFsL21lbWJlci1pbXBvcnQtbW9kYWwuaTE4bi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBcUI7SUFDeEQsRUFBRSxFQUFFO1FBQ0YsS0FBSyxFQUFFLG1CQUFtQjtRQUMxQixJQUFJLEVBQUUsc0VBQXNFO1FBQzVFLGNBQWMsRUFBRSxnRUFBZ0U7UUFDaEYsY0FBYyxFQUFFLG9CQUFvQjtRQUNwQyxlQUFlLEVBQUUsdUJBQXVCO1FBQ3hDLGNBQWMsRUFBRSxnQkFBZ0I7UUFDaEMsWUFBWSxFQUFFLFFBQVE7UUFDdEIsYUFBYSxFQUFFLGNBQWM7UUFDN0IsY0FBYyxFQUFFLGlEQUFpRDtRQUNqRSxNQUFNLEVBQUUsVUFBVTtRQUNsQixVQUFVLEVBQUUsZUFBZTtRQUMzQixVQUFVLEVBQUUsbURBQW1EO1FBQy9ELE1BQU0sRUFBRSw4Q0FBOEM7UUFDdEQsT0FBTyxFQUFFLFNBQVM7UUFDbEIsT0FBTyxFQUFFLFNBQVM7UUFDbEIsUUFBUSxFQUFFLFdBQVc7UUFDckIsT0FBTyxFQUFFLFVBQVU7UUFDbkIsTUFBTSxFQUFFLFdBQVc7UUFDbkIsUUFBUSxFQUFFLE9BQU87UUFDakIsU0FBUyxFQUFFLFFBQVE7UUFDbkIsU0FBUyxFQUFFLFNBQVM7UUFDcEIsY0FBYyxFQUFFLG9CQUFvQjtRQUNwQyxpQkFBaUIsRUFBRSxzQkFBc0I7UUFDekMsS0FBSyxFQUFFLG9CQUFvQjtRQUMzQixLQUFLLEVBQUUsUUFBUTtRQUNmLFlBQVksRUFBRSx3REFBd0Q7S0FDdkU7SUFDRCxFQUFFLEVBQUU7UUFDRixLQUFLLEVBQUUsZ0JBQWdCO1FBQ3ZCLElBQUksRUFBRSxtRUFBbUU7UUFDekUsY0FBYyxFQUFFLCtEQUErRDtRQUMvRSxjQUFjLEVBQUUsa0JBQWtCO1FBQ2xDLGVBQWUsRUFBRSw2QkFBNkI7UUFDOUMsY0FBYyxFQUFFLGlCQUFpQjtRQUNqQyxZQUFZLEVBQUUsTUFBTTtRQUNwQixhQUFhLEVBQUUsZUFBZTtRQUM5QixjQUFjLEVBQUUsdUNBQXVDO1FBQ3ZELE1BQU0sRUFBRSxRQUFRO1FBQ2hCLFVBQVUsRUFBRSxjQUFjO1FBQzFCLFVBQVUsRUFBRSwyQ0FBMkM7UUFDdkQsTUFBTSxFQUFFLGdEQUFnRDtRQUN4RCxPQUFPLEVBQUUsU0FBUztRQUNsQixPQUFPLEVBQUUsU0FBUztRQUNsQixRQUFRLEVBQUUsVUFBVTtRQUNwQixPQUFPLEVBQUUsU0FBUztRQUNsQixNQUFNLEVBQUUsUUFBUTtRQUNoQixRQUFRLEVBQUUsT0FBTztRQUNqQixTQUFTLEVBQUUsUUFBUTtRQUNuQixTQUFTLEVBQUUsUUFBUTtRQUNuQixjQUFjLEVBQUUsaUJBQWlCO1FBQ2pDLGlCQUFpQixFQUFFLG9CQUFvQjtRQUN2QyxLQUFLLEVBQUUsc0JBQXNCO1FBQzdCLEtBQUssRUFBRSxPQUFPO1FBQ2QsWUFBWSxFQUFFLDBDQUEwQztLQUN6RDtDQUNGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMYW5ndWFnZXNDb250ZW50IH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvaTE4bi90eXBlcyc7XG5cbi8qKlxuICogRGVmYXVsdHMgaTE4biAoZXMvZW4pIGVtYmViaWRvcyBlbiBgdmFsLW1lbWJlci1pbXBvcnQtbW9kYWxgIChBRFItMDIzKS5cbiAqIEF1dG8tcmVnaXN0cmFkb3Mgc2kgZWwgY29uc3VtZXIgbm8gcHJvdmV5w7MgZWwgbmFtZXNwYWNlIGBTZXR0aW5ncy5JbXBvcnRNb2RhbGAuXG4gKi9cbmV4cG9ydCBjb25zdCBNRU1CRVJfSU1QT1JUX01PREFMX0kxOE46IExhbmd1YWdlc0NvbnRlbnQgPSB7XG4gIGVzOiB7XG4gICAgdGl0bGU6ICdJbXBvcnRhciBtaWVtYnJvcycsXG4gICAgaGludDogJ1BlZ2EgdW4gQ1NWIGNvbiBjb2x1bW5hczogZW1haWwsIG5vbWJyZSwgcm9sICh1bmEgZmlsYSBwb3IgcGVyc29uYSkuJyxcbiAgICBjc3ZQbGFjZWhvbGRlcjogJ2VtYWlsLG5vbWJyZSxyb2xcXG5hbmFAeC5jb20sQW5hLGVkaXRvclxcbmJldG9AeC5jb20sQmV0byx2aWV3ZXInLFxuICAgIHJvbGVzQXZhaWxhYmxlOiAnUm9sZXMgZGlzcG9uaWJsZXM6JyxcbiAgICBvbkNvbmZsaWN0TGFiZWw6ICdTaSBlbCBlbWFpbCB5YSBleGlzdGUnLFxuICAgIGNvbmZsaWN0QXNzaWduOiAnQXNpZ25hciBlbCByb2wnLFxuICAgIGNvbmZsaWN0U2tpcDogJ09taXRpcicsXG4gICAgY29uZmxpY3RFcnJvcjogJ01hcmNhciBlcnJvcicsXG4gICAgc2VuZEFjdGl2YXRpb246ICdFbnZpYXIgZW1haWwgZGUgYWN0aXZhY2nDs24gYSBsYXMgY3VlbnRhcyBudWV2YXMnLFxuICAgIHN1Ym1pdDogJ0ltcG9ydGFyJyxcbiAgICBzdWJtaXR0aW5nOiAnSW1wb3J0YW5kby4uLicsXG4gICAgcGFyc2VFcnJvcjogJ05vIHNlIHB1ZG8gaW50ZXJwcmV0YXIgZWwgQ1NWLiBSZXZpc2EgZWwgZm9ybWF0by4nLFxuICAgIG5vUm93czogJ1BlZ2EgYWwgbWVub3MgdW5hIGZpbGEgdsOhbGlkYSAoZW1haWwgeSByb2wpLicsXG4gICAgc3VtbWFyeTogJ1Jlc3VtZW4nLFxuICAgIGNyZWF0ZWQ6ICdjcmVhZG9zJyxcbiAgICBhc3NpZ25lZDogJ2FzaWduYWRvcycsXG4gICAgc2tpcHBlZDogJ29taXRpZG9zJyxcbiAgICBmYWlsZWQ6ICdjb24gZXJyb3InLFxuICAgIGNvbEVtYWlsOiAnRW1haWwnLFxuICAgIGNvbFN0YXR1czogJ0VzdGFkbycsXG4gICAgY29sRGV0YWlsOiAnRGV0YWxsZScsXG4gICAgYWN0aXZhdGlvblNlbnQ6ICdhY3RpdmFjacOzbiBlbnZpYWRhJyxcbiAgICBhY3RpdmF0aW9uUGVuZGluZzogJ2FjdGl2YWNpw7NuIHBlbmRpZW50ZScsXG4gICAgYWdhaW46ICdJbXBvcnRhciBvdHJvIGxvdGUnLFxuICAgIGNsb3NlOiAnQ2VycmFyJyxcbiAgICBnZW5lcmljRXJyb3I6ICdObyBzZSBwdWRvIGNvbXBsZXRhciBsYSBpbXBvcnRhY2nDs24uIEludGVudGEgZGUgbnVldm8uJyxcbiAgfSxcbiAgZW46IHtcbiAgICB0aXRsZTogJ0ltcG9ydCBtZW1iZXJzJyxcbiAgICBoaW50OiAnUGFzdGUgYSBDU1Ygd2l0aCBjb2x1bW5zOiBlbWFpbCwgbmFtZSwgcm9sZSAob25lIHJvdyBwZXIgcGVyc29uKS4nLFxuICAgIGNzdlBsYWNlaG9sZGVyOiAnZW1haWwsbmFtZSxyb2xlXFxuYW5hQHguY29tLEFuYSxlZGl0b3JcXG5iZXRvQHguY29tLEJldG8sdmlld2VyJyxcbiAgICByb2xlc0F2YWlsYWJsZTogJ0F2YWlsYWJsZSByb2xlczonLFxuICAgIG9uQ29uZmxpY3RMYWJlbDogJ0lmIHRoZSBlbWFpbCBhbHJlYWR5IGV4aXN0cycsXG4gICAgY29uZmxpY3RBc3NpZ246ICdBc3NpZ24gdGhlIHJvbGUnLFxuICAgIGNvbmZsaWN0U2tpcDogJ1NraXAnLFxuICAgIGNvbmZsaWN0RXJyb3I6ICdNYXJrIGFzIGVycm9yJyxcbiAgICBzZW5kQWN0aXZhdGlvbjogJ1NlbmQgYWN0aXZhdGlvbiBlbWFpbCB0byBuZXcgYWNjb3VudHMnLFxuICAgIHN1Ym1pdDogJ0ltcG9ydCcsXG4gICAgc3VibWl0dGluZzogJ0ltcG9ydGluZy4uLicsXG4gICAgcGFyc2VFcnJvcjogXCJDb3VsZG4ndCBwYXJzZSB0aGUgQ1NWLiBDaGVjayB0aGUgZm9ybWF0LlwiLFxuICAgIG5vUm93czogJ1Bhc3RlIGF0IGxlYXN0IG9uZSB2YWxpZCByb3cgKGVtYWlsIGFuZCByb2xlKS4nLFxuICAgIHN1bW1hcnk6ICdTdW1tYXJ5JyxcbiAgICBjcmVhdGVkOiAnY3JlYXRlZCcsXG4gICAgYXNzaWduZWQ6ICdhc3NpZ25lZCcsXG4gICAgc2tpcHBlZDogJ3NraXBwZWQnLFxuICAgIGZhaWxlZDogJ2ZhaWxlZCcsXG4gICAgY29sRW1haWw6ICdFbWFpbCcsXG4gICAgY29sU3RhdHVzOiAnU3RhdHVzJyxcbiAgICBjb2xEZXRhaWw6ICdEZXRhaWwnLFxuICAgIGFjdGl2YXRpb25TZW50OiAnYWN0aXZhdGlvbiBzZW50JyxcbiAgICBhY3RpdmF0aW9uUGVuZGluZzogJ2FjdGl2YXRpb24gcGVuZGluZycsXG4gICAgYWdhaW46ICdJbXBvcnQgYW5vdGhlciBiYXRjaCcsXG4gICAgY2xvc2U6ICdDbG9zZScsXG4gICAgZ2VuZXJpY0Vycm9yOiBcIkNvdWxkbid0IGNvbXBsZXRlIHRoZSBpbXBvcnQuIFRyeSBhZ2Fpbi5cIixcbiAgfSxcbn07XG4iXX0=
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { OnInit } from '@angular/core';
|
|
2
|
-
import { ImportMembersResponse, ImportOnConflict, ImportRowResult } from '../../../services/org/types';
|
|
3
|
-
import * as i0 from "@angular/core";
|
|
4
|
-
/**
|
|
5
|
-
* `val-member-import-modal` — panel de carga masiva de miembros (ADR-023 fase 6).
|
|
6
|
-
*
|
|
7
|
-
* El admin pega un CSV (`email,nombre,rol`); el modal lo parsea a filas y llama
|
|
8
|
-
* `OrgService.importMembers`. Muestra el resultado por-fila (partial success):
|
|
9
|
-
* `created` / `assigned` / `skipped` / `error`. Header canónico (Regla #5).
|
|
10
|
-
*
|
|
11
|
-
* Auto-registra defaults i18n (es/en) en `Settings.ImportModal`.
|
|
12
|
-
*/
|
|
13
|
-
export declare class MemberImportModalComponent implements OnInit {
|
|
14
|
-
private i18n;
|
|
15
|
-
private orgService;
|
|
16
|
-
/** Org destino del import. */
|
|
17
|
-
orgId: string;
|
|
18
|
-
/** Nombres de roles disponibles (para el hint). Opcional. */
|
|
19
|
-
availableRoles: string[];
|
|
20
|
-
/** Callback tras una importación exitosa (≥1 fila procesada) — refresca la lista. */
|
|
21
|
-
onSuccess?: () => void;
|
|
22
|
-
/** Inyectado por `ModalService.open`. */
|
|
23
|
-
_modalRef?: {
|
|
24
|
-
dismiss: (data?: unknown, role?: string) => void;
|
|
25
|
-
};
|
|
26
|
-
/** Namespace i18n. */
|
|
27
|
-
i18nNamespace: string;
|
|
28
|
-
csv: string;
|
|
29
|
-
onConflict: ImportOnConflict;
|
|
30
|
-
sendActivation: boolean;
|
|
31
|
-
readonly submitting: import("@angular/core").WritableSignal<boolean>;
|
|
32
|
-
readonly errorMsg: import("@angular/core").WritableSignal<string>;
|
|
33
|
-
readonly results: import("@angular/core").WritableSignal<ImportMembersResponse>;
|
|
34
|
-
readonly rolesHint: import("@angular/core").Signal<string>;
|
|
35
|
-
readonly summaryLabel: import("@angular/core").Signal<string>;
|
|
36
|
-
constructor();
|
|
37
|
-
ngOnInit(): void;
|
|
38
|
-
/** Parsea el CSV pegado a filas {email,name,roleName}. Tolera header. */
|
|
39
|
-
private parseCsv;
|
|
40
|
-
submit(): void;
|
|
41
|
-
statusLabel(r: ImportRowResult): string;
|
|
42
|
-
reset(): void;
|
|
43
|
-
dismiss(): void;
|
|
44
|
-
t(key: string): string;
|
|
45
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<MemberImportModalComponent, never>;
|
|
46
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<MemberImportModalComponent, "val-member-import-modal", never, { "orgId": { "alias": "orgId"; "required": false; }; "availableRoles": { "alias": "availableRoles"; "required": false; }; "onSuccess": { "alias": "onSuccess"; "required": false; }; "_modalRef": { "alias": "_modalRef"; "required": false; }; "i18nNamespace": { "alias": "i18nNamespace"; "required": false; }; }, {}, never, never, true, never>;
|
|
47
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { LanguagesContent } from '../../../services/i18n/types';
|
|
2
|
-
/**
|
|
3
|
-
* Defaults i18n (es/en) embebidos en `val-member-import-modal` (ADR-023).
|
|
4
|
-
* Auto-registrados si el consumer no proveyó el namespace `Settings.ImportModal`.
|
|
5
|
-
*/
|
|
6
|
-
export declare const MEMBER_IMPORT_MODAL_I18N: LanguagesContent;
|