lib.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. // Licensed to Cloudera, Inc. under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. Cloudera, Inc. licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. // Start Models
  17. var Collection = function(name) {
  18. var self = this;
  19. self.name = ko.observable(name).extend({'errors': null});
  20. self.fields = ko.observableArray();
  21. // Metadata
  22. self.uniqueKeyField = ko.observable().extend({'errors': null});
  23. self.hasHueCollection = ko.observable(true).extend({'errors': null});
  24. self.hasSolrCollection = ko.observable(true).extend({'errors': null});
  25. self.removeField = function(field) {
  26. if (field.name() != self.uniqueKeyField()) {
  27. self.fields.remove(field);
  28. }
  29. };
  30. self.addField = function(name, type) {
  31. self.fields.push(new Field(self, name, type));
  32. };
  33. self.newField = function() {
  34. self.addField('', 'text_general');
  35. };
  36. self.setData = function(data_json) {
  37. self.data(data_json);
  38. };
  39. };
  40. var Field = function(collection, name, type, required, indexed, stored) {
  41. var self = this;
  42. indexed = (indexed == undefined) ? true : !!indexed;
  43. required = (required == undefined) ? true : !!required;
  44. self.name = ko.observable(name).extend({'errors': null});
  45. self.type = ko.observable(type).extend({'errors': null});
  46. self.required = ko.observable(required).extend({'errors': null});
  47. self.indexed = ko.observable(indexed).extend({'errors': null});
  48. self.stored = ko.observable(stored).extend({'errors': null});
  49. // Metadata
  50. self.saved = ko.observable(false);
  51. self.uniqueKeyField = ko.computed({
  52. 'read': function() {
  53. return collection.uniqueKeyField() == self.name();
  54. },
  55. 'write': function(value) {
  56. collection.uniqueKeyField(self.name());
  57. self.indexed(true);
  58. }
  59. });
  60. self.editable = ko.computed(function() {
  61. return !self.uniqueKeyField() && self.name() != '_version_';
  62. });
  63. self.remove = function() {
  64. collection.removeField(self);
  65. };
  66. };
  67. var HiveDatabase = function(name) {
  68. var self = this;
  69. self.name = ko.observable(name).extend({'errors': null});
  70. self.tables = ko.observableArray();
  71. };
  72. var HiveTable = function(name) {
  73. var self = this;
  74. self.name = ko.observable(name).extend({'errors': null});
  75. self.columns = ko.observableArray();
  76. };
  77. var HBaseCluster = function(name) {
  78. var self = this;
  79. self.name = ko.observable(name).extend({'errors': null});
  80. self.tables = ko.observableArray();
  81. };
  82. var HBaseTable = function(name) {
  83. var self = this;
  84. self.name = ko.observable(name).extend({'errors': null});
  85. };
  86. // End Models
  87. // Start Wizard
  88. var Page = function(url, name, next, validate_fn) {
  89. var self = this;
  90. self.name = ko.observable(name);
  91. self.url = ko.observable(url);
  92. self.next = ko.observable(next);
  93. self.validate = validate_fn || function() { return true; };
  94. };
  95. var Wizard = function() {
  96. var self = this;
  97. self.rootPage = ko.observable();
  98. self.currentPage = ko.observable(self.rootPage());
  99. // Stack of previous pages.
  100. self.previousPages = ko.observableArray();
  101. self.pages = {};
  102. self.hasPrevious = ko.computed(function() {
  103. return self.previousPages().length > 0;
  104. });
  105. self.hasNext = ko.computed(function() {
  106. return !!(self.currentPage() && self.currentPage().next());
  107. });
  108. self.pageList = ko.computed(function() {
  109. var page = self.rootPage();
  110. var pages = [];
  111. while(page) {
  112. pages.push(page);
  113. page = self.pages[page.next()];
  114. }
  115. return pages;
  116. });
  117. self.previousUrl = ko.computed(function() {
  118. if (self.previousPages().length > 0) {
  119. return self.previousPages()[self.previousPages().length - 1].url();
  120. } else {
  121. return null;
  122. }
  123. });
  124. self.nextUrl = ko.computed(function() {
  125. if (self.currentPage() && self.currentPage().next()) {
  126. return self.currentPage().next();
  127. } else {
  128. return null;
  129. }
  130. });
  131. self.next = function() {
  132. if (self.hasNext() && self.currentPage().validate()) {
  133. self.previousPages.push(self.currentPage());
  134. self.currentPage(self.pages[self.currentPage().next()]);
  135. }
  136. };
  137. self.previous = function() {
  138. if (self.hasPrevious()) {
  139. self.currentPage(self.previousPages.pop());
  140. }
  141. };
  142. self.setPageByUrl = function(url) {
  143. var urls = ko.utils.arrayMap(self.pageList(), function(page) {
  144. return page.url();
  145. });
  146. var previousUrls = ko.utils.arrayMap(self.previousPages(), function(page) {
  147. return page.url();
  148. });
  149. if ($.inArray(url, previousUrls) != -1) {
  150. var previousPageURL = null;
  151. self.previous();
  152. while(self.hasPrevious() && self.currentPage().url() != url && self.currentPage().url() != previousPageURL) {
  153. previousPageURL = self.currentPage().url();
  154. self.previous();
  155. }
  156. } else if ($.inArray(url, urls) != -1) {
  157. var previousPageURL = null;
  158. while(self.hasNext() && self.currentPage().url() != url && self.currentPage().url() != previousPageURL) {
  159. previousPageURL = self.currentPage().url();
  160. self.next();
  161. }
  162. }
  163. };
  164. self.getPage = function(url, name, next, validate_fn) {
  165. self.pages;
  166. if (!self.pages[url]) {
  167. self.pages[url] = new Page(url, name, next, validate_fn);
  168. }
  169. return self.pages[url];
  170. };
  171. };
  172. // End Wizard
  173. // Start utils
  174. ko.bindingHandlers.routie = {
  175. init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
  176. $(element).click(function() {
  177. var obj = ko.utils.unwrapObservable(valueAccessor());
  178. var url = null;
  179. var bubble = false;
  180. if ($.isPlainObject(obj)) {
  181. url = obj.url;
  182. bubble = !!obj.bubble;
  183. } else {
  184. url = obj;
  185. }
  186. routie(url);
  187. return bubble;
  188. });
  189. }
  190. };
  191. ko.bindingHandlers.filter = {
  192. init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
  193. var obj = ko.utils.unwrapObservable(valueAccessor());
  194. var test_fn = obj.test;
  195. var list = obj.list;
  196. var filteredList = obj.filteredList;
  197. filteredList(list());
  198. $(element).keyup(function(e) {
  199. if (e.target.value) {
  200. filteredList(ko.utils.arrayFilter(list(), function(obj) {
  201. return test_fn(obj, e.target.value);
  202. }));
  203. } else {
  204. filteredList(list());
  205. }
  206. return (obj.bubble == undefined) ? false : obj.bubble;
  207. });
  208. }
  209. };
  210. ko.extenders.errors = function(target, options) {
  211. target.errors = ko.observableArray();
  212. target.errors.remove = function(obj) {
  213. var index = target.errors().indexOf(obj);
  214. if (index > -1) {
  215. target.errors.splice(index, 1);
  216. }
  217. };
  218. return target;
  219. };
  220. ko.extenders.selectable = function(target, options) {
  221. target.selected = ko.observable(false);
  222. target.toggleSelect = function() {
  223. target.selected(!target.selected());
  224. };
  225. return target;
  226. };
  227. ko.bindingHandlers.chosen = {
  228. init: function(element, options) {
  229. $(element).chosen(options);
  230. },
  231. update: function(element) {
  232. $(element).trigger('chosen:updated');
  233. }
  234. };
  235. ko.bindingHandlers.editableText = {
  236. init: function(element, valueAccessor) {
  237. $(element).attr('contenteditable', true);
  238. $(element).on('click', function() {
  239. $(element).focus();
  240. });
  241. $(element).on('blur', function() {
  242. var observable = valueAccessor();
  243. observable( $(this).text() );
  244. });
  245. },
  246. update: function(element, valueAccessor) {
  247. var value = ko.utils.unwrapObservable(valueAccessor());
  248. $(element).text(value);
  249. }
  250. };
  251. function chooseUniqueKey(collection) {
  252. function fieldChooser(fields) {
  253. if (fields.length > 0) {
  254. fields[0].uniqueKeyField(true);
  255. return true;
  256. }
  257. return false;
  258. }
  259. // Find a field named "ID"
  260. if (fieldChooser(ko.utils.arrayFilter(collection.fields(), function(field) {
  261. return field.name().toLowerCase() == 'id';
  262. }))) return;
  263. // Find a long
  264. if (fieldChooser(ko.utils.arrayFilter(collection.fields(), function(field) {
  265. return $.inArray(field.type().toLowerCase(), ['long', 'tlong', 'plong']) != -1;
  266. }))) return;
  267. // Find an integer
  268. if (fieldChooser(ko.utils.arrayFilter(collection.fields(), function(field) {
  269. return $.inArray(field.type().toLowerCase(), ['int', 'tint', 'pint']) != -1;
  270. }))) return;
  271. // Find first indexed field
  272. if (fieldChooser(ko.utils.arrayFilter(collection.fields(), function(field) {
  273. return field.indexed();
  274. }))) return;
  275. // Choose a field
  276. fieldChooser(collection.fields());
  277. }
  278. function getCharacterLabel(character) {
  279. var LABELS = {
  280. '\t': '\\t'
  281. };
  282. if (LABELS[character]) {
  283. return LABELS[character];
  284. } else {
  285. return character;
  286. }
  287. }
  288. function validateNotNull(obs, message) {
  289. var ret = true;
  290. if (!obs()) {
  291. obs.errors.push(message);
  292. ret = false;
  293. } else {
  294. obs.errors.remove(message);
  295. }
  296. return ret;
  297. }
  298. // End utils