feat/Make API_URL a runtime config in the client

pull/33/head
Miroito 3 years ago
parent 3cfbf0e5f2
commit a18c4afdb7

145
Cargo.lock generated

@ -60,12 +60,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]] [[package]]
name = "arrayvec" name = "arrayvec"
version = "0.7.2" version = "0.7.2"
@ -253,9 +247,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]] [[package]]
name = "axum" name = "axum"
version = "0.6.12" version = "0.6.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349f8ccfd9221ee7d1f3d4b33e1f8319b3a81ed8f61f2ea40b37b859794b4491" checksum = "113713495a32dd0ab52baf5c10044725aa3aec00b31beda84218e469029b72a3"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum-core", "axum-core",
@ -285,9 +279,9 @@ dependencies = [
[[package]] [[package]]
name = "axum-core" name = "axum-core"
version = "0.3.3" version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2f958c80c248b34b9a877a643811be8dbca03ca5ba827f2b63baf3a81e5fc4e" checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bytes", "bytes",
@ -354,18 +348,6 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitvec"
version = "0.19.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55f93d0ef3363c364d5976646a38f04cf67cfe1d4c8d160cdea02cab2c116b33"
dependencies = [
"funty",
"radium",
"tap",
"wyz",
]
[[package]] [[package]]
name = "block-buffer" name = "block-buffer"
version = "0.10.3" version = "0.10.3"
@ -689,13 +671,13 @@ dependencies = [
[[package]] [[package]]
name = "css-minify" name = "css-minify"
version = "0.2.2" version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692b185e3b7c9af96b3195f3021f53a931d896968ed2ad3fb1cdb6558b30c9ab" checksum = "874c6e2d19f8d4a285083b11a3241bfbe01ac3ed85f26e1e6b34888d960552bd"
dependencies = [ dependencies = [
"derive_more", "derive_more",
"indexmap", "indexmap",
"nom 6.1.2", "nom",
] ]
[[package]] [[package]]
@ -754,9 +736,9 @@ dependencies = [
[[package]] [[package]]
name = "darling" name = "darling"
version = "0.13.4" version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"darling_macro", "darling_macro",
@ -764,9 +746,9 @@ dependencies = [
[[package]] [[package]]
name = "darling_core" name = "darling_core"
version = "0.13.4" version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
dependencies = [ dependencies = [
"fnv", "fnv",
"ident_case", "ident_case",
@ -778,9 +760,9 @@ dependencies = [
[[package]] [[package]]
name = "darling_macro" name = "darling_macro"
version = "0.13.4" version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"quote", "quote",
@ -1033,12 +1015,6 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
[[package]]
name = "funty"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
[[package]] [[package]]
name = "futures" name = "futures"
version = "0.3.26" version = "0.3.26"
@ -1222,9 +1198,9 @@ dependencies = [
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.3.15" version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21"
dependencies = [ dependencies = [
"bytes", "bytes",
"fnv", "fnv",
@ -1368,9 +1344,9 @@ dependencies = [
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "0.14.25" version = "0.14.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-channel", "futures-channel",
@ -1523,19 +1499,6 @@ dependencies = [
"spin", "spin",
] ]
[[package]]
name = "lexical-core"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
dependencies = [
"arrayvec 0.5.2",
"bitflags",
"cfg-if",
"ryu",
"static_assertions",
]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.139" version = "0.2.139"
@ -1648,22 +1611,23 @@ dependencies = [
[[package]] [[package]]
name = "minify-html-onepass" name = "minify-html-onepass"
version = "0.10.1" version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d552bca3e100fe7835371eba6b37c83a857a6fe5f400e176dc15a28403e0d1c" checksum = "c89548d0be6d3c7295335473fbe5c021fde64de738e01312301c90b9f1dd8476"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"css-minify", "css-minify",
"lazy_static", "lazy_static",
"memchr", "memchr",
"minify-js", "minify-js",
"rustc-hash",
] ]
[[package]] [[package]]
name = "minify-js" name = "minify-js"
version = "0.2.9" version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe033709f5a1159736cf7e22748518ffb75af26f3a6264d52ecc8bb38c68c36" checksum = "c300f90ba1138b5c5daf5d9441dc9bdc67b808aac22cf638362a2647bc213be4"
dependencies = [ dependencies = [
"lazy_static", "lazy_static",
"parse-js", "parse-js",
@ -1714,19 +1678,6 @@ dependencies = [
"tempfile", "tempfile",
] ]
[[package]]
name = "nom"
version = "6.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2"
dependencies = [
"bitvec",
"funty",
"lexical-core",
"memchr",
"version_check",
]
[[package]] [[package]]
name = "nom" name = "nom"
version = "7.1.3" version = "7.1.3"
@ -1958,9 +1909,9 @@ dependencies = [
[[package]] [[package]]
name = "parse-js" name = "parse-js"
version = "0.3.1" version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66bb85ec60d22b9e6d4adac1e3dbdaf3903a4485f476c5f4dd7ed1285cbf4dad" checksum = "30534759e6ad87aa144c396544747e1c25b1020bd133356fd758c8facec764e5"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"lazy_static", "lazy_static",
@ -1990,9 +1941,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
[[package]] [[package]]
name = "perseus" name = "perseus"
version = "0.4.0-beta.22" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a3bf9f8bbc387bcc1b5e69e380b78aa598777e1b44872816ed86fc599aa9729" checksum = "c692ad07b59511f3f2faac6ae47136b0f7f28fe92a962da60459b659ddf947ca"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"chrono", "chrono",
@ -2021,9 +1972,9 @@ dependencies = [
[[package]] [[package]]
name = "perseus-axum" name = "perseus-axum"
version = "0.4.0-beta.22" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ca2d139e1eb507cca8ffcda8878f1da174285058843bf75d4f8c64b7016d8a8" checksum = "58e7975a5d967d3a1e39ffe479b58588e1db03e8ec03b2666e633cfd07793bc0"
dependencies = [ dependencies = [
"axum", "axum",
"perseus", "perseus",
@ -2032,9 +1983,9 @@ dependencies = [
[[package]] [[package]]
name = "perseus-macro" name = "perseus-macro"
version = "0.4.0-beta.22" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5620bc354c480258abe55f2bcdaa5569d584a5b76fb7a1dc4fb34a5d5bd9dcf" checksum = "868803376c686cfe84dc5a84114ea631bd561f243f1a48115c4418b19c9d199b"
dependencies = [ dependencies = [
"darling", "darling",
"proc-macro2", "proc-macro2",
@ -2221,12 +2172,6 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "radium"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.8.5" version = "0.8.5"
@ -2441,7 +2386,7 @@ version = "1.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13cf35f7140155d02ba4ec3294373d513a3c7baa8364c162b030e33c61520a8" checksum = "e13cf35f7140155d02ba4ec3294373d513a3c7baa8364c162b030e33c61520a8"
dependencies = [ dependencies = [
"arrayvec 0.7.2", "arrayvec",
"borsh", "borsh",
"bytecheck", "bytecheck",
"byteorder", "byteorder",
@ -2453,6 +2398,12 @@ dependencies = [
"serde_json", "serde_json",
] ]
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]] [[package]]
name = "rustc_version" name = "rustc_version"
version = "0.2.3" version = "0.2.3"
@ -2951,7 +2902,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e" checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e"
dependencies = [ dependencies = [
"itertools", "itertools",
"nom 7.1.3", "nom",
"unicode_categories", "unicode_categories",
] ]
@ -3059,12 +3010,6 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]] [[package]]
name = "stdweb" name = "stdweb"
version = "0.4.20" version = "0.4.20"
@ -3225,7 +3170,7 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92914a2f809b636d245b28d8a734801ecb8ff9c4996bbe6ea4176582e12503eb" checksum = "92914a2f809b636d245b28d8a734801ecb8ff9c4996bbe6ea4176582e12503eb"
dependencies = [ dependencies = [
"nom 7.1.3", "nom",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 1.0.108", "syn 1.0.108",
@ -3276,12 +3221,6 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]]
name = "tap"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.3.0" version = "3.3.0"
@ -4064,12 +4003,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "wyz"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
[[package]] [[package]]
name = "zeroize" name = "zeroize"
version = "1.5.7" version = "1.5.7"

@ -9,7 +9,7 @@ edition = "2021"
chrono = { workspace = true, features = ["serde"] } chrono = { workspace = true, features = ["serde"] }
serde = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true } serde_json = { workspace = true }
perseus = { version = "0.4.0-beta.22", features = ["hydrate"] } perseus = { version = "0.4", features = ["hydrate"] }
sycamore = { version = "^0.8.1", features = [ sycamore = { version = "^0.8.1", features = [
"ssr", "ssr",
"serde", "serde",
@ -23,9 +23,7 @@ fantoccini = "^0.19.3"
[target.'cfg(engine)'.dependencies] [target.'cfg(engine)'.dependencies]
tokio = { version = "1", features = ["macros", "rt", "rt-multi-thread"] } tokio = { version = "1", features = ["macros", "rt", "rt-multi-thread"] }
reqwest = { version = "0.11", features = ["json", "rustls-tls"] } reqwest = { version = "0.11", features = ["json", "rustls-tls"] }
perseus-axum = { version = "=0.4.0-beta.22", features = ["dflt-server"] } perseus-axum = { version = "0.4", features = ["dflt-server"] }
# dotenvy = { workspace = true }
# envy = { workspace = true }
[target.'cfg(client)'.dependencies] [target.'cfg(client)'.dependencies]
reqwasm = "0.5.0" reqwasm = "0.5.0"

@ -1,13 +1,13 @@
# get the base image # get the base image
FROM rust:1.66-slim AS build FROM rust:1.69 AS build
# install build dependencies # install build dependencies
RUN apt update \ RUN apt-get update \
&& apt install -y --no-install-recommends lsb-release apt-transport-https \ && apt-get install -y --no-install-recommends lsb-release apt-transport-https \
build-essential curl wget pkg-config libssl-dev build-essential curl wget pkg-config
# vars # vars
ENV PERSEUS_VERSION=0.4.0-beta.22 \ ENV PERSEUS_VERSION=0.4.0 \
PERSEUS_SIZE_OPT_VERSION=0.1.9 \ PERSEUS_SIZE_OPT_VERSION=0.1.9 \
ESBUILD_VERSION=0.15.18 \ ESBUILD_VERSION=0.15.18 \
BINARYEN_VERSION=112 BINARYEN_VERSION=112
@ -16,10 +16,8 @@ ENV PERSEUS_VERSION=0.4.0-beta.22 \
WORKDIR /app WORKDIR /app
# download the target for wasm # download the target for wasm
RUN rustup target add wasm32-unknown-unknown RUN rustup target add wasm32-unknown-unknown;\
cargo install wasm-pack # might not be a bad idea to fix the version of this in the future
# install wasm-pack
RUN cargo install wasm-pack
# retrieve the src dir # retrieve the src dir
COPY . . COPY . .
@ -29,25 +27,19 @@ COPY . .
WORKDIR /app/client WORKDIR /app/client
# install perseus-cli # install perseus-cli
RUN cargo install perseus-cli --version $PERSEUS_VERSION RUN cargo install perseus-cli --version $PERSEUS_VERSION;\
perseus clean
# clean and prep app
RUN perseus clean
# specify deps in app config # specify deps in app config
RUN sed -i s"/perseus = .*/perseus = \"${PERSEUS_VERSION}\"/" ./Cargo.toml \ # RUN sed -i s"/perseus = .*/perseus = \"${PERSEUS_VERSION}\"/" ./Cargo.toml \
&& sed -i s"/perseus-size-opt = .*/perseus-size-opt = \"${PERSEUS_SIZE_OPT_VERSION}\"/" ./Cargo.toml \ # && sed -i s"/perseus-size-opt = .*/perseus-size-opt = \"${PERSEUS_SIZE_OPT_VERSION}\"/" ./Cargo.toml \
&& cat ./Cargo.toml # && cat ./Cargo.toml
#
# modify main.rs # # modify main.rs
RUN sed -i s'/SizeOpts::default()/SizeOpts { wee_alloc: true, lto: true, opt_level: "s".to_string(), codegen_units: 1, enable_fluent_bundle_patch: false, }/' ./src/main.rs \ # RUN sed -i s'/SizeOpts::default()/SizeOpts { wee_alloc: true, lto: true, opt_level: "z".to_string(), codegen_units: 1, enable_fluent_bundle_patch: false, }/' ./src/main.rs \
&& cat ./src/main.rs # && cat ./src/main.rs
# # run plugin(s) to adjust app
ARG API_URL # RUN perseus tinker
ENV API_URL $API_URL
# run plugin(s) to adjust app
RUN perseus tinker
# single-threaded perseus CLI mode required for low memory environments # single-threaded perseus CLI mode required for low memory environments
#ENV PERSEUS_CLI_SEQUENTIAL=true #ENV PERSEUS_CLI_SEQUENTIAL=true
@ -84,4 +76,4 @@ COPY --from=build /app/client/pkg /app/
ENV HOST=0.0.0.0 ENV HOST=0.0.0.0
CMD ./server CMD ["./server"]

@ -1,2 +1,17 @@
use serde::{Deserialize, Serialize};
pub mod routes; pub mod routes;
pub mod types; pub mod types;
#[derive(Clone, Serialize, Deserialize)]
pub struct FastInsidersApi {
url: String,
}
impl FastInsidersApi {
pub fn new(url: &str) -> Self {
FastInsidersApi {
url: url.to_owned(),
}
}
}

@ -1 +1,2 @@
pub mod company;
pub mod transaction; pub mod transaction;

@ -1,20 +1,21 @@
use crate::api::types::{ use crate::api::{
types::{
paginated_response::PaginatedResponse, paginated_response::PaginatedResponse,
transaction::{LatestTransaction, TransactionCompany, TransactionsAggregated}, transaction::{LatestTransaction, TransactionCompany, TransactionsAggregated},
},
FastInsidersApi,
}; };
impl FastInsidersApi {
pub async fn get_transactions( pub async fn get_transactions(
&self,
company_slug: Option<String>, company_slug: Option<String>,
page: i64, page: i64,
size: i64, size: i64,
) -> Result<PaginatedResponse<TransactionCompany>, ()> { ) -> Result<PaginatedResponse<TransactionCompany>, ()> {
use crate::env::Config;
// TODO: Remove build-time environment variable
let api_url = Config::new().api_url;
let route = &format!( let route = &format!(
"{}transaction?{}&page={}&size={}", "{}/transaction?{}&page={}&size={}",
api_url, self.url,
company_slug.map_or("".to_string(), |c| format!("company_slug={}", c)), company_slug.map_or("".to_string(), |c| format!("company_slug={}", c)),
page, page,
size, size,
@ -41,17 +42,14 @@ pub async fn get_transactions(
} }
pub async fn get_aggregated_transactions( pub async fn get_aggregated_transactions(
&self,
hours: Option<String>, hours: Option<String>,
page: i64, page: i64,
size: i64, size: i64,
) -> Result<PaginatedResponse<TransactionsAggregated>, ()> { ) -> Result<PaginatedResponse<TransactionsAggregated>, ()> {
use crate::env::Config;
// TODO: Remove build-time environment variable
let api_url = Config::new().api_url;
let route = &format!( let route = &format!(
"{}transaction/aggregated?{}&page={}&size={}", "{}/transaction/aggregated?{}&page={}&size={}",
api_url, self.url,
hours.map_or("".to_string(), |c| format!("hours={}", c)), hours.map_or("".to_string(), |c| format!("hours={}", c)),
page, page,
size, size,
@ -78,15 +76,15 @@ pub async fn get_aggregated_transactions(
} }
pub async fn get_latest_transactions( pub async fn get_latest_transactions(
&self,
_: Option<String>, _: Option<String>,
page: i64, page: i64,
size: i64, size: i64,
) -> Result<PaginatedResponse<LatestTransaction>, ()> { ) -> Result<PaginatedResponse<LatestTransaction>, ()> {
use crate::env::Config; let route = &format!(
"{}/transaction/latest?page={}&size={}",
// TODO: Remove build-time environment variable self.url, page, size,
let api_url = Config::new().api_url; );
let route = &format!("{}transaction/latest?page={}&size={}", api_url, page, size,);
#[cfg(client)] #[cfg(client)]
let res = reqwasm::http::Request::get(route) let res = reqwasm::http::Request::get(route)
@ -107,3 +105,4 @@ pub async fn get_latest_transactions(
return Ok(res); return Ok(res);
} }
}

@ -1,3 +1,5 @@
use std::future::Future;
use perseus::prelude::*; use perseus::prelude::*;
use serde::Deserialize; use serde::Deserialize;
use sycamore::prelude::*; use sycamore::prelude::*;
@ -7,19 +9,23 @@ pub trait IntoAsyncSelectListItem {
} }
#[derive(Prop)] #[derive(Prop)]
pub struct AsyncSelectRx<'a, T> pub struct AsyncSelectRx<'a, T, F, R>
where where
T: 'static + PartialEq + Clone + IntoAsyncSelectListItem, T: 'static + PartialEq + Clone + IntoAsyncSelectListItem,
F: Future<Output = Result<Vec<T>, ()>>,
R: Fn(String, Option<u64>) -> F,
{ {
pub remote_list: &'a ReadSignal<String>, pub route: &'a R,
pub selected_item: &'a Signal<Option<T>>, pub selected_item: &'a Signal<Option<T>>,
} }
#[component] #[component]
pub fn BaseAsyncSelect<'a, G, T>(cx: Scope<'a>, props: AsyncSelectRx<'a, T>) -> View<G> pub fn BaseAsyncSelect<'a, G, T, F, R>(cx: Scope<'a>, props: AsyncSelectRx<'a, T, F, R>) -> View<G>
where where
G: Html, G: Html,
T: 'static + PartialEq + Clone + IntoAsyncSelectListItem, T: 'a + PartialEq + Clone + IntoAsyncSelectListItem,
F: Future<Output = Result<Vec<T>, ()>>,
R: Fn(String, Option<u64>) -> F,
for<'de> T: Deserialize<'de>, for<'de> T: Deserialize<'de>,
{ {
let input = create_signal(cx, "".to_string()); let input = create_signal(cx, "".to_string());
@ -47,16 +53,7 @@ where
#[cfg(client)] #[cfg(client)]
spawn_local_scoped(cx, async move { spawn_local_scoped(cx, async move {
let res = reqwasm::http::Request::get(&format!( let res = (props.route)(input.get().to_string(), Some(5))
"{}/{}?limit={}",
props.remote_list.get(),
input.get(),
5
))
.send()
.await
.unwrap()
.json::<Vec<T>>()
.await .await
.unwrap(); .unwrap();
visible.set(!res.is_empty()); visible.set(!res.is_empty());
@ -76,7 +73,7 @@ where
let item = x.clone(); let item = x.clone();
view! {cx, view! {cx,
li ( li (
class="w-full p-2 cursor-pointer dark:hover:bg-slate-900 hover:bg-slate-400", class="p-2 w-full cursor-pointer dark:hover:bg-slate-900 hover:bg-slate-400",
on:mousedown=move |_| { on:mousedown=move |_| {
selected.set(true); selected.set(true);
props.selected_item.set(Some(item.clone())); props.selected_item.set(Some(item.clone()));

@ -13,28 +13,29 @@ use crate::{
#[derive(Prop)] #[derive(Prop)]
pub struct PaginatedTableStateRx<'a, M, F, C> pub struct PaginatedTableStateRx<'a, M, F, C>
where where
M: 'static, M: 'a,
C: Fn(Option<String>, i64, i64) -> F, C: Fn(Option<String>, i64, i64) -> F,
F: std::future::Future<Output = Result<PaginatedResponse<M>, ()>>, F: std::future::Future<Output = Result<PaginatedResponse<M>, ()>> + 'a,
{ {
pub record_label: String, pub record_label: String,
pub route: C, pub route: &'a C,
pub filter: Option<String>, pub filter: Option<String>,
pub table_class: &'a String, pub table_class: &'a String,
} }
impl<'a, M, F, C> PaginatedTableStateRx<'a, M, F, C> impl<'a, M, F, C> PaginatedTableStateRx<'a, M, F, C>
where where
M: 'static, M: 'a,
C: Fn(Option<String>, i64, i64) -> F, C: Fn(Option<String>, i64, i64) -> F,
F: std::future::Future<Output = Result<PaginatedResponse<M>, ()>>, F: std::future::Future<Output = Result<PaginatedResponse<M>, ()>> + 'a,
{ {
async fn get_data(&self, page: i64, size: i64) -> Result<PaginatedResponse<M>, ()> { async fn get_data(&self, page: i64, size: i64) -> Result<PaginatedResponse<M>, ()> {
(self.route)(self.filter.clone(), page, size).await (self.route)(self.filter.clone(), page, size).await
} }
} }
/// This is a generic component that will display a paginated table given a function of the generic signature C and a filter represented by an Option<String> /// This is a generic component that will display a paginated table given a
/// function of the generic signature C and a filter represented by an Option<String>
#[component] #[component]
pub fn PaginatedTable<'a, G, M, F, C>( pub fn PaginatedTable<'a, G, M, F, C>(
cx: Scope<'a>, cx: Scope<'a>,
@ -42,11 +43,11 @@ pub fn PaginatedTable<'a, G, M, F, C>(
) -> View<G> ) -> View<G>
where where
G: Html, G: Html,
M: 'static + Clone, M: 'a + Clone,
PaginatedResponse<M>: IntoTableData<G>, PaginatedResponse<M>: IntoTableData<G>,
for<'de> M: Deserialize<'de>, for<'de> M: Deserialize<'de>,
C: Fn(Option<String>, i64, i64) -> F + 'static, C: Fn(Option<String>, i64, i64) -> F,
F: std::future::Future<Output = Result<PaginatedResponse<M>, ()>> + 'static, F: std::future::Future<Output = Result<PaginatedResponse<M>, ()>> + 'a,
{ {
let paginated_data = create_signal(cx, None); let paginated_data = create_signal(cx, None);
let table_prop: TableContentRx<G> = TableContentRx { let table_prop: TableContentRx<G> = TableContentRx {
@ -81,11 +82,11 @@ where
page.set(0); page.set(0);
}); });
let props_sig = create_signal(cx, props); let props_sig = create_signal(cx, props);
#[cfg(client)]
create_effect(cx, move || { create_effect(cx, move || {
let page = *page.get(); let page = *page.get();
let page_size_s = page_size_string.get(); let page_size_s = page_size_string.get();
let page_size = page_size_s.parse().unwrap_or(20); let page_size = page_size_s.parse().unwrap_or(20);
#[cfg(client)]
spawn_local_scoped(cx, async move { spawn_local_scoped(cx, async move {
let res = props_sig.get().get_data(page, page_size).await.unwrap(); let res = props_sig.get().get_data(page, page_size).await.unwrap();
paginated_data.set(Some(res.clone())); paginated_data.set(Some(res.clone()));
@ -101,7 +102,7 @@ where
(if paginated_data.get().is_some() { (if paginated_data.get().is_some() {
if *n_rows.get() == 0 { if *n_rows.get() == 0 {
view!{cx, view!{cx,
div (class="bg-slate-200 dark:bg-slate-800 text-center rounded-md") { div (class="text-center rounded-md bg-slate-200 dark:bg-slate-800") {
(format!("No {}", props_sig.get().record_label)) (format!("No {}", props_sig.get().record_label))
} }
} }
@ -111,7 +112,7 @@ where
p (class="text-right") { (format!("{} {}", n_rows.get(), props_sig.get().record_label)) } p (class="text-right") { (format!("{} {}", n_rows.get(), props_sig.get().record_label)) }
div (class="flex flex-row justify-between") { div (class="flex flex-row justify-between") {
select (bind:value=page_size_string, select (bind:value=page_size_string,
class="p-2 justify-end text-slate-700 dark:text-slate-100 bg-slate-200 dark:bg-slate-800 rounded-md", class="justify-end p-2 rounded-md text-slate-700 bg-slate-200 dark:text-slate-100 dark:bg-slate-800",
id="size-select", id="size-select",
) { ) {
option (value="10", selected=(*page_size_string.get()).eq("10")) { "10" } option (value="10", selected=(*page_size_string.get()).eq("10")) { "10" }
@ -120,11 +121,11 @@ where
option (value="40", selected=(*page_size_string.get()).eq("40")) { "40" } option (value="40", selected=(*page_size_string.get()).eq("40")) { "40" }
option (value="50", selected=(*page_size_string.get()).eq("50")) { "50" } option (value="50", selected=(*page_size_string.get()).eq("50")) { "50" }
} }
div (id="page_buttons", class="flex flex-row p-2 bg-slate-200 dark:bg-slate-800 rounded-md") { div (id="page_buttons", class="flex flex-row p-2 rounded-md bg-slate-200 dark:bg-slate-800") {
button (on:click=page_down,class="m-1 hover:font-bold") { button (on:click=page_down,class="m-1 hover:font-bold") {
"<<" "<<"
} }
div (class="m-1 align-middle text-center") { div (class="m-1 text-center align-middle") {
(format!("{}/{}",*page.get() + 1, *n_page.get()) ) (format!("{}/{}",*page.get() + 1, *n_page.get()) )
} }
button (on:click=page_up, class="m-1 hover:font-bold") { button (on:click=page_up, class="m-1 hover:font-bold") {

@ -10,22 +10,8 @@ pub struct Config {
#[cfg(engine)] #[cfg(engine)]
impl Config { impl Config {
pub fn new() -> Self { pub fn new() -> Self {
let api_url = env!("API_URL").to_string(); let api_url =
std::env::var("API_URL").expect("The environment variable API_URL should be set");
Config { api_url } Config { api_url }
} }
} }
#[cfg(client)]
impl Config {
pub fn new() -> Self {
let api_url = env!("API_URL").to_string();
Config { api_url }
}
}
#[cfg(engine)]
impl Default for Config {
fn default() -> Self {
Config::new()
}
}

@ -1,26 +1,49 @@
use perseus::prelude::*; use perseus::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::env::Config; use crate::api::FastInsidersApi;
use perseus::state::GlobalStateCreator; use perseus::state::GlobalStateCreator;
pub fn get_global_state_creator() -> GlobalStateCreator { pub fn get_global_state_creator() -> GlobalStateCreator {
GlobalStateCreator::new().build_state_fn(get_build_state) GlobalStateCreator::new()
.build_state_fn(get_build_state)
.request_state_fn(get_request_state)
.amalgamate_states_fn(amalgamate_states)
} }
#[derive(Serialize, Deserialize, ReactiveState)] #[derive(Serialize, Deserialize, ReactiveState)]
#[rx(alias = "AppStateRx")] #[rx(alias = "AppStateRx")]
pub struct AppState { pub struct AppState {
pub dark_mode: bool, pub dark_mode: bool,
pub config: Config, pub api: FastInsidersApi,
}
#[engine_only_fn]
pub async fn get_build_state() -> AppState {
AppState {
dark_mode: true,
api: FastInsidersApi::new(""), // It's unfortunately not possible to have a different type
// for the build state and the request state, I would rather
// have left this out
// This will also only ever work as long as we don't need the api
// while building the app, so no SSR!
}
} }
#[engine_only_fn] #[engine_only_fn]
pub async fn get_build_state(_locale: String) -> AppState { async fn get_request_state(_req: Request) -> AppState {
use crate::env::Config; use crate::env::Config;
let config = Config::new(); let config = Config::new();
AppState { AppState {
config,
dark_mode: true, dark_mode: true,
api: FastInsidersApi::new(&config.api_url),
}
}
#[engine_only_fn]
async fn amalgamate_states(build_state: AppState, request_state: AppState) -> AppState {
AppState {
dark_mode: build_state.dark_mode,
api: request_state.api,
} }
} }

@ -2,10 +2,7 @@ use perseus::prelude::*;
use sycamore::prelude::*; use sycamore::prelude::*;
use crate::{ use crate::{
api::{ api::types::transaction::{LatestTransaction, TransactionsAggregated},
routes::transaction::{get_aggregated_transactions, get_latest_transactions},
types::transaction::{LatestTransaction, TransactionsAggregated},
},
components::{ components::{
main_content_container::MainContentContainer, main_content_container::MainContentContainer,
paginated_data_table::{PaginatedTable, PaginatedTableStateRx}, paginated_data_table::{PaginatedTable, PaginatedTableStateRx},
@ -14,23 +11,33 @@ use crate::{
global_state::AppStateRx, global_state::AppStateRx,
}; };
fn index_page<G: Html>(cx: Scope) -> View<G> { fn index_page<G: Html>(cx: BoundedScope) -> View<G> {
let global_state = Reactor::<G>::from_cx(cx).get_global_state::<AppStateRx>(cx); let reactor = Reactor::<G>::from_cx(cx);
let global_state = reactor.get_global_state::<AppStateRx>(cx);
let api = global_state.api.get();
let api_scope_ref = create_ref(cx, api);
let table_classes = create_ref(cx, "w-full".to_string()); let table_classes = create_ref(cx, "w-full".to_string());
let route_ref = create_ref(cx, move |c, p, s| {
api_scope_ref.get_latest_transactions(c, p, s)
});
let latest_transactions: PaginatedTableStateRx<LatestTransaction, _, _> = let latest_transactions: PaginatedTableStateRx<LatestTransaction, _, _> =
PaginatedTableStateRx { PaginatedTableStateRx {
record_label: "transactions".to_owned(), record_label: "transactions".to_owned(),
route: get_latest_transactions, route: route_ref,
filter: Some("72".to_string()), filter: Some("72".to_string()),
table_class: table_classes, table_class: table_classes,
}; };
let route_ref = create_ref(cx, move |c, p, s| {
api_scope_ref.get_aggregated_transactions(c, p, s)
});
let table_transactions_month: PaginatedTableStateRx<TransactionsAggregated, _, _> = let table_transactions_month: PaginatedTableStateRx<TransactionsAggregated, _, _> =
PaginatedTableStateRx { PaginatedTableStateRx {
record_label: "companies".to_owned(), record_label: "companies".to_owned(),
route: get_aggregated_transactions, route: route_ref,
filter: Some((24 * 30).to_string()), filter: Some((24 * 30).to_string()),
table_class: table_classes, table_class: table_classes,
}; };

@ -3,8 +3,6 @@ use serde::{Deserialize, Serialize};
use sycamore::prelude::*; use sycamore::prelude::*;
use crate::{ use crate::{
api::routes::transaction::get_transactions,
api::types::{company::Company, transaction::TransactionCompany},
components::{ components::{
base_async_select::{AsyncSelectRx, BaseAsyncSelect}, base_async_select::{AsyncSelectRx, BaseAsyncSelect},
base_button::{BaseButton, BaseButtonStateRx}, base_button::{BaseButton, BaseButtonStateRx},
@ -12,7 +10,6 @@ use crate::{
paginated_data_table::{PaginatedTable, PaginatedTableStateRx}, paginated_data_table::{PaginatedTable, PaginatedTableStateRx},
the_header::TheHeader, the_header::TheHeader,
}, },
env::Config,
global_state::AppStateRx, global_state::AppStateRx,
}; };
@ -23,8 +20,10 @@ pub struct TransactionsPageState {
} }
#[auto_scope] #[auto_scope]
fn transactions_page<G: Html>(cx: Scope, state: &TransactionsPageStateRx) -> View<G> { fn transactions_page<'a, G: Html>(cx: Scope, state: &TransactionsPageStateRx) -> View<G> {
let global_state = Reactor::<G>::from_cx(cx).get_global_state::<AppStateRx>(cx); let global_state = Reactor::<G>::from_cx(cx).get_global_state::<AppStateRx>(cx);
let api = global_state.api.get();
let api_scope_ref = create_ref(cx, api);
let expand = create_signal(cx, false); let expand = create_signal(cx, false);
let filter_expand = BaseButtonStateRx { let filter_expand = BaseButtonStateRx {
@ -40,17 +39,17 @@ fn transactions_page<G: Html>(cx: Scope, state: &TransactionsPageStateRx) -> Vie
} }
}); });
let paginated_table_state: PaginatedTableStateRx<TransactionCompany, _, _> = let route_ref = create_ref(cx, move |c, p, s| api_scope_ref.get_transactions(c, p, s));
PaginatedTableStateRx { let paginated_table_state: PaginatedTableStateRx<_, _, _> = PaginatedTableStateRx {
record_label: "transactions".to_owned(), record_label: "transactions".to_owned(),
route: get_transactions, route: route_ref,
filter: (*state.company_slug.get()).clone(), filter: (*state.company_slug.get()).clone(),
table_class: create_ref(cx, "".to_string()), table_class: create_ref(cx, "".to_string()),
}; };
let api_url = Config::new().api_url; let route_ref = create_ref(cx, |n, l| api_scope_ref.get_company_by_name(n, l));
let async_select_prop: AsyncSelectRx<Company> = AsyncSelectRx { let async_select_prop: AsyncSelectRx<_, _, _> = AsyncSelectRx {
remote_list: create_signal(cx, format!("{}company", api_url)), route: create_ref(cx, |n, l| api_scope_ref.get_company_by_name(n, l)),
selected_item: create_signal(cx, None), selected_item: create_signal(cx, None),
}; };

@ -4,22 +4,17 @@ services:
container_name: fast-insiders-client container_name: fast-insiders-client
image: fast-insiders-client:latest image: fast-insiders-client:latest
build: build:
context: .
args:
API_URL: http://localhost:8000/
dockerfile: ./client/Dockerfile dockerfile: ./client/Dockerfile
restart: always restart: always
ports: ports:
- 8080:8080 - 8080:8080
environment: environment:
- PERSEUS_HOST=0.0.0.0 - PERSEUS_HOST=0.0.0.0
- API_URL=http://localhost:8000
server: server:
container_name: fast-insiders-server container_name: fast-insiders-server
image: fast-insiders-server:latest image: fast-insiders-server:latest
build: build:
context: .
args:
API_URL: http://localhost:8000/
dockerfile: ./server/Dockerfile dockerfile: ./server/Dockerfile
restart: always restart: always
ports: ports:

@ -1,4 +1,4 @@
FROM rust:1.66-slim as build FROM rust:1.69-slim as build
# Install build dependencies # Install build dependencies
RUN apt-get update \ RUN apt-get update \
@ -10,17 +10,10 @@ WORKDIR /app
# retrieve the src dir # retrieve the src dir
COPY . . COPY . .
# RUN curl https://git.albv.org/alban/fast-insiders/archive/master.tar.gz | tar -xz
# go to src dir # Build failed when not using nightly though I don't know which crate is responsible
# WORKDIR /app
# Rocket only runs on Nightly
RUN rustup default nightly RUN rustup default nightly
ARG API_URL
ENV API_URL=$API_URL
# go to src dir # go to src dir
WORKDIR /app/server WORKDIR /app/server
@ -30,9 +23,6 @@ RUN cargo build --release
# prepare deployment image # prepare deployment image
FROM debian:stable-slim FROM debian:stable-slim
# For tls to work
RUN apt-get update && apt-get -y --no-install-recommends install ca-certificates libssl-dev && rm -rf /var/lib/apt/lists/*
WORKDIR /app WORKDIR /app
COPY --from=build /app/target/release/server /app/ COPY --from=build /app/target/release/server /app/
@ -40,4 +30,3 @@ COPY --from=build /app/target/release/server /app/
ENV HOST=0.0.0.0 ENV HOST=0.0.0.0
CMD ["./server"] CMD ["./server"]

@ -1,4 +1,4 @@
use axum::extract::{Json, Path, Query, State}; use axum::extract::{Json, Query, State};
use chrono::{NaiveDate, NaiveDateTime}; use chrono::{NaiveDate, NaiveDateTime};
use sea_orm::{ use sea_orm::{
prelude::*, DbBackend, FromQueryResult, ItemsAndPagesNumber, JoinType, Order, QueryOrder, prelude::*, DbBackend, FromQueryResult, ItemsAndPagesNumber, JoinType, Order, QueryOrder,

Loading…
Cancel
Save