Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

467 строки
16 KiB

  1. import {path} from '../../environments/path';
  2. import {AgGridLocale} from '../lang/ag-gridlocale';
  3. import {IGridValidationErrors} from '../model/virtual/grid-validation-errors';
  4. import {GridSelectEditorComponent} from '../grid-cellrenderer/grid-select/grid-select-editor/grid-select-editor.component';
  5. import {GridSelectRendererComponent} from '../grid-cellrenderer/grid-select/grid-select-renderer/grid-select-renderer.component';
  6. import {GridCheckboxRendererComponent} from '../grid-cellrenderer/grid-checkbox/grid-checkbox-renderer/grid-checkbox-renderer.component';
  7. import {GridCheckboxEditorComponent} from '../grid-cellrenderer/grid-checkbox/grid-checkbox-editor/grid-checkbox-editor.component';
  8. import {GridDateRendererComponent} from '../grid-cellrenderer/grid-date/grid-date-renderer/grid-date-renderer.component';
  9. import {GridDateEditorComponent} from '../grid-cellrenderer/grid-date/grid-date-editor/grid-date-editor.component';
  10. import {GridTextRendererComponent} from '../grid-cellrenderer/grid-text/grid-text-renderer/grid-text-renderer.component';
  11. import {GridTextEditorComponent} from '../grid-cellrenderer/grid-text/grid-text-editor/grid-text-editor.component';
  12. import {AgGridComponentConst} from './ag-grid-component-const';
  13. import {GridInputRendererComponent} from '../grid-cellrenderer/grid-input/grid-input-renderer/grid-input-renderer.component';
  14. import {GridInputEditorComponent} from '../grid-cellrenderer/grid-input/grid-input-editor/grid-input-editor.component';
  15. import {GridBlockedRendererComponent} from '../grid-cellrenderer/grid-blocked/grid-blocked-renderer/grid-blocked-renderer.component';
  16. import {GridBlockedEditorComponent} from '../grid-cellrenderer/grid-blocked/grid-blocked-editor/grid-blocked-editor.component';
  17. import {Utils} from '../utils/utils';
  18. export class AgGridComponent {
  19. static readonly MIN_HEIGHT: number = 16;
  20. public params: any;
  21. public columnDefs: any[] = [];
  22. public defaultColDef: {} = {};
  23. public rowData: any[] = [];
  24. public rowSelection: string;
  25. public gridParamsColumnApi;
  26. public gridParamsApi;
  27. public apiAssetsPath: string;
  28. public resetSearchBtn: boolean;
  29. public localeText: {};
  30. public frameworkComponents: {};
  31. public bSizeColumnsToFit: boolean;
  32. public gridErrors: IGridValidationErrors[];
  33. public errorIndex: number;
  34. public resetValueByError: boolean;
  35. public errorMessage: string;
  36. public nextAddedItemId: number;
  37. /**
  38. * Constructor
  39. */
  40. constructor(bSizeColumnsToFit: boolean = true) {
  41. AgGridComponentConst.setGridInputError();
  42. this.rowData = [];
  43. this.columnDefs = [];
  44. this.rowSelection = 'multiple';
  45. this.defaultColDef = {
  46. editable: true
  47. };
  48. this.apiAssetsPath = path.path_assets;
  49. this.frameworkComponents = {};
  50. this.localeText = AgGridLocale.getLocale();
  51. this.bSizeColumnsToFit = bSizeColumnsToFit;
  52. this.gridErrors = [];
  53. this.errorIndex = -1;
  54. this.resetValueByError = false;
  55. this.errorMessage = null;
  56. this.nextAddedItemId = null;
  57. this.frameworkComponents = {
  58. gridSelectEditor: GridSelectEditorComponent,
  59. gridSelectRenderer: GridSelectRendererComponent,
  60. gridCheckboxRenderer: GridCheckboxRendererComponent,
  61. gridCheckboxEditor: GridCheckboxEditorComponent,
  62. gridDateRenderer: GridDateRendererComponent,
  63. gridDateEditor: GridDateEditorComponent,
  64. gridInputRenderer: GridInputRendererComponent,
  65. gridInputEditor: GridInputEditorComponent,
  66. gridTextRenderer: GridTextRendererComponent,
  67. gridTextEditor: GridTextEditorComponent,
  68. gridBlockedRenderer: GridBlockedRendererComponent,
  69. gridBlockedEditor: GridBlockedEditorComponent
  70. };
  71. }
  72. /**
  73. * Callback on grid ready
  74. */
  75. public onGridReady(params): void {
  76. this.params = params;
  77. this.gridParamsColumnApi = params.columnApi;
  78. this.gridParamsApi = params.api;
  79. // Set for cadasters
  80. if (!this.bSizeColumnsToFit) {
  81. const allColumnIds = [];
  82. this.gridParamsColumnApi.getAllColumns().forEach((column) => {
  83. allColumnIds.push(column.colId);
  84. });
  85. this.gridParamsColumnApi.autoSizeColumns(allColumnIds);
  86. }
  87. }
  88. /**
  89. * On row clicked
  90. */
  91. public onRowClicked(e): void {
  92. // Reset error message
  93. AgGridComponentConst.setGridInputError();
  94. this.errorMessage = null;
  95. }
  96. /**
  97. * On cell editing stopped
  98. */
  99. public onCellEditingStopped(e): void {
  100. if (null !== AgGridComponentConst.gridInputError) {
  101. this.errorMessage = AgGridComponentConst.gridInputError;
  102. e.api.ensureIndexVisible(e.rowIndex, 'middle');
  103. e.api.ensureColumnVisible(e.colDef.field.toString());
  104. } else {
  105. this.errorMessage = null;
  106. }
  107. }
  108. /**
  109. * Sizes columns to fit
  110. */
  111. public onFirstDataRendered(params: any): void {
  112. // Set for info components
  113. if (this.bSizeColumnsToFit) {
  114. params.api.sizeColumnsToFit();
  115. }
  116. }
  117. /**
  118. * Resizes grid
  119. */
  120. public gridSizeChanged(params: any): void {
  121. if (undefined !== this.gridParamsApi) {
  122. this.gridParamsApi.sizeColumnsToFit();
  123. }
  124. }
  125. /**
  126. * Search Form
  127. */
  128. public searchFormSubmit(params: any): void {
  129. if (params.target.value !== '') {
  130. this.resetSearchBtn = true;
  131. this.gridParamsApi.setQuickFilter(params.target.value);
  132. } else {
  133. this.resetSearchBtn = false;
  134. this.gridParamsApi.setQuickFilter(null);
  135. }
  136. }
  137. /**
  138. * Reset search input
  139. */
  140. public resetSearch(e: any): void {
  141. e.originalTarget[0].value = '';
  142. this.resetSearchBtn = false;
  143. this.gridParamsApi.setQuickFilter(null);
  144. }
  145. /**
  146. * Stop editing state
  147. */
  148. public stopEditing(): void {
  149. this.params.api.stopEditing();
  150. }
  151. /**
  152. * Configures scrollToService - https://www.npmjs.com/package/@nicky-lenaers/ngx-scroll-to
  153. */
  154. public scrollTo(targetFieldName: string = null, lastFieldName: string = null): void {
  155. if (null !== targetFieldName) {
  156. if (null !== lastFieldName) {
  157. // Scroll to last field first to ensure our target field name is on left-hand side
  158. this.params.api.ensureColumnVisible(lastFieldName);
  159. }
  160. this.params.api.ensureColumnVisible(targetFieldName);
  161. }
  162. }
  163. /**
  164. * Cell renderer selector for individual cells with optional default parameters
  165. */
  166. public cellRendererSelector(params: any): {} {
  167. return AgGridComponentConst.cellRendererSelector(params);
  168. }
  169. /**
  170. * Cell editor selector for individual cells
  171. */
  172. public cellEditorSelector(params: any): {} {
  173. return AgGridComponentConst.cellEditorSelector(params);
  174. }
  175. /**
  176. * Validates grid
  177. */
  178. public validateGrid(): boolean {
  179. const oldErrors: IGridValidationErrors[] = this.gridErrors;
  180. this.gridErrors = [];
  181. this.errorIndex = -1;
  182. const primaryColumns = this.params.api.columnController.primaryColumns;
  183. const errorColumn: any[] = [];
  184. const errors: IGridValidationErrors[] = [];
  185. primaryColumns.forEach((value) => {
  186. if (undefined !== value.colDef.cellEditorParams) {
  187. if (undefined !== value.colDef.cellEditorParams.mandatory && true === value.colDef.cellEditorParams.mandatory) {
  188. errorColumn.push(value.colDef.field);
  189. }
  190. }
  191. });
  192. errorColumn.forEach((value, i) => {
  193. this.params.api.forEachNode((rowNode, index) => {
  194. if (null === rowNode.data[value] || undefined === rowNode.data[value]) {
  195. errors.push({
  196. column: value,
  197. row: index
  198. });
  199. }
  200. });
  201. });
  202. this.gridErrors = errors;
  203. if (this.gridErrors.length !== 0) {
  204. if (oldErrors.length !== this.gridErrors.length) {
  205. this.params.api.ensureIndexVisible(this.gridErrors[0].row, 'middle');
  206. this.params.api.ensureColumnVisible(this.gridErrors[0].column);
  207. }
  208. }
  209. return this.gridErrors.length === 0;
  210. }
  211. /**
  212. * Jumps to error
  213. */
  214. public jumpToError(direction: string): void {
  215. const errorLength: number = this.gridErrors.length - 1;
  216. // If any errors
  217. if (errorLength >= 0) {
  218. // if errorIndex is smaller or same as list of all errors
  219. if (errorLength === 0) {
  220. this.errorIndex = 0;
  221. } else {
  222. if (direction === 'next') {
  223. this.errorIndex = this.errorIndex < errorLength ? this.errorIndex + 1 : 0;
  224. } else {
  225. this.errorIndex = this.errorIndex <= 0 ? errorLength : this.errorIndex - 1;
  226. }
  227. }
  228. this.params.api.ensureIndexVisible(this.gridErrors[this.errorIndex].row, 'middle');
  229. this.params.api.ensureColumnVisible(this.gridErrors[this.errorIndex].column);
  230. } else {
  231. // reset errorIndex if no errors
  232. this.errorIndex = -1;
  233. }
  234. }
  235. /**
  236. * Shows input error
  237. */
  238. public showInputError(positionIndex: number, field: string, oldValue: string, type: string): void {
  239. this.resetValueByError = true;
  240. this.params.api.clearFocusedCell();
  241. this.params.api.ensureIndexVisible(positionIndex, 'middle');
  242. this.params.api.ensureColumnVisible(field);
  243. // Lifecycle hack
  244. setTimeout(() => {
  245. // Reset to old value
  246. this.params.api.getRowNode(positionIndex).setDataValue(field, oldValue);
  247. this.params.api.startEditingCell({
  248. rowIndex: positionIndex,
  249. colKey: field,
  250. });
  251. switch (type) {
  252. case 'int':
  253. this.errorMessage = 'Bitte geben Sie einen ganzzahligen Wert ein.';
  254. break;
  255. case 'float':
  256. this.errorMessage = 'Bitte geben Sie einen dezimalen oder ganzzahligen Wert ein.';
  257. break;
  258. }
  259. }, 10);
  260. }
  261. /**
  262. * Add row to grid and returns position index
  263. */
  264. public addRow(item: {}): number {
  265. this.initNextAddedItemId();
  266. const rowModel = this.gridParamsApi.rowModel;
  267. // Note: default is last row
  268. let addIndex: number = rowModel.rowsToDisplay.length + 1;
  269. rowModel.rowsToDisplay.forEach((row, i) => {
  270. if (row.selected === true) {
  271. // Note: Add index is the row after selected row
  272. addIndex = i + 1;
  273. return;
  274. }
  275. });
  276. this.gridParamsApi.updateRowData({
  277. add: [item],
  278. addIndex
  279. });
  280. return addIndex;
  281. }
  282. /**
  283. * Removes selected rows
  284. */
  285. public removeRows(): void {
  286. this.initNextAddedItemId();
  287. const selectedRows: {}[] = this.gridParamsApi.getSelectedRows();
  288. this.gridParamsApi.updateRowData({remove: selectedRows});
  289. }
  290. /**
  291. * Gets next row position
  292. */
  293. public getNextRowPosition(): number {
  294. return this.gridParamsApi.rowModel.length + 1;
  295. }
  296. /**
  297. * inits next dummy id for next added entry, if necessary
  298. */
  299. private initNextAddedItemId(): void {
  300. if (this.nextAddedItemId === null) {
  301. this.nextAddedItemId = (this.rowData.length + 1) * -1;
  302. }
  303. }
  304. /**
  305. * Returns dummy id for added entry
  306. */
  307. public getNextAddedItemId(): number {
  308. this.initNextAddedItemId();
  309. const res: number = this.nextAddedItemId;
  310. this.nextAddedItemId--;
  311. return res;
  312. }
  313. /**
  314. * column resize event
  315. */
  316. public onColumnResized(event): void {
  317. if (event.finished !== false) {
  318. event.api.setHeaderHeight(AgGridComponent.MIN_HEIGHT);
  319. const headerCells = Array.from(document.querySelectorAll('.content .ag-header-cell-label'));
  320. let minHeight: number = AgGridComponent.MIN_HEIGHT;
  321. headerCells.forEach(cell => {
  322. minHeight = Math.max(minHeight, cell.scrollHeight);
  323. });
  324. // set header height to calculated height + padding (top: 8px, bottom: 8px)
  325. event.api.setHeaderHeight(minHeight + 16);
  326. }
  327. if (event.finished) {
  328. this.gridParamsApi.resetRowHeights();
  329. }
  330. }
  331. /**
  332. * Renders colored dot
  333. */
  334. public dotRenderer(params): string {
  335. return '<span class=\'dot dot--' + params.value + '\'></span>';
  336. }
  337. /**
  338. * Renders email address
  339. */
  340. public emailRenderer(params): string {
  341. return null !== params.value ? '<a href=\'mailto:' + params.value + '\'>' + params.value + '</a>' : '';
  342. }
  343. /**
  344. * Renders phone number
  345. */
  346. public phoneRenderer(params): string {
  347. return null !== params.value ? '<a href=\'tel:' + params.value + '\'>' + params.value + '</a>' : '';
  348. }
  349. /**
  350. * Renders phone number
  351. */
  352. public urlRenderer(params): string {
  353. return null !== params.value ? '<a href=\'' + Utils.checkUrl(params.value) + '\' target=\'_blank\'>' + params.value + '</a>' : '';
  354. }
  355. /**
  356. * option renderer
  357. */
  358. public optionRenderer(params): string {
  359. return params.data.is_option_meeting ? 'Ja' : '';
  360. }
  361. /**
  362. * address renderer
  363. */
  364. public addressRenderer(params): string {
  365. let address = '';
  366. if (params.data.typeType === 'visit') {
  367. const street = params.data.street !== null ? params.data.street : '';
  368. const streetNo = params.data.street_no !== null ? params.data.street_no : '';
  369. const zip = params.data.zip !== null ? params.data.zip : '';
  370. const city = params.data.city !== null ? params.data.city : '';
  371. let br = '';
  372. if (zip !== null || city !== null) {
  373. br = '<br />';
  374. }
  375. address = street + ' ' + streetNo + ' ' + br + zip + ' ' + city;
  376. }
  377. return address;
  378. }
  379. /**
  380. * participants renderer
  381. */
  382. public participantsRenderer(params): string {
  383. let participantNames = '';
  384. params.data.participants.forEach((value) => {
  385. participantNames += params.data.that.appService.getConfig().vc_user_by_id[value.participant_user_id].firstname +
  386. ' ' + params.data.that.appService.getConfig().vc_user_by_id[value.participant_user_id].lastname + '<br />';
  387. });
  388. return participantNames;
  389. }
  390. /**
  391. * Time renderer
  392. */
  393. public timeRenderer(params): string {
  394. return Utils.getDateTimeToDisplay(params.value, false, true);
  395. }
  396. /**
  397. * Date renderer
  398. */
  399. public dateRenderer(params): string {
  400. return Utils.getDateTimeToDisplay(params.value);
  401. }
  402. /**
  403. * Datetime renderer
  404. */
  405. public dateTimeRenderer(params): string {
  406. return Utils.getDateTimeToDisplay(params.value, true, true);
  407. }
  408. /**
  409. * Date comparator
  410. */
  411. public dateComparator(date1, date2, callbackCheck: boolean = true) {
  412. if (date1 === null && date2 === null) {
  413. return 0;
  414. }
  415. if (date1 === null) {
  416. return -1;
  417. }
  418. if (date2 === null) {
  419. return 1;
  420. }
  421. const stamp1: number = Utils.getParsedDate(date1);
  422. const stamp2: number = Utils.getParsedDate(date2);
  423. return stamp1 < stamp2 ? 1 : stamp1 === stamp2 ? 0 : -1;
  424. }
  425. }