Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 

366 righe
19 KiB

  1. /**
  2. * (c) by aheadware.com
  3. */
  4. var app = app || {};
  5. app.state = app.state || {};
  6. app.state.AppointmentEdit= function()
  7. {
  8. var state = app.core.StateManager.createState( 'appointment-edit' ),
  9. $content;
  10. state.onEnter = function( p )
  11. {
  12. var teams = null,
  13. team = null,
  14. groups = [],
  15. group = null,
  16. acData = {},
  17. isSerial = p.hasOwnProperty( 'serial' ) ? p.serial : false,
  18. appointment = null,
  19. appointmentId = p.id;
  20. $content = app.core.View.getContent();
  21. function radioIcons() {
  22. var radioIcons = document.getElementById('radio-icons');
  23. if (radioIcons) {
  24. var toggleButton = radioIcons.querySelector('p');
  25. var toggleLabel = toggleButton.querySelector('span');
  26. var radioIconsInner = radioIcons.querySelector('.radio-icons-inner');
  27. var iconSpan = toggleButton.querySelector('.selected-icon');
  28. if (!iconSpan) {
  29. iconSpan = document.createElement('span');
  30. iconSpan.className = 'selected-icon';
  31. toggleLabel.insertBefore(iconSpan, toggleLabel.lastElementChild);
  32. }
  33. if (toggleButton && radioIconsInner) {
  34. toggleButton.addEventListener('click', function(event) {
  35. event.stopPropagation();
  36. if (radioIconsInner.style.display === 'none' || radioIconsInner.style.display === '') {
  37. radioIconsInner.style.display = 'block';
  38. } else {
  39. radioIconsInner.style.display = 'none';
  40. }
  41. });
  42. radioIconsInner.addEventListener('click', function(event) {
  43. if (event.target.tagName === 'INPUT' && event.target.type === 'radio') {
  44. var selectedIcon = event.target.value;
  45. if (selectedIcon) {
  46. iconSpan.innerHTML = '<i class="fas ' + selectedIcon + '"></i>';
  47. } else {
  48. iconSpan.innerHTML = '';
  49. }
  50. radioIconsInner.style.display = 'none';
  51. }
  52. });
  53. }
  54. }
  55. }
  56. function autocompleteSubjectLookup()
  57. {
  58. return acData.hasOwnProperty( 'subjects_' + group.getId() ) ? acData[ 'subjects_' + group.getId() ] : [];
  59. }
  60. function autocompleteLocationLookup()
  61. {
  62. return acData.hasOwnProperty( 'locations_' + group.getId() ) ? acData[ 'locations_' + group.getId() ] : [];
  63. }
  64. function updateMaxPossibleBookers()
  65. {
  66. var bookVal = $content.find( '[name="input-visibility"]:checked' ).first().val(),
  67. activeGroupId = $content.find( '[data-id="select-team-id"]' ).first().val(),
  68. categoryIds = null,
  69. group = null,
  70. $mbDiv = $content.find( '[data-id="max-bookers"]' ).first(),
  71. bookerIds = [];
  72. if ( 'visibility-category-only' === bookVal )
  73. {
  74. var members = [];
  75. for( var gi = 0; gi < groups.length; gi++ )
  76. {
  77. if ( groups[ gi ].getId() == activeGroupId )
  78. {
  79. group = groups[ gi ];
  80. break;
  81. }
  82. }
  83. categoryIds = $content.find( '[data-id="select-category-' + group.getId() + '"]' ).first().val();
  84. members = group.getMembers();
  85. for ( var mi = 0; mi < members.length; mi++ )
  86. {
  87. for ( var ci = 0; ci < categoryIds.length; ci++ )
  88. {
  89. if ( members[ mi ].isInGroupCourseCategoryId( categoryIds[ ci ] ) )
  90. {
  91. bookerIds.push( members[ mi ].getId() );
  92. break;
  93. }
  94. }
  95. }
  96. $mbDiv.find( '[data-id="span-max-bookers"]' ).first().html( bookerIds.length );
  97. $mbDiv.show();
  98. }
  99. else
  100. {
  101. $mbDiv.hide();
  102. }
  103. }
  104. app.gui.PageLoader.show();
  105. app.core.Rpc.call(
  106. 'Appointment',
  107. 'getAutocompleteData',
  108. null,
  109. function( acd )
  110. {
  111. acData = acd;
  112. app.core.Rpc.call(
  113. 'Team',
  114. 'getTeamsForAppointmentCreation',
  115. null,
  116. function( res1 )
  117. {
  118. teams = res1.teams;
  119. for ( var gi = 0; gi < teams.length; gi++ )
  120. {
  121. groups.push( new app.model.Group( teams[ gi ], res1[ 'members_' + res1.teams[ gi ].id ] ) );
  122. }
  123. app.core.Rpc.call(
  124. 'Appointment',
  125. 'getDetail',
  126. {
  127. appointmentId : appointmentId
  128. },
  129. function( res2 )
  130. {
  131. appointment = new app.model.Appointment( res2.appointment, res2.attendee_data );
  132. for ( var ti = 0; ti < teams.length; ti++ ) {
  133. if ( teams[ ti ].id == appointment.getTeamId() ) {
  134. team = teams[ ti ];
  135. break;
  136. }
  137. }
  138. for ( var gi = 0; gi < groups.length; gi++ )
  139. {
  140. if ( groups[ gi ].getId() == appointment.getTeamId() ) {
  141. group = groups[ gi ];
  142. break;
  143. }
  144. }
  145. app.core.View.setContent(
  146. app.core.View.getTemplate(
  147. 'appointment-form-edit',
  148. {
  149. team: team,
  150. a: appointment,
  151. g : group,
  152. currentProfile : app.model.SessionUser.getUserProfile()
  153. }
  154. )
  155. );
  156. radioIcons();
  157. $content.find( '[data-id="input-subject"]' ).first().autocomplete( {
  158. lookup: autocompleteSubjectLookup()
  159. });
  160. $content.find( '[data-id="input-location"]' ).first().autocomplete( {
  161. lookup: autocompleteLocationLookup()
  162. });
  163. $content.find( '[name="category"]' ).change( function()
  164. {
  165. updateMaxPossibleBookers();
  166. });
  167. $content.find( 'input[name="input-visibility"]' ).change( function()
  168. {
  169. updateMaxPossibleBookers();
  170. });
  171. $content.find( '[data-id="btn-save"]' ).click( function()
  172. {
  173. let $form = $content.find( '[data-id="form-appointment"]' ).first(),
  174. isValid = app.util.Form.bootstrapValidate( $form );
  175. if ( isValid )
  176. {
  177. app.gui.PageLoader.show();
  178. app.core.Rpc.call(
  179. 'Appointment',
  180. 'update',
  181. {
  182. icon: $('input[name="categoryicon"]:checked').val(),
  183. processSerial : isSerial,
  184. appointmentId : appointmentId,
  185. categoryIds : $form.find( '[data-id="select-category-' + appointment.getTeamId() + '"]' ).first().val(),
  186. visibility : ( 'visibility-category-only' === $form.find( '[name="input-visibility"]:checked' ).first().val() ) ? app.model.Appointment.ENUM_VISIBLE_FOR_CATEGORIES : app.model.Appointment.ENUM_VISIBLE_FOR_ALL,
  187. subject : $form.find( '[data-id="input-subject"]' ).first().val(),
  188. startTime : app.util.Helper.getMomentFromInputDateAndTime(
  189. $form.find( '[data-id="input-start-date"]' ).first(),
  190. $form.find( '[data-id="input-start-time"]' ).first()
  191. ).unix(),
  192. endTime : app.util.Helper.getMomentFromInputDateAndTime(
  193. $form.find( '[data-id="input-end-date"]' ).first(),
  194. $form.find( '[data-id="input-end-time"]' ).first()
  195. ).unix(),
  196. deadlineTime : app.util.Helper.getMomentFromInputDateAndTime(
  197. $form.find( '[data-id="input-deadline-date"]' ).first(),
  198. $form.find( '[data-id="input-deadline-time"]' ).first()
  199. ).unix(),
  200. deadlineRejectTime : app.util.Helper.getMomentFromInputDateAndTime(
  201. $form.find( '[data-id="input-deadline-reject-date"]' ).first(),
  202. $form.find( '[data-id="input-deadline-reject-time"]' ).first()
  203. ).unix(),
  204. location : $form.find( '[data-id="input-location"]' ).first().val(),
  205. //minAttendee : $form.find( '[data-id="select-min-attendee"]' ).first().val(),
  206. maxAttendee : $form.find( '[data-id="select-max-attendee"]' ).first().val(),
  207. comment : $form.find( '[data-id="textarea-comment"]' ).val(),
  208. resetAttendeeList : $form.find( '[data-id="checkbox-reset-attendee-list"]' ).first().is( ':checked' ) ? 'reset' : null,
  209. priceFactor : (+$form.find( '[data-id="input-price-factor"]' ).first().val()) * 100
  210. },
  211. function( res )
  212. {
  213. if ( res && res.hasOwnProperty( 'appointment' ) )
  214. {
  215. app.core.View.toastSuccess( _lc( 'APPOINTMENT_SUCCESSFULLY_UPDATED' ) );
  216. app.core.Controller.redirect( '#/home' );
  217. }
  218. }
  219. );
  220. }
  221. });
  222. /*
  223. // start: min/max attendee
  224. $content.find( '[data-id="select-min-attendee"],[data-id="select-max-attendee"]' ).on( 'input', function()
  225. {
  226. let $minSelect = $content.find( '[data-id="select-min-attendee"]' ).first(),
  227. $maxSelect = $content.find( '[data-id="select-max-attendee"]' ).first();
  228. if ( $minSelect.val() != "0" &&
  229. $maxSelect.val() != "0" &&
  230. $minSelect.val() > $maxSelect.val() )
  231. {
  232. $minSelect.get(0).setCustomValidity( "Cannot be higher than max." );
  233. $maxSelect.get(0).setCustomValidity( "Cannot be lower than min." );
  234. }
  235. else
  236. {
  237. $minSelect.get( 0 ).setCustomValidity( '' );
  238. $maxSelect.get( 0 ).setCustomValidity( '' );
  239. }
  240. });
  241. // stop: min/max attendee
  242. */
  243. // start: start-/enddate
  244. $content.find( '[data-id="input-start-date"],[data-id="input-start-time"],[data-id="input-end-date"],[data-id="input-end-time"]' ).on( 'input', function()
  245. {
  246. var $startDate = $content.find( '[data-id="input-start-date"]' ).first(),
  247. $startTime = $content.find( '[data-id="input-start-time"]' ).first(),
  248. $endDate = $content.find( '[data-id="input-end-date"]' ).first(),
  249. $endTime = $content.find( '[data-id="input-end-time"]' ).first(),
  250. $deadlineDate = $content.find( '[data-id="input-deadline-date"]' ).first(),
  251. $deadlineTime = $content.find( '[data-id="input-deadline-time"]' ).first(),
  252. momentNow = moment(),
  253. momentStart = app.util.Helper.getMomentFromInputDateAndTime( $startDate, $startTime ),
  254. momentEnd = app.util.Helper.getMomentFromInputDateAndTime( $endDate, $endTime ),
  255. momentDeadline = app.util.Helper.getMomentFromInputDateAndTime( $deadlineDate, $deadlineTime );
  256. if ( momentNow.isAfter( momentStart ) )
  257. {
  258. $startDate.get(0).setCustomValidity( "Cannot be in past" );
  259. $startTime.get(0).setCustomValidity( "Cannot be in past!" );
  260. }
  261. else
  262. {
  263. $startDate.get(0).setCustomValidity( "" );
  264. $startTime.get(0).setCustomValidity( "" );
  265. if ( momentStart.isAfter( momentEnd ) )
  266. {
  267. $endDate.get(0).setCustomValidity( "Start cannot be after end." );
  268. $endTime.get(0).setCustomValidity( "Start cannot be after end." );
  269. }
  270. else
  271. {
  272. $endDate.get(0).setCustomValidity( "" );
  273. $endTime.get(0).setCustomValidity( "" );
  274. }
  275. // Update deadline
  276. if ( momentDeadline.isAfter( momentStart ) )
  277. {
  278. $content.find( '[data-id="input-deadline-date"]' ).first().val( $startDate.val() );
  279. $content.find( '[data-id="input-deadline-time"]' ).first().val( $startTime.val() );
  280. }
  281. }
  282. });
  283. // end: start-/enddate
  284. // start: deadline
  285. $content.find( '[data-id="input-deadline-date"],[data-id="input-deadline-time"]' ).on( "input", function()
  286. {
  287. var $startDate = $content.find( '[data-id="input-start-date"]' ).first(),
  288. $startTime = $content.find( '[data-id="input-start-time"]' ).first(),
  289. $deadlineDate = $content.find( '[data-id="input-deadline-date"]' ).first(),
  290. $deadlineTime = $content.find( '[data-id="input-deadline-time"]' ).first(),
  291. momentStart = app.util.Helper.getMomentFromInputDateAndTime( $startDate, $startTime ),
  292. momentDeadline = app.util.Helper.getMomentFromInputDateAndTime( $deadlineDate, $deadlineTime );
  293. if ( momentDeadline.isAfter( momentStart ) )
  294. {
  295. $deadlineDate.get( 0 ).setCustomValidity( "Deadline cannot be past start time" );
  296. $deadlineTime.get( 0 ).setCustomValidity( "Deadline cannot be past start time" );
  297. }
  298. else
  299. {
  300. $deadlineDate.get( 0 ).setCustomValidity( "" );
  301. $deadlineTime.get( 0 ).setCustomValidity( "" );
  302. }
  303. });
  304. // stop: deadline
  305. updateMaxPossibleBookers();
  306. app.gui.PageLoader.hide();
  307. }
  308. );
  309. }
  310. );
  311. }
  312. );
  313. };
  314. state.onExit = function( p )
  315. {
  316. $content.find( '[data-id="input-subject"]' ).first().autocomplete( 'dispose' );
  317. $content.find( '[data-id="input-location"]' ).first().autocomplete( 'dispose' );
  318. app.gui.Clockpicker.destroyForContent();
  319. };
  320. return state;
  321. };