multistore
Razmig Sarkissian 2 years ago
parent 0540943b26
commit 0b098b5b3b
  1. 2
      PadelClub/Data/Match.swift
  2. 13
      PadelClub/Data/MatchScheduler.swift
  3. 5
      PadelClub/Data/Tournament.swift
  4. 19
      PadelClub/Views/Club/CourtView.swift
  5. 2
      PadelClub/Views/GroupStage/Shared/GroupStageTeamReplacementView.swift
  6. 41
      PadelClub/Views/Planning/CourtAvailabilitySettingsView.swift
  7. 4
      PadelClub/Views/Planning/PlanningSettingsView.swift

@ -269,7 +269,7 @@ class Match: ModelObject, Storable {
} }
func roundTitle() -> String? { func roundTitle() -> String? {
if groupStage != nil { return "Poule" } if groupStage != nil { return groupStageObject?.groupStageTitle() }
else if let roundObject { return roundObject.roundTitle() } else if let roundObject { return roundObject.roundTitle() }
else { return nil } else { return nil }
} }

@ -111,7 +111,7 @@ class MatchScheduler : ModelObject, Storable {
return lastDate return lastDate
} }
func groupStageDispatcher(numberOfCourtsAvailablePerRotation: Int, groupStages: [GroupStage], startingDate: Date?) -> GroupStageMatchDispatcher { func groupStageDispatcher(numberOfCourtsAvailablePerRotation: Int, groupStages: [GroupStage], startingDate: Date) -> GroupStageMatchDispatcher {
let _groupStages = groupStages let _groupStages = groupStages
@ -156,7 +156,16 @@ class MatchScheduler : ModelObject, Storable {
(0..<numberOfCourtsAvailablePerRotation).forEach { courtIndex in (0..<numberOfCourtsAvailablePerRotation).forEach { courtIndex in
//print(mt.map { ($0.bracket!.index.intValue, counts[$0.bracket!.index.intValue]) }) //print(mt.map { ($0.bracket!.index.intValue, counts[$0.bracket!.index.intValue]) })
if let first = rotationMatches.first(where: { match in if let first = rotationMatches.first(where: { match in
teamsPerRotation[rotationIndex]!.allSatisfy({ match.containsTeamId($0) == false }) == true let estimatedDuration = match.matchFormat.getEstimatedDuration(additionalEstimationDuration)
let timeIntervalToAdd = (Double(rotationIndex)) * Double(estimatedDuration) * 60
let rotationStartDate: Date = startingDate.addingTimeInterval(timeIntervalToAdd)
let courtsUnavailable = courtsUnavailable(startDate: rotationStartDate, duration: match.matchFormat.getEstimatedDuration(additionalEstimationDuration))
if courtIndex >= numberOfCourtsAvailablePerRotation - courtsUnavailable {
return false
} else {
return teamsPerRotation[rotationIndex]!.allSatisfy({ match.containsTeamId($0) == false }) == true
}
}) { }) {
let timeMatch = GroupStageTimeMatch(matchID: first.id, rotationIndex: rotationIndex, courtIndex: courtIndex, groupIndex: first.groupStageObject!.index) let timeMatch = GroupStageTimeMatch(matchID: first.id, rotationIndex: rotationIndex, courtIndex: courtIndex, groupIndex: first.groupStageObject!.index)
slots.append(timeMatch) slots.append(timeMatch)

@ -363,8 +363,9 @@ class Tournament : ModelObject, Storable {
} }
func seeds() -> [TeamRegistration] { func seeds() -> [TeamRegistration] {
let seeds = max(teamCount - groupStageCount * teamsPerGroupStage, 0) let selectedSortedTeams = selectedSortedTeams()
return Array(selectedSortedTeams().prefix(seeds)) let seeds = max(selectedSortedTeams.count - groupStageCount * teamsPerGroupStage, 0)
return Array(selectedSortedTeams.prefix(seeds))
} }
func availableSeeds() -> [TeamRegistration] { func availableSeeds() -> [TeamRegistration] {

@ -25,9 +25,24 @@ struct CourtView: View {
.keyboardType(.alphabet) .keyboardType(.alphabet)
.multilineTextAlignment(.trailing) .multilineTextAlignment(.trailing)
.frame(maxWidth: .infinity) .frame(maxWidth: .infinity)
.onSubmit {
court.name = name
if name.isEmpty {
court.name = nil
}
try? dataStore.courts.addOrUpdate(instance: court)
}
} label: { } label: {
Text("Nom du terrain") Text("Nom du terrain")
} }
} footer: {
if court.name?.isEmpty == false {
FooterButtonView("nom par défaut") {
name = ""
court.name = nil
try? dataStore.courts.addOrUpdate(instance: court)
}
}
} }
Section { Section {
@ -39,10 +54,6 @@ struct CourtView: View {
} }
} }
} }
.onChange(of: name) {
court.name = name
try? dataStore.courts.addOrUpdate(instance: court)
}
.onChange(of: [court.indoor, court.exitAllowed]) { .onChange(of: [court.indoor, court.exitAllowed]) {
try? dataStore.courts.addOrUpdate(instance: court) try? dataStore.courts.addOrUpdate(instance: court)
} }

@ -72,6 +72,8 @@ struct GroupStageTeamReplacementView: View {
} }
.labelsHidden() .labelsHidden()
.pickerStyle(.inline) .pickerStyle(.inline)
} header: {
Text("Remplacer")
} footer: { } footer: {
Text("Remplacement de l'équipe ou d'un joueur particulier") Text("Remplacement de l'équipe ou d'un joueur particulier")
} }

@ -33,24 +33,7 @@ struct CourtAvailabilitySettingsView: View {
if let dates = courtsUnavailability[key] { if let dates = courtsUnavailability[key] {
Section { Section {
ForEach(dates) { dateInterval in ForEach(dates) { dateInterval in
HStack { Menu {
VStack(alignment: .leading, spacing: 0) {
Text(dateInterval.startDate.localizedTime()).font(.largeTitle)
Text(dateInterval.startDate.localizedDay()).font(.caption)
}
Spacer()
VStack {
Image(systemName: "arrowshape.forward.fill")
.tint(.master)
Text("indisponible").foregroundStyle(.red).font(.caption)
}
Spacer()
VStack(alignment: .trailing, spacing: 0) {
Text(dateInterval.endDate.localizedTime()).font(.largeTitle)
Text(dateInterval.endDate.localizedDay()).font(.caption)
}
}
.contextMenu(menuItems: {
Button("dupliquer") { Button("dupliquer") {
let duplicatedDateInterval = DateInterval(event: event.id, courtIndex: (courtIndex+1)%tournament.courtCount, startDate: dateInterval.startDate, endDate: dateInterval.endDate) let duplicatedDateInterval = DateInterval(event: event.id, courtIndex: (courtIndex+1)%tournament.courtCount, startDate: dateInterval.startDate, endDate: dateInterval.endDate)
try? dataStore.dateIntervals.addOrUpdate(instance: duplicatedDateInterval) try? dataStore.dateIntervals.addOrUpdate(instance: duplicatedDateInterval)
@ -65,7 +48,25 @@ struct CourtAvailabilitySettingsView: View {
Button("effacer", role: .destructive) { Button("effacer", role: .destructive) {
try? dataStore.dateIntervals.delete(instance: dateInterval) try? dataStore.dateIntervals.delete(instance: dateInterval)
} }
}) } label: {
HStack {
VStack(alignment: .leading, spacing: 0) {
Text(dateInterval.startDate.localizedTime()).font(.largeTitle)
Text(dateInterval.startDate.localizedDay()).font(.caption)
}
Spacer()
VStack {
Image(systemName: "arrowshape.forward.fill")
.tint(.master)
Text("indisponible").foregroundStyle(.red).font(.caption)
}
Spacer()
VStack(alignment: .trailing, spacing: 0) {
Text(dateInterval.endDate.localizedTime()).font(.largeTitle)
Text(dateInterval.endDate.localizedDay()).font(.caption)
}
}
}
.swipeActions { .swipeActions {
Button(role: .destructive) { Button(role: .destructive) {
try? dataStore.dateIntervals.delete(instance: dateInterval) try? dataStore.dateIntervals.delete(instance: dateInterval)
@ -95,6 +96,8 @@ struct CourtAvailabilitySettingsView: View {
Text("Vous pouvez précisez l'indisponibilité d'une ou plusieurs terrains, que ce soit pour une journée entière ou un créneau précis.") Text("Vous pouvez précisez l'indisponibilité d'une ou plusieurs terrains, que ce soit pour une journée entière ou un créneau précis.")
} actions: { } actions: {
RowButtonView("Ajouter une indisponibilité", systemImage: "plus.circle.fill") { RowButtonView("Ajouter une indisponibilité", systemImage: "plus.circle.fill") {
startDate = tournament.startDate
endDate = tournament.startDate.addingTimeInterval(5400)
showingPopover = true showingPopover = true
} }
} }

@ -42,15 +42,13 @@ struct PlanningSettingsView: View {
} }
} header: { } header: {
Text("Démarrage et durée du tournoi") Text("Démarrage et durée du tournoi")
} footer: {
Text("todo: Expliquer ce que ca fait")
} }
Section { Section {
TournamentFieldsManagerView(localizedStringKey: "Terrains maximum", count: $tournament.courtCount) TournamentFieldsManagerView(localizedStringKey: "Terrains maximum", count: $tournament.courtCount)
if tournament.groupStages().isEmpty == false { if tournament.groupStages().isEmpty == false {
TournamentFieldsManagerView(localizedStringKey: "Terrains par poule", count: $groupStageCourtCount, max: tournament.maximumCourtsPerGroupSage()) TournamentFieldsManagerView(localizedStringKey: "Nombre de poule en même temps", count: $groupStageCourtCount, max: tournament.groupStageCount)
} }
if let event = tournament.eventObject() { if let event = tournament.eventObject() {

Loading…
Cancel
Save