-
Notifications
You must be signed in to change notification settings - Fork 8.2k
/
config.js
158 lines (134 loc) · 4.49 KB
/
config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
define(function (require) {
var module = require('ui/modules').get('kibana/config', [
'kibana/notify'
]);
require('ui/routes').addSetupWork(function (config) {
return config.init();
});
// service for delivering config variables to everywhere else
module.service('config', function (Private, Notifier, kbnVersion, kbnIndex, $rootScope, buildNum) {
var config = this;
var angular = require('angular');
var _ = require('lodash');
var defaults = Private(require('ui/config/defaults'));
var DelayedUpdater = Private(require('ui/config/_delayed_updater'));
var vals = Private(require('ui/config/_vals'));
var notify = new Notifier({
location: 'Config'
});
// active or previous instance of DelayedUpdater. This will log and then process an
// update once it is requested by calling #set() or #clear().
var updater;
var DocSource = Private(require('ui/courier/data_source/doc_source'));
var doc = (new DocSource())
.index(kbnIndex)
.type('config')
.id(kbnVersion);
/******
* PUBLIC API
******/
/**
* Executes once and returns a promise that is resolved once the
* config has loaded for the first time.
*
* @return {Promise} - Resolved when the config loads initially
*/
config.init = _.once(function () {
var complete = notify.lifecycle('config init');
return (function getDoc() {
// used to apply an entire es response to the vals, silentAndLocal will prevent
// event/notifications/writes from occuring.
var applyMassUpdate = function (resp, silentAndLocal) {
_.union(_.keys(resp._source), _.keys(vals)).forEach(function (key) {
change(key, resp._source[key], silentAndLocal);
});
};
return doc.fetch().then(function initDoc(resp) {
if (!resp.found) {
return doc.doIndex({
buildNum: buildNum
}).then(getDoc);
} else {
// apply update, and keep it quiet the first time
applyMassUpdate(resp, true);
// don't keep it quiet other times
doc.onUpdate(function (resp) {
applyMassUpdate(resp, false);
});
}
});
}())
.then(function () {
$rootScope.$broadcast('init:config');
})
.then(complete, complete.failure);
});
config.get = function (key, defaultVal) {
var keyVal;
if (vals[key] == null) {
if (defaultVal == null) {
keyVal = defaults[key].value;
} else {
keyVal = _.cloneDeep(defaultVal);
}
} else {
keyVal = vals[key];
}
if (defaults[key] && defaults[key].type === 'json') {
return JSON.parse(keyVal);
}
return keyVal;
};
// sets a value in the config
config.set = function (key, val) {
if (_.isPlainObject(val)) {
return change(key, angular.toJson(val));
} else {
return change(key, val);
}
};
// clears a value from the config
config.clear = function (key) {
return change(key);
};
// alias for clear
config.delete = config.clear;
config.close = function () {
if (updater) updater.fire();
};
/**
* A little helper for binding config variables to $scopes
*
* @param {Scope} $scope - an angular $scope object
* @param {string} key - the config key to bind to
* @param {string} [property] - optional property name where the value should
* be stored. Defaults to the config key
* @return {function} - an unbind function
*/
config.$bind = function ($scope, key, property) {
if (!property) property = key;
var update = function () {
$scope[property] = config.get(key);
};
update();
return _.partial(_.invoke, [
$scope.$on('change:config.' + key, update),
$scope.$on('init:config', update)
], 'call');
};
/*****
* PRIVATE API
*****/
function change(key, val, silentAndLocal) {
// if the previous updater has already fired, then start over with null
if (updater && updater.fired) updater = null;
// create a new updater
if (!updater) updater = new DelayedUpdater(doc);
// return a promise that will be resolved once the action is eventually done
return updater.update(key, val, silentAndLocal);
}
config._vals = function () {
return _.cloneDeep(vals);
};
});
});