OpenSlides/client/src/app/site/motions/models/view-csv-create-motion.ts

181 lines
4.9 KiB
TypeScript
Raw Normal View History

2018-12-04 19:31:24 +01:00
import { ViewCreateMotion } from './view-create-motion';
import { CreateMotion } from './create-motion';
/**
* Interface for imported secondary data. A name can be matched to an existing
* model instance by the solve... functions.
* TODO MultiId will be filled if there is more than one match (to be used in case of 'I want to select one of these matches)
*/
export interface CsvMapping {
name: string;
id?: number;
multiId?: number[];
}
type CsvImportStatus = 'new' | 'error' | 'done';
/**
* Create motion class for the View. Its different to ViewMotion in fact that the submitter handling is different
* on motion creation.
*
* @ignore
*/
export class ViewCsvCreateMotion extends ViewCreateMotion {
protected _motion: CreateMotion;
/**
* Mapping for a new/existing category.
*/
public csvCategory: CsvMapping;
/**
* Mapping for a new/existing motion block.
*/
public csvMotionblock: CsvMapping;
/**
* Mapping for new/existing submitters.
*/
public csvSubmitters: CsvMapping[];
/**
* The current import status of this motion.
* Starts as 'new', if set to 'done', a proper {@link Motion} model will
* probably exist in the dataStore. error status will be set if the import
* cannot be done
*/
private _status: CsvImportStatus = 'new';
/**
* list of import errors See {@link MotionImportService}
*/
public errors: string[] = [];
/**
* Returns the current status.
*/
public get status(): CsvImportStatus {
return this._status;
}
public set status(status: CsvImportStatus) {
this._status = status;
}
public get motion(): CreateMotion {
return this._motion;
}
public constructor(motion?: CreateMotion) {
super(motion);
}
/**
* Duplicate this motion into a copy of itself
*/
public copy(): ViewCreateMotion {
return new ViewCreateMotion(
this._motion,
this._category,
this._submitters,
this._supporters,
this._workflow,
this._state
);
}
/**
* Checks if a given error is present. TODO: Is more a ViewModel option
*
* @param error
*/
public hasError(error: string): boolean {
return this.errors.includes(error);
}
/**
* Toggle to set a CreateMotion to a 'successfully parsed' status
*/
public done(): void {
this._status = 'done';
}
/**
* takes a list of motion block mappings to update the current csvMotionblock.
* Returns the amount of entries that remain unmatched
*
* @param motionBlocks
*/
public solveMotionBlocks(motionBlocks: CsvMapping[]): number {
if (!this.csvMotionblock) {
return 0;
} else if (this.csvMotionblock.id) {
this.motion.motion_block_id = this.csvMotionblock.id;
return 0;
} else {
const newBlock = motionBlocks.find(newMotionBlock => newMotionBlock.name === this.csvMotionblock.name);
if (newBlock) {
this.csvMotionblock = newBlock;
this.motion.motion_block_id = newBlock.id;
return 0;
} else {
return 1;
}
}
}
/**
* takes a list of category maps to update the current csv_category.
* Returns the amount of entries that remain unmatched
*
* @param categories
*/
public solveCategory(categories: CsvMapping[]): number {
if (!this.csvCategory) {
return 0;
} else if (this.csvCategory.id) {
this.motion.category_id = this.csvCategory.id;
return 0;
} else {
const newCat = categories.find(newCategory => newCategory.name === this.csvCategory.name);
if (newCat) {
this.csvCategory = newCat;
this.motion.category_id = newCat.id;
return 0;
} else {
return 1;
}
}
}
/**
* takes a list of solved submitter maps to update. Returns the amount of
* entries that remain unmatched
*
* @param submitters
*/
public solveSubmitters(submitters: CsvMapping[]): number {
let open = 0;
const ids: number[] = [];
this.csvSubmitters.forEach(csvSubmitter => {
if (csvSubmitter.id) {
ids.push(csvSubmitter.id);
return;
}
if (!submitters.length) {
open += 1;
return;
}
const mapped = submitters.find(newSubmitter => newSubmitter.name === csvSubmitter.name);
if (mapped) {
csvSubmitter.id = mapped.id;
ids.push(mapped.id);
} else {
open += 1;
}
});
this.motion.submitters_id = ids;
return open;
}
}