Skip to content

Commit

Permalink
Merge pull request #951 from SynBioHub/edit-types
Browse files Browse the repository at this point in the history
Add/remove fields
  • Loading branch information
cjmyers authored Jun 15, 2019
2 parents 0a753e1 + 6a3cd4c commit d9be6e3
Show file tree
Hide file tree
Showing 12 changed files with 438 additions and 80 deletions.
145 changes: 136 additions & 9 deletions browser/field-editor.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,59 @@
function updateSparql(value, field, cb) {
console.log(window.location.href + "/edit/" + field)
function updateSparql(value, oldVal, field, cb) {
$.ajax({
type: 'POST',
url: window.location.href + "/edit/" + field,
data: { object: value },
data: { object: value, previous: oldVal },
success: (data, status, xhr) => cb(data),
error: () => console.log("Failed to update SPARQL")
})
}

function save($input, $elem, toEdit) {
function addSparql(value, field, cb) {
$.ajax({
type: 'POST',
url: window.location.href + "/add/" + field,
data: { object: value },
success: (data, status, xhr) => cb(data),
error: () => console.log("Failed to add SPARQL")
})
}

function removeSparql(value, field, cb, finalCb) {
$.ajax({
type: 'POST',
url: window.location.href + "/remove/" + field,
data: { object: value },
success: (data, status, xhr) => cb(data),
error: () => console.log("Failed to remove SPARQL"),
complete: finalCb
})
}

function save($input, $elem, toEdit, oldVal) {
let newVal = $input.val()
$input.prop('disabled', true)

appendEditor(0, $elem)

updateSparql(newVal, toEdit, (newText) => {
updateSparql(newVal, oldVal, toEdit, (newText) => {
$elem.text(newText)
$input.replaceWith($elem)
appendEditor(0, $elem)
})
}

function appendEditor(idx, elem) {
function add($input, $elem, toEdit) {
let newVal = $input.val()
$input.prop('disabled', true)

appendEditor(0, $elem)

addSparql(newVal, toEdit, (newText) => {
location.reload()
})
}

function getField(elem, idx) {
let $elem = $(elem)
let toEdit = null

Expand All @@ -33,11 +64,18 @@ function appendEditor(idx, elem) {
}
})

return toEdit
}

function appendEditor(idx, elem) {
let $elem = $(elem)
let toEdit = getField($elem)

if (toEdit === null) {
return
}

let editClass = 'do-edit-' + toEdit
let editClass = 'do-edit-' + toEdit + idx

let editLink = document.createElement('a')
editLink.setAttribute('style', 'margin-left: 10px')
Expand All @@ -54,13 +92,102 @@ function appendEditor(idx, elem) {

$elem.replaceWith($input)

$input.one('blur', () => save($input, $elem, toEdit)).focus()
$input.one('blur', () => save($input, $elem, toEdit, text)).focus()
})
}

function appendRemover($elems) {
let toRemove = getField($elems[0])

if (toRemove === null) {
return
}

$elems.each((idx, elem) => {
let $elem = $(elem)
let removeClass = 'do-remove-' + toRemove + '-' + idx

let removeLink = document.createElement('a')
removeLink.setAttribute('class', "remove-" + toRemove)
removeLink.setAttribute('style', 'margin-left: 2px')

let removeButton = document.createElement('span')
removeButton.setAttribute('class', 'fa fa-trash ' + removeClass)
removeLink.appendChild(removeButton)

$elem.append(removeLink)

$('.' + removeClass).on('click', () => {
let $trashes = $(".remove-" + toRemove)
let text = $elem.attr("editText") || $elem.text()

$trashes.remove()

removeSparql(text, toRemove, () => {
$elem.remove()
updateAddRemove()
},
() => {
updateAddRemove()
})
})
})
}

function appendAdder($elems) {
let $last = $elems.filter(":last")
let toAdd = getField($last)

if (toAdd === null) {
return
}

let addClass = 'do-add-' + toAdd

let addLink = document.createElement('a')
addLink.setAttribute('class', "add-" + toAdd)
addLink.setAttribute('style', 'margin-left: 2px')

let addButton = document.createElement('span')
addButton.setAttribute('class', 'fa fa-plus ' + addClass)
addLink.appendChild(addButton)

$last.append(addLink)
$("." + addClass).on("click", () => {
let $row = $("<tr><td/><td/><tr>")
let $cell = $row.find("td").last()
let $input = $("<input/>")
$cell.append($input)
$last.parent().append($row)

$input.one('blur', () => add($input, $last, toAdd)).focus()
})
}

function updateAddRemove() {
let $multiples = $(".edit-multiple")
let fields = new Set($.map($multiples, getField))

// Remove existing adders and removers
$("a[class|=add]").remove()
$("a[class|=remove]").remove()

fields.forEach(field => {
let classname = '.edit-' + field
let $elems = $(classname)

appendAdder($elems)

if ($elems.length > 1) {
appendRemover($elems)
}
})
}

// Entry point for editors
$(window).on('load', function() {
let $editables = $(".edit")
console.log($editables)
$editables.each(appendEditor)

updateAddRemove()
})
102 changes: 102 additions & 0 deletions lib/api/addObject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
const config = require('../config')
const getUrisFromReq = require('../getUrisFromReq')
const loadTemplate = require('../loadTemplate')
const sparql = require('../sparql/sparql')
const lookupRole = require('../role')
const lookupType = require('../type')

const PREDICATES = {
'role': 'http://sbols.org/v2#role',
'type': 'http://sbols.org/v2#type'
}

function subjectIsValid (subject) {
let defaultGraph = config.get('triplestore').defaultGraph

return !subject.startsWith(defaultGraph)
}

function predicateIsValid (predicate) {
return predicate !== undefined
}

function objectIsValid (object) {
return object && object !== ''
}

function tripleIsValid (subject, predicate, object) {
if (predicate === PREDICATES['role']) {
// this needs to actually validate roles
return true
}

return true
}

function getDisplayString (type, object) {
switch (type) {
case 'role':
let role = lookupRole(object)
return role.description.name || role.term || role.uri
case 'type':
let type = lookupType(object)
return type.description.name || type.term || type.uri
default:
return object
}
}

function formatObject (object) {
if (object.startsWith('http')) {
return `<${object}>`
} else {
return `"${object}"`
}
}

function serve (req, res) {
let { graphUri, uri } = getUrisFromReq(req, res)
let field = req.params.field

let d = new Date()
let modified = d.toISOString()
modified = modified.substring(0, modified.indexOf('.'))
modified = JSON.stringify(modified)

let subject = uri
let predicate = PREDICATES[field]
let object = req.body.object || ''

if (!subjectIsValid(subject)) {
res.sendStatus(403).end()
return
} else if (!predicateIsValid(predicate)) {
res.sendStatus(404).end()
return
} else if (!objectIsValid(object)) {
res.sendStatus(400).end()
return
} else if (!tripleIsValid(subject, predicate, object)) {
res.sendStatus(400).end()
return
}

const params = {
subject: subject,
predicate: predicate,
object: formatObject(object),
modified: modified
}

const query = loadTemplate('./sparql/AddTriple.sparql', params)
console.log(query)

sparql.updateQueryJson(query, graphUri).then(result => {
res.send(getDisplayString(field, object))
}).catch(error => {
console.error(error)
res.sendStatus(500).end()
})
}

module.exports = serve
9 changes: 8 additions & 1 deletion lib/api/editObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ const getUrisFromReq = require('../getUrisFromReq')
const loadTemplate = require('../loadTemplate')
const sparql = require('../sparql/sparql')
const lookupRole = require('../role')
const lookupType = require('../type')

const PREDICATES = {
'title': 'http://purl.org/dc/terms/title',
'description': 'http://purl.org/dc/terms/description',
'role': 'http://sbols.org/v2#role',
'wasDerivedFrom': 'http://sbols.org/v2#wasDerivedFrom'
'wasDerivedFrom': 'http://sbols.org/v2#wasDerivedFrom',
'type': 'http://sbols.org/v2#type'
}

function subjectIsValid (subject) {
Expand Down Expand Up @@ -39,6 +41,9 @@ function getDisplayString (type, object) {
case 'role':
let role = lookupRole(object)
return role.description.name || role.term || role.uri
case 'type':
let type = lookupType(object)
return type.description.name || type.term || type.uri
default:
return object
}
Expand All @@ -64,6 +69,7 @@ function serve (req, res) {
let subject = uri
let predicate = PREDICATES[field]
let object = req.body.object || ''
let previous = req.body.previous || ''

if (!subjectIsValid(subject)) {
res.sendStatus(403).end()
Expand All @@ -83,6 +89,7 @@ function serve (req, res) {
subject: subject,
predicate: predicate,
object: formatObject(object),
previous: formatObject(previous),
modified: modified
}

Expand Down
Loading

0 comments on commit d9be6e3

Please sign in to comment.