.
This commit is contained in:
+88
-45
@@ -1,17 +1,16 @@
|
||||
use crate::rdf::ontology::Ontology;
|
||||
use std::collections::HashSet;
|
||||
use crate::rdf::ontology::{LabeledIri, Ontology};
|
||||
use crate::rdf::term_helper::{TermHelper, TermHelperMut};
|
||||
use crate::rdf::vocab::{gl, rda};
|
||||
use gl_search::{Schema, SearchDocument, SearchIndex, doc};
|
||||
use gl_search::{Schema, SearchDocument, SearchIndex, doc, NamedFieldDocument, OwnedValue};
|
||||
use http::StatusCode;
|
||||
use iced::alignment::Horizontal;
|
||||
use iced::widget::button::Style;
|
||||
use iced::widget::grid::Sizing;
|
||||
use iced::widget::{
|
||||
button, center, column, combo_box, container, grid, mouse_area, opaque, row, scrollable, space,
|
||||
stack, table, text, text_input, toggler,
|
||||
};
|
||||
use iced::widget::{button, center, column, combo_box, container, grid, mouse_area, opaque, pick_list, row, scrollable, space, stack, table, text, text_input, toggler};
|
||||
use iced::window::Settings;
|
||||
use iced::{Background, Color, Element, Length, Subscription, Task, color, window};
|
||||
use iced::widget::text::Wrapping;
|
||||
use ldp::middleware::BasicAuthMiddleware;
|
||||
use ldp::model::{KeyedDataset, QuadKey};
|
||||
use ldp::reqwest::{Client, Url};
|
||||
@@ -20,7 +19,7 @@ use ldp::traverse::Traverse;
|
||||
use ldp::{RdfSource, RdfSourceUpdateResponse, ResourceRequestBuilder, SerializationOptions};
|
||||
use oxigraph::io::RdfFormat;
|
||||
use oxigraph::model::vocab::{rdf, rdfs};
|
||||
use oxigraph::model::{BaseDirection, Dataset, NamedNode, Quad, Term, TermRef};
|
||||
use oxigraph::model::{BaseDirection, Dataset, NamedNode, NamedNodeRef, Quad, Term, TermRef};
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -44,6 +43,7 @@ pub(crate) enum Message {
|
||||
HoverRow(QuadKey),
|
||||
UnhoverRow(QuadKey),
|
||||
QueryUpdated(String),
|
||||
QueryTypeUpdated(NamedNode),
|
||||
SearchResultClicked(NamedNode),
|
||||
DatatypeUpdated(QuadKey, Option<String>),
|
||||
LanguageUpdated(QuadKey, Option<String>),
|
||||
@@ -74,7 +74,8 @@ struct SearchState {
|
||||
window_id: window::Id,
|
||||
action: SearchResultClickAction,
|
||||
query: String,
|
||||
results: Vec<NamedNode>,
|
||||
type_: LabeledIri,
|
||||
results: Vec<NamedFieldDocument>,
|
||||
}
|
||||
|
||||
pub(crate) struct Publisher {
|
||||
@@ -113,12 +114,14 @@ impl Publisher {
|
||||
Schema::iri_field() => iri.as_str(),
|
||||
);
|
||||
|
||||
if let Some(label) = &info.label {
|
||||
document.add_text(Schema::field("label"), label.to_lowercase());
|
||||
if let Some(label) = &info.label &&
|
||||
let Some(field) = ontology.field_for_property(&rdfs::LABEL.into_owned()) {
|
||||
document.add_text(Schema::field(&field.name), label);
|
||||
}
|
||||
|
||||
if let Some(comment) = &info.comment {
|
||||
document.add_text(Schema::field("comment"), comment.to_lowercase());
|
||||
if let Some(comment) = &info.comment &&
|
||||
let Some(field) = ontology.field_for_property(&rdfs::COMMENT.into_owned()) {
|
||||
document.add_text(Schema::field(&field.name), comment);
|
||||
}
|
||||
|
||||
index.add(document).expect("Unable to add annotated IRI to search index");
|
||||
@@ -192,9 +195,9 @@ impl Publisher {
|
||||
&& let TermRef::Literal(literal) = quad.object
|
||||
{
|
||||
let field = Schema::schema()
|
||||
.get_field(&field.key)
|
||||
.get_field(field.name.as_str())
|
||||
.expect("Field not found in schema");
|
||||
document.add_text(field, literal.value().to_lowercase());
|
||||
document.add_text(field, literal.value());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,19 +309,29 @@ impl Publisher {
|
||||
if let Some(search_state) = &mut self.search_state {
|
||||
search_state.action = action;
|
||||
} else {
|
||||
let (id, window_task) = window::open(Settings::default());
|
||||
self.search_state = Some(SearchState {
|
||||
window_id: id,
|
||||
action,
|
||||
query: String::new(),
|
||||
results: Vec::new(),
|
||||
});
|
||||
task = window_task.map(|_| Message::None)
|
||||
if let Some(type_) = self.ontology.labeled_entities().next() {
|
||||
let (id, window_task) = window::open(Settings::default());
|
||||
self.search_state = Some(SearchState {
|
||||
window_id: id,
|
||||
action,
|
||||
query: String::new(),
|
||||
type_,
|
||||
results: Vec::new(),
|
||||
});
|
||||
task = window_task.map(|_| Message::None)
|
||||
};
|
||||
}
|
||||
}
|
||||
Message::QueryTypeUpdated(type_) => {
|
||||
if let Some(search_state) = &mut self.search_state {
|
||||
if let Some(type_) = self.ontology.labeled_entity(&type_) {
|
||||
search_state.type_ = type_;
|
||||
}
|
||||
}
|
||||
}
|
||||
Message::QueryUpdated(new_query) => {
|
||||
if let Some(search_state) = &mut self.search_state {
|
||||
let type_ = match search_state.action {
|
||||
let catalog_id = match search_state.action {
|
||||
SearchResultClickAction::Predicate(_) => self.ontology.catalog_id(&rdf::PROPERTY.into_owned()),
|
||||
SearchResultClickAction::Object(key) => {
|
||||
self.document
|
||||
@@ -334,11 +347,8 @@ impl Publisher {
|
||||
|
||||
search_state.results = self
|
||||
.index
|
||||
.query(type_, new_query.as_str(), Schema::all_fields())
|
||||
.expect("Error encountered while querying index")
|
||||
.iter()
|
||||
.map(NamedNode::new_unchecked)
|
||||
.collect();
|
||||
.query(catalog_id, new_query.as_str(), Schema::all_fields())
|
||||
.expect("Error encountered while querying index");
|
||||
search_state.query = new_query;
|
||||
};
|
||||
}
|
||||
@@ -670,7 +680,41 @@ impl Publisher {
|
||||
let search_input =
|
||||
text_input("Query", &search_state.query).on_input(Message::QueryUpdated);
|
||||
|
||||
let label_column = table::column("Label", |result: &NamedNode| {
|
||||
let mut entities = self.ontology
|
||||
.labeled_entities()
|
||||
.collect::<Vec<_>>();
|
||||
entities.sort_by(|a, b| Ord::cmp(&a.label, &b.label));
|
||||
|
||||
let type_selector = pick_list(Some(&search_state.type_), entities, ToString::to_string)
|
||||
.on_select(|selection| Message::QueryTypeUpdated(selection.iri));
|
||||
|
||||
let mut columns = vec![];
|
||||
for field in self.ontology.fields_for_class(&search_state.type_.iri) {
|
||||
let header_text = field.label.as_ref().unwrap_or(&field.name);
|
||||
columns.push(table::column(text(header_text), |document: &NamedFieldDocument| {
|
||||
let cell_value = document.0
|
||||
.get(&field.name)
|
||||
.and_then(|values| values.first())
|
||||
.map(|value| match value {
|
||||
OwnedValue::Str(string) => string,
|
||||
_ => "???",
|
||||
}).unwrap_or("");
|
||||
|
||||
let iri = document.0
|
||||
.get("iri")
|
||||
.and_then(|values| values.first())
|
||||
.map(|value| match value {
|
||||
OwnedValue::Str(string) => string,
|
||||
_ => "???",
|
||||
}).unwrap_or("");
|
||||
|
||||
button(text(cell_value).wrapping(Wrapping::Word))
|
||||
.on_press(Message::SearchResultClicked(NamedNode::new_unchecked(iri)))
|
||||
.style(button::text)
|
||||
}).width(Length::Fixed(256.0)));
|
||||
}
|
||||
|
||||
/*let label_column = table::column("Label", |result: &NamedNode| {
|
||||
let header_text = self
|
||||
.ontology
|
||||
.info(result.as_ref())
|
||||
@@ -695,7 +739,7 @@ impl Publisher {
|
||||
.style(button::text)
|
||||
});
|
||||
|
||||
/*let description_column = table::column("Description", |result: &NamedNode| {
|
||||
let description_column = table::column("Description", |result: &NamedNode| {
|
||||
let header_text = self.ontology.info(result.as_ref())
|
||||
.and_then(|info| info.comment.clone())
|
||||
.unwrap_or("Unknown".to_string());
|
||||
@@ -703,25 +747,24 @@ impl Publisher {
|
||||
button(text(header_text))
|
||||
.on_press(Message::SearchResultClicked(result.clone()))
|
||||
.style(button::text)
|
||||
});*/
|
||||
});
|
||||
|
||||
let iri_column = table::column("IRI", |result: &NamedNode| {
|
||||
button(text(result.as_str()))
|
||||
.on_press(Message::SearchResultClicked(result.clone()))
|
||||
.style(button::text)
|
||||
});
|
||||
});*/
|
||||
|
||||
let results_table = scrollable(table(
|
||||
[
|
||||
label_column,
|
||||
//description_column,
|
||||
type_column,
|
||||
iri_column,
|
||||
],
|
||||
&search_state.results,
|
||||
));
|
||||
let results_table = if columns.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(scrollable(table(columns, &search_state.results)))
|
||||
};
|
||||
|
||||
return column![search_input, results_table].into();
|
||||
return column![
|
||||
row![search_input, type_selector],
|
||||
results_table
|
||||
].into();
|
||||
}
|
||||
|
||||
let add_row_button = button("Add row").on_press(Message::AddRow(None));
|
||||
@@ -742,8 +785,8 @@ impl Publisher {
|
||||
|
||||
let body: Element<Message> = if self.show_new_document_buttons {
|
||||
column![
|
||||
self.view_new_entity_buttons(self.ontology.subclass_of(gl::ENTITY)),
|
||||
self.view_new_entity_buttons(self.ontology.subclass_of(rda::ENTITY)),
|
||||
//self.view_new_entity_buttons(self.ontology.subclass_of(gl::ENTITY)),
|
||||
//self.view_new_entity_buttons(self.ontology.subclass_of(rda::ENTITY)),
|
||||
]
|
||||
.into()
|
||||
} else {
|
||||
@@ -818,4 +861,4 @@ where
|
||||
)
|
||||
]
|
||||
.into()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user