Skip to content

Commit 717e415

Browse files
authored
Merge branch 'aliencube:main' into feature/308-endpoint-for-resource
2 parents b10c7ed + 97a3b53 commit 717e415

File tree

8 files changed

+536
-97
lines changed

8 files changed

+536
-97
lines changed

src/AzureOpenAIProxy.PlaygroundApp/AzureOpenAIProxy.PlaygroundApp.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<PackageReference Include="Microsoft.FluentUI.AspNetCore.Components" Version="$(FluentUIVersion)" />
1111
<PackageReference Include="Microsoft.FluentUI.AspNetCore.Components.Emoji" Version="$(FluentUIVersion)" />
1212
<PackageReference Include="Microsoft.FluentUI.AspNetCore.Components.Icons" Version="$(FluentUIVersion)" />
13+
<PackageReference Include="NodaTime" Version="3.1.12" />
1314
</ItemGroup>
1415

1516
<ItemGroup>

src/AzureOpenAIProxy.PlaygroundApp/Components/Pages/AdminNewEvent.razor

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
<PageTitle>New event</PageTitle>
44

55
<h1>New event</h1>
6+
7+
<NewEventDetailsComponent Id="admin-new-event" @rendermode="InteractiveServer" />
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
@using AzureOpenAIProxy.PlaygroundApp.Clients
2+
@using AzureOpenAIProxy.PlaygroundApp.Models;
3+
4+
@using System.Globalization
5+
6+
@using NodaTime
7+
@using NodaTime.Extensions
8+
@using NodaTime.TimeZones
9+
10+
<FluentLayout Id="@Id">
11+
@if (adminEventDetails == null)
12+
{
13+
<p><em>Loading...</em></p>
14+
}
15+
else
16+
{
17+
<FluentHeader>New Event</FluentHeader>
18+
<FluentBodyContent>
19+
<section>
20+
<h2>Event Infomation</h2>
21+
22+
<FluentStack Class="create-fluent-stack" Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center">
23+
<FluentLabel For="event-title" Class="create-input-label">Title</FluentLabel>
24+
<FluentTextField Id="event-title" Name="title" TextFieldType="TextFieldType.Text" Required />
25+
</FluentStack>
26+
27+
<FluentStack Class="create-fluent-stack" Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center">
28+
<FluentLabel For="event-summary" Class="create-input-label">Summary</FluentLabel>
29+
<FluentTextField id="event-summary" TextFieldType="TextFieldType.Text" Required />
30+
</FluentStack>
31+
32+
<FluentStack Class="create-fluent-stack" Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center">
33+
<FluentLabel For="event-description" Class="create-input-label">Description</FluentLabel>
34+
<FluentTextArea Id="event-description" Style="width:300px" />
35+
</FluentStack>
36+
37+
<FluentStack Class="create-fluent-stack" Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center">
38+
<FluentLabel For="event-start-date" Class="create-input-label">Event Start Date</FluentLabel>
39+
<FluentDatePicker Id="event-start-date" Value="@adminEventDetails.DateStart.DateTime" ValueChanged="@(e => adminEventDetails.DateStart = e.Value)" Culture="System.Globalization.CultureInfo.CurrentCulture" />
40+
<FluentTimePicker Id="event-start-time" Value="@adminEventDetails.DateStart.DateTime" ValueChanged="@(e => adminEventDetails.DateStart = e.Value)" />
41+
</FluentStack>
42+
43+
<FluentStack Class="create-fluent-stack" Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center">
44+
<FluentLabel For="event-end-date" Class="create-input-label">Event End Date</FluentLabel>
45+
<FluentDatePicker Id="event-end-date" Value="@adminEventDetails.DateEnd.DateTime" ValueChanged="@(e => adminEventDetails.DateEnd = e.Value)" Culture="System.Globalization.CultureInfo.CurrentCulture" />
46+
<FluentTimePicker Id="event-end-time" Value="@adminEventDetails.DateEnd.DateTime" ValueChanged="@(e => adminEventDetails.DateEnd = e.Value)" />
47+
</FluentStack>
48+
49+
<FluentStack Class="create-fluent-stack" Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center">
50+
<FluentLabel For="event-timezone" Class="create-input-label">Time Zone</FluentLabel>
51+
<FluentSelect Id="event-timezone" @bind-Value="@adminEventDetails.TimeZone" Height="500px" TOption="string" Required>
52+
@foreach (var timeZone in timeZoneList)
53+
{
54+
<FluentOption Value="@timeZone.Id">@timeZone.Id</FluentOption>
55+
}
56+
</FluentSelect>
57+
</FluentStack>
58+
</section>
59+
60+
<section>
61+
<h2>Event Organizer</h2>
62+
63+
<FluentStack Class="create-fluent-stack" Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center">
64+
<FluentLabel For="event-organizer-name" Class="create-input-label">Organizer Name</FluentLabel>
65+
<FluentTextField Id="event-organizer-name" TextFieldType="TextFieldType.Text" Required />
66+
</FluentStack>
67+
68+
69+
<FluentStack Class="create-fluent-stack" Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center">
70+
<FluentLabel For="event-organizer-email" Class="create-input-label">Organizer Email</FluentLabel>
71+
<FluentTextField Id="event-organizer-email" TextFieldType="TextFieldType.Email" Required />
72+
</FluentStack>
73+
</section>
74+
75+
<section>
76+
<h2>Event Coorganizers</h2>
77+
78+
<FluentStack Class="create-fluent-stack" Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center">
79+
<FluentLabel For="event-coorgnizer-name" Class="create-input-label">Coorgnizer Name</FluentLabel>
80+
<FluentTextField Id="event-coorgnizer-name" TextFieldType="TextFieldType.Text" Required />
81+
</FluentStack>
82+
83+
<FluentStack Class="create-fluent-stack" Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center">
84+
<FluentLabel For="event-coorgnizer-email" Class="create-input-label">Coorgnizer Email</FluentLabel>
85+
<FluentTextField Id="event-coorgnizer-email" TextFieldType="TextFieldType.Email" Required />
86+
</FluentStack>
87+
</section>
88+
89+
<section>
90+
<h2>Event Configuration</h2>
91+
92+
<FluentStack Class="create-fluent-stack" Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center">
93+
<FluentLabel For="event-max-token-cap" Class="create-input-label">Max Token Cap</FluentLabel>
94+
<FluentNumberField Id="event-max-token-cap" @bind-Value="adminEventDetails.MaxTokenCap" Required />
95+
</FluentStack>
96+
97+
<FluentStack Class="create-fluent-stack" Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center">
98+
<FluentLabel For="event-daily-request-cap" Class="create-input-label">Daily Request Cap</FluentLabel>
99+
<FluentNumberField Id="event-daily-request-cap" @bind-Value="adminEventDetails.DailyRequestCap" Required />
100+
</FluentStack>
101+
</section>
102+
103+
<section class="button-section">
104+
<FluentButton Id="admin-event-detail-add" Appearance="Appearance.Accent" Class="button" OnClick="AddEvent">Add Event</FluentButton>
105+
<FluentButton Id="admin-event-detail-cancel" Appearance="Appearance.Outline" Class="button" OnClick="CancelEvent">Cancel</FluentButton>
106+
</section>
107+
</FluentBodyContent>
108+
}
109+
</FluentLayout>
110+
111+
112+
@code {
113+
private List<DateTimeZone>? timeZoneList;
114+
private AdminEventDetails? adminEventDetails;
115+
private DateTimeOffset currentTime = DateTimeOffset.UtcNow;
116+
117+
[Parameter]
118+
public string? Id { get; set; }
119+
120+
protected override async Task OnInitializedAsync()
121+
{
122+
adminEventDetails = adminEventDetails == null ? new() : adminEventDetails;
123+
124+
timeZoneList = DateTimeZoneProviders.Tzdb.GetAllZones().ToList();
125+
126+
CultureInfo customCulture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
127+
customCulture.DateTimeFormat.ShortDatePattern = "yyyy-MM-dd";
128+
customCulture.DateTimeFormat.ShortTimePattern = "HH:mm";
129+
130+
CultureInfo.DefaultThreadCurrentCulture = customCulture;
131+
CultureInfo.DefaultThreadCurrentUICulture = customCulture;
132+
}
133+
134+
protected override async Task OnAfterRenderAsync(bool firstRender)
135+
{
136+
if (firstRender)
137+
{
138+
var timezoneId = GetIanaTimezoneId();
139+
currentTime = GetCurrentDateTimeOffset(timezoneId);
140+
141+
adminEventDetails.DateStart = currentTime.AddHours(1).AddMinutes(-currentTime.Minute);
142+
adminEventDetails.DateEnd = currentTime.AddDays(1).AddHours(1).AddMinutes(-currentTime.Minute);
143+
adminEventDetails.TimeZone = timezoneId;
144+
145+
await InvokeAsync(StateHasChanged);
146+
}
147+
}
148+
149+
private async Task AddEvent()
150+
{
151+
await Task.CompletedTask;
152+
}
153+
154+
private async Task CancelEvent()
155+
{
156+
await Task.CompletedTask;
157+
}
158+
159+
private string GetIanaTimezoneId()
160+
{
161+
string timezoneId = TimeZoneInfo.Local.Id;
162+
163+
if (OperatingSystem.IsWindows())
164+
{
165+
if (TimeZoneInfo.TryConvertWindowsIdToIanaId(timezoneId, out var ianaTimezoneId))
166+
{
167+
timezoneId = ianaTimezoneId;
168+
}
169+
}
170+
171+
return timezoneId;
172+
}
173+
174+
private DateTimeOffset GetCurrentDateTimeOffset(string timezoneId)
175+
{
176+
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timezoneId);
177+
178+
return TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, timeZoneInfo);
179+
}
180+
}
181+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
section {
2+
margin-bottom: 100px
3+
}
4+
5+
::deep .create-input-label {
6+
width: 200px;
7+
--type-ramp-base-font-size: 22px;
8+
}
9+
10+
::deep .create-fluent-stack {
11+
height: 100px;
12+
}
13+
14+
.button-section {
15+
display: flex;
16+
justify-content: center;
17+
gap: 50px;
18+
}
19+
20+
.button {
21+
width: 150px;
22+
height: 50px;
23+
font-size: 16px;
24+
margin: 0 10px;
25+
}
Lines changed: 59 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,60 @@
1-
using System.Text.Json.Serialization;
2-
3-
namespace AzureOpenAIProxy.PlaygroundApp.Models;
4-
5-
/// <summary>
6-
/// This represent the event detail data for response by admin event endpoint.
7-
/// </summary>
8-
public class AdminEventDetails : EventDetails
9-
{
10-
/// <summary>
11-
/// Gets or sets the event description.
12-
/// </summary>
13-
public string? Description { get; set; }
14-
15-
/// <summary>
16-
/// Gets or sets the event start date.
17-
/// </summary>
18-
[JsonRequired]
19-
public DateTimeOffset DateStart { get; set; }
20-
21-
/// <summary>
22-
/// Gets or sets the event end date.
23-
/// </summary>
24-
[JsonRequired]
25-
public DateTimeOffset DateEnd { get; set; }
26-
27-
/// <summary>
28-
/// Gets or sets the event start to end date timezone.
29-
/// </summary>
30-
[JsonRequired]
31-
public string TimeZone { get; set; } = string.Empty;
32-
33-
/// <summary>
34-
/// Gets or sets the event active status.
35-
/// </summary>
36-
[JsonRequired]
37-
public bool IsActive { get; set; }
38-
39-
/// <summary>
40-
/// Gets or sets the event organizer name.
41-
/// </summary>
42-
[JsonRequired]
43-
public string OrganizerName { get; set; } = string.Empty;
44-
45-
/// <summary>
46-
/// Gets or sets the event organizer email.
47-
/// </summary>
48-
[JsonRequired]
49-
public string OrganizerEmail { get; set; } = string.Empty;
50-
51-
/// <summary>
52-
/// Gets or sets the event coorganizer name.
53-
/// </summary>
54-
public string? CoorganizerName { get; set; }
55-
56-
/// <summary>
57-
/// Gets or sets the event coorganizer email.
58-
/// </summary>
59-
public string? CoorganizerEmail { get; set; }
1+
using System.Text.Json.Serialization;
2+
3+
namespace AzureOpenAIProxy.PlaygroundApp.Models;
4+
5+
/// <summary>
6+
/// This represent the event detail data for response by admin event endpoint.
7+
/// </summary>
8+
public class AdminEventDetails : EventDetails
9+
{
10+
/// <summary>
11+
/// Gets or sets the event description.
12+
/// </summary>
13+
public string? Description { get; set; }
14+
15+
/// <summary>
16+
/// Gets or sets the event start date.
17+
/// </summary>
18+
[JsonRequired]
19+
public DateTimeOffset DateStart { get; set; }
20+
21+
/// <summary>
22+
/// Gets or sets the event end date.
23+
/// </summary>
24+
[JsonRequired]
25+
public DateTimeOffset DateEnd { get; set; }
26+
27+
/// <summary>
28+
/// Gets or sets the event start to end date timezone.
29+
/// </summary>
30+
[JsonRequired]
31+
public string TimeZone { get; set; } = string.Empty;
32+
33+
/// <summary>
34+
/// Gets or sets the event active status.
35+
/// </summary>
36+
[JsonRequired]
37+
public bool IsActive { get; set; }
38+
39+
/// <summary>
40+
/// Gets or sets the event organizer name.
41+
/// </summary>
42+
[JsonRequired]
43+
public string OrganizerName { get; set; } = string.Empty;
44+
45+
/// <summary>
46+
/// Gets or sets the event organizer email.
47+
/// </summary>
48+
[JsonRequired]
49+
public string OrganizerEmail { get; set; } = string.Empty;
50+
51+
/// <summary>
52+
/// Gets or sets the event coorganizer name.
53+
/// </summary>
54+
public string? CoorganizerName { get; set; }
55+
56+
/// <summary>
57+
/// Gets or sets the event coorganizer email.
58+
/// </summary>
59+
public string? CoorganizerEmail { get; set; }
6060
}

0 commit comments

Comments
 (0)