Merge pull request #6186 from tsiegleauq/import-supporter
Add CSV import for supporters
This commit is contained in:
commit
18ffcaca92
@ -32,6 +32,11 @@ export class ImportCreateMotion extends CreateMotion {
|
||||
*/
|
||||
public csvSubmitters: CsvMapping[];
|
||||
|
||||
/**
|
||||
* Mapping for new/existing supporters.
|
||||
*/
|
||||
public csvSupporters: CsvMapping[];
|
||||
|
||||
/**
|
||||
* Mapping for new/existing tags.
|
||||
*/
|
||||
@ -115,6 +120,30 @@ export class ImportCreateMotion extends CreateMotion {
|
||||
return open;
|
||||
}
|
||||
|
||||
public solveSupporters(supporters: CsvMapping[]): number {
|
||||
let open = 0;
|
||||
const ids: number[] = [];
|
||||
this.csvSupporters.forEach(csvSupporter => {
|
||||
if (csvSupporter.id) {
|
||||
ids.push(csvSupporter.id);
|
||||
return;
|
||||
}
|
||||
if (!supporters.length) {
|
||||
open += 1;
|
||||
return;
|
||||
}
|
||||
const mapped = supporters.find(newSupporter => newSupporter.name === csvSupporter.name);
|
||||
if (mapped) {
|
||||
csvSupporter.id = mapped.id;
|
||||
ids.push(mapped.id);
|
||||
} else {
|
||||
open += 1;
|
||||
}
|
||||
});
|
||||
this.supporters_id = ids;
|
||||
return open;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to iterate over the found tags.
|
||||
*
|
||||
|
@ -18,8 +18,7 @@
|
||||
<br />
|
||||
<div class="code red-warning-text">
|
||||
<span *ngFor="let header of this.expectedHeader; let last = last">
|
||||
<span>{{ header | translate }}</span
|
||||
><span *ngIf="!last">, </span>
|
||||
{{ header | translate }}<span *ngIf="!last">, </span>
|
||||
</span>
|
||||
</div>
|
||||
<ul>
|
||||
@ -41,11 +40,7 @@
|
||||
<div class="wrapper">
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'Encoding of the file' | translate }}</mat-label>
|
||||
<mat-select
|
||||
class="selection"
|
||||
(selectionChange)="selectEncoding($event)"
|
||||
[value]="encodings[0].value"
|
||||
>
|
||||
<mat-select class="selection" (selectionChange)="selectEncoding($event)" [value]="encodings[0].value">
|
||||
<mat-option *ngFor="let option of encodings" [value]="option.value">
|
||||
{{ option.label | translate }}
|
||||
</mat-option>
|
||||
@ -220,6 +215,27 @@
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- supporters column -->
|
||||
<ng-container matColumnDef="supporters">
|
||||
<mat-header-cell *matHeaderCellDef>{{ 'Supporters' | translate }}</mat-header-cell>
|
||||
<mat-cell *matCellDef="let entry">
|
||||
<div *ngIf="entry.newEntry?.csvSupporters?.length">
|
||||
<mat-icon
|
||||
color="warn"
|
||||
*ngIf="hasError(entry, 'Supporters')"
|
||||
matTooltip="{{ getVerboseError('Supporters') | translate }}"
|
||||
>
|
||||
warning
|
||||
</mat-icon>
|
||||
<div *ngFor="let supporters of entry.newEntry.csvSupporters">
|
||||
{{ supporters.name }}
|
||||
<mat-icon class="newBadge" color="accent" inline *ngIf="!supporters.id">add</mat-icon>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- category column -->
|
||||
<ng-container matColumnDef="category">
|
||||
<mat-header-cell *matHeaderCellDef>{{ 'Category' | translate }}</mat-header-cell>
|
||||
|
@ -175,6 +175,7 @@ export class MotionCsvExportService {
|
||||
const headerRow = [
|
||||
'Identifier',
|
||||
'Submitters',
|
||||
'Supporters',
|
||||
'Title',
|
||||
'Text',
|
||||
'Reason',
|
||||
@ -187,6 +188,7 @@ export class MotionCsvExportService {
|
||||
[
|
||||
'A1',
|
||||
'Submitter A',
|
||||
'Supporter A',
|
||||
'Title 1',
|
||||
'Text 1',
|
||||
'Reason 1',
|
||||
@ -195,8 +197,19 @@ export class MotionCsvExportService {
|
||||
'Block A',
|
||||
'Last Year Conference A'
|
||||
],
|
||||
['B1', 'Submitter B', 'Title 2', 'Text 2', 'Reason 2', 'Category B', null, 'Block A', 'Origin B'],
|
||||
['C2', null, 'Title 3', 'Text 3', null, null, null, null, null]
|
||||
[
|
||||
'B1',
|
||||
'Submitter B',
|
||||
'Supporter B',
|
||||
'Title 2',
|
||||
'Text 2',
|
||||
'Reason 2',
|
||||
'Category B',
|
||||
null,
|
||||
'Block A',
|
||||
'Origin B'
|
||||
],
|
||||
['C2', null, null, 'Title 3', 'Text 3', null, null, null, null, null]
|
||||
];
|
||||
this.csvExport.dummyCSVExport(headerRow, rows, `${this.translate.instant('motions-example')}.csv`);
|
||||
}
|
||||
|
@ -48,6 +48,11 @@ export class MotionImportService extends BaseImportService<Motion> {
|
||||
*/
|
||||
public newSubmitters: CsvMapping[] = [];
|
||||
|
||||
/**
|
||||
* supporters that need to be created prior to importing
|
||||
*/
|
||||
public newSupporters: CsvMapping[] = [];
|
||||
|
||||
/**
|
||||
* Categories that need to be created prior to importing
|
||||
*/
|
||||
@ -92,6 +97,7 @@ export class MotionImportService extends BaseImportService<Motion> {
|
||||
*/
|
||||
public clearData(): void {
|
||||
this.newSubmitters = [];
|
||||
this.newSupporters = [];
|
||||
this.newCategories = [];
|
||||
this.newMotionBlocks = [];
|
||||
this.newTags = [];
|
||||
@ -110,7 +116,10 @@ export class MotionImportService extends BaseImportService<Motion> {
|
||||
for (let idx = 0; idx < headerLength; idx++) {
|
||||
switch (this.expectedHeader[idx]) {
|
||||
case 'submitters':
|
||||
newEntry.csvSubmitters = this.getSubmitters(line[idx]);
|
||||
newEntry.csvSubmitters = this.getUsers(line[idx], 'submitter');
|
||||
break;
|
||||
case 'supporters':
|
||||
newEntry.csvSupporters = this.getUsers(line[idx], 'supporter');
|
||||
break;
|
||||
case 'category':
|
||||
newEntry.csvCategory = this.getCategory(line[idx]);
|
||||
@ -150,7 +159,8 @@ export class MotionImportService extends BaseImportService<Motion> {
|
||||
public async doImport(): Promise<void> {
|
||||
this.newMotionBlocks = await this.createNewMotionBlocks();
|
||||
this.newCategories = await this.createNewCategories();
|
||||
this.newSubmitters = await this.createNewUsers();
|
||||
this.newSubmitters = await this.createNewUsers(this.newSubmitters);
|
||||
this.newSupporters = await this.createNewUsers(this.newSupporters);
|
||||
this.newTags = await this.createNewTags();
|
||||
|
||||
for (const entry of this.entries) {
|
||||
@ -169,12 +179,18 @@ export class MotionImportService extends BaseImportService<Motion> {
|
||||
this.updatePreview();
|
||||
continue;
|
||||
}
|
||||
const openUsers = (entry.newEntry as ImportCreateMotion).solveSubmitters(this.newSubmitters);
|
||||
if (openUsers) {
|
||||
const openSubmitters = (entry.newEntry as ImportCreateMotion).solveSubmitters(this.newSubmitters);
|
||||
if (openSubmitters) {
|
||||
this.setError(entry, 'Submitters');
|
||||
this.updatePreview();
|
||||
continue;
|
||||
}
|
||||
const openSupporters = (entry.newEntry as ImportCreateMotion).solveSupporters(this.newSupporters);
|
||||
if (openSupporters) {
|
||||
this.setError(entry, 'Supporters');
|
||||
this.updatePreview();
|
||||
continue;
|
||||
}
|
||||
const openTags = (entry.newEntry as ImportCreateMotion).solveTags(this.newTags);
|
||||
if (openTags) {
|
||||
this.setError(entry, 'Tags');
|
||||
@ -191,39 +207,51 @@ export class MotionImportService extends BaseImportService<Motion> {
|
||||
* Checks the provided submitter(s) and returns an object with mapping of
|
||||
* existing users and of users that need to be created
|
||||
*
|
||||
* @param submitterlist
|
||||
* @param userList
|
||||
* @returns a list of submitters mapped with (if already existing) their id
|
||||
*/
|
||||
public getSubmitters(submitterlist: string): CsvMapping[] {
|
||||
public getUsers(userList: string, kind: 'submitter' | 'supporter'): CsvMapping[] {
|
||||
console.log('kind: ', kind);
|
||||
const result: CsvMapping[] = [];
|
||||
if (!submitterlist) {
|
||||
if (!userList) {
|
||||
return result;
|
||||
}
|
||||
const submitterArray = submitterlist.split(','); // TODO fails with 'full name'
|
||||
for (const submitter of submitterArray) {
|
||||
const existingSubmitters = this.userRepo.getUsersByName(submitter.trim());
|
||||
if (!existingSubmitters.length) {
|
||||
if (!this.newSubmitters.find(listedSubmitter => listedSubmitter.name === submitter)) {
|
||||
this.newSubmitters.push({ name: submitter });
|
||||
const userArray = userList.split(','); // TODO fails with 'full name'
|
||||
|
||||
console.log('userArray: ', userList);
|
||||
for (const user of userArray) {
|
||||
const existingUsers = this.userRepo.getUsersByName(user.trim());
|
||||
if (!existingUsers.length) {
|
||||
if (kind === 'submitter') {
|
||||
if (!this.newSubmitters.find(listedSubmitter => listedSubmitter.name === user)) {
|
||||
this.newSubmitters.push({ name: user });
|
||||
}
|
||||
result.push({ name: user });
|
||||
} else if (kind === 'supporter') {
|
||||
if (!this.newSupporters.find(listedSupporter => listedSupporter.name === user)) {
|
||||
this.newSupporters.push({ name: user });
|
||||
}
|
||||
result.push({ name: user });
|
||||
}
|
||||
result.push({ name: submitter });
|
||||
}
|
||||
if (existingSubmitters.length === 1) {
|
||||
if (existingUsers.length === 1) {
|
||||
result.push({
|
||||
name: existingSubmitters[0].short_name,
|
||||
id: existingSubmitters[0].id
|
||||
name: existingUsers[0].short_name,
|
||||
id: existingUsers[0].id
|
||||
});
|
||||
}
|
||||
if (existingSubmitters.length > 1) {
|
||||
if (existingUsers.length > 1) {
|
||||
result.push({
|
||||
name: submitter,
|
||||
multiId: existingSubmitters.map(ex => ex.id)
|
||||
name: user,
|
||||
multiId: existingUsers.map(ex => ex.id)
|
||||
});
|
||||
this.matSnackbar.open('TODO: multiple possible users found for this string', 'ok');
|
||||
// TODO How to handle several submitters ? Is this possible?
|
||||
// should have some kind of choice dialog there
|
||||
}
|
||||
}
|
||||
|
||||
console.log('res: ', result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -331,9 +359,9 @@ export class MotionImportService extends BaseImportService<Motion> {
|
||||
*
|
||||
* @returns a promise with list of new Submitters, updated with newly created ids
|
||||
*/
|
||||
private async createNewUsers(): Promise<CsvMapping[]> {
|
||||
private async createNewUsers(list: CsvMapping[]): Promise<CsvMapping[]> {
|
||||
const promises: Promise<CsvMapping>[] = [];
|
||||
for (const user of this.newSubmitters) {
|
||||
for (const user of list) {
|
||||
promises.push(this.userRepo.createFromString(user.name));
|
||||
}
|
||||
return await Promise.all(promises);
|
||||
|
@ -700,7 +700,7 @@ button.mat-menu-item.selected {
|
||||
|
||||
.first-column {
|
||||
flex: 1;
|
||||
min-width: 0px;
|
||||
min-width: 40px;
|
||||
}
|
||||
|
||||
.filter-imports {
|
||||
|
Loading…
Reference in New Issue
Block a user