Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
[![GitHub last commit](https://img.shields.io/github/last-commit/softwaremagico/KendoTournamentManager)](https://github.com/softwaremagico/KendoTournamentManager)
[![Issues](https://img.shields.io/github/issues/softwaremagico/KendoTournamentManager.svg)](https://github.com/softwaremagico/KendoTournamentManager/issues)
[![CircleCI](https://circleci.com/gh/softwaremagico/KendoTournamentManager.svg?style=shield)](https://circleci.com/gh/softwaremagico/KendoTournamentManager)
[![Time](https://img.shields.io/badge/development-716h-blueviolet.svg)]()
[![Time](https://img.shields.io/badge/development-717.5h-blueviolet.svg)]()

[![Powered by](https://img.shields.io/badge/powered%20by%20java-orange.svg?logo=OpenJDK&logoColor=white)]()
[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=kendo-tournament-backend&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=kendo-tournament-backend)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,4 +336,17 @@ public long delete(TournamentDTO tournamentDTO) {
return getProvider().delete(tournamentConverter.reverse(tournamentDTO));
}

public void refreshGroupContent(Integer tournamentId, Integer level) {
final List<Group> tournamentGroups = getProvider().getGroups(tournamentProvider.get(tournamentId).orElseThrow(()
-> new TournamentNotFoundException(this.getClass(), "No tournament found with id '" + tournamentId + "'.")));

//Remove teams assignation.
for (Group group : tournamentGroups) {
if (group.getLevel() >= level && (group.getFights() == null || group.getFights().isEmpty())) {
group.getTeams().clear();
getProvider().save(group);
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,8 @@ private void populateLevel(Tournament tournament, int level) throws LevelNotFini
for (GroupLink link : levelLinks) {
final List<ScoreOfTeam> teamsRanking = rankingProvider.getTeamsScoreRanking(link.getSource());
checkDrawScore(link.getSource(), teamsRanking, link.getWinner());
if (link.getWinner() != null && teamsRanking.get(link.getWinner()) != null && teamsRanking.get(link.getWinner()).getTeam() != null) {
if (link.getWinner() != null && teamsRanking.get(link.getWinner()) != null && teamsRanking.get(link.getWinner()).getTeam() != null
&& !link.getDestination().getTeams().contains(teamsRanking.get(link.getWinner()).getTeam())) {
link.getDestination().getTeams().add(teamsRanking.get(link.getWinner()).getTeam());
} else {
KendoTournamentLogger.warning(this.getClass(), "Missing data for level '{}' population with winner '{}' using ranking:\n\t{}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,16 @@ public byte[] getAllFromTournamentAsPdf(@Parameter(description = "Id of an exist
throw new BadRequestException(this.getClass(), e.getMessage());
}
}


@PreAuthorize("hasAnyAuthority(@securityService.viewerPrivilege, @securityService.editorPrivilege, @securityService.adminPrivilege)")
@Operation(summary = "Recalculate teams and fights from a group that has not started.", security = @SecurityRequirement(name = "bearerAuth"))
@PatchMapping(value = "/refresh/tournaments/{tournamentId}/levels/{level}", produces = {MediaType.APPLICATION_PDF_VALUE, MediaType.APPLICATION_JSON_VALUE})
public void refreshNonStartedGroups(@Parameter(description = "Id of an existing tournament", required = true) @PathVariable("tournamentId")
Integer tournamentId,
@Parameter(description = "Group level to starting the checks.", required = false) @PathVariable("level")
Integer level,
HttpServletResponse response, HttpServletRequest request) {
getController().refreshGroupContent(tournamentId, level == null ? 0 : level);
}
}
13 changes: 13 additions & 0 deletions frontend/src/app/services/group.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,17 @@ export class GroupService {
});
}

refreshNonStartedGroups(tournamentId: number, level:number): Observable<void> {
const url: string = `${this.baseUrl}/refresh/tournaments/${tournamentId}/levels/${level}`;
return this.http.patch<void>(url, null)
.pipe(
tap({
next: () => this.loggerService.info(`Refreshing groups from tournament ${tournamentId}`),
error: () => this.systemOverloadService.isBusy.next(false),
complete: () => this.systemOverloadService.isBusy.next(false),
}),
catchError(this.messageService.handleError<void>(`Refreshing groups from tournament ${tournamentId}`))
);
}

}
1 change: 1 addition & 0 deletions frontend/src/app/services/rbac/rbac.activity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export enum RbacActivity {
EDIT_GROUP = 'EDIT_GROUP',
DELETE_GROUP = 'DELETE_GROUP',
SELECT_GROUP = 'SELECT_GROUP',
REFRESH_GROUPS = 'REFRESH_GROUPS',
CLEAN_UP_GROUPS = 'CLEAN_UP_GROUPS',
DOWNLOAD_GROUPS_PDF = 'DOWNLOAD_GROUPS_PDF',

Expand Down
3 changes: 2 additions & 1 deletion frontend/src/app/views/fight-list/fight-list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@ export class FightListComponent extends RbacBasedComponent implements OnInit, On
this.groupService.update(this.selectedGroup).subscribe((): void => {
this.messageService.infoMessage("fightDeleted");
this.refreshFights();
this.selectFirstUnfinishedDuel();
});
}
}
Expand Down Expand Up @@ -873,7 +874,7 @@ export class FightListComponent extends RbacBasedComponent implements OnInit, On
}
for (const duel of fight.duels) {
if (!duel.finished) {
this.selectedFight = fight;
this.selectFight(fight);
this.selectDuel(duel);
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,16 @@
matTooltip="{{'delete' | translate}}">
<mat-icon>clear</mat-icon>
</button>
<button (click)="refreshGroups()" *ngIf="(RbacActivity.REFRESH_GROUPS | rbac : this.rbacService.getActivities())"
[disabled]="(tournament && tournament.locked) || updatingGroup || groups.length < 1"
[matTooltipShowDelay]="500"
color="primary" mat-button
class="refresh-group"
matTooltip="{{'refreshStructure' | translate}}">
<mat-icon>settings_backup_restore</mat-icon>
</button>
<mat-divider [vertical]="true"
*ngIf="(numberOfWinners == 2) && (RbacActivity.CREATE_FIGHT | rbac : this.rbacService.getActivities())"
*ngIf="(RbacActivity.CREATE_FIGHT | rbac : this.rbacService.getActivities())"
></mat-divider>
<button (click)="openConfirmationGenerateElementsDialog()"
*ngIf="isWizardEnabled && (RbacActivity.CREATE_FIGHT | rbac : this.rbacService.getActivities())"
Expand All @@ -53,12 +61,14 @@
<mat-icon>auto_fix_high</mat-icon>
</button>
<mat-divider [vertical]="true"
*ngIf="(numberOfWinners == 2) && (RbacActivity.DOWNLOAD_GROUPS_PDF | rbac : this.rbacService.getActivities())"
class="download-divider"
*ngIf="(RbacActivity.DOWNLOAD_GROUPS_PDF | rbac : this.rbacService.getActivities())"
></mat-divider>
<button (click)="downloadPDF()"
*ngIf="isWizardEnabled && (RbacActivity.DOWNLOAD_GROUPS_PDF | rbac : this.rbacService.getActivities())"
[matTooltipShowDelay]="500"
color="primary" mat-button
class="download"
matTooltip="{{'download' | translate}}">
<mat-icon>file_download</mat-icon>
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,18 @@
height: 75vh;
}
}

@media screen and (max-width: 800px) {
.refresh-group {
display: none !important;
}

.download-divider {
display: none !important;
}

.download {
display: none !important;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,10 @@ export class TournamentGeneratorComponent extends RbacBasedComponent implements
this.messageService.infoMessage('infoTournamentUpdated');
});
}

refreshGroups() {
this.groupService.refreshNonStartedGroups(this.tournamentId, 1).subscribe((): void => {
this.tournamentBracketsEditorComponent.updateData(true, true);
});
}
}
3 changes: 2 additions & 1 deletion frontend/src/assets/i18n/ca.json
Original file line number Diff line number Diff line change
Expand Up @@ -745,5 +745,6 @@
"darkMode": "Mode Fosc",
"lightMode": "Mode Clar",
"newVersionAvailable": "La versió '{{newVersion}}' està disponible! La versió actual és '{{currentVersion}}'.",
"input_data_is_invalid": "Les dades proporcionades no són vàlides!"
"input_data_is_invalid": "Les dades proporcionades no són vàlides!",
"refreshStructure": "Corrige la estructura de los grupos que no tienen ningún combate asignado."
}
3 changes: 2 additions & 1 deletion frontend/src/assets/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -723,5 +723,6 @@
"darkMode": "Donkere Modus",
"lightMode": "Lichte Modus",
"newVersionAvailable": "Version '{{newVersion}}' ist verfügbar! Aktuelle Version ist '{{currentVersion}}'.",
"input_data_is_invalid": "Die angegebenen Daten sind ungültig!"
"input_data_is_invalid": "Die angegebenen Daten sind ungültig!",
"refreshStructure": "Korrigieren Sie die Struktur der Gruppen, denen keine Kampfeinsätze zugewiesen sind."
}
3 changes: 2 additions & 1 deletion frontend/src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -740,5 +740,6 @@
"darkMode": "Dark Mode",
"lightMode": "Light Mode",
"newVersionAvailable": "Version '{{newVersion}}' is available! Current version is '{{currentVersion}}'",
"input_data_is_invalid": "Provided data are invalid!"
"input_data_is_invalid": "Provided data are invalid!",
"refreshStructure": "Correct the structure of groups that do not have any assigned fight."
}
3 changes: 2 additions & 1 deletion frontend/src/assets/i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -741,5 +741,6 @@
"darkMode": "Modo Oscuro",
"lightMode": "Modo Claro",
"newVersionAvailable": "¡La versión '{{newVersion}}' está disponible! La versión actual es '{{currentVersion}}'.",
"input_data_is_invalid": "¡Los datos proporcionados no son válidos!"
"input_data_is_invalid": "¡Los datos proporcionados no son válidos!",
"refreshStructure": "Corrige la estructura de los grupos que no tienen ningún combate asignado."
}
3 changes: 2 additions & 1 deletion frontend/src/assets/i18n/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -729,5 +729,6 @@
"darkMode": "Modalità Scura",
"lightMode": "Modalità Chiara",
"newVersionAvailable": "La versione '{{newVersion}}' è disponibile! La versione attuale è '{{currentVersion}}'.",
"input_data_is_invalid": "I dati forniti non sono validi!"
"input_data_is_invalid": "I dati forniti non sono validi!",
"refreshStructure": "Correggere la struttura dei gruppi a cui non è assegnato alcun combattimento."
}
3 changes: 2 additions & 1 deletion frontend/src/assets/i18n/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -723,5 +723,6 @@
"darkMode": "Dunkler Modus",
"lightMode": "Heller Modus",
"newVersionAvailable": "Versie '{{newVersion}}' is beschikbaar! Huidige versie is '{{currentVersion}}'.",
"input_data_is_invalid": "De opgegeven gegevens zijn ongeldig!"
"input_data_is_invalid": "De opgegeven gegevens zijn ongeldig!",
"refreshStructure": "Verbeter de structuur van groepen waaraan geen gevechtstaken zijn toegewezen."
}
Loading