@@ -63,6 +63,7 @@ export class PeoplePicker {
6363 . then ( ( { groupNode, graphNode} ) => {
6464 new GroupBuilder (
6565 this . element ,
66+ bookBaseUrl ,
6667 graphNode ,
6768 groupNode ,
6869 this . onSelectGroup
@@ -133,10 +134,19 @@ export class PeoplePicker {
133134 // might fail.
134135 const patchPromises = [ graphNode , groupIndexNode ]
135136 . map ( namedGraph => {
136- const typeStatement = rdf . st ( groupNode , ns . rdf ( 'type' ) , ns . vcard ( 'Group' ) , namedGraph )
137- const nameStatement = rdf . st ( groupNode , ns . vcard ( 'fn' ) , 'Untitled Group' , namedGraph )
138- return webClient . patch ( namedGraph . value , [ ] , [ typeStatement , nameStatement ] )
139- . then ( ( ) => kb . add ( [ typeStatement , nameStatement ] ) )
137+ const typeStatement = rdf . st ( groupNode , ns . rdf ( 'type' ) , ns . vcard ( 'Group' ) )
138+ const nameStatement = rdf . st ( groupNode , ns . vcard ( 'fn' ) , rdf . literal ( 'Untitled Group' ) )
139+ const includesGroupStatement = rdf . st ( rdf . namedNode ( `${ bookBaseUrl } book.ttl#this` ) , ns . vcard ( 'includesGroup' ) , groupNode )
140+ const toIns = namedGraph . equals ( groupIndexNode )
141+ ? [ typeStatement , nameStatement , includesGroupStatement ]
142+ : [ typeStatement , nameStatement ]
143+ return patch ( namedGraph . value , { toIns} )
144+ . then ( ( ) => {
145+ toIns . forEach ( st => {
146+ st . why = namedGraph
147+ kb . add ( st )
148+ } )
149+ } )
140150 } )
141151 return Promise . all ( patchPromises )
142152 . then ( ( ) => ( { groupNode, graphNode} ) )
@@ -224,8 +234,9 @@ export class Group {
224234}
225235
226236export class GroupBuilder {
227- constructor ( element , groupGraph , groupNode , doneBuildingCb , groupChangedCb ) {
237+ constructor ( element , bookBaseUrl , groupGraph , groupNode , doneBuildingCb , groupChangedCb ) {
228238 this . element = element
239+ this . bookBaseUrl = bookBaseUrl
229240 this . groupGraph = groupGraph
230241 this . groupNode = groupNode
231242 this . onGroupChanged = ( err , changeType , agent ) => {
@@ -263,8 +274,13 @@ export class GroupBuilder {
263274 const groupNameInput = document . createElement ( 'input' )
264275 groupNameInput . type = 'text'
265276 groupNameInput . value = getWithDefault ( this . groupNode , ns . vcard ( 'fn' ) , 'Untitled Group' )
266- groupNameInput . addEventListener ( 'input ' , event => {
277+ groupNameInput . addEventListener ( 'change ' , event => {
267278 this . setGroupName ( event . target . value )
279+ . catch ( err => {
280+ this . element . appendChild (
281+ errorMessageBlock ( document , `Error changing group name. (${ err } )` )
282+ )
283+ } )
268284 } )
269285 const groupNameLabel = document . createElement ( 'label' )
270286 groupNameLabel . textContent = escape ( 'Group Name:' )
@@ -316,12 +332,13 @@ export class GroupBuilder {
316332 return resolve ( webIdNode )
317333 } )
318334 } ) . then ( webIdNode => {
319- const statement = rdf . st ( this . groupNode , ns . vcard ( 'hasMember' ) , webIdNode , this . groupGraph )
335+ const statement = rdf . st ( this . groupNode , ns . vcard ( 'hasMember' ) , webIdNode )
320336 if ( kb . holdsStatement ( statement ) ) {
321337 return webIdNode
322338 }
323- return webClient . patch ( this . groupGraph . value , [ ] , [ statement ] )
339+ return patch ( this . groupGraph . value , { toIns : [ statement ] } )
324340 . then ( ( ) => {
341+ statement . why = this . groupGraph
325342 kb . add ( statement )
326343 this . onGroupChanged ( null , 'added' , webIdNode )
327344 this . render ( )
@@ -331,8 +348,8 @@ export class GroupBuilder {
331348
332349 handleRemove ( webIdNode ) {
333350 return event => {
334- const statement = rdf . st ( this . groupNode , ns . vcard ( 'hasMember' ) , webIdNode , this . groupGraph )
335- return webClient . patch ( this . groupGraph . value , [ statement ] , [ ] )
351+ const statement = rdf . st ( this . groupNode , ns . vcard ( 'hasMember' ) , webIdNode )
352+ return patch ( this . groupGraph . value , { toDel : [ statement ] } )
336353 . then ( ( ) => {
337354 kb . remove ( statement )
338355 this . onGroupChanged ( null , 'removed' , webIdNode )
@@ -350,11 +367,20 @@ export class GroupBuilder {
350367 }
351368
352369 setGroupName ( name ) {
353- kb . match ( this . groupNode , ns . vcard ( 'fn' ) ) . forEach ( st => {
354- kb . remove ( st )
355- kb . add ( this . groupNode , ns . vcard ( 'fn' ) , rdf . literal ( name ) , st . why )
356- // TODO: sync
357- } )
370+ // TODO: refactor this bookmark footprint URL logic into a helper function, only pass `bookBaseUrl` between components
371+ const groupIndexUrl = `${ this . bookBaseUrl } groups.ttl`
372+ const updatePromises = [ this . groupGraph , rdf . namedNode ( groupIndexUrl ) ]
373+ . map ( namedGraph => {
374+ const oldNameStatements = kb . match ( this . groupNode , ns . vcard ( 'fn' ) , null , namedGraph )
375+ const newNameStatement = rdf . st ( this . groupNode , ns . vcard ( 'fn' ) , rdf . literal ( name ) )
376+ return patch ( namedGraph . value , { toDel : oldNameStatements , toIns : [ newNameStatement ] } )
377+ . then ( solidResponse => {
378+ kb . removeStatements ( oldNameStatements )
379+ newNameStatement . why = namedGraph
380+ kb . add ( newNameStatement )
381+ } )
382+ } )
383+ return Promise . all ( updatePromises )
358384 }
359385}
360386
@@ -407,3 +433,15 @@ function getWithDefault (subject, predicate, defaultValue) {
407433 const object = kb . any ( subject , predicate )
408434 return object ? object . value : defaultValue
409435}
436+
437+ function patch ( url , { toDel, toIns} ) {
438+ return webClient . patch ( url , toDel , toIns )
439+ . then ( solidResponse => {
440+ const status = solidResponse . xhr . status
441+ if ( status < 200 || status >= 400 ) {
442+ const err = new Error ( `PATCH failed for resource <${ solidResponse . url } >` )
443+ err . solidResponse = solidResponse
444+ throw err
445+ }
446+ } )
447+ }
0 commit comments