.
This commit is contained in:
+48
-103
@@ -22,7 +22,7 @@ use ldp::reqwest_middleware::{ClientBuilder, ClientWithMiddleware};
|
||||
use ldp::{RdfSource, RdfSourceUpdateResponse, ResourceRequestBuilder, SerializationOptions};
|
||||
use oxigraph::io::RdfFormat;
|
||||
use oxigraph::model::{BaseDirection, Graph, NamedNode, NamedOrBlankNode, NamedOrBlankNodeRef, Quad, Term, TermRef, Triple, TripleRef};
|
||||
use tracing::{error, trace};
|
||||
use tracing::{debug, error, trace};
|
||||
use gl_graph::class::Class;
|
||||
use gl_graph::ontology::{ConnectedOntology, OntologyBuilder, ReadOnlyEntity, ResourceDescription};
|
||||
use gl_search::tantivy::schema::Value;
|
||||
@@ -74,10 +74,9 @@ pub(crate) enum Message {
|
||||
NavigateBack,
|
||||
NavigateForward,
|
||||
ResetState,
|
||||
SetShowReadOnly(bool),
|
||||
SetShowInferredTriples(bool),
|
||||
RunInference,
|
||||
SetInferredTriples(Graph),
|
||||
ShowInferencesWindow,
|
||||
Event(Event),
|
||||
}
|
||||
|
||||
@@ -110,13 +109,12 @@ pub(crate) struct Publisher {
|
||||
abbreviated_datatypes: Vec<String>,
|
||||
resource_descriptions: HashMap<NamedNode, ResourceDescription>,
|
||||
window_id: window::Id,
|
||||
inference_window_id: Option<window::Id>,
|
||||
url_input: String,
|
||||
url_input_valid: bool,
|
||||
navigator: Navigator<Url>,
|
||||
document: RdfSource<KeyedDataset<RowState>>,
|
||||
inferred_triples: Graph,
|
||||
show_read_only: bool,
|
||||
show_inferred_triples: bool,
|
||||
hovered_row: Option<QuadKey>,
|
||||
search_state: Option<SearchState>,
|
||||
index: SearchIndex,
|
||||
@@ -168,13 +166,12 @@ impl Publisher {
|
||||
abbreviated_datatypes: Vec::new(),
|
||||
resource_descriptions: HashMap::new(),
|
||||
window_id: id,
|
||||
inference_window_id: None,
|
||||
url_input: starting_url.to_string(),
|
||||
url_input_valid: true,
|
||||
navigator,
|
||||
document,
|
||||
inferred_triples: Graph::new(),
|
||||
show_read_only: false,
|
||||
show_inferred_triples: false,
|
||||
hovered_row: None,
|
||||
search_state: None,
|
||||
index,
|
||||
@@ -574,11 +571,17 @@ impl Publisher {
|
||||
}
|
||||
}
|
||||
Message::NavigateToObject(key) => {
|
||||
if let Some(quad) = self.document.dataset_mut().quads.get_mut(key)
|
||||
&& let Term::NamedNode(node) = &quad.object {
|
||||
let url = Url::parse(node.as_str()).expect("Invalid URL");
|
||||
if let Some(quad) = self.document.dataset_mut().quads.get_mut(key) {
|
||||
let url = if let Term::NamedNode(node) = &quad.object {
|
||||
Url::parse(node.as_str()).ok()
|
||||
} else if let Term::Literal(literal) = &quad.object {
|
||||
Url::parse(literal.value()).ok()
|
||||
} else { None };
|
||||
|
||||
if let Some(url) = url {
|
||||
task = Task::done(Message::URLInputChanged(url.to_string()))
|
||||
.chain(Task::done(Message::URLInputSubmitted));
|
||||
}
|
||||
}
|
||||
}
|
||||
Message::NavigateBack => {
|
||||
@@ -591,12 +594,6 @@ impl Publisher {
|
||||
task = Task::done(Message::URLInputChanged(url.to_string()))
|
||||
.chain(Task::done(Message::NavigateTo(url)));
|
||||
}
|
||||
Message::SetShowReadOnly(value) => {
|
||||
self.show_read_only = value;
|
||||
}
|
||||
Message::SetShowInferredTriples(value) => {
|
||||
self.show_inferred_triples = value;
|
||||
}
|
||||
Message::RunInference => {
|
||||
if let Some(ontology) = &mut self.ontology {
|
||||
let graph = self.document
|
||||
@@ -627,6 +624,15 @@ impl Publisher {
|
||||
|
||||
self.inferred_triples = graph;
|
||||
}
|
||||
Message::ShowInferencesWindow => {
|
||||
if let Some(id) = self.inference_window_id {
|
||||
task = window::gain_focus(id);
|
||||
} else {
|
||||
let (id, window_task) = window::open(Settings::default());
|
||||
self.inference_window_id = Some(id);
|
||||
task = window_task.map(|_| Message::None);
|
||||
}
|
||||
}
|
||||
Message::Event(Event::KeyPressed {
|
||||
key: keyboard::Key::Named(key::Named::Tab),
|
||||
modifiers,
|
||||
@@ -643,8 +649,14 @@ impl Publisher {
|
||||
task
|
||||
}
|
||||
|
||||
pub(crate) fn title(&self, _window: window::Id) -> String {
|
||||
"Graph of Liberty Publisher".to_string()
|
||||
pub(crate) fn title(&self, window: window::Id) -> String {
|
||||
if let Some(inference_window_id) = self.inference_window_id && window == inference_window_id {
|
||||
"Graph of Liberty Publisher - Inferences".to_string()
|
||||
} else if let Some(search_state) = &self.search_state && window == search_state.window_id {
|
||||
"Graph of Liberty Publisher - Search".to_string()
|
||||
} else {
|
||||
"Graph of Liberty Publisher".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn subscription(&self) -> Subscription<Message> {
|
||||
@@ -727,17 +739,10 @@ impl Publisher {
|
||||
})
|
||||
.unwrap_or(Horizontal::Left);
|
||||
|
||||
// If the datatype is something, then it's not a named node, and we should use a plain
|
||||
// text_input as opposed to an iri_input.
|
||||
let object_input: Element<Message> = if term.datatype().is_some() {
|
||||
let base = text_input("Object", value.clone());
|
||||
if state.read_only {
|
||||
base.into()
|
||||
} else {
|
||||
base.on_input(move |value| Message::ObjectUpdated(key, value))
|
||||
.into()
|
||||
}
|
||||
} else {
|
||||
/* If the object is not a valid URL (either as a literal string or as a named node), then
|
||||
* use a normal text input instead of an iri_input.
|
||||
*/
|
||||
let object_input: Element<Message> = if term.is_named_node() || Url::parse(term.value()).is_ok() {
|
||||
let base = iri_input(&self.curie_helper, "Object", Some(base), value.as_str())
|
||||
.on_shift_click(Message::NavigateToObject(key));
|
||||
if state.read_only {
|
||||
@@ -750,6 +755,14 @@ impl Publisher {
|
||||
)))
|
||||
.into()
|
||||
}
|
||||
} else {
|
||||
let base = text_input("Object", value.clone());
|
||||
if state.read_only {
|
||||
base.into()
|
||||
} else {
|
||||
base.on_input(move |value| Message::ObjectUpdated(key, value))
|
||||
.into()
|
||||
}
|
||||
};
|
||||
|
||||
let selected_datatype = term
|
||||
@@ -888,6 +901,11 @@ impl Publisher {
|
||||
return self.view_search_window(search_state);
|
||||
}
|
||||
|
||||
if let Some(inference_window_id) = self.inference_window_id && window == inference_window_id {
|
||||
return crate::window::inferences::view_inference_window(&self.resource_descriptions, self.document.origin(), &self.curie_helper, &self.inferred_triples);
|
||||
}
|
||||
|
||||
let show_inferences_button = button("\u{1f9e0}").on_press(Message::ShowInferencesWindow);
|
||||
let back_button = button("\u{1f870}").on_press(Message::NavigateBack);
|
||||
let forward_button = button("\u{1f872}").on_press(Message::NavigateForward);
|
||||
let new_document_button = button("New Document").on_press(Message::ShowNewDocumentButtons);
|
||||
@@ -905,7 +923,6 @@ impl Publisher {
|
||||
rows = self.document
|
||||
.dataset()
|
||||
.iter_both()
|
||||
.filter(|(_, _, state)| self.show_read_only || !state.read_only)
|
||||
.map(|(key, quad, state)| self.view_row(key, quad, state))
|
||||
.collect();
|
||||
|
||||
@@ -928,63 +945,6 @@ impl Publisher {
|
||||
column(rows).into()
|
||||
};
|
||||
|
||||
let inference_table = if self.show_inferred_triples {
|
||||
let subject_column = table::column("Subject", |triple: TripleRef| {
|
||||
let curie = if let NamedOrBlankNodeRef::NamedNode(subject) = triple.subject {
|
||||
Some(self.curie_helper
|
||||
.abbreviate(Some(self.document.origin()), subject.as_str())
|
||||
.unwrap_or_else(|| subject.as_str().to_string()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
curie.map(text)
|
||||
});
|
||||
|
||||
let predicate_column = table::column("Predicate", |triple: TripleRef| {
|
||||
let curie = self.curie_helper
|
||||
.abbreviate(None, triple.predicate.as_str())
|
||||
.unwrap_or_else(|| triple.predicate.as_str().to_string());
|
||||
|
||||
let label = self.resource_descriptions
|
||||
.get(&triple.predicate.into_owned())
|
||||
.and_then(|description| description.label.clone());
|
||||
|
||||
if let Some(label) = label {
|
||||
text(format!("{curie} ({label})"))
|
||||
} else {
|
||||
text(curie)
|
||||
}
|
||||
});
|
||||
|
||||
let object_column = table::column("Object", |triple: TripleRef| {
|
||||
match triple.object {
|
||||
TermRef::NamedNode(node) => {
|
||||
let curie = self.curie_helper
|
||||
.abbreviate(Some(self.document.origin()), node.as_str())
|
||||
.unwrap_or_else(|| node.as_str().to_string());
|
||||
|
||||
let label = self.resource_descriptions
|
||||
.get(&node.into_owned())
|
||||
.and_then(|description| description.label.clone());
|
||||
|
||||
if let Some(label) = label {
|
||||
text(format!("{curie} ({label})"))
|
||||
} else {
|
||||
text(curie)
|
||||
}
|
||||
}
|
||||
_ => text(triple.object.to_string()),
|
||||
}
|
||||
});
|
||||
Some(table(
|
||||
[subject_column, predicate_column, object_column],
|
||||
self.inferred_triples.iter(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let save_button_base = button(text("\u{1f4be}"));
|
||||
let save_button = if self.modified {
|
||||
save_button_base.on_press(Message::SaveGraph(false))
|
||||
@@ -992,22 +952,9 @@ impl Publisher {
|
||||
save_button_base
|
||||
};
|
||||
|
||||
let inferred_triples_toggle =
|
||||
toggler(self.show_inferred_triples).on_toggle(Message::SetShowInferredTriples);
|
||||
|
||||
let read_only_toggle = toggler(self.show_read_only).on_toggle(Message::SetShowReadOnly);
|
||||
|
||||
let footer = row![
|
||||
space::horizontal(),
|
||||
text("Show Inferred Triples"),
|
||||
inferred_triples_toggle,
|
||||
space::horizontal(),
|
||||
text("Show Read Only Triples"),
|
||||
read_only_toggle
|
||||
];
|
||||
|
||||
let content = navigation_area(column![
|
||||
row![
|
||||
show_inferences_button,
|
||||
new_document_button,
|
||||
add_row_button,
|
||||
back_button,
|
||||
@@ -1015,9 +962,7 @@ impl Publisher {
|
||||
address_input,
|
||||
save_button,
|
||||
],
|
||||
footer,
|
||||
scrollable(body),
|
||||
scrollable(inference_table),
|
||||
])
|
||||
.on_back_click(Message::NavigateBack)
|
||||
.on_forward_click(Message::NavigateForward);
|
||||
|
||||
Reference in New Issue
Block a user