c2vi dash working
This commit is contained in:
1773
Cargo.lock
generated
1773
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
141
flake.nix
141
flake.nix
@@ -35,7 +35,7 @@ let
|
|||||||
];
|
];
|
||||||
wasmCrane = (crane.mkLib pkgs).overrideToolchain wasmToolchain;
|
wasmCrane = (crane.mkLib pkgs).overrideToolchain wasmToolchain;
|
||||||
|
|
||||||
osToolchain = fenix.packages.${system}.nightly.toolchain;
|
osToolchain = fenix.packages.${system}.latest.toolchain;
|
||||||
|
|
||||||
osCrane = (crane.mkLib pkgs).overrideToolchain osToolchain;
|
osCrane = (crane.mkLib pkgs).overrideToolchain osToolchain;
|
||||||
|
|
||||||
@@ -120,11 +120,67 @@ in {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
fileSetForCrate =
|
||||||
default = osCrane.buildPackage {
|
crate:
|
||||||
src = "${self}";
|
pkgs.lib.fileset.toSource {
|
||||||
cargoExtraArgs = "--bin mize --features target-os";
|
root = ./.;
|
||||||
|
fileset = pkgs.lib.fileset.unions [
|
||||||
|
./Cargo.toml
|
||||||
|
./Cargo.lock
|
||||||
|
(craneLib.fileset.commonCargoSources ./packages/marts)
|
||||||
|
(craneLib.fileset.commonCargoSources ./packages/mize)
|
||||||
|
(craneLib.fileset.commonCargoSources ./packages/ppc/spacetimedb)
|
||||||
|
(craneLib.fileset.commonCargoSources ./packages/mme)
|
||||||
|
(craneLib.fileset.commonCargoSources ./packages/vic)
|
||||||
|
(craneLib.fileset.commonCargoSources ./packages/ac_mize_macros)
|
||||||
|
(craneLib.fileset.commonCargoSources crate)
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
ppc = osCrane.buildPackage {
|
||||||
|
src = fileSetForCrate ./packages/ppc;
|
||||||
|
cargoExtraArgs = "-p ppc";
|
||||||
|
nativeBuildInputs = [
|
||||||
|
pkgs.pkg-config
|
||||||
|
pkgs.gobject-introspection
|
||||||
|
pkgs.gobject-introspection.dev
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
git # needed to build spacetimedb as it needs to get it's git hash for setting it's version
|
||||||
|
at-spi2-atk
|
||||||
|
atkmm
|
||||||
|
cairo
|
||||||
|
gdk-pixbuf
|
||||||
|
glib
|
||||||
|
gtk3
|
||||||
|
harfbuzz
|
||||||
|
librsvg
|
||||||
|
libsoup_3
|
||||||
|
pango
|
||||||
|
webkitgtk_4_1
|
||||||
|
openssl
|
||||||
|
wasm-bindgen-cli
|
||||||
|
lld_20
|
||||||
|
xdotool
|
||||||
|
];
|
||||||
|
|
||||||
|
LD_LIBRARY_PATH = with pkgs; pkgs.lib.makeLibraryPath [
|
||||||
|
xdotool
|
||||||
|
webkitgtk_4_1
|
||||||
|
pango
|
||||||
|
openssl
|
||||||
|
at-spi2-atk
|
||||||
|
atkmm
|
||||||
|
cairo
|
||||||
|
gdk-pixbuf
|
||||||
|
glib
|
||||||
|
gtk3
|
||||||
|
harfbuzz
|
||||||
|
librsvg
|
||||||
|
libsoup_3
|
||||||
|
];
|
||||||
|
};
|
||||||
|
#SPACETIMEDB_NIX_BUILD_GIT_COMMIT =
|
||||||
|
|
||||||
wasm = wasmCrane.buildPackage {
|
wasm = wasmCrane.buildPackage {
|
||||||
src = "${self}";
|
src = "${self}";
|
||||||
@@ -213,6 +269,81 @@ in {
|
|||||||
|
|
||||||
|
|
||||||
#default = (mizeLib.buildMizeForSystem system).modules.mize.devShell;
|
#default = (mizeLib.buildMizeForSystem system).modules.mize.devShell;
|
||||||
|
buildShell = pkgs.mkShell {
|
||||||
|
|
||||||
|
MIZE_BUILD_CONFIG = let
|
||||||
|
settingsFormat = pkgs.formats.toml { };
|
||||||
|
in settingsFormat.generate "mize-build-config.toml" {
|
||||||
|
config = {
|
||||||
|
namespace = "mize.buildtime.ns";
|
||||||
|
module_url = "c2vi.dev";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
shellHook = ''
|
||||||
|
mize_project_root=$(${pkgs.lib.getExe pkgs.git} rev-parse --show-toplevel)
|
||||||
|
export MIZE_CONFIG_FILES=$mize_project_root/mize_config.toml
|
||||||
|
'';
|
||||||
|
nativeBuildInputs = [
|
||||||
|
pkgs.wasm-pack
|
||||||
|
pkgs.pkg-config
|
||||||
|
pkgs.gobject-introspection
|
||||||
|
pkgs.gobject-introspection.dev
|
||||||
|
|
||||||
|
# thanks to: https://github.com/NixOS/nixpkgs/pull/496279/changes
|
||||||
|
(pkgs.buildWasmBindgenCli rec {
|
||||||
|
src = pkgs.fetchCrate {
|
||||||
|
pname = "wasm-bindgen-cli";
|
||||||
|
version = "0.2.114";
|
||||||
|
hash = "sha256-xrCym+rFY6EUQFWyWl6OPA+LtftpUAE5pIaElAIVqW0=";
|
||||||
|
};
|
||||||
|
|
||||||
|
cargoDeps = pkgs.rustPlatform.fetchCargoVendor {
|
||||||
|
inherit src;
|
||||||
|
inherit (src) pname version;
|
||||||
|
hash = "sha256-Z8+dUXPQq7S+Q7DWNr2Y9d8GMuEdSnq00quUR0wDNPM=";
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(fenix.packages.${system}.combine [
|
||||||
|
fenix.packages.${system}.latest.toolchain
|
||||||
|
fenix.packages.${system}.targets.wasm32-unknown-unknown.latest.toolchain
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
at-spi2-atk
|
||||||
|
atkmm
|
||||||
|
cairo
|
||||||
|
gdk-pixbuf
|
||||||
|
glib
|
||||||
|
gtk3
|
||||||
|
harfbuzz
|
||||||
|
librsvg
|
||||||
|
libsoup_3
|
||||||
|
pango
|
||||||
|
webkitgtk_4_1
|
||||||
|
openssl
|
||||||
|
wasm-bindgen-cli
|
||||||
|
lld_20
|
||||||
|
xdotool
|
||||||
|
];
|
||||||
|
|
||||||
|
LD_LIBRARY_PATH = with pkgs; pkgs.lib.makeLibraryPath [
|
||||||
|
xdotool
|
||||||
|
webkitgtk_4_1
|
||||||
|
pango
|
||||||
|
openssl
|
||||||
|
at-spi2-atk
|
||||||
|
atkmm
|
||||||
|
cairo
|
||||||
|
gdk-pixbuf
|
||||||
|
glib
|
||||||
|
gtk3
|
||||||
|
harfbuzz
|
||||||
|
librsvg
|
||||||
|
libsoup_3
|
||||||
|
];
|
||||||
|
|
||||||
|
};
|
||||||
default = pkgs.mkShell {
|
default = pkgs.mkShell {
|
||||||
|
|
||||||
MIZE_BUILD_CONFIG = let
|
MIZE_BUILD_CONFIG = let
|
||||||
|
|||||||
19
md
19
md
@@ -2,7 +2,7 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
MIZE_SRC="/home/me/work/mize" # hardcoded for now
|
MIZE_SRC="/home/me/work/mize" # hardcoded for now
|
||||||
RSYNC_EXCLUDES="--exclude=.git --exclude=node_modules --exclude=target --exclude=mize_config.toml --exclude=rust_dist --exclude=deno_dist --exclude=dist --exclude=result --exclude=pkg"
|
RSYNC_EXCLUDES="--exclude=node_modules --exclude=target --exclude=mize_config.toml --exclude=rust_dist --exclude=deno_dist --exclude=dist --exclude=result --exclude=pkg"
|
||||||
|
|
||||||
function main {
|
function main {
|
||||||
if [[ "$1" == "dlu" ]]; then
|
if [[ "$1" == "dlu" ]]; then
|
||||||
@@ -23,13 +23,22 @@ function deploy_lush {
|
|||||||
echo "c2vi: Deploying to lush..."
|
echo "c2vi: Deploying to lush..."
|
||||||
|
|
||||||
# Copy files to lush
|
# Copy files to lush
|
||||||
rsync -r -u -v --delete --mkpath $RSYNC_EXCLUDES $MIZE_SRC/* lush:here/mize
|
rsync -r -u -v -a --delete --include=".git/" --include=".git/**" --mkpath $RSYNC_EXCLUDES $MIZE_SRC lush:here
|
||||||
|
|
||||||
# compile
|
# compile
|
||||||
ssh lush nix develop /home/me/here/mize --impure -v -L -c sh -c "cargo build --release --manifest-path /home/me/here/mize/packages/ppc/Cargo.toml"
|
ssh lush << EOF
|
||||||
|
if ! tmux has-session -t ppc-deploy 2>/dev/null; then
|
||||||
|
echo "Created new tmux session...."
|
||||||
|
tmux new-session -d -s ppc-deploy "nix develop git+file:///home/me/here/mize#buildShell"
|
||||||
|
tmux send-keys -t ppc-deploy "cargo build --featuers desktop --manifest-path /home/me/here/mize/packages/ppc/Cargo.toml" Enter
|
||||||
|
tmux send-keys -t ppc-deploy "systemctl --user restart ppc" Enter
|
||||||
|
else
|
||||||
|
echo "using existing session..."
|
||||||
|
tmux send-keys -t ppc-deploy "cargo build --features desktop --manifest-path /home/me/here/mize/packages/ppc/Cargo.toml" Enter
|
||||||
|
tmux send-keys -t ppc-deploy "systemctl --user restart ppc" Enter
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
|
||||||
# restart service
|
|
||||||
ssh lush "sudo systemctl restart ppc"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function deploy_main_website {
|
function deploy_main_website {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ futures = "0.3.32"
|
|||||||
mize = { path = "../mize/", default-features = false }
|
mize = { path = "../mize/", default-features = false }
|
||||||
tokio = "1.49.0"
|
tokio = "1.49.0"
|
||||||
# https://github.com/rscarson/rustyscript/pull/415
|
# https://github.com/rscarson/rustyscript/pull/415
|
||||||
rustyscript = { git = 'https://github.com/rscarson/rustyscript', rev = 'e39529eac2c5d37cfcbb7d7d63da7264d7a5afdb', optional = true }
|
#rustyscript = { git = 'https://github.com/rscarson/rustyscript', rev = 'e39529eac2c5d37cfcbb7d7d63da7264d7a5afdb', optional = true }
|
||||||
#deno_core = { version = "0.380.1", optional = true }
|
#deno_core = { version = "0.380.1", optional = true }
|
||||||
chrono = "0.4.44"
|
chrono = "0.4.44"
|
||||||
reqwest = { version = "0.13.2", features = ["blocking", "json"] }
|
reqwest = { version = "0.13.2", features = ["blocking", "json"] }
|
||||||
@@ -22,7 +22,7 @@ dioxus = { version = "0.7.1", optional = true }
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["target-os", "desktop", "server"]
|
default = ["target-os", "desktop", "server"]
|
||||||
target-os = [ "clap", "mize/target-os", "rustyscript", "rusqlite", "dioxus" ]
|
target-os = [ "clap", "mize/target-os", "rusqlite", "dioxus" ]
|
||||||
desktop = ["dioxus/desktop"]
|
desktop = ["dioxus/desktop"]
|
||||||
server = []
|
server = []
|
||||||
target-js = [ "mize/target-js" ]
|
target-js = [ "mize/target-js" ]
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ pub fn c2vi(mize: &mut Mize) -> MizeResult<()> {
|
|||||||
pub fn c2vi_client(mize: &mut Mize) -> MizeResult<()> {
|
pub fn c2vi_client(mize: &mut Mize) -> MizeResult<()> {
|
||||||
//let storage_path = mize.get_config("c2vi.local_storage_path")?.as_
|
//let storage_path = mize.get_config("c2vi.local_storage_path")?.as_
|
||||||
let storage_path = "/home/me/work/app-data/ppc";
|
let storage_path = "/home/me/work/app-data/ppc";
|
||||||
println!("storage_path: {}", storage_path);
|
//println!("storage_path: {}", storage_path);
|
||||||
let db_path = std::path::PathBuf::from(&storage_path).join("data.db");
|
let db_path = std::path::PathBuf::from(&storage_path).join("data.db");
|
||||||
let conn = Connection::open(&db_path)
|
let conn = Connection::open(&db_path)
|
||||||
.map_err(|e| mize_err!("Failed to open C2vi database at {:?}: {}", db_path, e))?;
|
.map_err(|e| mize_err!("Failed to open C2vi database at {:?}: {}", db_path, e))?;
|
||||||
|
|||||||
@@ -51,14 +51,11 @@ pub fn gather_config(mize: &mut Mize) -> MizeResult<()> {
|
|||||||
println!("reading config file: {config_file_path}");
|
println!("reading config file: {config_file_path}");
|
||||||
let content = std::fs::read_to_string(config_file_path)?;
|
let content = std::fs::read_to_string(config_file_path)?;
|
||||||
let mut data = ItemData::from_toml(content.as_str())?;
|
let mut data = ItemData::from_toml(content.as_str())?;
|
||||||
println!("config data: {data}");
|
|
||||||
for path in data.get_paths_recursive()? {
|
for path in data.get_paths_recursive()? {
|
||||||
let mut conf_name = path.replace("/", ".");
|
let mut conf_name = path.replace("/", ".");
|
||||||
if conf_name.starts_with(".") {
|
if conf_name.starts_with(".") {
|
||||||
conf_name.remove(0);
|
conf_name.remove(0);
|
||||||
}
|
}
|
||||||
println!("adding config {conf_name} from config file {config_file_path}");
|
|
||||||
println!("path: {:?}", path);
|
|
||||||
let val = data.get_path(path.split("/").filter(|s| s != &"").collect::<Vec<&str>>())?;
|
let val = data.get_path(path.split("/").filter(|s| s != &"").collect::<Vec<&str>>())?;
|
||||||
match config_opts.get_mut(&conf_name) {
|
match config_opts.get_mut(&conf_name) {
|
||||||
Some(opt) => {
|
Some(opt) => {
|
||||||
|
|||||||
@@ -869,7 +869,7 @@ impl Mize {
|
|||||||
|
|
||||||
// get the cached value
|
// get the cached value
|
||||||
if let Some(val) = opt.val.clone() {
|
if let Some(val) = opt.val.clone() {
|
||||||
println!("get_config: {name} has cached value: {val}");
|
//println!("get_config: {name} has cached value: {val}");
|
||||||
return Ok(val);
|
return Ok(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ path = "lib.rs"
|
|||||||
name = "ppc"
|
name = "ppc"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["target-os", "server", "client"]
|
default = ["target-os", "server", "client", "desktop"]
|
||||||
target-os = [ "clap", "mize/target-os", "marts/target-os", "tracing", "webbrowser", "base64", "serde_json", "serde" ]
|
target-os = [ "clap", "mize/target-os", "marts/target-os", "tracing", "webbrowser", "base64", "serde_json", "serde" ]
|
||||||
target-obsidian = [ "js-sys", "wasm-bindgen", "mize/target-js", "marts/target-js", "base64", "serde_json", "serde", "openidconnect", "dioxus", "dioxus-web", "web-sys", "web-sys/Document", "dioxus/web" ]
|
target-obsidian = [ "js-sys", "wasm-bindgen", "mize/target-js", "marts/target-js", "base64", "serde_json", "serde", "openidconnect", "dioxus", "dioxus-web", "web-sys", "web-sys/Document", "dioxus/web" ]
|
||||||
server = [ "axum", "axum-extra", "openidconnect", "serde", "serde_json", "reqwest", "rand", "url", "time", "tokio", "dioxus/ssr", "dioxus/server", "dioxus/fullstack", "dioxus/router", "dioxus-ssr", "html-escape", "axum-oidc", "tower", "tower-sessions", "marts/server", "target-os" ]
|
server = [ "axum", "axum-extra", "openidconnect", "serde", "serde_json", "reqwest", "rand", "url", "time", "tokio", "dioxus/ssr", "dioxus/server", "dioxus/fullstack", "dioxus/router", "dioxus-ssr", "html-escape", "axum-oidc", "tower", "tower-sessions", "marts/server", "target-os" ]
|
||||||
|
|||||||
@@ -3,17 +3,19 @@ use base64::{
|
|||||||
alphabet::STANDARD,
|
alphabet::STANDARD,
|
||||||
engine::{DecodePaddingMode, GeneralPurpose, GeneralPurposeConfig},
|
engine::{DecodePaddingMode, GeneralPurpose, GeneralPurposeConfig},
|
||||||
};
|
};
|
||||||
|
use dioxus::{fullstack::ClientResponse, html::ol};
|
||||||
use mize::{Mize, MizeError, MizePart, MizeResult, item::ItemData, mize_err, mize_part};
|
use mize::{Mize, MizeError, MizePart, MizeResult, item::ItemData, mize_err, mize_part};
|
||||||
use openidconnect::{
|
use openidconnect::{
|
||||||
AuthorizationCode, ClientId, CsrfToken, DeviceAuthorizationResponse,
|
AccessToken, AuthorizationCode, ClientId, CsrfToken, DeviceAuthorizationResponse,
|
||||||
EmptyExtraDeviceAuthorizationFields, IssuerUrl, Nonce, OAuth2TokenResponse, PkceCodeChallenge,
|
EmptyExtraDeviceAuthorizationFields, IssuerUrl, Nonce, OAuth2TokenResponse, PkceCodeChallenge,
|
||||||
PkceCodeVerifier, RedirectUrl, RefreshToken, Scope,
|
PkceCodeVerifier, RedirectUrl, RefreshToken, Scope, TokenResponse,
|
||||||
core::{CoreAuthenticationFlow, CoreClient, CoreProviderMetadata},
|
core::{CoreAuthenticationFlow, CoreClient, CoreProviderMetadata},
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
io::{self, Write},
|
io::{self, Write},
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
|
thread,
|
||||||
};
|
};
|
||||||
|
|
||||||
// console_log macro
|
// console_log macro
|
||||||
@@ -45,7 +47,7 @@ pub struct ClientAuth {
|
|||||||
secrets: Option<ClientSecrets>,
|
secrets: Option<ClientSecrets>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Serialize, Deserialize)]
|
#[derive(Default, Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct ClientSecrets {
|
pub struct ClientSecrets {
|
||||||
id_token: String,
|
id_token: String,
|
||||||
access_token: String,
|
access_token: String,
|
||||||
@@ -79,23 +81,64 @@ impl ClientAuth {
|
|||||||
}
|
}
|
||||||
Ok(&self.secrets.as_ref().unwrap().refresh_token)
|
Ok(&self.secrets.as_ref().unwrap().refresh_token)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn refresh(&mut self) -> MizeResult<()> {
|
||||||
|
let secrets = self.secrets.clone().ok_or(mize_err!(
|
||||||
|
"no client secrets, meaning the refresh thread can't use the refresh token"
|
||||||
|
))?;
|
||||||
|
self.mize.spawn_async_blocking(
|
||||||
|
"auth.refresh_flow",
|
||||||
|
refresh_flow(self.mize.clone(), secrets),
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start_refresh_thread(&mut self) -> MizeResult<()> {
|
||||||
|
let mut mize_clone = self.mize.clone();
|
||||||
|
self.mize.spawn_background("auth.refresh", move || {
|
||||||
|
loop {
|
||||||
|
thread::sleep(Duration::from_hours(23));
|
||||||
|
let mut auth = mize_clone.get_part_native::<ClientAuth>("auth")?;
|
||||||
|
auth.refresh()?;
|
||||||
|
drop(auth);
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn client_auth(mize: &mut Mize) -> MizeResult<()> {
|
pub fn client_auth(mize: &mut Mize) -> MizeResult<()> {
|
||||||
let mize_clone = mize.clone();
|
let mize_clone = mize.clone();
|
||||||
|
|
||||||
let secrets = match read_secrets(mize) {
|
let mut secrets = match read_secrets(mize) {
|
||||||
Ok(secrets) => Some(secrets),
|
Ok(secrets) => Some(secrets),
|
||||||
Err(_) => None,
|
Err(err) => {
|
||||||
|
println!("err reading secrets: {:?}", err);
|
||||||
|
None
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "target-os")]
|
#[cfg(feature = "target-os")]
|
||||||
{
|
{
|
||||||
let mut cli = mize.get_part_native::<marts::CliPart>("cli")?;
|
let mut cli = mize.get_part_native::<marts::CliPart>("cli")?;
|
||||||
cli.subcommand(Command::new("login"), |_, mut mize| {
|
cli.subcommand(Command::new("login"), |_, mut mize| {
|
||||||
let secrets = mize.spawn_async_blocking("client_auth", auth_flow(mize_clone))?;
|
|
||||||
write_secrets(&mut mize, &secrets)?;
|
|
||||||
let mut auth = mize.get_part_native::<ClientAuth>("client_auth")?;
|
let mut auth = mize.get_part_native::<ClientAuth>("client_auth")?;
|
||||||
|
println!("secrets: {:?}", auth.secrets);
|
||||||
|
let secrets = if auth.secrets.is_some() {
|
||||||
|
match mize.spawn_async_blocking(
|
||||||
|
"client_auth",
|
||||||
|
refresh_flow(mize.clone(), auth.secrets.clone().unwrap()),
|
||||||
|
) {
|
||||||
|
Ok(secrets) => secrets,
|
||||||
|
Err(err) => {
|
||||||
|
println!("err refreshing secrets: {:?}", err);
|
||||||
|
mize.spawn_async_blocking("client_auth", auth_flow(mize_clone))?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mize.spawn_async_blocking("client_auth", auth_flow(mize_clone))?
|
||||||
|
};
|
||||||
|
write_secrets(&mut mize, &secrets)?;
|
||||||
auth.secrets = Some(secrets);
|
auth.secrets = Some(secrets);
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
@@ -104,6 +147,16 @@ pub fn client_auth(mize: &mut Mize) -> MizeResult<()> {
|
|||||||
#[cfg(feature = "target-obsidian")]
|
#[cfg(feature = "target-obsidian")]
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
// check if login token is stil valid refresh if not
|
||||||
|
/*
|
||||||
|
if secrets.is_some() {
|
||||||
|
secrets = Some(mize.spawn_async_blocking(
|
||||||
|
"client_auth",
|
||||||
|
refresh_flow(mize.clone(), secrets.clone().unwrap()),
|
||||||
|
)?);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
mize.register_part(Box::new(ClientAuth {
|
mize.register_part(Box::new(ClientAuth {
|
||||||
secrets,
|
secrets,
|
||||||
mize: mize.clone(),
|
mize: mize.clone(),
|
||||||
@@ -143,13 +196,79 @@ struct Combined<'a> {
|
|||||||
state: &'a str,
|
state: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use openidconnect::DeviceAuthorizationUrl;
|
||||||
use openidconnect::reqwest::Client as HttpClient;
|
use openidconnect::reqwest::Client as HttpClient;
|
||||||
use openidconnect::{AuthUrl, DeviceAuthorizationUrl};
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::time::sleep;
|
|
||||||
|
async fn refresh_flow(mut mize: Mize, old_secrets: ClientSecrets) -> MizeResult<ClientSecrets> {
|
||||||
|
println!("Refresh flow...");
|
||||||
|
let issuer = mize.get_config("auth.client.issuer")?.value_string()?;
|
||||||
|
let client_id = mize.get_config("auth.client.client_id")?.value_string()?;
|
||||||
|
|
||||||
|
let issuer = IssuerUrl::new(issuer)?;
|
||||||
|
let client_id = ClientId::new(client_id);
|
||||||
|
|
||||||
|
let http_client = HttpClient::new();
|
||||||
|
|
||||||
|
// Teach openidconnect-rs about the device authorization url.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
struct MyExtraProviderMetadata {
|
||||||
|
device_authorization_endpoint: String,
|
||||||
|
}
|
||||||
|
use openidconnect::AdditionalProviderMetadata;
|
||||||
|
use openidconnect::ProviderMetadata;
|
||||||
|
use openidconnect::core::{
|
||||||
|
CoreAuthDisplay, CoreClaimName, CoreClaimType, CoreClient, CoreClientAuthMethod,
|
||||||
|
CoreDeviceAuthorizationResponse, CoreGrantType, CoreJsonWebKey, CoreJsonWebKeyType,
|
||||||
|
CoreJsonWebKeyUse, CoreJweContentEncryptionAlgorithm, CoreJweKeyManagementAlgorithm,
|
||||||
|
CoreJwsSigningAlgorithm, CoreResponseMode, CoreResponseType, CoreSubjectIdentifierType,
|
||||||
|
};
|
||||||
|
impl AdditionalProviderMetadata for MyExtraProviderMetadata {}
|
||||||
|
type MyProviderMetadata = ProviderMetadata<
|
||||||
|
MyExtraProviderMetadata,
|
||||||
|
CoreAuthDisplay,
|
||||||
|
CoreClientAuthMethod,
|
||||||
|
CoreClaimName,
|
||||||
|
CoreClaimType,
|
||||||
|
CoreGrantType,
|
||||||
|
CoreJweContentEncryptionAlgorithm,
|
||||||
|
CoreJweKeyManagementAlgorithm,
|
||||||
|
CoreJsonWebKey,
|
||||||
|
CoreResponseMode,
|
||||||
|
CoreResponseType,
|
||||||
|
CoreSubjectIdentifierType,
|
||||||
|
>;
|
||||||
|
|
||||||
|
// Discover provider metadata
|
||||||
|
let provider_metadata: MyProviderMetadata =
|
||||||
|
MyProviderMetadata::discover_async(issuer, &http_client).await?;
|
||||||
|
|
||||||
|
let device_auth_url = provider_metadata
|
||||||
|
.additional_metadata()
|
||||||
|
.device_authorization_endpoint
|
||||||
|
.clone();
|
||||||
|
|
||||||
|
let client = CoreClient::from_provider_metadata(
|
||||||
|
provider_metadata,
|
||||||
|
client_id,
|
||||||
|
None, // public client
|
||||||
|
)
|
||||||
|
.set_device_authorization_url(DeviceAuthorizationUrl::new(device_auth_url)?);
|
||||||
|
|
||||||
|
let refresh_token = RefreshToken::new(old_secrets.refresh_token);
|
||||||
|
let res = client
|
||||||
|
.exchange_refresh_token(&refresh_token)?
|
||||||
|
.request_async(&http_client)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
return Ok(ClientSecrets {
|
||||||
|
id_token: res.id_token().unwrap().to_string(),
|
||||||
|
access_token: res.access_token().secret().to_owned(),
|
||||||
|
refresh_token: res.refresh_token().unwrap().secret().to_owned(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async fn auth_flow(mut mize: Mize) -> MizeResult<ClientSecrets> {
|
async fn auth_flow(mut mize: Mize) -> MizeResult<ClientSecrets> {
|
||||||
// ===== CONFIG =====
|
|
||||||
let issuer = mize.get_config("auth.client.issuer")?.value_string()?;
|
let issuer = mize.get_config("auth.client.issuer")?.value_string()?;
|
||||||
let client_id = mize.get_config("auth.client.client_id")?.value_string()?;
|
let client_id = mize.get_config("auth.client.client_id")?.value_string()?;
|
||||||
|
|
||||||
|
|||||||
60
packages/ppc/generated/action_type.rs
Normal file
60
packages/ppc/generated/action_type.rs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||||
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
|
#![allow(unused, clippy::all)]
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
|
#[sats(crate = __lib)]
|
||||||
|
pub struct Action {
|
||||||
|
pub name: String,
|
||||||
|
pub activity: Option<u64>,
|
||||||
|
pub task: Option<u64>,
|
||||||
|
pub start: Option<__sdk::Timestamp>,
|
||||||
|
pub end: Option<__sdk::Timestamp>,
|
||||||
|
pub duration: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for Action {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Column accessor struct for the table `Action`.
|
||||||
|
///
|
||||||
|
/// Provides typed access to columns for query building.
|
||||||
|
pub struct ActionCols {
|
||||||
|
pub name: __sdk::__query_builder::Col<Action, String>,
|
||||||
|
pub activity: __sdk::__query_builder::Col<Action, Option<u64>>,
|
||||||
|
pub task: __sdk::__query_builder::Col<Action, Option<u64>>,
|
||||||
|
pub start: __sdk::__query_builder::Col<Action, Option<__sdk::Timestamp>>,
|
||||||
|
pub end: __sdk::__query_builder::Col<Action, Option<__sdk::Timestamp>>,
|
||||||
|
pub duration: __sdk::__query_builder::Col<Action, Option<u64>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::__query_builder::HasCols for Action {
|
||||||
|
type Cols = ActionCols;
|
||||||
|
fn cols(table_name: &'static str) -> Self::Cols {
|
||||||
|
ActionCols {
|
||||||
|
name: __sdk::__query_builder::Col::new(table_name, "name"),
|
||||||
|
activity: __sdk::__query_builder::Col::new(table_name, "activity"),
|
||||||
|
task: __sdk::__query_builder::Col::new(table_name, "task"),
|
||||||
|
start: __sdk::__query_builder::Col::new(table_name, "start"),
|
||||||
|
end: __sdk::__query_builder::Col::new(table_name, "end"),
|
||||||
|
duration: __sdk::__query_builder::Col::new(table_name, "duration"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Indexed column accessor struct for the table `Action`.
|
||||||
|
///
|
||||||
|
/// Provides typed access to indexed columns for query building.
|
||||||
|
pub struct ActionIxCols {}
|
||||||
|
|
||||||
|
impl __sdk::__query_builder::HasIxCols for Action {
|
||||||
|
type IxCols = ActionIxCols;
|
||||||
|
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||||
|
ActionIxCols {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::__query_builder::CanBeLookupTable for Action {}
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
|
||||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
|
||||||
|
|
||||||
#![allow(unused, clippy::all)]
|
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
|
||||||
|
|
||||||
use super::activity_type::Activity;
|
|
||||||
|
|
||||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
|
||||||
#[sats(crate = __lib)]
|
|
||||||
pub struct Event {
|
|
||||||
pub start: __sdk::Timestamp,
|
|
||||||
pub end: __sdk::Timestamp,
|
|
||||||
pub activity: Activity,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::InModule for Event {
|
|
||||||
type Module = super::RemoteModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Column accessor struct for the table `Event`.
|
|
||||||
///
|
|
||||||
/// Provides typed access to columns for query building.
|
|
||||||
pub struct EventCols {
|
|
||||||
pub start: __sdk::__query_builder::Col<Event, __sdk::Timestamp>,
|
|
||||||
pub end: __sdk::__query_builder::Col<Event, __sdk::Timestamp>,
|
|
||||||
pub activity: __sdk::__query_builder::Col<Event, Activity>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasCols for Event {
|
|
||||||
type Cols = EventCols;
|
|
||||||
fn cols(table_name: &'static str) -> Self::Cols {
|
|
||||||
EventCols {
|
|
||||||
start: __sdk::__query_builder::Col::new(table_name, "start"),
|
|
||||||
end: __sdk::__query_builder::Col::new(table_name, "end"),
|
|
||||||
activity: __sdk::__query_builder::Col::new(table_name, "activity"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Indexed column accessor struct for the table `Event`.
|
|
||||||
///
|
|
||||||
/// Provides typed access to indexed columns for query building.
|
|
||||||
pub struct EventIxCols {}
|
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasIxCols for Event {
|
|
||||||
type IxCols = EventIxCols;
|
|
||||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
|
||||||
EventIxCols {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::__query_builder::CanBeLookupTable for Event {}
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
|
||||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
|
||||||
|
|
||||||
#![allow(unused, clippy::all)]
|
|
||||||
use super::activity_type::Activity;
|
|
||||||
use super::event_type::Event;
|
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
|
||||||
|
|
||||||
/// Table handle for the table `events`.
|
|
||||||
///
|
|
||||||
/// Obtain a handle from the [`EventsTableAccess::events`] method on [`super::RemoteTables`],
|
|
||||||
/// like `ctx.db.events()`.
|
|
||||||
///
|
|
||||||
/// Users are encouraged not to explicitly reference this type,
|
|
||||||
/// but to directly chain method calls,
|
|
||||||
/// like `ctx.db.events().on_insert(...)`.
|
|
||||||
pub struct EventsTableHandle<'ctx> {
|
|
||||||
imp: __sdk::TableHandle<Event>,
|
|
||||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for access to the table `events`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::RemoteTables`].
|
|
||||||
pub trait EventsTableAccess {
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
/// Obtain a [`EventsTableHandle`], which mediates access to the table `events`.
|
|
||||||
fn events(&self) -> EventsTableHandle<'_>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EventsTableAccess for super::RemoteTables {
|
|
||||||
fn events(&self) -> EventsTableHandle<'_> {
|
|
||||||
EventsTableHandle {
|
|
||||||
imp: self.imp.get_table::<Event>("events"),
|
|
||||||
ctx: std::marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct EventsInsertCallbackId(__sdk::CallbackId);
|
|
||||||
pub struct EventsDeleteCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
impl<'ctx> __sdk::Table for EventsTableHandle<'ctx> {
|
|
||||||
type Row = Event;
|
|
||||||
type EventContext = super::EventContext;
|
|
||||||
|
|
||||||
fn count(&self) -> u64 {
|
|
||||||
self.imp.count()
|
|
||||||
}
|
|
||||||
fn iter(&self) -> impl Iterator<Item = Event> + '_ {
|
|
||||||
self.imp.iter()
|
|
||||||
}
|
|
||||||
|
|
||||||
type InsertCallbackId = EventsInsertCallbackId;
|
|
||||||
|
|
||||||
fn on_insert(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
|
||||||
) -> EventsInsertCallbackId {
|
|
||||||
EventsInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_insert(&self, callback: EventsInsertCallbackId) {
|
|
||||||
self.imp.remove_on_insert(callback.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeleteCallbackId = EventsDeleteCallbackId;
|
|
||||||
|
|
||||||
fn on_delete(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
|
||||||
) -> EventsDeleteCallbackId {
|
|
||||||
EventsDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_delete(&self, callback: EventsDeleteCallbackId) {
|
|
||||||
self.imp.remove_on_delete(callback.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
|
||||||
let _table = client_cache.get_or_make_table::<Event>("events");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub(super) fn parse_table_update(
|
|
||||||
raw_updates: __ws::v2::TableUpdate,
|
|
||||||
) -> __sdk::Result<__sdk::TableUpdate<Event>> {
|
|
||||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
|
||||||
__sdk::InternalError::failed_parse("TableUpdate<Event>", "TableUpdate")
|
|
||||||
.with_cause(e)
|
|
||||||
.into()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for query builder access to the table `Event`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
|
||||||
pub trait eventsQueryTableAccess {
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
/// Get a query builder for the table `Event`.
|
|
||||||
fn events(&self) -> __sdk::__query_builder::Table<Event>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl eventsQueryTableAccess for __sdk::QueryTableAccessor {
|
|
||||||
fn events(&self) -> __sdk::__query_builder::Table<Event> {
|
|
||||||
__sdk::__query_builder::Table::new("events")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
60
packages/ppc/generated/log_event_type.rs
Normal file
60
packages/ppc/generated/log_event_type.rs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||||
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
|
#![allow(unused, clippy::all)]
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
use super::action_type::Action;
|
||||||
|
|
||||||
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
|
#[sats(crate = __lib)]
|
||||||
|
pub struct LogEvent {
|
||||||
|
pub id: u64,
|
||||||
|
pub start: __sdk::Timestamp,
|
||||||
|
pub end: __sdk::Timestamp,
|
||||||
|
pub action: Action,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for LogEvent {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Column accessor struct for the table `LogEvent`.
|
||||||
|
///
|
||||||
|
/// Provides typed access to columns for query building.
|
||||||
|
pub struct LogEventCols {
|
||||||
|
pub id: __sdk::__query_builder::Col<LogEvent, u64>,
|
||||||
|
pub start: __sdk::__query_builder::Col<LogEvent, __sdk::Timestamp>,
|
||||||
|
pub end: __sdk::__query_builder::Col<LogEvent, __sdk::Timestamp>,
|
||||||
|
pub action: __sdk::__query_builder::Col<LogEvent, Action>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::__query_builder::HasCols for LogEvent {
|
||||||
|
type Cols = LogEventCols;
|
||||||
|
fn cols(table_name: &'static str) -> Self::Cols {
|
||||||
|
LogEventCols {
|
||||||
|
id: __sdk::__query_builder::Col::new(table_name, "id"),
|
||||||
|
start: __sdk::__query_builder::Col::new(table_name, "start"),
|
||||||
|
end: __sdk::__query_builder::Col::new(table_name, "end"),
|
||||||
|
action: __sdk::__query_builder::Col::new(table_name, "action"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Indexed column accessor struct for the table `LogEvent`.
|
||||||
|
///
|
||||||
|
/// Provides typed access to indexed columns for query building.
|
||||||
|
pub struct LogEventIxCols {
|
||||||
|
pub id: __sdk::__query_builder::IxCol<LogEvent, u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::__query_builder::HasIxCols for LogEvent {
|
||||||
|
type IxCols = LogEventIxCols;
|
||||||
|
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||||
|
LogEventIxCols {
|
||||||
|
id: __sdk::__query_builder::IxCol::new(table_name, "id"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::__query_builder::CanBeLookupTable for LogEvent {}
|
||||||
160
packages/ppc/generated/log_events_table.rs
Normal file
160
packages/ppc/generated/log_events_table.rs
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||||
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
|
#![allow(unused, clippy::all)]
|
||||||
|
use super::action_type::Action;
|
||||||
|
use super::log_event_type::LogEvent;
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
/// Table handle for the table `log_events`.
|
||||||
|
///
|
||||||
|
/// Obtain a handle from the [`LogEventsTableAccess::log_events`] method on [`super::RemoteTables`],
|
||||||
|
/// like `ctx.db.log_events()`.
|
||||||
|
///
|
||||||
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
|
/// but to directly chain method calls,
|
||||||
|
/// like `ctx.db.log_events().on_insert(...)`.
|
||||||
|
pub struct LogEventsTableHandle<'ctx> {
|
||||||
|
imp: __sdk::TableHandle<LogEvent>,
|
||||||
|
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for access to the table `log_events`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::RemoteTables`].
|
||||||
|
pub trait LogEventsTableAccess {
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
/// Obtain a [`LogEventsTableHandle`], which mediates access to the table `log_events`.
|
||||||
|
fn log_events(&self) -> LogEventsTableHandle<'_>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LogEventsTableAccess for super::RemoteTables {
|
||||||
|
fn log_events(&self) -> LogEventsTableHandle<'_> {
|
||||||
|
LogEventsTableHandle {
|
||||||
|
imp: self.imp.get_table::<LogEvent>("log_events"),
|
||||||
|
ctx: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LogEventsInsertCallbackId(__sdk::CallbackId);
|
||||||
|
pub struct LogEventsDeleteCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
impl<'ctx> __sdk::Table for LogEventsTableHandle<'ctx> {
|
||||||
|
type Row = LogEvent;
|
||||||
|
type EventContext = super::EventContext;
|
||||||
|
|
||||||
|
fn count(&self) -> u64 {
|
||||||
|
self.imp.count()
|
||||||
|
}
|
||||||
|
fn iter(&self) -> impl Iterator<Item = LogEvent> + '_ {
|
||||||
|
self.imp.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
type InsertCallbackId = LogEventsInsertCallbackId;
|
||||||
|
|
||||||
|
fn on_insert(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||||
|
) -> LogEventsInsertCallbackId {
|
||||||
|
LogEventsInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_insert(&self, callback: LogEventsInsertCallbackId) {
|
||||||
|
self.imp.remove_on_insert(callback.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteCallbackId = LogEventsDeleteCallbackId;
|
||||||
|
|
||||||
|
fn on_delete(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||||
|
) -> LogEventsDeleteCallbackId {
|
||||||
|
LogEventsDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_delete(&self, callback: LogEventsDeleteCallbackId) {
|
||||||
|
self.imp.remove_on_delete(callback.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LogEventsUpdateCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
impl<'ctx> __sdk::TableWithPrimaryKey for LogEventsTableHandle<'ctx> {
|
||||||
|
type UpdateCallbackId = LogEventsUpdateCallbackId;
|
||||||
|
|
||||||
|
fn on_update(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||||
|
) -> LogEventsUpdateCallbackId {
|
||||||
|
LogEventsUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_update(&self, callback: LogEventsUpdateCallbackId) {
|
||||||
|
self.imp.remove_on_update(callback.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Access to the `id` unique index on the table `log_events`,
|
||||||
|
/// which allows point queries on the field of the same name
|
||||||
|
/// via the [`LogEventsIdUnique::find`] method.
|
||||||
|
///
|
||||||
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
|
/// but to directly chain method calls,
|
||||||
|
/// like `ctx.db.log_events().id().find(...)`.
|
||||||
|
pub struct LogEventsIdUnique<'ctx> {
|
||||||
|
imp: __sdk::UniqueConstraintHandle<LogEvent, u64>,
|
||||||
|
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> LogEventsTableHandle<'ctx> {
|
||||||
|
/// Get a handle on the `id` unique index on the table `log_events`.
|
||||||
|
pub fn id(&self) -> LogEventsIdUnique<'ctx> {
|
||||||
|
LogEventsIdUnique {
|
||||||
|
imp: self.imp.get_unique_constraint::<u64>("id"),
|
||||||
|
phantom: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> LogEventsIdUnique<'ctx> {
|
||||||
|
/// Find the subscribed row whose `id` column value is equal to `col_val`,
|
||||||
|
/// if such a row is present in the client cache.
|
||||||
|
pub fn find(&self, col_val: &u64) -> Option<LogEvent> {
|
||||||
|
self.imp.find(col_val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||||
|
let _table = client_cache.get_or_make_table::<LogEvent>("log_events");
|
||||||
|
_table.add_unique_constraint::<u64>("id", |row| &row.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub(super) fn parse_table_update(
|
||||||
|
raw_updates: __ws::v2::TableUpdate,
|
||||||
|
) -> __sdk::Result<__sdk::TableUpdate<LogEvent>> {
|
||||||
|
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||||
|
__sdk::InternalError::failed_parse("TableUpdate<LogEvent>", "TableUpdate")
|
||||||
|
.with_cause(e)
|
||||||
|
.into()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for query builder access to the table `LogEvent`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||||
|
pub trait log_eventsQueryTableAccess {
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
/// Get a query builder for the table `LogEvent`.
|
||||||
|
fn log_events(&self) -> __sdk::__query_builder::Table<LogEvent>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl log_eventsQueryTableAccess for __sdk::QueryTableAccessor {
|
||||||
|
fn log_events(&self) -> __sdk::__query_builder::Table<LogEvent> {
|
||||||
|
__sdk::__query_builder::Table::new("log_events")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,11 +6,13 @@
|
|||||||
#![allow(unused, clippy::all)]
|
#![allow(unused, clippy::all)]
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
pub mod action_type;
|
||||||
pub mod activities_table;
|
pub mod activities_table;
|
||||||
pub mod activity_type;
|
pub mod activity_type;
|
||||||
pub mod add_activity_reducer;
|
pub mod add_activity_reducer;
|
||||||
pub mod event_type;
|
pub mod log_event_type;
|
||||||
pub mod events_table;
|
pub mod log_events_table;
|
||||||
|
pub mod next_action_reducer;
|
||||||
pub mod profile_type;
|
pub mod profile_type;
|
||||||
pub mod profiles_table;
|
pub mod profiles_table;
|
||||||
pub mod remove_activity_reducer;
|
pub mod remove_activity_reducer;
|
||||||
@@ -20,12 +22,15 @@ pub mod task_part_type;
|
|||||||
pub mod task_type;
|
pub mod task_type;
|
||||||
pub mod tasks_table;
|
pub mod tasks_table;
|
||||||
pub mod update_activity_reducer;
|
pub mod update_activity_reducer;
|
||||||
|
pub mod update_upcoming_reducer;
|
||||||
|
|
||||||
|
pub use action_type::Action;
|
||||||
pub use activities_table::*;
|
pub use activities_table::*;
|
||||||
pub use activity_type::Activity;
|
pub use activity_type::Activity;
|
||||||
pub use add_activity_reducer::add_activity;
|
pub use add_activity_reducer::add_activity;
|
||||||
pub use event_type::Event;
|
pub use log_event_type::LogEvent;
|
||||||
pub use events_table::*;
|
pub use log_events_table::*;
|
||||||
|
pub use next_action_reducer::next_action;
|
||||||
pub use profile_type::Profile;
|
pub use profile_type::Profile;
|
||||||
pub use profiles_table::*;
|
pub use profiles_table::*;
|
||||||
pub use remove_activity_reducer::remove_activity;
|
pub use remove_activity_reducer::remove_activity;
|
||||||
@@ -35,6 +40,7 @@ pub use task_part_type::TaskPart;
|
|||||||
pub use task_type::Task;
|
pub use task_type::Task;
|
||||||
pub use tasks_table::*;
|
pub use tasks_table::*;
|
||||||
pub use update_activity_reducer::update_activity;
|
pub use update_activity_reducer::update_activity;
|
||||||
|
pub use update_upcoming_reducer::update_upcoming;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
|
||||||
@@ -45,9 +51,11 @@ pub use update_activity_reducer::update_activity;
|
|||||||
|
|
||||||
pub enum Reducer {
|
pub enum Reducer {
|
||||||
AddActivity { name: String },
|
AddActivity { name: String },
|
||||||
|
NextAction,
|
||||||
RemoveActivity { activity: Activity },
|
RemoveActivity { activity: Activity },
|
||||||
SetActivityName { id: u64, name: String },
|
SetActivityName { id: u64, name: String },
|
||||||
UpdateActivity { activity: Activity },
|
UpdateActivity { activity: Activity },
|
||||||
|
UpdateUpcoming { upcoming: Vec<Action> },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for Reducer {
|
impl __sdk::InModule for Reducer {
|
||||||
@@ -58,9 +66,11 @@ impl __sdk::Reducer for Reducer {
|
|||||||
fn reducer_name(&self) -> &'static str {
|
fn reducer_name(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Reducer::AddActivity { .. } => "add_activity",
|
Reducer::AddActivity { .. } => "add_activity",
|
||||||
|
Reducer::NextAction => "next_action",
|
||||||
Reducer::RemoveActivity { .. } => "remove_activity",
|
Reducer::RemoveActivity { .. } => "remove_activity",
|
||||||
Reducer::SetActivityName { .. } => "set_activity_name",
|
Reducer::SetActivityName { .. } => "set_activity_name",
|
||||||
Reducer::UpdateActivity { .. } => "update_activity",
|
Reducer::UpdateActivity { .. } => "update_activity",
|
||||||
|
Reducer::UpdateUpcoming { .. } => "update_upcoming",
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,6 +80,7 @@ impl __sdk::Reducer for Reducer {
|
|||||||
Reducer::AddActivity { name } => {
|
Reducer::AddActivity { name } => {
|
||||||
__sats::bsatn::to_vec(&add_activity_reducer::AddActivityArgs { name: name.clone() })
|
__sats::bsatn::to_vec(&add_activity_reducer::AddActivityArgs { name: name.clone() })
|
||||||
}
|
}
|
||||||
|
Reducer::NextAction => __sats::bsatn::to_vec(&next_action_reducer::NextActionArgs {}),
|
||||||
Reducer::RemoveActivity { activity } => {
|
Reducer::RemoveActivity { activity } => {
|
||||||
__sats::bsatn::to_vec(&remove_activity_reducer::RemoveActivityArgs {
|
__sats::bsatn::to_vec(&remove_activity_reducer::RemoveActivityArgs {
|
||||||
activity: activity.clone(),
|
activity: activity.clone(),
|
||||||
@@ -86,6 +97,11 @@ impl __sdk::Reducer for Reducer {
|
|||||||
activity: activity.clone(),
|
activity: activity.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Reducer::UpdateUpcoming { upcoming } => {
|
||||||
|
__sats::bsatn::to_vec(&update_upcoming_reducer::UpdateUpcomingArgs {
|
||||||
|
upcoming: upcoming.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,7 +112,7 @@ impl __sdk::Reducer for Reducer {
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct DbUpdate {
|
pub struct DbUpdate {
|
||||||
activities: __sdk::TableUpdate<Activity>,
|
activities: __sdk::TableUpdate<Activity>,
|
||||||
events: __sdk::TableUpdate<Event>,
|
log_events: __sdk::TableUpdate<LogEvent>,
|
||||||
profiles: __sdk::TableUpdate<Profile>,
|
profiles: __sdk::TableUpdate<Profile>,
|
||||||
task_part: __sdk::TableUpdate<TaskPart>,
|
task_part: __sdk::TableUpdate<TaskPart>,
|
||||||
tasks: __sdk::TableUpdate<Task>,
|
tasks: __sdk::TableUpdate<Task>,
|
||||||
@@ -111,9 +127,9 @@ impl TryFrom<__ws::v2::TransactionUpdate> for DbUpdate {
|
|||||||
"activities" => db_update
|
"activities" => db_update
|
||||||
.activities
|
.activities
|
||||||
.append(activities_table::parse_table_update(table_update)?),
|
.append(activities_table::parse_table_update(table_update)?),
|
||||||
"events" => db_update
|
"log_events" => db_update
|
||||||
.events
|
.log_events
|
||||||
.append(events_table::parse_table_update(table_update)?),
|
.append(log_events_table::parse_table_update(table_update)?),
|
||||||
"profiles" => db_update
|
"profiles" => db_update
|
||||||
.profiles
|
.profiles
|
||||||
.append(profiles_table::parse_table_update(table_update)?),
|
.append(profiles_table::parse_table_update(table_update)?),
|
||||||
@@ -152,7 +168,9 @@ impl __sdk::DbUpdate for DbUpdate {
|
|||||||
diff.activities = cache
|
diff.activities = cache
|
||||||
.apply_diff_to_table::<Activity>("activities", &self.activities)
|
.apply_diff_to_table::<Activity>("activities", &self.activities)
|
||||||
.with_updates_by_pk(|row| &row.id);
|
.with_updates_by_pk(|row| &row.id);
|
||||||
diff.events = cache.apply_diff_to_table::<Event>("events", &self.events);
|
diff.log_events = cache
|
||||||
|
.apply_diff_to_table::<LogEvent>("log_events", &self.log_events)
|
||||||
|
.with_updates_by_pk(|row| &row.id);
|
||||||
diff.profiles = cache
|
diff.profiles = cache
|
||||||
.apply_diff_to_table::<Profile>("profiles", &self.profiles)
|
.apply_diff_to_table::<Profile>("profiles", &self.profiles)
|
||||||
.with_updates_by_pk(|row| &row.identity);
|
.with_updates_by_pk(|row| &row.identity);
|
||||||
@@ -172,8 +190,8 @@ impl __sdk::DbUpdate for DbUpdate {
|
|||||||
"activities" => db_update
|
"activities" => db_update
|
||||||
.activities
|
.activities
|
||||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||||
"events" => db_update
|
"log_events" => db_update
|
||||||
.events
|
.log_events
|
||||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||||
"profiles" => db_update
|
"profiles" => db_update
|
||||||
.profiles
|
.profiles
|
||||||
@@ -200,8 +218,8 @@ impl __sdk::DbUpdate for DbUpdate {
|
|||||||
"activities" => db_update
|
"activities" => db_update
|
||||||
.activities
|
.activities
|
||||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||||
"events" => db_update
|
"log_events" => db_update
|
||||||
.events
|
.log_events
|
||||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||||
"profiles" => db_update
|
"profiles" => db_update
|
||||||
.profiles
|
.profiles
|
||||||
@@ -228,7 +246,7 @@ impl __sdk::DbUpdate for DbUpdate {
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct AppliedDiff<'r> {
|
pub struct AppliedDiff<'r> {
|
||||||
activities: __sdk::TableAppliedDiff<'r, Activity>,
|
activities: __sdk::TableAppliedDiff<'r, Activity>,
|
||||||
events: __sdk::TableAppliedDiff<'r, Event>,
|
log_events: __sdk::TableAppliedDiff<'r, LogEvent>,
|
||||||
profiles: __sdk::TableAppliedDiff<'r, Profile>,
|
profiles: __sdk::TableAppliedDiff<'r, Profile>,
|
||||||
task_part: __sdk::TableAppliedDiff<'r, TaskPart>,
|
task_part: __sdk::TableAppliedDiff<'r, TaskPart>,
|
||||||
tasks: __sdk::TableAppliedDiff<'r, Task>,
|
tasks: __sdk::TableAppliedDiff<'r, Task>,
|
||||||
@@ -246,7 +264,7 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> {
|
|||||||
callbacks: &mut __sdk::DbCallbacks<RemoteModule>,
|
callbacks: &mut __sdk::DbCallbacks<RemoteModule>,
|
||||||
) {
|
) {
|
||||||
callbacks.invoke_table_row_callbacks::<Activity>("activities", &self.activities, event);
|
callbacks.invoke_table_row_callbacks::<Activity>("activities", &self.activities, event);
|
||||||
callbacks.invoke_table_row_callbacks::<Event>("events", &self.events, event);
|
callbacks.invoke_table_row_callbacks::<LogEvent>("log_events", &self.log_events, event);
|
||||||
callbacks.invoke_table_row_callbacks::<Profile>("profiles", &self.profiles, event);
|
callbacks.invoke_table_row_callbacks::<Profile>("profiles", &self.profiles, event);
|
||||||
callbacks.invoke_table_row_callbacks::<TaskPart>("task_part", &self.task_part, event);
|
callbacks.invoke_table_row_callbacks::<TaskPart>("task_part", &self.task_part, event);
|
||||||
callbacks.invoke_table_row_callbacks::<Task>("tasks", &self.tasks, event);
|
callbacks.invoke_table_row_callbacks::<Task>("tasks", &self.tasks, event);
|
||||||
@@ -911,11 +929,11 @@ impl __sdk::SpacetimeModule for RemoteModule {
|
|||||||
|
|
||||||
fn register_tables(client_cache: &mut __sdk::ClientCache<Self>) {
|
fn register_tables(client_cache: &mut __sdk::ClientCache<Self>) {
|
||||||
activities_table::register_table(client_cache);
|
activities_table::register_table(client_cache);
|
||||||
events_table::register_table(client_cache);
|
log_events_table::register_table(client_cache);
|
||||||
profiles_table::register_table(client_cache);
|
profiles_table::register_table(client_cache);
|
||||||
task_part_table::register_table(client_cache);
|
task_part_table::register_table(client_cache);
|
||||||
tasks_table::register_table(client_cache);
|
tasks_table::register_table(client_cache);
|
||||||
}
|
}
|
||||||
const ALL_TABLE_NAMES: &'static [&'static str] =
|
const ALL_TABLE_NAMES: &'static [&'static str] =
|
||||||
&["activities", "events", "profiles", "task_part", "tasks"];
|
&["activities", "log_events", "profiles", "task_part", "tasks"];
|
||||||
}
|
}
|
||||||
|
|||||||
62
packages/ppc/generated/next_action_reducer.rs
Normal file
62
packages/ppc/generated/next_action_reducer.rs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||||
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
|
#![allow(unused, clippy::all)]
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
|
#[sats(crate = __lib)]
|
||||||
|
pub(super) struct NextActionArgs {}
|
||||||
|
|
||||||
|
impl From<NextActionArgs> for super::Reducer {
|
||||||
|
fn from(args: NextActionArgs) -> Self {
|
||||||
|
Self::NextAction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for NextActionArgs {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for access to the reducer `next_action`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::RemoteReducers`].
|
||||||
|
pub trait next_action {
|
||||||
|
/// Request that the remote module invoke the reducer `next_action` to run as soon as possible.
|
||||||
|
///
|
||||||
|
/// This method returns immediately, and errors only if we are unable to send the request.
|
||||||
|
/// The reducer will run asynchronously in the future,
|
||||||
|
/// and this method provides no way to listen for its completion status.
|
||||||
|
/// /// Use [`next_action:next_action_then`] to run a callback after the reducer completes.
|
||||||
|
fn next_action(&self) -> __sdk::Result<()> {
|
||||||
|
self.next_action_then(|_, _| {})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Request that the remote module invoke the reducer `next_action` to run as soon as possible,
|
||||||
|
/// registering `callback` to run when we are notified that the reducer completed.
|
||||||
|
///
|
||||||
|
/// This method returns immediately, and errors only if we are unable to send the request.
|
||||||
|
/// The reducer will run asynchronously in the future,
|
||||||
|
/// and its status can be observed with the `callback`.
|
||||||
|
fn next_action_then(
|
||||||
|
&self,
|
||||||
|
|
||||||
|
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
||||||
|
+ Send
|
||||||
|
+ 'static,
|
||||||
|
) -> __sdk::Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl next_action for super::RemoteReducers {
|
||||||
|
fn next_action_then(
|
||||||
|
&self,
|
||||||
|
|
||||||
|
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
||||||
|
+ Send
|
||||||
|
+ 'static,
|
||||||
|
) -> __sdk::Result<()> {
|
||||||
|
self.imp
|
||||||
|
.invoke_reducer_with_callback(NextActionArgs {}, callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
#![allow(unused, clippy::all)]
|
#![allow(unused, clippy::all)]
|
||||||
use super::activity_type::Activity;
|
use super::action_type::Action;
|
||||||
use super::task_part_type::TaskPart;
|
use super::task_part_type::TaskPart;
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,15 @@
|
|||||||
#![allow(unused, clippy::all)]
|
#![allow(unused, clippy::all)]
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
use super::activity_type::Activity;
|
use super::action_type::Action;
|
||||||
|
|
||||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
#[sats(crate = __lib)]
|
#[sats(crate = __lib)]
|
||||||
pub struct TaskPart {
|
pub struct TaskPart {
|
||||||
pub identity: __sdk::Identity,
|
pub identity: __sdk::Identity,
|
||||||
pub current_activity: Activity,
|
pub start_of_current: __sdk::Timestamp,
|
||||||
|
pub current: Action,
|
||||||
|
pub upcoming: Vec<Action>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for TaskPart {
|
impl __sdk::InModule for TaskPart {
|
||||||
@@ -22,7 +24,9 @@ impl __sdk::InModule for TaskPart {
|
|||||||
/// Provides typed access to columns for query building.
|
/// Provides typed access to columns for query building.
|
||||||
pub struct TaskPartCols {
|
pub struct TaskPartCols {
|
||||||
pub identity: __sdk::__query_builder::Col<TaskPart, __sdk::Identity>,
|
pub identity: __sdk::__query_builder::Col<TaskPart, __sdk::Identity>,
|
||||||
pub current_activity: __sdk::__query_builder::Col<TaskPart, Activity>,
|
pub start_of_current: __sdk::__query_builder::Col<TaskPart, __sdk::Timestamp>,
|
||||||
|
pub current: __sdk::__query_builder::Col<TaskPart, Action>,
|
||||||
|
pub upcoming: __sdk::__query_builder::Col<TaskPart, Vec<Action>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasCols for TaskPart {
|
impl __sdk::__query_builder::HasCols for TaskPart {
|
||||||
@@ -30,7 +34,9 @@ impl __sdk::__query_builder::HasCols for TaskPart {
|
|||||||
fn cols(table_name: &'static str) -> Self::Cols {
|
fn cols(table_name: &'static str) -> Self::Cols {
|
||||||
TaskPartCols {
|
TaskPartCols {
|
||||||
identity: __sdk::__query_builder::Col::new(table_name, "identity"),
|
identity: __sdk::__query_builder::Col::new(table_name, "identity"),
|
||||||
current_activity: __sdk::__query_builder::Col::new(table_name, "current_activity"),
|
start_of_current: __sdk::__query_builder::Col::new(table_name, "start_of_current"),
|
||||||
|
current: __sdk::__query_builder::Col::new(table_name, "current"),
|
||||||
|
upcoming: __sdk::__query_builder::Col::new(table_name, "upcoming"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
70
packages/ppc/generated/update_upcoming_reducer.rs
Normal file
70
packages/ppc/generated/update_upcoming_reducer.rs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||||
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
|
#![allow(unused, clippy::all)]
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
use super::action_type::Action;
|
||||||
|
|
||||||
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
|
#[sats(crate = __lib)]
|
||||||
|
pub(super) struct UpdateUpcomingArgs {
|
||||||
|
pub upcoming: Vec<Action>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<UpdateUpcomingArgs> for super::Reducer {
|
||||||
|
fn from(args: UpdateUpcomingArgs) -> Self {
|
||||||
|
Self::UpdateUpcoming {
|
||||||
|
upcoming: args.upcoming,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for UpdateUpcomingArgs {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for access to the reducer `update_upcoming`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::RemoteReducers`].
|
||||||
|
pub trait update_upcoming {
|
||||||
|
/// Request that the remote module invoke the reducer `update_upcoming` to run as soon as possible.
|
||||||
|
///
|
||||||
|
/// This method returns immediately, and errors only if we are unable to send the request.
|
||||||
|
/// The reducer will run asynchronously in the future,
|
||||||
|
/// and this method provides no way to listen for its completion status.
|
||||||
|
/// /// Use [`update_upcoming:update_upcoming_then`] to run a callback after the reducer completes.
|
||||||
|
fn update_upcoming(&self, upcoming: Vec<Action>) -> __sdk::Result<()> {
|
||||||
|
self.update_upcoming_then(upcoming, |_, _| {})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Request that the remote module invoke the reducer `update_upcoming` to run as soon as possible,
|
||||||
|
/// registering `callback` to run when we are notified that the reducer completed.
|
||||||
|
///
|
||||||
|
/// This method returns immediately, and errors only if we are unable to send the request.
|
||||||
|
/// The reducer will run asynchronously in the future,
|
||||||
|
/// and its status can be observed with the `callback`.
|
||||||
|
fn update_upcoming_then(
|
||||||
|
&self,
|
||||||
|
upcoming: Vec<Action>,
|
||||||
|
|
||||||
|
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
||||||
|
+ Send
|
||||||
|
+ 'static,
|
||||||
|
) -> __sdk::Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl update_upcoming for super::RemoteReducers {
|
||||||
|
fn update_upcoming_then(
|
||||||
|
&self,
|
||||||
|
upcoming: Vec<Action>,
|
||||||
|
|
||||||
|
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
||||||
|
+ Send
|
||||||
|
+ 'static,
|
||||||
|
) -> __sdk::Result<()> {
|
||||||
|
self.imp
|
||||||
|
.invoke_reducer_with_callback(UpdateUpcomingArgs { upcoming }, callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,14 +39,28 @@ fn os_main(mize: &mut Mize) -> MizeResult<()> {
|
|||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
ppc::server(mize)?;
|
ppc::server(mize)?;
|
||||||
|
|
||||||
|
let mut cli = mize.get_part_native::<marts::CliPart>("cli")?;
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
#[cfg(feature = "desktop")]
|
#[cfg(feature = "desktop")]
|
||||||
|
{
|
||||||
cli.subcommand(Command::new("gui"), |_, _| {
|
cli.subcommand(Command::new("gui"), |_, _| {
|
||||||
ppc::ui::launch_desktop_app();
|
ppc::ui::launch_desktop_app();
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
cli.subcommand(Command::new("c2vi-dash"), |_, mut mize| {
|
||||||
|
// refresh the credentials every 23h
|
||||||
|
// as this is basically running as a daemon
|
||||||
|
use ppc::auth::client::ClientAuth;
|
||||||
|
let mut auth = mize.get_part_native::<ClientAuth>("auth")?;
|
||||||
|
auth.refresh()?;
|
||||||
|
auth.start_refresh_thread()?;
|
||||||
|
drop(auth);
|
||||||
|
|
||||||
let mut cli = mize.get_part_native::<marts::CliPart>("cli")?;
|
ppc::ui::launch_c2vi_dashboard(&mut mize);
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
cli.with_cmd(|_, cmd| {
|
cli.with_cmd(|_, cmd| {
|
||||||
Ok(cmd
|
Ok(cmd
|
||||||
|
|||||||
@@ -1,5 +1,18 @@
|
|||||||
// Minimal cross-platform UI component
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
use mize::Mize;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
generated::{
|
||||||
|
Action, ActivitiesTableAccess, Activity, DbConnection, TaskPart, TaskPartTableAccess,
|
||||||
|
activitiesQueryTableAccess, next_action, remove_activity, task_partQueryTableAccess,
|
||||||
|
update_activity, update_upcoming,
|
||||||
|
},
|
||||||
|
spacetime::SpacetimePart,
|
||||||
|
};
|
||||||
|
use spacetimedb_sdk::{
|
||||||
|
DbContext, Error, Event, Identity, Status, SubscriptionHandle, Table, TableWithPrimaryKey,
|
||||||
|
credentials,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn hello_world() -> Element {
|
pub fn hello_world() -> Element {
|
||||||
rsx! {
|
rsx! {
|
||||||
@@ -12,6 +25,126 @@ pub fn hello_world() -> Element {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn c2vi_dash_main() -> Element {
|
||||||
|
let mut current = use_signal_sync(|| "".to_string());
|
||||||
|
use_effect(move || {
|
||||||
|
let mut mize = use_context::<Mize>();
|
||||||
|
let mut spacetime = mize.get_part_native::<SpacetimePart>("spacetime").unwrap();
|
||||||
|
let con = spacetime.con();
|
||||||
|
con.subscription_builder()
|
||||||
|
.on_applied(move |ctx| {
|
||||||
|
let data = ctx.db.task_part().identity().find(&ctx.identity()).unwrap();
|
||||||
|
current.set(data.current.name.clone());
|
||||||
|
})
|
||||||
|
.add_query(|q| q.from.task_part())
|
||||||
|
.subscribe();
|
||||||
|
con.db
|
||||||
|
.task_part()
|
||||||
|
.on_update(move |_, old: &TaskPart, new: &TaskPart| {
|
||||||
|
current.set(new.current.name.clone());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
rsx! {
|
||||||
|
div {
|
||||||
|
style: "text-align: center; padding: 2rem; font-size: 50px;",
|
||||||
|
p {
|
||||||
|
"{current}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn launch_desktop_app() {
|
pub fn launch_desktop_app() {
|
||||||
dioxus::launch(hello_world);
|
dioxus::launch(hello_world);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "desktop")]
|
||||||
|
pub fn launch_c2vi_dashboard(mize: &mut Mize) {
|
||||||
|
use dioxus::desktop::{Config, WindowBuilder, muda::Menu};
|
||||||
|
let mize_clone = mize.clone();
|
||||||
|
LaunchBuilder::new()
|
||||||
|
.with_context_provider(move || Box::new(mize_clone.clone()))
|
||||||
|
.with_cfg(desktop! {
|
||||||
|
Config::new().with_window(WindowBuilder::new().with_decorations(false).with_title("PPC"))
|
||||||
|
})
|
||||||
|
.launch(c2vi_dash_main);
|
||||||
|
}
|
||||||
|
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
/*
|
||||||
|
pub fn use_spacetime_row<T>() -> {
|
||||||
|
let mut mize = use_context::<Mize>();
|
||||||
|
let mut spacetime = mize.get_part_native::<SpacetimePart>("spacetime").unwrap();
|
||||||
|
let con = spacetime.con();
|
||||||
|
|
||||||
|
let data = use_signal(|| None:: <T>);
|
||||||
|
|
||||||
|
let a = con.db.task_part();
|
||||||
|
let table = con.db.
|
||||||
|
|
||||||
|
use_effect(cx, (), {});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn use_spacetime_users() -> Signal<Vec<User>> {
|
||||||
|
let mut mize = use_context::<Mize>();
|
||||||
|
let mut spacetime = mize.get_part_native::<SpacetimePart>("spacetime").unwrap();
|
||||||
|
let con = spacetime.con();
|
||||||
|
|
||||||
|
let users = use_signal(|| Vec::<User>::new());
|
||||||
|
|
||||||
|
use_effect(cx, (), {
|
||||||
|
let users = users.clone();
|
||||||
|
let conn = ctx.conn.clone();
|
||||||
|
|
||||||
|
move |_| {
|
||||||
|
conn.on_connect(move |db_ctx| {
|
||||||
|
// initial subscription
|
||||||
|
db_ctx.subscription_builder()
|
||||||
|
.on_applied({
|
||||||
|
let users = users.clone();
|
||||||
|
move |ctx| {
|
||||||
|
let all: Vec<_> =
|
||||||
|
ctx.db.user().iter().cloned().collect();
|
||||||
|
users.set(all);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.subscribe(["SELECT * FROM user"]);
|
||||||
|
|
||||||
|
// incremental updates
|
||||||
|
db_ctx.db.user().on_insert({
|
||||||
|
let users = users.clone();
|
||||||
|
move |_, row| {
|
||||||
|
users.with_mut(|v| v.push(row.clone()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
db_ctx.db.user().on_delete({
|
||||||
|
let users = users.clone();
|
||||||
|
move |_, row| {
|
||||||
|
users.with_mut(|v| {
|
||||||
|
v.retain(|u| u.id != row.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
db_ctx.db.user().on_update({
|
||||||
|
let users = users.clone();
|
||||||
|
move |_, old, new| {
|
||||||
|
users.with_mut(|v| {
|
||||||
|
if let Some(u) = v.iter_mut().find(|u| u.id == old.id) {
|
||||||
|
*u = new.clone();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
async move {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
users
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
|
use std::task;
|
||||||
|
|
||||||
use log::*;
|
use log::*;
|
||||||
use spacetimedb::{reducer, table, Identity, ReducerContext, Table, Timestamp};
|
use spacetimedb::{
|
||||||
|
reducer, table, view, Deserialize, Identity, ReducerContext, Serialize, SpacetimeType, Table,
|
||||||
|
Timestamp, ViewContext,
|
||||||
|
};
|
||||||
|
|
||||||
#[table(accessor = profiles, public)]
|
#[table(accessor = profiles, public)]
|
||||||
pub struct Profile {
|
pub struct Profile {
|
||||||
@@ -13,7 +18,9 @@ pub struct Profile {
|
|||||||
pub struct TaskPart {
|
pub struct TaskPart {
|
||||||
#[primary_key]
|
#[primary_key]
|
||||||
identity: Identity,
|
identity: Identity,
|
||||||
current_activity: Activity,
|
start_of_current: Timestamp,
|
||||||
|
current: Action,
|
||||||
|
upcoming: Vec<Action>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[table(accessor = activities, public)]
|
#[table(accessor = activities, public)]
|
||||||
@@ -36,14 +43,26 @@ pub struct Task {
|
|||||||
parent: Option<u64>,
|
parent: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[table(accessor = events, public)]
|
#[table(accessor = action)]
|
||||||
pub struct Event {
|
#[derive(Clone)]
|
||||||
start: Timestamp,
|
pub struct Action {
|
||||||
end: Timestamp,
|
name: String,
|
||||||
activity: Activity,
|
activity: Option<u64>,
|
||||||
|
task: Option<u64>,
|
||||||
|
start: Option<Timestamp>,
|
||||||
|
end: Option<Timestamp>,
|
||||||
|
duration: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO....
|
#[table(accessor = log_events, public)]
|
||||||
|
pub struct LogEvent {
|
||||||
|
#[primary_key]
|
||||||
|
#[auto_inc]
|
||||||
|
id: u64,
|
||||||
|
start: Timestamp,
|
||||||
|
end: Timestamp,
|
||||||
|
action: Action,
|
||||||
|
}
|
||||||
|
|
||||||
#[reducer(init)]
|
#[reducer(init)]
|
||||||
pub fn init(_ctx: &ReducerContext) {
|
pub fn init(_ctx: &ReducerContext) {
|
||||||
@@ -106,6 +125,57 @@ pub fn set_activity_name(ctx: &ReducerContext, id: u64, name: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[reducer]
|
||||||
|
pub fn update_upcoming(ctx: &ReducerContext, upcoming: Vec<Action>) {
|
||||||
|
if ctx.db.task_part().identity().find(ctx.sender()).is_none() {
|
||||||
|
ctx.db.task_part().insert(TaskPart {
|
||||||
|
upcoming,
|
||||||
|
identity: ctx.sender(),
|
||||||
|
current: Action {
|
||||||
|
name: "filler".to_string(),
|
||||||
|
activity: None,
|
||||||
|
task: None,
|
||||||
|
start: None,
|
||||||
|
end: None,
|
||||||
|
duration: None,
|
||||||
|
},
|
||||||
|
start_of_current: ctx.timestamp,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ctx.db.task_part().identity().update(TaskPart {
|
||||||
|
upcoming,
|
||||||
|
..ctx.db.task_part().identity().find(&ctx.sender()).unwrap()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[reducer]
|
||||||
|
pub fn next_action(ctx: &ReducerContext) -> Result<(), String> {
|
||||||
|
if let Some(mut task_part) = ctx.db.task_part().identity().find(&ctx.sender()) {
|
||||||
|
if task_part.upcoming.is_empty() {
|
||||||
|
return Err("No upcoming actions".to_string());
|
||||||
|
}
|
||||||
|
let action = task_part.upcoming.remove(0);
|
||||||
|
let start_of_old_action = task_part.start_of_current;
|
||||||
|
ctx.db.task_part().identity().update(TaskPart {
|
||||||
|
upcoming: task_part.upcoming,
|
||||||
|
identity: task_part.identity,
|
||||||
|
current: action.clone(),
|
||||||
|
start_of_current: ctx.timestamp,
|
||||||
|
});
|
||||||
|
// create log event
|
||||||
|
ctx.db.log_events().insert(LogEvent {
|
||||||
|
start: start_of_old_action,
|
||||||
|
end: ctx.timestamp,
|
||||||
|
action: task_part.current,
|
||||||
|
id: 0,
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err("Task part data not found for this user".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[reducer]
|
#[reducer]
|
||||||
pub fn update_activity(ctx: &ReducerContext, activity: Activity) {
|
pub fn update_activity(ctx: &ReducerContext, activity: Activity) {
|
||||||
if activity.id == 0 {
|
if activity.id == 0 {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::{io::Read, sync::oneshot, thread, time::Duration};
|
use std::{io::Read, sync::oneshot, thread, time::Duration};
|
||||||
|
|
||||||
use clap::{ArgMatches, Command};
|
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||||
use mize::{Mize, MizeError, MizePart, MizePartGuard, MizeResult, mize_err, mize_part};
|
use mize::{Mize, MizeError, MizePart, MizePartGuard, MizeResult, mize_err, mize_part};
|
||||||
use spacetimedb_sdk::{
|
use spacetimedb_sdk::{
|
||||||
DbContext, Error, Event, Identity, Status, SubscriptionHandle, Table, TableWithPrimaryKey,
|
DbContext, Error, Event, Identity, Status, SubscriptionHandle, Table, TableWithPrimaryKey,
|
||||||
@@ -9,8 +9,9 @@ use spacetimedb_sdk::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
generated::{
|
generated::{
|
||||||
ActivitiesTableAccess, Activity, DbConnection, activitiesQueryTableAccess, remove_activity,
|
Action, ActivitiesTableAccess, Activity, DbConnection, TaskPartTableAccess,
|
||||||
update_activity,
|
activitiesQueryTableAccess, next_action, remove_activity, task_partQueryTableAccess,
|
||||||
|
update_activity, update_upcoming,
|
||||||
},
|
},
|
||||||
spacetime::SpacetimePart,
|
spacetime::SpacetimePart,
|
||||||
};
|
};
|
||||||
@@ -24,6 +25,23 @@ pub struct TimeTrack {
|
|||||||
pub fn timetrack(mize: &mut Mize) -> MizeResult<()> {
|
pub fn timetrack(mize: &mut Mize) -> MizeResult<()> {
|
||||||
let mut cli = mize.get_part_native::<marts::CliPart>("cli")?;
|
let mut cli = mize.get_part_native::<marts::CliPart>("cli")?;
|
||||||
|
|
||||||
|
cli.subcommand(
|
||||||
|
Command::new("editActionList").alias("aal").arg(
|
||||||
|
Arg::new("defaultTemplate")
|
||||||
|
.short('d')
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
),
|
||||||
|
command_edit_action_list,
|
||||||
|
);
|
||||||
|
cli.subcommand(Command::new("nextAction").alias("ne"), command_next_action);
|
||||||
|
cli.subcommand(
|
||||||
|
Command::new("printCurrentAction").alias("cu"),
|
||||||
|
command_current_action,
|
||||||
|
);
|
||||||
|
cli.subcommand(
|
||||||
|
Command::new("listActions").alias("la"),
|
||||||
|
command_list_actions,
|
||||||
|
);
|
||||||
cli.subcommand(
|
cli.subcommand(
|
||||||
Command::new("listActivities").alias("lac"),
|
Command::new("listActivities").alias("lac"),
|
||||||
command_list_activities,
|
command_list_activities,
|
||||||
@@ -43,9 +61,58 @@ impl MizePart for TimeTrack {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn command_next_action(_: &ArgMatches, mut mize: Mize) -> MizeResult<()> {
|
||||||
|
let mut spacetime = mize.get_part_native::<SpacetimePart>("spacetime")?;
|
||||||
|
let con = spacetime.con();
|
||||||
|
let (wait_tx, waiter_rx) = std::sync::oneshot::channel::<()>();
|
||||||
|
con.reducers.next_action_then(|_, _| {
|
||||||
|
wait_tx.send(()).unwrap();
|
||||||
|
})?;
|
||||||
|
waiter_rx.recv()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn command_current_action(_: &ArgMatches, mut mize: Mize) -> MizeResult<()> {
|
||||||
|
let mut spacetime = mize.get_part_native::<SpacetimePart>("spacetime")?;
|
||||||
|
let action = get_current_action(&mut mize, spacetime.con())?;
|
||||||
|
println!("{}", action.name);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_current_action(mize: &mut Mize, con: &DbConnection) -> MizeResult<Action> {
|
||||||
|
let (wait_tx, wait_rx) = std::sync::oneshot::channel::<Action>();
|
||||||
|
con.subscription_builder()
|
||||||
|
.on_applied(|ctx| {
|
||||||
|
let task_part_data = ctx.db.task_part().identity().find(&ctx.identity());
|
||||||
|
if task_part_data.is_none() {
|
||||||
|
wait_tx
|
||||||
|
.send(Action {
|
||||||
|
name: "fillier".to_string(),
|
||||||
|
activity: None,
|
||||||
|
task: None,
|
||||||
|
start: None,
|
||||||
|
end: None,
|
||||||
|
duration: None,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
} else {
|
||||||
|
wait_tx.send(task_part_data.unwrap().current).unwrap();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.add_query(|q| {
|
||||||
|
q.from.task_part()
|
||||||
|
//.r#where(|row| row.identity.eq(con.identity()))
|
||||||
|
})
|
||||||
|
.subscribe();
|
||||||
|
let action = wait_rx.recv().unwrap();
|
||||||
|
Ok(action)
|
||||||
|
}
|
||||||
|
|
||||||
fn command_list_activities(_: &ArgMatches, mut mize: Mize) -> MizeResult<()> {
|
fn command_list_activities(_: &ArgMatches, mut mize: Mize) -> MizeResult<()> {
|
||||||
let mut spacetime = mize.get_part_native::<SpacetimePart>("spacetime")?;
|
let mut spacetime = mize.get_part_native::<SpacetimePart>("spacetime")?;
|
||||||
let activities = get_activities(&mut mize, spacetime.con())?;
|
let activities = get_activities(&mut mize, spacetime.con())?;
|
||||||
|
|
||||||
for ac in activities.clone() {
|
for ac in activities.clone() {
|
||||||
print!("ac {}: {}", ac.id, ac.name);
|
print!("ac {}: {}", ac.id, ac.name);
|
||||||
if !ac.parents_ids.is_empty() {
|
if !ac.parents_ids.is_empty() {
|
||||||
@@ -60,6 +127,121 @@ fn command_list_activities(_: &ArgMatches, mut mize: Mize) -> MizeResult<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn command_list_actions(_: &ArgMatches, mut mize: Mize) -> MizeResult<()> {
|
||||||
|
let mut spacetime = mize.get_part_native::<SpacetimePart>("spacetime")?;
|
||||||
|
|
||||||
|
let actions = get_actions(spacetime.con())?;
|
||||||
|
|
||||||
|
for action in actions {
|
||||||
|
println!("{}", action.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn command_edit_action_list(matches: &ArgMatches, mut mize: Mize) -> MizeResult<()> {
|
||||||
|
let mut spacetime = mize.get_part_native::<SpacetimePart>("spacetime")?;
|
||||||
|
|
||||||
|
// maybe append a template to the action list
|
||||||
|
if matches.get_flag("defaultTemplate") {
|
||||||
|
println!("Appending template...");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// get list of actions
|
||||||
|
let mut actions = get_actions(spacetime.con())?;
|
||||||
|
|
||||||
|
// write to tmp file
|
||||||
|
let mut tmp_file_content = actions_to_string(&actions)?;
|
||||||
|
let tmp_file = std::env::temp_dir().join(format!(
|
||||||
|
"ppc-edit-actions-{}.txt",
|
||||||
|
chrono::Utc::now().timestamp()
|
||||||
|
));
|
||||||
|
std::fs::write(&tmp_file, tmp_file_content)
|
||||||
|
.map_err(|e| mize_err!("Failed to write temp file: {}", e))?;
|
||||||
|
|
||||||
|
// open $EDITOR blocking
|
||||||
|
std::process::Command::new("nvim")
|
||||||
|
.arg(&tmp_file)
|
||||||
|
.status()
|
||||||
|
.map_err(|e| mize_err!("Failed to run nvim: {}", e))?;
|
||||||
|
|
||||||
|
// read file and update db
|
||||||
|
let new_file_content = std::fs::read_to_string(&tmp_file)
|
||||||
|
.map_err(|e| mize_err!("Failed to read temp file: {}", e))?;
|
||||||
|
|
||||||
|
actions = actions_from_string(actions, new_file_content)?;
|
||||||
|
set_actions(actions, spacetime.con())?;
|
||||||
|
|
||||||
|
// delete tmpfile
|
||||||
|
let _ = std::fs::remove_file(&tmp_file);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_actions(con: &DbConnection) -> MizeResult<Vec<Action>> {
|
||||||
|
let (exit_tx, exit_rx) = std::sync::oneshot::channel::<Vec<Action>>();
|
||||||
|
con.subscription_builder()
|
||||||
|
.on_applied(|ctx| {
|
||||||
|
let task_part_data = ctx.db.task_part().identity().find(&ctx.identity());
|
||||||
|
if task_part_data.is_none() {
|
||||||
|
exit_tx.send(Vec::new()).unwrap();
|
||||||
|
} else {
|
||||||
|
exit_tx.send(task_part_data.unwrap().upcoming).unwrap();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.add_query(|q| {
|
||||||
|
q.from.task_part()
|
||||||
|
//.r#where(|row| row.identity.eq(con.identity()))
|
||||||
|
})
|
||||||
|
.subscribe();
|
||||||
|
let activities = exit_rx.recv().unwrap();
|
||||||
|
Ok(activities)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_actions(actions: Vec<Action>, con: &DbConnection) -> MizeResult<()> {
|
||||||
|
let (wait_tx, waiter_rx) = std::sync::oneshot::channel::<()>();
|
||||||
|
con.reducers
|
||||||
|
.update_upcoming_then(actions, |_, _| wait_tx.send(()).unwrap())?;
|
||||||
|
waiter_rx.recv().unwrap();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn actions_to_string(actions: &Vec<Action>) -> MizeResult<String> {
|
||||||
|
let mut string = String::new();
|
||||||
|
|
||||||
|
for action in actions.iter() {
|
||||||
|
string.push_str(format!("{}\n", action.name).as_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn actions_from_string(mut old_actions: Vec<Action>, string: String) -> MizeResult<Vec<Action>> {
|
||||||
|
let mut new_actions = Vec::new();
|
||||||
|
for line in string.lines() {
|
||||||
|
if line.trim().is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut action = Action {
|
||||||
|
name: line.to_owned(),
|
||||||
|
activity: None,
|
||||||
|
task: None,
|
||||||
|
start: None,
|
||||||
|
end: None,
|
||||||
|
duration: None,
|
||||||
|
};
|
||||||
|
parse_action(&mut action);
|
||||||
|
new_actions.push(action);
|
||||||
|
}
|
||||||
|
Ok(new_actions)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_action(action: &mut Action) {
|
||||||
|
let parts: Vec<&str> = action.name.split_whitespace().collect();
|
||||||
|
}
|
||||||
|
|
||||||
fn command_edit_activities(_: &ArgMatches, mut mize: Mize) -> MizeResult<()> {
|
fn command_edit_activities(_: &ArgMatches, mut mize: Mize) -> MizeResult<()> {
|
||||||
let mut spacetime = mize.get_part_native::<SpacetimePart>("spacetime")?;
|
let mut spacetime = mize.get_part_native::<SpacetimePart>("spacetime")?;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user