config_history_flow.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. var App = require('app');
  19. App.ConfigHistoryFlowView = Em.View.extend({
  20. templateName: require('templates/common/configs/config_history_flow'),
  21. /**
  22. * index of the first element(service version box) in viewport
  23. */
  24. startIndex: 0,
  25. showLeftArrow: false,
  26. showRightArrow: false,
  27. VERSIONS_IN_FLOW: 5,
  28. VERSIONS_IN_DROPDOWN: 6,
  29. /**
  30. * flag identify whether to show all versions or short list of them
  31. */
  32. showFullList: false,
  33. compareServiceVersion: null,
  34. showCompareVersionBar: function() {
  35. return !Em.isNone(this.get('compareServiceVersion'));
  36. }.property('compareServiceVersion'),
  37. isSaveDisabled: function () {
  38. return (this.get('controller.isSubmitDisabled') || !this.get('controller.versionLoaded'));
  39. }.property('controller.isSubmitDisabled', 'controller.versionLoaded'),
  40. serviceName: function () {
  41. return this.get('controller.selectedService.serviceName');
  42. }.property('controller.selectedService.serviceName'),
  43. selectedConfigGroupName: function () {
  44. return this.get('controller.selectedConfigGroup.displayName');
  45. }.property('controller.selectedConfigGroup.displayName'),
  46. isDefaultConfigGroupSelected: function () {
  47. return this.get('controller.selectedConfigGroup.isDefault');
  48. }.property('controller.selectedConfigGroup.isDefault'),
  49. displayedServiceVersion: function () {
  50. return this.get('serviceVersions').findProperty('isDisplayed');
  51. }.property('serviceVersions.@each.isDisplayed'),
  52. /**
  53. * identify whether to show link that open whole content of notes
  54. */
  55. showMoreLink: function () {
  56. //100 is number of symbols that fit into label
  57. return (this.get('displayedServiceVersion.notes.length') > 100);
  58. }.property('displayedServiceVersion.notes.length'),
  59. /**
  60. * formatted notes ready to display
  61. */
  62. shortNotes: function () {
  63. //100 is number of symbols that fit into label
  64. if (this.get('showMoreLink')) {
  65. return this.get('displayedServiceVersion.notes').slice(0, 100) + '...';
  66. }
  67. return this.get('displayedServiceVersion.notes');
  68. }.property('displayedServiceVersion'),
  69. serviceVersions: function () {
  70. var serviceVersions;
  71. var allServiceVersions = App.ServiceConfigVersion.find().filterProperty('serviceName', this.get('serviceName'));
  72. if (this.get('isDefaultConfigGroupSelected')) {
  73. // filtered all versions which belong to default group
  74. serviceVersions = allServiceVersions.filterProperty('groupName', null);
  75. serviceVersions.forEach( function (version) {
  76. version.set('isDisabled', false);
  77. });
  78. }else {
  79. // filter out default group(should be grayedOut) and current selectedGroup versions
  80. var defaultServiceVersions = allServiceVersions.filterProperty('groupName', null);
  81. defaultServiceVersions.forEach( function (version) {
  82. version.set('isDisabled', true);
  83. });
  84. var selectedServiceVersions = allServiceVersions.filterProperty('groupName', this.get('selectedConfigGroupName'));
  85. selectedServiceVersions.forEach( function (version) {
  86. version.set('isDisabled', false);
  87. });
  88. serviceVersions = selectedServiceVersions.concat(defaultServiceVersions) ;
  89. }
  90. return serviceVersions.sort(function (a, b) {
  91. return Em.get(a, 'createTime') - Em.get(b, 'createTime');
  92. });
  93. }.property('serviceName', 'selectedConfigGroupName', 'isDefaultConfigGroupSelected'),
  94. /**
  95. * service versions which in viewport and visible to user
  96. */
  97. visibleServiceVersion: function () {
  98. return this.get('serviceVersions').slice(this.get('startIndex'), (this.get('startIndex') + this.VERSIONS_IN_FLOW));
  99. }.property('startIndex'),
  100. /**
  101. * enable actions to manipulate version only after it's loaded
  102. */
  103. versionActionsDisabled: function () {
  104. return !this.get('controller.versionLoaded');
  105. }.property('controller.versionLoaded'),
  106. /**
  107. * list of service versions
  108. * by default 6 is number of items in short list
  109. */
  110. dropDownList: function () {
  111. var serviceVersions = this.get('serviceVersions').without(this.get('displayedServiceVersion')).slice(0).reverse();
  112. if (this.get('showFullList')) {
  113. return serviceVersions;
  114. }
  115. return serviceVersions.slice(0, this.VERSIONS_IN_DROPDOWN);
  116. }.property('serviceVersions', 'showFullList', 'displayedServiceVersion'),
  117. openFullList: function (event) {
  118. event.stopPropagation();
  119. this.set('showFullList', true);
  120. },
  121. hideFullList: function (event) {
  122. this.set('showFullList', !(this.get('serviceVersions.length') > this.VERSIONS_IN_DROPDOWN));
  123. },
  124. didInsertElement: function () {
  125. App.tooltip(this.$('[data-toggle=tooltip]'),{
  126. placement: 'bottom'
  127. });
  128. },
  129. willInsertElement: function () {
  130. var serviceVersions = this.get('serviceVersions');
  131. var startIndex = 0;
  132. serviceVersions.setEach('isDisplayed', false);
  133. //set the correct version to display
  134. var allCurrent = serviceVersions.filterProperty('isCurrent');
  135. if (this.get('isDefaultConfigGroupSelected')) {
  136. // display current in default group
  137. allCurrent.findProperty('groupName', null).set('isDisplayed', true);
  138. }else {
  139. // display current in selected group
  140. var current = allCurrent.findProperty('groupName', this.get('selectedConfigGroupName'));
  141. current ? current.set('isDisplayed', true) : allCurrent.findProperty('groupName', null).set('isDisplayed', true);
  142. }
  143. if (serviceVersions.length > 0) {
  144. if (serviceVersions.length > this.VERSIONS_IN_FLOW) {
  145. startIndex = serviceVersions.length - this.VERSIONS_IN_FLOW;
  146. }
  147. this.set('startIndex', startIndex);
  148. this.adjustFlowView();
  149. }
  150. this.keepInfoBarAtTop();
  151. },
  152. /**
  153. * initialize event to keep info bar position at the top of the page
  154. */
  155. keepInfoBarAtTop: function () {
  156. var defaultTop;
  157. var self = this;
  158. //reset defaultTop value in closure
  159. $(window).unbind('scroll');
  160. $(window).on('scroll', function (event) {
  161. var infoBar = $('#config_history_flow>.version-info-bar-wrapper');
  162. var scrollTop = $(window).scrollTop();
  163. if (infoBar.length === 0) {
  164. $(window).unbind('scroll');
  165. return;
  166. }
  167. //290 - default "top" property in px
  168. defaultTop = defaultTop || (infoBar.get(0).getBoundingClientRect() && infoBar.get(0).getBoundingClientRect().top) || 290;
  169. self.setInfoBarPosition(infoBar, defaultTop, scrollTop);
  170. })
  171. },
  172. /**
  173. * calculate and reset top position of info bar
  174. * @param infoBar
  175. * @param defaultTop
  176. * @param scrollTop
  177. */
  178. setInfoBarPosition: function (infoBar, defaultTop, scrollTop) {
  179. if (scrollTop > defaultTop) {
  180. infoBar.css('top', '10px');
  181. } else if (scrollTop > 0) {
  182. infoBar.css('top', (defaultTop - scrollTop) + 'px');
  183. } else {
  184. infoBar.css('top', 'auto');
  185. }
  186. },
  187. /**
  188. * define the first element in viewport
  189. * change visibility of arrows
  190. */
  191. adjustFlowView: function () {
  192. var startIndex = this.get('startIndex');
  193. this.get('serviceVersions').forEach(function (serviceVersion, index) {
  194. serviceVersion.set('first', (index === startIndex));
  195. });
  196. this.set('showLeftArrow', (startIndex !== 0));
  197. this.set('showRightArrow', (this.get('serviceVersions.length') > this.VERSIONS_IN_FLOW) && ((startIndex + this.VERSIONS_IN_FLOW) !== this.get('serviceVersions.length')));
  198. },
  199. /**
  200. * switch configs view version to chosen
  201. */
  202. switchVersion: function (event) {
  203. var version = event.context.get('version');
  204. var versionIndex = 0;
  205. this.set('compareServiceVersion', null);
  206. this.get('serviceVersions').forEach(function (serviceVersion, index) {
  207. if (serviceVersion.get('version') === version) {
  208. serviceVersion.set('isDisplayed', true);
  209. versionIndex = index;
  210. } else {
  211. serviceVersion.set('isDisplayed', false);
  212. }
  213. });
  214. this.shiftFlowOnSwitch(versionIndex);
  215. this.get('controller').loadSelectedVersion(version);
  216. },
  217. /**
  218. * add config values of chosen version to view for comparison
  219. * add a second version-info-bar for the chosen version
  220. */
  221. compare: function (event) {
  222. var isDisabled = event.context ? event.context.get('isDisabled') : false;
  223. if (isDisabled) return;
  224. this.set('controller.compareServiceVersion', event.context);
  225. this.set('compareServiceVersion', event.context);
  226. this.get('controller').onConfigGroupChange();
  227. },
  228. /**
  229. * revert config values to chosen version and apply reverted configs to server
  230. */
  231. revert: function (event) {
  232. var self = this;
  233. var isDisabled = event.context ? event.context.get('isDisabled') : false;
  234. if (isDisabled) return;
  235. var serviceConfigVersion = event.context || Em.Object.create({
  236. version: this.get('displayedServiceVersion.version'),
  237. serviceName: this.get('displayedServiceVersion.serviceName'),
  238. notes:''
  239. });
  240. var versionText = event.context ? event.context.get('versionText') : this.get('displayedServiceVersion.versionText');
  241. var configGroupName = this.get('displayedServiceVersion.configGroupName');
  242. return App.ModalPopup.show({
  243. header: Em.I18n.t('dashboard.configHistory.info-bar.makeCurrent.popup.title'),
  244. serviceConfigNote: Em.I18n.t('services.service.config.configHistory.makeCurrent.message').format(versionText),
  245. bodyClass: Em.View.extend({
  246. templateName: require('templates/common/configs/save_configuration'),
  247. notesArea: Em.TextArea.extend({
  248. classNames: ['full-width'],
  249. value: Em.I18n.t('services.service.config.configHistory.makeCurrent.message').format(versionText),
  250. onChangeValue: function() {
  251. this.get('parentView.parentView').set('serviceConfigNote', this.get('value'));
  252. }.observes('value')
  253. })
  254. }),
  255. primary: Em.I18n.t('dashboard.configHistory.info-bar.revert.button'),
  256. secondary: Em.I18n.t('common.discard'),
  257. third: Em.I18n.t('common.cancel'),
  258. onPrimary: function () {
  259. serviceConfigVersion.set('serviceConfigNote', this.get('serviceConfigNote'));
  260. self.sendRevertCall(serviceConfigVersion);
  261. this.hide();
  262. }
  263. });
  264. },
  265. /**
  266. * send PUT call to revert config to selected version
  267. * @param serviceConfigVersion
  268. */
  269. sendRevertCall: function (serviceConfigVersion) {
  270. App.ajax.send({
  271. name: 'service.serviceConfigVersion.revert',
  272. sender: this,
  273. data: {
  274. data: {
  275. "Clusters": {
  276. "desired_service_config_versions": {
  277. "service_config_version": serviceConfigVersion.get('version'),
  278. "service_name": serviceConfigVersion.get('serviceName'),
  279. "service_config_version_note": serviceConfigVersion.get('serviceConfigNote')
  280. }
  281. }
  282. }
  283. },
  284. success: 'sendRevertCallSuccess'
  285. });
  286. },
  287. sendRevertCallSuccess: function (data, opt, params) {
  288. // revert to an old version would generate a new version with latest version number,
  289. // so, need to loadStep to update
  290. this.get('controller').loadStep();
  291. },
  292. /**
  293. * save configuration
  294. * @return {object}
  295. */
  296. save: function () {
  297. var self = this;
  298. return App.ModalPopup.show({
  299. header: Em.I18n.t('dashboard.configHistory.info-bar.save.popup.title'),
  300. serviceConfigNote: '',
  301. bodyClass: Em.View.extend({
  302. templateName: require('templates/common/configs/save_configuration'),
  303. notesArea: Em.TextArea.extend({
  304. classNames: ['full-width'],
  305. placeholder: Em.I18n.t('dashboard.configHistory.info-bar.save.popup.placeholder'),
  306. onChangeValue: function() {
  307. this.get('parentView.parentView').set('serviceConfigNote', this.get('value'));
  308. }.observes('value')
  309. })
  310. }),
  311. footerClass: Ember.View.extend({
  312. templateName: require('templates/main/service/info/save_popup_footer')
  313. }),
  314. primary: Em.I18n.t('common.save'),
  315. secondary: Em.I18n.t('common.cancel'),
  316. onSave: function () {
  317. self.get('controller').set('serviceConfigVersionNote', this.get('serviceConfigNote'));
  318. self.get('controller').restartServicePopup();
  319. this.hide();
  320. },
  321. onDiscard: function () {
  322. this.hide();
  323. },
  324. onCancel: function () {
  325. this.hide();
  326. }
  327. });
  328. },
  329. /**
  330. * move back to the previous service version
  331. */
  332. shiftBack: function () {
  333. this.decrementProperty('startIndex');
  334. this.adjustFlowView();
  335. },
  336. /**
  337. * move forward to the next service version
  338. */
  339. shiftForward: function () {
  340. this.incrementProperty('startIndex');
  341. this.adjustFlowView();
  342. },
  343. /**
  344. * shift flow view to position where selected version is visible
  345. * @param versionIndex
  346. */
  347. shiftFlowOnSwitch: function (versionIndex) {
  348. var serviceVersions = this.get('serviceVersions');
  349. if ((this.get('startIndex') + this.VERSIONS_IN_FLOW) < versionIndex || versionIndex < this.get('startIndex')) {
  350. versionIndex = (serviceVersions.length < (versionIndex + this.VERSIONS_IN_FLOW)) ? serviceVersions.length - this.VERSIONS_IN_FLOW : versionIndex;
  351. this.set('startIndex', versionIndex);
  352. this.adjustFlowView();
  353. }
  354. }
  355. });