fix(Codex): only allow inbounds time intervals on edit archive
This commit is contained in:
@@ -168,6 +168,18 @@ type Archives =
|
||||
let form, setForm = React.useState initForm
|
||||
let isOpen, setIsOpen = React.useState false
|
||||
let errMsg, setErrMsg = React.useState None
|
||||
let dataSet, setDataSet = React.useState None
|
||||
|
||||
React.useEffectOnce (fun _ ->
|
||||
Remoting.adminApi.getArchiveDataSet archive.archiveId
|
||||
|> Async.StartAsPromise
|
||||
|> Promise.iter (fun res ->
|
||||
match res with
|
||||
| Ok ds -> setDataSet (Some ds)
|
||||
| Error msg ->
|
||||
Browser.Dom.console.error("Error fetching dataset: %s", msg)
|
||||
)
|
||||
)
|
||||
|
||||
let handleEditArchive () =
|
||||
let utcTime = System.DateTime(form.StartTime.Year, form.StartTime.Month, form.StartTime.Day, 0, 0, 0, System.DateTimeKind.Utc)
|
||||
@@ -184,6 +196,13 @@ type Archives =
|
||||
setErrMsg (Some msg)
|
||||
)
|
||||
|
||||
let framesExceedEnd =
|
||||
dataSet
|
||||
|> Option.map (fun ds ->
|
||||
form.StartTime.AddHours(form.Frames) > ds.EndTime
|
||||
)
|
||||
|> Option.defaultValue false
|
||||
|
||||
Fui.dialog [
|
||||
dialog.open' isOpen
|
||||
dialog.onOpenChange (fun (d: DialogOpenChangeData<Browser.Types.MouseEvent>) ->
|
||||
@@ -258,6 +277,11 @@ type Archives =
|
||||
datePicker.placeholder "Select a date..."
|
||||
datePicker.showWeekNumbers true
|
||||
datePicker.formatDate (fun d -> d.ToShortDateString())
|
||||
match dataSet with
|
||||
| None -> ()
|
||||
| Some ds ->
|
||||
datePicker.minDate ds.StartTime
|
||||
datePicker.maxDate ds.EndTime
|
||||
datePicker.value (Some form.StartTime)
|
||||
datePicker.onSelectDate (fun d ->
|
||||
d |> Option.iter (fun d' ->
|
||||
@@ -292,8 +316,17 @@ type Archives =
|
||||
]
|
||||
]
|
||||
Fui.text.caption1 [
|
||||
if framesExceedEnd then
|
||||
text.style [style.color Theme.tokens.colorStatusDangerForeground1]
|
||||
|
||||
let endDate = form.StartTime.AddHours(form.Frames).ToShortDateString()
|
||||
text.text (sprintf "End Date: %s, %d frames" endDate form.Frames)
|
||||
text.text
|
||||
($"End Date: {endDate}, {form.Frames} frames"
|
||||
+
|
||||
if framesExceedEnd then
|
||||
" (Exceeds DataSet Bounds!)"
|
||||
else
|
||||
"")
|
||||
]
|
||||
Fui.checkbox [
|
||||
checkbox.label "Published"
|
||||
|
||||
@@ -292,6 +292,20 @@ module Admin =
|
||||
return Error "Error fetching dataSets"
|
||||
}
|
||||
|
||||
let getArchiveDataSet (ctx: HttpContext) (archiveId: System.Guid) =
|
||||
async {
|
||||
let user = ctx.User.Identity.Name
|
||||
let logger = ctx.GetLogger<Remoting.Api.Admin> ()
|
||||
try
|
||||
do logger.LogInformation("getArchiveDataSet {Archive} from {User}", archiveId, user)
|
||||
let db = ctx.GetService<NpgsqlDataSource> ()
|
||||
let! dataSet = Archmaester.Dapper.queryArchiveDataSet db archiveId
|
||||
return Ok dataSet
|
||||
with e ->
|
||||
do logger.LogError (e, "getArchiveDataSet {Archive} from {User}", archiveId, user)
|
||||
return Error "Error fetching dataset"
|
||||
}
|
||||
|
||||
let addArchive (ctx: HttpContext) (archive: Remoting.AddArchiveRequest) =
|
||||
let archmaesterAdd (db: Entity.ArchiveContext) =
|
||||
async {
|
||||
@@ -528,6 +542,7 @@ module Admin =
|
||||
getGroupUsers = Handler.getGroupUsers ctx
|
||||
removeUsers = Handler.removeUsers ctx
|
||||
getDataSets = fun () -> Handler.getAllDataSets ctx
|
||||
getArchiveDataSet = Handler.getArchiveDataSet ctx
|
||||
addArchive = Handler.addArchive ctx
|
||||
updateArchive = Handler.updateArchive ctx
|
||||
}
|
||||
|
||||
@@ -201,6 +201,64 @@ module Archmaester =
|
||||
)
|
||||
}
|
||||
|
||||
let queryArchiveDataSet (db: NpgsqlDataSource) (archiveId: System.Guid) =
|
||||
async {
|
||||
use conn = db.OpenConnection ()
|
||||
let query =
|
||||
"""
|
||||
SELECT
|
||||
a.id AS a_id,
|
||||
a.base_path,
|
||||
m.id AS m_id,
|
||||
m.name AS m_name,
|
||||
MIN(f.start_time) AS start_time,
|
||||
MAX(f.start_time) AS end_time
|
||||
FROM
|
||||
attribs AS a
|
||||
JOIN
|
||||
model_areas AS m
|
||||
ON m.id = a.model_area_id
|
||||
LEFT JOIN
|
||||
files AS f
|
||||
ON f.attribs_id = a.id
|
||||
LEFT JOIN
|
||||
archives as ar
|
||||
ON ar.attribs_id = a.id
|
||||
WHERE
|
||||
ar.id = @archive_id
|
||||
GROUP BY
|
||||
a.id,
|
||||
a.base_path,
|
||||
m.id,
|
||||
m.name
|
||||
;
|
||||
"""
|
||||
|
||||
let param =
|
||||
dict [
|
||||
"archive_id", box archiveId
|
||||
]
|
||||
|
||||
let! res =
|
||||
conn.QueryAsync<DataSetTable>(query, param)
|
||||
|> Async.AwaitTask
|
||||
|
||||
return
|
||||
res
|
||||
|> Array.ofSeq
|
||||
|> Array.map (fun x ->
|
||||
{
|
||||
Id = x.a_id
|
||||
BasePath = x.base_path
|
||||
ModelAreaId = x.m_id
|
||||
ModelAreaName = x.m_name
|
||||
StartTime = x.start_time
|
||||
EndTime = x.end_time.AddHours(24)
|
||||
} : Remoting.DataSet
|
||||
) // TODO: is there a better way to select single rows?
|
||||
|> Array.head
|
||||
}
|
||||
|
||||
module EFCore =
|
||||
open System.Linq
|
||||
|
||||
|
||||
@@ -214,6 +214,7 @@ module Remoting =
|
||||
getGroupUsers: string -> Async<string array>
|
||||
removeUsers: string array -> Async<Result<unit, string>>
|
||||
getDataSets: unit -> Async<Result<DataSet array, string>>
|
||||
getArchiveDataSet: System.Guid -> Async<Result<DataSet, string>>
|
||||
addArchive: AddArchiveRequest -> Async<Result<Archive, string>>
|
||||
updateArchive: System.Guid -> EditArchiveRequest -> Async<Result<Archive, string>>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user