add choices for the future

This commit is contained in:
Tykayn 2021-02-05 17:02:52 +01:00 committed by tykayn
parent 2d49389d11
commit 237984c040
9 changed files with 324 additions and 253 deletions

View File

@ -36,22 +36,22 @@ export class Poll {
new User(item.owner.pseudo, item.owner.email, undefined),
item.slug,
item.title,
item.description,
item.configuration,
item.comments
.map(
(c: Pick<Comment, 'author' | 'content' | 'dateCreated'>) =>
new Comment(c.author, c.content, new Date(c.dateCreated))
)
.sort(Comment.sortChronologically),
item.choices.map((c: Pick<Choice, 'label' | 'imageUrl' | 'participants' | 'counts'>) => {
const choice = new Choice(c.label, c.imageUrl, new Map(c.participants));
choice.participants.forEach((value, key) => {
choice.participants.set(key, new Set(value));
});
choice.updateCounts();
return choice;
})
item.description
// item.configuration,
// item.comments
// .map(
// (c: Pick<Comment, 'author' | 'content' | 'dateCreated'>) =>
// new Comment(c.author, c.content, new Date(c.dateCreated))
// )
// .sort(Comment.sortChronologically),
// item.choices.map((c: Pick<Choice, 'label' | 'imageUrl' | 'participants' | 'counts'>) => {
// const choice = new Choice(c.label, c.imageUrl, new Map(c.participants));
// choice.participants.forEach((value, key) => {
// choice.participants.set(key, new Set(value));
// });
// choice.updateCounts();
// return choice;
// })
);
}
}

View File

@ -23,9 +23,8 @@
<br />
<label for="slug"
>Url pour les participants
<label for="slug">
Url personnalisée pour les participants
<i class="fa fa-close"></i>
</label>
<br />
@ -48,13 +47,16 @@
<input #slug matInput id="slug" placeholder="Url" formControlName="slug" required />
<br />
<div appearance="outline" class="is-not-flex">
<mat-label>Nombre de jours avant expiration</mat-label>
<mat-label
>Nombre de jours avant expiration de la possibilité de voter, après le sondage reste
consultable</mat-label
>
<input
#expiracy
id="expiracy"
matInput
type="number"
placeholder="Nombre de jours avant expiration"
placeholder="Nombre de jours avant fin des votes"
formControlName="expiracyNumberOfDays"
required
/>
@ -69,15 +71,57 @@
<i class="fa fa-close"></i>
</button>
</div>
<div appearance="outline" class="is-not-flex">
<mat-label
>Nombre de jours avant archivage, après quoi le sondage n'est plus visible par le public</mat-label
>
<input
#archive
id="archive"
matInput
type="number"
placeholder="Nombre de jours avant archivage"
formControlName="archiveNumberOfDays"
required
/>
<button
mat-button
*ngIf="archive.value"
matSuffix
mat-icon-button
aria-label="Clear"
(click)="archive.value = ''"
>
<i class="fa fa-close"></i>
</button>
</div>
<mat-checkbox class="is-not-flex" formControlName="areResultsPublic">
Les participants pourront consulter les résultats
</mat-checkbox>
<mat-checkbox class="is-not-flex" formControlName="isAboutDate">
Les choix possibles concerneront des dates
</mat-checkbox>
<h3 class="title is-3">
<i class="fa fa-lock"></i>
Accès sécurisé
</h3>
<mat-checkbox class="is-not-flex" formControlName="isProtectedByPassword">
Le sondage sera protégé par un mot de passe
</mat-checkbox>
<input
*ngIf="form.value.isProtectedByPassword"
#password
id="password"
matInput
type="password"
placeholder="password"
formControlName="password"
required
/>
<h3 class="title is-3">
<i class="fa fa-enveloppe"></i>
Notifications
</h3>
<mat-checkbox class="is-not-flex" formControlName="isOwnerNotifiedByEmailOnNewVote">
Vous recevrez un mail à chaque nouvelle participation
</mat-checkbox>
@ -88,4 +132,34 @@
La réponse « peut-être » sera disponible
</mat-checkbox>
</fieldset>
<fieldset>
<h2>
Fonctionnalités pas encore disponibles:
</h2>
<app-wip-todo></app-wip-todo>
<mat-checkbox class="is-not-flex" formControlName="isProtectedByPassword">
Spécifier un lien unique de vote à des participants définis
</mat-checkbox>
<mat-checkbox class="is-not-flex" formControlName="allowComments">
Autoriser les commentaires
</mat-checkbox>
<mat-checkbox class="is-not-flex" formControlName="hasMaxCountOfAnswers">
Nombre de réponses limitées à ce nombre
</mat-checkbox>
<input
*ngIf="form.value.hasMaxCountOfAnswers"
#limitCount
id="limitCount"
matInput
type="number"
placeholder="Nombre de réponses max"
formControlName="maxCountOfAnswers"
required
/>
<mat-checkbox class="is-not-flex" formControlName="isZeroKnoledge">
Les informations du sondage seront chiffrés en base de données
</mat-checkbox>
</fieldset>
</form>

View File

@ -64,50 +64,39 @@
</div>
<hr />
<!-- <div class="columns">-->
<!-- <div class="column">-->
<!-- <img src="assets/img/undraw_Moving_twwf.svg" alt="image WIP" />-->
<!-- <div>-->
<!-- <h2>-->
<!-- {{ 'choices.title' | translate }}-->
<!-- </h2>-->
<!-- {{ 'dates.add' | translate }}-->
<!-- <p>-->
<!-- <i>-->
<!-- {{ 'choices.helper' | translate }}-->
<!-- </i>-->
<!-- </p>-->
<!-- {{ 'choices.answer_preset_1' | translate }}-->
<!-- {{ 'choices.add' | translate }}-->
<!-- {{ 'choices.continue' | translate }}-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="column">-->
<!-- <button class="btn btn&#45;&#45;warning" (click)="askInitFormDefault()">-->
<!-- <i class="fa fa-refresh"></i>-->
<!-- Tout réinitialiser-->
<!-- </button>-->
<!-- <br />-->
<!-- <button class="btn is-success" (click)="createPoll()">-->
<!-- <i class="fa fa-save"></i>-->
<!-- Enregistrer le sondage-->
<!-- </button>-->
<!-- <br />-->
<!-- <button class="btn is-default" (click)="automaticSlug()">-->
<!-- <i class="fa fa-refresh"></i>-->
<!-- Slug automatique-->
<!-- </button>-->
<!-- <div class="columns">-->
<!-- <div class="column">-->
<!-- Slug:-->
<!-- </div>-->
<!-- <div class="column">-->
<!-- <div class="well">-->
<!-- {{ form.slug }}-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<div class="columns">
<div class="column">
<img src="assets/img/undraw_Moving_twwf.svg" alt="image WIP" />
<div>
<h2>
{{ 'choices.title' | translate }}
</h2>
{{ 'dates.add' | translate }}
<p>
<i>
{{ 'choices.helper' | translate }}
</i>
</p>
{{ 'choices.answer_preset_1' | translate }}
{{ 'choices.add' | translate }}
{{ 'choices.continue' | translate }}
</div>
</div>
</div>
<div class="column">
<button class="btn btn--warning" (click)="askInitFormDefault()">
<i class="fa fa-refresh"></i>
Tout réinitialiser
</button>
<br />
<button class="btn is-success" (click)="createPoll()">
<i class="fa fa-save"></i>
Enregistrer le sondage
</button>
<br />
<button class="btn is-default" (click)="automaticSlug()">
<i class="fa fa-refresh"></i>
Slug automatique
</button>
</div>
</form>

View File

@ -1,6 +1,6 @@
import { ChangeDetectorRef, Component, EventEmitter, Inject, Input, OnInit, Output } from '@angular/core';
import { ChangeDetectorRef, Component, Inject, Input, OnInit } from '@angular/core';
import { ToastService } from '../../../../core/services/toast.service';
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { FormBuilder, FormGroup } from '@angular/forms';
import { UuidService } from '../../../../core/services/uuid.service';
import { PollService } from '../../../../core/services/poll.service';
import { ApiService } from '../../../../core/services/api.service';
@ -13,7 +13,7 @@ import { Poll } from '../../../../core/models/poll.model';
templateUrl: './base-config.component.html',
styleUrls: ['./base-config.component.scss'],
})
export class BaseConfigComponent implements OnInit {
export class BaseConfigComponent {
@Input()
public poll?: Poll;
@Input()
@ -30,8 +30,6 @@ export class BaseConfigComponent implements OnInit {
@Inject(DOCUMENT) private document: Document
) {}
ngOnInit(): void {}
askInitFormDefault(): void {
// this.initFormDefault(false);
this.toastService.display('formulaire réinitialisé');
@ -43,19 +41,18 @@ export class BaseConfigComponent implements OnInit {
console.log('newpoll', newpoll);
const router = this.router;
this.apiService.createPoll(newpoll).then((resp) => {
console.log('resp', resp);
router.navigate(['success']);
});
// this.router
// if (this.form.valid) {
// console.log('Le sondage est correctement rempli, prêt à enregistrer.');
// const newpoll = this.pollService.newPollFromForm(this.form);
// // TODO : save the poll
// this.apiService.createPoll(newpoll);
// } else {
// this.toastService.display('invalid form');
// }
if (this.form.valid) {
console.log('Le sondage est correctement rempli, prêt à enregistrer.');
const newpoll = this.pollService.newPollFromForm(this.form);
// TODO : save the poll
this.apiService.createPoll(newpoll).then((resp) => {
console.log('resp', resp);
router.navigate(['success']);
});
} else {
this.toastService.display('invalid form');
}
}
public updateSlug(): void {
@ -67,10 +64,6 @@ export class BaseConfigComponent implements OnInit {
* set the poll slug from other data of the poll
*/
automaticSlug() {
this.form.patchValue({ slug: this.pollService.makeSlug(this.poll) });
}
formUpdate() {
this.formChange.emit(this.form);
this.form.patchValue({ slug: this.pollService.makeSlug(this.form.value) });
}
}

View File

@ -1,139 +1,145 @@
<div class="date-selection">
<!-- interval-->
<form [formGroup]="form">
<!-- interval-->
<section *ngIf="showDateInterval" class="date-interval form-row">
<button
(click)="showDateInterval = !showDateInterval"
[ngClass]="{ active: showDateInterval }"
class="btn btn--primary"
id="toggle_interval_button"
>
<i class="fa fa-clock-o" aria-hidden="true"></i>
{{ 'dates.add_interval' | translate }}
</button>
<h2>{{ 'dates.add_interval' | translate }}</h2>
<div class="columns">
<div class="column">
{{ 'dates.interval_propose' | translate }}
</div>
<div class="column">
<label for="start_interval" class="hidden">start</label>
<input id="start_interval" (change)="countDays()" formControlName="startDateInterval" type="date" />
</div>
</div>
<div class="columns">
<div class="column">
{{ 'dates.interval_span' | translate }}
</div>
<div class="column">
<label for="end_interval" class="hidden">end</label>
<input id="end_interval" formControlName="endDateInterval" type="date" />
</div>
</div>
<button (click)="addIntervalOfDates()" class="btn btn-block btn--primary">
<i class="fa fa-plus" aria-hidden="true"></i>
{{ 'dates.interval_button' | translate }}
{{ intervalDays }}
{{ 'dates.interval_button_dates' | translate }}
</button>
</section>
<!-- <section *ngIf="showDateInterval" class="date-interval form-row">-->
<!-- <button-->
<!-- (click)="showDateInterval = !showDateInterval"-->
<!-- [ngClass]="{ active: showDateInterval }"-->
<!-- class="btn btn&#45;&#45;primary"-->
<!-- id="toggle_interval_button"-->
<!-- >-->
<!-- <i class="fa fa-clock-o" aria-hidden="true"></i>-->
<!-- {{ 'dates.add_interval' | translate }}-->
<!-- </button>-->
<!-- <h2>{{ 'dates.add_interval' | translate }}</h2>-->
<!-- <div class="columns">-->
<!-- <div class="column">-->
<!-- {{ 'dates.interval_propose' | translate }}-->
<!-- </div>-->
<!-- <div class="column">-->
<!-- <label for="start_interval" class="hidden">start</label>-->
<!-- <input id="start_interval" (change)="countDays()" formControlName="startDateInterval" type="date" />-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="columns">-->
<!-- <div class="column">-->
<!-- {{ 'dates.interval_span' | translate }}-->
<!-- </div>-->
<!-- <div class="column">-->
<!-- <label for="end_interval" class="hidden">end</label>-->
<!-- <input id="end_interval" formControlName="endDateInterval" type="date" />-->
<!-- </div>-->
<!-- </div>-->
<!-- <button (click)="addIntervalOfDates()" class="btn btn-block btn&#45;&#45;primary">-->
<!-- <i class="fa fa-plus" aria-hidden="true"></i>-->
<!-- {{ 'dates.interval_button' | translate }}-->
<!-- {{ intervalDays }}-->
<!-- {{ 'dates.interval_button_dates' | translate }}-->
<!-- </button>-->
<!-- </section>-->
<div class="dates-list">
<div class="title">
<span class="count-dates">
{{ timeList.length }}
<div class="dates-list">
<div class="title">
<span class="count-dates">
{{ timeList.length }}
</span>
<span class="count-dates-txt">
{{ 'dates.count_time' | translate }}
(pour chaque jour)
</span>
</div>
<div class="actions">
<button
(click)="addTime()"
*ngIf="'false' === allowSeveralHours"
class="btn btn--primary"
id="add_time_button"
>
<i class="fa fa-plus" aria-hidden="true"></i>
{{ 'dates.add_time' | translate }}
</button>
<button
(click)="removeAllTimes()"
*ngIf="'false' === allowSeveralHours"
class="btn btn--warning"
id="remove_time_button"
>
<i class="fa fa-trash" aria-hidden="true"></i>
Aucune plage horaire
</button>
<button
(click)="resetTimes()"
*ngIf="'false' === allowSeveralHours"
class="btn btn--warning"
id="reset_time_button"
>
<i class="fa fa-refresh" aria-hidden="true"></i>
réinitialiser
</button>
</div>
<div *ngIf="'false' === allowSeveralHours" class="identical-dates">
<div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)">
<div *ngFor="let time of timeList; index as id" class="time-choice" cdkDrag>
<label for="timeChoices_{{ id }}">
<i class="fa fa-clock-o" aria-hidden="true"></i>
</label>
<input
[(ngModel)]="time.literal"
name="timeChoices_{{ id }}"
type="text"
id="timeChoices_{{ id }}"
/>
<button (click)="time.timeList.splice(id, 1)" class="btn btn-warning">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
<hr />
<span class="count-dates title">
{{ dateList.length }}
</span>
<span class="count-dates-txt">
{{ 'dates.count_time' | translate }}
(pour chaque jour)
<span>
{{ 'dates.count_dates' | translate }}
</span>
</div>
<div class="actions">
<button
(click)="addTime()"
*ngIf="'false' === allowSeveralHours"
class="btn btn--primary"
id="add_time_button"
>
<i class="fa fa-plus" aria-hidden="true"></i>
{{ 'dates.add_time' | translate }}
<button class="btn btn--primary" (click)="addChoice()">
{{ 'dates.add' | translate }}
</button>
<button
(click)="removeAllTimes()"
*ngIf="'false' === allowSeveralHours"
class="btn btn--warning"
id="remove_time_button"
>
<i class="fa fa-trash" aria-hidden="true"></i>
Aucune plage horaire
</button>
<button
(click)="resetTimes()"
*ngIf="'false' === allowSeveralHours"
class="btn btn--warning"
id="reset_time_button"
>
<i class="fa fa-refresh" aria-hidden="true"></i>
réinitialiser
</button>
</div>
<div *ngIf="'false' === allowSeveralHours" class="identical-dates">
<div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)">
<div *ngFor="let time of timeList; index as id" class="time-choice" cdkDrag>
<label for="timeChoices_{{ id }}">
<i class="fa fa-clock-o" aria-hidden="true"></i>
</label>
<input
[(ngModel)]="time.literal"
name="timeChoices_{{ id }}"
type="text"
id="timeChoices_{{ id }}"
/>
<button (click)="time.timeList.splice(id, 1)" class="btn btn-warning">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
<div *ngFor="let choice of dateList; index as id" class="date-choice">
{{ id }})
<input
[(ngModel)]="choice.date_object"
name="dateChoices_{{ id }}"
id="dateChoices_{{ id }}"
useValueAsDate
type="date"
/>
<button (click)="dateList.splice(id, 1)" class="btn btn-warning">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
<button
(click)="addTimeToDate(choice, id)"
*ngIf="'true' === allowSeveralHours"
class="btn btn--primary"
>
{{ 'dates.add_time' | translate }}
</button>
<div *ngIf="'true' === allowSeveralHours" class="several-times">
<div *ngFor="let timeItem of choice.timeList; index as idTime" class="time-choice">
<input
[(ngModel)]="timeItem.literal"
name="dateTime_{{ id }}_Choices_{{ idTime }}"
id="dateTime_{{ id }}_Choices_{{ idTime }}"
type="text"
/>
<button (click)="choice.timeList.splice(idTime, 1)" class="btn btn-warning">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
</div>
<hr />
<span class="count-dates title">
{{ dateList.length }}
</span>
<span>
{{ 'dates.count_dates' | translate }}
</span>
<button class="btn btn--primary" (click)="addChoice()">
{{ 'dates.add' | translate }}
</button>
<div *ngFor="let choice of dateList; index as id" class="date-choice">
{{ id }})
<input
[(ngModel)]="choice.date_object"
name="dateChoices_{{ id }}"
id="dateChoices_{{ id }}"
useValueAsDate
type="date"
/>
<button (click)="dateList.splice(id, 1)" class="btn btn-warning">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
<button (click)="addTimeToDate(choice, id)" *ngIf="'true' === allowSeveralHours" class="btn btn--primary">
{{ 'dates.add_time' | translate }}
</button>
<div *ngIf="'true' === allowSeveralHours" class="several-times">
<div *ngFor="let timeItem of choice.timeList; index as idTime" class="time-choice">
<input
[(ngModel)]="timeItem.literal"
name="dateTime_{{ id }}_Choices_{{ idTime }}"
id="dateTime_{{ id }}_Choices_{{ idTime }}"
type="text"
/>
<button (click)="choice.timeList.splice(idTime, 1)" class="btn btn-warning">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
</div>
</form>
</div>

View File

@ -9,6 +9,7 @@ import { Router } from '@angular/router';
import { DOCUMENT } from '@angular/common';
import { DateChoice, otherDefaultDates } from '../../../old-stuff/config/defaultConfigs';
import { Poll } from '../../../../core/models/poll.model';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
@Component({
selector: 'app-date-select',
@ -16,8 +17,6 @@ import { Poll } from '../../../../core/models/poll.model';
styleUrls: ['./date-select.component.scss'],
})
export class DateSelectComponent implements OnInit {
@Input()
public poll?: Poll;
@Input()
public form: FormGroup;
@ -163,7 +162,7 @@ export class DateSelectComponent implements OnInit {
imageUrl: 'mon url',
});
}
this.choices.push(newControlGroup);
this.form.value.choices.push(newControlGroup);
this.cd.detectChanges();
console.log('this.choices.length', this.choices.length);
@ -238,4 +237,8 @@ export class DateSelectComponent implements OnInit {
this.addChoice('raisin');
this.addChoice('abricot');
}
drop(event: CdkDragDrop<string[]>) {
moveItemInArray(this.form.value.choices, event.previousIndex, event.currentIndex);
}
}

View File

@ -8,26 +8,27 @@
<p class="subtitle">
{{ 'creation.want' | translate }}
</p>
<app-kind-select [(form)]="form"></app-kind-select>
<app-base-config [(form)]="form"></app-base-config>
<app-kind-select [form]="form"></app-kind-select>
<app-date-select ng-if="form.value.isAboutDate" [form]="form"></app-date-select>
<app-text-select ng-if="!form.value.isAboutDate" [form]="form"></app-text-select>
<app-base-config [form]="form"></app-base-config>
</div>
<div class="column">
<pre class="debug padded warning">
</div>
<div class="column">
<pre class="debug padded warning">
form values :
{{ form.value | json }}
</pre
>
<pre class="debug padded warning">
>
<pre class="debug padded warning">
poll initial values :
{{ poll | json }}
{{ poll | json }}
</pre
>
</div>
>
</div>
<!-- choix spécialement pour les dates-->
<!-- <app-date-select ng-if="form.kind == 'date'"></app-date-select>-->
<!-- <app-text-select ng-if="form.kind == 'classic'"></app-text-select>-->
<button class="btn is-info" (click)="advancedDisplayEnabled = !advancedDisplayEnabled">
<i class="fa fa-save"></i>
{{ 'creation.advanced' | translate }}

View File

@ -20,7 +20,7 @@ export class FormComponent implements OnInit {
public poll?: Poll;
public form: FormGroup;
public advancedDisplayEnabled = false;
public advancedDisplayEnabled = true;
constructor(
private fb: FormBuilder,
@ -34,10 +34,6 @@ export class FormComponent implements OnInit {
@Inject(DOCUMENT) private document: any
) {}
drop(event: CdkDragDrop<string[]>) {
// moveItemInArray(this.choices, event.previousIndex, event.currentIndex);
}
ngOnInit(): void {
this.initFormDefault();
@ -53,16 +49,21 @@ export class FormComponent implements OnInit {
slug: [this.uuidService.getUUID(), [Validators.required]],
description: ['', [Validators.required]],
choices: new FormArray([]),
// configuration: new FormGroup(),
whoModifiesAnswers: ['', [Validators.required]],
whoCanChangeAnswers: ['', [Validators.required]],
isAboutDate: [true, [Validators.required]],
startDateInterval: ['', [Validators.required]],
endDateInterval: ['', [Validators.required]],
isProtectedByPassword: [false, [Validators.required]],
hasMaxCountOfAnswers: [true, [Validators.required]],
allowComments: [true, [Validators.required]],
maxCountOfAnswers: [150, [Validators.required]],
isOwnerNotifiedByEmailOnNewVote: [false, [Validators.required]],
isOwnerNotifiedByEmailOnNewComment: [false, [Validators.required]],
isMaybeAnswerAvailable: [false, [Validators.required]],
areResultsPublic: [true, [Validators.required]],
password: [this.uuidService.getUUID(), [Validators.required]],
expiracyNumberOfDays: [60, [Validators.required, Validators.min(0)]],
});
console.log('this.form ', this.form);
@ -83,16 +84,16 @@ export class FormComponent implements OnInit {
creatorPseudo: 'Chuck Norris',
creatorEmail: 'chucknorris@example.com',
isAboutDate: true,
// configuration: {
// whoModifiesAnswers: 'everybody',
// whoCanChangeAnswers: 'everybody'
// isProtectedByPassword: false,
// isOwnerNotifiedByEmailOnNewVote: false,
// isOwnerNotifiedByEmailOnNewComment: false,
// isMaybeAnswerAvailable: false,
// areResultsPublic: true,
// expiracyNumberOfDays: 60,
// },
configuration: {
whoModifiesAnswers: 'everybody',
whoCanChangeAnswers: 'everybody',
isProtectedByPassword: false,
isOwnerNotifiedByEmailOnNewVote: false,
isOwnerNotifiedByEmailOnNewComment: false,
isMaybeAnswerAvailable: false,
areResultsPublic: true,
expiracyNumberOfDays: 60,
},
comments: [],
choices: [],
dateChoices: [],

View File

@ -1,4 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { Component, Input, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Component({
selector: 'app-text-select',
@ -6,6 +7,9 @@ import { Component, OnInit } from '@angular/core';
styleUrls: ['./text-select.component.scss'],
})
export class TextSelectComponent implements OnInit {
@Input()
public form: FormGroup;
constructor() {}
ngOnInit(): void {}