Completed
Push — master ( 2455fe...15213d )
by Koen
11s
created

MatchesManager.js ➔ ... ➔ declare.getData   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 3
nop 0
dl 0
loc 31
rs 8.5806
c 0
b 0
f 0
1
define([
2
  'dojo/_base/declare',
3
  'dojo/_base/array',
4
  'dojo/_base/lang',
5
  'dojo/dom-construct',
6
  'dojo/dom-class',
7
  'dojo/dom-style',
8
  'dojo/json',
9
  'dojo/topic',
10
  'dojo/on',
11
  'dojo/promise/all',
12
  'dijit/_WidgetBase',
13
  'dijit/_TemplatedMixin',
14
  'dojo/text!./templates/MatchesManager.html',
15
  'dstore/Memory',
16
  'dstore/Trackable',
17
  'dgrid/OnDemandGrid',
18
  'dgrid/extensions/DijitRegistry',
19
  'dgrid/extensions/ColumnResizer',
20
  '../../utils/DomUtils',
21
  '../dialogs/AddMatchesDialog'
22
], function (
23
  declare,
24
  array,
25
  lang,
26
  domConstruct,
27
  domClass,
28
  domStyle,
29
  JSON,
30
  topic,
31
  on,
32
  all,
33
  _WidgetBase,
34
  _TemplatedMixin,
35
  template,
36
  Memory,
37
  Trackable,
38
  OnDemandGrid,
39
  DijitRegistry,
40
  ColumnResizer,
41
  DomUtils,
42
  AddMatchesDialog
43
) {
44
  return declare([_WidgetBase, _TemplatedMixin], {
45
46
    templateString: template,
47
    baseClass: 'matches-manager',
48
    languageController: null,
49
    listController: null,
50
    conceptSchemeController: null,
51
    concept: null,
52
    scheme: null,
53
    matchTypes: null,
54
    _loaded: false,
55
    _broadStore: null,
56
    _broadGrid: null,
57
    _narrowStore: null,
58
    _narrowGrid: null,
59
    _relatedStore: null,
60
    _relatedGrid: null,
61
    _exactStore: null,
62
    _exactGrid: null,
63
    _closeStore: null,
64
    _closeGrid: null,
65
    _index: 0,
66
    _matchesDialog: null,
67
68
    postCreate: function () {
69
      this.inherited(arguments);
70
      console.debug('RelationManager::postCreate');
71
      var TrackableMemory = declare([Memory, Trackable]);
72
73
      // init grids
74
      this._broadStore = new TrackableMemory({ data: [] });
75
      this._broadGrid = this._createGrid({
76
        collection: this._broadStore
77
      }, this.broadGridNode);
78
79
      this._narrowStore = new TrackableMemory({ data: [] });
80
      this._narrowGrid = this._createGrid({
81
        collection: this._narrowStore
82
      }, this.narrowGridNode);
83
84
      this._relatedStore = new TrackableMemory({ data: [] });
85
      this._relatedGrid = this._createGrid({
86
        collection: this._relatedStore
87
      }, this.relatedGridNode);
88
89
      this._exactStore = new TrackableMemory({ data: [] });
90
      this._exactGrid = this._createGrid({
91
        collection: this._exactStore
92
      }, this.exactGridNode);
93
94
      this._closeStore = new TrackableMemory({ data: [] });
95
      this._closeGrid = this._createGrid({
96
        collection: this._closeStore
97
      }, this.closeGridNode);
98
99
      if (this.concept && this.concept.matches) {
100
        this._loadMatches(this.concept.matches);
101
      }
102
103
      // load add dialog
104
      this._matchesDialog = new AddMatchesDialog({
105
        concept: this.concept,
106
        externalSchemeStore: this.conceptSchemeController.getExternalSchemeStore(),
107
        conceptSchemeController: this.conceptSchemeController,
108
        matchTypesList: this.listController.getMatchTypes()
109
      });
110
      this._matchesDialog.startup();
111
112
      this.own(
113
        on(this._matchesDialog, 'match.add', lang.hitch(this, function(evt) {
114
          this._addNewMatch(evt.match, evt.matchType);
115
        }))
116
      );
117
    },
118
119
    startup: function () {
120
      this.inherited(arguments);
121
      console.debug('RelationManager::startup');
122
      this._broadGrid.startup();
123
      this._narrowGrid.startup();
124
      this._relatedGrid.startup();
125
      this._exactGrid.startup();
126
      this._closeGrid.startup();
127
    },
128
129
    reset: function() {
130
      var TrackableMemory = declare([Memory, Trackable]);
131
      this._broadStore = new TrackableMemory({ data: [] });
132
      this._broadGrid.set('collection', this._broadStore);
133
      this._narrowStore = new TrackableMemory({ data: [] });
134
      this._narrowGrid.set('collection', this._narrowStore);
135
      this._relatedStore = new TrackableMemory({ data: [] });
136
      this._relatedGrid.set('collection', this._relatedStore);
137
      this._exactStore = new TrackableMemory({ data: [] });
138
      this._exactGrid.set('collection', this._exactStore);
139
      this._closeStore = new TrackableMemory({ data: [] });
140
      this._closeGrid.set('collection', this._closeStore);
141
142
      if (this._matchesDialog) { this._matchesDialog.reset(); }
143
    },
144
145
    _createGrid: function(options, node) {
146
      var columns = {
147
        label: {
148
          label: '',
149
          get: function(object) {
150
            return object.data.label;
151
          }
152
        },
153
        uri: {
154
          label: '',
155
          renderCell: function(object){
156
            if (object && object.data) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if object && object.data is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
157
              return domConstruct.create('a', { href: object.data.uri, target: '_blank', title: object.data.uri,
158
                innerHTML: '<i class="fa fa-external-link"></i>&nbsp;&nbsp;' + object.data.uri });
159
            }
160
          }
161
        },
162
        remove: {
163
          label: '',
164
          renderCell: lang.hitch(this, function (object) {
165
            if (object.id === undefined) {
166
              return null;
167
            }
168
            var div = domConstruct.create('div', {'class': 'dGridHyperlink'});
169
            domConstruct.create('a', {
170
              href: '#',
171
              title: 'Remove match',
172
              className: 'fa fa-trash',
173
              innerHTML: '',
174
              onclick: lang.hitch(this, function (evt) {
175
                evt.preventDefault();
176
                this._removeRow(object.id, object.type);
177
              })
178
            }, div);
179
            return div;
180
          })
181
        }
182
      };
183
184
      var grid = new (declare([OnDemandGrid, DijitRegistry, ColumnResizer]))({
185
        className: "dgrid-autoheight",
186
        collection: options.collection,
187
        columns: columns,
188
        showHeader: false,
189
        noDataMessage: '',
190
        loadingMessage: 'Fetching data..'
191
      }, node);
192
193
      grid.on('dgrid-error', function(event) {
194
        console.debug(event.error.message);
195
      });
196
197
      return grid;
198
    },
199
200
    setConcept: function(concept) {
201
      if (concept) {
202
        this.concept = concept;
203
        this.reset();
204
        if (this.concept.matches) {
205
          this._loadMatches(this.concept.matches);
206
        }
207
      }
208
    },
209
210
    _loadMatches: function(matches) {
211
      if (matches) {
212
        var promises = [];
213
        this.loadingMatchesNode.style.display = 'inline-block';
214
        if (matches.broad) {
215
          array.forEach(matches.broad, function (match) {
216
            promises.push(this.conceptSchemeController.getMatch(match, 'broad').then(lang.hitch(this, function (matched) {
217
              this._addMatch(matched, this._broadStore);
218
            })));
219
          }, this);
220
        }
221
        if (matches.close) {
222
          array.forEach(matches.close, function (match) {
223
            promises.push(this.conceptSchemeController.getMatch(match, 'close').then(lang.hitch(this, function (matched) {
224
              this._addMatch(matched, this._closeStore);
225
            })));
226
          }, this);
227
        }
228
        if (matches.exact) {
229
          array.forEach(matches.exact, function (match) {
230
            promises.push(this.conceptSchemeController.getMatch(match, 'exact').then(lang.hitch(this, function (matched) {
231
              this._addMatch(matched, this._exactStore);
232
            })));
233
          }, this);
234
        }
235
        if (matches.narrow) {
236
          array.forEach(matches.narrow, function (match) {
237
            promises.push(this.conceptSchemeController.getMatch(match, 'narrow').then(lang.hitch(this, function (matched) {
238
              this._addMatch(matched, this._narrowStore);
239
            })));
240
          }, this);
241
        }
242
        if (matches.related) {
243
          array.forEach(matches.related, function (match) {
244
            promises.push(this.conceptSchemeController.getMatch(match, 'related').then(lang.hitch(this, function (matched) {
245
              this._addMatch(matched, this._relatedStore);
246
            })));
247
          }, this);
248
        }
249
250
        all(promises).then(lang.hitch(this, function(res) {
0 ignored issues
show
Unused Code introduced by
The parameter res is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
251
          this.loadingMatchesNode.style.display = 'none';
252
          this._loaded = true;
253
        }));
254
      }
255
    },
256
257
    getData: function() {
258
      var data = {};
259
260
      if (this._loaded) {
261
        var matches = {};
262
        matches.narrow = array.map(this._narrowStore.data, function (item) {
263
          return item.data.uri;
264
        });
265
        matches.broad = array.map(this._broadStore.data, function (item) {
266
          return item.data.uri;
267
        });
268
        matches.related = array.map(this._relatedStore.data, function (item) {
269
          return item.data.uri;
270
        });
271
        matches.close = array.map(this._closeStore.data, function (item) {
272
          return item.data.uri;
273
        });
274
        matches.exact = array.map(this._exactStore.data, function (item) {
275
          return item.data.uri;
276
        });
277
        data.matches = matches;
278
      } else { // when not all matches are loaded into store => return existing matches
279
        if (this.concept && this.concept.matches) {
280
          data.matches = this.concept.matches;
281
        } else {
282
          data.matches = [];
283
        }
284
      }
285
286
      return data;
287
    },
288
289
    _addNewMatch: function(match, matchtype) {
290
      var store = null;
0 ignored issues
show
Unused Code introduced by
The assignment to store seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
291
292
      switch(matchtype) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
293
        case 'broad': store = this._broadStore;
294
          break;
295
        case 'narrow': store = this._narrowStore;
296
          break;
297
        case 'related': store = this._relatedStore;
298
          break;
299
        case 'close': store = this._closeStore;
300
          break;
301
        case 'exact': store = this._exactStore;
302
          break;
303
      }
304
305
      if (match && store) {
306
        var formatMatch = {
307
          data: {
308
            id: match.id,
309
            label: match.label,
310
            uri: match.uri
311
          },
312
          type: match.type
313
        };
314
        this._addMatch(formatMatch, store);
315
      }
316
    },
317
318
    _addMatch: function(match, store) {
319
      var found = array.some(store.data, function (item) {
320
        return item.data.id == match.data.id;
321
      });
322
      if (!found) {
323
        store.add(match);
324
        return true;
325
      }
326
      return false;
327
    },
328
329
    _addMatches: function(evt) {
330
      evt ? evt.preventDefault() : null;
331
      // open dialog
332
      this._matchesDialog.show();
333
    },
334
335
    _removeRow: function(rowId, type) {
336
      var store = null;
0 ignored issues
show
Unused Code introduced by
The assignment to store seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
337
      switch(type) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
338
        case 'broad': store = this._broadStore;
339
          break;
340
        case 'close': store = this._closeStore;
341
          break;
342
        case 'exact': store = this._exactStore;
343
          break;
344
        case 'narrow': store = this._narrowStore;
345
          break;
346
        case 'related': store = this._relatedStore;
347
          break;
348
      }
349
      if (store) {
350
        store.remove(rowId);
351
      }
352
    }
353
  });
354
});