-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
12228fc
commit a6454fb
Showing
8 changed files
with
351 additions
and
275 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[toolchain] | ||
channel = "nightly" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
//! This file contains all logic related to parsing the YAML files | ||
//! and querying the resulting data structures. | ||
use std::collections::HashMap; | ||
use serde::Deserialize; | ||
|
||
#[derive(Debug, Deserialize, Clone)] | ||
pub struct QueryEngine { | ||
pub id: String, | ||
pub short_name: String, | ||
pub description: String, | ||
pub url: String, | ||
pub logo: String | ||
} | ||
|
||
#[derive(Debug, Deserialize, Clone)] | ||
pub struct Integration { | ||
pub id: String, | ||
pub short_name: String, | ||
pub description: String, | ||
pub logo: String | ||
} | ||
|
||
#[derive(Debug, Deserialize, Clone)] | ||
pub struct Feature { | ||
pub supported: bool, | ||
pub evidence: String, | ||
pub caveats: Option<String> | ||
} | ||
|
||
#[derive(Debug, Deserialize, Clone)] | ||
pub struct IntegrationSupport { | ||
pub import: Feature, | ||
pub export: Feature, | ||
} | ||
|
||
#[derive(Debug, Clone)] | ||
pub struct Data { | ||
pub engines: Vec<QueryEngine>, | ||
pub integrations: Vec<Integration>, | ||
pub support_matrix: HashMap<String, HashMap<String, IntegrationSupport>> | ||
} | ||
|
||
impl Data { | ||
pub fn get_support(&self, engine: &str, integration: &str) -> Option<&IntegrationSupport> { | ||
self.support_matrix.get(engine)?.get(integration) | ||
} | ||
} | ||
|
||
const ENGINES_YAML: &str = include_str!("../query_engines.yaml"); | ||
const INTEGRATIONS_YAML: &str = include_str!("../integrations.yaml"); | ||
const SUPPORT_MATRIX_YAML: &str = include_str!("../support_matrix.yaml"); | ||
|
||
/** | ||
* Get the data parsed from the YAML files included statically in the binary. | ||
* Panics if the YAML files are not parsable. | ||
*/ | ||
pub fn parse_data_from_static_yamls() -> &'static Data { | ||
static STATIC_DATA: std::sync::OnceLock<Data> = std::sync::OnceLock::new(); | ||
STATIC_DATA.get_or_init(|| { | ||
let engines: Vec<QueryEngine> = serde_yaml::from_str(ENGINES_YAML).expect("Unable to parse YAML"); | ||
let integrations: Vec<Integration> = serde_yaml::from_str(INTEGRATIONS_YAML).expect("Unable to parse YAML"); | ||
let support_matrix: HashMap<String, HashMap<String, IntegrationSupport>> = serde_yaml::from_str(SUPPORT_MATRIX_YAML).expect("Unable to parse YAML"); | ||
Data { engines, integrations, support_matrix } | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,283 +1,14 @@ | ||
mod markdown; | ||
#![allow(dead_code)] | ||
|
||
use std::{collections::HashMap, panic}; | ||
mod data; | ||
mod ui; | ||
|
||
use leptos::*; | ||
use markdown::Markdown; | ||
use serde::Deserialize; | ||
|
||
#[derive(Debug, Deserialize, Clone)] | ||
struct QueryEngine { | ||
id: String, | ||
short_name: String, | ||
description: String, | ||
url: String, | ||
logo: String | ||
} | ||
|
||
#[derive(Debug, Deserialize, Clone)] | ||
struct Integration { | ||
id: String, | ||
short_name: String, | ||
description: String, | ||
logo: String | ||
} | ||
|
||
#[derive(Debug, Deserialize, Clone)] | ||
struct Feature { | ||
supported: bool, | ||
evidence: String, | ||
caveats: Option<String> | ||
} | ||
|
||
#[derive(Debug, Deserialize, Clone)] | ||
struct IntegrationSupport { | ||
import: Feature, | ||
export: Feature, | ||
} | ||
|
||
#[derive(Debug, Clone)] | ||
struct ClickedCell { | ||
query_engine: QueryEngine, | ||
integration: Integration, | ||
mouse_x: i32, | ||
mouse_y: i32 | ||
} | ||
|
||
const ENGINES: &str = include_str!("../query_engines.yaml"); | ||
const INTEGRATIONS: &str = include_str!("../integrations.yaml"); | ||
const SUPPORT_MATRIX: &str = include_str!("../support_matrix.yaml"); | ||
use std::panic; | ||
|
||
fn main() { | ||
panic::set_hook(Box::new(console_error_panic_hook::hook)); | ||
let query_engines: Vec<QueryEngine> = | ||
serde_yaml::from_str(ENGINES).expect("Unable to parse YAML"); | ||
|
||
let integrations: Vec<Integration> = | ||
serde_yaml::from_str(INTEGRATIONS).expect("Unable to parse YAML"); | ||
|
||
let support_matrix: HashMap<String, HashMap<String, IntegrationSupport>> = | ||
serde_yaml::from_str(SUPPORT_MATRIX).expect("Failed to parse YAML"); | ||
|
||
let ( | ||
clicked_on_cell, | ||
set_clicked_on_cell | ||
) = leptos::create_signal(None); | ||
|
||
let (support_matrix, _) = leptos::create_signal(support_matrix); | ||
|
||
let (filtered_integrations, _set_filtered_integrations) = leptos::create_signal(integrations.clone()); | ||
let (filtered_query_engines, _set_filtered_query_engines) = leptos::create_signal(query_engines.clone()); | ||
let data = data::parse_data_from_static_yamls(); | ||
|
||
mount_to_body(move || { | ||
view! { | ||
<div class="content"> | ||
<h1>"Engine Query"</h1> | ||
<p> | ||
Answer all your queries about query engines. | ||
</p> | ||
<table class="styled-table"> | ||
<thead> | ||
<tr> | ||
<th></th> | ||
<For | ||
each=filtered_integrations | ||
key=|i| i.id.clone() | ||
let:integration | ||
> | ||
<th> | ||
<div class="logo-in-th-container"><img class="logo-in-th" src={format!("static/images/{}", integration.logo)} /></div> | ||
<div class="th-rotated-text"> | ||
<span> | ||
{&integration.short_name} | ||
</span> | ||
</div> | ||
</th> | ||
</For> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<For | ||
each=filtered_query_engines | ||
key=|qe| qe.id.clone() | ||
let:qe | ||
> | ||
<tr> | ||
<td> | ||
<img class="logo-small" src={format!("static/images/{}", qe.logo)} /> | ||
<span class="logo-text">{&qe.short_name}</span> | ||
</td> | ||
<For | ||
each=filtered_integrations | ||
key=|i| i.id.clone() | ||
let:integration | ||
> | ||
<td | ||
class="support-matrix-cell-td" | ||
on:click={ | ||
// TODO: not sure if all these clone()s are necessary | ||
let qe = qe.clone(); | ||
let integration = integration.clone(); | ||
move |mouse_event| { | ||
set_clicked_on_cell( | ||
Some(ClickedCell { | ||
query_engine: qe.clone(), | ||
integration: integration.clone(), | ||
mouse_x: mouse_event.client_x(), | ||
mouse_y: mouse_event.client_y() | ||
}) | ||
) | ||
} | ||
} | ||
> | ||
{ | ||
let support = support_matrix.get().get(&qe.id).and_then(|qe_support_map| qe_support_map.get(&integration.id)).cloned(); | ||
let support_text = if let Some(support) = support { | ||
let support_text = match (support.import.supported, support.export.supported) { | ||
(true, true) => "✅", | ||
(true, false) => "🔎", | ||
(false, true) => "✍️", | ||
(false, false) => "❌", | ||
}; | ||
let has_caveats = support.import.caveats.is_some() || support.export.caveats.is_some(); | ||
let caveats_text = if has_caveats { | ||
"*" | ||
} else { | ||
"" | ||
}; | ||
format!("{}{}", support_text, caveats_text) | ||
} else { | ||
"❓".to_string() | ||
}; | ||
view! { | ||
<div class="support-matrix-cell">{ support_text }</div> | ||
} | ||
} | ||
</td> | ||
</For> | ||
</tr> | ||
</For> | ||
</tbody> | ||
</table> | ||
<p> | ||
<b>Legend:</b> | ||
<ul> | ||
<li>"✅ = Can read & write"</li> | ||
<li>"🔎 = Can read but not write"</li> | ||
<li>"✍️ = Can write but not read"</li> | ||
<li>"❌ = Not supported"</li> | ||
<li>"❓ = Unknown ("<a href="https://github.com/datamindedbe/playground-engine-query/edit/main/support_matrix.yaml">"please contribute!"</a>")"</li> | ||
</ul> | ||
</p> | ||
{ | ||
move || { | ||
if let Some(c) = clicked_on_cell.get() { | ||
let support = support_matrix.get().get(&c.query_engine.id).and_then(|qe_support_map| qe_support_map.get(&c.integration.id)).cloned(); | ||
view! { | ||
<div class="support-details-popup" style={move || format!("--clicked-at-x: {}px; --clicked-at-y: {}px;", c.mouse_x, c.mouse_y)}> | ||
<img | ||
class="popup-close-button" | ||
src="static/images/cross-mark.png" | ||
on:click={ | ||
move |_mouse_event| { | ||
set_clicked_on_cell(None) | ||
} | ||
} | ||
/> | ||
<p class="popup-subtitle">"Can " | ||
<img class="logo-small" src={format!("static/images/{}", c.query_engine.logo)} /> | ||
<span class="logo-text">{&c.query_engine.short_name}</span> | ||
" " | ||
<span class="popup-subtitle-emphasis">"read"</span> | ||
" from " | ||
<img class="logo-small" src={format!("static/images/{}", c.integration.logo)} /> | ||
<span class="logo-text">{&c.integration.short_name}</span> | ||
" ?" | ||
</p> | ||
<p> | ||
{ | ||
if let Some(support) = &support { | ||
let evidence_str = if let Some(caveats) = &support.import.caveats { | ||
format!("{}\n\n⚠️ {}", support.import.evidence, caveats) | ||
} else { | ||
support.import.evidence.clone() | ||
}; | ||
if support.import.supported { | ||
view! { | ||
<div> | ||
<p><span class="popup-yesno">"Yes."</span></p> | ||
<p><Markdown src={evidence_str} /></p> | ||
</div> | ||
} | ||
} else { | ||
view! { | ||
<div> | ||
<p><span class="popup-yesno">"No."</span></p> | ||
<p><Markdown src={evidence_str} /></p> | ||
</div> | ||
} | ||
} | ||
} else { | ||
view! { | ||
<div> | ||
<p>"Unknown ("<a href="https://github.com/datamindedbe/playground-engine-query/edit/main/support_matrix.yaml">"please contribute!"</a>")"</p> | ||
</div> | ||
} | ||
} | ||
} | ||
</p> | ||
<p class="popup-subtitle">"Can " | ||
<img class="logo-small" src={format!("static/images/{}", c.query_engine.logo)} /> | ||
<span class="logo-text">{&c.query_engine.short_name}</span> | ||
" " | ||
<span class="popup-subtitle-emphasis">"write"</span> | ||
" to " | ||
<img class="logo-small" src={format!("static/images/{}", c.integration.logo)} /> | ||
<span class="logo-text">{&c.integration.short_name}</span> | ||
" ?" | ||
</p> | ||
<p> | ||
{ | ||
if let Some(support) = &support { | ||
let evidence_str = if let Some(caveats) = &support.export.caveats { | ||
format!("{}\n\n⚠️ {}", support.export.evidence, caveats) | ||
} else { | ||
support.export.evidence.clone() | ||
}; | ||
if support.export.supported { | ||
view! { | ||
<div> | ||
<p><span class="popup-yesno">"Yes."</span></p> | ||
<p><Markdown src={evidence_str} /></p> | ||
</div> | ||
} | ||
} else { | ||
view! { | ||
<div> | ||
<p><span class="popup-yesno">"No."</span></p> | ||
<p><Markdown src={evidence_str} /></p> | ||
</div> | ||
} | ||
} | ||
} else { | ||
view! { | ||
<div> | ||
<p>"Unknown ("<a href="https://github.com/datamindedbe/playground-engine-query/edit/main/support_matrix.yaml">"please contribute!"</a>")"</p> | ||
</div> | ||
} | ||
} | ||
} | ||
</p> | ||
</div> | ||
} | ||
} else { | ||
view! { | ||
<div style="display: hidden;" /> | ||
} | ||
} | ||
} | ||
} | ||
</div> | ||
} | ||
}) | ||
ui::mount_ui_to_body(&data); | ||
} |
Oops, something went wrong.