initial create user
This commit is contained in:
parent
b9866a8c19
commit
6837495eba
250
Cargo.lock
generated
250
Cargo.lock
generated
@ -107,7 +107,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"sha-1 0.9.4",
|
||||
"sha-1 0.9.6",
|
||||
"slab",
|
||||
"time 0.2.26",
|
||||
]
|
||||
@ -202,7 +202,7 @@ checksum = "c697a62a2f51c5c26af6b1dded0622f15bec690da191615947e0c1b2b7b75198"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"chrono",
|
||||
"futures 0.3.14",
|
||||
"futures 0.3.15",
|
||||
"pin-project 0.4.28",
|
||||
"slog",
|
||||
]
|
||||
@ -327,16 +327,16 @@ dependencies = [
|
||||
"actix-service",
|
||||
"actix-web",
|
||||
"derive_more",
|
||||
"futures 0.3.14",
|
||||
"futures 0.3.15",
|
||||
"mime_guess",
|
||||
"path-slash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.14.1"
|
||||
version = "0.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7"
|
||||
checksum = "03345e98af8f3d786b6d9f656ccfa6ac316d954e92bc4841f0bba20789d5fb5a"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
@ -426,9 +426,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.15"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@ -575,11 +575,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.57"
|
||||
version = "0.3.59"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ed203b9ba68b242c62b3fb7480f589dd49829be1edb3fe8fc8b4ffda2dcb8d"
|
||||
checksum = "4717cfcbfaa661a0fd48f8453951837ae7e8f81e481fbb136e3202d72805a744"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"miniz_oxide 0.4.4",
|
||||
@ -706,9 +707,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.15"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d"
|
||||
checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@ -983,10 +984,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b"
|
||||
|
||||
[[package]]
|
||||
name = "cpuid-bool"
|
||||
version = "0.1.2"
|
||||
name = "cpufeatures"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
|
||||
checksum = "281f563b2c3a0e535ab12d81d3c5859045795256ad269afa7c19542585b68f93"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpuid-bool"
|
||||
@ -1035,9 +1039,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.3"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12"
|
||||
checksum = "52fb27eab85b17fbb9f6fd667089e07d6a2eb8743d02639ee7f6a7a7729c9c94"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils",
|
||||
@ -1058,9 +1062,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.3"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49"
|
||||
checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278"
|
||||
dependencies = [
|
||||
"autocfg 1.0.1",
|
||||
"cfg-if 1.0.0",
|
||||
@ -1197,9 +1201,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "enum-map"
|
||||
version = "1.0.0"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88acdb627a242ba1bf36653fa200f72c037ca3324e0710d1ac4fee809a1539cd"
|
||||
checksum = "34c3f3c98ee954dbafd343b3e0d827bb167cdda151b3c88ae04b0e5fa7db1028"
|
||||
dependencies = [
|
||||
"enum-map-derive",
|
||||
"serde",
|
||||
@ -1315,7 +1319,7 @@ dependencies = [
|
||||
"fluent-syntax 0.11.0",
|
||||
"intl-memoizer",
|
||||
"intl_pluralrules",
|
||||
"ouroboros 0.9.1",
|
||||
"ouroboros 0.9.2",
|
||||
"rustc-hash",
|
||||
"smallvec",
|
||||
"unic-langid",
|
||||
@ -1464,9 +1468,9 @@ checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253"
|
||||
checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@ -1479,9 +1483,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25"
|
||||
checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@ -1489,9 +1493,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815"
|
||||
checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"
|
||||
|
||||
[[package]]
|
||||
name = "futures-cpupool"
|
||||
@ -1505,9 +1509,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d"
|
||||
checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
@ -1516,16 +1520,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04"
|
||||
checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b"
|
||||
checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121"
|
||||
dependencies = [
|
||||
"autocfg 1.0.1",
|
||||
"proc-macro-hack",
|
||||
"proc-macro2 1.0.26",
|
||||
"quote 1.0.9",
|
||||
@ -1534,22 +1539,23 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23"
|
||||
checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc"
|
||||
checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.14"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025"
|
||||
checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967"
|
||||
dependencies = [
|
||||
"autocfg 1.0.1",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
@ -1659,9 +1665,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.23.0"
|
||||
version = "0.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
|
||||
checksum = "0e4075386626662786ddb0ec9081e7c7eeb1ba31951f447ca780ef9f5d568189"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
@ -1855,9 +1861,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a1ce40d6fc9764887c2fdc7305c3dcc429ba11ff981c1509416afd5697e4437"
|
||||
checksum = "f3a87b616e37e93c22fb19bcd386f02f3af5ea98a25670ad0fce773de23c5e68"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
@ -2063,9 +2069,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.50"
|
||||
version = "0.3.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c"
|
||||
checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
@ -2107,9 +2113,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.93"
|
||||
version = "0.2.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
|
||||
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@ -2140,9 +2146,9 @@ checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a3c91c24eae6777794bb1997ad98bbb87daf92890acab859f7eaa4320333176"
|
||||
checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb"
|
||||
dependencies = [
|
||||
"scopeguard 1.1.0",
|
||||
]
|
||||
@ -2194,9 +2200,9 @@ checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.4"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
@ -2398,9 +2404,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.23.0"
|
||||
version = "0.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
|
||||
checksum = "1a5b3dd1c072ee7963717671d1ca129f1048fda25edea6b752bfc71ac8854170"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
@ -2422,9 +2428,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.33"
|
||||
version = "0.10.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a61075b62a23fef5a29815de7536d940aa35ce96d18ce0cc5076272db678a577"
|
||||
checksum = "6d7830286ad6a3973c0f1d9b73738f69c76b739301d0229c4b96501695cbe4c8"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if 1.0.0",
|
||||
@ -2436,15 +2442,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.2"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
|
||||
checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.61"
|
||||
version = "0.9.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "313752393519e876837e09e1fa183ddef0be7735868dced3196f4472d536277f"
|
||||
checksum = "b6b0d6fb7d80f877617dfcb014e605e2b5ab2fb0afdf27935219bb6bd984cb98"
|
||||
dependencies = [
|
||||
"autocfg 1.0.1",
|
||||
"cc",
|
||||
@ -2460,7 +2466,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b91cea1dfd50064e52db033179952d18c770cbc5dfefc8eba45d619357ba3914"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures 0.3.14",
|
||||
"futures 0.3.15",
|
||||
"js-sys",
|
||||
"lazy_static",
|
||||
"percent-encoding",
|
||||
@ -2503,11 +2509,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ouroboros"
|
||||
version = "0.9.1"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc53e78022445d2d37b673c5aaeed945a7aacaa4aa89c867c1f28b2e6778e67d"
|
||||
checksum = "c8234affc3c31a8b744cc236fd3dc7443f57c6370cbb7d61f41f9c7dcc6c2530"
|
||||
dependencies = [
|
||||
"ouroboros_macro 0.9.1",
|
||||
"ouroboros_macro 0.9.2",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
@ -2526,9 +2532,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ouroboros_macro"
|
||||
version = "0.9.1"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee93af29e97048340c10f5c1a1d88c754f48337a41fbd4fb8e1e20ce41c76936"
|
||||
checksum = "3633332cd8c0b6a865e2e0e705fad9cde25fe458cd0c693629b58a7b15e4d852"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"proc-macro-error",
|
||||
@ -2714,7 +2720,7 @@ version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eebcc4aa140b9abd2bc40d9c3f7ccec842679cd79045ac3a7ac698c1a064b7cd"
|
||||
dependencies = [
|
||||
"cpuid-bool 0.2.0",
|
||||
"cpuid-bool",
|
||||
"opaque-debug 0.3.0",
|
||||
"universal-hash",
|
||||
]
|
||||
@ -2776,7 +2782,7 @@ version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.1",
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3129,18 +3135,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.6"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8270314b5ccceb518e7e578952f0b72b88222d02e8f77f5ecf7abbb673539041"
|
||||
checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.4.6"
|
||||
version = "1.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759"
|
||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@ -3159,9 +3165,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.23"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
@ -3247,9 +3253,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.18"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
|
||||
checksum = "410f7acf3cb3a44527c5d9546bad4bf4e6c460915d5f9f2fc524498bfe8f70ce"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
@ -3365,7 +3371,7 @@ dependencies = [
|
||||
"cookie",
|
||||
"dbg",
|
||||
"enclose",
|
||||
"futures 0.3.14",
|
||||
"futures 0.3.15",
|
||||
"gloo-file",
|
||||
"gloo-timers",
|
||||
"indexmap",
|
||||
@ -3417,18 +3423,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.125"
|
||||
version = "1.0.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
|
||||
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.125"
|
||||
version = "1.0.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
|
||||
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.26",
|
||||
"quote 1.0.9",
|
||||
@ -3473,13 +3479,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.9.4"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfebf75d25bd900fd1e7d11501efab59bc846dbc76196839663e6637bba9f25f"
|
||||
checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16"
|
||||
dependencies = [
|
||||
"block-buffer 0.9.0",
|
||||
"cfg-if 1.0.0",
|
||||
"cpuid-bool 0.1.2",
|
||||
"cpufeatures",
|
||||
"digest 0.9.0",
|
||||
"opaque-debug 0.3.0",
|
||||
]
|
||||
@ -3492,13 +3498,13 @@ checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.9.3"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de"
|
||||
checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12"
|
||||
dependencies = [
|
||||
"block-buffer 0.9.0",
|
||||
"cfg-if 1.0.0",
|
||||
"cpuid-bool 0.1.2",
|
||||
"cpufeatures",
|
||||
"digest 0.9.0",
|
||||
"opaque-debug 0.3.0",
|
||||
]
|
||||
@ -3597,9 +3603,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "spinning_top"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8bd0ab6b8c375d2d963503b90d3770010d95bc3b5f98036f948dee24bf4e8879"
|
||||
checksum = "75adad84ee84b521fb2cca2d4fd0f1dab1d8d026bda3c5bea4ca63b5f9f9293c"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
@ -3680,7 +3686,7 @@ dependencies = [
|
||||
"cargo_metadata",
|
||||
"dotenv",
|
||||
"either",
|
||||
"futures 0.3.14",
|
||||
"futures 0.3.15",
|
||||
"heck",
|
||||
"hex",
|
||||
"lazy_static",
|
||||
@ -3820,13 +3826,13 @@ checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.70"
|
||||
version = "1.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9505f307c872bab8eb46f77ae357c8eba1fdacead58ee5a850116b1d7f82883"
|
||||
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.26",
|
||||
"quote 1.0.9",
|
||||
"unicode-xid 0.2.1",
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3838,7 +3844,7 @@ dependencies = [
|
||||
"proc-macro2 1.0.26",
|
||||
"quote 1.0.9",
|
||||
"syn",
|
||||
"unicode-xid 0.2.1",
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4126,9 +4132,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.25"
|
||||
version = "0.1.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f"
|
||||
checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"log",
|
||||
@ -4144,7 +4150,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc36fc2f840643e49d220d07cd7ca81bc31c7f6df25f164d4257971533dab354"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"futures 0.3.14",
|
||||
"futures 0.3.15",
|
||||
"tracing",
|
||||
"tracing-futures",
|
||||
"uuid",
|
||||
@ -4163,9 +4169,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-bunyan-formatter"
|
||||
version = "0.2.0"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05e6b1b6c038da11d8d704f93b3974b0394824cdcc8c818c48255183cf315fd5"
|
||||
checksum = "dce1eae70720bd6bb3944f7cf501761aeae658bd1f9293aa373c71a195064910"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"gethostname",
|
||||
@ -4180,9 +4186,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.17"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f"
|
||||
checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
@ -4233,9 +4239,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.2.17"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "705096c6f83bf68ea5d357a6aa01829ddbdac531b357b45abeca842938085baa"
|
||||
checksum = "aa5553bf0883ba7c9cbe493b085c29926bd41b66afc31ff72cf17ff4fb60dcd5"
|
||||
dependencies = [
|
||||
"ansi_term 0.12.1",
|
||||
"chrono",
|
||||
@ -4262,7 +4268,7 @@ dependencies = [
|
||||
"async-trait",
|
||||
"cfg-if 1.0.0",
|
||||
"enum-as-inner",
|
||||
"futures 0.3.14",
|
||||
"futures 0.3.15",
|
||||
"idna",
|
||||
"lazy_static",
|
||||
"log",
|
||||
@ -4280,7 +4286,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "710f593b371175db53a26d0b38ed2978fafb9e9e8d3868b1acd753ea18df0ceb"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"futures 0.3.14",
|
||||
"futures 0.3.15",
|
||||
"ipconfig",
|
||||
"lazy_static",
|
||||
"log",
|
||||
@ -4459,9 +4465,9 @@ checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "unicode_categories"
|
||||
@ -4487,9 +4493,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.2.1"
|
||||
version = "2.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b"
|
||||
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
@ -4597,9 +4603,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.73"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9"
|
||||
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"serde",
|
||||
@ -4609,9 +4615,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.73"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae"
|
||||
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
@ -4624,9 +4630,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.23"
|
||||
version = "0.4.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81b8b767af23de6ac18bf2168b690bed2902743ddf0fb39252e36f9e2bfc63ea"
|
||||
checksum = "5fba7978c679d53ce2d0ac80c8c175840feb849a161664365d1287b41f2e67f1"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
@ -4636,9 +4642,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.73"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f"
|
||||
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
|
||||
dependencies = [
|
||||
"quote 1.0.9",
|
||||
"wasm-bindgen-macro-support",
|
||||
@ -4646,9 +4652,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.73"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c"
|
||||
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.26",
|
||||
"quote 1.0.9",
|
||||
@ -4659,15 +4665,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.73"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489"
|
||||
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.50"
|
||||
version = "0.3.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be"
|
||||
checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
|
@ -2,4 +2,10 @@
|
||||
members = [
|
||||
"pslink",
|
||||
"app",
|
||||
]
|
||||
]
|
||||
|
||||
[profile]
|
||||
[profile.release]
|
||||
lto = true
|
||||
#codegen-units = 1
|
||||
opt-level = 'z'
|
@ -19,12 +19,9 @@ crate-type = ["cdylib", "rlib"]
|
||||
fluent = "0.15"
|
||||
seed = "0.8"
|
||||
serde = "1.0"
|
||||
strum_macros = "0.20"
|
||||
unic-langid = "0.9"
|
||||
strum_macros = "0.20"
|
||||
strum = "0.20"
|
||||
enum-map = "1"
|
||||
|
||||
shared = { path = "../shared" }
|
||||
|
||||
[profile.release]
|
||||
opt-level = 'z'
|
@ -28,9 +28,11 @@ edit-user-headline = Benutzereinstellungen von: {$username}
|
||||
username = Benutzername
|
||||
email = Email
|
||||
password = Passwort
|
||||
password-placeholder = Leer lassen um das Passwort nicht zu ändern
|
||||
leave-password-empty-hint = Leer lassen um das Passwort nicht zu ändern
|
||||
save-user = Benutzer speichern
|
||||
edit-user = Benutzer editieren
|
||||
create-user = Benutzer Erstellen
|
||||
new-user = Neuer Benutzer
|
||||
make-user-admin = Zum Administrator befördern
|
||||
make-user-regular = Zurückstufen zum normalen Nutzer
|
||||
|
||||
|
@ -28,9 +28,11 @@ edit-user-headline = Change Settings of: {$username}
|
||||
username = Username
|
||||
email = Email
|
||||
password = Password
|
||||
password-placeholder = Leave this empty to keep the current password
|
||||
leave-password-empty-hint = Leave this empty to keep the current password
|
||||
save-user = Save this user
|
||||
edit-user = Edit this user
|
||||
new-user = Neuer Benutzer
|
||||
create-user = Create user
|
||||
make-user-admin = Promote to admin
|
||||
make-user-regular = Demote to regular
|
||||
|
||||
|
@ -49,13 +49,13 @@ enum Page {
|
||||
impl Page {
|
||||
fn init(mut url: Url, orders: &mut impl Orders<Msg>, i18n: I18n) -> Self {
|
||||
url.next_path_part();
|
||||
let result = match url.remaining_path_parts().as_slice() {
|
||||
[] | ["list_links"] => Self::Home(pages::list_links::init(
|
||||
let result = match url.next_path_part() {
|
||||
None | Some("list_links") => Self::Home(pages::list_links::init(
|
||||
url,
|
||||
&mut orders.proxy(Msg::ListLinksMsg),
|
||||
i18n,
|
||||
)),
|
||||
["list_users"] => Self::ListUsers(pages::list_users::init(
|
||||
Some("list_users") => Self::ListUsers(pages::list_users::init(
|
||||
url,
|
||||
&mut orders.proxy(Msg::ListUsersMsg),
|
||||
i18n,
|
||||
@ -144,6 +144,10 @@ impl<'a> Urls<'a> {
|
||||
pub fn list_users(self) -> Url {
|
||||
self.base_url().add_path_part("list_users")
|
||||
}
|
||||
#[must_use]
|
||||
pub fn create_user(self) -> Url {
|
||||
self.list_users().add_path_part("create_user")
|
||||
}
|
||||
}
|
||||
|
||||
// ------ ------
|
||||
|
@ -25,8 +25,12 @@ pub fn navigation(i18n: &I18n, base_url: &Url) -> Node<Msg> {
|
||||
],],
|
||||
li![a![ev(Ev::Click, |_| Msg::NoMessage), t!("add-link"),],],
|
||||
li![a![
|
||||
attrs! {At::Href => "#"},
|
||||
ev(Ev::Click, |_| Msg::NoMessage),
|
||||
attrs! {At::Href => crate::Urls::new(base_url).create_user()},
|
||||
ev(Ev::Click, |_| Msg::ListUsersMsg(
|
||||
super::pages::list_users::Msg::Edit(
|
||||
super::pages::list_users::UserEditMsg::CreateNewUser
|
||||
)
|
||||
)),
|
||||
t!("invite-user"),
|
||||
],],
|
||||
li![a![
|
||||
|
@ -1,21 +1,33 @@
|
||||
use std::cell::RefCell;
|
||||
|
||||
use enum_map::EnumMap;
|
||||
use seed::{attrs, button, h1, input, log, prelude::*, section, table, td, th, tr, Url, C};
|
||||
use seed::{
|
||||
a, attrs, button, div, h1, input, log, p, prelude::*, section, table, td, th, tr, Url, C, IF,
|
||||
};
|
||||
use shared::{
|
||||
apirequests::general::{Operation, Ordering},
|
||||
apirequests::users::{UserOverviewColumns, UserRequestForm},
|
||||
apirequests::{
|
||||
general::{EditMode, SuccessMessage},
|
||||
users::{UserDelta, UserOverviewColumns, UserRequestForm},
|
||||
},
|
||||
datatypes::User,
|
||||
};
|
||||
|
||||
use crate::i18n::I18n;
|
||||
#[must_use]
|
||||
pub fn init(_: Url, orders: &mut impl Orders<Msg>, i18n: I18n) -> Model {
|
||||
orders.send_msg(Msg::Fetch);
|
||||
pub fn init(mut url: Url, orders: &mut impl Orders<Msg>, i18n: I18n) -> Model {
|
||||
orders.send_msg(Msg::Query(UserQueryMsg::Fetch));
|
||||
let user_edit = match url.next_path_part() {
|
||||
Some("create_user") => Some(RefCell::new(UserDelta::default())),
|
||||
None | Some(_) => None,
|
||||
};
|
||||
Model {
|
||||
users: Vec::new(),
|
||||
i18n,
|
||||
formconfig: UserRequestForm::default(),
|
||||
inputs: EnumMap::default(),
|
||||
user_edit: None,
|
||||
user_edit,
|
||||
last_message: None,
|
||||
}
|
||||
}
|
||||
#[derive(Debug)]
|
||||
@ -24,13 +36,8 @@ pub struct Model {
|
||||
i18n: I18n,
|
||||
formconfig: UserRequestForm,
|
||||
inputs: EnumMap<UserOverviewColumns, FilterInput>,
|
||||
user_edit: Option<UserEditMode>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum UserEditMode {
|
||||
Create { user: User },
|
||||
Edit { user: User },
|
||||
user_edit: Option<RefCell<UserDelta>>,
|
||||
last_message: Option<SuccessMessage>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
@ -40,32 +47,61 @@ struct FilterInput {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Msg {
|
||||
Query(UserQueryMsg),
|
||||
Edit(UserEditMsg),
|
||||
}
|
||||
|
||||
/// All the messages on user Querying
|
||||
#[derive(Clone)]
|
||||
pub enum UserQueryMsg {
|
||||
Fetch,
|
||||
FailedToFetchUsers,
|
||||
OrderBy(UserOverviewColumns),
|
||||
Received(Vec<User>),
|
||||
IdFilterChanged(String),
|
||||
EmailFilterChanged(String),
|
||||
UsernameFilterChanged(String),
|
||||
EditUserSelected(User),
|
||||
}
|
||||
/// All the messages on user editing
|
||||
#[derive(Clone)]
|
||||
pub enum UserEditMsg {
|
||||
EditUserSelected(UserDelta),
|
||||
CreateNewUser,
|
||||
UserCreated(SuccessMessage),
|
||||
EditUsernameChanged(String),
|
||||
EditEmailChanged(String),
|
||||
EditPasswordChanged(String),
|
||||
SaveUser,
|
||||
FailedToCreateUser,
|
||||
}
|
||||
|
||||
/// # Panics
|
||||
/// Sould only panic on bugs.
|
||||
pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
match msg {
|
||||
Msg::Fetch => {
|
||||
Msg::Query(msg) => process_query_messages(msg, model, orders),
|
||||
Msg::Edit(msg) => process_user_edit_messages(msg, model, orders),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_query_messages(msg: UserQueryMsg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
match msg {
|
||||
UserQueryMsg::Fetch => {
|
||||
orders.skip(); // No need to rerender
|
||||
let data = model.formconfig.clone(); // complicated way to move into the closure
|
||||
orders.perform_cmd(async {
|
||||
let data = data;
|
||||
let response = fetch(
|
||||
let response = match fetch(
|
||||
Request::new("/admin/json/list_users/")
|
||||
.method(Method::Post)
|
||||
.json(&data)
|
||||
.expect("serialization failed"),
|
||||
)
|
||||
.await
|
||||
.expect("HTTP request failed");
|
||||
{
|
||||
Ok(response) => response,
|
||||
Err(_) => return Msg::Query(UserQueryMsg::FailedToFetchUsers),
|
||||
};
|
||||
|
||||
let users: Vec<User> = response
|
||||
.check_status() // ensure we've got 2xx status
|
||||
@ -74,10 +110,10 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
.await
|
||||
.expect("deserialization failed");
|
||||
|
||||
Msg::Received(users)
|
||||
Msg::Query(UserQueryMsg::Received(users))
|
||||
});
|
||||
}
|
||||
Msg::OrderBy(column) => {
|
||||
UserQueryMsg::OrderBy(column) => {
|
||||
model.formconfig.order = model.formconfig.order.as_ref().map_or_else(
|
||||
|| {
|
||||
Some(Operation {
|
||||
@ -96,7 +132,7 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
})
|
||||
},
|
||||
);
|
||||
orders.send_msg(Msg::Fetch);
|
||||
orders.send_msg(Msg::Query(UserQueryMsg::Fetch));
|
||||
|
||||
model.users.sort_by(match column {
|
||||
UserOverviewColumns::Id => |o: &User, t: &User| o.id.cmp(&t.id),
|
||||
@ -104,34 +140,115 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
UserOverviewColumns::Email => |o: &User, t: &User| o.email.cmp(&t.email),
|
||||
})
|
||||
}
|
||||
Msg::Received(response) => {
|
||||
UserQueryMsg::Received(response) => {
|
||||
model.users = response;
|
||||
}
|
||||
Msg::IdFilterChanged(s) => {
|
||||
UserQueryMsg::IdFilterChanged(s) => {
|
||||
log!("Filter is: ", &s);
|
||||
let sanit = s.chars().filter(|x| x.is_numeric()).collect();
|
||||
model.formconfig.filter[UserOverviewColumns::Id].sieve = sanit;
|
||||
orders.send_msg(Msg::Fetch);
|
||||
orders.send_msg(Msg::Query(UserQueryMsg::Fetch));
|
||||
}
|
||||
Msg::UsernameFilterChanged(s) => {
|
||||
UserQueryMsg::UsernameFilterChanged(s) => {
|
||||
log!("Filter is: ", &s);
|
||||
let sanit = s.chars().filter(|x| x.is_alphanumeric()).collect();
|
||||
model.formconfig.filter[UserOverviewColumns::Username].sieve = sanit;
|
||||
orders.send_msg(Msg::Fetch);
|
||||
orders.send_msg(Msg::Query(UserQueryMsg::Fetch));
|
||||
}
|
||||
Msg::EmailFilterChanged(s) => {
|
||||
UserQueryMsg::EmailFilterChanged(s) => {
|
||||
log!("Filter is: ", &s);
|
||||
// FIXME: Sanitazion does not work for @
|
||||
let sanit = s.chars().filter(|x| x.is_alphanumeric()).collect();
|
||||
model.formconfig.filter[UserOverviewColumns::Email].sieve = sanit;
|
||||
orders.send_msg(Msg::Fetch);
|
||||
orders.send_msg(Msg::Query(UserQueryMsg::Fetch));
|
||||
}
|
||||
Msg::EditUserSelected(user) => {
|
||||
log!("Editing user: ", user);
|
||||
model.user_edit = Some(UserEditMode::Edit { user })
|
||||
|
||||
UserQueryMsg::FailedToFetchUsers => {
|
||||
log!("Failed to fetch users");
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn process_user_edit_messages(
|
||||
msg: UserEditMsg,
|
||||
model: &mut Model,
|
||||
orders: &mut impl Orders<Msg>,
|
||||
) {
|
||||
match msg {
|
||||
UserEditMsg::EditUserSelected(user) => {
|
||||
log!("Editing user: ", user);
|
||||
model.user_edit = Some(RefCell::new(user))
|
||||
}
|
||||
UserEditMsg::CreateNewUser => {
|
||||
log!("Creating new user");
|
||||
model.user_edit = Some(RefCell::new(UserDelta::default()))
|
||||
}
|
||||
UserEditMsg::EditUsernameChanged(s) => {
|
||||
log!("New Username is: ", &s);
|
||||
if let Some(ref ue) = model.user_edit {
|
||||
ue.try_borrow_mut()
|
||||
.expect("Failed to borrow mutably")
|
||||
.username = s;
|
||||
};
|
||||
}
|
||||
UserEditMsg::EditEmailChanged(s) => {
|
||||
log!("New Email is: ", &s);
|
||||
if let Some(ref ue) = model.user_edit {
|
||||
ue.try_borrow_mut().expect("Failed to borrow mutably").email = s;
|
||||
};
|
||||
}
|
||||
UserEditMsg::EditPasswordChanged(s) => {
|
||||
log!("New Password is: ", &s);
|
||||
if let Some(ref ue) = model.user_edit {
|
||||
ue.try_borrow_mut()
|
||||
.expect("Failed to borrow mutably")
|
||||
.password = Some(s);
|
||||
};
|
||||
}
|
||||
UserEditMsg::SaveUser => {
|
||||
let data = model
|
||||
.user_edit
|
||||
.as_ref()
|
||||
.expect("Somehow a user should exist!")
|
||||
.borrow()
|
||||
.clone(); // complicated way to move into the closure
|
||||
log!("Saving User: ", &data.username);
|
||||
|
||||
orders.perform_cmd(async {
|
||||
let data = data;
|
||||
let response = match fetch(
|
||||
Request::new("/admin/json/create_user/")
|
||||
.method(Method::Post)
|
||||
.json(&data)
|
||||
.expect("serialization failed"),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(response) => response,
|
||||
Err(_) => return Msg::Edit(UserEditMsg::FailedToCreateUser),
|
||||
};
|
||||
|
||||
let message: SuccessMessage = response
|
||||
.check_status() // ensure we've got 2xx status
|
||||
.expect("status check failed")
|
||||
.json()
|
||||
.await
|
||||
.expect("deserialization failed");
|
||||
|
||||
Msg::Edit(UserEditMsg::UserCreated(message))
|
||||
});
|
||||
}
|
||||
UserEditMsg::FailedToCreateUser => {
|
||||
log!("Failed to create user");
|
||||
}
|
||||
UserEditMsg::UserCreated(u) => {
|
||||
log!(u, "created user");
|
||||
model.last_message = Some(u);
|
||||
model.user_edit = None;
|
||||
orders.send_msg(Msg::Query(UserQueryMsg::Fetch));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
/// # Panics
|
||||
/// Sould only panic on bugs.
|
||||
@ -140,6 +257,11 @@ pub fn view(model: &Model) -> Node<Msg> {
|
||||
let t = move |key: &str| lang.translate(key, None);
|
||||
section![
|
||||
h1!("List Users Page from list_users"),
|
||||
if let Some(message) = &model.last_message {
|
||||
div![C!("Message"), &message.message]
|
||||
} else {
|
||||
section!()
|
||||
},
|
||||
table![
|
||||
// Column Headlines
|
||||
view_user_table_head(&t),
|
||||
@ -148,22 +270,36 @@ pub fn view(model: &Model) -> Node<Msg> {
|
||||
// Add all the users one line for each
|
||||
model.users.iter().map(view_user)
|
||||
],
|
||||
button![ev(Ev::Click, |_| Msg::Fetch), "Refresh"]
|
||||
button![
|
||||
ev(Ev::Click, |_| Msg::Query(UserQueryMsg::Fetch)),
|
||||
"Refresh"
|
||||
],
|
||||
if let Some(l) = &model.user_edit {
|
||||
edit_or_create_user(l, t)
|
||||
} else {
|
||||
section!()
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn view_user_table_head<F: Fn(&str) -> String>(t: F) -> Node<Msg> {
|
||||
tr![
|
||||
th![
|
||||
ev(Ev::Click, |_| Msg::OrderBy(UserOverviewColumns::Id)),
|
||||
ev(Ev::Click, |_| Msg::Query(UserQueryMsg::OrderBy(
|
||||
UserOverviewColumns::Id
|
||||
))),
|
||||
t("userid")
|
||||
],
|
||||
th![
|
||||
ev(Ev::Click, |_| Msg::OrderBy(UserOverviewColumns::Email)),
|
||||
ev(Ev::Click, |_| Msg::Query(UserQueryMsg::OrderBy(
|
||||
UserOverviewColumns::Email
|
||||
))),
|
||||
t("email")
|
||||
],
|
||||
th![
|
||||
ev(Ev::Click, |_| Msg::OrderBy(UserOverviewColumns::Username)),
|
||||
ev(Ev::Click, |_| Msg::Query(UserQueryMsg::OrderBy(
|
||||
UserOverviewColumns::Username
|
||||
))),
|
||||
t("username")
|
||||
],
|
||||
]
|
||||
@ -178,7 +314,9 @@ fn view_user_table_filter_input<F: Fn(&str) -> String>(model: &Model, t: F) -> N
|
||||
At::Type => "search",
|
||||
At::Placeholder => t("search-placeholder")
|
||||
},
|
||||
input_ev(Ev::Input, Msg::IdFilterChanged),
|
||||
input_ev(Ev::Input, |s| {
|
||||
Msg::Query(UserQueryMsg::IdFilterChanged(s))
|
||||
}),
|
||||
el_ref(&model.inputs[UserOverviewColumns::Id].filter_input),
|
||||
]],
|
||||
td![input![
|
||||
@ -188,7 +326,9 @@ fn view_user_table_filter_input<F: Fn(&str) -> String>(model: &Model, t: F) -> N
|
||||
At::Type => "search",
|
||||
At::Placeholder => t("search-placeholder")
|
||||
},
|
||||
input_ev(Ev::Input, Msg::EmailFilterChanged),
|
||||
input_ev(Ev::Input, |s| {
|
||||
Msg::Query(UserQueryMsg::EmailFilterChanged(s))
|
||||
}),
|
||||
el_ref(&model.inputs[UserOverviewColumns::Email].filter_input),
|
||||
]],
|
||||
td![input![
|
||||
@ -198,19 +338,100 @@ fn view_user_table_filter_input<F: Fn(&str) -> String>(model: &Model, t: F) -> N
|
||||
At::Type => "search",
|
||||
At::Placeholder => t("search-placeholder")
|
||||
},
|
||||
input_ev(Ev::Input, Msg::UsernameFilterChanged),
|
||||
input_ev(Ev::Input, |s| {
|
||||
Msg::Query(UserQueryMsg::UsernameFilterChanged(s))
|
||||
}),
|
||||
el_ref(&model.inputs[UserOverviewColumns::Username].filter_input),
|
||||
]],
|
||||
]
|
||||
}
|
||||
|
||||
fn view_user(l: &User) -> Node<Msg> {
|
||||
let user = l.clone();
|
||||
let user = UserDelta::from(l.clone());
|
||||
tr![
|
||||
ev(Ev::Click, |_| Msg::EditUserSelected(user)),
|
||||
ev(Ev::Click, |_| Msg::Edit(UserEditMsg::EditUserSelected(
|
||||
user
|
||||
))),
|
||||
td![&l.id],
|
||||
td![&l.email],
|
||||
//td![a![attrs![At::Href => &l.link.target], &l.link.target]],
|
||||
td![&l.username],
|
||||
]
|
||||
}
|
||||
|
||||
fn edit_or_create_user<F: Fn(&str) -> String>(l: &RefCell<UserDelta>, t: F) -> Node<Msg> {
|
||||
let user = l.borrow();
|
||||
div![
|
||||
C!["editdialog", "center"],
|
||||
h1![match &user.edit {
|
||||
EditMode::Edit => t("edit-user"),
|
||||
EditMode::Create => t("new-user"),
|
||||
}],
|
||||
table![
|
||||
tr![
|
||||
th![
|
||||
ev(Ev::Click, |_| Msg::Query(UserQueryMsg::OrderBy(
|
||||
UserOverviewColumns::Username
|
||||
))),
|
||||
t("username")
|
||||
],
|
||||
td![input![
|
||||
attrs! {
|
||||
At::Value => &user.username,
|
||||
At::Type => "text",
|
||||
At::Placeholder => t("username")
|
||||
},
|
||||
input_ev(Ev::Input, |s| {
|
||||
Msg::Edit(UserEditMsg::EditUsernameChanged(s))
|
||||
}),
|
||||
]]
|
||||
],
|
||||
tr![
|
||||
th![
|
||||
ev(Ev::Click, |_| Msg::Query(UserQueryMsg::OrderBy(
|
||||
UserOverviewColumns::Email
|
||||
))),
|
||||
t("email")
|
||||
],
|
||||
td![input![
|
||||
attrs! {
|
||||
At::Value => &user.email,
|
||||
At::Type => "email",
|
||||
At::Placeholder => t("email")
|
||||
},
|
||||
input_ev(Ev::Input, |s| {
|
||||
Msg::Edit(UserEditMsg::EditEmailChanged(s))
|
||||
}),
|
||||
]]
|
||||
],
|
||||
tr![
|
||||
th![
|
||||
ev(Ev::Click, |_| Msg::Query(UserQueryMsg::OrderBy(
|
||||
UserOverviewColumns::Email
|
||||
))),
|
||||
t("password")
|
||||
],
|
||||
td![
|
||||
input![
|
||||
attrs! {
|
||||
At::Type => "password",
|
||||
At::Placeholder => t("password")
|
||||
},
|
||||
input_ev(Ev::Input, |s| {
|
||||
Msg::Edit(UserEditMsg::EditPasswordChanged(s))
|
||||
}),
|
||||
],
|
||||
IF!(user.edit == EditMode::Edit => p![t("leave-password-empty-hint")])
|
||||
]
|
||||
]
|
||||
],
|
||||
a![
|
||||
match &user.edit {
|
||||
EditMode::Edit => t("edit-user"),
|
||||
EditMode::Create => t("create-user"),
|
||||
},
|
||||
C!["button"],
|
||||
ev(Ev::Click, |_| Msg::Edit(UserEditMsg::SaveUser))
|
||||
]
|
||||
]
|
||||
}
|
||||
|
@ -71,8 +71,3 @@ tokio = "0.2.25"
|
||||
[dev-dependencies.reqwest]
|
||||
features = ["cookies"]
|
||||
version = "0.10.10"
|
||||
|
||||
[profile]
|
||||
[profile.release]
|
||||
lto = true
|
||||
#codegen-units = 1
|
@ -370,7 +370,11 @@ pub async fn webservice(
|
||||
.service(
|
||||
web::scope("/json")
|
||||
.route("/list_links/", web::post().to(views::index_json))
|
||||
.route("/list_users/", web::post().to(views::index_users_json)),
|
||||
.route("/list_users/", web::post().to(views::index_users_json))
|
||||
.route(
|
||||
"/create_user/",
|
||||
web::post().to(views::process_create_user_json),
|
||||
),
|
||||
)
|
||||
// login to the admin area
|
||||
.route("/login/", web::get().to(views::login))
|
||||
|
@ -23,7 +23,7 @@ pub trait UserDbOperations<T> {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl UserDbOperations<User> for User {
|
||||
impl UserDbOperations<Self> for User {
|
||||
async fn get_user(id: i64, server_config: &ServerConfig) -> Result<Self, ServerError> {
|
||||
let user = sqlx::query_as!(Self, "Select * from users where id = ? ", id)
|
||||
.fetch_one(&server_config.db_pool)
|
||||
@ -186,7 +186,7 @@ pub trait LinkDbOperations<T> {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl LinkDbOperations<Link> for Link {
|
||||
impl LinkDbOperations<Self> for Link {
|
||||
async fn get_link_by_code(
|
||||
code: &str,
|
||||
server_config: &ServerConfig,
|
||||
|
@ -6,7 +6,7 @@ use shared::{
|
||||
apirequests::{
|
||||
general::{Filter, Operation, Ordering},
|
||||
links::{LinkOverviewColumns, LinkRequestForm},
|
||||
users::{UserOverviewColumns, UserRequestForm},
|
||||
users::{UserDelta, UserOverviewColumns, UserRequestForm},
|
||||
},
|
||||
datatypes::{Count, FullLink, Link, User},
|
||||
};
|
||||
@ -389,6 +389,51 @@ pub async fn create_user(
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Create a new user and save it to the database
|
||||
///
|
||||
/// # Errors
|
||||
/// Fails with [`ServerError`] if access to the database fails, this user does not have permissions or the user already exists.
|
||||
#[instrument(skip(id))]
|
||||
pub async fn create_user_json(
|
||||
id: &Identity,
|
||||
data: &web::Json<UserDelta>,
|
||||
server_config: &ServerConfig,
|
||||
) -> Result<Item<User>, ServerError> {
|
||||
info!("Creating a User: {:?}", &data);
|
||||
let auth = authenticate(id, server_config).await?;
|
||||
|
||||
// Require a password on user creation!
|
||||
let password = match &data.password {
|
||||
Some(pass) => pass,
|
||||
None => {
|
||||
return Err(ServerError::User(
|
||||
"A new users does require a password".to_string(),
|
||||
))
|
||||
}
|
||||
};
|
||||
match auth {
|
||||
Role::Admin { user } => {
|
||||
let new_user = NewUser::new(
|
||||
data.username.clone(),
|
||||
data.email.clone(),
|
||||
password,
|
||||
&server_config.secret,
|
||||
)?;
|
||||
|
||||
new_user.insert_user(server_config).await?;
|
||||
|
||||
// querry the new user
|
||||
let new_user = get_user_by_name(&data.username, server_config).await?;
|
||||
Ok(Item {
|
||||
user,
|
||||
item: new_user,
|
||||
})
|
||||
}
|
||||
Role::Regular { .. } | Role::Disabled | Role::NotAuthenticated => {
|
||||
Err(ServerError::User("Permission denied!".to_owned()))
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Take a [`actix_web::web::Form<NewUser>`] and update the corresponding entry in the database.
|
||||
/// The password is only updated if a new password of at least 4 characters is provided.
|
||||
/// The `user_id` is never changed.
|
||||
|
@ -14,7 +14,11 @@ use fluent_templates::LanguageIdentifier;
|
||||
use image::{DynamicImage, ImageOutputFormat, Luma};
|
||||
use qrcode::{render::svg, QrCode};
|
||||
use queries::{authenticate, Role};
|
||||
use shared::apirequests::{links::LinkRequestForm, users::UserRequestForm};
|
||||
use shared::apirequests::{
|
||||
general::SuccessMessage,
|
||||
links::LinkRequestForm,
|
||||
users::{UserDelta, UserRequestForm},
|
||||
};
|
||||
use tera::{Context, Tera};
|
||||
use tracing::{error, info, instrument, warn};
|
||||
|
||||
@ -346,6 +350,21 @@ pub async fn process_signup(
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(id))]
|
||||
pub async fn process_create_user_json(
|
||||
config: web::Data<crate::ServerConfig>,
|
||||
form: web::Json<UserDelta>,
|
||||
id: Identity,
|
||||
) -> Result<HttpResponse, ServerError> {
|
||||
info!("Listing Users to Json api");
|
||||
match queries::create_user_json(&id, &form, &config).await {
|
||||
Ok(item) => Ok(HttpResponse::Ok().json2(&SuccessMessage {
|
||||
message: format!("Successfully saved user: {}", item.item.username),
|
||||
})),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(id))]
|
||||
pub async fn toggle_admin(
|
||||
data: web::Path<String>,
|
||||
|
@ -1,163 +1,173 @@
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
form {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.center {
|
||||
position: absolute;
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-left: -200px;
|
||||
margin-top: -200px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 30px;
|
||||
color: #333;
|
||||
position: absolute;
|
||||
width: 600px;
|
||||
max-width: 100%;
|
||||
height: 400px;
|
||||
max-height: 100%;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-left: -300px;
|
||||
margin-top: -200px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 30px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.center input {
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
margin: 5px;
|
||||
border-radius: 1px;
|
||||
border: 1px solid rgb(90, 90, 90);
|
||||
font-family: inherit;
|
||||
background-color: #eae9ea;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border-radius: 1px;
|
||||
border: 1px solid rgb(90, 90, 90);
|
||||
font-family: inherit;
|
||||
background-color: #eae9ea;
|
||||
}
|
||||
|
||||
.center {
|
||||
width: 800px;
|
||||
height: 600px;
|
||||
margin-left: -400px;
|
||||
margin-top: -300px;
|
||||
|
||||
.center table p {
|
||||
font-size: x-small;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
th, td {
|
||||
text-align: center;
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
th,
|
||||
td {
|
||||
text-align: center;
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
table tr:nth-child(even) {
|
||||
background-color: #eee;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
table tr:nth-child(odd) {
|
||||
background-color: #fff;
|
||||
}
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
table tr.filters input {
|
||||
background-image: url("/static/search.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
background-image: url("/static/search.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
table tr.filters td {
|
||||
padding:5px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
nav {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: space-between;
|
||||
align-items:stretch;
|
||||
width:100%;
|
||||
height: 60px;
|
||||
}
|
||||
nav ol {
|
||||
display:flex;
|
||||
align-items: center;
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: space-between;
|
||||
align-items: stretch;
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
nav li a, nav li div.willkommen {
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 14px 16px;
|
||||
text-decoration: none;
|
||||
border-radius: 0 0 10px 10px;
|
||||
nav ol {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
nav li a,
|
||||
nav li div.willkommen {
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 14px 16px;
|
||||
text-decoration: none;
|
||||
border-radius: 0 0 10px 10px;
|
||||
}
|
||||
|
||||
nav li a {
|
||||
background: rgb(2,0,36);
|
||||
background: linear-gradient(180deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 35%, rgb(0, 145, 174) 100%);
|
||||
background: rgb(2, 0, 36);
|
||||
background: linear-gradient(180deg, rgba(2, 0, 36, 1) 0%, rgba(9, 9, 121, 1) 35%, rgb(0, 145, 174) 100%);
|
||||
}
|
||||
|
||||
nav li {
|
||||
float: left;
|
||||
float: left;
|
||||
}
|
||||
|
||||
nav li a:hover {
|
||||
background: rgb(2,0,36);
|
||||
background: linear-gradient(180deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 35%, rgb(60, 170, 255) 100%);
|
||||
background: rgb(2, 0, 36);
|
||||
background: linear-gradient(180deg, rgba(2, 0, 36, 1) 0%, rgba(9, 9, 121, 1) 35%, rgb(60, 170, 255) 100%);
|
||||
}
|
||||
|
||||
nav li {
|
||||
margin: 5px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
nav li div{
|
||||
background-color: burlywood;
|
||||
text-align: center;
|
||||
padding: 14px 16px;
|
||||
border-radius: 0 0 10px 10px;
|
||||
nav li div {
|
||||
background-color: burlywood;
|
||||
text-align: center;
|
||||
padding: 14px 16px;
|
||||
border-radius: 0 0 10px 10px;
|
||||
}
|
||||
|
||||
|
||||
svg {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
div.actions {
|
||||
margin-left:5px;
|
||||
display: flex;
|
||||
width:100%;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
color: #333;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
margin-left: 5px;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
color: #333;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
div.danger {
|
||||
background-color: rgb(235, 127, 77);
|
||||
font-size: smaller;
|
||||
border: 2px solid crimson;
|
||||
background-color: rgb(235, 127, 77);
|
||||
font-size: smaller;
|
||||
border: 2px solid crimson;
|
||||
}
|
||||
|
||||
div.danger h3 {
|
||||
width:100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
a.button, div.actions input {
|
||||
width: 250px;
|
||||
display:block;
|
||||
padding: 15px;
|
||||
margin-left: 15px;
|
||||
text-align: center;
|
||||
border-radius: 1px;
|
||||
border: 1px solid rgb(90, 90, 90);
|
||||
font-family: inherit;
|
||||
background-color: #eae9ea;
|
||||
a.button,
|
||||
div.actions input {
|
||||
width: 250px;
|
||||
display: block;
|
||||
padding: 15px;
|
||||
margin-left: 15px;
|
||||
text-align: center;
|
||||
border-radius: 1px;
|
||||
border: 1px solid rgb(90, 90, 90);
|
||||
font-family: inherit;
|
||||
background-color: #eae9ea;
|
||||
}
|
||||
|
||||
div.editdialog {
|
||||
background-color: aliceblue;
|
||||
border: 5px solid rgb(90, 90, 90);
|
||||
}
|
@ -25,3 +25,20 @@ pub struct Operation<T, V> {
|
||||
pub column: T,
|
||||
pub value: V,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq)]
|
||||
pub enum EditMode {
|
||||
Create,
|
||||
Edit,
|
||||
}
|
||||
|
||||
impl Default for EditMode {
|
||||
fn default() -> Self {
|
||||
Self::Create
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, Serialize, Debug)]
|
||||
pub struct SuccessMessage {
|
||||
pub message: String,
|
||||
}
|
||||
|
@ -1,12 +1,17 @@
|
||||
use enum_map::{Enum, EnumMap};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::general::{Filter, Operation, Ordering};
|
||||
use crate::datatypes::User;
|
||||
|
||||
use super::general::{EditMode, Filter, Operation, Ordering};
|
||||
|
||||
#[derive(Clone, Deserialize, Serialize, Debug)]
|
||||
pub struct UserRequestForm {
|
||||
// The filters up to one for each column
|
||||
pub filter: EnumMap<UserOverviewColumns, Filter>,
|
||||
// Order According to this column
|
||||
pub order: Option<Operation<UserOverviewColumns, Ordering>>,
|
||||
// Return a maximum of `amount` results
|
||||
pub amount: usize,
|
||||
}
|
||||
|
||||
@ -20,6 +25,31 @@ impl Default for UserRequestForm {
|
||||
}
|
||||
}
|
||||
|
||||
/// The Struct that is responsible for creating and editing users.
|
||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct UserDelta {
|
||||
pub edit: EditMode,
|
||||
pub id: Option<i64>,
|
||||
pub username: String,
|
||||
pub email: String,
|
||||
pub password: Option<String>,
|
||||
}
|
||||
|
||||
impl From<User> for UserDelta {
|
||||
/// Automatically create a `UserDelta` from a User.
|
||||
fn from(u: User) -> Self {
|
||||
Self {
|
||||
edit: EditMode::Edit,
|
||||
id: Some(u.id),
|
||||
username: u.username,
|
||||
email: u.email,
|
||||
password: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The columns in the user view table. The table can be ordered according to these.
|
||||
#[allow(clippy::use_self)]
|
||||
#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq, Hash, Enum)]
|
||||
pub enum UserOverviewColumns {
|
||||
Id,
|
||||
|
Loading…
Reference in New Issue
Block a user