From 2583bd1b9ecdaa4bd1755cd89c522cd3b2248cde Mon Sep 17 00:00:00 2001 From: Adrian Wozniak Date: Mon, 30 Mar 2020 08:16:26 +0200 Subject: [PATCH] Start wasm --- Cargo.lock | 379 +++++++++--------- jirs-client/Cargo.toml | 10 +- jirs-client/dev/styles.css | 0 jirs-client/js/index.js | 5 +- jirs-client/js/template.ejs | 14 + jirs-client/src/lib.rs | 74 ++-- jirs-client/src/model.rs | 51 +++ jirs-client/webpack.config.js | 4 +- .../src/Project/ProjectSettings/index.jsx | 135 ++++--- react-client/src/actions/forms.ts | 3 + react-client/src/actions/projects.ts | 0 react-client/src/api/projects.ts | 4 + react-client/src/reducers/forms.ts | 29 +- react-client/src/reducers/types.ts | 5 + react-client/src/sagas/forms.ts | 10 + react-client/src/sagas/index.ts | 2 + react-client/src/sagas/projects.ts | 0 17 files changed, 445 insertions(+), 280 deletions(-) create mode 100644 jirs-client/dev/styles.css create mode 100644 jirs-client/js/template.ejs create mode 100644 jirs-client/src/model.rs create mode 100644 react-client/src/actions/projects.ts create mode 100644 react-client/src/api/projects.ts create mode 100644 react-client/src/sagas/forms.ts create mode 100644 react-client/src/sagas/projects.ts diff --git a/Cargo.lock b/Cargo.lock index 813632ee..98e65bed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,7 +106,7 @@ dependencies = [ "lazy_static", "log 0.4.8", "mime", - "percent-encoding", + "percent-encoding 2.1.0", "pin-project", "rand 0.7.3", "regex 1.3.6", @@ -280,7 +280,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "time", - "url", + "url 2.1.1", ] [[package]] @@ -329,18 +329,6 @@ dependencies = [ "memchr 2.3.3", ] -[[package]] -name = "anyhow" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "013a6e0a2cbe3d20f9c60b65458f7a7f7a5e636c5d0f45a5a6aee5d4b1f01785" - -[[package]] -name = "anymap" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344" - [[package]] name = "arc-swap" version = "0.4.5" @@ -391,7 +379,7 @@ dependencies = [ "futures-core", "log 0.4.8", "mime", - "percent-encoding", + "percent-encoding 2.1.0", "rand 0.7.3", "serde", "serde_json", @@ -420,12 +408,6 @@ dependencies = [ "libc", ] -[[package]] -name = "base-x" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b20b618342cf9891c292c4f5ac2cde7287cc5c87e87e9c769d617793607dec1" - [[package]] name = "base64" version = "0.11.0" @@ -443,28 +425,12 @@ dependencies = [ "num-traits", ] -[[package]] -name = "bincode" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5753e2a71534719bf3f4e57006c3a4f0d2c672a4b676eec84161f763eca87dbf" -dependencies = [ - "byteorder", - "serde", -] - [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -[[package]] -name = "boolinator" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9" - [[package]] name = "brotli-sys" version = "0.3.2" @@ -524,12 +490,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -[[package]] -name = "cfg-match" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8100e46ff92eb85bf6dc2930c73f2a4f7176393c84a9446b3d501e1b354e7b34" - [[package]] name = "chrono" version = "0.4.11" @@ -551,6 +511,26 @@ dependencies = [ "bitflags", ] +[[package]] +name = "console_error_panic_hook" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "cookie" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5" +dependencies = [ + "time", + "url 1.7.2", +] + [[package]] name = "copyless" version = "0.1.4" @@ -587,6 +567,15 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "dbg" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4677188513e0e9d7adced5997cf9a1e7a3c996c994f90093325c5332c1a8b221" +dependencies = [ + "version_check 0.1.5", +] + [[package]] name = "derive_more" version = "0.99.3" @@ -633,12 +622,6 @@ dependencies = [ "syn", ] -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" - [[package]] name = "dotenv" version = "0.15.0" @@ -657,6 +640,12 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" +[[package]] +name = "enclose" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1056f553da426e9c025a662efa48b52e62e0a3a7648aa2d15aeaaf7f0d329357" + [[package]] name = "encoding_rs" version = "0.8.22" @@ -863,6 +852,15 @@ dependencies = [ "byteorder", ] +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + [[package]] name = "getrandom" version = "0.1.14" @@ -874,6 +872,17 @@ dependencies = [ "wasi", ] +[[package]] +name = "gloo-timers" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f" +dependencies = [ + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "h2" version = "0.2.2" @@ -948,6 +957,17 @@ dependencies = [ "quick-error", ] +[[package]] +name = "idna" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "idna" version = "0.2.0" @@ -1012,7 +1032,15 @@ version = "0.1.0" name = "jirs-client" version = "0.1.0" dependencies = [ - "yew", + "chrono", + "jirs-data", + "js-sys", + "seed", + "serde", + "serde_json", + "uuid 0.8.1", + "wasm-bindgen", + "web-sys", ] [[package]] @@ -1048,17 +1076,26 @@ dependencies = [ "num-bigint", "num-integer", "num-traits", - "percent-encoding", + "percent-encoding 2.1.0", "pq-sys", "quickcheck", "r2d2", "serde", "serde_json", "time", - "url", + "url 2.1.1", "uuid 0.8.1", ] +[[package]] +name = "js-sys" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a27d435371a2fa5b6d2b028a74bbdb1234f308da363226a2854ca3ff8ba7055" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "kernel32-sys" version = "0.2.2" @@ -1294,6 +1331,12 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "percent-encoding" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" + [[package]] name = "percent-encoding" version = "2.1.0" @@ -1368,6 +1411,18 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "pulldown-cmark" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c205cc82214f3594e2d50686730314f817c67ffa80fe800cf0db78c3c2b9d9e" +dependencies = [ + "bitflags", + "getopts", + "memchr 2.3.3", + "unicase", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -1552,15 +1607,6 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - [[package]] name = "ryu" version = "1.0.3" @@ -1583,20 +1629,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] -name = "semver" -version = "0.9.0" +name = "seed" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +checksum = "cd5d8fd7f12f565f639caf4b6d74a3853d5d7234d0543ec3beae81311492623e" dependencies = [ - "semver-parser", + "console_error_panic_hook", + "cookie", + "dbg", + "enclose", + "futures", + "gloo-timers", + "indexmap", + "js-sys", + "pulldown-cmark", + "serde", + "serde_json", + "version_check 0.9.1", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", ] -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "serde" version = "1.0.105" @@ -1637,7 +1691,7 @@ dependencies = [ "dtoa", "itoa", "serde", - "url", + "url 2.1.1", ] [[package]] @@ -1680,57 +1734,6 @@ dependencies = [ "winapi 0.3.8", ] -[[package]] -name = "stdweb" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" -dependencies = [ - "discard", - "rustc_version", - "serde", - "serde_json", - "stdweb-derive", - "stdweb-internal-macros", - "stdweb-internal-runtime", - "wasm-bindgen", -] - -[[package]] -name = "stdweb-derive" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" -dependencies = [ - "proc-macro2", - "quote", - "serde", - "serde_derive", - "syn", -] - -[[package]] -name = "stdweb-internal-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" -dependencies = [ - "base-x", - "proc-macro2", - "quote", - "serde", - "serde_derive", - "serde_json", - "sha1", - "syn", -] - -[[package]] -name = "stdweb-internal-runtime" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" - [[package]] name = "syn" version = "1.0.17" @@ -1763,26 +1766,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "thiserror" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3711fd1c4e75b3eff12ba5c40dba762b6b65c5476e8174c1a664772060c49bf" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae2b85ba4c9aa32dd3343bd80eb8d22e9b54b7688c17ea3907f236885353b233" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "thread-id" version = "2.0.0" @@ -1876,14 +1859,14 @@ dependencies = [ "enum-as-inner", "failure", "futures", - "idna", + "idna 0.2.0", "lazy_static", "log 0.4.8", "rand 0.7.3", "smallvec", "socket2", "tokio", - "url", + "url 2.1.1", ] [[package]] @@ -1905,6 +1888,15 @@ dependencies = [ "trust-dns-proto", ] +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check 0.9.1", +] + [[package]] name = "unicode-bidi" version = "0.3.4" @@ -1929,21 +1921,38 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" +[[package]] +name = "unicode-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" + [[package]] name = "unicode-xid" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +[[package]] +name = "url" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +dependencies = [ + "idna 0.1.5", + "matches", + "percent-encoding 1.0.1", +] + [[package]] name = "url" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" dependencies = [ - "idna", + "idna 0.2.0", "matches", - "percent-encoding", + "percent-encoding 2.1.0", ] [[package]] @@ -1976,6 +1985,18 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" +[[package]] +name = "version_check" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" + +[[package]] +name = "version_check" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -1989,6 +2010,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f" dependencies = [ "cfg-if", + "serde", + "serde_json", "wasm-bindgen-macro", ] @@ -2007,6 +2030,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7add542ea1ac7fdaa9dc25e031a6af33b7d63376292bd24140c637d00d1c312a" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.60" @@ -2036,6 +2071,16 @@ version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639" +[[package]] +name = "web-sys" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d6f51648d8c56c366144378a33290049eafdd784071077f6fe37dae64c1c4cb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "widestring" version = "0.4.0" @@ -2103,43 +2148,3 @@ dependencies = [ "winapi 0.2.8", "winapi-build", ] - -[[package]] -name = "yew" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20c1d343cdf3d625752fd4d9fef73e1b6b2b8a08b00c832b0fc4a47f3b10fbef" -dependencies = [ - "anyhow", - "anymap", - "bincode", - "cfg-if", - "cfg-match", - "http", - "indexmap", - "log 0.4.8", - "proc-macro-hack", - "proc-macro-nested", - "ryu", - "serde", - "serde_json", - "slab", - "stdweb", - "thiserror", - "wasm-bindgen", - "yew-macro", -] - -[[package]] -name = "yew-macro" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb25d91f16265dd1643497ac3252be6c21c169d9cf3babcae32325c74200499f" -dependencies = [ - "boolinator", - "lazy_static", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn", -] diff --git a/jirs-client/Cargo.toml b/jirs-client/Cargo.toml index bb444494..13291ea4 100644 --- a/jirs-client/Cargo.toml +++ b/jirs-client/Cargo.toml @@ -10,4 +10,12 @@ name = "jirs_client" path = "./src/lib.rs" [dependencies] -yew = { version = "*", features = ["std_web"] } +jirs-data = { path = "../jirs-data" } +seed = { version = "*" } +serde = "*" +serde_json = "*" +chrono = { version = "*", features = [ "serde" ] } +uuid = { version = "*", features = [ "serde" ] } +wasm-bindgen = "*" +web-sys = "*" +js-sys = "*" diff --git a/jirs-client/dev/styles.css b/jirs-client/dev/styles.css new file mode 100644 index 00000000..e69de29b diff --git a/jirs-client/js/index.js b/jirs-client/js/index.js index 020c598c..98a87ed8 100644 --- a/jirs-client/js/index.js +++ b/jirs-client/js/index.js @@ -1 +1,4 @@ -import("../pkg/index"); +import("../pkg/index.js").then(module => { + console.log(module) + // module.main(); +}); diff --git a/jirs-client/js/template.ejs b/jirs-client/js/template.ejs new file mode 100644 index 00000000..1733f955 --- /dev/null +++ b/jirs-client/js/template.ejs @@ -0,0 +1,14 @@ + + + + + + JIRS + + + + + +
+ + diff --git a/jirs-client/src/lib.rs b/jirs-client/src/lib.rs index 5b78248e..e0fa7b27 100644 --- a/jirs-client/src/lib.rs +++ b/jirs-client/src/lib.rs @@ -1,47 +1,45 @@ -use yew::{html, Callback, ClickEvent, Component, ComponentLink, Html, ShouldRender}; +use seed::{prelude::*, *}; -struct App { - clicked: bool, - onclick: Callback, -} +mod model; + +type Model = i32; enum Msg { - Click, + Increment, + ChangeGuidePage(i32), + ChangePage(i32), } -impl Component for App { - type Message = Msg; - type Properties = (); - - fn create(_: Self::Properties, link: ComponentLink) -> Self { - App { - clicked: false, - onclick: link.callback(|_| Msg::Click), - } - } - - fn update(&mut self, msg: Self::Message) -> ShouldRender { - match msg { - Msg::Click => { - self.clicked = true; - true // Indicate that the Component should re-render - } - } - } - - fn view(&self) -> Html { - let button_text = if self.clicked { - "Clicked!" - } else { - "Click me!" - }; - - html! { - - } +fn update(msg: Msg, model: &mut Model, _: &mut impl Orders) { + match msg { + Msg::Increment => *model += 1, } } -fn main() { - yew::start_app::(); +fn view(model: &Model) -> Node { + div![ + "This is a counter: ", + class!["counter"], + button![model.to_string(), ev(Ev::Click, |_| Msg::Increment),], + ] +} + +fn routes(url: Url) -> Option { + if url.path.is_empty() { + return Some(Msg::ChangePage(0)); + } + + match url.path[0].as_ref() { + "guide" => match url.path.get(1).as_ref() { + Some(page) => Some(Msg::ChangeGuidePage(page.parse::().unwrap())), + None => Some(Msg::ChangePage(0)), + }, + "changelog" => Some(Msg::ChangePage(1)), + _ => Some(Msg::ChangePage(0)), + } +} + +#[wasm_bindgen(start)] +pub fn render() { + App::builder(update, view).routes(routes).build_and_start(); } diff --git a/jirs-client/src/model.rs b/jirs-client/src/model.rs new file mode 100644 index 00000000..beefc985 --- /dev/null +++ b/jirs-client/src/model.rs @@ -0,0 +1,51 @@ +use std::collections::hash_map::HashMap; + +use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +use jirs_data::*; + +type ProjectId = i32; + +#[derive(Serialize, Deserialize)] +pub struct CreateCommentForm { + fields: CreateCommentPayload, +} + +#[derive(Serialize, Deserialize)] +pub struct CreateIssueForm { + fields: CreateIssuePayload, +} + +#[derive(Serialize, Deserialize)] +pub struct UpdateProjectForm { + id: ProjectId, + fields: UpdateProjectPayload, +} + +#[derive(Serialize, Deserialize)] +pub struct Model { + access_token: Option, + user: Option, + project: Option, + project_form: Option, + issue_form: Option, + comment_form: Option, + issues: Vec, + comments_by_project_id: HashMap>, +} + +impl Default for Model { + fn default() -> Self { + Self { + access_token: None, + project: None, + user: None, + issue_form: None, + project_form: None, + comment_form: None, + issues: vec![], + comments_by_project_id: Default::default(), + } + } +} diff --git a/jirs-client/webpack.config.js b/jirs-client/webpack.config.js index 659dcd57..b7dcd259 100644 --- a/jirs-client/webpack.config.js +++ b/jirs-client/webpack.config.js @@ -30,6 +30,8 @@ module.exports = { args: "--log-level warn", extraArgs: "--no-typescript", }), - new HtmlWebpackPlugin(), + new HtmlWebpackPlugin({ + template: path.resolve(__dirname, "js", "template.ejs"), + }), ] }; diff --git a/react-client/src/Project/ProjectSettings/index.jsx b/react-client/src/Project/ProjectSettings/index.jsx index edad490c..ab8f91ce 100644 --- a/react-client/src/Project/ProjectSettings/index.jsx +++ b/react-client/src/Project/ProjectSettings/index.jsx @@ -1,70 +1,103 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { connect } from "react-redux"; import { ProjectCategory, ProjectCategoryCopy } from 'shared/constants/projects'; import toast from 'shared/utils/toast'; -import useApi from 'shared/hooks/api'; +import api from 'shared/utils/api'; import { Breadcrumbs, Form } from 'shared/components'; +import { updateProjectFormFieldChanged, updateProjectFormRequest, updateProjectFormSuccess, } from 'actions/forms'; import { ActionButton, FormCont, FormElement, FormHeading } from './Styles'; -const ProjectSettings = ({ project, fetchProject }) => { - const [ { isUpdating }, updateProject ] = useApi.put(`/project/${ project.id }`); - - return ( -
({ - name: get('name'), - url: get('url'), - category: get('category'), - description: get('description'), - }))} - validations={{ - name: [Form.is.required(), Form.is.maxLength(100)], - url: Form.is.url(), - category: Form.is.required(), - }} - onSubmit={async (values, form) => { - try { - await updateProject(values); - await fetchProject(); - toast.success('Changes have been saved successfully.'); - } catch (error) { - Form.handleAPIError(error, form); +class ProjectSettings extends React.Component { + state = { + isUpdating: false, form: { + name: '', + url: '', + category: '', + description: '', } - }} - > - - - - Project Details + }; - - - - + componentDidMount() { + this.props.updateProjectFormFieldChanged(this.props.project); + } - - Save changes - - - -
- ); -}; + onSubmit = async () => { + this.setState({ isUpdating: true }); + try { + await api.put(`/project/${ this.props.project.id }`, this.state.form); + await this.props.fetchProject(); + toast.success('Changes have been saved successfully.'); + } catch (error) { + } + this.setState({ isUpdating: false }); + }; + + onChange = (field, value) => this.props.updateProject({ [field]: value }); + + render() { + let { updateProject: project } = this.props; + console.log(project); + if (!project.id) return <>; + + + return ( +
+ + + + Project Details + + + + + + + + Save changes + + + +
+ ); + } +} const categoryOptions = Object.values(ProjectCategory).map(category => ({ - value: category, - label: ProjectCategoryCopy[category], + value: category, + label: ProjectCategoryCopy[category], })); ProjectSettings.propTypes = { - project: PropTypes.object.isRequired, - fetchProject: PropTypes.func.isRequired, + project: PropTypes.object.isRequired, + fetchProject: PropTypes.func.isRequired, }; -export default ProjectSettings; +const mapStateToProps = ({ forms: { updateProject } }) => ({ updateProject }); +const mapDispatchToProps = ({ + updateProjectFormFieldChanged, + updateProjectFormRequest, + updateProjectFormSuccess, +}); + +export default connect(mapStateToProps, mapDispatchToProps)(ProjectSettings); diff --git a/react-client/src/actions/forms.ts b/react-client/src/actions/forms.ts index 46215289..d7241df9 100644 --- a/react-client/src/actions/forms.ts +++ b/react-client/src/actions/forms.ts @@ -7,3 +7,6 @@ export const passwordChanged = createAction(ActionType.SignInPasswordChanged, ev export const signInSubmit = createAction(ActionType.SignInRequest, event => { event.preventDefault(); }); +export const updateProjectFormFieldChanged = createAction(ActionType.UpdateProjectFormFieldChanged); +export const updateProjectFormRequest = createAction(ActionType.UpdateProjectFormRequest); +export const updateProjectFormSuccess = createAction(ActionType.UpdateProjectFormSuccess); diff --git a/react-client/src/actions/projects.ts b/react-client/src/actions/projects.ts new file mode 100644 index 00000000..e69de29b diff --git a/react-client/src/api/projects.ts b/react-client/src/api/projects.ts new file mode 100644 index 00000000..2a3d4008 --- /dev/null +++ b/react-client/src/api/projects.ts @@ -0,0 +1,4 @@ +import { request } from './index'; + +export const updateProject = form => + request({ path: `/project/${ form.get('id') }`, form }); diff --git a/react-client/src/reducers/forms.ts b/react-client/src/reducers/forms.ts index 46807f85..2121a5c2 100644 --- a/react-client/src/reducers/forms.ts +++ b/react-client/src/reducers/forms.ts @@ -7,6 +7,14 @@ interface SignInFormState { password: string, } +interface UpdateProjectState { + id?: number, + name: string, + url: string, + category: string, + description: string, +} + const initialSignIn = (): SignInFormState => ({ email: '', password: '' }); const signInForm = (state: SignInFormState = initialSignIn(), { type, payload }: JirsAction) => { @@ -22,4 +30,23 @@ const signInForm = (state: SignInFormState = initialSignIn(), { type, payload }: } }; -export default combineReducers({ signInForm }) +const initialUpdateProject = (): UpdateProjectState => ({ + id: null, + name: '', + url: '', + category: '', + description: '', +}); + +const updateProject = (state = initialUpdateProject(), { type, payload }: JirsAction) => { + switch (type) { + case ActionType.UpdateProjectFormFieldChanged: + return { ...state, ...payload }; + case ActionType.UpdateProjectFormSuccess: + return initialUpdateProject(); + default: + return state; + } +}; + +export default combineReducers({ signInForm, updateProject }) diff --git a/react-client/src/reducers/types.ts b/react-client/src/reducers/types.ts index 18e5b706..3867b8d8 100644 --- a/react-client/src/reducers/types.ts +++ b/react-client/src/reducers/types.ts @@ -13,10 +13,15 @@ export interface User { export enum ActionType { CurrentUser = 'CurrentUser', FetchCurrentUser = 'FetchCurrentUser', + // SignInEmailChanged = 'SignInEmailChanged', SignInPasswordChanged = 'SignInPasswordChanged', SignInRequest = 'SignInRequest', SignInSuccess = 'SignInSuccess', + // + UpdateProjectFormFieldChanged = 'UpdateProjectFormFieldChanged', + UpdateProjectFormRequest = 'UpdateProjectFormRequest', + UpdateProjectFormSuccess = 'UpdateProjectFormSuccess', } export interface JirsAction extends Action { diff --git a/react-client/src/sagas/forms.ts b/react-client/src/sagas/forms.ts new file mode 100644 index 00000000..dd83d280 --- /dev/null +++ b/react-client/src/sagas/forms.ts @@ -0,0 +1,10 @@ +import { call, select } from 'redux-saga/effects'; + +import * as projectsApi from 'api/projects'; + +export const updateProject = function * () { + const state = yield select(({ forms: { updateProject } }) => updateProject); + const form = new FormData; + for (const key in state) form.append(key, state[key]); + yield call(projectsApi.updateProject, form); +}; diff --git a/react-client/src/sagas/index.ts b/react-client/src/sagas/index.ts index e5c50ec5..c90bc3e6 100644 --- a/react-client/src/sagas/index.ts +++ b/react-client/src/sagas/index.ts @@ -2,9 +2,11 @@ import { takeEvery } from 'redux-saga/effects'; import { ActionType } from "../reducers/types"; import * as usersSaga from './users'; +import * as formsSaga from './forms'; const main = function * () { yield takeEvery(ActionType.FetchCurrentUser, usersSaga.fetchCurrentUser); + yield takeEvery(ActionType.UpdateProjectFormRequest, formsSaga.updateProject); }; export default main diff --git a/react-client/src/sagas/projects.ts b/react-client/src/sagas/projects.ts new file mode 100644 index 00000000..e69de29b