Commit 6b235830 authored by Romain DELEAU's avatar Romain DELEAU

create multiple optionnal tasks

parent 27450948
...@@ -40,6 +40,7 @@ import { TutorialService } from './services/tutorial/tutorial.service'; ...@@ -40,6 +40,7 @@ import { TutorialService } from './services/tutorial/tutorial.service';
import { VerifyGameFailSnackbarComponent } from './components/snackbars/verify-game-fail-snackbar/verify-game-fail-snackbar.component'; import { VerifyGameFailSnackbarComponent } from './components/snackbars/verify-game-fail-snackbar/verify-game-fail-snackbar.component';
import { VerifyDialogComponent } from './components/dialogs/verify-dialog/verify-dialog.component'; import { VerifyDialogComponent } from './components/dialogs/verify-dialog/verify-dialog.component';
import { LegalDialogComponent } from './components/dialogs/legal-dialog/legal-dialog.component'; import { LegalDialogComponent } from './components/dialogs/legal-dialog/legal-dialog.component';
import { CreateOptionnalTaskDialogComponent } from './components/dialogs/create-optionnal-task-dialog/create-optionnal-task-dialog.component';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
...@@ -388,7 +389,28 @@ export class AppComponent { ...@@ -388,7 +389,28 @@ export class AppComponent {
} }
addTask(mission: Mission, role: Role, missionIndex: number, roleIndex: number, i: number, j: number, type: string) { addTask(mission: Mission, role: Role, missionIndex: number, roleIndex: number, i: number, j: number, type: string) {
role.addTask(i, j, type); if (type == 'optionnal') {
let quantity: number;
let minquantity: number;
if (role.countOptionnalTasksInClolumn(role.getRealIndex(i,j)) > 1) {
minquantity = 1;
quantity = 1;
} else {
minquantity = 2;
quantity = 2;
}
const dialogRef = this.dialog.open(CreateOptionnalTaskDialogComponent, {
data: { minquantity: minquantity, quantity: quantity, result: false },
});
dialogRef.afterClosed().subscribe(result => {
quantity = (result as CreateOptionnalTaskDialogData).quantity;
if ((result as CreateOptionnalTaskDialogData).result == true) {
role.addOptionnalTask(i, j, type, quantity);
}
});
} else {
role.addTask(i, j, type);
}
switch(type) { switch(type) {
case 'normal': this.scenario.traces.push(new Trace(this.scenario.traces.length,'new',missionIndex,roleIndex,'all','Task_['+i+';'+j+']', '#B9DFE3')); break; case 'normal': this.scenario.traces.push(new Trace(this.scenario.traces.length,'new',missionIndex,roleIndex,'all','Task_['+i+';'+j+']', '#B9DFE3')); break;
case 'annexe': this.scenario.traces.push(new Trace(this.scenario.traces.length,'new',missionIndex,roleIndex,'all','Side_task_['+i+';'+j+']', '#BCCECC')); break; case 'annexe': this.scenario.traces.push(new Trace(this.scenario.traces.length,'new',missionIndex,roleIndex,'all','Side_task_['+i+';'+j+']', '#BCCECC')); break;
...@@ -488,4 +510,10 @@ export class AppComponent { ...@@ -488,4 +510,10 @@ export class AppComponent {
maxWidth: '50vw', maxWidth: '50vw',
}); });
} }
}
export interface CreateOptionnalTaskDialogData {
quantity: number;
minquantity: number;
result: boolean;
} }
\ No newline at end of file
...@@ -54,6 +54,8 @@ import { RoleNameDuplicateComponent } from './components/snackbars/role-name-dup ...@@ -54,6 +54,8 @@ import { RoleNameDuplicateComponent } from './components/snackbars/role-name-dup
import { CopyRoleSuccessComponent } from './components/snackbars/copy-role-success/copy-role-success.component'; import { CopyRoleSuccessComponent } from './components/snackbars/copy-role-success/copy-role-success.component';
import { LegalDialogComponent } from './components/dialogs/legal-dialog/legal-dialog.component'; import { LegalDialogComponent } from './components/dialogs/legal-dialog/legal-dialog.component';
import { RewardsComponent } from './sider-pieces/rewards/rewards.component'; import { RewardsComponent } from './sider-pieces/rewards/rewards.component';
import { MoveOptionnalTasksComponent } from './components/snackbars/move-optionnal-tasks/move-optionnal-tasks.component';
import { CreateOptionnalTaskDialogComponent } from './components/dialogs/create-optionnal-task-dialog/create-optionnal-task-dialog.component';
export function HttpLoaderFactory(http: HttpClient) { export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http); return new TranslateHttpLoader(http);
...@@ -99,7 +101,9 @@ export function HttpLoaderFactory(http: HttpClient) { ...@@ -99,7 +101,9 @@ export function HttpLoaderFactory(http: HttpClient) {
RoleNameDuplicateComponent, RoleNameDuplicateComponent,
CopyRoleSuccessComponent, CopyRoleSuccessComponent,
LegalDialogComponent, LegalDialogComponent,
RewardsComponent RewardsComponent,
MoveOptionnalTasksComponent,
CreateOptionnalTaskDialogComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,
......
...@@ -34,6 +34,34 @@ export class Role { ...@@ -34,6 +34,34 @@ export class Role {
} }
} }
public addOptionnalTask(i: number, j: number, type: string, quantity: number): void {
this.tasks[i][j] = new Task(type);
if (this.tasks[i + 1] == null) {
this.tasks[i + 1] = [];
}
if (quantity >= 1) {
this.tasks[i][j] = new Task(type);
if (this.tasks[i + 1] == null) {
this.tasks[i + 1] = [];
}
let visualStartJ: number = this.getRealIndex(i, j);
for (let k = 1; k < quantity; k++) {
let secondi: number = i + 1;
let realDestJ: number = this.getDestinationIndexFromRealIndex(visualStartJ, secondi);
let visualDestJ: number = this.getRealIndex(secondi, realDestJ);
while (this.tasks[secondi][realDestJ] instanceof Task || visualStartJ != visualDestJ) {
secondi++;
realDestJ = this.getDestinationIndexFromRealIndex(visualStartJ, secondi);
visualDestJ = this.getRealIndex(secondi, realDestJ);
}
this.tasks[secondi][this.getDestinationIndexFromRealIndex(this.getRealIndex(i, j), secondi)] = new Task(type);
if (this.tasks[secondi + 1] == null) {
this.tasks[secondi + 1] = [];
}
}
}
}
public addTask(i: number, j: number, type: string) { public addTask(i: number, j: number, type: string) {
this.tasks[i][j] = new Task(type); this.tasks[i][j] = new Task(type);
if (this.tasks[i + 1] == null) { if (this.tasks[i + 1] == null) {
...@@ -222,4 +250,20 @@ export class Role { ...@@ -222,4 +250,20 @@ export class Role {
} }
return res; return res;
} }
public countOptionnalTasksInClolumn(realColumn: number): number {
let cpt: number = 0;
this.tasks.forEach((inlineTasks, i) => {
let j: number = 0;
while (this.getRealIndex(i,j) < realColumn) {
j++;
}
if (inlineTasks[j]?.type == 'optionnal') {
cpt++;
}
});
return cpt;
}
} }
<h2 mat-dialog-title>{{'dialog_createOptTask_title' | translate}}</h2>
<mat-dialog-content>
<label for="quantity">{{'dialog_createOptTask_label' | translate}}</label>
<input name="quantity" type="number" [min]="data.minquantity" max="10" [(ngModel)]="data.quantity"/>
</mat-dialog-content>
<div mat-dialog-actions align="end">
<button mat-button mat-dialog-close>{{'dialog_button_cancel' | translate}}</button>
<button mat-button [mat-dialog-close]="data" (click)="data.result = true" cdkFocusInitial>{{'dialog_button_validate' | translate}}</button>
</div>
h2 {
font-family: 'Glacial Indifference Bold', sans-serif;
}
mat-dialog-content {
display: flex;
text-align: center;
label {
font-size: 17px;
margin-bottom: 5px;
margin-right: 5px;
}
input {
text-align: center;
border-radius: 5px;
height: 25px;
width: 25px;
}
}
button {
margin-top: 20px;
}
\ No newline at end of file
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CreateOptionnalTaskDialogComponent } from './create-optionnal-task-dialog.component';
describe('CreateOptionnalTaskDialogComponent', () => {
let component: CreateOptionnalTaskDialogComponent;
let fixture: ComponentFixture<CreateOptionnalTaskDialogComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ CreateOptionnalTaskDialogComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(CreateOptionnalTaskDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
export interface DialogData {
quantity: number;
minquantity: number;
result: boolean;
}
@Component({
selector: 'app-create-optionnal-task-dialog',
templateUrl: './create-optionnal-task-dialog.component.html',
styleUrls: ['./create-optionnal-task-dialog.component.scss']
})
export class CreateOptionnalTaskDialogComponent implements OnInit {
constructor(public dialogRef: MatDialogRef<CreateOptionnalTaskDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: DialogData) { }
ngOnInit(): void {
}
}
<span matSnackBarLabel>{{'snackbar_moveOptionnalTask' | translate}}</span>
::ng-deep .mat-snack-bar-container {
background-color: #ffa808;
color: white;
box-shadow: 0px 0px 15px 5px #ffa808;
text-align: center;
}
\ No newline at end of file
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MoveOptionnalTasksComponent } from './move-optionnal-tasks.component';
describe('MoveOptionnalTasksComponent', () => {
let component: MoveOptionnalTasksComponent;
let fixture: ComponentFixture<MoveOptionnalTasksComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ MoveOptionnalTasksComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(MoveOptionnalTasksComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-move-optionnal-tasks',
templateUrl: './move-optionnal-tasks.component.html',
styleUrls: ['./move-optionnal-tasks.component.scss']
})
export class MoveOptionnalTasksComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}
...@@ -16,6 +16,7 @@ import { IdentifierSnackbarComponent } from 'src/app/components/snackbars/identi ...@@ -16,6 +16,7 @@ import { IdentifierSnackbarComponent } from 'src/app/components/snackbars/identi
import { Trace } from 'src/app/class/trace/trace'; import { Trace } from 'src/app/class/trace/trace';
import { MinimapService } from 'src/app/services/minimap/minimap.service'; import { MinimapService } from 'src/app/services/minimap/minimap.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { MoveOptionnalTasksComponent } from 'src/app/components/snackbars/move-optionnal-tasks/move-optionnal-tasks.component';
@Component({ @Component({
selector: 'app-optionnal-task', selector: 'app-optionnal-task',
...@@ -218,6 +219,7 @@ export class OptionnalTaskComponent implements OnInit { ...@@ -218,6 +219,7 @@ export class OptionnalTaskComponent implements OnInit {
this.displayPrequires = 'hide'; this.displayPrequires = 'hide';
this.displaySymbolChoice = 'hide'; this.displaySymbolChoice = 'hide';
this.mission.equalizeLengths(); this.mission.equalizeLengths();
this._snackBar.openFromComponent(MoveOptionnalTasksComponent, { duration: 5000 });
} else if (direction == 'top' && this.canMoveTo('top')) { } else if (direction == 'top' && this.canMoveTo('top')) {
this.role.moveTask(this.i, this.j, direction); this.role.moveTask(this.i, this.j, direction);
this.displayMenu = 'hide'; this.displayMenu = 'hide';
...@@ -230,6 +232,7 @@ export class OptionnalTaskComponent implements OnInit { ...@@ -230,6 +232,7 @@ export class OptionnalTaskComponent implements OnInit {
this.displayPrequires = 'hide'; this.displayPrequires = 'hide';
this.displaySymbolChoice = 'hide'; this.displaySymbolChoice = 'hide';
this.mission.equalizeLengths(); this.mission.equalizeLengths();
this._snackBar.openFromComponent(MoveOptionnalTasksComponent, { duration: 5000 });
} else if (direction == 'bottom') { } else if (direction == 'bottom') {
this.role.moveTask(this.i, this.j, direction); this.role.moveTask(this.i, this.j, direction);
this.displayMenu = 'hide'; this.displayMenu = 'hide';
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
"snackbar_loading_fail": "File upload failed.", "snackbar_loading_fail": "File upload failed.",
"snackbar_loading_success": "File upload successful.", "snackbar_loading_success": "File upload successful.",
"snackbar_roleName": "Attention, this title is already used in this Mission", "snackbar_roleName": "Attention, this title is already used in this Mission",
"snackbar_moveOptionnalTask": "Make sure to keep alternative tasks grouped in the same column",
"siderTitle_game": "Game", "siderTitle_game": "Game",
"siderTitle_mission": "Mission", "siderTitle_mission": "Mission",
...@@ -52,10 +53,13 @@ ...@@ -52,10 +53,13 @@
"dialog_save_title": "Download the scenario", "dialog_save_title": "Download the scenario",
"dialog_save_content": "Project name :", "dialog_save_content": "Project name :",
"dialog_save_placeholder": "My Scenario", "dialog_save_placeholder": "My Scenario",
"dialog_createOptTask_title": "Creation of Alternative Task(s)",
"dialog_createOptTask_label": "Quantity of Alternative Tasks to create in the column:",
"dialog_button_yes": "Yes", "dialog_button_yes": "Yes",
"dialog_button_no": "No", "dialog_button_no": "No",
"dialog_button_save": "Download", "dialog_button_save": "Download",
"dialog_button_cancel": "Cancel", "dialog_button_cancel": "Cancel",
"dialog_button_validate": "Validate",
"game_tooltip": "The game includes one or more Missions. Each Mission comprises at least 2 Roles. The Roles can be different within the various Missions of the game.", "game_tooltip": "The game includes one or more Missions. Each Mission comprises at least 2 Roles. The Roles can be different within the various Missions of the game.",
"gameEducationnalObjective_title": "Educationnal objective", "gameEducationnalObjective_title": "Educationnal objective",
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
"snackbar_loading_fail": "Chargement du fichier échoué", "snackbar_loading_fail": "Chargement du fichier échoué",
"snackbar_loading_success": "Chargement du fichier réussi", "snackbar_loading_success": "Chargement du fichier réussi",
"snackbar_roleName": "Attention, cet intitulé est déjà utilisé dans cette Mission", "snackbar_roleName": "Attention, cet intitulé est déjà utilisé dans cette Mission",
"snackbar_moveOptionnalTask": "Veillez à garder les tâches alternatives groupées dans la même colonne",
"siderTitle_game": "Jeu", "siderTitle_game": "Jeu",
"siderTitle_mission": "Mission", "siderTitle_mission": "Mission",
...@@ -52,10 +53,13 @@ ...@@ -52,10 +53,13 @@
"dialog_save_title": "Télécharger le scénario", "dialog_save_title": "Télécharger le scénario",
"dialog_save_content": "Nom du projet :", "dialog_save_content": "Nom du projet :",
"dialog_save_placeholder": "Mon Scénario", "dialog_save_placeholder": "Mon Scénario",
"dialog_createOptTask_title": "Création de Tâche(s) Alternative(s)",
"dialog_createOptTask_label": "Quantié de Tâches Alternatives à créer dans la colonne :",
"dialog_button_yes": "Oui", "dialog_button_yes": "Oui",
"dialog_button_no": "Non", "dialog_button_no": "Non",
"dialog_button_save": "Télécharger", "dialog_button_save": "Télécharger",
"dialog_button_cancel": "Annuler", "dialog_button_cancel": "Annuler",
"dialog_button_validate": "Valider",
"game_tooltip": "Le jeu comprend une ou plusieurs Missions. Chaque mission comprend au moins 2 Rôles. Les Rôles peuvent être différents au sein des différentes Missions du jeu.", "game_tooltip": "Le jeu comprend une ou plusieurs Missions. Chaque mission comprend au moins 2 Rôles. Les Rôles peuvent être différents au sein des différentes Missions du jeu.",
"gameEducationnalObjective_title": "Objectif(s) pédagogique", "gameEducationnalObjective_title": "Objectif(s) pédagogique",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment