Skip to content

Instantly share code, notes, and snippets.

@santaklouse
Last active September 11, 2018 16:33
Show Gist options
  • Save santaklouse/d7734ef21bbe3982821748686539415f to your computer and use it in GitHub Desktop.
Save santaklouse/d7734ef21bbe3982821748686539415f to your computer and use it in GitHub Desktop.
AngularJS services example
(function(angular) {
'use strict';
angular.module('noname.services', ['ngResource'])
.factory('templateUrl', ['$templateCache', 'config', 'feature', function($templateCache, config, feature) {
return function(placement, name) {
var templatePath = function(role) {
var path;
role = role || 'common';
path = ['@UnknownBundle', role, placement, name].join('/');
return (_.last(path) === '/') ? path.slice(0, path.length-1) : path;
};
if ($templateCache.get(templatePath(config.getRole()))) {
return templatePath(config.getRole());
}
return templatePath();
}
}])
.service('urlTemplate', ['$filter', 'dateUtils', 'utils', '$injector', function($filter, dateUtils, utils, $injector) {
return {
/**
* Returns object with params prepared for urlTemplate function (filling url template)
*
* @param {Array} fieldsFromConfig names of fields which should be taken from config)
* @param {Object} [params] additional params that should be added to url (together with config values)
* @param {Boolean} [shouldFormatDate] if true and in params 'date' exists - formats date to 'yyyyMMdd' format
*
* @return {Object}
*/
prepareParams: function(fieldsFromConfig, params, shouldFormatDate) {
var config = $injector.get('config');
var result = _.pick(config, fieldsFromConfig);
if (result.date && _.isDate(result.date) && shouldFormatDate) {
result.date = $filter('date')(result.date, 'yyyyMMdd');
}
if (params && utils.isObject(params)) {
return _.assignIn(result, params);
}
return result;
},
/**
* @param {String} urlTemplate template str (${...} - will be replaced with values from params object)
* @param {Object} params params which be included to template string
*
* @return {String|Array}
*/
fill: function(urlTemplate, params) {
var value;
return urlTemplate.replace(/[\$%]{(\w+?)}/gi, function(match, field) {
value = params[field];
return value === undefined ? '' : value;
});
},
/**
* Converts urlTemplate template pattern (like /${date}/) to angular format (like /:date/)
*
* @param {String} urlTemplate - str with marks, like: ${contractId}/%{date}/%{tz}
* % - can be used for building angular routing with optional params
* e.g.: /${id}/%{smth_optional} -> /:id/:smth_optional?
* @return {String}
*/
toAngularRouteFormat: function(urlTemplate) {
urlTemplate = String(urlTemplate);
if (urlTemplate[0] !== '/') {
urlTemplate = '/' + urlTemplate;
}
return urlTemplate.replace(/[\$%]{(\w+?)}/gi, function(match, field) {
if (!field) {
return '';
}
return ':' + field + (match[0] === '%' ? '?' : '');
});
},
/**
* Return array of 'config' service field names (${...} - params inside of this will be returned as array)
*
* @param {String} urlTemplate template str
* @param {Array} [config.allowedConfigFields] list of allowed to change config fields
* @return {Array}
*/
parse: function(urlTemplate, useAnyFields) {
var result = [], config = $injector.get('config');
urlTemplate.replace(/[\$%]{(\w+?)}/gi, function(match, field) {
result.push(field);
return match;
});
if (useAnyFields || !config.allowedConfigFields) {
return result;
}
return result.filter(function(val) {
return config.allowedConfigFields.indexOf(val) !== -1;
});
},
/**
* Compiles url string from template string
*
* @param {String} url template str ${...} - will be replaced with values from params object
* @param {Array} fieldsFromConfig names of fields which should be taken from config
* @param {Object} [params] additional params that should be added to url (besides config values
*
* @return {String}
*/
compile: function(url, fieldsFromConfig, params) {
return this.fill(
url,
this.prepareParams(fieldsFromConfig, params, true)
);
},
extractLocationParams: function(path) {
var config = $injector.get('config'),
configKeysFromTemplate = config.urlTemplateKeysList,
urlPathValues = _.compact(path.split('/')).filter(function(val) {
//remove parts of pattern
return config.urlTemplatePattern.indexOf(val) === -1;
});
if (!urlPathValues.length) {
return {};
}
var getParamFromUrl = function(param, defaultVal) {
var paramIndex = configKeysFromTemplate.indexOf(param);
return (paramIndex !== -1 && urlPathValues[paramIndex])
|| (utils.isUndefined(defaultVal) ? null : defaultVal);
};
//build hash of path params with values (key=>val)
return _.chain(configKeysFromTemplate)
.map(function(param) {
if (config.allowedConfigFields.indexOf(param) === -1) {
return;
}
return [param, getParamFromUrl(param, null)];
})
.compact()
.fromPairs()
.value();
}
};
}])
.factory('generateSnapshotUrl', ['snapshotPageUrlTemplate', '$location', 'urlTemplate', function(snapshotPageUrlTemplate, $location, urlTemplate) {
return function(time, baseUrl) {
if (!time) {
return '#';
}
baseUrl = baseUrl || $location.absUrl();
return urlTemplate.compile(
snapshotPageUrlTemplate,
['contractId'],
{
base: location.origin,
time: time,
backUrl: encodeURIComponent(baseUrl)
}
);
};
}])
.service('utils', [function() {
var _CRCTable = [],
getType = {},
dateIdentifier = 'Date',
crypto = window.crypto,
u32_4 = new Uint32Array(4),
a16 = Array(16),
charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
charsetLength = charset.length,
getCharCode = _.memoize(function(i) {
return charset.charCodeAt(i);
}),
dateString = /^([1-2][0-9]{3})(0[1-9]|1[0-2])([0-2][0-9]|3[0-1])$/;
var _makeCRCTable = _.memoize(function(val) {
if (val !== undefined) {
return (_CRCTable.length ? _CRCTable : _makeCRCTable())[val];
}
var c, n = 0;
for (; n < 256; n++) {
c = n;
for (var k = 0; k < 8; k++) {
c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
}
_CRCTable[n] = c;
}
return _CRCTable;
});
var utils = {
memoizeHasher: function(){
return _.chain(_.toArray(arguments))
.map(function(value) {
if (utils.isObject(value)) {
return JSON.stringify(value) + typeof(value);
}
return String(value) + typeof(value);
})
.value()
.join()
},
/**
* Checks if `value` is classified as an Function.
*
* @description (faster a bit smaller ~x3 than _.isFunction and )
* @param {*} value
* @returns {Boolean}
*/
isFunction: function(value) {
return typeof value === 'function' || value instanceof Function;
},
/**
* Checks if `value` is classified as an Date object.
*
* @description (faster >x3 than _.isDate and ~x10 angular.isDate)
* @param {*} value
* @returns {Boolean}
*/
isDate: function (value){
return getType.toString.call(value).indexOf(dateIdentifier) !== -1;
},
/**
* Checks that string has valid WD URL date format: yyyymmdd (like 19991231)
* @param {String} str
* @returns {Boolean}
*/
isValidWDDate: function(str){
if (!str) {
return false;
}
return dateString.test(str);
},
/**
* Checks if `value` has boolean type.
*
* @param {*} value
* @returns {Boolean}
*/
isBoolean: function (value){
return typeof(value) === 'boolean';
},
/**
* Checks if `value` is classified as an Number.
*
* @param {*} value
* @description (a bit faster than _.isNumber)
* @returns {Boolean}
*/
isNumber: function (value){
return typeof(value) === 'number' || value instanceof Number;
},
/**
* Checks is `value` is Integer (no fractional).
*
* @param num
* @returns {boolean}
*/
isInteger: function (value) {
return (value ^ 0) === value;
},
/**
* Checks if `value` is classified as an undefined.
*
* @param {*} value
* @description (a bit faster than _.isUndefined)
* @returns {Boolean}
*/
isUndefined: function (value) {
return value === undefined;
},
/**
* Checks if `value` is null.
*
* @param {*} value
* @returns {Boolean}
*/
isNull: function(value) {
return value === null;
},
/**
* Checks if `value` is the of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @description (faster >x10 than _.iObject)
* @param {*} value The value to check.
* @returns {Boolean}
*
* @example
*
* utils.isObject({});
* // => true
*
* utils.isObject([1, 2, 3]);
* // => true
*
* utils.isObject(_.noop);
* // => true
*
* utils.isObject(1);
* // => false
*
* utils.isObject('str');
* // => false
*
* utils.isObject(undefined);
* // => false
*/
isObject: function (value){
if (value === null) {
return false;
}
value = typeof(value);
return value === 'object' || value === 'function';
},
/**
* Checks if `value` is the String.
*
* @description (mostly faster than _.iObject for many input types)
* @param {*} value The value to check.
* @returns {Boolean}
*/
isString: function (value){
return (typeof value === 'string' || value instanceof String)
},
fastArrayJoin: function(array) {
var i = 0, l = array.length, result = '';
for(;i<l;){
result += array[i++];
}
return result;
},
/**
* Checks if `string` contains at least one substring from list of substrings
*
* @param {String} string The main string.
* @param {Array|String} substrings The list of substrings to check.
* @returns {Boolean}
*/
isStringContainsOneOfSubstrings: function(string, substrings) {
if (!string) {
return false;
}
if (!angular.isArray(substrings)) {
if (utils.isString(substrings)) {
return string.indexOf(substrings) !== -1;
}
return false;
}
return substrings.some(function(substring) {
return string.indexOf(substring) !== -1;
});
},
/**
* Just if you need random string
*
* @link https://bocoup.com/weblog/random-numbers
* @link https://developer.mozilla.org/en-US/docs/Web/API/RandomSource/getRandomValues
* @returns {String}
*/
rand: function() {
if (crypto && crypto.getRandomValues) {
return utils.fastArrayJoin(crypto.getRandomValues.call(crypto, u32_4));
}
var i = 0, result = '';
for (; i < a16.length; i++) {
result += getCharCode(Math.random() * charsetLength|0);
}
},
/**
* Simple, fast generation of RFC4122 UUIDS.
*
* @link http://www.ietf.org/rfc/rfc4122.txt
* @return {String}
*/
UUID: function() {
var b = function (a) {
return a?(a^Math.random()*16>>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11)
.replace(/[018]/g, b)
};
return b();
},
/**
* Javascript implementation of Java’s String.hashCode() method
* @param {String} str
* @param {Boolean} [inHex]
* @param {Number} [radix=10] - scale of notation (radix=16 if inHex is false)
* @returns {String}
*/
hashCode: _.memoize(function(value, inHex, radix) {
if (utils.isObject(value)) {
value = _.toPairs(value);
}
if (!utils.isString(value)) {
value = !value ? '0' : value.toString();
}
var hash = 0, i = 0,
length = value.length;
if (!length) {
return hash;
}
for (; i < length; i++) {
hash = ((hash << 5) - hash) + value.charCodeAt(i);
hash = hash & hash;
}
radix = inHex ? 16 : (radix ? radix : 10);
return Math.abs(hash).toString(radix);
}, function(value, inHex, radix){
return _.chain([value, inHex, radix])
.map(function(value) {
if (utils.isObject(value)){
return JSON.stringify(value) + typeof(value);
}
return String(value) + typeof(value);
})
.value()
.join()
}),
hash: function(value) {
return utils.hashCode(value, 0, 36);
},
/**
* Generates CRC32 for string
* https://jsperf.com/js-crc32
*/
CRC32: _.memoize(function(str) {
if (utils.isObject(str)){
str = JSON.stringify(str) + typeof(str);
} else {
str = String(str);
}
var i = 0, l = str.length, crc = 0 ^ (-1);
for (; i < l; ) {
crc = (crc >>> 8) ^ _makeCRCTable((crc ^ str.charCodeAt(++i)) & 0xFF);
}
return (crc ^ (-1)) >>> 0;
}, function(str){
return utils.isObject(str) ? JSON.stringify(str) + typeof(str):String(str);
}),
/**
* Capitalize str
*
* @param {String} str
* @param {Boolean} lowercaseRest - if true other part of string will be lowercased
* @returns {String}
*/
capitalize: _.memoize(function(str, lowercaseRest) {
if (!str) {
return str;
}
if (!utils.isString(str)) {
str = String(str);
}
return str.charAt(0).toUpperCase() + (lowercaseRest ? str.slice(1).toLowerCase() : str.slice(1));
}, function(str, lowercaseRest) {return [str + typeof(str), lowercaseRest + typeof(lowercaseRest)].join()})
};
return utils;
}])
.service('Engagements', ['requestCanceler', 'config', '$filter', '$http', 'singleEngagementTemplateUrl', 'engagementsTemplateUrl', 'dateUtils', 'oca_root', 'getApiCache', 'getCached', 'dateRange', 'utils', 'feature', 'sendLegacyApiRequest', 'urlTemplate', function(requestCanceler, config, $filter, $http, singleEngagementTemplateUrl, engagementsTemplateUrl, dateUtils, oca_root, getApiCache, getCached, dateRange, utils, feature, sendLegacyApiRequest, urlTemplate) {
/*
* contract fields example (engagements API)
{
hourly_charge_rate: "240",
engagement_end_ts: "",
status: "active",
weekly_salary_charge_amount: "0",
buyer_company__name: "Company Name 1+2={{1+2}}",
buyer_company__reference: "188955",
created_time: "1500394588000",
job__title: "Round test 4",
provider_company__name: "",
cj_job_application_uid: "",
reference: "402718",
engagement_start_date: "1500336000000",
provider_company__reference: "",
weekly_hours_limit: "",
engagement_job_type: "hourly",
buyer_team__name: "Company Name 1+2={{1+2}}",
provider_team__reference: "",
job_application_ref: "",
job_ref_ciphertext: "~01ff2bc8a79192ae6a",
active_milestone: "",
is_paused: "0",
engagement_start_ts: "1500394588000",
is_autopaused: "0",
buyer_team__reference: "188955",
engagement_end_date: "",
provider__name: "Alex Black",
provider_team__id: "",
offer_id: "",
weekly_stipend_hours: "",
dev_recno_ciphertext: "~019dc6e32gb52f9f99",
buyer_team__id: "xtyqmd1xmiy67eag",
provider__reference: "789390",
provider_team__name: "",
engagement_title: "Round test 4",
provider__id: "alexblack",
description: "",
portrait_url: "https://nonane-portraits.s3.amazonaws.com/Users:alexblack:PortraitUrl_original?AWSAccessKeyId=AKIAI6O4KKJ4MFGGZ5AA&Expires=2147483647&Signature=xWWUa%2FgIsqxrJlUlFTMGgLcQTj4%3D&1474484153340556"
}
*/
var unknownFF = feature.isEnabled('unknownFeature'),
requestParams = {
method: 'GET',
transformResponse: function(response, headersGetter, status) {
if (!response) {
return [];
}
//if 401 Unauthorized
if (!unknownFF && parseInt(status, 10) === 401) {
return location.reload();
}
response = angular.fromJson(response);
if (_.get(response, 'engagement')) {
var engagement = _.get(response, 'engagement');
engagement.engagement_title = _.get(engagement, 'job__title', '');
return {
engagement: engagement
};
}
return {
lister: _.get(response, 'engagements.lister', []),
engagements: _.get(response, 'engagements.engagement', [])
};
}
},
cache = getApiCache('engagements');
var engagements = {
all: [],
hashFunction: function(params) {
if (_.isString(params)) {
return utils.hash(params);
}
return utils.hash([params.buyer_team__reference, params.status, params.page, params.limit, params.regex].join());
},
result: function (url, cache) {
return getCached(url, cache, requestParams.transformResponse);
},
_prepareAndSend: function(successCallback, errorCallback) {
// debugger;
return sendLegacyApiRequest(requestParams, function(data) {
if (utils.isFunction(successCallback)) {
successCallback(engagements.result(requestParams.url, cache) || data);
}
}, function(obj, status) {
if (utils.isFunction(errorCallback)) {
errorCallback(status);
}
});
},
one: function(ref, successCallback, errorCallback) {
// debugger;
cache = getApiCache('engagement');
requestParams.url = urlTemplate.fill(singleEngagementTemplateUrl, {contract_reference: ref});
requestParams.params = {
field_set: ["basic", "buyer_team__name", "parent_reference", "buyer_company__reference", "buyer_company__name", "provider__name", "provider_team__name", "provider_company__name", "provider_company__reference"].join(';'),
};
requestCanceler
.setApiIdentifier('engagement')
.setUrl(requestParams.url+ref)
.setCache(cache);
var cachedResponse = getCached(requestParams.url, cache, requestParams.transformResponse);
if (cachedResponse) {
if (utils.isFunction(successCallback)) {
successCallback(cachedResponse);
}
var deferred = $q.defer();
deferred.resolve(cachedResponse);
return deferred.promise;
}
_.assignIn(requestParams, {
timeout: requestCanceler
.cancelRequestIfNeeded()
.getPromise(),
cache: cache,
cancelable: true
});
return this._prepareAndSend(successCallback, errorCallback);
},
fetch: function(params, successCallback, errorCallback) {
cache = getApiCache('engagements');
requestParams.url = engagementsTemplateUrl;
requestParams.params = _.assignIn({
field_set: ["basic", "buyer_team__name", "parent_reference", "buyer_company__reference", "buyer_company__name", "provider__name", "provider_team__name", "provider_company__name", "provider_company__reference"].join(';'),
order_by: ['provider__name', 'engagement_title'].join(';')+'A',
page: 0,
role: ['buyer', 'buyer_wd'].join(';'),
include_sub_teams: true
// regex: params.regex
}, params, {
status: params.includePast ? ['closed', 'active'].join(';') : 'active',
buyer_team__reference: config.getTeam().reference
});
requestCanceler
.setApiIdentifier('engagements')
.setUrl(requestParams.url+this.hashFunction(requestParams.params))
.setCache(cache);
var cachedResponse = getCached(requestParams.url, cache, requestParams.transformResponse);
if (cachedResponse) {
if (utils.isFunction(successCallback)) {
successCallback(cachedResponse);
}
var deferred = $q.defer();
deferred.resolve(cachedResponse);
return deferred.promise;
}
_.assignIn(requestParams, {
timeout: requestCanceler
.cancelRequestIfNeeded()
.getPromise(),
cache: cache,
cancelable: true
});
return this._prepareAndSend(successCallback, errorCallback);
}
};
return engagements;
}])
.factory('config', ['baseConfig', 'contracts', function(baseConfig, contracts) {
var config = {
contractId: null,
tz: baseConfig.findInitialTimezone()
};
config = _.assignIn(baseConfig, config);
config.tzOffset = config.getTzOffset();
config.date = config.getInitDate();
config.changeContract(config.contractId);
return config;
}])
.service('Snapshots', ['$timeout', 'Workdiary', 'Workdays', 'config', 'loading', 'dateUtils', '$filter', '$q', function($timeout, Workdiary, Workdays, config, loading, dateUtils, $filter, $q) {
var errorsCatcher = function(deffered) {
return function() {
deffered.reject({
error: arguments
});
}
};
return {
selected_time: null,
snapshot: null,
_allSnapshots: [],
snapshots: function(index) {
return !_.isUndefined(index) ? _.get(this._allSnapshots, index) : this._allSnapshots;
},
count: function() {
return this.snapshots().length;
},
fillSnapshots: function() {
this._allSnapshots = _.chain(Workdiary.snapshots)
.values()
.concat(this._allSnapshots)
.flatten()
.compact()
.uniqBy('cell_time')
.sortBy('cell_time')
.value();
return this;
},
move: function (direction) {
if (this.count() !== _.size(_.values(Workdiary.snapshots))) {
this.fillSnapshots();
}
return this.setCurrent(this.snapshots(this.findIndex() + direction));
},
find: function(time) {
time = +time || this.selected_time;
return _.find(this.snapshots(), function(s) {
return +s.time === time || +s.cell_time === time;
});
},
findIndex: function(time) {
time = +time || this.selected_time;
return _.findIndex(this.snapshots(), function(s) {
return +s.time === time || +s.cell_time === time;
});
},
checkNeighbour: function(direction) {
var deffered = $q.defer();
var keys = Workdays.all;
var time = this.selected_time * 1000;
var key = _.indexOf(keys, $filter('date')(dateUtils.utcToLocal(dateUtils.sparse(time+'u')), 'yyyyMMdd'));
var result = _.get(Workdays.all, key + direction);
if (result) {
var next_date_timestamp = dateUtils.shortDateParse(result, false, true);
} else {
deffered.resolve();
return deffered.promise;
}
Workdiary.fetchByDate(next_date_timestamp, function(data) {
this.fillSnapshots();
this.setCurrent();
deffered.resolve();
}.bind(this), function() {
errorsCatcher(deffered).apply(this, arguments);
}.bind(this));
return deffered.promise;
},
setCurrent: function(newSnapshot, index) {
var selected_time;
if (this.count() !== _.size(_.values(Workdiary.snapshots))) {
this.fillSnapshots();
}
if (newSnapshot) {
if (_.isObject(newSnapshot)) {
selected_time = +_.get(newSnapshot, 'time', newSnapshot.cell_time);
}
this.selected_time = +selected_time || +newSnapshot;
this.snapshot = this.find(this.selected_time);
}
this.next = this.snapshots(this.findIndex() + 1);
this.prev = this.snapshots(this.findIndex() - 1);
return this;
},
neighbour: function(direction) {
return this.snapshots(this.findIndex() + direction);
}
};
}])
.service('Contracts', ['$timeout', '$injector', 'loading', 'dateUtils', '$filter', '$q', 'contracts', 'utils', 'Engagements', 'config', function($timeout, $injector, loading, dateUtils, $filter, $q, contracts, utils, Engagements, config) {
var limit = 20;
var _items = _.chain(config.contracts)
.values()
.concat(contracts)
.flatten()
.compact()
.uniqBy('reference')
.sortBy('reference')
.value();
var loaded = {};
//teamId { page: is past }
return {
page: 0,
lastQuery: '',
query: function(query) {
if (query) {
this.lastQuery = query;
return this;
}
return this.lastQuery;
},
cache: {},
add: function(query, data) {
var contract, i = 0, l = data.length,
hash = this.hasher(query),
contracts = this.cache[hash];
if (!contracts) {
this.cache[hash] = [];
contracts = this.cache[hash];
}
for (; i < l; ) {
contract = data[i++];
if (_.find(contracts, { 'reference': contract.reference })) {
continue;
}
contract.buyer_team_id = contract.buyer_team__id;
contracts.push(contract);
}
return data;
},
isLoaded: function(query) {
return !!this.cache[this.hasher(query)];
},
get: function(query) {
return this.cache[this.hasher(query)] || [];
},
all: function() {
if (!_.size(this.cache)) {
return [];
}
return _.chain(this.cache)
.values()
.flatten()
.compact()
.value();
},
count: function(query, teamId) {
return _.get(this.cache, this.hasher(query, teamId), []).length;
},
hasher: _.memoize(function(str, teamId) {
str = str || '';
teamId = teamId || config.teamId;
return utils.hash('' + str + teamId + config.includePast);
}, function(str, teamId) {
return '' + str + (teamId || config.teamId) + config.includePast;
}),
lister: {},
pageHashes: {},
find: function(ref) {
if (!ref) {
return;
}
return _.find(this.all(), function(contract) {
return _.includes([
String(contract.reference),
String(contract.parent_reference)
],
ref.toString()
);
});
},
getPage: function(query) {
var hash = this.hasher(query);
if (utils.isUndefined(this.pageHashes[hash])) {
this.pageHashes[hash] = 0;
}
return this.pageHashes[hash];
},
incPage: function(query) {
var hash = this.hasher(query);
if (utils.isUndefined(this.pageHashes[hash])) {
this.pageHashes[hash] = 0;
}
this.pageHashes[hash]++;
},
requests: {},
fetch: function(query, page) {
query = query || '';
this.page = _.isUndefined(page) ? this.getPage(query) : page;
var params = {
//offset:count
page: (+this.page*limit)+';'+limit,
};
params.regex = query;
var self = this;
params.includePast = config.includePast;
this.query(query);
if (this.requests[this.hasher(query)]) {
return this.requests[this.hasher(query)];
}
this.requests[this.hasher(query)] = Engagements
.fetch(params)
.then(function(response) {
self.incPage(query);
self.lister = _.get(response, 'data.lister', []);
self.requests[self.hasher(query)] = false;
return self.add(query, _.get(response, 'data.engagements', []));
});
return this.requests[this.hasher(query)];
},
fetchByRef: function(ref, successCallback, errorCallback) {
var self = this;
if (this.requests[this.hasher(ref)]) {
return this.requests[this.hasher(ref)];
}
this.requests[this.hasher(ref)] = Engagements
.one(ref, successCallback, errorCallback)
.then(function(response) {
var contract = _.get(response, 'data.engagement');
if (contract) {
self.add(ref, [contract]);
config.contracts.push(contract);
}
self.requests[self.hasher(ref)] = false;
return contract;
});
return this.requests[this.hasher(ref)];
},
byTeamRef: function(teamId) {
teamId = teamId || config.teamId;
return _.filter(this.all(), {buyer_team__id: teamId});
},
getFirstActiveContract: function(teamRef) {
return _.chain(this.all())
.filter(['is_paused', false])
.orderBy(['engagement_title', 'provider__name'], ['asc', 'asc'])
.first()
.value();
},
};
}])
;
})(angular);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment