Merge branch 'ui-redesign' into 'main'

Field Validation

See merge request vade/vade-mecum!4
This commit is contained in:
Joe Bellus 2022-02-13 03:11:22 +00:00
commit b1c8342253
10 changed files with 89 additions and 44 deletions

View File

@ -1,6 +1,6 @@
FROM alpine:latest
COPY target/x86_64-unknown-linux-musl/release/vade /app/vade
EXPOSE 8088
EXPOSE 8089
WORKDIR app
RUN touch data.db
CMD ["./vade"]
RUN mkdir data
CMD ["./vade", "--db data/"]

BIN
public/bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -15,7 +15,7 @@ axios.interceptors.request.use(function (config) {
axios.defaults.baseURL = process.env.NODE_ENV === 'development'
? 'http://localhost:8088'
? 'http://localhost:8089'
: '';
axios.interceptors.response.use(function (response) {

View File

@ -76,15 +76,24 @@ async fn main() {
let st = state.clone();
actix_rt::spawn(async move {
loop {
tokio::time::sleep(tokio::time::Duration::from_secs(60)).await;
let apps: Vec<entity::application::Model> = entity::application::Entity::find()
.filter(entity::application::Column::EnableHealthcheck.eq(true))
.all(&st.db)
.await
.unwrap();
let client = reqwest::Client::builder()
.danger_accept_invalid_certs(true)
.build()
.unwrap();
for app in apps {
match reqwest::get(app.url).await {
match client
.request(reqwest::Method::GET, app.url)
.timeout(std::time::Duration::from_secs(5))
.send()
.await
{
Ok(res) if res.status() == 200 => {
st.healthcheck_status.lock().await.insert(app.id, true);
let _ = events::EventBroker::from_registry()
@ -94,7 +103,18 @@ async fn main() {
})
.await;
}
_ => {
Err(e) => {
tracing::warn!("Error performing healthcheck: {}", e);
st.healthcheck_status.lock().await.insert(app.id, false);
let _ = events::EventBroker::from_registry()
.send(events::Event::HealthcheckChange {
app_id: app.id,
alive: false,
})
.await;
}
Ok(res) => {
tracing::warn!("Non 200 status code: {}", res.status());
st.healthcheck_status.lock().await.insert(app.id, false);
let _ = events::EventBroker::from_registry()
.send(events::Event::HealthcheckChange {
@ -105,6 +125,7 @@ async fn main() {
}
}
}
tokio::time::sleep(tokio::time::Duration::from_secs(60)).await;
}
});
@ -113,9 +134,9 @@ async fn main() {
HttpServer::new(move || {
let cors = actix_cors::Cors::permissive();
App::new()
.wrap(cors)
.app_data(state.clone())
.wrap(tracing_actix_web::TracingLogger::default())
.wrap(cors)
.service(web::resource("/events/{token}").to(socket_session::event_session_index))
.service(api::routes())
.service(dist)

View File

@ -83,6 +83,7 @@ export default {
} else {
let resp = await axios.post("/api/applications", {
active: true,
enableHealthcheck: !!this.app.enableHealthcheck,
...this.app,
});
if (resp.status == 200) {

View File

@ -33,7 +33,7 @@ export default {
}
.tile:hover {
transition: all 0.1s;
background-color: #333;
background-color: rgba(50,50,50, 0.5);
box-shadow: rgba(0, 0, 0, 0.5) 0px 20px 30px -10px;
}
.label {

View File

@ -19,6 +19,8 @@ export default {
<style>
.bookmark-tile {
padding: 5px 25px;
border-radius: 5px;
transition: all 0.2s;
}
.bookmark-tile, .bookmark-tile svg {
@ -28,6 +30,8 @@ export default {
}
.bookmark-tile:hover, .bookmark-tile:hover svg {
transition: all 0.2s;
background: rgba(0,0,0,0.25);
color: #fff;
}

View File

@ -62,6 +62,7 @@ export default {
left: 50%;
transform: translate(-50%, 0%);
display: none;
z-index: 100;
}
.modal.open {

View File

@ -15,6 +15,6 @@ export default {
<style scoped>
.tile.new {
background: #444;
background: rgba(0,0,0,0.8);
}
</style>

View File

@ -16,6 +16,50 @@
:appData="app"
:key="app.id"
/>
</div>
</div>
<div class="container" v-for="cat in applicationCategories" :key="cat.id">
<h1 @click="appCatClicked(cat)" class="editable">
<font-awesome-icon v-if="cat.glyph" :icon="cat.glyph" />
{{cat.categoryName}}
</h1>
<div class="app-tiles">
<application-tile
@clicked="appTileClicked"
v-for="app in appsForCategory(cat.id)"
:appData="app"
:key="app.id"
/>
</div>
</div>
<div class="container" v-if="bookmarks.length">
<h1 class="bookmark">BOOKMARKS</h1>
<div class="bookmark-container">
<div class="bookmark-category" v-if="bookmarksForCategory(null).length">
<h2>UNCATEGORZED</h2>
<bookmark-tile
v-for="bm in bookmarksForCategory(null)"
:key="bm.id"
:bookmark="bm"
@clicked="bookmarkClicked"
/>
</div>
<div class="bookmark-category" v-for="cat in bookmarkCategories" :key="cat.id">
<h2 @click="bookmarkCatClicked(cat)" class="editable">
<font-awesome-icon v-if="cat.glyph" :icon="cat.glyph" />
{{cat.categoryName}}
</h2>
<bookmark-tile
@clicked="bookmarkClicked"
v-for="bm in bookmarksForCategory(cat.id)"
:key="bm.id"
:bookmark="bm"
/>
</div>
</div>
</div>
<edit-mode-button :editMode="editMode" @click="toggleEdit" />
<application-modal
:open="appOpen"
:data="editApp"
@ -43,51 +87,6 @@
@update="reload"
/>
</div>
</div>
<div class="container" v-for="cat in applicationCategories" :key="cat.id">
<h1 @click="appCatClicked(cat)" class="editable">
<font-awesome-icon v-if="cat.glyph" :icon="cat.glyph" />
{{cat.categoryName}}
</h1>
<div class="app-tiles">
<application-tile
@clicked="appTileClicked"
v-for="app in appsForCategory(cat.id)"
:appData="app"
:key="app.id"
/>
</div>
</div>
<div class="container" v-if="bookmarks.length">
<h1 class="bookmark">BOOKMARKS</h1>
<div class="bookmark-container">
<div class="bookmark-category">
<h2>UNCATEGORZED</h2>
<bookmark-tile
v-for="bm in bookmarksForCategory(null)"
:key="bm.id"
:bookmark="bm"
@clicked="bookmarkClicked"
/>
</div>
<div class="bookmark-category" v-for="cat in bookmarkCategories" :key="cat.id">
<h2 @click="bookmarkCatClicked(cat)" class="editable">
<font-awesome-icon v-if="cat.glyph" :icon="cat.glyph" />
{{cat.categoryName}}
</h2>
<bookmark-tile
@clicked="bookmarkClicked"
v-for="bm in bookmarksForCategory(cat.id)"
:key="bm.id"
:bookmark="bm"
/>
</div>
</div>
</div>
<edit-mode-button :editMode="editMode" @click="toggleEdit" />
</div>
</template>
<script>
@ -252,16 +251,22 @@ h1 {
font-weight: bold;
line-height: 1;
margin-bottom: 5px;
padding-left: 25px;
font-size: 24px;
font-size: 18px;
padding-bottom: 10px;
color: rgba(255,255,255,0.25);
text-shadow: 1px 1px rgba(0,0,0,0.25);
text-transform: uppercase;
text-align: right;
}
h2 {
color: #fff;
font-size: 18px;
text-transform: uppercase;
padding-left: 25px;
font-weight: bold;
margin-bottom: 5px;
color: rgba(255,255,255,0.25);
text-shadow: 1px 1px rgba(0,0,0,0.25);
}
.edit-mode .editable {
cursor: pointer;
@ -275,12 +280,25 @@ h2 svg {
grid-template-columns: repeat(4, 25%);
}
.container {
padding: 10px 50px;
padding: 25px;
width: 1000px;
margin: auto auto;
margin: 20px auto;
-webkit-backdrop-filter: blur(6px);
backdrop-filter: blur(6px);
background-color: rgba(0,0,0,0.4);
border-radius: 15px;
}
.container svg {
color: rgba(255,255,255,0.25);
}
.dashboard {
margin-top: 150px;
user-select: none;
min-height: calc(100vh - 150px);
min-width: 100vw;
padding-top: 150px;
background: url('/bg.jpg');
background-position: center center;
background-size: cover;
}
.editmode-tiles {
display: flex;