diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bb8f2697..fb93c631b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [[0.12.11]](https://github.com/thoth-pub/thoth/releases/tag/v0.12.11) - 2024-10-14 +### Changed + - [324](https://github.com/thoth-pub/thoth/issues/324) - Make Locations editable, including the ability to change the Canonical Location for a Publication + - [635](https://github.com/thoth-pub/thoth/pull/635) - Upgrade `reqwest` to v0.12.8 + - [635](https://github.com/thoth-pub/thoth/pull/635) - Upgrade `reqwest-middleware` to v0.3.3 + - [635](https://github.com/thoth-pub/thoth/pull/635) - Upgrade `reqwest-retry` to v0.6.1 + - [635](https://github.com/thoth-pub/thoth/pull/635) - Upgrade `paperclip` to v0.9.2 + ## [[0.12.10]](https://github.com/thoth-pub/thoth/releases/tag/v0.12.10) - 2024-10-01 ### Added - [628](https://github.com/thoth-pub/thoth/pull/628) - Implement OpenAPI v3 schema in export API, served under `/openapi.json` diff --git a/Cargo.lock b/Cargo.lock index c7303322f..1df3e68d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -54,8 +54,8 @@ dependencies = [ "encoding_rs", "flate2", "futures-core", - "h2", - "http", + "h2 0.3.26", + "http 0.2.12", "httparse", "httpdate", "itoa", @@ -107,7 +107,7 @@ checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" dependencies = [ "bytestring", "cfg-if", - "http", + "http 0.2.12", "regex", "regex-lite", "serde", @@ -449,6 +449,12 @@ dependencies = [ "syn 2.0.76", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "auto_enums" version = "0.8.6" @@ -644,7 +650,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -1511,7 +1517,26 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.12", + "indexmap 2.4.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", "indexmap 2.4.0", "slab", "tokio", @@ -1578,14 +1603,37 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" -version = "0.4.6" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body", "pin-project-lite", ] @@ -1609,39 +1657,74 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.30" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", - "h2", - "http", + "h2 0.4.6", + "http 1.1.0", "http-body", "httparse", - "httpdate", "itoa", "pin-project-lite", - "socket2", + "smallvec", "tokio", - "tower-service", - "tracing", "want", ] +[[package]] +name = "hyper-rustls" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + [[package]] name = "hyper-tls" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", + "http-body-util", "hyper", + "hyper-util", "native-tls", "tokio", "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", ] [[package]] @@ -2111,9 +2194,9 @@ dependencies = [ [[package]] name = "paperclip" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac41f27e83168c22515ef52d62a0357b5f5b8df846aa391f8b903b0ed7719429" +checksum = "b0fd8369d5ed760936fdc16ccdc429b59d58faaed3ef8a212ac27b8076f855b4" dependencies = [ "anyhow", "itertools", @@ -2133,9 +2216,9 @@ dependencies = [ [[package]] name = "paperclip-actix" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5b6f4c003aa6167df82f1574c951638a8b9a43827059da0cda8b5df88d20ecf" +checksum = "d657a5d373b74ab8c2331593c36784fb9b3b0a83484d7b4a898adbed303bbaf2" dependencies = [ "actix-service", "actix-web", @@ -2150,9 +2233,9 @@ dependencies = [ [[package]] name = "paperclip-core" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2e742f71daf34eb8f62ccc5a1a5e1f029eb84be563523a2a5ee049366329f4" +checksum = "1a6842cfd9f8603f9d8ece3feb8b6995306b87f3e38d9251b86f503b61390183" dependencies = [ "actix-web", "mime", @@ -2170,15 +2253,15 @@ dependencies = [ [[package]] name = "paperclip-macros" -version = "0.6.5" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0385be5ae9c886c46688290534363a229f2531aa2c5c2bfc3b3ddafed5143aaa" +checksum = "827a0067440b62e798bc3e8cfb7036a0f63c3adbb21fe6a56fb3d6f6d8fa53f8" dependencies = [ "heck 0.4.1", - "http", + "http 0.2.12", "lazy_static", "mime", - "proc-macro-error", + "proc-macro-error2", "proc-macro2", "quote", "strum 0.24.1", @@ -2231,7 +2314,7 @@ dependencies = [ "libc", "redox_syscall 0.5.3", "smallvec", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -2376,6 +2459,28 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.76", +] + [[package]] name = "proc-macro2" version = "1.0.86" @@ -2490,25 +2595,27 @@ checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" -version = "0.11.27" +version = "0.12.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "bytes", "encoding_rs", "futures-core", "futures-util", - "h2", - "http", + "h2 0.4.6", + "http 1.1.0", "http-body", + "http-body-util", "hyper", + "hyper-rustls", "hyper-tls", + "hyper-util", "ipnet", "js-sys", "log", "mime", - "mime_guess", "native-tls", "once_cell", "percent-encoding", @@ -2526,42 +2633,40 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg", + "windows-registry", ] [[package]] name = "reqwest-middleware" -version = "0.2.5" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a735987236a8e238bf0296c7e351b999c188ccc11477f311b82b55c93984216" +checksum = "562ceb5a604d3f7c885a792d42c199fd8af239d0a51b2fa6a78aafa092452b04" dependencies = [ "anyhow", "async-trait", - "http", + "http 1.1.0", "reqwest", "serde", - "task-local-extensions", "thiserror", + "tower-service", ] [[package]] name = "reqwest-retry" -version = "0.3.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9af20b65c2ee9746cc575acb6bd28a05ffc0d15e25c992a8f4462d8686aacb4f" +checksum = "a83df1aaec00176d0fabb65dea13f832d2a446ca99107afc17c5d2d4981221d0" dependencies = [ "anyhow", "async-trait", - "chrono", "futures", "getrandom", - "http", + "http 1.1.0", "hyper", "parking_lot 0.11.2", "reqwest", "reqwest-middleware", "retry-policies", - "task-local-extensions", "tokio", "tracing", "wasm-timer", @@ -2569,12 +2674,10 @@ dependencies = [ [[package]] name = "retry-policies" -version = "0.2.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17dd00bff1d737c40dbcd47d4375281bf4c17933f9eef0a185fc7bacca23ecbd" +checksum = "5875471e6cab2871bc150ecb8c727db5113c9338cc3354dc5ee3425b6aa40a1c" dependencies = [ - "anyhow", - "chrono", "rand", ] @@ -2636,13 +2739,43 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls" +version = "0.23.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + [[package]] name = "rustls-pemfile" -version = "1.0.4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "base64 0.21.7", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", ] [[package]] @@ -2986,40 +3119,34 @@ dependencies = [ [[package]] name = "sync_wrapper" -version = "0.1.2" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] [[package]] name = "system-configuration" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "system-configuration-sys", ] [[package]] name = "system-configuration-sys" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" dependencies = [ "core-foundation-sys", "libc", ] -[[package]] -name = "task-local-extensions" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba323866e5d033818e3240feeb9f7db2c4296674e4d9e16b97b7bf8f490434e8" -dependencies = [ - "pin-utils", -] - [[package]] name = "tempfile" version = "3.12.0" @@ -3055,7 +3182,7 @@ dependencies = [ [[package]] name = "thoth" -version = "0.12.10" +version = "0.12.11" dependencies = [ "cargo-husky", "clap", @@ -3070,7 +3197,7 @@ dependencies = [ [[package]] name = "thoth-api" -version = "0.12.10" +version = "0.12.11" dependencies = [ "actix-web", "argon2rs", @@ -3099,7 +3226,7 @@ dependencies = [ [[package]] name = "thoth-api-server" -version = "0.12.10" +version = "0.12.11" dependencies = [ "actix-cors", "actix-identity", @@ -3115,7 +3242,7 @@ dependencies = [ [[package]] name = "thoth-app" -version = "0.12.10" +version = "0.12.11" dependencies = [ "anyhow", "chrono", @@ -3144,7 +3271,7 @@ dependencies = [ [[package]] name = "thoth-app-server" -version = "0.12.10" +version = "0.12.11" dependencies = [ "actix-cors", "actix-web", @@ -3154,7 +3281,7 @@ dependencies = [ [[package]] name = "thoth-client" -version = "0.12.10" +version = "0.12.11" dependencies = [ "chrono", "graphql_client", @@ -3170,7 +3297,7 @@ dependencies = [ [[package]] name = "thoth-errors" -version = "0.12.10" +version = "0.12.11" dependencies = [ "actix-web", "csv", @@ -3191,7 +3318,7 @@ dependencies = [ [[package]] name = "thoth-export-server" -version = "0.12.10" +version = "0.12.11" dependencies = [ "actix-cors", "actix-web", @@ -3288,6 +3415,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.11" @@ -3645,49 +3783,55 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] -name = "windows-sys" -version = "0.48.0" +name = "windows-registry" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" dependencies = [ - "windows-targets 0.48.5", + "windows-result", + "windows-strings", + "windows-targets", ] [[package]] -name = "windows-sys" -version = "0.52.0" +name = "windows-result" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets", ] [[package]] name = "windows-sys" -version = "0.59.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -3696,46 +3840,28 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -3748,48 +3874,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -3805,16 +3907,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "xml-rs" version = "0.8.21" @@ -3840,7 +3932,7 @@ dependencies = [ "cfg-match", "console_error_panic_hook", "gloo 0.2.1", - "http", + "http 0.2.12", "indexmap 1.9.3", "js-sys", "log", diff --git a/Cargo.toml b/Cargo.toml index e657279b0..6de3d6de3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "thoth" -version = "0.12.10" +version = "0.12.11" authors = ["Javier Arias ", "Ross Higman "] edition = "2021" license = "Apache-2.0" @@ -16,11 +16,11 @@ maintenance = { status = "actively-developed" } members = ["thoth-api", "thoth-api-server", "thoth-app", "thoth-app-server", "thoth-client", "thoth-errors", "thoth-export-server"] [dependencies] -thoth-api = { version = "=0.12.10", path = "thoth-api", features = ["backend"] } -thoth-api-server = { version = "=0.12.10", path = "thoth-api-server" } -thoth-app-server = { version = "=0.12.10", path = "thoth-app-server" } -thoth-errors = { version = "=0.12.10", path = "thoth-errors" } -thoth-export-server = { version = "=0.12.10", path = "thoth-export-server" } +thoth-api = { version = "=0.12.11", path = "thoth-api", features = ["backend"] } +thoth-api-server = { version = "=0.12.11", path = "thoth-api-server" } +thoth-app-server = { version = "=0.12.11", path = "thoth-app-server" } +thoth-errors = { version = "=0.12.11", path = "thoth-errors" } +thoth-export-server = { version = "=0.12.11", path = "thoth-export-server" } clap = { version = "4.5.16", features = ["cargo", "env"] } dialoguer = { version = "0.11.0", features = ["password"] } dotenv = "0.15.0" diff --git a/thoth-api-server/Cargo.toml b/thoth-api-server/Cargo.toml index 5ea315228..dcd3d64ac 100644 --- a/thoth-api-server/Cargo.toml +++ b/thoth-api-server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "thoth-api-server" -version = "0.12.10" +version = "0.12.11" authors = ["Javier Arias ", "Ross Higman "] edition = "2021" license = "Apache-2.0" @@ -9,8 +9,8 @@ repository = "https://github.com/thoth-pub/thoth" readme = "README.md" [dependencies] -thoth-api = { version = "=0.12.10", path = "../thoth-api", features = ["backend"] } -thoth-errors = { version = "=0.12.10", path = "../thoth-errors" } +thoth-api = { version = "=0.12.11", path = "../thoth-api", features = ["backend"] } +thoth-errors = { version = "=0.12.11", path = "../thoth-errors" } actix-web = "4.9" actix-cors = "0.7.0" actix-identity = "0.7.1" diff --git a/thoth-api/Cargo.toml b/thoth-api/Cargo.toml index 409e2f7ea..96733f334 100644 --- a/thoth-api/Cargo.toml +++ b/thoth-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "thoth-api" -version = "0.12.10" +version = "0.12.11" authors = ["Javier Arias ", "Ross Higman "] edition = "2021" license = "Apache-2.0" @@ -16,7 +16,7 @@ maintenance = { status = "actively-developed" } backend = ["diesel", "diesel-derive-enum", "diesel_migrations", "futures", "actix-web", "jsonwebtoken"] [dependencies] -thoth-errors = { version = "=0.12.10", path = "../thoth-errors" } +thoth-errors = { version = "=0.12.11", path = "../thoth-errors" } actix-web = { version = "4.8", optional = true } argon2rs = "0.2.5" isbn2 = "0.4.0" diff --git a/thoth-api/src/graphql/model.rs b/thoth-api/src/graphql/model.rs index 0537f31a0..830cb9051 100644 --- a/thoth-api/src/graphql/model.rs +++ b/thoth-api/src/graphql/model.rs @@ -1984,13 +1984,6 @@ impl MutationRoot { )?)?; } - if data.canonical != location.canonical { - // Each publication must have exactly one canonical location. - // Updating an existing location would always violate this, - // as it should always result in either zero or two canonical locations. - return Err(ThothError::CanonicalLocationError.into()); - } - if data.canonical { data.canonical_record_complete(&context.db)?; } diff --git a/thoth-api/src/model/location/crud.rs b/thoth-api/src/model/location/crud.rs index 1692dce4f..878e3530d 100644 --- a/thoth-api/src/model/location/crud.rs +++ b/thoth-api/src/model/location/crud.rs @@ -2,11 +2,11 @@ use super::{ Location, LocationField, LocationHistory, LocationOrderBy, LocationPlatform, NewLocation, NewLocationHistory, PatchLocation, }; +use crate::db_insert; use crate::graphql::utils::Direction; use crate::model::{Crud, DbInsert, HistoryEntry}; use crate::schema::{location, location_history}; -use crate::{crud_methods, db_insert}; -use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl}; +use diesel::{Connection, ExpressionMethods, QueryDsl, RunQueryDsl}; use thoth_errors::{ThothError, ThothResult}; use uuid::Uuid; @@ -126,7 +126,73 @@ impl Crud for Location { crate::model::publication::Publication::from_id(db, &self.publication_id)?.publisher_id(db) } - crud_methods!(location::table, location::dsl::location); + // `crud_methods!` cannot be used for update(), because we need to execute multiple statements + // in the same transaction for changing a non-canonical location to canonical. + // These functions recreate the `crud_methods!` logic. + fn from_id(db: &crate::db::PgPool, entity_id: &Uuid) -> ThothResult { + let mut connection = db.get()?; + location::table + .find(entity_id) + .get_result::(&mut connection) + .map_err(Into::into) + } + + fn create(db: &crate::db::PgPool, data: &NewLocation) -> ThothResult { + db.get()?.transaction(|connection| { + diesel::insert_into(location::table) + .values(data) + .get_result::(connection) + .map_err(Into::into) + }) + } + + fn update( + &self, + db: &crate::db::PgPool, + data: &PatchLocation, + account_id: &Uuid, + ) -> ThothResult { + let mut connection = db.get()?; + connection + .transaction(|connection| { + if data.canonical == self.canonical { + // No change in canonical status, just update the current location + diesel::update(location::table.find(&self.location_id)) + .set(data) + .get_result::(connection) + .map_err(Into::into) + } else if self.canonical && !data.canonical { + // Trying to change canonical location to non-canonical results in error. + Err(ThothError::CanonicalLocationError) + } else { + // Update the existing canonical location to non-canonical + let mut old_canonical_location = + PatchLocation::from(self.get_canonical_location(db)?); + old_canonical_location.canonical = false; + diesel::update(location::table.find(old_canonical_location.location_id)) + .set(old_canonical_location) + .execute(connection)?; + diesel::update(location::table.find(&self.location_id)) + .set(data) + .get_result::(connection) + .map_err(Into::into) + } + }) + .and_then(|location| { + self.new_history_entry(account_id) + .insert(&mut connection) + .map(|_| location) + }) + } + + fn delete(self, db: &crate::db::PgPool) -> ThothResult { + db.get()?.transaction(|connection| { + diesel::delete(location::table.find(self.location_id)) + .execute(connection) + .map(|_| self) + .map_err(Into::into) + }) + } } impl HistoryEntry for Location { @@ -181,6 +247,17 @@ impl NewLocation { } } +impl Location { + pub fn get_canonical_location(&self, db: &crate::db::PgPool) -> ThothResult { + let mut connection = db.get()?; + location::table + .filter(location::publication_id.eq(self.publication_id)) + .filter(location::canonical.eq(true)) + .first::(&mut connection) + .map_err(Into::into) + } +} + impl PatchLocation { pub fn canonical_record_complete(&self, db: &crate::db::PgPool) -> ThothResult<()> { location_canonical_record_complete( diff --git a/thoth-api/src/model/location/mod.rs b/thoth-api/src/model/location/mod.rs index bdf894b79..fba42a0a6 100644 --- a/thoth-api/src/model/location/mod.rs +++ b/thoth-api/src/model/location/mod.rs @@ -242,6 +242,42 @@ impl Default for LocationOrderBy { } } +impl From for PatchLocation { + fn from(location: Location) -> Self { + PatchLocation { + location_id: location.location_id, + publication_id: location.publication_id, + landing_page: location.landing_page, + full_text_url: location.full_text_url, + location_platform: location.location_platform, + canonical: location.canonical, + } + } +} + +#[test] +fn test_location_to_patch_location() { + let location = Location { + location_id: Uuid::parse_str("00000000-0000-0000-AAAA-000000000001").unwrap(), + publication_id: Uuid::parse_str("00000000-0000-0000-AAAA-000000000002").unwrap(), + landing_page: Some("https://www.book.com/pb_landing".to_string()), + full_text_url: Some("https://example.com/full_text.pdf".to_string()), + location_platform: LocationPlatform::PublisherWebsite, + created_at: Default::default(), + updated_at: Default::default(), + canonical: true, + }; + + let patch_location = PatchLocation::from(location.clone()); + + assert_eq!(patch_location.location_id, location.location_id); + assert_eq!(patch_location.publication_id, location.publication_id); + assert_eq!(patch_location.landing_page, location.landing_page); + assert_eq!(patch_location.full_text_url, location.full_text_url); + assert_eq!(patch_location.location_platform, location.location_platform); + assert_eq!(patch_location.canonical, location.canonical); +} + #[test] fn test_locationplatform_default() { let locationplatform: LocationPlatform = Default::default(); diff --git a/thoth-api/src/model/mod.rs b/thoth-api/src/model/mod.rs index e35126b83..42fb26c4f 100644 --- a/thoth-api/src/model/mod.rs +++ b/thoth-api/src/model/mod.rs @@ -400,24 +400,18 @@ macro_rules! crud_methods { use diesel::{QueryDsl, RunQueryDsl}; let mut connection = db.get()?; - match $entity_dsl + $entity_dsl .find(entity_id) .get_result::(&mut connection) - { - Ok(t) => Ok(t), - Err(e) => Err(ThothError::from(e)), - } + .map_err(Into::into) } fn create(db: &$crate::db::PgPool, data: &Self::NewEntity) -> ThothResult { let mut connection = db.get()?; - match diesel::insert_into($table_dsl) + diesel::insert_into($table_dsl) .values(data) .get_result::(&mut connection) - { - Ok(t) => Ok(t), - Err(e) => Err(ThothError::from(e)), - } + .map_err(Into::into) } /// Makes a database transaction that first updates the entity and then creates a new @@ -483,13 +477,10 @@ macro_rules! db_insert { fn insert(&self, connection: &mut diesel::PgConnection) -> ThothResult { use diesel::RunQueryDsl; - match diesel::insert_into($table_dsl) + diesel::insert_into($table_dsl) .values(self) .get_result(connection) - { - Ok(t) => Ok(t), - Err(e) => Err(ThothError::from(e)), - } + .map_err(Into::into) } }; } diff --git a/thoth-api/src/model/work_relation/crud.rs b/thoth-api/src/model/work_relation/crud.rs index 9f5fda3f5..1e7fbfdd9 100644 --- a/thoth-api/src/model/work_relation/crud.rs +++ b/thoth-api/src/model/work_relation/crud.rs @@ -118,13 +118,10 @@ impl Crud for WorkRelation { // This function recreates the `crud_methods!` from_id() logic. fn from_id(db: &crate::db::PgPool, entity_id: &Uuid) -> ThothResult { let mut connection = db.get()?; - match work_relation::table + work_relation::table .find(entity_id) .get_result::(&mut connection) - { - Ok(t) => Ok(t), - Err(e) => Err(ThothError::from(e)), - } + .map_err(Into::into) } fn create(db: &crate::db::PgPool, data: &NewWorkRelation) -> ThothResult { diff --git a/thoth-app-server/Cargo.toml b/thoth-app-server/Cargo.toml index 338fdbfd3..224fdcc6e 100644 --- a/thoth-app-server/Cargo.toml +++ b/thoth-app-server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "thoth-app-server" -version = "0.12.10" +version = "0.12.11" authors = ["Javier Arias ", "Ross Higman "] edition = "2021" license = "Apache-2.0" diff --git a/thoth-app/Cargo.toml b/thoth-app/Cargo.toml index f2fb79a38..47b991591 100644 --- a/thoth-app/Cargo.toml +++ b/thoth-app/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "thoth-app" -version = "0.12.10" +version = "0.12.11" authors = ["Javier Arias ", "Ross Higman "] edition = "2021" license = "Apache-2.0" @@ -27,7 +27,7 @@ yewtil = { version = "0.4.0", features = ["fetch"] } wasm-bindgen = "0.2.93" wasm-logger = "0.2.0" web-sys = { version = "0.3.57", features = ["HtmlInputElement", "HtmlSelectElement", "HtmlTextAreaElement"] } -reqwest = { version = "0.11", features = ["json"] } +reqwest = { version = "0.12", features = ["json"] } semver = "1.0.23" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" @@ -36,8 +36,8 @@ uuid = { version = "1.10.0", features = ["serde", "v4"] } # `getrandom` is a dependency of `uuid`, we need to explicitly import and include the `js` feature to enable wasm # https://docs.rs/getrandom/latest/getrandom/#webassembly-support getrandom = { version = "0.2", features = ["js"] } -thoth-api = { version = "=0.12.10", path = "../thoth-api" } -thoth-errors = { version = "=0.12.10", path = "../thoth-errors" } +thoth-api = { version = "=0.12.11", path = "../thoth-api" } +thoth-errors = { version = "=0.12.11", path = "../thoth-errors" } [build-dependencies] dotenv = "0.15.0" diff --git a/thoth-app/src/component/locations_form.rs b/thoth-app/src/component/locations_form.rs index 8ee8c1f8b..4515f9387 100644 --- a/thoth-app/src/component/locations_form.rs +++ b/thoth-app/src/component/locations_form.rs @@ -22,7 +22,7 @@ use crate::models::location::create_location_mutation::CreateLocationRequest; use crate::models::location::create_location_mutation::CreateLocationRequestBody; use crate::models::location::create_location_mutation::PushActionCreateLocation; use crate::models::location::create_location_mutation::PushCreateLocation; -use crate::models::location::create_location_mutation::Variables; +use crate::models::location::create_location_mutation::Variables as CreateVariables; use crate::models::location::delete_location_mutation::DeleteLocationRequest; use crate::models::location::delete_location_mutation::DeleteLocationRequestBody; use crate::models::location::delete_location_mutation::PushActionDeleteLocation; @@ -30,8 +30,14 @@ use crate::models::location::delete_location_mutation::PushDeleteLocation; use crate::models::location::delete_location_mutation::Variables as DeleteVariables; use crate::models::location::location_platforms_query::FetchActionLocationPlatforms; use crate::models::location::location_platforms_query::FetchLocationPlatforms; +use crate::models::location::update_location_mutation::PushActionUpdateLocation; +use crate::models::location::update_location_mutation::PushUpdateLocation; +use crate::models::location::update_location_mutation::UpdateLocationRequest; +use crate::models::location::update_location_mutation::UpdateLocationRequestBody; +use crate::models::location::update_location_mutation::Variables as UpdateVariables; use crate::models::location::LocationPlatformValues; use crate::string::CANCEL_BUTTON; +use crate::string::EDIT_BUTTON; use crate::string::EMPTY_LOCATIONS; use crate::string::NO; use crate::string::REMOVE_BUTTON; @@ -42,11 +48,13 @@ use super::ToOption; pub struct LocationsFormComponent { data: LocationsFormData, - new_location: Location, - show_add_form: bool, + location: Location, + show_modal_form: bool, + in_edit_mode: bool, fetch_location_platforms: FetchLocationPlatforms, - push_location: PushCreateLocation, + create_location: PushCreateLocation, delete_location: PushDeleteLocation, + update_location: PushUpdateLocation, notification_bus: NotificationDispatcher, } @@ -56,13 +64,15 @@ struct LocationsFormData { } pub enum Msg { - ToggleAddFormDisplay(bool), + ToggleModalFormDisplay(bool, Option), SetLocationPlatformsFetchState(FetchActionLocationPlatforms), GetLocationPlatforms, - SetLocationPushState(PushActionCreateLocation), + SetLocationCreateState(PushActionCreateLocation), CreateLocation, SetLocationDeleteState(PushActionDeleteLocation), DeleteLocation(Uuid), + SetLocationUpdateState(PushActionUpdateLocation), + UpdateLocation, ChangeLandingPage(String), ChangeFullTextUrl(String), ChangeLocationPlatform(LocationPlatform), @@ -73,7 +83,7 @@ pub enum Msg { pub struct Props { pub locations: Option>, pub publication_id: Uuid, - pub update_locations: Callback>>, + pub update_locations: Callback<()>, } impl Component for LocationsFormComponent { @@ -82,35 +92,50 @@ impl Component for LocationsFormComponent { fn create(ctx: &Context) -> Self { let data: LocationsFormData = Default::default(); - let show_add_form = false; + let show_modal_form = false; + let in_edit_mode = false; // The first location needs to be canonical = true (as it will be // the only location); subsequent locations need to be canonical = false - let new_location = Location { + let location = Location { canonical: ctx.props().locations.as_ref().unwrap_or(&vec![]).is_empty(), ..Default::default() }; let fetch_location_platforms = Default::default(); - let push_location = Default::default(); + let create_location = Default::default(); let delete_location = Default::default(); + let update_location = Default::default(); let notification_bus = NotificationBus::dispatcher(); ctx.link().send_message(Msg::GetLocationPlatforms); LocationsFormComponent { data, - new_location, - show_add_form, + location, + show_modal_form, + in_edit_mode, fetch_location_platforms, - push_location, + create_location, delete_location, + update_location, notification_bus, } } fn update(&mut self, ctx: &Context, msg: Self::Message) -> bool { match msg { - Msg::ToggleAddFormDisplay(value) => { - self.show_add_form = value; + Msg::ToggleModalFormDisplay(show_form, l) => { + self.show_modal_form = show_form; + self.in_edit_mode = l.is_some(); + + if self.in_edit_mode { + if let Some(location) = l { + // Editing existing location: load its current values. + self.location = location; + } + } else { + self.location = Default::default(); + self.location.location_platform = LocationPlatform::Other; + } true } Msg::SetLocationPlatformsFetchState(fetch_state) => { @@ -133,9 +158,9 @@ impl Component for LocationsFormComponent { .send_message(Msg::SetLocationPlatformsFetchState(FetchAction::Fetching)); false } - Msg::SetLocationPushState(fetch_state) => { - self.push_location.apply(fetch_state); - match self.push_location.as_ref().state() { + Msg::SetLocationCreateState(fetch_state) => { + self.create_location.apply(fetch_state); + match self.create_location.as_ref().state() { FetchState::NotFetching(_) => false, FetchState::Fetching(_) => false, FetchState::Fetched(body) => match &body.data.create_location { @@ -144,12 +169,14 @@ impl Component for LocationsFormComponent { let mut locations: Vec = ctx.props().locations.clone().unwrap_or_default(); locations.push(location); - ctx.props().update_locations.emit(Some(locations)); - ctx.link().send_message(Msg::ToggleAddFormDisplay(false)); + ctx.props().update_locations.emit(()); + ctx.link() + .send_message(Msg::ToggleModalFormDisplay(false, None)); true } None => { - ctx.link().send_message(Msg::ToggleAddFormDisplay(false)); + ctx.link() + .send_message(Msg::ToggleModalFormDisplay(false, None)); self.notification_bus.send(Request::NotificationBusMsg(( "Failed to save".to_string(), NotificationStatus::Danger, @@ -158,7 +185,8 @@ impl Component for LocationsFormComponent { } }, FetchState::Failed(_, err) => { - ctx.link().send_message(Msg::ToggleAddFormDisplay(false)); + ctx.link() + .send_message(Msg::ToggleModalFormDisplay(false, None)); self.notification_bus.send(Request::NotificationBusMsg(( ThothError::from(err).to_string(), NotificationStatus::Danger, @@ -169,21 +197,77 @@ impl Component for LocationsFormComponent { } Msg::CreateLocation => { let body = CreateLocationRequestBody { - variables: Variables { + variables: CreateVariables { publication_id: ctx.props().publication_id, - landing_page: self.new_location.landing_page.clone(), - full_text_url: self.new_location.full_text_url.clone(), - location_platform: self.new_location.location_platform.clone(), - canonical: self.new_location.canonical, + landing_page: self.location.landing_page.clone(), + full_text_url: self.location.full_text_url.clone(), + location_platform: self.location.location_platform.clone(), + canonical: self.location.canonical, }, ..Default::default() }; let request = CreateLocationRequest { body }; - self.push_location = Fetch::new(request); + self.create_location = Fetch::new(request); ctx.link() - .send_future(self.push_location.fetch(Msg::SetLocationPushState)); + .send_future(self.create_location.fetch(Msg::SetLocationCreateState)); ctx.link() - .send_message(Msg::SetLocationPushState(FetchAction::Fetching)); + .send_message(Msg::SetLocationCreateState(FetchAction::Fetching)); + false + } + Msg::SetLocationUpdateState(fetch_state) => { + self.update_location.apply(fetch_state); + match self.update_location.as_ref().state() { + FetchState::NotFetching(_) => false, + FetchState::Fetching(_) => false, + FetchState::Fetched(body) => match &body.data.update_location { + Some(_l) => { + ctx.props().update_locations.emit(()); + ctx.link() + .send_message(Msg::ToggleModalFormDisplay(false, None)); + // changed the return value to false below, but this doesn't fix the display + // issue where the page jumps during refresh when modal is exited + false + } + None => { + ctx.link() + .send_message(Msg::ToggleModalFormDisplay(false, None)); + self.notification_bus.send(Request::NotificationBusMsg(( + "Failed to save".to_string(), + NotificationStatus::Danger, + ))); + false + } + }, + FetchState::Failed(_, err) => { + ctx.link() + .send_message(Msg::ToggleModalFormDisplay(false, None)); + self.notification_bus.send(Request::NotificationBusMsg(( + ThothError::from(err).to_string(), + NotificationStatus::Danger, + ))); + false + } + } + } + Msg::UpdateLocation => { + let body = UpdateLocationRequestBody { + variables: UpdateVariables { + location_id: self.location.location_id, + publication_id: self.location.publication_id, + landing_page: self.location.landing_page.clone(), + full_text_url: self.location.full_text_url.clone(), + location_platform: self.location.location_platform.clone(), + canonical: self.location.canonical, + }, + ..Default::default() + }; + let request = UpdateLocationRequest { body }; + self.update_location = Fetch::new(request); + ctx.link() + .send_future(self.update_location.fetch(Msg::SetLocationUpdateState)); + ctx.link() + .send_message(Msg::SetLocationUpdateState(FetchAction::Fetching)); + false } Msg::SetLocationDeleteState(fetch_state) => { @@ -192,16 +276,8 @@ impl Component for LocationsFormComponent { FetchState::NotFetching(_) => false, FetchState::Fetching(_) => false, FetchState::Fetched(body) => match &body.data.delete_location { - Some(location) => { - let to_keep: Vec = ctx - .props() - .locations - .clone() - .unwrap_or_default() - .into_iter() - .filter(|l| l.location_id != location.location_id) - .collect(); - ctx.props().update_locations.emit(Some(to_keep)); + Some(_location) => { + ctx.props().update_locations.emit(()); true } None => { @@ -234,18 +310,14 @@ impl Component for LocationsFormComponent { .send_message(Msg::SetLocationDeleteState(FetchAction::Fetching)); false } - Msg::ChangeLandingPage(val) => self - .new_location - .landing_page - .neq_assign(val.to_opt_string()), - Msg::ChangeFullTextUrl(val) => self - .new_location - .full_text_url - .neq_assign(val.to_opt_string()), - Msg::ChangeLocationPlatform(code) => { - self.new_location.location_platform.neq_assign(code) + Msg::ChangeLandingPage(val) => { + self.location.landing_page.neq_assign(val.to_opt_string()) + } + Msg::ChangeFullTextUrl(val) => { + self.location.full_text_url.neq_assign(val.to_opt_string()) } - Msg::ChangeCanonical(val) => self.new_location.canonical.neq_assign(val), + Msg::ChangeLocationPlatform(code) => self.location.location_platform.neq_assign(code), + Msg::ChangeCanonical(val) => self.location.canonical.neq_assign(val), } } @@ -253,11 +325,11 @@ impl Component for LocationsFormComponent { let locations = ctx.props().locations.clone().unwrap_or_default(); let open_modal = ctx.link().callback(|e: MouseEvent| { e.prevent_default(); - Msg::ToggleAddFormDisplay(true) + Msg::ToggleModalFormDisplay(true, None) }); let close_modal = ctx.link().callback(|e: MouseEvent| { e.prevent_default(); - Msg::ToggleAddFormDisplay(false) + Msg::ToggleModalFormDisplay(false, None) }); html! {