Add Docker build
This commit is contained in:
8
.dockerignore
Normal file
8
.dockerignore
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
.git
|
||||||
|
.github
|
||||||
|
.env
|
||||||
|
target/
|
||||||
|
tests/
|
||||||
|
Dockerfile
|
||||||
|
web/dist
|
||||||
|
api/config/local.*
|
||||||
56
Cargo.lock
generated
56
Cargo.lock
generated
@@ -19,6 +19,29 @@ dependencies = [
|
|||||||
"tokio-util 0.7.0",
|
"tokio-util 0.7.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "actix-files"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d81bde9a79336aa51ebed236e91fc1a0528ff67cfdf4f68ca4c61ede9fd26fb5"
|
||||||
|
dependencies = [
|
||||||
|
"actix-http",
|
||||||
|
"actix-service",
|
||||||
|
"actix-utils",
|
||||||
|
"actix-web",
|
||||||
|
"askama_escape",
|
||||||
|
"bitflags",
|
||||||
|
"bytes",
|
||||||
|
"derive_more",
|
||||||
|
"futures-core",
|
||||||
|
"http-range",
|
||||||
|
"log",
|
||||||
|
"mime",
|
||||||
|
"mime_guess",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "actix-http"
|
name = "actix-http"
|
||||||
version = "3.0.4"
|
version = "3.0.4"
|
||||||
@@ -243,6 +266,12 @@ version = "1.0.56"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27"
|
checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "askama_escape"
|
||||||
|
version = "0.10.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.52"
|
version = "0.1.52"
|
||||||
@@ -456,6 +485,7 @@ dependencies = [
|
|||||||
name = "contextswitch-api"
|
name = "contextswitch-api"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"actix-files",
|
||||||
"actix-http",
|
"actix-http",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
@@ -490,6 +520,7 @@ dependencies = [
|
|||||||
"reqwasm",
|
"reqwasm",
|
||||||
"serde",
|
"serde",
|
||||||
"uikit-rs",
|
"uikit-rs",
|
||||||
|
"wasm-bindgen",
|
||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
"yew",
|
"yew",
|
||||||
]
|
]
|
||||||
@@ -939,6 +970,12 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http-range"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httparse"
|
name = "httparse"
|
||||||
version = "1.6.0"
|
version = "1.6.0"
|
||||||
@@ -1152,6 +1189,16 @@ version = "0.3.16"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mime_guess"
|
||||||
|
version = "2.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
|
||||||
|
dependencies = [
|
||||||
|
"mime",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minimal-lexical"
|
name = "minimal-lexical"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@@ -2202,6 +2249,15 @@ dependencies = [
|
|||||||
"yew",
|
"yew",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicase"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
||||||
|
dependencies = [
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.7"
|
version = "0.3.7"
|
||||||
|
|||||||
34
Dockerfile
Normal file
34
Dockerfile
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
FROM lukemathwalker/cargo-chef:latest-rust-1.57.0 as chef
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
FROM chef as planner
|
||||||
|
COPY . .
|
||||||
|
RUN cargo chef prepare --recipe-path recipe.json
|
||||||
|
|
||||||
|
FROM chef as builder
|
||||||
|
RUN cargo install cargo-make
|
||||||
|
RUN cargo install trunk
|
||||||
|
RUN rustup target add wasm32-unknown-unknown
|
||||||
|
COPY --from=planner /app/recipe.json recipe.json
|
||||||
|
RUN cargo chef cook -p contextswitch --release --recipe-path recipe.json
|
||||||
|
RUN cargo chef cook -p contextswitch-api --release --recipe-path recipe.json
|
||||||
|
RUN cargo chef cook -p contextswitch-web --release --recipe-path recipe.json --target wasm32-unknown-unknown
|
||||||
|
COPY . .
|
||||||
|
RUN cargo make build-release
|
||||||
|
RUN sed -i 's#http://localhost:8000/api#/api#' web/dist/snippets/contextswitch-web-*/js/api.js
|
||||||
|
|
||||||
|
FROM debian:bullseye-slim AS runtime
|
||||||
|
WORKDIR /app
|
||||||
|
RUN mkdir /data
|
||||||
|
RUN apt-get update -y \
|
||||||
|
&& apt-get install -y --no-install-recommends openssl taskwarrior \
|
||||||
|
&& apt-get autoremove -y \
|
||||||
|
&& apt-get clean -y \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
COPY --from=builder /app/target/release/contextswitch-api contextswitch
|
||||||
|
COPY --from=builder /app/api/config/default.toml config/default.toml
|
||||||
|
COPY --from=builder /app/web/dist/ .
|
||||||
|
ENV CS_TASKWARRIOR.DATA_LOCATION /data
|
||||||
|
ENV CS_APPLICATION.API_PATH /api
|
||||||
|
ENV CS_APPLICATION.STATIC_PATH /
|
||||||
|
CMD ["/app/contextswitch"]
|
||||||
@@ -5,7 +5,7 @@ CARGO_MAKE_CLIPPY_ARGS = "--tests -- -D warnings"
|
|||||||
|
|
||||||
[tasks.default]
|
[tasks.default]
|
||||||
clear = true
|
clear = true
|
||||||
alias = "run"
|
alias = "watch"
|
||||||
|
|
||||||
[tasks.test]
|
[tasks.test]
|
||||||
install_crate = "cargo-nextest"
|
install_crate = "cargo-nextest"
|
||||||
@@ -21,17 +21,14 @@ condition = {}
|
|||||||
workspace = false
|
workspace = false
|
||||||
|
|
||||||
[tasks.run-api]
|
[tasks.run-api]
|
||||||
install_crate = { crate_name = "bunyan", binary = "bunyan" }
|
|
||||||
env = { "CONFIG_PATH" = "api/config", "TASKRC" = "$PWD/api/taskrc" }
|
|
||||||
command = "bash"
|
command = "bash"
|
||||||
args = ["-c", "cargo run -p contextswitch-api | bunyan"]
|
args = ["-c", "cd api; cargo make run"]
|
||||||
workspace = false
|
workspace = false
|
||||||
watch = { watch = ["./api/"], no_git_ignore = true }
|
watch = { watch = ["./api/"], no_git_ignore = true }
|
||||||
|
|
||||||
[tasks.run-web]
|
[tasks.run-web]
|
||||||
install_crate = { crate_name = "trunk", binary = "trunk" }
|
|
||||||
command = "bash"
|
command = "bash"
|
||||||
args = ["-c", "cd web; trunk serve"]
|
args = ["-c", "cd web; cargo make run"]
|
||||||
workspace = false
|
workspace = false
|
||||||
|
|
||||||
[tasks.run]
|
[tasks.run]
|
||||||
@@ -39,16 +36,16 @@ run_task = { name = ["run-api", "run-web"], parallel = true, fork = true }
|
|||||||
workspace = false
|
workspace = false
|
||||||
|
|
||||||
[tasks.watch-api]
|
[tasks.watch-api]
|
||||||
watch = { watch = ["./api/"], no_git_ignore = true }
|
|
||||||
command = "bash"
|
command = "bash"
|
||||||
args = ["-c", "cd api; cargo make watch-flow"]
|
args = ["-c", "cd api; cargo make dev-test-flow"]
|
||||||
workspace = false
|
workspace = false
|
||||||
|
watch = { watch = ["./api/"], no_git_ignore = true }
|
||||||
|
|
||||||
[tasks.watch-web]
|
[tasks.watch-web]
|
||||||
watch = { watch = ["./web/"], no_git_ignore = true }
|
|
||||||
command = "bash"
|
command = "bash"
|
||||||
args = ["-c", "cd web; cargo make watch-flow"]
|
args = ["-c", "cd web; cargo make dev-test-flow"]
|
||||||
workspace = false
|
workspace = false
|
||||||
|
watch = { watch = ["./web/"], no_git_ignore = true }
|
||||||
|
|
||||||
[tasks.watch-root]
|
[tasks.watch-root]
|
||||||
watch = { watch = ["./src/"], no_git_ignore = true }
|
watch = { watch = ["./src/"], no_git_ignore = true }
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ thiserror = "1.0"
|
|||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
http = "0.2.0"
|
http = "0.2.0"
|
||||||
config = "0.12.0"
|
config = "0.12.0"
|
||||||
|
actix-files = "0.6.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
proptest = "1.0.0"
|
proptest = "1.0.0"
|
||||||
|
|||||||
@@ -1 +1,8 @@
|
|||||||
extend = "../Makefile.toml"
|
extend = "../Makefile.toml"
|
||||||
|
|
||||||
|
[tasks.run]
|
||||||
|
clear = true
|
||||||
|
install_crate = { crate_name = "bunyan", binary = "bunyan" }
|
||||||
|
env = { "TASKRC" = "$PWD/taskrc" }
|
||||||
|
command = "bash"
|
||||||
|
args = ["-c", "cargo run | bunyan"]
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
port = 8000
|
port = 8000
|
||||||
# See https://docs.rs/tracing-subscriber/latest/tracing_subscriber/struct.EnvFilter.html
|
# See https://docs.rs/tracing-subscriber/latest/tracing_subscriber/struct.EnvFilter.html
|
||||||
log_directive = "info"
|
log_directive = "info"
|
||||||
|
api_path = ""
|
||||||
|
front_base_url = "http://localhost:8080"
|
||||||
|
|
||||||
[taskwarrior]
|
[taskwarrior]
|
||||||
data_location = "/tmp"
|
data_location = "/tmp"
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
[application]
|
[application]
|
||||||
log_directive = "debug"
|
log_directive = "debug"
|
||||||
|
static_dir = "../web/dist"
|
||||||
|
api_path = "/api"
|
||||||
|
static_path = ""
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ pub struct Settings {
|
|||||||
pub struct ApplicationSettings {
|
pub struct ApplicationSettings {
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
pub log_directive: String,
|
pub log_directive: String,
|
||||||
|
pub front_base_url: String,
|
||||||
|
pub api_path: String,
|
||||||
|
pub static_path: Option<String>,
|
||||||
|
pub static_dir: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
@@ -23,13 +27,21 @@ pub struct TaskwarriorSettings {
|
|||||||
impl Settings {
|
impl Settings {
|
||||||
pub fn new_from_file(file: Option<String>) -> Result<Self, ConfigError> {
|
pub fn new_from_file(file: Option<String>) -> Result<Self, ConfigError> {
|
||||||
let config_file_required = file.is_some();
|
let config_file_required = file.is_some();
|
||||||
let config_file =
|
|
||||||
file.unwrap_or_else(|| env::var("CONFIG").unwrap_or_else(|_| "dev".into()));
|
|
||||||
let config_path = env::var("CONFIG_PATH").unwrap_or_else(|_| "config".into());
|
let config_path = env::var("CONFIG_PATH").unwrap_or_else(|_| "config".into());
|
||||||
|
let config_file = file.unwrap_or_else(|| {
|
||||||
|
env::var("CONFIG_FILE").unwrap_or_else(|_| format!("{}/dev", &config_path).into())
|
||||||
|
});
|
||||||
|
|
||||||
|
let default_config_file = format!("{}/default", config_path);
|
||||||
|
let local_config_file = format!("{}/local", config_path);
|
||||||
|
println!(
|
||||||
|
"Trying to load {:?} config files",
|
||||||
|
vec![&default_config_file, &local_config_file, &config_file]
|
||||||
|
);
|
||||||
|
|
||||||
let config = Config::builder()
|
let config = Config::builder()
|
||||||
.add_source(File::with_name(&format!("{}/default", config_path)))
|
.add_source(File::with_name(&default_config_file))
|
||||||
.add_source(File::with_name(&format!("{}/local", config_path)).required(false))
|
.add_source(File::with_name(&local_config_file).required(false))
|
||||||
.add_source(File::with_name(&config_file).required(config_file_required))
|
.add_source(File::with_name(&config_file).required(config_file_required))
|
||||||
.add_source(Environment::with_prefix("cs"))
|
.add_source(Environment::with_prefix("cs"))
|
||||||
.build()?;
|
.build()?;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
use actix_files as fs;
|
||||||
use actix_web::{dev::Server, http, middleware, web, App, HttpServer};
|
use actix_web::{dev::Server, http, middleware, web, App, HttpServer};
|
||||||
|
use configuration::Settings;
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
use std::env;
|
|
||||||
use std::net::TcpListener;
|
use std::net::TcpListener;
|
||||||
|
use tracing::info;
|
||||||
use tracing_actix_web::TracingLogger;
|
use tracing_actix_web::TracingLogger;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@@ -12,30 +14,55 @@ pub mod contextswitch;
|
|||||||
pub mod observability;
|
pub mod observability;
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
|
|
||||||
pub fn run(listener: TcpListener) -> Result<Server, std::io::Error> {
|
pub fn run(listener: TcpListener, settings: &Settings) -> Result<Server, std::io::Error> {
|
||||||
let cs_front_base_url =
|
let api_path = settings.application.api_path.clone();
|
||||||
env::var("CS_FRONT_BASE_URL").unwrap_or_else(|_| "http://localhost:8080".to_string());
|
let front_base_url = settings.application.front_base_url.clone();
|
||||||
|
let static_path = settings.application.static_path.clone();
|
||||||
|
let static_dir = settings
|
||||||
|
.application
|
||||||
|
.static_dir
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_else(|| ".".to_string());
|
||||||
|
|
||||||
let server = HttpServer::new(move || {
|
let server = HttpServer::new(move || {
|
||||||
App::new()
|
info!(
|
||||||
.wrap(TracingLogger::default())
|
"Mounting API on {}",
|
||||||
.wrap(middleware::Compress::default())
|
if api_path.is_empty() { "/" } else { &api_path }
|
||||||
|
);
|
||||||
|
let api_scope = web::scope(&api_path)
|
||||||
.wrap(
|
.wrap(
|
||||||
middleware::DefaultHeaders::new()
|
middleware::DefaultHeaders::new()
|
||||||
.add(("Access-Control-Allow-Origin", cs_front_base_url.as_bytes()))
|
.add(("Access-Control-Allow-Origin", front_base_url.as_bytes()))
|
||||||
.add((
|
.add((
|
||||||
"Access-Control-Allow-Methods",
|
"Access-Control-Allow-Methods",
|
||||||
"POST, GET, OPTIONS".as_bytes(),
|
"POST, GET, OPTIONS".as_bytes(),
|
||||||
))
|
))
|
||||||
.add(("Access-Control-Allow-Headers", "content-type".as_bytes())),
|
.add(("Access-Control-Allow-Headers", "content-type".as_bytes())),
|
||||||
)
|
)
|
||||||
.route("/ping", web::get().to(routes::ping))
|
|
||||||
.route("/tasks", web::get().to(routes::list_tasks))
|
.route("/tasks", web::get().to(routes::list_tasks))
|
||||||
.route("/tasks", web::post().to(routes::add_task))
|
.route("/tasks", web::post().to(routes::add_task))
|
||||||
.route("/tasks/{task_id}", web::put().to(routes::update_task))
|
.route("/tasks/{task_id}", web::put().to(routes::update_task))
|
||||||
.route(
|
.route(
|
||||||
"/tasks",
|
"/tasks",
|
||||||
web::method(http::Method::OPTIONS).to(routes::option_task),
|
web::method(http::Method::OPTIONS).to(routes::option_task),
|
||||||
)
|
);
|
||||||
|
|
||||||
|
let mut app = App::new()
|
||||||
|
.wrap(TracingLogger::default())
|
||||||
|
.wrap(middleware::Compress::default())
|
||||||
|
.route("/ping", web::get().to(routes::ping))
|
||||||
|
.service(api_scope);
|
||||||
|
if let Some(path) = &static_path {
|
||||||
|
info!(
|
||||||
|
"Mounting static files on {}",
|
||||||
|
if path.is_empty() { "/" } else { &path }
|
||||||
|
);
|
||||||
|
let static_scope = fs::Files::new(&path, &static_dir)
|
||||||
|
.use_last_modified(true)
|
||||||
|
.index_file("index.html");
|
||||||
|
app = app.service(static_scope);
|
||||||
|
}
|
||||||
|
app
|
||||||
})
|
})
|
||||||
.keep_alive(http::KeepAlive::Timeout(Duration::from_secs(60)))
|
.keep_alive(http::KeepAlive::Timeout(Duration::from_secs(60)))
|
||||||
.shutdown_timeout(60)
|
.shutdown_timeout(60)
|
||||||
|
|||||||
@@ -13,5 +13,5 @@ async fn main() -> std::io::Result<()> {
|
|||||||
|
|
||||||
let listener = TcpListener::bind(format!("0.0.0.0:{}", settings.application.port))
|
let listener = TcpListener::bind(format!("0.0.0.0:{}", settings.application.port))
|
||||||
.expect("Failed to bind port");
|
.expect("Failed to bind port");
|
||||||
run(listener)?.await
|
run(listener, &settings)?.await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ fn setup_tracing(settings: &Settings) {
|
|||||||
init_subscriber(subscriber);
|
init_subscriber(subscriber);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_server() -> String {
|
fn setup_server(settings: &Settings) -> String {
|
||||||
info!("Setting up server");
|
info!("Setting up server");
|
||||||
let listener = TcpListener::bind("127.0.0.1:0").expect("Failed to bind random port");
|
let listener = TcpListener::bind("127.0.0.1:0").expect("Failed to bind random port");
|
||||||
let port = listener.local_addr().unwrap().port();
|
let port = listener.local_addr().unwrap().port();
|
||||||
|
|
||||||
let server = contextswitch_api::run(listener).expect("Failed to bind address");
|
let server = contextswitch_api::run(listener, &settings).expect("Failed to bind address");
|
||||||
let _ = tokio::spawn(server);
|
let _ = tokio::spawn(server);
|
||||||
format!("http://127.0.0.1:{}", port)
|
format!("http://127.0.0.1:{}", port)
|
||||||
}
|
}
|
||||||
@@ -38,6 +38,7 @@ pub fn app_address() -> String {
|
|||||||
let settings = Settings::new_from_file(Some("config/test".to_string()))
|
let settings = Settings::new_from_file(Some("config/test".to_string()))
|
||||||
.expect("Cannot load test configuration");
|
.expect("Cannot load test configuration");
|
||||||
setup_tracing(&settings);
|
setup_tracing(&settings);
|
||||||
|
let address = setup_server(&settings);
|
||||||
setup_taskwarrior(settings);
|
setup_taskwarrior(settings);
|
||||||
setup_server()
|
address
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,3 +18,4 @@ reqwasm = "0.5"
|
|||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
wasm-bindgen-futures = "0.4"
|
wasm-bindgen-futures = "0.4"
|
||||||
uikit-rs = { git = "https://github.com/dax/uikit-rs.git" }
|
uikit-rs = { git = "https://github.com/dax/uikit-rs.git" }
|
||||||
|
wasm-bindgen = "0.2.79"
|
||||||
|
|||||||
@@ -1 +1,12 @@
|
|||||||
extend = "../Makefile.toml"
|
extend = "../Makefile.toml"
|
||||||
|
|
||||||
|
[tasks.build-release]
|
||||||
|
install_crate = { crate_name = "trunk", binary = "trunk" }
|
||||||
|
command = "trunk"
|
||||||
|
args = ["build", "--release"]
|
||||||
|
|
||||||
|
[tasks.run]
|
||||||
|
clear = true
|
||||||
|
install_crate = { crate_name = "trunk", binary = "trunk" }
|
||||||
|
command = "trunk"
|
||||||
|
args = ["serve"]
|
||||||
|
|||||||
3
web/js/api.js
Normal file
3
web/js/api.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function get_api_base_url() {
|
||||||
|
return "http://localhost:8000/api";
|
||||||
|
}
|
||||||
@@ -2,10 +2,16 @@ use components::tasks_list::TasksList;
|
|||||||
use contextswitch::Task;
|
use contextswitch::Task;
|
||||||
use reqwasm::http::Request;
|
use reqwasm::http::Request;
|
||||||
use uikit_rs as uk;
|
use uikit_rs as uk;
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
mod components;
|
mod components;
|
||||||
|
|
||||||
|
#[wasm_bindgen(module = "/js/api.js")]
|
||||||
|
extern "C" {
|
||||||
|
fn get_api_base_url() -> String;
|
||||||
|
}
|
||||||
|
|
||||||
#[function_component(App)]
|
#[function_component(App)]
|
||||||
pub fn app() -> Html {
|
pub fn app() -> Html {
|
||||||
let tasks = use_state(Vec::new);
|
let tasks = use_state(Vec::new);
|
||||||
@@ -15,7 +21,7 @@ pub fn app() -> Html {
|
|||||||
move |_| {
|
move |_| {
|
||||||
wasm_bindgen_futures::spawn_local(async move {
|
wasm_bindgen_futures::spawn_local(async move {
|
||||||
let fetched_tasks: Vec<Task> =
|
let fetched_tasks: Vec<Task> =
|
||||||
Request::get("http://localhost:8000/tasks?filter=task")
|
Request::get(&format!("{}/tasks?filter=task", get_api_base_url()))
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
.unwrap() // TODO
|
.unwrap() // TODO
|
||||||
|
|||||||
Reference in New Issue
Block a user