.
This commit is contained in:
+61
-68
@@ -1,6 +1,6 @@
|
||||
use crate::rdf::ontology::{LabeledIri, Ontology};
|
||||
use crate::rdf::term_helper::{TermHelper, TermHelperMut};
|
||||
use gl_search::{Schema, SearchDocument, SearchIndex, doc, IndexWriter};
|
||||
use gl_search::{Schema, SearchDocument, SearchIndex, doc, IndexWriter, Value};
|
||||
use http::StatusCode;
|
||||
use iced::alignment::Horizontal;
|
||||
use iced::widget::button::Style;
|
||||
@@ -8,6 +8,7 @@ use iced::widget::grid::Sizing;
|
||||
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};
|
||||
@@ -16,9 +17,9 @@ 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 tracing::{debug_span, error, trace};
|
||||
use crate::rdf::conversion;
|
||||
use oxigraph::model::{BaseDirection, Dataset, NamedNode, NamedNodeRef, Quad, Term, TermRef};
|
||||
use tracing::{debug, debug_span, error, trace};
|
||||
use crate::rdf::language;
|
||||
use crate::widget::iri_input::iri_input;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -108,39 +109,23 @@ impl Publisher {
|
||||
.build()
|
||||
.expect("Failed to build search index");
|
||||
|
||||
let classes_to_index = [
|
||||
rdf::PROPERTY,
|
||||
rdfs::CLASS,
|
||||
];
|
||||
|
||||
debug_span!("Ontology Indexing").in_scope(|| {
|
||||
let mut counter = 0;
|
||||
let mut writer = index.writer().expect("Failed to build index writer");
|
||||
for class in &classes_to_index {
|
||||
let class = class.into_owned();
|
||||
if let Some(id) = ontology.catalog_id(&class) {
|
||||
writer.remove_all_of_type(id).expect("Failed to remove documents from search index");
|
||||
for individual in ontology.individuals(&class) {
|
||||
let info = ontology.info(&individual, &conversion::english());
|
||||
if info.label.is_some() || info.comment.is_some() {
|
||||
let mut document = doc!(
|
||||
Schema::type_field() => id,
|
||||
Schema::iri_field() => individual.as_str(),
|
||||
);
|
||||
|
||||
if let Some(field) = ontology.field_for_property(&rdfs::LABEL.into_owned()) {
|
||||
document.add_text(Schema::field(&field.name), info.label.unwrap_or_default());
|
||||
}
|
||||
|
||||
if let Some(field) = ontology.field_for_property(&rdfs::COMMENT.into_owned()) {
|
||||
document.add_text(Schema::field(&field.name), info.comment.unwrap_or_default());
|
||||
}
|
||||
|
||||
writer.add(document).expect("Failed to add document to search index");
|
||||
}
|
||||
}
|
||||
let index = ontology.index(&*language::ENGLISH_OR_UNTAGGED).expect("Unable to generate index of entities");
|
||||
for (individual, entry) in index {
|
||||
let mut document = doc!(
|
||||
Schema::type_field() => entry.catalog_id,
|
||||
Schema::iri_field() => individual.as_str(),
|
||||
);
|
||||
for (key, value) in entry.fields {
|
||||
document.add_text(Schema::field(&key, language::ENGLISH_PRIMARY), value.as_str());
|
||||
}
|
||||
writer.add(document).expect("Failed to add document to search index");
|
||||
counter += 1;
|
||||
}
|
||||
writer.commit().expect("Failed to commit changes to search index");
|
||||
debug!("Added {counter} documents to search index");
|
||||
});
|
||||
|
||||
let mut abbreviated_datatypes = ontology
|
||||
@@ -207,7 +192,7 @@ impl Publisher {
|
||||
document.add_u64(Schema::type_field(), catalog_id);
|
||||
document.add_text(Schema::iri_field(), rdf_source.origin());
|
||||
|
||||
for quad in rdf_source.dataset() {
|
||||
/*for quad in rdf_source.dataset() {
|
||||
if let Some(field) =
|
||||
self.ontology.field_for_property(&quad.predicate.into_owned())
|
||||
&& let TermRef::Literal(literal) = quad.object
|
||||
@@ -217,7 +202,7 @@ impl Publisher {
|
||||
.expect("Field not found in schema");
|
||||
document.add_text(field, literal.value());
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if let Some(writer) = &self.index_writer {
|
||||
writer.add(document).expect("Unable to add document to search index");
|
||||
@@ -328,13 +313,13 @@ impl Publisher {
|
||||
if let Some(search_state) = &mut self.search_state {
|
||||
search_state.action = action;
|
||||
} else {
|
||||
if let Some(type_) = self.ontology.labeled_entities().next() {
|
||||
if let Some(entity) = self.ontology.labeled_entities(&*language::ENGLISH_OR_UNTAGGED).next() {
|
||||
let (id, window_task) = window::open(Settings::default());
|
||||
self.search_state = Some(SearchState {
|
||||
window_id: id,
|
||||
action,
|
||||
query: String::new(),
|
||||
type_,
|
||||
type_: entity,
|
||||
results: Vec::new(),
|
||||
});
|
||||
task = window_task.map(|_| Message::None)
|
||||
@@ -350,6 +335,7 @@ impl Publisher {
|
||||
}
|
||||
Message::QueryUpdated(new_query) => {
|
||||
if let Some(search_state) = &mut self.search_state {
|
||||
let selected_entity_class = &search_state.type_.iri;
|
||||
let catalog_id = match search_state.action {
|
||||
SearchResultClickAction::Predicate(_) => self.ontology.catalog_id(&rdf::PROPERTY.into_owned()),
|
||||
SearchResultClickAction::Object(key) => {
|
||||
@@ -360,10 +346,10 @@ impl Publisher {
|
||||
.and_then(|quad| if quad.predicate == rdf::TYPE {
|
||||
self.ontology.catalog_id(&rdfs::CLASS.into_owned())
|
||||
} else {
|
||||
self.ontology.catalog_id(&search_state.type_.iri)
|
||||
self.ontology.catalog_id(selected_entity_class)
|
||||
})
|
||||
},
|
||||
SearchResultClickAction::URLInput => self.ontology.catalog_id(&search_state.type_.iri),
|
||||
SearchResultClickAction::URLInput => self.ontology.catalog_id(selected_entity_class),
|
||||
};
|
||||
|
||||
let index = self.index.clone();
|
||||
@@ -373,7 +359,7 @@ impl Publisher {
|
||||
});
|
||||
task = Task::future(async {
|
||||
match search_task.await {
|
||||
Ok(Ok(documents)) => Message::SetSearchResults(documents),
|
||||
Ok(Ok(results)) => Message::SetSearchResults(results),
|
||||
Ok(Err(err)) => Message::ShowError(err.to_string()),
|
||||
Err(err) => Message::ShowError(err.to_string()),
|
||||
}
|
||||
@@ -556,9 +542,8 @@ impl Publisher {
|
||||
|
||||
let property_label = self
|
||||
.ontology
|
||||
.info(&triple.predicate, &conversion::english())
|
||||
.label
|
||||
.unwrap_or(self.ontology.abbreviate(triple.predicate.as_ref()));
|
||||
.info(&triple.predicate, &*language::ENGLISH_OR_UNTAGGED)
|
||||
.label;
|
||||
|
||||
let property: Element<Message> = if state.read_only {
|
||||
text(property_label).into()
|
||||
@@ -574,10 +559,8 @@ impl Publisher {
|
||||
let term = TermHelper::new(&triple.object);
|
||||
|
||||
let value_label = term.value_as_named_node().and_then(|node| {
|
||||
self.ontology
|
||||
.info(&node.into_owned(), &conversion::english())
|
||||
.label
|
||||
.map(|label| container(text(label)))
|
||||
let info = self.ontology.info(&node.into_owned(), &*language::ENGLISH_OR_UNTAGGED);
|
||||
Some(container(text(info.label)))
|
||||
});
|
||||
|
||||
let value = term
|
||||
@@ -668,9 +651,8 @@ impl Publisher {
|
||||
let buttons = entities.map(|entity| {
|
||||
let label = self
|
||||
.ontology
|
||||
.info(&entity, &conversion::english())
|
||||
.label
|
||||
.unwrap_or(entity.as_str().to_string());
|
||||
.info(&entity, &*language::ENGLISH_OR_UNTAGGED)
|
||||
.label;
|
||||
button(text(label))
|
||||
.on_press(Message::NewDocument(entity))
|
||||
.into()
|
||||
@@ -689,35 +671,46 @@ impl Publisher {
|
||||
text_input("Query", &search_state.query).on_input(Message::QueryUpdated);
|
||||
|
||||
let mut entities = self.ontology
|
||||
.labeled_entities()
|
||||
.labeled_entities(&*language::ENGLISH_OR_UNTAGGED)
|
||||
.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: &QueryResult| {
|
||||
let cell_value = document.0.get(&field.name)
|
||||
.and_then(|values| values.first())
|
||||
.map(|value| match value {
|
||||
OwnedValue::Str(string) => string,
|
||||
_ => "???",
|
||||
}).unwrap_or("");
|
||||
let fields = self.ontology.fields_for_class(&search_state.type_.iri, &*language::ENGLISH_OR_UNTAGGED)
|
||||
.expect("Unable to load fields for class");
|
||||
|
||||
let iri = document.get("iri")
|
||||
.and_then(|values| values.first())
|
||||
.map(|value| match value {
|
||||
OwnedValue::Str(string) => string,
|
||||
_ => "???",
|
||||
}).unwrap_or("");
|
||||
let mut columns = vec![
|
||||
table::column(text("CURIE"), |document: &SearchDocument| {
|
||||
let iri = document.get_first(Schema::iri_field())
|
||||
.and_then(|value| value.as_str())
|
||||
.unwrap_or_default();
|
||||
|
||||
button(text(cell_value).wrapping(Wrapping::Word))
|
||||
let abbreviated_iri = self.ontology.abbreviate(NamedNodeRef::new_unchecked(iri));
|
||||
button(text(abbreviated_iri).wrapping(Wrapping::Word))
|
||||
.on_press(Message::SearchResultClicked(NamedNode::new_unchecked(iri)))
|
||||
.style(button::text)
|
||||
}).width(Length::Fixed(256.0)));*/
|
||||
})
|
||||
];
|
||||
|
||||
for field in fields.into_iter() {
|
||||
let field_name = field.name.clone();
|
||||
columns.push(
|
||||
table::column(text(field.label), move |document: &SearchDocument| {
|
||||
let iri = document.get_first(Schema::iri_field())
|
||||
.and_then(|value| value.as_str())
|
||||
.unwrap_or_default();
|
||||
|
||||
let value = document.get_first(Schema::field(&field_name, language::ENGLISH_PRIMARY))
|
||||
.and_then(|value| value.as_str())
|
||||
.unwrap_or_default();
|
||||
|
||||
button(text(value).wrapping(Wrapping::Word))
|
||||
.on_press(Message::SearchResultClicked(NamedNode::new_unchecked(iri)))
|
||||
.style(button::text)
|
||||
}).width(Length::Fixed(256.0))
|
||||
);
|
||||
}
|
||||
|
||||
let results_table = if columns.is_empty() {
|
||||
|
||||
Reference in New Issue
Block a user