Compare commits
16 Commits
main
...
mrtz/tauri
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06632b4413 | ||
| 2ff9dafc13 | |||
| 6a24342322 | |||
| d05015decf | |||
| b66cc67802 | |||
| ac27a0544d | |||
| 3ba01c882b | |||
| 649b0af9d4 | |||
| 918041e063 | |||
| c3c6bb06df | |||
| 647302778f | |||
| e53de54c13 | |||
| 8e9d975cca | |||
| e8990fa1d4 | |||
| ff4f3aebab | |||
| 4ddbe133b0 |
@@ -1,38 +0,0 @@
|
||||
open Fake.Core
|
||||
open Fake.IO
|
||||
open Farmer
|
||||
open Farmer.Builders
|
||||
|
||||
open Helpers
|
||||
|
||||
initializeContext()
|
||||
|
||||
let packPath = Path.getFullName "packages"
|
||||
|
||||
Target.create "Clean" (fun _ -> Shell.cleanDir packPath)
|
||||
|
||||
Target.create "InstallClient" (fun _ ->
|
||||
run bun "install" "."
|
||||
run dotnet "tool restore" "."
|
||||
)
|
||||
|
||||
Target.create "Run" ignore
|
||||
|
||||
Target.create "Format" (fun _ ->
|
||||
run dotnet "fantomas . -r" "src"
|
||||
)
|
||||
|
||||
open Fake.Core.TargetOperators
|
||||
|
||||
let dependencies = [
|
||||
"Clean"
|
||||
==> "InstallClient"
|
||||
|
||||
"Run"
|
||||
==> "InstallClient"
|
||||
|
||||
"Format"
|
||||
]
|
||||
|
||||
[<EntryPoint>]
|
||||
let main args = runOrDefault args
|
||||
@@ -124,4 +124,4 @@ let runOrDefault args =
|
||||
0
|
||||
with e ->
|
||||
printfn "%A" e
|
||||
1
|
||||
1
|
||||
|
||||
@@ -7,6 +7,9 @@ charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = false
|
||||
|
||||
[*.html]
|
||||
indent_size = 2
|
||||
|
||||
[*.js]
|
||||
indent_size = 2
|
||||
max_line_length= 80
|
||||
|
||||
3
.gitignore
vendored
@@ -29,4 +29,5 @@ NuGet.Config
|
||||
sync.list
|
||||
packages.lock.json
|
||||
package-lock.json
|
||||
*.nupkg
|
||||
*.nupkg
|
||||
*.jsx
|
||||
17
Build.fsproj
@@ -1,17 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include=".build/Helpers.fs" />
|
||||
<Compile Include=".build/Build.fs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fake.Core.Target" Version="6.1.3" />
|
||||
<PackageReference Include="Fake.DotNet.Cli" Version="6.1.3" />
|
||||
<PackageReference Include="Fake.IO.FileSystem" Version="6.1.3" />
|
||||
<PackageReference Include="Farmer" Version="1.9.6" />
|
||||
<PackageReference Update="FSharp.Core" Version="9.0.100" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
17
package.json
@@ -15,17 +15,29 @@
|
||||
"@sentry/vite-plugin": "^3.5.0",
|
||||
"@vitejs/plugin-react": "^5.0.0",
|
||||
"rollup-plugin-scss": "^4.0.1",
|
||||
"sass": "^1.89.2",
|
||||
"@tauri-apps/cli": "^2.7.1",
|
||||
"semantic-release": "^24.2.5",
|
||||
"semantic-release-dotnet": "^1.0.0",
|
||||
"vite": "npm:rolldown-vite@latest",
|
||||
"vite-plugin-mkcert": "^1.17.8"
|
||||
},
|
||||
"dependencies": {
|
||||
"@carbon/icons-react": "^11.65.0",
|
||||
"@carbon/react": "^1.89.0",
|
||||
"@carbon/type": "^11.45.0",
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.1",
|
||||
"@fluentui/react-components": "^9.68.3",
|
||||
"@fluentui/react-icons": "^2.0.307",
|
||||
"@fluentui/web-components": "^3.0.0-beta.115",
|
||||
"@fontsource/roboto": "^5.2.6",
|
||||
"@fortawesome/fontawesome-free": "^6.7.2",
|
||||
"@ibm/plex-sans": "^1.1.0",
|
||||
"@lit-labs/motion": "^1.0.8",
|
||||
"@lit/context": "^1.1.5",
|
||||
"@microsoft/signalr": "^8.0.7",
|
||||
"@mui/icons-material": "^7.3.1",
|
||||
"@mui/material": "^7.3.1",
|
||||
"@sentry/browser": "^9.30.0",
|
||||
"@shoelace-style/shoelace": "^2.20.1",
|
||||
"@spectrum-web-components/accordion": "^1.7.0",
|
||||
@@ -62,6 +74,8 @@
|
||||
"@spectrum-web-components/underlay": "^1.6.0",
|
||||
"@turf/bezier-spline": "^7.2.0",
|
||||
"@vaadin/login": "^24.8.0",
|
||||
"@tauri-apps/api": "^2.7.0",
|
||||
"@tauri-apps/plugin-shell": "^2",
|
||||
"lit": "^3.3.0",
|
||||
"lit-html": "^3.3.0",
|
||||
"ol": "^10.6.0",
|
||||
@@ -70,6 +84,7 @@
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-plotly.js": "^2.6.0",
|
||||
"sass": "^1.90.0",
|
||||
"vis-timeline": "^7.7.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@ pkgs.mkShellNoCC {
|
||||
buildInputs = [ dotnet-sdk ];
|
||||
|
||||
packages = [
|
||||
pkgs.fsautocomplete
|
||||
pkgs.fantomas
|
||||
|
||||
# JavaScript
|
||||
pkgs.bun
|
||||
pkgs.nodejs-slim
|
||||
|
||||
@@ -5,12 +5,12 @@ open Farmer.Builders
|
||||
|
||||
open Helpers
|
||||
|
||||
initializeContext()
|
||||
initializeContext ()
|
||||
|
||||
let serverPath = Path.getFullName "src/Server"
|
||||
let clientPath = Path.getFullName "src/Client"
|
||||
let testPath = Path.getFullName "test"
|
||||
let libPath = Path.getFullName "src/Interfaces" |> Some
|
||||
let testPath = Path.getFullName "test"
|
||||
let libPath = Path.getFullName "src/Interfaces" |> Some
|
||||
|
||||
let distPath = Path.getFullName "dist"
|
||||
let packPath = Path.getFullName "packages"
|
||||
@@ -25,66 +25,63 @@ let fableWatch = $"fable watch -e .jsx -o build --run {vite}"
|
||||
|
||||
Target.create "Clean" (fun _ -> Shell.cleanDir distPath)
|
||||
|
||||
Target.create "InstallClient" (fun _ ->
|
||||
run bun "install" "."
|
||||
run dotnet "tool restore" ".")
|
||||
|
||||
Target.create "Bundle" (fun _ ->
|
||||
[ "server", dotnet $"build -tl -c Release -o {distPath} -p:DefineConstants=" serverPath
|
||||
"client", dotnet (fable "-m production") clientPath ]
|
||||
|> runParallel
|
||||
)
|
||||
runParallel [
|
||||
"server", dotnet $"build -tl -c Release -o {distPath} -p:DefineConstants=" serverPath
|
||||
"client", dotnet (fable "-m production") clientPath
|
||||
])
|
||||
|
||||
Target.create "BundleDebug" (fun _ ->
|
||||
[ "server", dotnet $"build -tl -c Debug -o {distPath} -p:DefineConstants=" serverPath
|
||||
"client", dotnet (fable "-m development --minify false --sourcemap true") clientPath ]
|
||||
|> runParallel
|
||||
Trace.log "--- Building Server ---"
|
||||
run dotnet $"build -tl -c Debug -o {distPath} -p:DefineConstants=" serverPath
|
||||
|
||||
Trace.log "--- Building Frontend ---"
|
||||
run dotnet (fable "-m development --minify false --sourcemap true") clientPath
|
||||
)
|
||||
|
||||
Target.create "Pack" (fun _ ->
|
||||
match libPath with
|
||||
| Some p -> run dotnet $"pack -c Release -o \"{packPath}\"" p
|
||||
| None -> ()
|
||||
)
|
||||
| None -> ())
|
||||
|
||||
Target.create "Run" (fun _ ->
|
||||
[ "server", dotnet "watch run" serverPath
|
||||
"client", dotnet fableWatch clientPath ]
|
||||
|> runParallel
|
||||
)
|
||||
runParallel [
|
||||
"server", dotnet "watch run" serverPath
|
||||
"client", dotnet fableWatch clientPath
|
||||
])
|
||||
|
||||
Target.create "Client" (fun _ ->
|
||||
run dotnet fableWatch clientPath
|
||||
)
|
||||
Target.create "Client" (fun _ -> run dotnet fableWatch clientPath)
|
||||
|
||||
Target.create "Format" (fun _ ->
|
||||
run dotnet "fantomas . -r" "src"
|
||||
)
|
||||
Target.create "Format" (fun _ -> run dotnet "fantomas . -r" "src")
|
||||
|
||||
Target.create "Test" (fun _ ->
|
||||
if System.IO.Directory.Exists testPath then
|
||||
[ "server", dotnet "run" (testPath + "/Server")
|
||||
"client", dotnet $"fable -e .jsx -o build --run {vite}" (testPath + "/Client") ]
|
||||
|> runParallel
|
||||
else ()
|
||||
)
|
||||
runParallel [
|
||||
"server", dotnet "run" (testPath + "/Server")
|
||||
"client", dotnet $"fable -e .jsx -o build --run {vite}" (testPath + "/Client")
|
||||
]
|
||||
else
|
||||
())
|
||||
|
||||
open Fake.Core.TargetOperators
|
||||
|
||||
let dependencies = [
|
||||
"Clean"
|
||||
==> "Bundle"
|
||||
"Clean" ==> "InstallClient" ==> "Bundle"
|
||||
|
||||
"Clean"
|
||||
==> "BundleDebug"
|
||||
"Clean" ==> "InstallClient" ==> "BundleDebug"
|
||||
|
||||
"Clean"
|
||||
==> "Test"
|
||||
"Clean" ==> "InstallClient" ==> "Test"
|
||||
|
||||
"Clean"
|
||||
==> "Run"
|
||||
"Clean" ==> "InstallClient" ==> "Run"
|
||||
|
||||
"Clean"
|
||||
==> "Pack"
|
||||
"Clean" ==> "InstallClient" ==> "Pack"
|
||||
|
||||
"Client"
|
||||
]
|
||||
|
||||
[<EntryPoint>]
|
||||
let main args = runOrDefault args
|
||||
let main args = runOrDefault args
|
||||
@@ -6,8 +6,35 @@ let
|
||||
port = 8000;
|
||||
shell = pkgs.callPackage ./../../shell.nix { };
|
||||
in
|
||||
pkgs.mkShellNoCC {
|
||||
pkgs.mkShell rec {
|
||||
inputsFrom = [ shell ];
|
||||
|
||||
packages = [
|
||||
pkgs.rustc
|
||||
pkgs.cargo
|
||||
pkgs.cargo-tauri
|
||||
pkgs.gobject-introspection
|
||||
pkgs.pkg-config
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
pkgs.at-spi2-atk
|
||||
pkgs.atkmm
|
||||
pkgs.cairo
|
||||
pkgs.gdk-pixbuf
|
||||
pkgs.glib
|
||||
pkgs.gtk3
|
||||
pkgs.harfbuzz
|
||||
pkgs.librsvg
|
||||
pkgs.libsoup_3
|
||||
pkgs.pango
|
||||
pkgs.webkitgtk_4_1
|
||||
pkgs.openssl
|
||||
];
|
||||
|
||||
RUST_BACKTRACE = "1";
|
||||
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs;
|
||||
|
||||
LOG_LEVEL = "verbose";
|
||||
REDIS = "localhost:6379";
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
module App
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
open Lit
|
||||
|
||||
open Remoting
|
||||
|
||||
let initSentry = Array.contains window.location.hostname Sentry.hostTargets
|
||||
@@ -11,20 +13,26 @@ if initSentry then
|
||||
console.debug "Pushing to Sentry"
|
||||
Sentry.init ()
|
||||
|
||||
let testAuthenticated () =
|
||||
promise {
|
||||
let! authenticated = authApi.IsAuthenticated() |> Async.StartAsPromise
|
||||
|
||||
if authenticated.IsSome && not (isNullOrUndefined sessionStorage["archive_id"]) then
|
||||
do! Utils.initAtlantisSessionUrls () |> Async.StartAsPromise
|
||||
else
|
||||
do sessionStorage.removeItem "archive_id"
|
||||
do console.info("Redirecting to /atlas.html")
|
||||
|
||||
return ()
|
||||
}
|
||||
|
||||
[<LitElement("init-app")>]
|
||||
let InitApp () =
|
||||
let _ = LitElement.init (fun cfg -> cfg.useShadowDom <- false)
|
||||
|
||||
Hook.useEffectOnce (fun () ->
|
||||
async {
|
||||
let! authenticated = authApi.IsAuthenticated()
|
||||
if authenticated.IsSome && not (isNullOrUndefined sessionStorage["archive_id"]) then
|
||||
do! Utils.initAtlantisSessionUrls ()
|
||||
window.location.href <- "/map.html"
|
||||
else
|
||||
sessionStorage.removeItem "archive_id"
|
||||
window.location.href <- "/atlas.html"
|
||||
return ()
|
||||
} |> Async.StartImmediate
|
||||
testAuthenticated ()
|
||||
|> Promise.start
|
||||
)
|
||||
Lit.nothing
|
||||
|
||||
Lit.nothing
|
||||
@@ -9,11 +9,11 @@ open Fable.OpenLayers.Event
|
||||
open Feliz.prop
|
||||
open Lit
|
||||
open Lit.Elmish
|
||||
open Remoting
|
||||
|
||||
open Archmaester.Dto
|
||||
open Atlantis.Types
|
||||
open Maps
|
||||
open Remoting
|
||||
|
||||
importSideEffects "../public/style.scss"
|
||||
importSideEffects "@spectrum-web-components/action-button/sp-action-button.js"
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
module App
|
||||
|
||||
open Archmaester
|
||||
open Archmaester.Dto
|
||||
open Browser
|
||||
open Fable.Remoting.Client
|
||||
open Lit
|
||||
|
||||
let archmaester =
|
||||
Remoting.createApi ()
|
||||
|> Remoting.withRouteBuilder Api.apiRouteBuilder
|
||||
|> Remoting.buildProxy<Api.Inventory>
|
||||
|
||||
let fetchArchives modelAreaId callback =
|
||||
async {
|
||||
let! res = archmaester.getArchive modelAreaId
|
||||
|
||||
match res with
|
||||
| Error err -> console.error $"Fetch archives error: {err}"
|
||||
| Ok archives -> Some [| archives |] |> callback
|
||||
}
|
||||
|> Async.StartImmediate
|
||||
|
||||
let fetchModelAreas callback =
|
||||
async {
|
||||
let! res = archmaester.getModelAreaArchives (HelloWorld, ArchiveType.FromString "*:*:*")
|
||||
|
||||
match res with
|
||||
| Error err -> console.error $"Fetch model areas error: {err}"
|
||||
| Ok modelAreas -> Some modelAreas |> callback
|
||||
}
|
||||
|
||||
[<LitElement("archive-listing")>]
|
||||
let ArchiveListing () =
|
||||
let _, _ = LitElement.init (fun init -> init.useShadowDom <- false)
|
||||
|
||||
let (modelAreas: ArchiveProps[] option), setModelAreas = Hook.useState None
|
||||
|
||||
Hook.useEffectOnce (fun _ -> fetchModelAreas setModelAreas |> Async.StartImmediate)
|
||||
|
||||
let archiveId (a: Archmaester.Dto.ArchiveProps) = a.archiveId.ToString ()
|
||||
let archiveFiles files =
|
||||
let fileEntry (fileName, _) = html $"""<li>{fileName}</li>"""
|
||||
files |> Array.sortBy fst |> Lit.mapUnique fst fileEntry
|
||||
|
||||
let archiveOwners (acl: ArchiveAcl option) =
|
||||
let owners =
|
||||
match acl with
|
||||
| Some x -> x.users
|
||||
| None -> [||]
|
||||
let userEntry name = html $"""<li>{name}</li>"""
|
||||
let users' = owners |> Array.map userEntry |> Lit.ofArray
|
||||
|
||||
if Array.isEmpty owners then
|
||||
Lit.nothing
|
||||
else
|
||||
html
|
||||
$"""
|
||||
<span>Owners:</span>
|
||||
<div class="overflow-y-scroll">
|
||||
<ul class="list-disc list-inside">
|
||||
{users'}
|
||||
</ul>
|
||||
</div>
|
||||
"""
|
||||
|
||||
let archiveUsers (acl: ArchiveAcl option) =
|
||||
let users =
|
||||
match acl with
|
||||
| Some x -> x.users
|
||||
| None -> [||]
|
||||
let userEntry name = html $"""<li>{name}</li>"""
|
||||
let users' = users |> Array.map userEntry |> Lit.ofArray
|
||||
|
||||
if Array.isEmpty users then
|
||||
Lit.nothing
|
||||
else
|
||||
html
|
||||
$"""
|
||||
<span>Users:</span>
|
||||
<div class="overflow-y-scroll">
|
||||
<ul class="list-disc list-inside">
|
||||
{users'}
|
||||
</ul>
|
||||
</div>
|
||||
"""
|
||||
|
||||
let archiveGroups (acl: ArchiveAcl option) =
|
||||
let groups =
|
||||
match acl with
|
||||
| Some x -> x.users
|
||||
| None -> [||]
|
||||
let groupEntry name = html $"""<li>{name}</li>"""
|
||||
let groups' = groups |> Array.map groupEntry |> Lit.ofArray
|
||||
|
||||
if Array.isEmpty groups then
|
||||
Lit.nothing
|
||||
else
|
||||
html
|
||||
$"""
|
||||
<span>Groups:</span>
|
||||
<div class="overflow-y-scroll max-h-96">
|
||||
<ul class="list-disc list-inside">
|
||||
{groups'}
|
||||
</ul>
|
||||
</div>
|
||||
"""
|
||||
|
||||
let archiveItem (item: ArchiveProps) =
|
||||
html
|
||||
$"""
|
||||
<div class="card w-full shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">
|
||||
{item.name}
|
||||
<div class="badge badge-secondary">{item.archiveType}</div>
|
||||
</h2>
|
||||
<h3>Start date: {item.startTime.ToShortDateString ()} {item.startTime.ToShortTimeString ()}</h3>
|
||||
<span>Projection: {item.projection}</span>
|
||||
{{archiveOwners item.acl}}
|
||||
{{archiveUsers item.acl}}
|
||||
{{archiveGroups item.acl}}
|
||||
<h4>Start date: {item.startTime}</h4>
|
||||
<h4>End date: {item.endTime}</h4>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
|
||||
let archiveName archiveName =
|
||||
html
|
||||
$"""
|
||||
<p>{archiveName}</p>
|
||||
"""
|
||||
|
||||
let modelAreaItem (item: ArchiveProps) =
|
||||
// let archiveList =
|
||||
// Array.map archiveName item.archiveType
|
||||
html
|
||||
$"""
|
||||
<div class="card w-full shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">
|
||||
{item.name}
|
||||
</h2>
|
||||
{item}
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
|
||||
let modelAreaList =
|
||||
match modelAreas with
|
||||
| None -> html $"""<progress class="progress w-56"></progress>"""
|
||||
| Some [||] -> html $"""<h1>No ModelAreas</h1>"""
|
||||
| Some models ->
|
||||
html
|
||||
$"""
|
||||
{models |> Lit.mapUnique (fun m -> m.name) modelAreaItem}
|
||||
"""
|
||||
|
||||
html
|
||||
$"""
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
{modelAreaList}
|
||||
</div>
|
||||
"""
|
||||
@@ -1,20 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Version>6.20.0</Version>
|
||||
<RootNamespace>Archivist</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="input.css" />
|
||||
<Content Include="index.html" />
|
||||
<Compile Include="App.fs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fable.Lit" Version="1.4.2" />
|
||||
<PackageReference Include="Fable.Remoting.Client" Version="7.32.0" />
|
||||
<PackageReference Update="FSharp.Core" Version="9.0.201" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\Interfaces\Archmaester\Archmaester.Api.fsproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,42 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Fable</title>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" href="fable.ico" />
|
||||
<link href="./build/client/style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<!-- navbar -->
|
||||
<div class="navbar bg-base-300">
|
||||
<div class="lg:hidden">
|
||||
<label for="drawer-toggle" class="btn btn-square btn-ghost">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="inline-block w-6 h-6 stroke-current"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path></svg>
|
||||
</label>
|
||||
</div>
|
||||
<div class="px-2 mx-2">
|
||||
Archmeister
|
||||
</div>
|
||||
</div>
|
||||
<div class="drawer drawer-mobile">
|
||||
<input id="drawer-toggle" type="checkbox" class="drawer-toggle">
|
||||
<div class="drawer-content">
|
||||
<!-- content -->
|
||||
<div class="flex justify-center">
|
||||
<archive-listing></archive-listing>
|
||||
</div>
|
||||
</div>
|
||||
<div class="drawer-side">
|
||||
<label for="drawer-toggle" class="drawer-overlay"></label>
|
||||
<ul class="menu p-4 w-80 bg-base-100 text-base-content">
|
||||
<li><a>Models</a></li>
|
||||
<li><a>Archives</a></li>
|
||||
<li><a>Groups</a></li>
|
||||
<li><a>Users</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="./build/App.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,3 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
dotnet fable watch -o build/client --run vite -c ../../vite.config.js
|
||||
@@ -21,7 +21,8 @@
|
||||
<PackageReference Update="FSharp.Core" Version="9.0.201"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="catalog\Catalog.fsproj"/>
|
||||
<ProjectReference Include="Atlas\Atlas.fsproj"/>
|
||||
<ProjectReference Include="Mapster\Mapster.fsproj"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
35
src/Atlantis/src/Client/catalog/Catalog.fsproj
Normal file
@@ -0,0 +1,35 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Version>6.20.0</Version>
|
||||
<RootNamespace>Archivist</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Utils.fs" />
|
||||
<Compile Include="Map.fs" />
|
||||
<Compile Include="carbon/components/Header.fs" />
|
||||
<Compile Include="carbon/Oceanography.fs" />
|
||||
<Compile Include="carbon/Home.fs" />
|
||||
<Compile Include="carbon/Carbon.fs" />
|
||||
<Compile Include="carbon/Index.fs" />
|
||||
<Compile Include="mui/Mui.fs" />
|
||||
<Compile Include="mui/Index.fs" />
|
||||
<Compile Include="fluentui/Archives.fs" />
|
||||
<Compile Include="fluentui/Oceanography.fs" />
|
||||
<Compile Include="fluentui/FluentUI.fs" />
|
||||
<Compile Include="fluentui/Index.fs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fable.Browser.Url" Version="1.4.0" />
|
||||
<PackageReference Include="Fable.Core" Version="4.5.0" />
|
||||
<PackageReference Include="Fable.OpenLayers" Version="2.18.0" />
|
||||
<PackageReference Include="Fable.Remoting.Client" Version="7.32.0" />
|
||||
<PackageReference Update="FSharp.Core" Version="9.0.201" />
|
||||
<PackageReference Include="Feliz" Version="2.9.0" />
|
||||
<PackageReference Include="Feliz.Router" Version="4.0.0" />
|
||||
<PackageReference Include="Feliz.UseMediaQuery" Version="1.5.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Lib\Lib.fsproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
27
src/Atlantis/src/Client/catalog/Map.fs
Normal file
@@ -0,0 +1,27 @@
|
||||
module Oceanbox.Catalog.Map
|
||||
|
||||
open Browser
|
||||
open Fable.OpenLayers
|
||||
|
||||
let create () : unit =
|
||||
let map =
|
||||
let osmLayer : Layer =
|
||||
Layer.tileLayer [
|
||||
layer.source (Source.osm [])
|
||||
]
|
||||
let view =
|
||||
View.view [
|
||||
view.center [| 0; 0 |]
|
||||
view.zoom 2
|
||||
]
|
||||
|
||||
OlMap.map [
|
||||
map.layers [|
|
||||
osmLayer
|
||||
|]
|
||||
map.view view
|
||||
]
|
||||
do map.setTarget "map"
|
||||
do console.debug("Create map %o", map)
|
||||
|
||||
()
|
||||
17
src/Atlantis/src/Client/catalog/Utils.fs
Normal file
@@ -0,0 +1,17 @@
|
||||
module Oceanbox.Catalog.Utils
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
open Feliz
|
||||
|
||||
let inline toReact (elem: JSX.Element) : ReactElement = unbox elem
|
||||
let inline toStyle (styles: IStyleAttribute seq) : obj = createObj (unbox styles)
|
||||
|
||||
[<Emit("Object.entries($0)")>]
|
||||
let inline spreadStyles object : IStyleAttribute array = jsNative
|
||||
|
||||
let toLocaleString (date: System.DateTime) : string =
|
||||
let jsDate = unbox<JS.Date> date
|
||||
|
||||
jsDate.toLocaleString()
|
||||
43
src/Atlantis/src/Client/catalog/carbon/Carbon.fs
Normal file
@@ -0,0 +1,43 @@
|
||||
module Oceanbox.Catalog.Carbon.App
|
||||
|
||||
open System
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
open Fable.OpenLayers
|
||||
open Feliz
|
||||
|
||||
let private Content: obj = import "Content" "@carbon/react"
|
||||
|
||||
let private BuoyIcon: obj = import "Buoy" "@carbon/icons-react"
|
||||
|
||||
type Page =
|
||||
| Home
|
||||
| Oceanography
|
||||
|
||||
[<JSX.Component>]
|
||||
let View () =
|
||||
let isOpen, setOpen = React.useState false
|
||||
let currentPage, setPage = React.useState Home
|
||||
|
||||
let page =
|
||||
match currentPage with
|
||||
| Home -> Home.View ()
|
||||
| Oceanography -> Oceanography.View ()
|
||||
|
||||
let handleNavigate (str: string) ev =
|
||||
console.info("Navigate from header: %s, %o", str, ev)
|
||||
match str with
|
||||
| "home" -> setPage Home
|
||||
| "oceanography" -> setPage Oceanography
|
||||
| _ -> console.error("Invalid page from navigation callback: %s", str)
|
||||
|
||||
JSX.html $"""
|
||||
<>
|
||||
{Header.MainHeader handleNavigate}
|
||||
<Content>
|
||||
{page}
|
||||
</Content>
|
||||
</>
|
||||
"""
|
||||
77
src/Atlantis/src/Client/catalog/carbon/Home.fs
Normal file
@@ -0,0 +1,77 @@
|
||||
module Oceanbox.Catalog.Carbon.Home
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
open Fable.OpenLayers
|
||||
open Feliz
|
||||
|
||||
open Oceanbox
|
||||
|
||||
let private Button: obj = import "Button" "@carbon/react"
|
||||
let private Column: obj = import "Column" "@carbon/react"
|
||||
let private Grid: obj = import "Grid" "@carbon/react"
|
||||
|
||||
let private AddIcon: obj = import "Add" "@carbon/react/icons"
|
||||
|
||||
[<JSX.Component>]
|
||||
let View () =
|
||||
React.useEffectOnce (fun () ->
|
||||
console.debug("Mounting Home")
|
||||
do Catalog.Map.create ()
|
||||
()
|
||||
)
|
||||
|
||||
JSX.html $"""
|
||||
<Grid className="home-grid" fullWidth>
|
||||
<Column
|
||||
sm={4}
|
||||
md={8}
|
||||
lg={ {| span = 16; offset = 4; |} }
|
||||
xlg={ {| span = 16; offset = 3; |} }
|
||||
max={ {| span = 16; offset = 2; |} }
|
||||
>
|
||||
<h2>Carbon</h2>
|
||||
</Column>
|
||||
|
||||
<Column
|
||||
sm={4}
|
||||
md={8}
|
||||
lg={ {| span = 16; offset = 4; |} }
|
||||
xlg={ {| span = 16; offset = 3; |} }
|
||||
max={ {| span = 16; offset = 2; |} }
|
||||
>
|
||||
<Grid>
|
||||
<Column sm={4} md={8} lg={16} max={4}>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Rhoncus dolor purus non
|
||||
enim praesent elementum facilisis leo vel. Risus at ultrices mi tempus
|
||||
imperdiet. Semper risus in hendrerit gravida rutrum quisque non tellus.
|
||||
Convallis convallis tellus id interdum velit laoreet id donec ultrices.
|
||||
Odio morbi quis commodo odio aenean sed adipiscing. Amet nisl suscipit
|
||||
adipiscing bibendum est ultricies integer quis. Cursus euismod quis viverra
|
||||
nibh cras. Metus vulputate eu scelerisque felis imperdiet proin fermentum
|
||||
leo. Mauris commodo quis imperdiet massa tincidunt. Cras tincidunt lobortis
|
||||
feugiat vivamus at augue. At augue eget arcu dictum varius duis at
|
||||
consectetur lorem. Velit sed ullamcorper morbi tincidunt. Lorem donec massa
|
||||
sapien faucibus et molestie ac.
|
||||
</p>
|
||||
</Column>
|
||||
<Column sm={4} md={8} lg={16} max={12}>
|
||||
<div id="map"></div>
|
||||
</Column>
|
||||
</Grid>
|
||||
</Column>
|
||||
|
||||
<Column
|
||||
sm={4}
|
||||
lg={ {| span = 6; offset = 4; |} }
|
||||
xlg={ {| span = 16; offset = 3; |} }
|
||||
max={ {| span = 16; offset = 2; |} }
|
||||
>
|
||||
<Button size="sm" kind="secondary">Cancel</Button>
|
||||
<Button size="sm" renderIcon={AddIcon}>Hello, Carbon!</Button>
|
||||
</Column>
|
||||
</Grid>
|
||||
"""
|
||||
24
src/Atlantis/src/Client/catalog/carbon/Index.fs
Normal file
@@ -0,0 +1,24 @@
|
||||
module Oceanbox.Catalog.Carbon.Index
|
||||
|
||||
open System
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
open Feliz
|
||||
|
||||
open Oceanbox.Catalog
|
||||
|
||||
let React : obj = importAll "react"
|
||||
|
||||
|
||||
let root = ReactDOM.createRoot (document.getElementById "root")
|
||||
root.render (
|
||||
JSX.html
|
||||
$"""
|
||||
<React.StrictMode>
|
||||
{App.View () |> Utils.toReact}
|
||||
</React.StrictMode>
|
||||
"""
|
||||
|> Utils.toReact
|
||||
)
|
||||
35
src/Atlantis/src/Client/catalog/carbon/Oceanography.fs
Normal file
@@ -0,0 +1,35 @@
|
||||
module Oceanbox.Catalog.Carbon.Oceanography
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
open Fable.OpenLayers
|
||||
open Feliz
|
||||
|
||||
open Oceanbox
|
||||
|
||||
let private Column: obj = import "Column" "@carbon/react"
|
||||
let private Grid: obj = import "Grid" "@carbon/react"
|
||||
|
||||
[<JSX.Component>]
|
||||
let View () =
|
||||
React.useEffectOnce (fun () ->
|
||||
console.debug("Mounting Oceanography")
|
||||
do Catalog.Map.create ()
|
||||
|
||||
()
|
||||
)
|
||||
|
||||
JSX.html $"""
|
||||
<Grid className="oceanography-grid" narrow>
|
||||
<Column
|
||||
sm={4}
|
||||
md={8}
|
||||
lg={ {| span = 16; offset = 4; |} }
|
||||
xlg={ {| span = 16; offset = 3; |} }
|
||||
max={ {| span = 16; offset = 2; |} }
|
||||
>
|
||||
<div id="map"></div>
|
||||
</Column>
|
||||
</Grid>
|
||||
"""
|
||||
118
src/Atlantis/src/Client/catalog/carbon/components/Header.fs
Normal file
@@ -0,0 +1,118 @@
|
||||
module Oceanbox.Catalog.Carbon.Header
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
open Feliz
|
||||
|
||||
let private CarbonHeader: obj = import "Header" "@carbon/react"
|
||||
let private HeaderContainer: obj = import "HeaderContainer" "@carbon/react"
|
||||
let private HeaderGlobalAction: obj = import "HeaderGlobalAction" "@carbon/react"
|
||||
let private HeaderGlobalBar: obj = import "HeaderGlobalBar" "@carbon/react"
|
||||
let private HeaderMenuButton: obj = import "HeaderMenuButton" "@carbon/react"
|
||||
let private HeaderMenuItem: obj = import "HeaderMenuItem" "@carbon/react"
|
||||
let private HeaderName: obj = import "HeaderName" "@carbon/react"
|
||||
let private HeaderNavigation: obj = import "HeaderNavigation" "@carbon/react"
|
||||
let private HeaderSideNavItems: obj = import "HeaderSideNavItems" "@carbon/react"
|
||||
let private SideNav: obj = import "SideNav" "@carbon/react"
|
||||
let private SideNavItems: obj = import "SideNavItems" "@carbon/react"
|
||||
let private SideNavLink: obj = import "SideNavLink" "@carbon/react"
|
||||
let private SideNavDivider: obj = import "SideNavDivider" "@carbon/react"
|
||||
let private SideNavMenu: obj = import "SideNavMenu" "@carbon/react"
|
||||
let private SideNavMenuItem: obj = import "SideNavMenuItem" "@carbon/react"
|
||||
let private SkipToContent: obj = import "SkipToContent" "@carbon/react"
|
||||
|
||||
let private BuoyIcon: obj = import "Buoy" "@carbon/icons-react"
|
||||
let private HomeIcon: obj = import "Home" "@carbon/icons-react"
|
||||
let private IbmCloudHpcIcon: obj = import "IbmCloudHpc" "@carbon/icons-react"
|
||||
let private NotificationIcon: obj = import "Notification" "@carbon/icons-react"
|
||||
let private SwitcherIcon: obj = import "Switcher" "@carbon/icons-react"
|
||||
|
||||
let private urlHashtag (str: string) : string =
|
||||
let url = URL.Create(str)
|
||||
console.debug("URI: %s, hash: %s", url, url.hash)
|
||||
|
||||
url.hash
|
||||
|
||||
[<JSX.Component>]
|
||||
let MainHeader (navigate: string -> obj -> unit) =
|
||||
let currentPage = urlHashtag document.URL
|
||||
|
||||
let inner props =
|
||||
let isSideNavExpanded = props?isSideNavExpanded
|
||||
let onClickSideNavExpand = props?onClickSideNavExpand
|
||||
|
||||
JSX.html $"""
|
||||
<Header aria-label="Main header">
|
||||
<SkipToContent />
|
||||
<HeaderMenuButton
|
||||
aria-label="Open menu"
|
||||
isActive={isSideNavExpanded}
|
||||
onClick={onClickSideNavExpand}
|
||||
/>
|
||||
<HeaderName href="/catalog" prefix="IO">
|
||||
Oceanbox
|
||||
</HeaderName>
|
||||
<HeaderNavigation aria-label="Navigation">
|
||||
<HeaderMenuItem href="/">Atlantis</HeaderMenuItem>
|
||||
<HeaderMenuItem href="/catalog">Home</HeaderMenuItem>
|
||||
<HeaderMenuItem href="../mui/index.html">Mui</HeaderMenuItem>
|
||||
<HeaderMenuItem href="index.html">Carbon</HeaderMenuItem>
|
||||
<HeaderMenuItem href="../fluentui/index.html">FluentUI</HeaderMenuItem>
|
||||
</HeaderNavigation>
|
||||
|
||||
<HeaderGlobalBar>
|
||||
<HeaderGlobalAction
|
||||
aria-label="Notifications"
|
||||
>
|
||||
<NotificationIcon size={20} />
|
||||
</HeaderGlobalAction>
|
||||
<HeaderGlobalAction
|
||||
aria-label="App switcher"
|
||||
>
|
||||
<SwitcherIcon size={20} />
|
||||
</HeaderGlobalAction>
|
||||
</HeaderGlobalBar>
|
||||
|
||||
<SideNav
|
||||
aria-label="Side navigation"
|
||||
isPersistent={true}
|
||||
expanded={isSideNavExpanded}
|
||||
>
|
||||
<SideNavItems>
|
||||
<HeaderSideNavItems>
|
||||
<HeaderMenuItem href="/">Atlantis</HeaderMenuItem>
|
||||
<HeaderMenuItem href="/catalog">Home</HeaderMenuItem>
|
||||
<HeaderMenuItem href="../mui/index.html">Mui</HeaderMenuItem>
|
||||
<HeaderMenuItem href="index.html">Carbon</HeaderMenuItem>
|
||||
<HeaderMenuItem href="../fluentui/index.html">FluentUI</HeaderMenuItem>
|
||||
</HeaderSideNavItems>
|
||||
<SideNavLink
|
||||
href="#"
|
||||
renderIcon={HomeIcon}
|
||||
isActive={currentPage = ""}
|
||||
onClick={navigate "home"}
|
||||
>
|
||||
Home
|
||||
</SideNavLink>
|
||||
<SideNavLink
|
||||
href="#oceanography"
|
||||
renderIcon={BuoyIcon}
|
||||
isActive={currentPage = "#oceanography"}
|
||||
onClick={navigate "oceanography"}
|
||||
>
|
||||
Oceanography
|
||||
</SideNavLink>
|
||||
<SideNavLink href="#compute" renderIcon={IbmCloudHpcIcon}>
|
||||
Compute
|
||||
</SideNavLink>
|
||||
<SideNavDivider />
|
||||
</SideNavItems>
|
||||
</SideNav>
|
||||
</Header>
|
||||
"""
|
||||
|
||||
JSX.html $"""
|
||||
<HeaderContainer render={inner}>
|
||||
</HeaderContainer>
|
||||
"""
|
||||
26
src/Atlantis/src/Client/catalog/carbon/index.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Fable - Carbon</title>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" href="../react.svg" />
|
||||
<link href="../index.css" rel="stylesheet">
|
||||
<link href="style.scss" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav class="navigation">
|
||||
<a href="/">Atlantis</a>
|
||||
<a href="/catalog">Home</a>
|
||||
<a href="../mui/index.html">Mui</a>
|
||||
<a href="index.html">Carbon</a>
|
||||
<a href="../fluentui/index.html">FluentUI</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<div id="root"></div>
|
||||
|
||||
<script type="module" src="../../build/catalog/carbon/Index.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
35
src/Atlantis/src/Client/catalog/carbon/style.scss
Normal file
@@ -0,0 +1,35 @@
|
||||
/* TODO(simkir): Import only what I use */
|
||||
@use "@carbon/react" with (
|
||||
$font-path: "@ibm/plex"
|
||||
);
|
||||
|
||||
@use "ol/ol";
|
||||
|
||||
html,
|
||||
body,
|
||||
#root,
|
||||
main {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
#map {
|
||||
width: 100%;
|
||||
min-height: 320px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.navigation {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.home-grid {
|
||||
row-gap: 16px;
|
||||
}
|
||||
|
||||
.oceanography-grid {
|
||||
height: 100%;
|
||||
}
|
||||
176
src/Atlantis/src/Client/catalog/fluentui/Archives.fs
Normal file
@@ -0,0 +1,176 @@
|
||||
module Oceanbox.Catalog.FluentUI.Archives
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
open Feliz
|
||||
|
||||
open Oceanbox.Catalog
|
||||
open Remoting
|
||||
|
||||
let private createTableColumn: obj -> unit = import "createTableColumn" "@fluentui/react-components"
|
||||
|
||||
let private Button: obj = import "Button" "@fluentui/react-components"
|
||||
let private DataGrid: obj = import "DataGrid" "@fluentui/react-components"
|
||||
let private DataGridBody: obj = import "DataGridBody" "@fluentui/react-components"
|
||||
let private DataGridCell: obj = import "DataGridCell" "@fluentui/react-components"
|
||||
let private DataGridHeader: obj = import "DataGridHeader" "@fluentui/react-components"
|
||||
let private DataGridHeaderCell: obj = import "DataGridHeaderCell" "@fluentui/react-components"
|
||||
let private DataGridRow: obj = import "DataGridRow" "@fluentui/react-components"
|
||||
let private Dialog: obj = import "Dialog" "@fluentui/react-components"
|
||||
let private DialogActions: obj = import "DialogActions" "@fluentui/react-components"
|
||||
let private DialogBody: obj = import "DialogBody" "@fluentui/react-components"
|
||||
let private DialogContent: obj = import "DialogContent" "@fluentui/react-components"
|
||||
let private DialogSurface: obj = import "DialogSurface" "@fluentui/react-components"
|
||||
let private DialogTitle: obj = import "DialogTitle" "@fluentui/react-components"
|
||||
let private DialogTrigger: obj = import "DialogTrigger" "@fluentui/react-components"
|
||||
let private TableCellLayout: obj = import "TableCellLayout" "@fluentui/react-components"
|
||||
|
||||
type private NameCell = {
|
||||
label: string
|
||||
}
|
||||
|
||||
type private LastUpdatedCell = {
|
||||
timestamp: System.DateTime
|
||||
}
|
||||
|
||||
type private Item = {
|
||||
Name: NameCell
|
||||
LastUpdated: LastUpdatedCell
|
||||
}
|
||||
|
||||
let private items: Item array = [|
|
||||
{ Name = { label = "test" }; LastUpdated = { timestamp = System.DateTime.Now } }
|
||||
{ Name = { label = "test1" }; LastUpdated = { timestamp = System.DateTime.Now } }
|
||||
{ Name = { label = "test2" }; LastUpdated = { timestamp = System.DateTime.Now } }
|
||||
{ Name = { label = "test3" }; LastUpdated = { timestamp = System.DateTime.Now } }
|
||||
|]
|
||||
|
||||
let columns: obj array = [|
|
||||
createTableColumn {|
|
||||
columnId = "Name"
|
||||
renderHeaderCell = fun () -> "Name"
|
||||
renderCell = fun (item: obj) ->
|
||||
JSX.html $"""
|
||||
<TableCellLayout>
|
||||
{item?Name?label}
|
||||
</TableCellLayout>
|
||||
"""
|
||||
|
||||
|}
|
||||
|
||||
createTableColumn {|
|
||||
columnId = "LastUpdated"
|
||||
renderHeaderCell = fun () -> "Last updated"
|
||||
renderCell = fun (item: Item) -> Utils.toLocaleString item.LastUpdated.timestamp
|
||||
|}
|
||||
|]
|
||||
|
||||
let fetchHelloWorldArchive () =
|
||||
let archiveUrl = sessionStorage["archmaester_url"]
|
||||
|
||||
async {
|
||||
if isNullOrUndefined archiveUrl then
|
||||
return None
|
||||
else
|
||||
let api = ArchivesApi archiveUrl
|
||||
|
||||
return Some "hello"
|
||||
}
|
||||
|
||||
let fetchArchives () =
|
||||
async {
|
||||
do! Utils.initAtlantisSessionUrls ()
|
||||
let! _ = fetchHelloWorldArchive ()
|
||||
|
||||
return ()
|
||||
}
|
||||
|
||||
[<JSX.Component>]
|
||||
let Table() =
|
||||
let renderCell (item: obj) (props: obj) =
|
||||
JSX.html $"""
|
||||
<DataGridCell>{props?renderCell item}</DataGridCell>
|
||||
"""
|
||||
|
||||
let renderHeader props =
|
||||
let renderHeaderCell: unit -> obj = props?renderHeaderCell
|
||||
|
||||
JSX.html $"""
|
||||
<DataGridHeaderCell>{renderHeaderCell()}</DataGridHeaderCell>
|
||||
"""
|
||||
|
||||
let renderRow row =
|
||||
let item = row?item
|
||||
let rowId: int = row?rowId
|
||||
|
||||
JSX.html $"""
|
||||
<DataGridRow
|
||||
key={rowId}
|
||||
>
|
||||
{renderCell item}
|
||||
</DataGridRow>
|
||||
"""
|
||||
|
||||
JSX.html $"""
|
||||
<DataGrid
|
||||
items={items}
|
||||
columns={columns}
|
||||
getRowId={fun item -> item?Name?label}
|
||||
style={{{{minWidth: "550px"}}}}
|
||||
>
|
||||
<DataGridHeader>
|
||||
<DataGridRow>
|
||||
{renderHeader}
|
||||
</DataGridRow>
|
||||
</DataGridHeader>
|
||||
|
||||
<DataGridBody>
|
||||
{renderRow}
|
||||
</DataGridBody>
|
||||
</DataGrid>
|
||||
"""
|
||||
|
||||
[<JSX.Component>]
|
||||
let private DialogTest () =
|
||||
JSX.html """
|
||||
<Dialog>
|
||||
<DialogTrigger disableButtonEnchancement>
|
||||
<Button appearance="primary">Dialog</Button>
|
||||
</DialogTrigger>
|
||||
<DialogSurface>
|
||||
<DialogBody>
|
||||
<DialogTitle>Dialog Title</DialogTitle>
|
||||
<DialogContent>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Rhoncus dolor purus non enim praesent elementum facilisis leo vel. Risus at ultrices mi tempus imperdiet. Semper risus in hendrerit gravida rutrum quisque non tellus. Convallis convallis tellus id interdum velit laoreet id donec ultrices. Odio morbi quis commodo odio aenean sed adipiscing. Amet nisl suscipit adipiscing bibendum est ultricies integer quis. Cursus euismod quis viverra nibh cras. Metus vulputate eu scelerisque felis imperdiet proin fermentum leo. Mauris commodo quis imperdiet massa tincidunt. Cras tincidunt lobortis feugiat vivamus at augue. At augue eget arcu dictum varius duis at consectetur lorem. Velit sed ullamcorper morbi tincidunt. Lorem donec massa sapien faucibus et molestie ac.
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button appearance="primary">Do something</Button>
|
||||
<DialogTrigger disableButtonEnchancement>
|
||||
<Button appearance="secondary">Close</Button>
|
||||
</DialogTrigger>
|
||||
</DialogActions>
|
||||
</DialogBody>
|
||||
</DialogSurface>
|
||||
</Dialog>
|
||||
"""
|
||||
|
||||
[<ReactComponent>]
|
||||
let View () =
|
||||
React.useEffectOnce (fun () ->
|
||||
fetchArchives ()
|
||||
|> Async.StartImmediate
|
||||
)
|
||||
|
||||
Html.div [
|
||||
prop.style [
|
||||
style.padding (length.px 16)
|
||||
]
|
||||
prop.children [
|
||||
Html.h1 "Archives"
|
||||
|
||||
Table() |> Utils.toReact
|
||||
|
||||
DialogTest () |> Utils.toReact
|
||||
]
|
||||
]
|
||||
140
src/Atlantis/src/Client/catalog/fluentui/FluentUI.fs
Normal file
@@ -0,0 +1,140 @@
|
||||
module Oceanbox.Catalog.FluentUI.App
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
open Feliz
|
||||
open Feliz.UseMediaQuery
|
||||
open Feliz.Router
|
||||
|
||||
open Oceanbox.Catalog
|
||||
|
||||
let private webLightTheme: obj = import "webLightTheme" "@fluentui/react-components"
|
||||
let private makeStyles: obj -> obj = import "makeStyles" "@fluentui/react-components"
|
||||
let private bundleIcon: obj -> obj = import "bundleIcon" "@fluentui/react-icons"
|
||||
|
||||
let private AppItem: obj = import "AppItem" "@fluentui/react-components"
|
||||
let private Button: obj = import "Button" "@fluentui/react-components"
|
||||
let private FluentProvider: obj = import "FluentProvider" "@fluentui/react-components"
|
||||
let private Hamburger: obj = import "Hamburger" "@fluentui/react-components"
|
||||
let private NavDrawer: obj = import "NavDrawer" "@fluentui/react-components"
|
||||
let private NavDrawerBody: obj = import "NavDrawerBody" "@fluentui/react-components"
|
||||
let private NavDrawerHeader: obj = import "NavDrawerHeader" "@fluentui/react-components"
|
||||
let private NavDivider: obj = import "NavDivider" "@fluentui/react-components"
|
||||
let private NavItem: obj = import "NavItem" "@fluentui/react-components"
|
||||
let private Tooltip: obj = import "Tooltip" "@fluentui/react-components"
|
||||
|
||||
let private WaterRegularIcon: obj = import "Water20Regular" "@fluentui/react-icons"
|
||||
let private ArchiveRegularIcon: obj = import "Archive20Regular" "@fluentui/react-icons"
|
||||
|
||||
let private useStyles: obj = makeStyles {|
|
||||
root = {|
|
||||
height = "100%"
|
||||
flexGrow = "1"
|
||||
|}
|
||||
appIcon = {|
|
||||
width = "32px"
|
||||
height = "32px"
|
||||
|}
|
||||
navDrawer = {|
|
||||
borderRight = "2px solid gainsboro"
|
||||
|}
|
||||
portalContainer = {|
|
||||
position = "fixed"
|
||||
top = "0.5em"
|
||||
left = "2.5em"
|
||||
|}
|
||||
|}
|
||||
|
||||
[<JSX.Component>]
|
||||
let View () =
|
||||
let styles: obj = emitJsExpr () "useStyles()"
|
||||
|
||||
let responsive = React.useResponsive ()
|
||||
|
||||
let currentUrl, updateUrl = React.useState(Router.currentUrl())
|
||||
|
||||
// TODO(simkir): Close nav when smaller screen
|
||||
let isOpen, setOpen = React.useState true
|
||||
|
||||
let screenLarge =
|
||||
responsive = ScreenSize.WideScreen
|
||||
|| responsive = ScreenSize.Desktop
|
||||
|| responsive = ScreenSize.Tablet
|
||||
|
||||
console.debug("Router currentUrl: %o", currentUrl)
|
||||
|
||||
let router =
|
||||
React.router [
|
||||
router.onUrlChanged updateUrl
|
||||
router.children [
|
||||
match currentUrl with
|
||||
| [ "oceanography" ] -> Oceanography.View isOpen (fun () -> setOpen true) |> Utils.toReact
|
||||
| [ "archives" ] -> Archives.View()
|
||||
| otherwise -> Html.h1 "404 Not found"
|
||||
]
|
||||
]
|
||||
|
||||
let pageId =
|
||||
match currentUrl with
|
||||
| [ "oceanography" ] -> "1"
|
||||
| [ "archives" ] -> "2"
|
||||
| otherwise -> "1"
|
||||
|
||||
JSX.html $"""
|
||||
<FluentProvider id="fluent-provider" className={styles?provider} theme={webLightTheme}>
|
||||
<NavDrawer
|
||||
className={styles?navDrawer}
|
||||
open={screenLarge && isOpen}
|
||||
type="inline"
|
||||
position="start"
|
||||
selectedValue={pageId}
|
||||
>
|
||||
<NavDrawerHeader>
|
||||
<Tooltip relationship="label" content="Close navigation">
|
||||
<Hamburger onClick={fun () -> setOpen (not isOpen)} />
|
||||
</Tooltip>
|
||||
</NavDrawerHeader>
|
||||
|
||||
<NavDrawerBody>
|
||||
<AppItem as="a" href="/">
|
||||
<img className={styles?appIcon} src="../ob.svg"></img>
|
||||
Oceanbox hmr test
|
||||
</AppItem>
|
||||
<AppItem as="a" href="/catalog">
|
||||
Home
|
||||
</AppItem>
|
||||
<AppItem as="a" href="../mui/index.html">
|
||||
Mui
|
||||
</AppItem>
|
||||
<AppItem as="a" href="../carbon/index.html">
|
||||
Carbon
|
||||
</AppItem>
|
||||
<AppItem as="a" href="index.html">
|
||||
FluentUI
|
||||
</AppItem>
|
||||
|
||||
<NavDivider />
|
||||
|
||||
<NavItem
|
||||
value="1"
|
||||
icon={{<WaterRegularIcon />}}
|
||||
onClick={fun () -> Router.navigate "oceanography"}
|
||||
>
|
||||
Oceanography
|
||||
</NavItem>
|
||||
<NavItem
|
||||
value="2"
|
||||
icon={{<ArchiveRegularIcon />}}
|
||||
onClick={fun () -> Router.navigate "archives"}
|
||||
>
|
||||
Archives
|
||||
</NavItem>
|
||||
</NavDrawerBody>
|
||||
</NavDrawer>
|
||||
|
||||
<main className={styles?root}>
|
||||
{router}
|
||||
</main>
|
||||
</FluentProvider>
|
||||
"""
|
||||
21
src/Atlantis/src/Client/catalog/fluentui/Index.fs
Normal file
@@ -0,0 +1,21 @@
|
||||
module Oceanbox.Catalog.FluentUI.Index
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
open Feliz
|
||||
|
||||
open Oceanbox.Catalog
|
||||
|
||||
let React : obj = importAll "react"
|
||||
|
||||
let root = ReactDOM.createRoot (document.getElementById "root")
|
||||
root.render (
|
||||
JSX.html
|
||||
$"""
|
||||
<React.StrictMode>
|
||||
{App.View () |> Utils.toReact}
|
||||
</React.StrictMode>
|
||||
"""
|
||||
|> Utils.toReact
|
||||
)
|
||||
60
src/Atlantis/src/Client/catalog/fluentui/Oceanography.fs
Normal file
@@ -0,0 +1,60 @@
|
||||
module Oceanbox.Catalog.FluentUI.Oceanography
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
open Fable.OpenLayers
|
||||
open Feliz
|
||||
|
||||
open Oceanbox
|
||||
|
||||
let private makeStyles: obj -> obj = import "makeStyles" "@fluentui/react-components"
|
||||
|
||||
let private Button: obj = import "Button" "@fluentui/react-components"
|
||||
let private Portal: obj = import "Portal" "@fluentui/react-components"
|
||||
|
||||
let private WindowColumnOneFourthLeftFocusLeftFilledIcon: obj = import "WindowColumnOneFourthLeftFocusLeftFilled" "@fluentui/react-icons"
|
||||
|
||||
let private useStyles: obj = makeStyles {|
|
||||
portalContainer = {|
|
||||
position = "fixed"
|
||||
top = "0.5em"
|
||||
left = "2.5em"
|
||||
|}
|
||||
|}
|
||||
|
||||
[<JSX.Component>]
|
||||
let View sideNavOpen onClick =
|
||||
let styles: obj = emitJsExpr () "useStyles()"
|
||||
|
||||
let mountNode, setMountNode = React.useState<Types.HTMLElement option> None
|
||||
|
||||
let mapBackButton =
|
||||
if sideNavOpen then
|
||||
JSX.nothing
|
||||
else
|
||||
JSX.html $"""
|
||||
<Portal mountNode={mountNode}>
|
||||
<div className={styles?portalContainer}>
|
||||
<Button
|
||||
icon={{<WindowColumnOneFourthLeftFocusLeftFilled />}}
|
||||
onClick={onClick}
|
||||
>
|
||||
</Button>
|
||||
</div>
|
||||
</Portal>
|
||||
"""
|
||||
|
||||
React.useEffectOnce (fun () ->
|
||||
console.debug("Mounting Oceanography")
|
||||
do Catalog.Map.create ()
|
||||
|
||||
()
|
||||
)
|
||||
|
||||
JSX.html $"""
|
||||
<>
|
||||
<div id="map" ref={setMountNode}></div>
|
||||
{mapBackButton}
|
||||
</>
|
||||
"""
|
||||
24
src/Atlantis/src/Client/catalog/fluentui/index.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Fable - FluentUI</title>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" href="../react.svg" />
|
||||
<link href="../index.css" rel="stylesheet">
|
||||
<link href="style.scss" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<nav id="catalog-nav">
|
||||
<a href="/">Atlantis</a>
|
||||
<a href="/catalog">Home</a>
|
||||
<a href="../mui/index.html">Mui</a>
|
||||
<a href="../carbon/index.html">Carbon</a>
|
||||
<a href="index.html">FluentUI</a>
|
||||
</nav>
|
||||
|
||||
<div id="root"></div>
|
||||
|
||||
<script type="module" src="../../build/catalog/fluentui/Index.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
26
src/Atlantis/src/Client/catalog/fluentui/style.scss
Normal file
@@ -0,0 +1,26 @@
|
||||
@use "ol/ol";
|
||||
|
||||
html, body, #root, #fluent-provider {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
main {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#catalog-nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div #fluent-provider {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#map {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
11
src/Atlantis/src/Client/catalog/index.css
Normal file
@@ -0,0 +1,11 @@
|
||||
nav {
|
||||
width: 100%;
|
||||
|
||||
background-color: white;
|
||||
|
||||
border-bottom: solid gainsboro;
|
||||
}
|
||||
|
||||
main {
|
||||
padding: 8px;
|
||||
}
|
||||
25
src/Atlantis/src/Client/catalog/index.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Catalog</title>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" href="react.svg" />
|
||||
<link href="index.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav class="navigation">
|
||||
<a href="/">Atlantis</a>
|
||||
<a href="/catalog">Home</a>
|
||||
<a href="/catalog/mui/index.html">Mui</a>
|
||||
<a href="/catalog/carbon/index.html">Carbon</a>
|
||||
<a href="/catalog/fluentui/index.html">FluentUI</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<p>Welcome to this oceanbox playground. Click on one of the component libraries to test their feel and look</p>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
25
src/Atlantis/src/Client/catalog/mui/Index.fs
Normal file
@@ -0,0 +1,25 @@
|
||||
module Oceanbox.Catalog.Mui.Index
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
open Feliz
|
||||
|
||||
open Oceanbox.Catalog
|
||||
|
||||
importAll "react"
|
||||
|
||||
import "StyledEngineProvider" "@mui/material/styles"
|
||||
|
||||
let root = ReactDOM.createRoot (document.getElementById "root")
|
||||
root.render (
|
||||
JSX.html
|
||||
$"""
|
||||
<react.StrictMode>
|
||||
<StyledEngineProvider injectFirst>
|
||||
{App.View () |> Utils.toReact}
|
||||
</StyledEngineProvider>
|
||||
</react.StrictMode>
|
||||
"""
|
||||
|> Utils.toReact
|
||||
)
|
||||
292
src/Atlantis/src/Client/catalog/mui/Mui.fs
Normal file
@@ -0,0 +1,292 @@
|
||||
module Oceanbox.Catalog.Mui.App
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
open Feliz
|
||||
|
||||
open Oceanbox.Catalog
|
||||
|
||||
importSideEffects "@fontsource/roboto/300.css"
|
||||
importSideEffects "@fontsource/roboto/400.css"
|
||||
importSideEffects "@fontsource/roboto/500.css"
|
||||
importSideEffects "@fontsource/roboto/700.css"
|
||||
|
||||
let private MuiAppBar: obj = importDefault "@mui/material/AppBar"
|
||||
importDefault "@mui/material/Box"
|
||||
importDefault "@mui/material/Button"
|
||||
importDefault "@mui/material/CssBaseline"
|
||||
importDefault "@mui/material/Divider"
|
||||
importDefault "@mui/material/Drawer"
|
||||
importDefault "@mui/material/IconButton"
|
||||
importDefault "@mui/material/List"
|
||||
importDefault "@mui/material/ListItem"
|
||||
importDefault "@mui/material/ListItemButton"
|
||||
importDefault "@mui/material/ListItemIcon"
|
||||
importDefault "@mui/material/ListItemText"
|
||||
importDefault "@mui/material/Toolbar"
|
||||
importDefault "@mui/material/Typography"
|
||||
|
||||
// NOTE: Renaming the import without mangling the name
|
||||
let private ChevronRightIcon: obj = importDefault "@mui/icons-material/ChevronRight"
|
||||
let private MenuIcon: obj = importDefault "@mui/icons-material/Menu"
|
||||
let private StorageIcon: obj = importDefault "@mui/icons-material/Storage"
|
||||
let private WaterIcon: obj = importDefault "@mui/icons-material/Water"
|
||||
let private QueryStatsIcon: obj = importDefault "@mui/icons-material/QueryStats"
|
||||
|
||||
let private ThemeProvider: obj = import "ThemeProvider" "@mui/material/styles"
|
||||
let private createTheme: obj -> unit = import "createTheme" "@mui/material/styles"
|
||||
let private useTheme: unit -> unit = import "useTheme" "@mui/material/styles"
|
||||
let private styled (comp: string) : obj -> unit = import "styled" "@mui/material/styles"
|
||||
let private styledWithOptions (comp: string) (options: obj) : obj -> unit = import "styled" "@mui/material/styles"
|
||||
|
||||
type Style =
|
||||
[<Import("styled", "@mui/material/styles")>]
|
||||
static member inline styled(comp: string, ?options: obj) : obj -> obj = jsNative
|
||||
|
||||
[<Import("styled", "@mui/material/styles")>]
|
||||
static member inline styled(comp: obj, ?options: obj) : obj -> obj = jsNative
|
||||
|
||||
let private drawerWidth = 260
|
||||
|
||||
let private darkTheme =
|
||||
createTheme (createObj [ "palette" ==> createObj [ "mode" ==> "light" ] ])
|
||||
|
||||
let private MyComponent =
|
||||
Style.styled
|
||||
("div", {| shouldForwardProp = fun prop -> prop <> "open" |})
|
||||
(Utils.toStyle [
|
||||
style.color "darkslategray"
|
||||
style.backgroundColor "aliceblue"
|
||||
style.padding 8
|
||||
style.borderRadius 4
|
||||
])
|
||||
|
||||
let private Main =
|
||||
styledWithOptions "main" {| shouldForwardProp = fun prop -> prop <> "open" |} (fun (props: obj) ->
|
||||
let theme = props?theme
|
||||
Utils.toStyle [
|
||||
style.flexGrow 1
|
||||
style.padding (props?theme?spacing 3 |> unbox<Styles.ICssUnit>)
|
||||
style.custom (
|
||||
"transition", props?theme?transitions?create("margin", createObj [
|
||||
"easing" ==> theme?transitions?easing?sharp
|
||||
"duration" ==> theme?transitions?duration?leavingScreen
|
||||
])
|
||||
)
|
||||
style.marginLeft (length.px -drawerWidth)
|
||||
style.custom (
|
||||
"variants", [|
|
||||
createObj [
|
||||
"props" ==> fun props -> props?``open``
|
||||
"style" ==> Utils.toStyle [
|
||||
style.custom (
|
||||
"transition", props?theme?transitions?create("margin", createObj [
|
||||
"easing" ==> theme?transitions?easing?easeOut
|
||||
"duration" ==> theme?transitions?duration?enteringScreen
|
||||
])
|
||||
)
|
||||
style.marginLeft 0
|
||||
]
|
||||
]
|
||||
|]
|
||||
)
|
||||
])
|
||||
|
||||
let private AppBar =
|
||||
let f (props: obj) =
|
||||
let theme = props?theme
|
||||
|
||||
Utils.toStyle [
|
||||
style.custom (
|
||||
"transition", props?theme?transitions?create(("margin", "width"), createObj [
|
||||
"easing" ==> theme?transitions?easing?sharp
|
||||
"duration" ==> theme?transitions?duration?leavingScreen
|
||||
])
|
||||
)
|
||||
style.custom (
|
||||
"variants", [|
|
||||
createObj [
|
||||
"props" ==> fun props -> props?``open``
|
||||
"style" ==> Utils.toStyle [
|
||||
style.width (length.calc $"100%% - {drawerWidth}px")
|
||||
style.marginLeft (length.px drawerWidth)
|
||||
style.custom (
|
||||
"transition", props?theme?transitions?create(("margin", "width"), createObj [
|
||||
"easing" ==> theme?transitions?easing?easeOut
|
||||
"duration" ==> theme?transitions?duration?enteringScreen
|
||||
])
|
||||
)
|
||||
]
|
||||
]
|
||||
|]
|
||||
)
|
||||
]
|
||||
|
||||
Style.styled(MuiAppBar, {| shouldForwardProp = fun prop -> prop <> "open" |}) f
|
||||
|
||||
let private DrawerHeader: unit =
|
||||
styled "div" (fun (props: obj) ->
|
||||
let theme: obj = props?theme
|
||||
let toolbar = Utils.spreadStyles theme?mixins?toolbar
|
||||
let style = [|
|
||||
style.display.flex
|
||||
style.alignItems.center
|
||||
style.justifyContent.flexEnd
|
||||
style.padding (theme?spacing (0, 1) |> unbox<Styles.ICssUnit>)
|
||||
|]
|
||||
|
||||
console.debug("[Mui] Styled DrawerHeader theme %o, toolbar: %o", theme, toolbar)
|
||||
|
||||
// NOTE(simkir): Not sure how to do spreading in a nice way. If you do `yield!` Fable turns the expression lazy,
|
||||
// kinda.
|
||||
Utils.toStyle (Array.append style toolbar))
|
||||
|
||||
let pages = [|
|
||||
"/", "Atlantis"
|
||||
"/catalog/index.html", "Home"
|
||||
"index.html", "Mui"
|
||||
"../carbon/index.html", "Carbon"
|
||||
"../fluentui/index.html", "FluentUI"
|
||||
|]
|
||||
|
||||
[<JSX.Component>]
|
||||
let View () =
|
||||
let theme = useTheme ()
|
||||
|
||||
let isOpen, setOpen = React.useState false
|
||||
|
||||
let handleDrawerOpen () = setOpen true
|
||||
let handleDrawerClose () = setOpen false
|
||||
|
||||
let linkButton (url: string, str: string) =
|
||||
JSX.html $"""
|
||||
<Button
|
||||
href={url}
|
||||
sx={
|
||||
Utils.toStyle [
|
||||
style.color "white"
|
||||
]
|
||||
}
|
||||
>
|
||||
{str}
|
||||
</Button>
|
||||
"""
|
||||
|
||||
JSX.html
|
||||
$"""
|
||||
<ThemeProvider theme={darkTheme}>
|
||||
<Box sx={Utils.toStyle [ style.display.flex ]}>
|
||||
<CssBaseline />
|
||||
<AppBar position="fixed" open={isOpen}>
|
||||
<Toolbar>
|
||||
<IconButton
|
||||
onClick={handleDrawerOpen}
|
||||
sx={Utils.toStyle [
|
||||
style.custom ("mr", 2)
|
||||
if isOpen then style.display.none
|
||||
]}
|
||||
>
|
||||
<MenuIcon />
|
||||
</IconButton>
|
||||
|
||||
<Typography
|
||||
variant="h5"
|
||||
sx={
|
||||
Utils.toStyle [
|
||||
style.custom ("mr", 2)
|
||||
]
|
||||
}
|
||||
>
|
||||
Oceanbox
|
||||
</Typography>
|
||||
<Box
|
||||
sx={
|
||||
Utils.toStyle [
|
||||
style.flexGrow 1
|
||||
]
|
||||
}
|
||||
>
|
||||
{pages |> Array.map linkButton}
|
||||
</Box>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
|
||||
<Drawer
|
||||
sx={
|
||||
Utils.toStyle [
|
||||
style.width (length.px drawerWidth)
|
||||
style.flexShrink 0
|
||||
style.custom (
|
||||
"& .MuiDrawer-paper",
|
||||
Utils.toStyle [
|
||||
style.width drawerWidth
|
||||
style.boxSizing.borderBox
|
||||
]
|
||||
)
|
||||
]
|
||||
}
|
||||
variant="persistent"
|
||||
anchor="left"
|
||||
open={isOpen}
|
||||
>
|
||||
<DrawerHeader>
|
||||
<IconButton
|
||||
onClick={handleDrawerClose}
|
||||
>
|
||||
<ChevronRightIcon />
|
||||
</IconButton>
|
||||
</DrawerHeader>
|
||||
<Divider />
|
||||
<List>
|
||||
<ListItem key="oceanography" disablePadding>
|
||||
<ListItemButton>
|
||||
<ListItemIcon>
|
||||
<WaterIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Oceanography" />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
<ListItem key="compute" disablePadding>
|
||||
<ListItemButton>
|
||||
<ListItemIcon>
|
||||
<StorageIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Compute" />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
<ListItem key="statistics" disablePadding>
|
||||
<ListItemButton>
|
||||
<ListItemIcon>
|
||||
<QueryStatsIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Statistics" />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
</List>
|
||||
</Drawer>
|
||||
|
||||
<Main open={isOpen}>
|
||||
<DrawerHeader />
|
||||
<Typography >
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Rhoncus dolor purus non
|
||||
enim praesent elementum facilisis leo vel. Risus at ultrices mi tempus
|
||||
imperdiet. Semper risus in hendrerit gravida rutrum quisque non tellus.
|
||||
Convallis convallis tellus id interdum velit laoreet id donec ultrices.
|
||||
Odio morbi quis commodo odio aenean sed adipiscing. Amet nisl suscipit
|
||||
adipiscing bibendum est ultricies integer quis. Cursus euismod quis viverra
|
||||
nibh cras. Metus vulputate eu scelerisque felis imperdiet proin fermentum
|
||||
leo. Mauris commodo quis imperdiet massa tincidunt. Cras tincidunt lobortis
|
||||
feugiat vivamus at augue. At augue eget arcu dictum varius duis at
|
||||
consectetur lorem. Velit sed ullamcorper morbi tincidunt. Lorem donec massa
|
||||
sapien faucibus et molestie ac.
|
||||
</Typography>
|
||||
|
||||
<Button variant="contained">Hello, Mui</Button>
|
||||
|
||||
<MyComponent>Styled div</MyComponent>
|
||||
</Main>
|
||||
</Box>
|
||||
</ThemeProvider>
|
||||
"""
|
||||
26
src/Atlantis/src/Client/catalog/mui/index.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Playground - Mui</title>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" href="../react.svg" />
|
||||
<link href="../index.css" rel="stylesheet">
|
||||
<link href="style.scss" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav class="navigation">
|
||||
<a href="/">Atlantis</a>
|
||||
<a href="/catalog/index.html">Home</a>
|
||||
<a href="index.html">Mui</a>
|
||||
<a href="../carbon/index.html">Carbon</a>
|
||||
<a href="../fluentui/index.html">FluentUI</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<div id="root"></div>
|
||||
|
||||
<script type="module" src="../../build/catalog/mui/Index.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
8
src/Atlantis/src/Client/catalog/mui/style.scss
Normal file
@@ -0,0 +1,8 @@
|
||||
.navigation {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.drawer-header {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
BIN
src/Atlantis/src/Client/catalog/public/ob.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
32
src/Atlantis/src/Client/catalog/public/ob.svg
Normal file
@@ -0,0 +1,32 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 850.39 566.93">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #003f70;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: #7296b7;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<g>
|
||||
<g>
|
||||
<circle class="cls-1" cx="296.72" cy="235.29" r="33.2"/>
|
||||
<circle class="cls-1" cx="338.77" cy="190.14" r="21.65"/>
|
||||
<g>
|
||||
<path class="cls-1" d="M505.8,293.18A66.28,66.28,0,0,0,439.6,227v-48.3a114.5,114.5,0,0,0,0,229v-48.3A66.27,66.27,0,0,0,505.8,293.18Zm-66.2,63a63,63,0,1,1,63-63A63.09,63.09,0,0,1,439.6,356.2Z"/>
|
||||
<g>
|
||||
<path class="cls-2" d="M439.6,185.56v4c57,0,103.38,46.48,103.38,103.61S496.6,396.78,439.6,396.78v4c59.21,0,107.38-48.27,107.38-107.61S498.81,185.56,439.6,185.56Z"/>
|
||||
<path class="cls-2" d="M439.6,192.44v3.86c53.3,0,96.66,43.46,96.66,96.88s-43.36,96.87-96.66,96.87v3.87c55.42,0,100.51-45.19,100.51-100.74S495,192.44,439.6,192.44Z"/>
|
||||
<path class="cls-2" d="M439.6,199.32V203c49.6,0,89.95,40.44,89.95,90.15s-40.35,90.14-89.95,90.14V387c51.64,0,93.65-42.11,93.65-93.86S491.24,199.32,439.6,199.32Z"/>
|
||||
<path class="cls-2" d="M439.6,206.2v3.56a83.42,83.42,0,0,1,0,166.83v3.57a87,87,0,0,0,0-174Z"/>
|
||||
<path class="cls-2" d="M439.6,213.07v3.42a76.69,76.69,0,0,1,0,153.37v3.42a80.11,80.11,0,0,0,0-160.21Z"/>
|
||||
<path class="cls-2" d="M439.6,220v3.27a70,70,0,0,1,0,139.91v3.27a73.23,73.23,0,0,0,0-146.45Z"/>
|
||||
<path class="cls-2" d="M439.6,226.83V230a63.23,63.23,0,0,1,0,126.46v3.12a66.35,66.35,0,0,0,0-132.7Z"/>
|
||||
<path class="cls-2" d="M439.6,178.68h0v4.16h0c60.7,0,110.09,49.5,110.09,110.34S500.3,403.51,439.6,403.51h0v4.16h0c63,0,114.24-51.36,114.24-114.49S502.59,178.68,439.6,178.68Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
9
src/Atlantis/src/Client/catalog/public/react.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-11.5 -10.23174 23 20.46348">
|
||||
<title>React Logo</title>
|
||||
<circle cx="0" cy="0" r="2.05" fill="#61dafb"/>
|
||||
<g stroke="#61dafb" stroke-width="1" fill="none">
|
||||
<ellipse rx="11" ry="4.2"/>
|
||||
<ellipse rx="11" ry="4.2" transform="rotate(60)"/>
|
||||
<ellipse rx="11" ry="4.2" transform="rotate(120)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 366 B |
7
src/Atlantis/src/Client/catalog/public/robots.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
User-agent: Googlebot
|
||||
Disallow: /nogooglebot/
|
||||
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://www.example.com/sitemap.xml
|
||||
3
src/Atlantis/src/Client/catalog/run
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
dotnet fable watch --verbose -e ".jsx" --run bunx --bun vite
|
||||
7
src/Atlantis/src/Client/catalog/src/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
|
||||
# Generated by Tauri
|
||||
# will have schema files for capabilities auto-completion
|
||||
/gen/schemas
|
||||
4667
src/Atlantis/src/Client/catalog/src/Cargo.lock
generated
Normal file
21
src/Atlantis/src/Client/catalog/src/Cargo.toml
Normal file
@@ -0,0 +1,21 @@
|
||||
[package]
|
||||
name = "atlantis"
|
||||
version = "0.1.0"
|
||||
description = "A Tauri App"
|
||||
authors = ["Moritz Jörg"]
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[lib]
|
||||
name = "atlantis_lib"
|
||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2", features = [] }
|
||||
|
||||
[dependencies]
|
||||
tauri = { version = "2", features = [] }
|
||||
tauri-plugin-shell = "2"
|
||||
serde_json = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
3
src/Atlantis/src/Client/catalog/src/build.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "default",
|
||||
"description": "Capability for the main window",
|
||||
"windows": ["main"],
|
||||
"permissions": [
|
||||
"core:default"
|
||||
]
|
||||
}
|
||||
BIN
src/Atlantis/src/Client/catalog/src/icons/128x128.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
src/Atlantis/src/Client/catalog/src/icons/128x128@2x.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
src/Atlantis/src/Client/catalog/src/icons/32x32.png
Normal file
|
After Width: | Height: | Size: 974 B |
BIN
src/Atlantis/src/Client/catalog/src/icons/Square107x107Logo.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
src/Atlantis/src/Client/catalog/src/icons/Square142x142Logo.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
src/Atlantis/src/Client/catalog/src/icons/Square150x150Logo.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
src/Atlantis/src/Client/catalog/src/icons/Square284x284Logo.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
src/Atlantis/src/Client/catalog/src/icons/Square30x30Logo.png
Normal file
|
After Width: | Height: | Size: 903 B |
BIN
src/Atlantis/src/Client/catalog/src/icons/Square310x310Logo.png
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
src/Atlantis/src/Client/catalog/src/icons/Square44x44Logo.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/Atlantis/src/Client/catalog/src/icons/Square71x71Logo.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
src/Atlantis/src/Client/catalog/src/icons/Square89x89Logo.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
src/Atlantis/src/Client/catalog/src/icons/StoreLogo.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
src/Atlantis/src/Client/catalog/src/icons/icon.icns
Normal file
BIN
src/Atlantis/src/Client/catalog/src/icons/icon.ico
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
src/Atlantis/src/Client/catalog/src/icons/icon.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
13
src/Atlantis/src/Client/catalog/src/src/lib.rs
Normal file
@@ -0,0 +1,13 @@
|
||||
#[tauri::command]
|
||||
fn greet(name: &str) -> String {
|
||||
format!("Hello {name}, You have been greeted from Rust!")
|
||||
}
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.invoke_handler(tauri::generate_handler![greet])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
6
src/Atlantis/src/Client/catalog/src/src/main.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
fn main() {
|
||||
atlantis_lib::run()
|
||||
}
|
||||
37
src/Atlantis/src/Client/catalog/src/tauri.conf.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "atlantis",
|
||||
"version": "0.1.0",
|
||||
"identifier": "com.oceanbox.atlantis",
|
||||
"build": {
|
||||
"beforeDevCommand": "./run",
|
||||
"devUrl": "http://localhost:8081",
|
||||
"beforeBuildCommand": "bun run build",
|
||||
"frontendDist": "../"
|
||||
},
|
||||
"app": {
|
||||
"windows": [
|
||||
{
|
||||
"title": "Atlantis",
|
||||
"width": 800,
|
||||
"height": 600,
|
||||
"resizable": true,
|
||||
"fullscreen": false
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": null
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
]
|
||||
}
|
||||
}
|
||||
76
src/Atlantis/src/Client/catalog/vite.config.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import mkcert from "vite-plugin-mkcert"
|
||||
import react from "@vitejs/plugin-react"
|
||||
import { defineConfig } from "vite"
|
||||
|
||||
const certDir = `${process.env.HOME}/.vite-plugin-mkcert`;
|
||||
const host = process.env.TAURI_DEV_HOST;
|
||||
|
||||
const proxy = {
|
||||
target: `http://127.0.0.1:8085/`,
|
||||
changeOrigin: false,
|
||||
secure: false,
|
||||
ws: true
|
||||
};
|
||||
|
||||
export default defineConfig({
|
||||
appType: "mpa",
|
||||
clearScreen: false,
|
||||
plugins: [
|
||||
react(),
|
||||
mkcert({
|
||||
hosts: [
|
||||
"localhost",
|
||||
"*.local.oceanbox.io"
|
||||
],
|
||||
savePath: `${certDir}/certs`,
|
||||
mkcertPath: `${certDir}/mkcert`
|
||||
}),
|
||||
],
|
||||
build: {
|
||||
rollupOptions: {
|
||||
input: {
|
||||
index: "index.html",
|
||||
carbon: "carbon/index.html",
|
||||
mui: "mui/index.html",
|
||||
fluentui: "fluentui/index.html",
|
||||
},
|
||||
},
|
||||
},
|
||||
server: {
|
||||
port: 8081,
|
||||
// host: "0.0.0.0",
|
||||
strictPort: true,
|
||||
https: false,
|
||||
host: host || false,
|
||||
hmr: host
|
||||
? {
|
||||
protocol: "ws",
|
||||
host,
|
||||
port: 8081,
|
||||
}
|
||||
: undefined,
|
||||
// https: true,
|
||||
// cors: true,
|
||||
watch: {
|
||||
// 3. tell Vite to ignore watching `src-tauri` and `fsharp`
|
||||
ignored: [
|
||||
"**/src-tauri/**",
|
||||
"**/*.fs"
|
||||
],
|
||||
},
|
||||
proxy: {
|
||||
'/socket': proxy,
|
||||
"/api": proxy,
|
||||
'/isAuthenticated': proxy,
|
||||
'/signin-oidc': proxy,
|
||||
'/signin': proxy,
|
||||
'/signout': proxy,
|
||||
'/token': proxy,
|
||||
'/claims': proxy,
|
||||
'/impersonate': proxy,
|
||||
'/unimpersonate': proxy,
|
||||
'/hub': proxy,
|
||||
'/barentswatch-token': proxy,
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -21,19 +21,6 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- <script> -->
|
||||
<!-- if (window.location.pathname == "/map") { -->
|
||||
<!-- var app = document.createElement("map-app"); -->
|
||||
<!-- } else if (window.location.pathname == "/atlas") { -->
|
||||
<!-- var app = document.createElement("atlas-app"); -->
|
||||
<!-- } else if (window.location.pathname == "/login") { -->
|
||||
<!-- var app = document.createElement("login-app"); -->
|
||||
<!-- } else { -->
|
||||
<!-- var app = document.createElement("init-app"); -->
|
||||
<!-- }; -->
|
||||
<!-- app.setAttribute("style", "height: 100%;"); -->
|
||||
<!-- document.body.appendChild(app); -->
|
||||
<!-- </script> -->
|
||||
<init-app id="app" style="height: 100%;"></init-app>
|
||||
<script type="module" src="./build/App.jsx"></script>
|
||||
</body>
|
||||
|
||||
@@ -18,78 +18,83 @@ var proxy = {
|
||||
};
|
||||
|
||||
const plugins = [
|
||||
react({jsxRuntime: "automatic"}),
|
||||
mkcert({
|
||||
hosts: [
|
||||
"localhost",
|
||||
"*.local.oceanbox.io"
|
||||
],
|
||||
savePath: `${certDir}/certs`,
|
||||
mkcertPath: `${certDir}/mkcert`
|
||||
}),
|
||||
!process.env.CREATE_SENTRY
|
||||
? null
|
||||
: sentryVitePlugin({
|
||||
org: "oceanbox",
|
||||
project: "atlantis-client",
|
||||
authToken: "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",
|
||||
filesToDeleteAfterUpload: "*",
|
||||
sourcemaps: {
|
||||
ignore: ["../../node_modules/**", "./vite.config.js"]
|
||||
},
|
||||
telemetry: false,
|
||||
}),
|
||||
react({jsxRuntime: "automatic"}),
|
||||
mkcert({
|
||||
hosts: [
|
||||
"localhost",
|
||||
"*.local.oceanbox.io"
|
||||
],
|
||||
savePath: `${certDir}/certs`,
|
||||
mkcertPath: `${certDir}/mkcert`
|
||||
}),
|
||||
!process.env.CREATE_SENTRY
|
||||
? null
|
||||
: sentryVitePlugin({
|
||||
org: "oceanbox",
|
||||
project: "atlantis-client",
|
||||
authToken: "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",
|
||||
filesToDeleteAfterUpload: "*",
|
||||
sourcemaps: {
|
||||
ignore: ["../../node_modules/**", "./vite.config.js"]
|
||||
},
|
||||
telemetry: false,
|
||||
}),
|
||||
];
|
||||
|
||||
export default defineConfig({
|
||||
plugins: plugins,
|
||||
resolve: {
|
||||
alias: {
|
||||
// We're only using a subset from plotly
|
||||
// Add alias to enable typing regardless
|
||||
'plotly.js': resolve(__dirname, './plotly-bundle'),
|
||||
// The bundler file still needs access to the actual plotly module
|
||||
'plotly-dist': resolve(__dirname, '../../node_modules/plotly.js')
|
||||
appType: "mpa",
|
||||
plugins: plugins,
|
||||
resolve: {
|
||||
alias: {
|
||||
// We're only using a subset from plotly
|
||||
// Add alias to enable typing regardless
|
||||
'plotly.js': resolve(__dirname, './plotly-bundle'),
|
||||
// The bundler file still needs access to the actual plotly module
|
||||
'plotly-dist': resolve(__dirname, '../../node_modules/plotly.js')
|
||||
},
|
||||
},
|
||||
define: {
|
||||
global: {},
|
||||
'process.env': {},
|
||||
},
|
||||
build: {
|
||||
rollupOptions: {
|
||||
input: {
|
||||
main: resolve(__dirname, './src/Client/index.html'),
|
||||
atlas: resolve(__dirname, './src/Client/atlas.html'),
|
||||
mapster: resolve(__dirname, './src/Client/map.html'),
|
||||
catalog: resolve(__dirname, "./src/Client/catalog/index.html"),
|
||||
catalogMui: "catalog/mui/index.html",
|
||||
catalogCarbon: "catalog/carbon/index.html",
|
||||
catalogFluentUI: "catalog/fluentui/index.html",
|
||||
},
|
||||
},
|
||||
define: {
|
||||
global: {},
|
||||
'process.env': {},
|
||||
minify: "oxc",
|
||||
},
|
||||
// config options
|
||||
server: {
|
||||
port: clientPort,
|
||||
host: '0.0.0.0',
|
||||
https: true,
|
||||
cors: true,
|
||||
proxy: {
|
||||
'/api': proxy,
|
||||
'/isAuthenticated': proxy,
|
||||
'/signin-oidc': proxy,
|
||||
'/signin': proxy,
|
||||
'/signout': proxy,
|
||||
'/token': proxy,
|
||||
'/claims': proxy,
|
||||
'/impersonate': proxy,
|
||||
'/unimpersonate': proxy,
|
||||
'/hub': proxy,
|
||||
'/barentswatch-token': proxy,
|
||||
'/socket': proxy,
|
||||
},
|
||||
build: {
|
||||
rollupOptions: {
|
||||
input: {
|
||||
main: resolve(__dirname, './src/Client/index.html'),
|
||||
atlas: resolve(__dirname, './src/Client/atlas.html'),
|
||||
mapster: resolve(__dirname, './src/Client/map.html'),
|
||||
},
|
||||
},
|
||||
minify: "oxc",
|
||||
},
|
||||
// config options
|
||||
server: {
|
||||
port: clientPort,
|
||||
host: '0.0.0.0',
|
||||
https: true,
|
||||
cors: true,
|
||||
proxy: {
|
||||
'/api': proxy,
|
||||
'/isAuthenticated': proxy,
|
||||
'/signin-oidc': proxy,
|
||||
'/signin': proxy,
|
||||
'/signout': proxy,
|
||||
'/token': proxy,
|
||||
'/claims': proxy,
|
||||
'/impersonate': proxy,
|
||||
'/unimpersonate': proxy,
|
||||
'/hub': proxy,
|
||||
'/barentswatch-token': proxy,
|
||||
'/socket': proxy,
|
||||
},
|
||||
watch: {
|
||||
ignored: [
|
||||
"**/*.fs" // Don't watch F# files
|
||||
],
|
||||
}
|
||||
watch: {
|
||||
ignored: [
|
||||
"**/*.fs" // Don't watch F# files
|
||||
],
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||