fix(inbox|xtracto): Delete/Read msg and allow non-ascii xtractor names
This commit is contained in:
@@ -28,8 +28,8 @@
|
||||
"nixpkgs": {
|
||||
"type": "Channel",
|
||||
"name": "nixpkgs-unstable",
|
||||
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre927565.13868c071cc7/nixexprs.tar.xz",
|
||||
"hash": "sha256-wufp5c0nWh/87f9eK7xy1eZXms5zd4yl6S4SR+LfA08="
|
||||
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre930106.bde090228871/nixexprs.tar.xz",
|
||||
"hash": "sha256-N1BW0usecHQVLHKlH+d1NW6CS2At1s3sjpE+N0dOgl4="
|
||||
},
|
||||
"pre-commit": {
|
||||
"type": "Git",
|
||||
@@ -40,9 +40,9 @@
|
||||
},
|
||||
"branch": "master",
|
||||
"submodules": false,
|
||||
"revision": "f0927703b7b1c8d97511c4116eb9b4ec6645a0fa",
|
||||
"url": "https://github.com/cachix/git-hooks.nix/archive/f0927703b7b1c8d97511c4116eb9b4ec6645a0fa.tar.gz",
|
||||
"hash": "sha256-6MkqajPICgugsuZ92OMoQcgSHnD6sJHwk8AxvMcIgTE="
|
||||
"revision": "be7d943c905ac39110153679404546625757ec5a",
|
||||
"url": "https://github.com/cachix/git-hooks.nix/archive/be7d943c905ac39110153679404546625757ec5a.tar.gz",
|
||||
"hash": "sha256-98kaVYyT0tb8CFSkXPxLs+Ezv2FnBH84pwvQVAXrMWw="
|
||||
}
|
||||
},
|
||||
"version": 7
|
||||
|
||||
@@ -24,7 +24,7 @@ pkgs.mkShellNoCC {
|
||||
|
||||
# JavaScript
|
||||
pkgs.bun
|
||||
pkgs.nodejs
|
||||
pkgs.nodejs_25
|
||||
|
||||
# Devlopment tools
|
||||
pkgs.npins
|
||||
|
||||
@@ -14,7 +14,7 @@ pack_path := "../../packages"
|
||||
|
||||
vite_prod := "bunx --bun vite build -c ../../vite.config.js -m production --emptyOutDir --outDir " + "../../dist/public"
|
||||
vite_dev := "bunx --bun vite build -c ../../vite.config.js -m development --minify false --sourcemap true --emptyOutDir --outDir " + "../../dist/public"
|
||||
vite := "bunx --bun vite -c ../../vite.config.js -m development "
|
||||
vite := "bunx vite -c ../../vite.config.js -m development "
|
||||
|
||||
# Default recipe - show available commands
|
||||
default:
|
||||
|
||||
@@ -43,16 +43,16 @@ let inboxDialog
|
||||
let table = document.getElementById "inbox-table"
|
||||
async {
|
||||
let! mbox = Remoting.inboxApi().getMessages ()
|
||||
// if mbox.Length = 0 then
|
||||
// table?items <- [| {
|
||||
// id = Guid.Empty
|
||||
// content = ""
|
||||
// unread = false
|
||||
// type' = MessageType.Note
|
||||
// created = DateTime.Now
|
||||
// } |]
|
||||
// else
|
||||
table?items <- mbox
|
||||
if mbox.Length = 0 then
|
||||
table?items <- [| {
|
||||
id = Guid.Empty
|
||||
content = ""
|
||||
unread = false
|
||||
type' = MessageType.Note
|
||||
created = DateTime.Now
|
||||
} |]
|
||||
else
|
||||
table?items <- mbox
|
||||
} |> Async.StartImmediate
|
||||
|
||||
Hook.useEffectOnChange(arg.unread, loadMessages)
|
||||
@@ -65,30 +65,18 @@ let inboxDialog
|
||||
|> Set.ofSeq
|
||||
|> setSelected
|
||||
|
||||
let doDelete _ =
|
||||
let doDelete selected _ =
|
||||
let table = document.getElementById "inbox-table"
|
||||
let selectedSet : Guid JS.Set = table?selectedSet
|
||||
let items: InboxItem array = table?items
|
||||
async {
|
||||
let toDelete =
|
||||
items
|
||||
|> Array.filter (fun item -> selectedSet.has(item.id))
|
||||
|> Array.map (fun item -> item.id)
|
||||
|
||||
console.debug("Deleting", toDelete.Length, "messages")
|
||||
items
|
||||
|> Array.filter (fun item -> Set.contains item.id selected)
|
||||
|> Array.iter (fun item ->
|
||||
console.log("Delete: %A", item.content)
|
||||
do arg.deleteMessage item.id
|
||||
)
|
||||
|
||||
for id in toDelete do
|
||||
arg.deleteMessage id
|
||||
|
||||
// Clear selection immediately
|
||||
selectedSet.clear()
|
||||
setSelected Set.empty
|
||||
|
||||
// Wait a bit for server to process, then reload
|
||||
do! Async.Sleep 200
|
||||
let! mbox = Remoting.inboxApi().getMessages ()
|
||||
table?items <- mbox
|
||||
} |> Async.StartImmediate
|
||||
loadMessages ()
|
||||
|
||||
let doRead selected _ =
|
||||
let table = document.getElementById "inbox-table"
|
||||
@@ -118,7 +106,7 @@ let inboxDialog
|
||||
html $"""
|
||||
<sp-field-group horizontal>
|
||||
<sp-action-button
|
||||
@click={Ev(doDelete)}
|
||||
@click={Ev(doDelete selected)}
|
||||
?disabled={selected.Count = 0}>
|
||||
<sp-icon-delete slot="icon"></sp-icon-delete> Delete selected
|
||||
</sp-action-button>
|
||||
@@ -308,11 +296,8 @@ let inboxDialog
|
||||
let sortFn = if sortDir = "asc" then Array.sortBy else Array.sortByDescending
|
||||
table?items
|
||||
|> sortFn (fun item -> JS.expr_js $"{item}[{sortKey}]")
|
||||
|> fun items -> table?items <- items))
|
||||
|
||||
let table =
|
||||
html $"""
|
||||
"""
|
||||
|> fun items -> table?items <- items)
|
||||
)
|
||||
|
||||
html $"""
|
||||
<div class="inbox-dialog">
|
||||
|
||||
@@ -101,20 +101,20 @@ type IPrincipalActor =
|
||||
inherit IActor
|
||||
abstract IsActive: unit: unit -> Task<bool>
|
||||
abstract IsRegistered: unit: unit -> Task<bool>
|
||||
abstract GetGroups: unit: unit -> Task<string[]>
|
||||
abstract GetRoles: unit: unit -> Task<string[]>
|
||||
abstract GetGroups: unit: unit -> Task<string array>
|
||||
abstract GetRoles: unit: unit -> Task<string array>
|
||||
abstract Register: unit: unit -> Task<bool>
|
||||
abstract Activate: unit: unit -> Task<bool>
|
||||
abstract Disable: unit: unit -> Task<bool>
|
||||
|
||||
type UserCredentials = { username: string; password: string }
|
||||
|
||||
// needed by signalr
|
||||
// NOTE: Needed by signalr
|
||||
type UserIdProvider() =
|
||||
interface IUserIdProvider with
|
||||
member this.GetUserId(ctx: HubConnectionContext) =
|
||||
let uid = ctx.User.Identity.Name
|
||||
Log.Verbose $"UserIdProvider: {uid}"
|
||||
Log.Verbose $"UserIdProvider: %s{uid}"
|
||||
uid
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
@@ -130,6 +130,7 @@ let tryStr str =
|
||||
None
|
||||
else
|
||||
Some str
|
||||
|
||||
let tryGetEnv =
|
||||
Environment.GetEnvironmentVariable
|
||||
>> tryStr
|
||||
@@ -140,7 +141,7 @@ let authorize: HttpHandler =
|
||||
|
||||
let addGroupsAndRoles (principal: ClaimsPrincipal) : Async<bool> =
|
||||
let addToIdentity (identity: ClaimsIdentity) ctype cc =
|
||||
eprintfn $"[MultiAuth] Adding claim {ctype} to principal: %A{cc}"
|
||||
eprintfn $"[MultiAuth] Adding claim %s{ctype} to principal: %A{cc}"
|
||||
cc
|
||||
|> Array.choose (fun g ->
|
||||
if not (principal.HasClaim (fun claim -> claim.Type = ctype && claim.Value = g)) then
|
||||
@@ -295,14 +296,14 @@ let oidOptions (settings: MultiAuthSettings) (o: OpenIdConnectOptions) =
|
||||
fun e ->
|
||||
task {
|
||||
eprintfn "[MultiAuth] RedirectToIdentityProvider: %A" e.Request.Host.Value
|
||||
// hack for https behind proxy
|
||||
// HACK: For https behind proxy
|
||||
e.ProtocolMessage.RedirectUri <- $"https://{e.Request.Host.Value}/signin-oidc"
|
||||
return ()
|
||||
}
|
||||
o.Events.OnRedirectToIdentityProviderForSignOut <-
|
||||
fun e ->
|
||||
task {
|
||||
// hack for https behind proxy
|
||||
// HACK: For https behind proxy
|
||||
e.ProtocolMessage.PostLogoutRedirectUri <- $"https://{e.Request.Host.Value}/signout-callback-oidc"
|
||||
return ()
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ module Xtract =
|
||||
Log.Debug $"Sorcerer.Xtract.downloadZip: user={username}, archiveId={archiveId}, jobId={jobId}"
|
||||
let fileName = $"/data/archives/xtract/{username}/{jobId}/xtract.zip"
|
||||
if File.Exists fileName then
|
||||
(setHttpHeader "Content-Disposition" $"attachment; filename={outname}.zip" >=> streamFile true fileName None None) next ctx
|
||||
(setHttpHeader "Content-Disposition" $"attachment; filename=site-report.zip" >=> streamFile true fileName None None) next ctx
|
||||
else
|
||||
Log.Warning $"Xtract file not found: {fileName}"
|
||||
RequestErrors.NOT_FOUND "File not found" next ctx
|
||||
|
||||
Reference in New Issue
Block a user