API Docs for: 1.0.0
Show:

File: Resources/public/js/views/services/ez-locationviewviewservice.js

  1. /*
  2. * Copyright (C) eZ Systems AS. All rights reserved.
  3. * For full copyright and license information view LICENSE file distributed with this source code.
  4. */
  5. YUI.add('ez-locationviewviewservice', function (Y) {
  6. "use strict";
  7. /**
  8. * Provides the view service component for the location view
  9. *
  10. * @module ez-locationviewviewservice
  11. */
  12. Y.namespace('eZ');
  13.  
  14. /**
  15. * Location view view service.
  16. *
  17. * Loads the models needed by the location view
  18. *
  19. * @namespace eZ
  20. * @class LocationViewViewService
  21. * @constructor
  22. * @extends eZ.ViewService
  23. */
  24. Y.eZ.LocationViewViewService = Y.Base.create('locationViewViewService', Y.eZ.ViewService, [Y.eZ.DraftConflict], {
  25. initializer: function () {
  26. this.on('*:editAction', this._editContent);
  27. this.on('*:sendToTrashAction', this._sendContentToTrashConfirmBox);
  28. this.on('*:deleteContentAction', this._confirmDeleteContent);
  29. this.on('*:moveAction', this._selectLocation);
  30. this.on('*:translateContent', this._translateContent);
  31. this.on('*:sortUpdate', this._updateSorting);
  32. this.after('*:requestChange', this._setLanguageCode);
  33.  
  34. this._setLanguageCode();
  35. },
  36.  
  37. /**
  38. * editAction event handler, makes the application navigate to edit the
  39. * content available in the event facade
  40. *
  41. * @method _editContent
  42. * @protected
  43. * @param {Object} e event facade of the editAction event
  44. */
  45. _editContent: function (e) {
  46. this._fireEditContentRequest(
  47. this.get('location').get('contentInfo'),
  48. this.get('contentType')
  49. );
  50. },
  51.  
  52. /**
  53. * `sendToTrashAction` event handler,
  54. * it asks confirmation to the user before sending the location to the trash.
  55. *
  56. * @method _sendContentToTrashConfirmBox
  57. * @protected
  58. * @param {Object} e event facade of the sendToTrashAction event
  59. */
  60. _sendContentToTrashConfirmBox: function (e) {
  61. e.preventDefault();
  62. this.fire('confirmBoxOpen', {
  63. config: {
  64. title: Y.eZ.trans('confirmed.send.to.trash', {}, 'locationview'),
  65. confirmHandler: Y.bind(function () {
  66. this._sendToTrash(e.content);
  67. }, this)
  68. },
  69. });
  70. },
  71.  
  72. /**
  73. * `deleteContentAction` event handler,
  74. * it asks confirmation to the user before delete the content item.
  75. *
  76. * @method _confirmDeleteContent
  77. * @protected
  78. * @param {Object} e event facade of the deleteAction event
  79. */
  80. _confirmDeleteContent: function (e) {
  81. e.preventDefault();
  82. this.fire('confirmBoxOpen', {
  83. config: {
  84. title: Y.eZ.trans('confirmed.delete', {}, 'locationview'),
  85. confirmHandler: Y.bind(this._deleteContent, this),
  86. },
  87. });
  88. },
  89.  
  90. /**
  91. * moveAction event handler, launch the universal discovery widget
  92. * to choose a location to move the content
  93. *
  94. * @method _selectLocation
  95. * @protected
  96. * @param {EventFacade} e
  97. */
  98. _selectLocation: function (e) {
  99. this.fire('contentDiscover', {
  100. config: {
  101. title: Y.eZ.trans('select.location.move.to', {}, 'locationview'),
  102. contentDiscoveredHandler: Y.bind(this._moveContent, this),
  103. isSelectable: function (contentStruct) {
  104. return contentStruct.contentType.get('isContainer');
  105. },
  106. },
  107. });
  108. },
  109.  
  110. /**
  111. * Sends location to trash, triggering loading parent location and notifications
  112. *
  113. * @method _sendToTrash
  114. * @protected
  115. */
  116. _sendToTrash: function () {
  117. var that = this,
  118. location = this.get('location'),
  119. locationId = location.get('id'),
  120. path = this.get('path'),
  121. content = this.get('content'),
  122. parentLocation = path[path.length - 1];
  123.  
  124. this._notify(
  125. Y.eZ.trans('sending.to.trash', {name: content.get('name')}, 'locationview'),
  126. 'send-to-trash-' + locationId,
  127. 'started',
  128. 0
  129. );
  130.  
  131. location.trash({api: this.get('capi')}, Y.bind(that._afterSendToTrashCallback, that, parentLocation, content));
  132. },
  133.  
  134. /**
  135. * Deletes the the content item, triggering loading parent location and notifications
  136. *
  137. * @method _deleteContent
  138. * @protected
  139. */
  140. _deleteContent: function () {
  141. var path = this.get('path'),
  142. content = this.get('content'),
  143. parentLocation = path[path.length - 1];
  144.  
  145. this._notify(
  146. Y.eZ.trans('deleting.content', {name: content.get('name')}, 'locationview'),
  147. 'delete-' + content.get('id'),
  148. 'started',
  149. 0
  150. );
  151.  
  152. content.delete({api: this.get('capi')}, Y.bind(this._afterDeleteCallback, this, parentLocation, content));
  153. },
  154.  
  155. /**
  156. * Send to trash callback triggering notifications and making app to navigate to parent location
  157. *
  158. * @method _afterSendToTrashCallback
  159. * @protected
  160. * @param {eZ.Location} parentLocation the parent location to which app will navigate to
  161. * @param {eZ.Content} content the content to be trashed
  162. * @param {Boolean} error
  163. */
  164. _afterSendToTrashCallback: function (parentLocation, content, error) {
  165. var app = this.get('app'),
  166. location = this.get('location'),
  167. locationId = location.get('id'),
  168. contentName = content.get('name');
  169.  
  170. if (error) {
  171. this._notify(
  172. Y.eZ.trans('failed.sending.to.trash', {name: contentName}, 'locationview'),
  173. 'send-to-trash-' + locationId,
  174. 'error',
  175. 0
  176. );
  177. return;
  178. }
  179.  
  180. this._notify(
  181. Y.eZ.trans('sent.to.trash', {name: contentName}, 'locationview'),
  182. 'send-to-trash-' + locationId,
  183. 'done',
  184. 5
  185. );
  186.  
  187. /**
  188. * Fired when the content is sent to trash
  189. *
  190. * @event sentToTrash
  191. * @param {eZ.Location} location
  192. */
  193. this.fire('sentToTrash', {location: location});
  194.  
  195. app.navigateTo('viewLocation', {
  196. id: parentLocation.get('id'),
  197. languageCode: content.get('mainLanguageCode')
  198. });
  199. },
  200.  
  201. /**
  202. * Delete content item callback triggering notifications and making app to navigate to parent location
  203. *
  204. * @method _afterDeleteCallback
  205. * @protected
  206. * @param {eZ.Location} parentLocation the parent location to which app will navigate to
  207. * @param {eZ.Content} content the content item that has been deleted
  208. * @param {Boolean} error
  209. */
  210. _afterDeleteCallback: function (parentLocation, content, error) {
  211. var app = this.get('app'),
  212. contentName = content.get('name');
  213.  
  214. if (error) {
  215. this._notify(
  216. Y.eZ.trans('failed.deleting.content', {name: contentName}, 'locationview'),
  217. 'delete-' + content.get('id'),
  218. 'error',
  219. 0
  220. );
  221. return;
  222. }
  223.  
  224. this._notify(
  225. Y.eZ.trans('deleted.content', {name: contentName}, 'locationview'),
  226. 'delete-' + content.get('id'),
  227. 'done',
  228. 5
  229. );
  230.  
  231. /**
  232. * Fired when the content has been deleted
  233. *
  234. * @event deletedContent
  235. * @param {eZ.Content} content
  236. */
  237. this.fire('deletedContent', {content: content});
  238.  
  239. app.navigateTo('viewLocation', {
  240. id: parentLocation.get('id'),
  241. languageCode: content.get('mainLanguageCode')
  242. });
  243. },
  244.  
  245. /**
  246. * Move the content to the selected location
  247. *
  248. * @method _moveContent
  249. * @protected
  250. * @param {EventFacade} e
  251. */
  252. _moveContent: function (e) {
  253. var app = this.get('app'),
  254. initialActiveView = app.get('activeView'),
  255. parentLocationId = e.selection.location.get('id'),
  256. oldParentLocationId = this.get('location').get('id'),
  257. locationId = this.get('location').get('id'),
  258. that = this,
  259. content = this.get('content'),
  260. contentName = content.get('name'),
  261. parentContentName = e.selection.contentInfo.get('name'),
  262. notificationIdentifier = 'move-notification-' + parentLocationId + '-' + locationId;
  263.  
  264. this._notify(
  265. Y.eZ.trans('being.moved.under', {name: contentName, parentName: parentContentName}, 'locationview'),
  266. notificationIdentifier,
  267. 'started', 5
  268. );
  269.  
  270. this.get('location').move({api: this.get('capi')}, parentLocationId, function (error, response) {
  271. if (error) {
  272. that._notify(
  273. Y.eZ.trans('failed.moving', {}, 'locationview'),
  274. notificationIdentifier, 'error', 0
  275. );
  276. return;
  277. }
  278.  
  279. that._notify(
  280. Y.eZ.trans('moved.under', {name: contentName, parentName: parentContentName}, 'locationview'),
  281. notificationIdentifier,
  282. 'done',
  283. 5
  284. );
  285. /**
  286. * Fired when the content is moved
  287. *
  288. * @event movedContent
  289. * @param {eZ.Location} location
  290. * @param {String} oldParentLocationId
  291. */
  292. that.fire('movedContent', {location: that.get('location'), oldParentLocationId: oldParentLocationId});
  293. if ( app.get('activeView') === initialActiveView ) {
  294. app.navigateTo(
  295. 'viewLocation',
  296. {id: response.getHeader('location'), languageCode: content.get('mainLanguageCode')}
  297. );
  298. }
  299. });
  300. },
  301.  
  302. /**
  303. * translate event handler, makes the application to navigate to edit content available
  304. * in the facade with given language and base language
  305. *
  306. * @method _translateContent
  307. * @protected
  308. * @param {EventFacade} e
  309. */
  310. _translateContent: function (e) {
  311. var app = this.get('app'),
  312. routeName = 'editContent',
  313. routeParams = {
  314. id: e.content.get('id'),
  315. languageCode: e.toLanguageCode,
  316. };
  317.  
  318. if (e.baseLanguageCode) {
  319. routeParams.baseLanguageCode = e.baseLanguageCode;
  320. routeName = 'translateContent';
  321. }
  322.  
  323. app.navigate(
  324. app.routeUri(routeName, routeParams)
  325. );
  326. },
  327.  
  328. /**
  329. * Update the sort methods of the location
  330. *
  331. * @method _updateSorting
  332. * @protected
  333. * @param {EventFacade} e
  334. */
  335. _updateSorting: function (e) {
  336. var loadOptions = {api: this.get('capi')},
  337. location = this.get('location'),
  338. notificationIdentifier = 'sort-change-' + e.sortType + '-' + e.sortOrder;
  339.  
  340. this._notify(
  341. Y.eZ.trans('updating.sort.method', {}, 'locationview'),
  342. notificationIdentifier,
  343. 'started',
  344. 5
  345. );
  346.  
  347. location.updateSorting(loadOptions, e.sortType, e.sortOrder, Y.bind(function (error, response) {
  348. if (!error) {
  349. this._notify(
  350. Y.eZ.trans('updated.sort.method', {}, 'locationview'),
  351. notificationIdentifier,
  352. 'done',
  353. 5
  354. );
  355. /**
  356. * Fired when the sortOrder and/or sortField have been
  357. * successfully updated.
  358. *
  359. * @event updatedLocationSorting
  360. * @param {eZ.Location} location the Location that has been
  361. * updated
  362. */
  363. this.fire('updatedLocationSorting', {
  364. location: location,
  365. });
  366. } else {
  367. this._notify(
  368. Y.eZ.trans('failed.updating.sort.method', {}, 'locationview'),
  369. notificationIdentifier,
  370. 'error',
  371. 0
  372. );
  373. }
  374. }, this));
  375. },
  376.  
  377. /**
  378. * Fire 'notify' event
  379. *
  380. * @method _notify
  381. * @protected
  382. * @param {String} text the text shown during the notification
  383. * @param {String} identifier the identifier of the notification
  384. * @param {String} state the state of the notification
  385. * @param {Integer} timeout the number of second, the notification will be shown
  386. */
  387. _notify: function (text, identifier, state, timeout) {
  388. this.fire('notify', {
  389. notification: {
  390. text: text,
  391. identifier: identifier,
  392. state: state,
  393. timeout: timeout,
  394. }
  395. });
  396. },
  397.  
  398. /**
  399. * Loads the location, the content and the path for the location id
  400. * available in the request and calls the next callback once it's done.
  401. *
  402. * @method _load
  403. * @protected
  404. * @param {Function} next
  405. */
  406. _load: function (next) {
  407. var loadOptions = {
  408. api: this.get('capi')
  409. },
  410. request = this.get('request'),
  411. service = this,
  412. location = this.get('location'), content = this.get('content'),
  413. type = this.get('contentType');
  414.  
  415. location.set('id', request.params.id);
  416. location.load(loadOptions, function (error) {
  417. var tasks, endLoadPath, endMainContentLoad,
  418. loadContentOptions = Y.merge(loadOptions);
  419.  
  420. loadContentOptions.languageCode = service.get('languageCode');
  421. if ( error ) {
  422. service._error(
  423. Y.eZ.trans('failed.to.load.location', {id: location.get('id')}, 'locationview')
  424. );
  425. return;
  426. }
  427.  
  428. tasks = new Y.Parallel();
  429.  
  430. endMainContentLoad = tasks.add();
  431. content.set('id', location.get('resources').Content);
  432. content.load(loadContentOptions, function (error) {
  433. if ( error ) {
  434. service._error(
  435. Y.eZ.trans('failed.to.load.content', {id: content.get('id')}, 'locationview')
  436. );
  437. return;
  438. }
  439. type.set('id', content.get('resources').ContentType);
  440. type.load(Y.merge(loadOptions, {loadGroups: true}), function (error) {
  441. if ( error ) {
  442. service._error(
  443. Y.eZ.trans('failed.to.load.content.type', {id: type.get('id')}, 'locationview')
  444. );
  445. return;
  446. }
  447. endMainContentLoad();
  448. });
  449. });
  450.  
  451. endLoadPath = tasks.add();
  452. location.loadPath(loadOptions, function(error, path) {
  453. if ( error ) {
  454. service._error(
  455. Y.eZ.trans('failed.to.load.location.path', {}, 'locationview')
  456. );
  457. return;
  458. }
  459.  
  460. service.set('path', path);
  461. endLoadPath();
  462. });
  463.  
  464. tasks.done(function () {
  465. service.get('response').view = {
  466. path: service.get('path'),
  467. location: service.get('location'),
  468. content: service.get('content'),
  469. };
  470. next(service);
  471. });
  472. });
  473. },
  474.  
  475. /**
  476. * Set languageCode attribute based on parameter from request
  477. *
  478. * @method _setLanguageCode
  479. * @protected
  480. */
  481. _setLanguageCode: function () {
  482. this.set('languageCode', this.get('request').params.languageCode);
  483. },
  484.  
  485. _getViewParameters: function () {
  486. return {
  487. content: this.get('content'),
  488. contentType: this.get('contentType'),
  489. location: this.get('location'),
  490. path: this.get('path'),
  491. config: this.get('config'),
  492. languageCode: this.get('request').params.languageCode,
  493. };
  494. },
  495. }, {
  496. ATTRS: {
  497. /**
  498. * The viewed location
  499. *
  500. * @attribute location
  501. * @type Y.eZ.Location
  502. */
  503. location: {
  504. cloneDefaultValue: false,
  505. value: new Y.eZ.Location()
  506. },
  507.  
  508. /**
  509. * The content associated with the location
  510. *
  511. * @attribute content
  512. * @type Y.eZ.Content
  513. */
  514. content: {
  515. cloneDefaultValue: false,
  516. value: new Y.eZ.Content()
  517. },
  518.  
  519. /**
  520. * The content type of the content
  521. *
  522. * @attribute contentType
  523. * @type Y.eZ.ContentType
  524. */
  525. contentType: {
  526. cloneDefaultValue: false,
  527. value: new Y.eZ.ContentType()
  528. },
  529.  
  530. /**
  531. * The path from the root location to the current location. Each
  532. * entry of the path consists of the location sorted by location depth
  533. *
  534. * @attribute path
  535. * @type Array
  536. */
  537. path: {
  538. value: []
  539. },
  540.  
  541. /**
  542. * The language code in which the content is being viewed
  543. *
  544. * @attribute languageCode
  545. * @type String
  546. */
  547. languageCode: {}
  548. }
  549. });
  550. });
  551.