// Generated by CoffeeScript 1.12.7
/**
* Data spreadsheet
* @module
*/
'use strict';
var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
app.directive('spreadsheet', [
'constantService', 'displayService', 'messageService', 'tooltipService', 'styleService', '$compile', '$templateCache', '$timeout', '$document', '$location', '$filter', '$route', 'routerService', 'storageService', 'Segment', function(constants, display, messages, tooltips, styles, $compile, $templateCache, $timeout, $document, $location, $filter, $route, router, storage, Segment) {
return {
restrict: 'E',
scope: true,
templateUrl: 'volume/spreadsheet.html',
controller: [
'$scope', '$element', '$attrs', function($scope, $element, $attrs) {
var Birthdate, Cats, Cols, Editing, Expanded, Groups, ID, Info, Key, Limit, Order, Row, Rows, SlotCount, TBody, TFoot, addRow, arr, base, base1, byDefault, byMagic, byNumber, bySortId, byType, clickGlobal, clickRemove, collapse, createNew, createRecord, createSlot, currentSort, currentSortDirection, doneEdit, edit, editCell, editCellTemplate, editInput, editScope, editSelect, expand, fill, generateAdd, generateFoot, generateMultiple, generateRecord, generateRow, generateText, getCategory, getMetric, inc, maybeInt, obj, optionCompletions, parseId, parseIntish, pivotOpts, populateAssetData, populateCols, populateRecord, populateRecordData, populateRecords, populateSlot, populateSlotData, populateSlots, pseudoCategory, pseudoMetric, recordDescription, ref, removeRecord, removeRow, removeSlot, save, saveDatum, saveRun, select, setFilter, setFocus, setKey, setRecord, sort, sortBy, stripPrefix, unedit, unselect, updateDatum, volume;
volume = $scope.volume;
Editing = $scope.editing = $attrs.edit !== void 0;
ID = $scope.id = (ref = $attrs.id) != null ? ref : 'ss';
$scope.showGlobal = false;
Limit = $attrs.limit || 2e308;
Key = void 0;
maybeInt = function(s) {
var i;
if (isNaN(i = parseInt(s, 10))) {
return s;
} else {
return i;
}
};
byDefault = function(a, b) {
return +(a > b) || +(a === b) - 1;
};
byNumber = function(a, b) {
return a - b;
};
byType = function(a, b) {
var ta, tb;
ta = typeof a;
tb = typeof b;
if (ta !== tb) {
a = ta;
b = tb;
}
return byDefault(a, b);
};
byMagic = function(a, b) {
var d;
if (isNaN(d = a - b)) {
return byType(a, b);
} else {
return d;
}
};
bySortId = function(a, b) {
return (a.sort || a.id) - (b.sort || b.id);
};
parseIntish = function(c) {
var i;
if (isNaN(i = parseInt(c, 10))) {
return c;
} else {
return i;
}
};
stripPrefix = function(s, prefix) {
if (s.startsWith(prefix)) {
return s.substr(prefix.length);
}
};
arr = function(a, f) {
if (f in a) {
return a[f];
} else {
return a[f] = [];
}
};
obj = function(a, f) {
if (f in a) {
return a[f];
} else {
return a[f] = {};
}
};
inc = function(a, f) {
if (f in a) {
return a[f]++;
} else {
a[f] = 1;
return 0;
}
};
Birthdate = constants.categoryName.participant.metricName.birthdate;
pseudoMetric = {
indicator: {
id: 'indicator',
name: 'indicator',
type: 'void',
sort: 0,
assumed: true
},
top: {
id: 'top',
category: 'slot',
name: 'type',
type: 'top',
sort: 1,
options: {
"false": 'session',
"true": 'materials'
}
},
name: {
id: 'name',
name: 'name',
type: 'text',
sort: 2
},
date: {
id: 'date',
category: 'slot',
name: 'test date',
type: 'date',
description: 'Date on which this session was acquired',
sort: 3
},
release: {
id: 'release',
category: 'slot',
name: 'release',
type: 'release',
description: 'Level of data release to which depicted participant(s) consented',
sort: 4
},
age: {
id: 'age',
category: Birthdate.category.id,
name: 'age',
type: 'age',
release: constants.release.EXCERPTS,
sort: Birthdate.id + 0.5,
description: 'Time between birthdate and test date',
readonly: true
},
summary: {
id: 'summary',
category: 'slot',
name: 'summary',
type: 'text',
sort: 2e308,
readonly: true
}
};
constants.deepFreeze(pseudoMetric);
getMetric = function(m) {
return pseudoMetric[m] || constants.metric[m];
};
pseudoCategory = {
slot: {
id: 'slot',
name: 'folder',
not: 'No folders',
template: ['top', 'name', 'date', 'release'],
fixed: true
},
asset: {
id: 'asset',
name: 'file',
not: 'No files',
template: ['name'],
description: 'Files included in this folder',
fixed: true
}
};
constants.deepFreeze(pseudoCategory);
getCategory = function(c) {
return pseudoCategory[c] || constants.category[c];
};
/*
* We use the following types of data structures:
* Row = index of slot in slots and rows (i)
* Slot_id = Database id of container
* Record_id = Database id of record
* Category_id = Database id of record category (c)
* Count = index of record within category for slot (n)
* Metric_id = Database id of metric, or "id" for Record_id, or "age" (m)
*/
TBody = $element[0].getElementsByTagName("tbody")[0];
TFoot = $element[0].getElementsByTagName("tfoot")[0];
Groups = [];
Cols = [];
Rows = [];
Cats = {};
Order = [];
Expanded = void 0;
SlotCount = 0;
/**
* Row in spreadsheet with the following properties: <br />
* <blockquote> i: Row index <br />
* tr: DOM Element tr <br />
* [Category_id]: (array of) metric data for category </blockquote>
* @interface spreadsheet/Row
*/
Row = (function() {
function Row(i) {
this.i = i != null ? i : Rows.length;
Rows[this.i] = this;
this.filt = true;
return;
}
Row.prototype.add = function(c, d) {
var n, v;
Cats[c] = true;
if (v = this[c]) {
if (Array.isArray(v)) {
n = v.push(d) - 1;
} else {
this[c] = [v, d];
n = 1;
}
} else {
this[c] = d;
n = 0;
}
return n;
};
Row.prototype.list = function(c) {
var v;
if (v = this[c]) {
if (Array.isArray(v)) {
return v;
} else {
return [v];
}
} else {
return [];
}
};
Row.prototype.count = function(c) {
var v;
if (v = this[c]) {
if (Array.isArray(v)) {
return v.length;
} else {
return 1;
}
} else {
return 0;
}
};
Row.prototype.get = function(c, n) {
var v;
if (v = this[c]) {
if (Array.isArray(v)) {
return v[n || 0];
} else if (!n) {
return v;
}
}
};
Row.prototype.set = function(c, n, d) {
n || (n = 0);
if (n || Array.isArray(this[c])) {
if (d != null) {
this[c].splice(n, 1, d);
} else {
this[c].splice(n, 1);
}
} else {
this[c] = d;
}
};
Object.defineProperty(Row.prototype, 'key', {
get: function() {
return this.get(Key.id);
}
});
return Row;
})();
/**
* Cell in spreadsheet with the following properties: <br />
* <blockquote>cell: target TD element <br />
* id: cell.id <br />
* i: Row <br />
* n: Count (index of count), optional [0] <br />
* m: index into Cols <br />
* cols: Groups element <br />
* col: Cols element <br />
* category: Category <br />
* c: Category_id <br />
* count: Count[i][c] <br />
* metric: Metric <br />
* row: Rows[i] <br />
* slot: Container <br />
* d: Data <br />
* record: Record <br />
* asset: Asset <br />
* v: Data value </blockquote>
* @interface spreadsheet/Info
*/
Info = (function() {
var f, properties, property, v;
function Info(x) {
if (typeof x === 'number') {
this.i = x;
} else if (x) {
this.cell = x;
}
this.parseId();
return;
}
Info.prototype.parseId = function(i) {
var s;
if (!((i != null ? this.id = i : i = this.id) && (i = stripPrefix(i, ID + '-')))) {
return;
}
s = i.split('_');
switch (s[0]) {
case 'add':
case 'more':
case 'no':
this.t = s[0];
this.i = parseInt(s[1], 10);
this.c = parseIntish(s[2]);
break;
case 'metric':
this.t = s[0];
this.m = parseInt(s[1], 10);
break;
case 'category':
this.t = s[0];
this.c = parseIntish(s[1]);
break;
default:
this.i = parseInt(s[0], 10);
this.m = parseInt(s[1], 10);
if (2 in s) {
this.n = parseInt(s[2], 10);
}
}
return true;
};
properties = {
n: function() {
return 0;
},
id: function() {
var ref1;
return (ref1 = this.cell) != null ? ref1.id : void 0;
},
cols: function() {
var c;
c = this.c;
return this.cols = Groups.find(function(col) {
return col.category.id == c;
});
},
col: function() {
return Cols[this.m];
},
category: function() {
var c;
if ((c = this.col) != null) {
return c.category;
} else if (this.hasOwnProperty('c')) {
return this.category = getCategory(this.c);
}
},
c: function() {
var ref1;
return (ref1 = this.category) != null ? ref1.id : void 0;
},
metric: function() {
var ref1;
return (ref1 = this.col) != null ? ref1.metric : void 0;
},
row: function() {
return Rows[this.i];
},
count: function() {
return this.row.count(this.c);
},
tr: function() {
return this.row.tr;
},
d: function() {
return this.row.get(this.c, this.n);
},
p: function() {
var c, cls;
cls = 'ss-';
if (typeof (c = this.c) !== 'number') {
cls += c.charAt(0);
}
return cls;
},
slot: function() {
var ref1;
return (ref1 = this.row.get('slot', this.c === 'slot' ? this.n : void 0)) != null ? ref1.slot : void 0;
},
record: function() {
var ref1;
return (ref1 = this.d) != null ? ref1.record : void 0;
},
asset: function() {
var ref1;
return (ref1 = this.d) != null ? ref1.asset : void 0;
},
v: function() {
var d, m;
if ((d = this.d) && (m = this.metric)) {
return d[m.id];
}
}
};
property = function(v, f) {
return {
get: f,
set: function(x) {
Object.defineProperty(this, v, {
value: x,
writable: true,
configureable: true,
enumerable: true
});
}
};
};
for (v in properties) {
f = properties[v];
properties[v] = property(v, f);
}
Object.defineProperties(Info.prototype, properties);
return Info;
})();
parseId = function(el) {
var info;
if (el.tagName !== 'TD') {
return;
}
info = new Info(el);
if (info.c != null) {
return info;
}
};
/**
* Populate data structures and fill Cols and Groups from volume metrics
* @interface spreadsheet/populateCols
*/
populateCols = function(slot) {
var all, cats, i, partindex;
Cols = [];
all = Object.keys(volume.metrics).sort(byNumber).map(function(i) {
return constants.category[i];
});
if (slot) {
slot = void 0;
cats = all.filter(function(c) {
var ref1;
return $scope.showGlobal || ((ref1 = Cats[c.id]) != null ? ref1 : Editing);
});
cats.unshift(pseudoCategory.asset);
cats.unshift(pseudoCategory.slot);
$scope.anyGlobal = all.some(function(c) {
return Cats[c.id] === false;
});
} else {
slot = [pseudoMetric.summary];
cats = [Key, pseudoCategory.slot];
$scope.anyGlobal = false;
}
$scope.groups = Groups = cats.map(function(category) {
var l, metrics, si;
metrics = (category.template || volume.metrics[category.id]).map(getMetric);
if (!Editing && indexOf.call(metrics, Birthdate) >= 0) {
(slot || metrics).push(pseudoMetric.age);
}
if (slot && category.id === 'slot') {
metrics.push.apply(metrics, slot);
}
metrics.sort(bySortId);
si = Cols.length;
Cols.push.apply(Cols, metrics.map(function(m) {
return {
category: category,
metric: m
};
}));
l = metrics.length;
Cols[si].first = Cols[si + l - 1].last = l;
return {
category: category,
metrics: metrics,
start: si
};
});
$scope.cols = Cols;
$scope.views = all;
partindex = false;
i = 0;
while (i < $scope.views.length) {
if ($scope.views[i].name === 'participant') {
partindex = true;
}
i++;
}
if (!Editing || partindex === false) {
$scope.views.unshift(pseudoCategory.slot);
} else {
$scope.views.splice(1, 0, pseudoCategory.slot);
}
};
populateSlotData = function(s) {
var d, ref1;
d = {
slot: s,
id: s.id,
top: s.top || false,
name: s.name,
date: s.date,
release: (ref1 = s.release) != null ? ref1 : -1
};
if (s.top === 'global') {
d.global = true;
d.summary = constants.message('global.name') + " (only displayed in volume description)";
}
return d;
};
populateRecordData = function(r) {
var d;
d = Object.create(r.measures);
d.record = r;
d.id = r.id;
return d;
};
populateAssetData = function(a) {
var d;
d = {
asset: a,
id: a.id,
name: a.name
};
return d;
};
/**
* Fill all Data values for Row i
* @interface spreadsheet/populateSlot
*/
populateSlot = function(slot) {
var asset, assetId, d, len, p, record, ref1, ref2, row, rr;
row = new Row();
row.add('slot', populateSlotData(slot));
ref1 = slot.records;
for (p = 0, len = ref1.length; p < len; p++) {
rr = ref1[p];
if (!((record = rr.record))) {
continue;
}
d = populateRecordData(record);
if ('age' in rr) {
d.age = rr.age;
}
row.add(record.category, d);
}
ref2 = slot.assets;
for (assetId in ref2) {
asset = ref2[assetId];
row.add('asset', populateAssetData(asset));
}
return row;
};
populateSlots = function() {
var ci, len, name1, p, record, ref1, ref2, results, rr, slot;
SlotCount = -1;
ref1 = volume.containers;
results = [];
for (ci in ref1) {
slot = ref1[ci];
SlotCount++;
if (slot.top === 'global') {
ref2 = slot.records;
for (p = 0, len = ref2.length; p < len; p++) {
rr = ref2[p];
if (!((record = rr.record))) {
continue;
}
record.global = true;
Cats[name1 = record.category] || (Cats[name1] = false);
}
continue;
}
results.push(populateSlot(slot));
}
return results;
};
populateRecord = function(record) {
var row;
row = new Row();
row.add(record.category, populateRecordData(record));
return row;
};
populateRecords = function() {
var any, ci, d, len, nog, nor, p, r, record, records, recs, ref1, ref2, row, rr, rrr, slot;
records = {};
nog = void 0;
ref1 = volume.records;
for (r in ref1) {
record = ref1[r];
if (!(record.category === Key.id)) {
continue;
}
if (nog) {
nog++;
} else {
nog = 1;
}
delete record.global;
records[r] = populateRecord(record);
}
SlotCount = -1;
nor = void 0;
ref2 = volume.containers;
for (ci in ref2) {
slot = ref2[ci];
SlotCount++;
recs = slot.records;
any = false;
for (p = 0, len = recs.length; p < len; p++) {
rr = recs[p];
if (!((row = records[rr.id]))) {
continue;
}
d = populateSlotData(slot);
if ('age' in rr) {
d.age = rr.age;
}
if (d.global) {
if (!rr.record.global) {
rr.record.global = true;
nog--;
}
row.partial = true;
} else {
d.summary = ((function() {
var len1, q, results;
results = [];
for (q = 0, len1 = recs.length; q < len1; q++) {
rrr = recs[q];
if (rrr.id !== rr.id) {
results.push(rrr.record.displayName);
}
}
return results;
})()).join(', ');
row.partial || (row.partial = !Segment.isFull(rr.segment));
}
row.add('slot', d);
any = true;
}
if (!(any || slot.top === 'global')) {
nor || (nor = new Row());
d = populateSlotData(slot);
d.summary = ((function() {
var len1, q, results;
results = [];
for (q = 0, len1 = recs.length; q < len1; q++) {
rrr = recs[q];
results.push(rrr.record.displayName);
}
return results;
})()).join(', ');
nor.add('slot', d);
}
}
if (nog === 0 && nor) {
return delete Rows[nor.i];
}
};
/**
* Generate HTML and add or replace the text contents of cell c for measure/type m with value v
* @interface spreadsheet/generateText
*/
generateText = function(info) {
var a, asset, cell, cls, cn, del, delicon, icon, slot, t, v;
$(cell = info.cell).empty();
cell.className = '';
v = info.v;
slot = info.slot;
if (info.col.first && info.d) {
if (info.c === 'asset') {
cell.classList.add('clickable');
cell.onclick = function(event) {
return $location.url(Editing ? slot.editRoute(t) : slot.route(t));
};
a = cell.appendChild(document.createElement('a'));
icon = a.appendChild(document.createElement('img'));
asset = info.asset;
icon.src = asset.icon;
icon.className = "format hint-format-" + asset.format.extension;
t = {
asset: asset.id
};
a.setAttribute('href', Editing ? slot.editRoute(t) : slot.route(t));
icon = cell.appendChild(document.createElement('span'));
icon.className = 'icon release ' + constants.release[asset.release] + ' hint-release-' + constants.release[asset.release];
} else {
if (Editing && Key.id === info.c) {
cell.classList.add('folder-type');
cell.classList.add('clickable');
del = cell.appendChild(document.createElement('a'));
del.className = 'clickable trash icon';
$(del).on('click', $scope.$lift(clickRemove));
}
if (info.c === 'slot') {
a = cell.appendChild(document.createElement('a'));
a.className = "session icon hint-action-slot";
a.setAttribute('href', Editing ? slot.editRoute() : slot.route());
}
}
}
switch (info.metric.id) {
case 'name':
if (v == null) {
v = '';
}
break;
case 'release':
if (v >= 0 || !(slot != null ? slot.top : void 0)) {
cn = constants.release[v];
cell.className = cn + ' release icon hint-release-' + cn;
}
if (slot != null ? slot.top : void 0) {
cell.classList.add('null');
}
v = '';
break;
case 'date':
if (slot != null ? slot.top : void 0) {
cell.classList.add('null');
}
break;
case 'age':
v = display.formatAge(v);
break;
case 'top':
if (v != null) {
v = info.metric.options[v];
} else if (Editing && info.col.first) {
cell.classList.add('add');
cell.classList.add('button');
v = 'add folder';
}
break;
case 'summary':
if (info.d.global && Editing) {
cell.classList.add('spreadsheet-global-record-cell');
del = cell.appendChild(document.createElement('a'));
del.className = 'button mini global-record white icon-text';
delicon = del.appendChild(document.createElement('span'));
delicon.className = 'icon trash';
del.appendChild(document.createTextNode('Remove'));
$(del).on('click', $scope.$lift(clickGlobal));
}
break;
default:
if (info.metric.type === 'void' && info.d) {
if (Editing && Key.id !== info.c) {
cell.className = 'clickable';
}
v = info.metric.name;
}
}
if (info.metric.long) {
cell.classList.add('long');
}
if (v != null) {
cell.classList.remove('blank');
} else {
cell.classList.add('blank');
v = info.metric.assumed || '';
}
cell.appendChild(document.createTextNode(v));
cell.id = info.id;
if (info.d) {
cell.classList.add(cls = info.p + info.d.id);
cell.classList.add(cls + '_' + info.metric.id);
}
};
generateAdd = function(info, td) {
var width;
info.m = info.cols.start;
width = info.width || info.cols.metrics.length;
if (info.metric.type === 'top' || typeof info.metric.id === 'number' && info.metric.type !== 'void') {
info.id = ID + '-' + info.i + '_' + info.cols.start + (info.hasOwnProperty('n') ? '_' + info.n : '');
info.cell = info.tr.appendChild(document.createElement('td'));
generateText(info);
info.tr.insertBefore(info.cell, td);
if (width > 1) {
td.setAttribute("colspan", width - 1);
td.classList.add('prompt');
if (info.c !== 'slot') {
return td.appendChild(document.createTextNode("\u2190 add " + info.category.name));
}
} else {
return info.tr.removeChild(td);
}
} else {
td.setAttribute("colspan", width);
td.classList.add('add');
td.classList.add('clickable');
td.id = ID + '-add_' + info.i + '_' + info.c;
return td.appendChild(document.createTextNode(Editing && info.metric.type !== 'void' ? "add " + info.category.name : info.category.not));
}
};
generateMultiple = function(info) {
var add, addicon, t, td, width;
t = info.count;
if ((info.hasOwnProperty('n') ? info.n < t : t === 1)) {
return;
}
td = info.tr.appendChild(document.createElement('td'));
width = info.cols.metrics.length;
td.setAttribute("colspan", width);
if (info.hasOwnProperty('n') || t <= 1) {
td.className = 'null';
if (!info.n || info.n === t) {
if (Editing && info.c !== 'slot' && info.c !== Key.id) {
generateAdd(info, td);
} else if (!info.n) {
td.appendChild(document.createTextNode(info.category.not));
if (Editing && info.c === 'slot' && Key.id !== 'slot' && Key.id !== 1) {
td.classList.add('spreadsheet-global-record-cell');
add = td.appendChild(document.createElement('a'));
add.className = 'button mini white global-record icon-text';
addicon = add.appendChild(document.createElement('span'));
addicon.className = 'add icon';
add.appendChild(document.createTextNode('Apply to whole volume'));
$(add).on('click', $scope.$lift(clickGlobal));
}
td.id = ID + '-no_' + info.i + '_' + info.c;
}
}
} else {
td.className = 'more';
td.id = ID + '-more_' + info.i + '_' + info.c;
if (Editing && info.c === 'slot' && Key.id !== 'slot' && t === SlotCount && !info.row.partial && info.row.key) {
td.classList.add('spreadsheet-global-record-cell');
add = td.appendChild(document.createElement('a'));
add.className = 'button mini yellow global-record icon-text hint-action-globalrecord';
add.appendChild(document.createTextNode('Convert to ' + constants.message('global.name').toLowerCase() + ' (irreversible)'));
$(add).on('click', $scope.$lift(clickGlobal));
}
td.appendChild(document.createTextNode(t + " " + info.category.name + "s"));
}
return td;
};
/**
* Add all the measure tds to row i for count n, record r
* @interface spreadsheet/generateRecord
*/
generateRecord = function(info) {
var cls, generateCell, l, mi, n, p, post, pre, q, ref1, ref2, td;
if (!(l = info.cols.metrics.length)) {
return;
}
if (td = generateMultiple(info)) {
if (!info.hasOwnProperty('n')) {
cls = info.p;
for (n = p = 0, ref1 = info.count - 1; p <= ref1; n = p += 1) {
td.classList.add(cls + info.row.get(info.c, n).id);
}
}
return;
}
pre = ID + '-' + info.i + '_';
post = info.hasOwnProperty('n') ? '_' + info.n : '';
generateCell = function(i) {
info.m = info.cols.start + i;
info.id = pre + info.m + post;
info.cell = info.tr.appendChild(document.createElement('td'));
generateText(info);
};
if (info.category.id === 'slot' && info.d.global) {
generateCell(l - 1);
info.cell.setAttribute("colspan", l);
return;
}
for (mi = q = 0, ref2 = l - 1; q <= ref2; mi = q += 1) {
generateCell(mi);
}
};
/**
* Fill out Rows[i].
* @interface spreadsheet/generateRow
*/
generateRow = function(i) {
var col, info, len, p, row, tr;
info = new Info(i);
row = info.row;
if (row.tr) {
$(row.tr).empty();
row.tr;
} else {
row.tr = document.createElement('tr');
}
tr = row.tr;
tr.id = ID + '_' + i;
tr.data = i;
for (p = 0, len = Groups.length; p < len; p++) {
col = Groups[p];
info.category = (info.cols = col).category;
generateRecord(info);
}
};
generateFoot = function() {
var info, row, td;
if (row = Rows[-1]) {
$(Rows[-1].tr).empty();
} else {
row = new Row(-1);
row.tr = TFoot.appendChild(document.createElement('tr'));
row.tr.id = ID + '_add';
}
info = new Info(row.i);
info.cols = Groups[0];
info.category = Key;
td = info.tr.appendChild(document.createElement('td'));
td.setAttribute("colspan", info.cols.metrics.length);
td.className = 'null';
info.width = Cols.length;
return generateAdd(info, td);
};
$scope.$on('displayService-toggleAge', function() {
var i, info, len, len1, m, mi, mid, n, p, pre, premid, q, results;
info = new Info();
results = [];
for (mi = p = 0, len = Cols.length; p < len; mi = ++p) {
m = Cols[mi];
if (m.metric.id !== 'age') {
continue;
}
info.m = mi;
pre = ID + '-';
mid = '_' + mi;
for (n = q = 0, len1 = Order.length; q < len1; n = ++q) {
i = Order[n];
info.i = i;
if (info.v) {
info.cell = document.getElementById(pre + i + mid);
if (info.cell) {
generateText(info);
}
}
}
if ((Expanded != null ? Expanded.c : void 0) === info.c && Expanded.count > 1) {
info.i = Expanded.i;
premid = pre + info.i + mid + '_';
results.push((function() {
var ref1, results1, w;
results1 = [];
for (n = w = 0, ref1 = Expanded.count - 1; w <= ref1; n = w += 1) {
info.n = n;
if (info.v) {
info.cell = document.getElementById(premid + n);
if (info.cell) {
results1.push(generateText(info));
} else {
results1.push(void 0);
}
} else {
results1.push(void 0);
}
}
return results1;
})());
} else {
results.push(void 0);
}
}
return results;
});
/**
* Place DOM elements and place all rows into spreadsheet.
* @interface spreadsheet/fill
*/
fill = function() {
var i, len, n, next, p, tr;
collapse();
n = 0;
next = TBody.firstChild;
for (p = 0, len = Order.length; p < len; p++) {
i = Order[p];
tr = Rows[i].tr;
if (Rows[i].filt && n++ < Limit) {
if (next === tr) {
next = next.nextSibling;
} else if (next) {
TBody.insertBefore(tr, next);
} else {
TBody.appendChild(tr);
}
} else {
if (next === tr) {
next = next.nextSibling;
TBody.removeChild(tr);
} else if (tr.parentNode) {
TBody.removeChild(tr);
}
}
}
if (n > Limit) {
$scope.more = n;
} else {
delete $scope.more;
}
};
/**
* Populate order based on compare function applied to values.
* @interface spreadsheet/sort
*/
sort = function(get) {
var i, idx, len, o, p;
idx = new Array(Order.length);
for (i = p = 0, len = Order.length; p < len; i = ++p) {
o = Order[i];
idx[o] = i;
}
Order.sort(function(i, j) {
return byMagic(get(i), get(j)) || idx[i] - idx[j];
});
};
currentSort = void 0;
currentSortDirection = false;
/**
* Sort by column
* @interface spreadsheet/sortBy
*/
sortBy = function(col, dir) {
var c, m;
if (currentSort === col && (dir == null)) {
currentSortDirection = !currentSortDirection;
Order.reverse();
} else {
if (!currentSort) {
Order.sort(function(i, j) {
var ref1, ref2;
return byNumber((ref1 = Rows[i].key) != null ? ref1.id : void 0, (ref2 = Rows[j].key) != null ? ref2.id : void 0);
});
}
c = col.category.id;
m = col.metric.id;
sort(function(i) {
var ref1;
return (ref1 = Rows[i].get(c)) != null ? ref1[m] : void 0;
});
currentSort = col;
if (dir) {
currentSortDirection = true;
Order.reverse();
} else {
currentSortDirection = false;
}
}
};
$scope.colClasses = function(col) {
var cls;
cls = [];
if (typeof col === 'object') {
if (col.first) {
cls.push('first');
}
if (col.last) {
cls.push('last');
}
}
cls.push('sort');
if (currentSort === col) {
cls.push('intransitive sort-' + (currentSortDirection ? 'desc' : 'asc'));
} else {
cls.push('intransitive sortable');
}
return cls;
};
/**
* Backend saving
* @interface spreadsheet/saveRun
*/
setFocus = void 0;
saveRun = function(cell, run) {
messages.clear(cell);
cell.classList.remove('error');
cell.classList.add('saving');
return run.then(function(res) {
cell.classList.remove('saving');
$scope.form.$setPristine();
return res;
}, function(res) {
cell.classList.remove('saving');
cell.classList.add('error');
messages.addError({
body: 'Could not save data',
report: res,
owner: cell
});
});
};
addRow = function(row) {
Order.push(row.i);
generateRow(row.i);
TBody.appendChild(row.tr);
return row;
};
createSlot = function(info) {
return saveRun(info.cell, volume.createContainer().then(function(slot) {
arr(slot, 'records');
return addRow(populateSlot(slot));
}));
};
createRecord = function(info) {
return saveRun(info.cell, volume.createRecord(info.c || void 0).then(function(record) {
return addRow(populateRecord(record));
}));
};
createNew = function(info) {
if (info.c === 'slot') {
return createSlot(info);
} else if (typeof info.c === 'number') {
return createRecord(info);
}
};
removeRow = function(i) {
var row;
unedit(false);
row = Rows[i];
delete Rows[i];
if (row.tr.parentNode) {
TBody.removeChild(row.tr);
}
Order.remove(i);
if ((Expanded != null ? Expanded.i : void 0) === i) {
Expanded = void 0;
}
};
removeSlot = function(info) {
return saveRun(info.cell, info.slot.remove().then(function(done) {
if (!done) {
messages.add({
body: "You must remove all associated records and files before you can remove this folder.",
type: 'red',
owner: info.cell
});
return;
}
removeRow(info.i);
}));
};
removeRecord = function(info) {
return saveRun(info.cell, info.record.remove().then(function(done) {
if (!done) {
messages.add({
body: "You must remove all associated sessions and materials before you can remove this " + info.category.name + ".",
type: 'red',
owner: info.cell
});
return;
}
removeRow(info.i);
}));
};
setRecord = function(info, record) {
var act, add;
add = function() {
if (record) {
return info.slot.addRecord(record);
} else if (record !== null) {
return info.slot.newRecord(info.c || '');
}
};
act = info.record ? info.slot.removeRecord(info.record).then(add) : add();
return saveRun(info.cell, act.then(function(rr) {
var i, o, r, ref1;
record = rr != null ? rr.record : void 0;
o = info.d;
if (record) {
r = populateRecordData(record);
if (o) {
info.row.set(info.c, info.n, r);
} else {
info.n = info.row.add(info.c, r);
}
} else {
info.row.set(info.c, info.n, void 0);
}
collapse();
generateRow(info.i);
if (info.n) {
expand(info);
}
if (record && setFocus === (i = info.id) && (i = (ref1 = document.getElementById(i)) != null ? ref1.nextSibling : void 0) && (i = parseId(i))) {
select(i);
}
setFocus = void 0;
return record;
}));
};
updateDatum = function(info, v) {
var len, li, p, ref1;
info.v = v;
info.d[info.metric.id] = v;
if (info.metric.id === 'top') {
collapse();
generateRow(info.i);
expand(info);
} else if (info.category.fixed) {
generateText(info);
} else {
ref1 = TBody.getElementsByClassName(info.p + info.d.id + '_' + info.metric.id);
for (p = 0, len = ref1.length; p < len; p++) {
li = ref1[p];
info.cell = li;
generateText(info);
}
}
};
saveDatum = function(info, v) {
var data, t;
if (info.c === 'slot') {
data = {};
if (info.metric.id === 'top') {
v = v === 'true';
}
data[info.metric.id] = v != null ? v : '';
if (info.slot[info.metric.id] == v) {
return;
}
return saveRun(info.cell, info.slot.save(data).then(function() {
updateDatum(info, v);
}));
} else if (info.c === 'asset') {
data = {};
t = info.metric.id;
data[t] = v != null ? v : '';
if (info.asset[t] === data[t]) {
return;
}
return saveRun(info.cell, info.asset.save(data).then(function() {
updateDatum(info, v);
}));
} else {
if (info.record.measures[info.metric.id] === v) {
return;
}
return saveRun(info.cell, info.record.measureSet(info.metric.id, v).then(function() {
updateDatum(info, v);
}));
}
};
/**
* Interaction and collapse any expanded row.
* @interface spreadsheet/collapse
*/
collapse = function() {
var el, i, t, tr;
if (!Expanded) {
return;
}
i = Expanded.i;
tr = Expanded.tr;
Expanded = void 0;
tr.classList.remove('expand');
t = 0;
while ((el = tr.nextSibling) && el.data === i) {
t++;
$(el).remove();
}
el = tr.firstChild;
while (el) {
el.removeAttribute("rowspan");
el = el.nextSibling;
}
return t;
};
/**
* Expand (or collapse) a row
* @interface spreadsheet/expand
*/
expand = function(info) {
var el, max, n, next, p, ref1, ref2, start;
if ((Expanded != null ? Expanded.i : void 0) === info.i && Expanded.c == info.c) {
if (info.t === 'more') {
collapse();
}
return;
}
collapse();
if (info.i < 0) {
return;
}
Expanded = new Info(info.i);
Expanded.c = info.c;
info.tr.classList.add('expand');
max = Expanded.count;
if (Editing && Expanded.c !== Key.id && Expanded.c !== 'slot') {
max++;
}
if (max <= 1) {
return;
}
next = info.tr.nextSibling;
start = Expanded.count === 1;
for (n = p = ref1 = +start, ref2 = max - 1; p <= ref2; n = p += 1) {
Expanded.n = n;
Expanded.tr = TBody.insertBefore(document.createElement('tr'), next);
Expanded.tr.data = Expanded.i;
Expanded.tr.className = 'expand';
generateRecord(Expanded);
}
Expanded.tr = info.tr;
if (!start) {
max++;
}
el = info.tr.firstChild;
while (el) {
info = new Info(el);
if (info.c != Expanded.c) {
el.setAttribute("rowspan", max);
}
el = el.nextSibling;
}
};
save = function(info, type, value) {
var c, r, ref1, ref2, u, v;
if (value === '') {
value = void 0;
} else {
switch (type) {
case 'record':
if (value === 'new') {
setRecord(info);
} else if (value === 'remove') {
if (info.d) {
setRecord(info, null);
}
} else if (v = stripPrefix(value, 'add_')) {
u = v.indexOf('_');
info.metric = constants.metric[v.slice(0, u)];
v = v.slice(u + 1);
setRecord(info).then(function(r) {
info.record = r;
if (r) {
saveDatum(info, v);
}
});
} else if (!isNaN(v = parseInt(value, 10))) {
if (v !== ((ref1 = info.d) != null ? ref1.id : void 0)) {
setRecord(info, volume.records[v]);
}
}
return;
case 'options':
if (value) {
c = optionCompletions(value);
}
if (c != null ? c.length : void 0) {
value = c[0];
}
}
}
if (type === 'ident') {
r = editScope.identCompleter(value);
if (Array.isArray(r)) {
if ((ref2 = r.find(function(o) {
return o["default"];
})) != null) {
ref2.run(info);
}
}
} else if (info.i === -1) {
if (!value) {
return;
}
createNew(info).then(function(row) {
saveDatum(new Info(row.tr.firstChild), value);
});
} else {
saveDatum(info, value);
}
};
editScope = $scope.$new(true);
editScope.constants = constants;
editInput = editScope.input = {};
editCellTemplate = $compile($templateCache.get('volume/spreadsheetEditCell.html'));
editCell = void 0;
unedit = function(event) {
var cell, edit, info;
if (!(edit = editCell)) {
return;
}
editCell = void 0;
cell = edit.parentNode;
$(edit).remove();
if (!(cell != null ? cell.parentNode : void 0)) {
return;
}
cell.classList.remove('editing');
tooltips.clear();
info = new Info(cell);
if (event !== false) {
save(info, editScope.type, editInput.value);
}
return info;
};
recordDescription = function(r) {
var k;
k = Object.keys(r.measures);
if (k.length) {
return k.sort(byNumber).map(function(m) {
return r.measures[m];
}).join(', ');
} else {
return '[' + r.id + ']';
}
};
edit = function(info) {
var c, e, found, len, m, mf, mi, ms, o, p, r, ref1, ref10, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, ri, rs, v;
switch (info.t) {
case void 0:
if (info.c === 'asset') {
$location.url(info.slot.editRoute({
asset: info.d.id
}));
return;
}
m = info.metric;
if (m.readonly) {
return;
}
editScope.type = m.type;
mi = m.id;
editScope.options = m.options;
if (m.type === 'void') {
editScope.type = 'record';
editScope.options = {
remove: info.category.not
};
editScope.options[v = info.d.id] = m.name;
} else if (info.c === 'slot') {
if (((ref1 = info.slot) != null ? ref1.top : void 0) && (mi === 'date' || mi === 'release')) {
return;
}
v = (ref2 = info.slot) != null ? ref2[mi] : void 0;
if (mi === 'top' && info.slot) {
v = !!v;
}
if (mi === 'release') {
v = (v != null ? v : -1) + '';
}
} else if (info.c === 'asset') {
v = info.asset[mi];
} else {
v = (ref3 = info.record) != null ? ref3.measures[mi] : void 0;
if (info.col.first && info.category !== Key) {
editScope.type = 'ident';
editScope.info = info;
rs = [];
mf = function(r) {
return function(m) {
return r.measures[m];
};
};
ref4 = volume.records;
for (ri in ref4) {
r = ref4[ri];
if (r.category === info.c && !info.row.list(info.c).some(function(d) {
return d.id == ri;
}) && !r.global) {
rs.push({
r: r,
v: ((ref5 = r.measures[mi]) != null ? ref5 : '').toLowerCase(),
d: recordDescription(r)
});
}
}
editScope.records = rs.sort(function(a, b) {
return byMagic(a.v, b.v);
});
} else if (m.options) {
editScope.type = 'options';
} else if (m.long) {
editScope.type = 'long';
}
}
editInput.value = (v != null ? v : '') + '';
break;
case 'add':
if (info.i === -1) {
createNew(info);
return;
}
if (info.c === 'asset') {
$location.url(info.slot.editRoute() + '?file=open');
return;
}
c = info.category;
editInput.value = ((ref6 = (ref7 = info.d) != null ? ref7.id : void 0) != null ? ref6 : 'remove') + '';
editScope.type = 'record';
editScope.options = {
"new": 'Create new ' + c.name,
remove: c.not
};
ref8 = volume.records;
for (ri in ref8) {
r = ref8[ri];
if (r.category === c.id && (!info.row.list(info.c).some(function(d) {
return d.id == ri;
}) || ri == editInput.value) && !r.global) {
editScope.options[ri] = r.displayName;
}
}
ms = info.cols.metrics;
if (ms.length === 1) {
if (ms[0].type === 'void' && Object.keys(editScope.options).length > 2) {
delete editScope.options['new'];
} else if (ms[0].options) {
delete editScope.options['new'];
ref9 = ms[0].options;
for (p = 0, len = ref9.length; p < len; p++) {
o = ref9[p];
found = false;
ref10 = volume.records;
for (ri in ref10) {
r = ref10[ri];
if (r.category === c.id && r.measures[m.id] === o) {
found = true;
break;
}
}
if (!found) {
editScope.options['add_' + ms[0].id + '_' + o] = o;
}
}
}
}
break;
default:
return;
}
e = editCellTemplate(editScope, function(e) {
info.cell.insertBefore(editCell = e[0], info.cell.firstChild);
info.cell.classList.add('editing');
});
e.on('click', function($event) {
$event.stopPropagation();
});
tooltips.clear();
$timeout(function() {
var input;
input = e.find('[name=edit]');
input.filter('input,textarea').focus().select();
input.filter('select').focus().one('change', $scope.$lift(editScope.unedit));
});
};
unselect = function() {
styles.clear();
unedit(false);
};
$scope.$on('$destroy', unselect);
select = function(info) {
var c, len, p, ref1;
styles.clear();
unedit();
expand(info);
if (!info.t) {
ref1 = info.cell.classList;
for (p = 0, len = ref1.length; p < len; p++) {
c = ref1[p];
if (!(c.startsWith('ss-'))) {
continue;
}
styles.set('.' + c + '{background-color:' + (c.includes('_', 4) ? 'rgba(243,180,140,0.7)' : 'rgba(243,180,140,0.4)') + ';\n text-}');
info.cell.classList.add('selected');
}
}
if (Editing) {
edit(info);
} else if (info.category) {
$scope.filter.add(info);
}
};
$scope.click = function(event) {
var info, ref1;
if (!(info = parseId(event.target))) {
return;
}
select(info);
if (((ref1 = info.metric) != null ? ref1.id : void 0) === 'age') {
display.toggleAge();
}
};
doneEdit = function(event, info) {
var c, i, ref1, ref2;
if (info && event && event.$key === 'Tab') {
setFocus = !event.shiftKey && info.cell.id;
c = info.cell;
while (true) {
c = event.shiftKey ? c.previousSibling : c.nextSibling;
if (!(c && (i = parseId(c)))) {
return;
}
if (!(((ref1 = i.category) != null ? ref1.id : void 0) === 'asset' || ((ref2 = i.metric) != null ? ref2.type : void 0) === 'void')) {
break;
}
}
select(i);
}
};
editScope.unedit = function(event) {
doneEdit(event, unedit(event));
if (event) {
event.preventDefault();
}
return false;
};
editSelect = function(event) {
editInput.value = this.text;
editScope.unedit(event);
};
editScope.identCompleter = function(input) {
var add, defd, info, inputl, len, o, os, p, r, rs, set, x;
info = editScope.info;
o = [];
defd = false;
add = function(t, f, d) {
o.push({
text: t,
select: function(event) {
info = unedit(false);
f(info);
doneEdit(event, info);
},
run: f,
"default": d && !defd
});
return defd || (defd = d);
};
if (info.d) {
if (input === info.record.measures[info.metric.id]) {
add("Keep " + info.record.displayName, function() {}, true);
}
if (!input) {
add("Remove " + info.record.displayName + " from this session", function(info) {
return setRecord(info, null);
}, true);
}
}
if (!info.d || input && input !== info.record.measures[info.metric.id]) {
inputl = (input != null ? input : '').toLowerCase();
set = function(r) {
return function(info) {
return setRecord(info, r);
};
};
rs = (function() {
var len, p, ref1, results;
ref1 = editScope.records;
results = [];
for (p = 0, len = ref1.length; p < len; p++) {
r = ref1[p];
if (r.v.startsWith(inputl)) {
results.push(r);
}
}
return results;
})();
for (p = 0, len = rs.length; p < len; p++) {
r = rs[p];
add("Use " + info.category.name + ' ' + r.d, set(r.r), input && rs.length === 1 || r.v === inputl);
}
os = info.metric.options ? (function() {
var len1, q, ref1, results;
ref1 = info.metric.options;
results = [];
for (q = 0, len1 = ref1.length; q < len1; q++) {
x = ref1[q];
if (x.toLowerCase().startsWith(inputl)) {
results.push(x);
}
}
return results;
})() : [];
if (input && !os.length) {
os = [input];
}
os.forEach(function(i) {
if (info.d) {
add("Change all " + info.record.displayName + " " + info.metric.name + " to '" + i + "'", function(info) {
return saveDatum(info, i);
}, input && !rs.length && os.length === 1 || i === input);
}
return add("Create new " + info.category.name + " with " + info.metric.name + " '" + i + "'", function(info) {
return setRecord(info).then(function(r) {
info.record = r;
if (r) {
saveDatum(info, i);
}
});
}, input && !rs.length && os.length === 1 || i === input);
});
}
if (o.length) {
return o;
} else {
return input;
}
};
optionCompletions = function(input) {
var i, len, o, p, ref1, results;
i = input.toLowerCase();
ref1 = editScope.options;
results = [];
for (p = 0, len = ref1.length; p < len; p++) {
o = ref1[p];
if (o.toLowerCase().startsWith(i)) {
results.push(o);
}
}
return results;
};
editScope.optionsCompleter = function(input) {
var i, len, match, o, p, results;
match = optionCompletions(input);
switch (match.length) {
case 0:
return input;
case 1:
return match[0];
default:
results = [];
for (i = p = 0, len = match.length; p < len; i = ++p) {
o = match[i];
results.push({
text: o,
select: editSelect,
"default": input && i === 0
});
}
return results;
}
};
$scope.clickHeader = function(col) {
if (!Editing) {
$scope.filter.add(col);
}
if (col.metric) {
sortBy(col);
fill();
}
};
clickRemove = function(event) {
var info;
if (!(info = parseId(event.target.parentNode))) {
return;
}
if (info.c === 'slot') {
removeSlot(info);
} else if (typeof info.c === 'number') {
removeRecord(info);
}
event.stopPropagation();
return false;
};
clickGlobal = function(event) {
var act, info, rec;
if (!(info = parseId(event.target.parentNode))) {
return;
}
rec = info.row.key.record;
act = rec.global ? volume.top.removeRecord(rec).then(function() {
delete rec.global;
info.row.set(info.c, info.n, void 0);
}) : info.count ? router.http(router.controllers.deleteRecordAllSlot, rec.id).then(function() {
return volume.top.addRecord(rec).then(function() {
return true;
});
}) : volume.top.addRecord(rec).then(function() {
rec.global = true;
info.row.set(info.c, info.n, populateSlotData(volume.top));
});
saveRun(info.cell, act.then(function(r) {
if (r) {
$route.reload();
return;
}
collapse();
generateRow(info.i);
if (info.n) {
expand(info);
}
}));
};
$scope.unlimit = function() {
Limit = 2e308;
fill();
};
$scope.showHideGlobal = function() {
$scope.showGlobal = !$scope.showGlobal;
$scope.setKey(Key.id);
};
$scope.tabOptionsClick = false;
$scope.tabOptionsToggle = function($event) {
$scope.tabOptionsClick = !$scope.tabOptionsClick;
$event.stopPropagation();
return false;
};
pivotOpts = void 0;
$scope.pivot = {
show: function() {
this.run(Rows);
},
hide: function() {
this.clear();
},
load: function(opts) {
if (this.run) {
if (opts) {
this.run(Rows, opts);
} else {
this.clear();
}
} else {
pivotOpts = opts;
}
},
init: function() {
if (pivotOpts) {
this.run(Rows, pivotOpts);
}
pivotOpts = void 0;
}
};
$scope.filter = {
update: function(f) {
unedit(false);
setFilter(f);
fill();
},
accept: function(f) {
if (f.category === pseudoCategory.slot) {
if (Key === pseudoCategory.slot) {
return f.metric;
} else {
return f.metric !== pseudoMetric.summary;
}
} else {
return f.category !== pseudoCategory.asset && (Key === pseudoCategory.slot || Key === f.category);
}
},
add: function(info) {
var last, ref1;
if (!this.accept(info)) {
return;
}
last = this.list.pop();
if (last != null ? last.op : void 0) {
this.list.push(last);
}
this.list.push({
category: info.category,
metric: info.metric && info.metric.type !== 'void' ? info.metric : pseudoMetric.indicator,
value: ((ref1 = info.metric) != null ? ref1.type : void 0) === 'numeric' ? parseFloat(info.v) : info.v
});
},
count: 0
};
setFilter = function(f) {
var c, len, len1, len2, p, q, ref1, row, s, w;
c = 0;
if (!f) {
for (p = 0, len = Rows.length; p < len; p++) {
row = Rows[p];
if (row) {
row.filt = true;
}
}
} else if (Key.id === 'slot') {
for (q = 0, len1 = Rows.length; q < len1; q++) {
row = Rows[q];
if (!(row)) {
continue;
}
s = row.slot;
if (!(row.filt = f(s, s.slot.records))) {
c++;
}
}
} else {
for (w = 0, len2 = Rows.length; w < len2; w++) {
row = Rows[w];
if (row) {
if (!(row.filt = f((ref1 = row.key) != null ? ref1.record : void 0, row.list('slot')))) {
c++;
}
}
}
}
$scope.filter.count = c;
if ($scope.pivot.active) {
$scope.pivot.show();
}
};
/**
* Call all populate functions on folder tab change/onload
* @interface spreadsheet/setKey
*/
setKey = function(key) {
var base, bySlot, foot, i, len, oldKey, p, row;
unselect();
oldKey = Key;
Key = $scope.key = (key != null) && volume.metrics[key] && getCategory(key) || pseudoCategory.slot;
foot = Rows[-1];
Rows = [];
Cats = {};
if (bySlot = Key === pseudoCategory.slot) {
populateSlots();
} else {
populateRecords();
}
$scope.count = Rows.length;
$(TBody).empty();
Expanded = void 0;
if (foot) {
Rows[-1] = foot;
}
populateCols(bySlot);
if (Key !== oldKey || Order.length !== Rows.length) {
Order = (function() {
var len, p, results;
results = [];
for (p = 0, len = Rows.length; p < len; p++) {
row = Rows[p];
if (row) {
results.push(row.i);
}
}
return results;
})();
currentSort = void 0;
sortBy(Cols.find(function(c) {
return c.category.id === 'slot' && c.metric.id === 'date';
}));
}
Order.sort(function(a, b) {
return a - b;
});
for (p = 0, len = Order.length; p < len; p++) {
i = Order[p];
generateRow(i);
}
if (Editing) {
generateFoot();
}
tooltips.clear();
$scope.filter.key = Key.id;
$scope.filter.list = $scope.filter.list.filter($scope.filter.accept);
setFilter(typeof (base = $scope.filter).make === "function" ? base.make() : void 0);
$location.replace().search('key', void 0);
$scope.tabOptionsClick = void 0;
};
$scope.setKey = function(key) {
setKey(key);
fill();
};
$scope.state = {
get: function() {
var base, l, state;
state = {
key: Key.id,
sort: currentSort && {
c: currentSort.category.id,
m: currentSort.metric.id,
dir: currentSortDirection
},
filter: $scope.filter.list.map(function(f) {
return {
c: f.category.id,
m: f.metric.id,
op: f.op,
v: f.value
};
}),
pivot: typeof (base = $scope.pivot).get === "function" ? base.get() : void 0,
"public": this["public"]
};
if (!state.sort) {
delete state.sort;
}
l = state.filter.pop();
if (l != null ? l.op : void 0) {
state.filter.push(l);
}
if (!state.pivot) {
delete state.pivot;
}
if (!state["public"]) {
delete state["public"];
}
return state;
},
put: function(state, key) {
var col, f, l, len, p, r, ref1;
if (state.filter) {
l = [];
ref1 = state.filter;
for (p = 0, len = ref1.length; p < len; p++) {
f = ref1[p];
r = {
category: getCategory(f.c),
metric: getMetric(f.m),
op: f.op,
value: f.v
};
if (r.category && r.metric) {
l.push(r);
}
}
$scope.filter.list = l;
} else {
$scope.filter.list = [
{
category: pseudoCategory.slot,
metric: pseudoMetric.top
}
];
}
setKey(key || state.key);
if (state.sort && (col = Cols.find(function(c) {
return c.category.id === state.sort.c && c.metric.id === state.sort.m;
}))) {
sortBy(col, state.sort.dir);
}
fill();
$scope.pivot.load(state.pivot);
},
name: 'default',
save: function() {
var name, state;
if (!(name = this.name)) {
return;
}
state = this.get();
router.http(router.controllers.postVolumeState, volume.id, encodeURIComponent(name), state).then(function() {
volume.state[name] = state;
messages.add({
type: 'green',
body: 'Display mode "' + name + '" saved successfully.'
});
}, function(res) {
messages.addError({
body: 'Error saving report state',
report: res
});
});
},
"delete": function() {
if (!this.name) {
return;
}
router.http(router.controllers.deleteVolumeState, volume.id, encodeURIComponent(this.name)).then((function(_this) {
return function() {
delete volume.state[_this.name];
_this.name = void 0;
};
})(this), function(res) {
messages.addError({
body: 'Error deleting report state',
report: res
});
});
},
restore: function(key, state) {
var ref1;
state = state || ((ref1 = volume.state) != null ? ref1[this.name] : void 0) || {};
state["public"] = !!state["public"];
this.put(state, key);
}
};
if (volume.state) {
if ((base = volume.state)['NIH Inclusion Enrollment Report'] == null) {
base['NIH Inclusion Enrollment Report'] = {
key: constants.categoryName.participant.id,
pivot: {
cols: ["participant ethnicity", "participant gender"],
rows: ["participant race"],
rendererName: "Table",
aggregatorName: "Count"
},
filter: [
{
c: "slot",
m: "top",
op: "false"
}, {
c: "slot",
m: "date",
op: "ge"
}, {
c: "slot",
m: "date",
op: "le",
v: $filter('date')(new Date(), 'yyyy-MM-dd')
}
]
};
}
if ((base1 = volume.state)['Session release level summary'] == null) {
base1['Session release level summary'] = {
key: 'slot',
pivot: {
cols: [],
rows: ["release"],
rendererName: "Table",
aggregatorName: "Count"
},
filter: [
{
c: "slot",
m: "top",
op: "false"
}
]
};
}
}
$scope.zip = function(event) {
var add, b, c, cs, f, l, len, len1, p, params, q, row;
event.preventDefault();
cs = [];
for (p = 0, len = Rows.length; p < len; p++) {
row = Rows[p];
if (row) {
cs.push({
i: row.slot.id,
f: !!row.filt
});
}
}
cs.sort(function(a, b) {
return a.i - b.i;
});
f = $scope.filter.count < cs.length / 2;
l = [];
b = void 0;
add = function() {
if (b) {
l.push(b.join('-'));
return b = void 0;
}
};
for (q = 0, len1 = cs.length; q < len1; q++) {
c = cs[q];
if (c.f === f) {
add();
} else if (b) {
b[1] = c.i;
} else {
b = [c.i];
}
}
add();
params = {};
if (l.length) {
params[f ? 'exclude' : 'include'] = l.join(',');
}
$location.url(router.volumeDescription([volume.id], params));
};
}
],
link: function($scope, $element, $attrs) {
var state;
state = storage.getValue('spreadsheet-state');
if ((state != null ? state.volume : void 0) !== $scope.volume.id) {
state = void 0;
}
$scope.state.restore($attrs.key || $location.search().key, state);
$scope.setKey($scope.views[0].id);
$scope.$on('refreshParent', function() {
$scope.volume.get({
records: true
}).then((function(res) {
$scope.volume.records = res.records;
$scope.setKey($scope.views[0].id);
}), function(res) {
return messages.addError({
body: constants.message('Please refresh the page.'),
report: res
});
});
});
$scope.$on('skiptrue', function() {
$scope.skiptrue = true;
});
$scope.$on('skipfalse', function() {
$scope.skiptrue = false;
});
$scope.$on('$destroy', function() {
state = $scope.state.get();
state.volume = $scope.volume.id;
storage.setValue('spreadsheet-state', state);
});
}
};
}
]);
//# sourceMappingURL=spreadsheet.js.map