Skip to content
This repository has been archived by the owner on Sep 4, 2024. It is now read-only.

Commit

Permalink
Support manually adding profile entries
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminaaron committed May 28, 2024
1 parent dfc000a commit 6552c9c
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 29 deletions.
67 changes: 55 additions & 12 deletions public/dom-building.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,58 @@

function handleAddNewEntry() {
buildSubjectSelectDropdown()
document.getElementById("addNewEntryLink").style.display = "none"
document.getElementById("manualProfileEntryGroup").style.display = "inline"
}

function buildSubjectSelectDropdown() {
const subjectSelectEl = document.getElementById("subjectDropdown")
subjectSelectEl.innerHTML = ""
addPlaceholderOption(subjectSelectEl, "Select a subject")

const subjectNodes = []
collectSubjectNodesRecursively(userProfile, subjectNodes)
for (let subjectNode of subjectNodes) {
let optionEl = document.createElement("option")
optionEl.value = JSON.stringify(subjectNode)
optionEl.textContent = MANUAL_KEY_TO_LABEL[subjectNode.id] ?? subjectNode.id
subjectSelectEl.appendChild(optionEl)
}
subjectSelectEl.addEventListener("change", event =>
buildDatafieldSelectDropdown(JSON.parse(event.target.value))
)
}

function buildDatafieldSelectDropdown(subjectNode) {
const dfSelectEl = document.getElementById("dfDropdown")
dfSelectEl.innerHTML = ""
addPlaceholderOption(dfSelectEl, "Select a datafield")

let optionEl
for (let df of Object.values(metadata.df)) {
if (df.isClass) continue
if (!df.objectHasClass && subjectNode.datafields.includes(shortenLongUri(df.uri))) continue
optionEl = document.createElement("option")
optionEl.value = df.uri
let label = df.label // + " (" + shortenLongUri(df.uri) + ")"
if (df.objectHasClass) label += " --> adds a new '" + metadata.df[df.objectHasClass].label + "'"
optionEl.textContent = label
dfSelectEl.appendChild(optionEl)
}
optionEl = document.createElement("option")
optionEl.value = "NEW_PREDICATE"
optionEl.textContent = "+ Add new datafield"
dfSelectEl.appendChild(optionEl)
}

function addPlaceholderOption(selectEl, text) {
const placeholder = document.createElement("option")
placeholder.textContent = text
placeholder.disabled = true
placeholder.selected = true
selectEl.appendChild(placeholder)
}

async function buildRemovalCell(td, sKey, pKey) {
td.textContent = "x"
td.addEventListener("click", async function() {
Expand Down Expand Up @@ -150,18 +204,7 @@ async function buildPrioritizedMissingDataList() {
})
spanEl.addEventListener("click", async function(event) {
event.preventDefault()
if (entry.objectHasClass) {
if (confirm("Do you want to add a " + metadata.df[entry.objectHasClass].label + "?")) {
instantiateNewObjectClassUnderSubject(entry.subject, entry.dfUri, entry.objectHasClass)
await finalizeProfileChanges()
}
return
}
let input = prompt("What is your value for: " + entry.label)
if (input !== null) {
addEntryToSubject(entry.subject, entry.dfUri, input)
await finalizeProfileChanges()
}
await promptForNewProfileEntry(entry)
})
div.appendChild(spanEl)
spanEl = document.createElement("span")
Expand Down
8 changes: 7 additions & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@
<h3>User profile</h3>
<div id="userProfileDiv"></div>
<br/>
<select style="display: none" id="dfDropdown"></select>
<small id="addNewEntryLink"><a href="#" onclick="handleAddNewEntry()">Add new entry</a></small>
<div id="manualProfileEntryGroup" style="display: none">
<select id="subjectDropdown"></select>
<select id="dfDropdown"></select>
<input type="button" value="Add" onclick="addManualProfileEntry()"/>
<br/>
</div>
<br/>
<small><a href="#" onclick="clearUserProfile()">Reset</a></small>
<small><a href="#" onclick="importUserProfileTurtle()">Import</a></small>
Expand Down
2 changes: 2 additions & 0 deletions public/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ let eligibleRPs
async function run() {
latestRPsRepoCommit = await fetchAsset("latest-rps-repo-commit.txt")
setInterval(checkForNewRepoCommits, 60 * 1000)

await parseTurtleFiles()

if (localStorage.getItem("userProfile") === null) {
localStorage.setItem("userProfile", JSON.stringify(EMPTY_PROFILE))
}
userProfile = JSON.parse(localStorage.getItem("userProfile"))
if (!await validateUserProfile()) return

await update()
}
15 changes: 1 addition & 14 deletions public/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,7 @@ async function parseTurtleFiles() {
df: await MatchingEngine.extractDatafieldsMetadata(turtleMap.datafields),
rp: await MatchingEngine.extractRequirementProfilesMetadata(Object.values(turtleMap.shacl))
}

const selectEl = document.getElementById("dfDropdown")
selectEl.innerHTML = ""
for (let df of Object.values(metadata.df)) {
const optionEl = document.createElement("option")
optionEl.value = df.uri
optionEl.textContent = df.label
selectEl.appendChild(optionEl)
}
selectEl.addEventListener("change", function(event) {
const selectedValue = event.target.value
// TODO
})

console.log("metadata", metadata)

buildFocusInputSelectChoices()
}
45 changes: 44 additions & 1 deletion public/profile.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,46 @@

async function addManualProfileEntry() {
document.getElementById("addNewEntryLink").style.display = "inline"
document.getElementById("manualProfileEntryGroup").style.display = "none"

let subjectSelectEl = document.getElementById("subjectDropdown")
let dfSelectEl = document.getElementById("dfDropdown")
if (!subjectSelectEl.value || !dfSelectEl.value) {
alert("Both a subject and a datafield need to be selected")
return
}

let dfUri = dfSelectEl.value
if (dfUri === "NEW_PREDICATE") {
alert("TODO")
} else {
await promptForNewProfileEntry({
subject: JSON.parse(subjectSelectEl.value).id,
dfUri: dfUri,
objectHasClass: metadata.df[dfUri]?.objectHasClass,
label: metadata.df[dfUri]?.label ?? dfUri.split("#")[1],
})
}

document.getElementById("subjectDropdown").innerHTML = ""
document.getElementById("dfDropdown").innerHTML = ""
}

async function promptForNewProfileEntry(entry) {
if (entry.objectHasClass) {
if (confirm("Do you want to add a " + metadata.df[entry.objectHasClass].label + "?")) {
instantiateNewObjectClassUnderSubject(entry.subject, entry.dfUri, entry.objectHasClass)
await finalizeProfileChanges()
}
return
}
let input = prompt("What is your value for: " + entry.label)
if (input !== null) {
addEntryToSubject(entry.subject, entry.dfUri, input)
await finalizeProfileChanges()
}
}

function addEntryToSubject(subject, predicate, objectValue) {
subject = shortenLongUri(subject)
predicate = shortenLongUri(predicate)
Expand All @@ -7,14 +49,15 @@ function addEntryToSubject(subject, predicate, objectValue) {
}

function instantiateNewObjectClassUnderSubject(subject, predicate, objectClass) {
predicate = shortenLongUri(predicate)
console.log("Adding object class instantiation:", subject, predicate, "-->", objectClass)
let shortObjectClassUri = shortenLongUri(objectClass)
let newInstanceUri = shortObjectClassUri.toLowerCase()
let nodeFound = false
searchNodeByEntryPredicateRecursively(userProfile, predicate, (node) => {
nodeFound = true
newInstanceUri = newInstanceUri + node[predicate].length
node[predicate].push({ "@id": newInstanceUri, "@type": shortObjectClassUri }) // verify that this works TODO
node[predicate].push({ "@id": newInstanceUri, "@type": shortObjectClassUri })
})
if (!nodeFound) { // e.g. no ff:hasChild array yet
newInstanceUri = newInstanceUri + "0"
Expand Down
15 changes: 15 additions & 0 deletions public/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,21 @@ function searchSubjectNodeRecursively(node, sKey, action) {
}
}

function collectSubjectNodesRecursively(node, subjectNodes) {
subjectNodes.push({
id: node["@id"],
type: node["@type"],
datafields: Object.keys(node).filter(key => !key.startsWith("@"))
})
for (let objectOrArray of Object.values(node)) {
if (Array.isArray(objectOrArray)) {
for (let arrayEl of objectOrArray) {
collectSubjectNodesRecursively(arrayEl, subjectNodes)
}
}
}
}

async function checkForNewRepoCommits() {
console.log("Checking for updates, old commit:", latestRPsRepoCommit)
let checkLatestRPsRepoCommit = await fetchAsset("latest-rps-repo-commit.txt")
Expand Down
2 changes: 1 addition & 1 deletion public/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ async function update() {
await buildProfileTable()

let userProfileTurtle = await MatchingEngine.convertUserProfileToTurtle(userProfile)
console.log("userProfileTurtle", userProfileTurtle)
// console.log("userProfileTurtle", userProfileTurtle)
validateAllReport = await MatchingEngine.validateAll(userProfileTurtle, turtleMap.shacl, turtleMap.datafields, turtleMap.materialization)
console.log("validateAllReport", validateAllReport)

Expand Down

0 comments on commit 6552c9c

Please sign in to comment.