Improve formatting for Event Create
This commit is contained in:
@@ -85,6 +85,7 @@ public class TeamScheduler
|
||||
model.Add(x[ts.Item1, s] != x[ts.Item2, s]);
|
||||
|
||||
var solver = new CpSolver();
|
||||
solver.StringParameters = "max_time_in_seconds:2.0";
|
||||
|
||||
var cpSolverStatus = solver.Solve(model);
|
||||
Debug.WriteLine($"Solver status: {cpSolverStatus}");
|
||||
|
||||
@@ -29,4 +29,16 @@ public class TeamSchedulerSolution(
|
||||
where gs.Key.Count() > 1
|
||||
select Tuple.Create(gs.First(), gs.Key);
|
||||
}
|
||||
|
||||
|
||||
public static Student[] GetStudentsNotInTimSlot(Team[] timeSlot, Student[] students)
|
||||
{
|
||||
var studentsInTimeSlot = timeSlot.SelectMany(ts => ts.Students).Distinct();
|
||||
return
|
||||
(from allStudent in students
|
||||
where studentsInTimeSlot.FirstOrDefault(e => e.Equals(allStudent)) == null
|
||||
select allStudent
|
||||
).ToArray();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,19 @@ namespace Core.Entities;
|
||||
public class EventDefinition
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(100, MinimumLength = 2)]
|
||||
[Display(Name = "Event Name")]
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(40, MinimumLength = 2)]
|
||||
[Display(Name = "Event Short Name")]
|
||||
public string? ShortName { get; set; }
|
||||
|
||||
[Required]
|
||||
public EventFormat EventFormat { get; set; }
|
||||
|
||||
[Range(1, 6)]
|
||||
@@ -55,6 +66,7 @@ public class EventDefinition
|
||||
|
||||
public string? Documentation { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Eligibility { get; set; }
|
||||
public string? Theme { get; set; }
|
||||
public string? Description { get; set; }
|
||||
|
||||
@@ -1,134 +1,63 @@
|
||||
@page "/events/create"
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using Core.Entities
|
||||
@using Data
|
||||
@inject AppDbContext context
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<PageTitle>Create</PageTitle>
|
||||
<PageTitle>Create Event - TSA Chapter Organizer</PageTitle>
|
||||
|
||||
<h1>Create</h1>
|
||||
<MudText Typo="Typo.h3">Create</MudText>
|
||||
<MudText Typo="Typo.h4">Event</MudText>
|
||||
<MudDivider />
|
||||
|
||||
<h2>EventDefinition</h2>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<EditForm method="post" Model="EventDefinition" OnValidSubmit="AddEventDefinition" FormName="create" Enhance>
|
||||
|
||||
<EditForm Model="EventDefinition" OnValidSubmit="OnValidSubmit" Enhance>
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary class="text-danger" role="alert"/>
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Name:</label>
|
||||
<InputText id="name" @bind-Value="EventDefinition.Name" class="form-control" />
|
||||
<ValidationMessage For="() => EventDefinition.Name" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="shortname" class="form-label">ShortName:</label>
|
||||
<InputText id="shortname" @bind-Value="EventDefinition.ShortName" class="form-control" />
|
||||
<ValidationMessage For="() => EventDefinition.ShortName" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="eventformat" class="form-label">EventFormat:</label>
|
||||
<InputSelect @bind-Value="@EventDefinition.EventFormat">
|
||||
@foreach (var format in Enum.GetValues(typeof(EventFormat)))
|
||||
{
|
||||
<option value="@format">@(@format.ToString())</option>
|
||||
}
|
||||
</InputSelect>
|
||||
<ValidationMessage For="() => EventDefinition.EventFormat" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="minteamsize" class="form-label">MinTeamSize:</label>
|
||||
<InputNumber id="minteamsize" @bind-Value="EventDefinition.MinTeamSize" class="form-control" />
|
||||
<ValidationMessage For="() => EventDefinition.MinTeamSize" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="maxteamsize" class="form-label">MaxTeamSize:</label>
|
||||
<InputNumber id="maxteamsize" @bind-Value="EventDefinition.MaxTeamSize" class="form-control" />
|
||||
<ValidationMessage For="() => EventDefinition.MaxTeamSize" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="semifinalistactivity" class="form-label">SemifinalistActivity:</label>
|
||||
<InputText id="semifinalistactivity" @bind-Value="EventDefinition.SemifinalistActivity" class="form-control" />
|
||||
<ValidationMessage For="() => EventDefinition.SemifinalistActivity" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="notes" class="form-label">Notes:</label>
|
||||
<InputText id="notes" @bind-Value="EventDefinition.Notes" class="form-control" />
|
||||
<ValidationMessage For="() => EventDefinition.Notes" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="maxteamcountstate" class="form-label">MaxTeamCountState:</label>
|
||||
<InputNumber id="maxteamcountstate" @bind-Value="EventDefinition.MaxTeamCountState" class="form-control" />
|
||||
<ValidationMessage For="() => EventDefinition.MaxTeamCountState" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="regionalevent" class="form-label">RegionalEvent:</label>
|
||||
<InputCheckbox id="regionalevent" @bind-Value="EventDefinition.RegionalEvent" class="form-check-input" />
|
||||
<ValidationMessage For="() => EventDefinition.RegionalEvent" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="regionalpresubmit" class="form-label">RegionalPresubmit:</label>
|
||||
<InputCheckbox id="regionalpresubmit" @bind-Value="EventDefinition.RegionalPresubmit" class="form-check-input" />
|
||||
<ValidationMessage For="() => EventDefinition.RegionalPresubmit" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="statepresubmission" class="form-label">StatePresubmission:</label>
|
||||
<InputCheckbox id="statepresubmission" @bind-Value="EventDefinition.StatePresubmission" class="form-check-input" />
|
||||
<ValidationMessage For="() => EventDefinition.StatePresubmission" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="statepretesting" class="form-label">StatePretesting:</label>
|
||||
<InputCheckbox id="statepretesting" @bind-Value="EventDefinition.StatePretesting" class="form-check-input" />
|
||||
<ValidationMessage For="() => EventDefinition.StatePretesting" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="statepreliminaryround" class="form-label">StatePreliminaryRound:</label>
|
||||
<InputCheckbox id="statepreliminaryround" @bind-Value="EventDefinition.StatePreliminaryRound" class="form-check-input" />
|
||||
<ValidationMessage For="() => EventDefinition.StatePreliminaryRound" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="documentation" class="form-label">Documentation:</label>
|
||||
<InputText id="documentation" @bind-Value="EventDefinition.Documentation" class="form-control" />
|
||||
<ValidationMessage For="() => EventDefinition.Documentation" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="eligibility" class="form-label">Eligibility:</label>
|
||||
<InputText id="eligibility" @bind-Value="EventDefinition.Eligibility" class="form-control" />
|
||||
<ValidationMessage For="() => EventDefinition.Eligibility" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="theme" class="form-label">Theme:</label>
|
||||
<InputText id="theme" @bind-Value="EventDefinition.Theme" class="form-control" />
|
||||
<ValidationMessage For="() => EventDefinition.Theme" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label">Description:</label>
|
||||
<InputText id="description" @bind-Value="EventDefinition.Description" class="form-control" />
|
||||
<ValidationMessage For="() => EventDefinition.Description" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="levelofeffort" class="form-label">LevelOfEffort:</label>
|
||||
<InputNumber id="levelofeffort" @bind-Value="EventDefinition.LevelOfEffort" class="form-control" />
|
||||
<ValidationMessage For="() => EventDefinition.LevelOfEffort" class="text-danger" />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Create</button>
|
||||
</EditForm>
|
||||
</div>
|
||||
</div>
|
||||
<MudGrid>
|
||||
<MudItem xs="12" sm="7">
|
||||
<MudPaper Class="pa-4">
|
||||
<MudTextField T="string" Label="Event Name" @bind-Value="EventDefinition.Name" For="@(() => EventDefinition.Name)"></MudTextField>
|
||||
<MudTextField T="string" Label="Short Name" @bind-Value="EventDefinition.ShortName" For="@(() => EventDefinition.ShortName)"></MudTextField>
|
||||
|
||||
<label for="@EventDefinition.EventFormat" class="form-label">Format:</label>
|
||||
<MudRadioGroup T="EventFormat" @bind-Value="@EventDefinition.EventFormat">
|
||||
@* <MudRadio T="EventFormat" Value="EventFormat.Team">Team</MudRadio>
|
||||
<MudRadio T="EventFormat" Value="EventFormat.Individual">Individual</MudRadio> *@
|
||||
@foreach (EventFormat format in Enum.GetValues(typeof(EventFormat)))
|
||||
{
|
||||
<MudRadio T="EventFormat" value="@format">@(format.ToString())</MudRadio>
|
||||
}
|
||||
</MudRadioGroup>
|
||||
<ValidationMessage For="() => EventDefinition.EventFormat" class="text-danger" />
|
||||
|
||||
<MudTextField T="string" Label="Theme" AutoGrow="true" @bind-Value="EventDefinition.Theme" For="@(() => EventDefinition.Theme)"></MudTextField>
|
||||
<MudTextField T="string" Label="Documentation" @bind-Value="EventDefinition.Documentation" For="@(() => EventDefinition.Documentation)"></MudTextField>
|
||||
<MudNumericField T="int?" Label="Level of Effort" @bind-Value="EventDefinition.LevelOfEffort" For="@(() => EventDefinition.LevelOfEffort)"></MudNumericField>
|
||||
|
||||
<MudNumericField T="int" Label="Minimum Team Size" @bind-Value="EventDefinition.MinTeamSize" For="@(() => EventDefinition.MinTeamSize)"></MudNumericField>
|
||||
<MudNumericField T="int" Label="Maxiumum Team Size" @bind-Value="EventDefinition.MaxTeamSize" For="@(() => EventDefinition.MaxTeamSize)"></MudNumericField>
|
||||
<MudNumericField T="int" Label="Maxiumum Team Count at State" @bind-Value="EventDefinition.MaxTeamCountState" For="@(() => EventDefinition.MaxTeamCountState)"></MudNumericField>
|
||||
|
||||
<MudTextField T="string" Label="Semifinalist Activity" @bind-Value="EventDefinition.SemifinalistActivity" For="@(() => EventDefinition.SemifinalistActivity)"></MudTextField>
|
||||
<MudCheckBox T="bool" Label="Regional Event" @bind-Value="EventDefinition.RegionalEvent" For="@(() => EventDefinition.RegionalEvent)"></MudCheckBox>
|
||||
<MudCheckBox T="bool" Label="Requires Presubmission" @bind-Value="EventDefinition.StatePresubmission" For="@(() => EventDefinition.StatePresubmission)"></MudCheckBox>
|
||||
<MudCheckBox T="bool" Label="Preliminary Round" @bind-Value="EventDefinition.StatePreliminaryRound" For="@(() => EventDefinition.StatePreliminaryRound)"></MudCheckBox>
|
||||
<MudTextField T="string" Label="Eligibility" @bind-Value="EventDefinition.Eligibility" For="@(() => EventDefinition.Eligibility)"></MudTextField>
|
||||
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
<MudButton StartIcon="@Icons.Material.Filled.ArrowBack" Href="events">Back</MudButton>
|
||||
<MudButton ButtonType="ButtonType.Submit" StartIcon="@Icons.Material.Filled.Save">Save</MudButton>
|
||||
</EditForm>
|
||||
|
||||
<div>
|
||||
<a href="/events">Back to List</a>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[SupplyParameterFromForm]
|
||||
private EventDefinition EventDefinition { get; set; } = new();
|
||||
|
||||
// To protect from overposting attacks, see https://learn.microsoft.com/aspnet/core/blazor/forms/#mitigate-overposting-attacks.
|
||||
private async Task AddEventDefinition()
|
||||
private void OnValidSubmit()
|
||||
{
|
||||
context.Events.Add(EventDefinition);
|
||||
await context.SaveChangesAsync();
|
||||
context.SaveChanges();
|
||||
NavigationManager.NavigateTo("/events");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
@page "/events/delete"
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using Core.Entities
|
||||
@using Data
|
||||
@inject AppDbContext context
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
@page "/events/details"
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using Core.Entities
|
||||
@using Data
|
||||
@inject AppDbContext context
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
|
||||
@@ -8,50 +8,34 @@
|
||||
<MudText Typo="Typo.h4">Student</MudText>
|
||||
<MudDivider />
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<EditForm method="post" Model="Student" OnValidSubmit="AddStudent" FormName="create" Enhance>
|
||||
|
||||
<EditForm Model="Student" OnValidSubmit="OnValidSubmit" Enhance>
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary class="text-danger" role="alert"/>
|
||||
<div class="mb-3">
|
||||
<label for="firstname" class="form-label">First Name:</label>
|
||||
<InputText id="firstname" @bind-Value="Student.FirstName" class="form-control" />
|
||||
<ValidationMessage For="() => Student.FirstName" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="lastname" class="form-label">Last Name:</label>
|
||||
<InputText id="lastname" @bind-Value="Student.LastName" class="form-control" />
|
||||
<ValidationMessage For="() => Student.LastName" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="grade" class="form-label">Grade:</label>
|
||||
<InputNumber id="grade" @bind-Value="Student.Grade" class="form-control" />
|
||||
<ValidationMessage For="() => Student.Grade" class="text-danger" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="tsayear" class="form-label">TSA Year:</label>
|
||||
<InputNumber id="tsayear" @bind-Value="Student.TsaYear" class="form-control" />
|
||||
<ValidationMessage For="() => Student.TsaYear" class="text-danger" />
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Create</button>
|
||||
<MudGrid>
|
||||
<MudItem xs="12" sm="7">
|
||||
<MudPaper Class="pa-4">
|
||||
<MudTextField T="string" Label="First Name" @bind-Value="Student.FirstName" For="@(() => Student.FirstName)"></MudTextField>
|
||||
<MudTextField T="string" Label="Last Name" @bind-Value="Student.LastName" For="@(() => Student.LastName)"></MudTextField>
|
||||
<MudTextField T="string" Label="Email Adress" @bind-Value="Student.Email" For="@(() => Student.Email)"></MudTextField>
|
||||
<MudTextField T="string" Label="Phone Number" @bind-Value="Student.PhoneNumber" For="@(() => Student.PhoneNumber)"></MudTextField>
|
||||
<MudTextField T="int" Label="Grade" @bind-Value="Student.Grade" For="@(() => Student.Grade)"></MudTextField>
|
||||
<MudTextField T="int" Label="TSA Year" @bind-Value="Student.TsaYear" For="@(() => Student.TsaYear)"></MudTextField>
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
<MudButton StartIcon="@Icons.Material.Filled.ArrowBack" Href="students">Back</MudButton>
|
||||
<MudButton ButtonType="ButtonType.Submit" StartIcon="@Icons.Material.Filled.Save">Save</MudButton>
|
||||
</EditForm>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a href="/students">Back to List</a>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[SupplyParameterFromForm]
|
||||
private Student Student { get; set; } = new() { TsaYear = 1 };
|
||||
|
||||
private async Task AddStudent()
|
||||
private void OnValidSubmit(EditContext context)
|
||||
{
|
||||
|
||||
Context.Students.Add(Student);
|
||||
await Context.SaveChangesAsync();
|
||||
Context.SaveChanges();
|
||||
NavigationManager.NavigateTo("/students");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,39 +21,19 @@ else
|
||||
<MudTh>Name</MudTh>
|
||||
<MudTh>Grade</MudTh>
|
||||
<MudTh>TSA Year</MudTh>
|
||||
<MudTh>1st</MudTh>
|
||||
<MudTh>2nd</MudTh>
|
||||
<MudTh>3rd</MudTh>
|
||||
<MudTh>4th</MudTh>
|
||||
<MudTh>5th</MudTh>
|
||||
<MudTh>6th</MudTh>
|
||||
<MudTh>7th</MudTh>
|
||||
<MudTh>8th</MudTh>
|
||||
<MudTh>9th</MudTh>
|
||||
<MudTh>10th</MudTh>
|
||||
<MudTh></MudTh>
|
||||
<MudTh>Warnings</MudTh>
|
||||
@for (var i = 1; i <= 10; i++)
|
||||
{
|
||||
var ii = i;
|
||||
<MudTh>@AppIcons.GetOrdinal(ii)</MudTh>
|
||||
}
|
||||
</HeaderContent>
|
||||
<RowTemplate>
|
||||
|
||||
<MudTd>@context.FirstName</MudTd>
|
||||
<MudTh>@context.Grade</MudTh>
|
||||
<MudTh>@context.TsaYear</MudTh>
|
||||
|
||||
@for (var i = 1; i <= 10; i++)
|
||||
{
|
||||
var st = context.EventRankings.FirstOrDefault(e => e.Rank == i);
|
||||
<MudTd Class="@($"event-rank-{i})")">
|
||||
@if (st != null)
|
||||
{
|
||||
<span>@st.EventDefinition.ShortName
|
||||
@if(st.EventDefinition.EventFormat == EventFormat.Individual) { <span>ⓘ</span>}
|
||||
@if(st.EventDefinition.RegionalEvent) {<span>ⓡ</span>}
|
||||
@if(st.EventDefinition.OnSiteActivity) {<span>ⓐ</span>}
|
||||
</span>
|
||||
}
|
||||
</MudTd>
|
||||
}
|
||||
<MudTd><MudButton StartIcon="@Icons.Material.Filled.TableChart" Href="@($"students/event-ranking-edit/{context.Id}")">Edit</MudButton></MudTd>
|
||||
<MudTd>
|
||||
@if (!context.RankedEvents.Any(re => re.OnSiteActivity))
|
||||
@@ -76,6 +56,22 @@ else
|
||||
</MudTooltip>
|
||||
}
|
||||
</MudTd>
|
||||
@for (var i = 1; i <= 10; i++)
|
||||
{
|
||||
var ii = i;
|
||||
var st = context.EventRankings.FirstOrDefault(e => e.Rank == i);
|
||||
<MudTd Class="@($"event-rank-{ii})")">
|
||||
@if (st != null)
|
||||
{
|
||||
<span>@st.EventDefinition.ShortName
|
||||
@if(st.EventDefinition.EventFormat == EventFormat.Individual) { <span>ⓘ</span>}
|
||||
@if(st.EventDefinition.RegionalEvent) {<span>ⓡ</span>}
|
||||
@if(st.EventDefinition.OnSiteActivity) {<span>ⓐ</span>}
|
||||
</span>
|
||||
}
|
||||
</MudTd>
|
||||
}
|
||||
|
||||
</RowTemplate>
|
||||
</MudTable>
|
||||
<MudTable Items="_eventStudentRankings" Hover="true" Breakpoint="Breakpoint.Sm" LoadingProgressColor="Color.Info">
|
||||
|
||||
@@ -16,19 +16,31 @@
|
||||
</HeaderContent>
|
||||
<RowTemplate>
|
||||
<MudTd>
|
||||
@{
|
||||
var ol = TeamSchedulerSolution.GetStudentTeamOverlaps(context);}
|
||||
@foreach (var t in context)
|
||||
{
|
||||
<MudItem>
|
||||
@t.ToString() -
|
||||
@string.Join(", ", t.Students)
|
||||
@string.Join(", ", t.Students.Select(s => s.FirstName + " " + (ol.Any(o => o.Item1.Equals(s)) ? "*" : "" )) )
|
||||
</MudItem>
|
||||
}
|
||||
@foreach (var overlap in TeamSchedulerSolution.GetStudentTeamOverlaps(context))
|
||||
@* @foreach (var overlap in ol)
|
||||
{
|
||||
<MudItem>
|
||||
@string.Join(", ", overlap.Item1)
|
||||
</MudItem>
|
||||
} *@
|
||||
|
||||
@{ var notInTimeSLot = TeamSchedulerSolution.GetStudentsNotInTimSlot(context, _students); }
|
||||
@if (notInTimeSLot.Any()) {
|
||||
<MudItem>
|
||||
<i>
|
||||
Not scheduled: @string.Join(", ", notInTimeSLot.Select(s => s.FirstName))
|
||||
</i>
|
||||
</MudItem>
|
||||
}
|
||||
|
||||
</MudTd>
|
||||
</RowTemplate>
|
||||
</MudTable>
|
||||
@@ -93,9 +105,12 @@
|
||||
);
|
||||
|
||||
var mustIncludeTeams = _teams;
|
||||
mustIncludeTeams = mustIncludeTeams.Where(t => t.Event.EventFormat == EventFormat.Team).ToArray();
|
||||
mustIncludeTeams = mustIncludeTeams.Where(t => t.Event.EventFormat != EventFormat.Individual).ToArray();
|
||||
mustIncludeTeams = mustIncludeTeams.Where(t => !t.ToString().Contains("#1")).ToArray();
|
||||
//mustIncludeTeams = mustIncludeTeams.Where(t => !t.ToString().Contains("Photo")).ToArray();
|
||||
|
||||
var teamScheduler = new TeamScheduler(mustIncludeTeams, 3);
|
||||
|
||||
var teamScheduler = new TeamScheduler(mustIncludeTeams, scheduleOptions.TimeSlots);
|
||||
|
||||
// teamScheduler
|
||||
// .ScheduleSeparate(
|
||||
|
||||
Reference in New Issue
Block a user