Skip to content
This repository has been archived by the owner on Jan 16, 2018. It is now read-only.

Commit

Permalink
[fix] contactListView
Browse files Browse the repository at this point in the history
  • Loading branch information
Noëlie Andrieu committed Jan 20, 2017
1 parent 557c641 commit 18a7feb
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 93 deletions.
15 changes: 8 additions & 7 deletions app/application.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ class Application extends Mn.Application
@model = new AppViewModel null, model: config

@contacts = new ContactsCollection()
@filtered = new FilteredCollection()
@filtered = new FilteredCollection {
contacts: @contacts
model: @model
channel: @channel
}

@tags = new TagsCollection @contacts

@layout = new AppLayout model: @model
Expand All @@ -50,14 +55,10 @@ class Application extends Mn.Application
onStart: ->
@layout.render()

callback = (models, collection) =>
console.log 'SUCCESS', models

@contacts.fetch {reset: true}, (models, collection) =>
# As long as Tags require Contacts to be loaded (see Tags.refs), we
# trigger all TagsCollection fetch after syncing ContactsCollection.
# @tags.underlying.fetch {reset: true}

@contacts.fetch {reset: true}, callback
@tags.underlying.fetch {reset: true}

# prohibit pushState because URIs mapped from cozy-home rely on
# fragment
Expand Down
64 changes: 55 additions & 9 deletions app/collections/contacts.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,61 @@ module.exports = class Contacts extends Backbone.Collection

@reset() if options.reset

cozy.init { isV2: true }
cozy.defineIndex 'io.cozy.contacts', ['id']
.then (index) =>
cozy.query index, { selector: id: {"$gte": " "} }
.then (result=[]) =>
@add result
success result
, (err) =>
success null, err
# FIXME: remove this fakeData
# when request will work
n = 'last name;first name;middle name;préfix;suffixe'
datapoints = []
datapoints.push {
id: "06",
name: "email",
value: "[email protected]",
type: "work"
}
datapoints.push {
id: "05",
name: "email",
value: "[email protected]",
type: "work"
}
datapoints.push {
id: "04",
name: "tel",
value: "0619384462",
type: "main"
}
datapoints.push {
id: "03",
name: "tel",
value: "0619384462",
type: "portable"
}
datapoints.push {
id: "02",
name: "tel",
value: "n0619384462",
type: "work"
}


result = []
result.push { n, datapoints }
result.push { n, datapoints }
result.push { n, datapoints }
result.push { n, datapoints }
result.push { n, datapoints }
#
@add result
success result, @

# cozy.init { isV2: true }
# cozy.defineIndex 'io.cozy.contacts', ['id']
# .then (index) =>
# cozy.query index, { selector: id: {"$gte": " "} }
# .then (result=[]) =>
# @add result
# success result, @
# , (err) =>
# success null, err



Expand Down
29 changes: 15 additions & 14 deletions app/collections/filtered.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ ContactViewModel = require 'views/models/contact'
{indexes, search} = require 'const-config'

tagRegExp = search.pattern 'tag'
app = null
scores = new Map()


Expand All @@ -30,25 +29,26 @@ module.exports = class FilteredCollection
query: null


constructor: ->
app = require 'application'
constructor: (options={}) ->
{ model, channel, contacts } = options
@app = { model, channel, contacts }

@models = []
@indexes = new Map Array::map.call indexes, (char) ->
vmodels = []
vmodels.channel = Backbone.Radio.channel "idx.#{char}"
[char, vmodels]

@listenTo app.model,
@listenTo @app.model,
'change:sort': @reset
'change:scored': (nil, scored) ->
@comparator = if scored
(a, b) -> (scores.get(b?.model) or 0) - scores.get(a.model)
else 'model.attributes.sortedName'

@listenTo app.channel, 'filter:text': @setQuery
@listenTo @app.channel, 'filter:text': @setQuery

@listenTo app.contacts,
@listenTo @app.contacts,
'reset': @reset
'add': @add
'remove': @remove
Expand All @@ -69,7 +69,7 @@ module.exports = class FilteredCollection
@query = query

if query
res = app.contacts.filter filter @query
res = @contacts.filter filter @query

# Reduce to get max score and get a median limit, then excludes all
# results $lt it.
Expand Down Expand Up @@ -103,7 +103,7 @@ module.exports = class FilteredCollection

get: (opts = {}) ->
base = if opts.index then @indexes.get(opts.index) else @models
tag = _.last app.model.get('filter')?.match tagRegExp
tag = _.last @app.model.get('filter')?.match tagRegExp

if tag and opts.tagged
base.filter (vmodel) -> _.includes vmodel.get('tags'), tag
Expand All @@ -114,9 +114,9 @@ module.exports = class FilteredCollection
# Internal models collection handlers
# ###################################
reset: ->
@models = app.contacts
@models = @app.contacts
.filter filter @query
.map (model) -> new ContactViewModel {}, model: model
.map (model) -> new ContactViewModel @app, { model }

@resetIndexes()

Expand All @@ -127,14 +127,15 @@ module.exports = class FilteredCollection
models = if _.isArray models then _.clone models else [models]

models.forEach (model) =>
return unless filter(@query, model)

vmodel = new ContactViewModel {}, model: model
return unless filter @query, model

vmodel = new ContactViewModel @app, { model }
idx = _.sortedIndex @models, vmodel, @comparator

@models.splice idx, 0, vmodel

@addToIndex vmodel

@trigger 'add', vmodel, @, {add:true, index: idx}


Expand Down Expand Up @@ -163,9 +164,9 @@ module.exports = class FilteredCollection

addToIndex: (vmodel, opts = {}) ->
set = @indexes.get vmodel.getIndexKey()

return vmodel if _.includes set, vmodel

# add model to collection
idx = _.sortedIndex set, vmodel, @comparator
set.splice idx, 0, vmodel

Expand Down
53 changes: 28 additions & 25 deletions app/models/contact.coffee
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
app = undefined


class Datapoint extends Backbone.Model

defaults:
Expand All @@ -25,9 +22,24 @@ module.exports = class Contact extends Backbone.Model
n: ';;;;'


constructor: (model, options={}) ->
options.parse = true
super model, options


initialize: ->
@AppViewModel = require('application').model
@listenTo @AppViewModel, 'change:sort': ->
@set 'sortedName': @_buildSortedName()


parse: (attrs) ->
datapoints = attrs.datapoints or []

# Remove empty values
delete attrs[key] for key, value of attrs when value is ''

# Get attrs from n property
if attrs.n
[gn, fn, ...] = attrs.n.split ';'
attrs.initials = _.chain [fn, gn]
Expand All @@ -47,20 +59,18 @@ module.exports = class Contact extends Backbone.Model
# following code.
if (url = attrs.url)
delete attrs.url
attrs.datapoints.unshift
datapoints.unshift
name: 'url'
type: 'main'
value: url

# Ensure Datapoints consistency
datapoints = @attributes.datapoints or
new Backbone.Collection attrs.datapoints or [],
model: Datapoint
parse: true
datapoints.comparator = 'name'
attrs.datapoints = datapoints
attrs.datapoints = new Backbone.Collection datapoints,
model: Datapoint
parse: true
attrs.datapoints.comparator = 'name'

attrs.tags = _.invoke attrs.tags, 'toLowerCase'
attrs.tags = _.invoke (attrs.tags or []), 'toLowerCase'

return attrs

Expand Down Expand Up @@ -89,12 +99,15 @@ module.exports = class Contact extends Backbone.Model
# Handle specific attributes.
attrs.fn = VCardParser.nToFN attrs.n.split ';'

datapoints = (attrs.datapoints?.toJSON() or [])
attrs.datapoints = datapoints.map (point) ->
datapoints = (attrs.datapoints or []).map (point) ->
if point.name is 'adr'
point.value = VCardParser.adrStringToArray point.value
return point

attrs.datapoints = new Backbone.Collection datapoints,
model: Datapoint
parse: true

# (legacy, see comments in "parse" function) The condition to decide if
# an e-mail address can be the main url is: it must be an url and it's
# mediatype is empty. Indeed if an url has a mediatype it means that
Expand Down Expand Up @@ -124,7 +137,7 @@ module.exports = class Contact extends Backbone.Model
# waits for cozy-client-js can handle this case
save: (options={}) ->
cozy.init { isV2: true }
cozy.create 'io.cozy.contacts', @attributes
cozy.create 'io.cozy.contacts', @toJSON()
.then (resp) =>
@attributes = resp
, () =>
Expand All @@ -134,7 +147,7 @@ module.exports = class Contact extends Backbone.Model
_buildSortedName: (n) ->
n ?= @get 'n'

sortKey = app.model.get 'sort'
sortKey = @AppViewModel?.get 'sort'
[gn, fn, mn, ...] = n.split ';'

_.chain if sortKey is 'fn' then [fn, mn, gn] else [gn, fn, mn]
Expand All @@ -143,16 +156,6 @@ module.exports = class Contact extends Backbone.Model
.value()


constructor: ->
app = require 'application'
super


initialize: ->
@listenTo app.model, 'change:sort': ->
@set 'sortedName': @_buildSortedName()


toString: (opts = {}) ->
[gn, fn, mn, pf, sf] = @attributes.n.split ';'
# wrap given name (at index 0) in pre/post tags if provided
Expand Down
7 changes: 3 additions & 4 deletions app/views/contacts/components/xtras.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ CONFIG = require('const-config').contact

module.exports = class ContactXtrasView extends Mn.ItemView

tagName: ->
if @model.get 'edit' then 'fieldset' else 'ul'

template: require 'views/templates/contacts/components/xtras'


tagName: -> if @model.get 'edit' then 'fieldset' else 'ul'


modelEvents: ->
_.reduce CONFIG.xtras, (memo, prop) ->
memo["change:#{prop}"] = (args...) ->
Expand All @@ -31,4 +31,3 @@ module.exports = class ContactXtrasView extends Mn.ItemView
ref = @model.get 'ref'
field = _.keys(model.changed)[0]
@$("##{field}-#{ref}").trigger 'focus'

10 changes: 7 additions & 3 deletions app/views/contacts/index.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ filtered = undefined

module.exports = class Contacts extends Mn.CompositeView

template: require 'views/templates/contacts'


sort: false


# backbone dom node dynamics are called before initialize, internal sets are
# so unavailable, so fallback to root method for detection
tagName: ->
Expand All @@ -23,11 +27,11 @@ module.exports = class Contacts extends Mn.CompositeView
else
'div'


attributes: ->
{model} = require 'application'
role: 'rowgroup' if model.get('scored') or @model?.has('char')

template: require 'views/templates/contacts'


events: ->
Expand All @@ -46,13 +50,13 @@ module.exports = class Contacts extends Mn.CompositeView
el.appendChild buffer


buildChildView: (child) ->
buildChildView: (model) ->
if @_hasContacts
ChildView = ContactRowView
else
ChildView = @constructor

new ChildView model: child
new ChildView { model }


showCollection: ->
Expand Down
Loading

0 comments on commit 18a7feb

Please sign in to comment.