UNPKG

9.25 kBPlain TextView Raw
1import {GridOptionsWrapper} from "./gridOptionsWrapper";
2import {ColumnController} from "./columnController/columnController";
3import {GridPanel} from "./gridPanel/gridPanel";
4import {Logger} from "./logger";
5import {EventService} from "./eventService";
6import {LoggerFactory} from "./logger";
7import {
8 AgEvent, BodyScrollEvent,
9 ColumnEvent, ColumnGroupOpenedEvent, ColumnMovedEvent, ColumnPinnedEvent, ColumnResizedEvent, ColumnVisibleEvent,
10 Events
11} from "./events";
12import {GridOptions} from "./entities/gridOptions";
13import {Column} from "./entities/column";
14import {ColumnGroup} from "./entities/columnGroup";
15import {Bean} from "./context/context";
16import {Qualifier} from "./context/context";
17import {Autowired} from "./context/context";
18import {PostConstruct} from "./context/context";
19import {OriginalColumnGroup} from "./entities/originalColumnGroup";
20
21@Bean('alignedGridsService')
22export class AlignedGridsService {
23
24 @Autowired('gridOptionsWrapper') private gridOptionsWrapper: GridOptionsWrapper;
25 @Autowired('columnController') private columnController: ColumnController;
26 @Autowired('eventService') private eventService: EventService;
27
28 private logger: Logger;
29
30 private gridPanel: GridPanel;
31
32 // flag to mark if we are consuming. to avoid cyclic events (ie other grid firing back to master
33 // while processing a master event) we mark this if consuming an event, and if we are, then
34 // we don't fire back any events.
35 private consuming = false;
36
37 private setBeans(@Qualifier('loggerFactory') loggerFactory: LoggerFactory) {
38 this.logger = loggerFactory.create('AlignedGridsService');
39 }
40
41 public registerGridComp(gridPanel: GridPanel): void {
42 this.gridPanel = gridPanel;
43 }
44
45 @PostConstruct
46 public init(): void {
47 this.eventService.addEventListener(Events.EVENT_COLUMN_MOVED, this.fireColumnEvent.bind(this));
48 this.eventService.addEventListener(Events.EVENT_COLUMN_VISIBLE, this.fireColumnEvent.bind(this));
49 this.eventService.addEventListener(Events.EVENT_COLUMN_PINNED, this.fireColumnEvent.bind(this));
50 this.eventService.addEventListener(Events.EVENT_COLUMN_GROUP_OPENED, this.fireColumnEvent.bind(this));
51 this.eventService.addEventListener(Events.EVENT_COLUMN_RESIZED, this.fireColumnEvent.bind(this));
52 this.eventService.addEventListener(Events.EVENT_BODY_SCROLL, this.fireScrollEvent.bind(this));
53 }
54
55 // common logic across all the fire methods
56 private fireEvent(callback: (alignedGridService: AlignedGridsService)=>void): void {
57 // if we are already consuming, then we are acting on an event from a master,
58 // so we don't cause a cyclic firing of events
59 if (this.consuming) {
60 return;
61 }
62
63 // iterate through the aligned grids, and pass each aligned grid service to the callback
64 let otherGrids = this.gridOptionsWrapper.getAlignedGrids();
65 if (otherGrids) {
66 otherGrids.forEach( (otherGridOptions: GridOptions) => {
67 if (otherGridOptions.api) {
68 let alignedGridService = otherGridOptions.api.__getAlignedGridService();
69 callback(alignedGridService);
70 }
71 });
72 }
73 }
74
75 // common logic across all consume methods. very little common logic, however extracting
76 // guarantees consistency across the methods.
77 private onEvent(callback: ()=>void): void {
78 this.consuming = true;
79 callback();
80 this.consuming = false;
81 }
82
83 private fireColumnEvent(event: ColumnEvent): void {
84 this.fireEvent(alignedGridsService => {
85 alignedGridsService.onColumnEvent(event);
86 });
87 }
88
89 private fireScrollEvent(event: BodyScrollEvent): void {
90 if (event.direction!=='horizontal') { return; }
91 this.fireEvent( alignedGridsService => {
92 alignedGridsService.onScrollEvent(event);
93 });
94 }
95
96 private onScrollEvent(event: BodyScrollEvent): void {
97 this.onEvent(()=> {
98 this.gridPanel.setHorizontalScrollPosition(event.left);
99 });
100 }
101
102 public getMasterColumns(event: ColumnEvent): Column[] {
103 let result: Column[] = [];
104 if (event.columns) {
105 event.columns.forEach( (column: Column) => {
106 result.push(column);
107 });
108 } else if (event.column) {
109 result.push(event.column);
110 }
111 return result;
112 }
113
114 public getColumnIds(event: ColumnEvent): string[] {
115 let result: string[] = [];
116 if (event.columns) {
117 event.columns.forEach( column => {
118 result.push(column.getColId());
119 });
120 } else if (event.columns) {
121 result.push(event.column.getColId());
122 }
123 return result;
124 }
125
126 public onColumnEvent(event: AgEvent): void {
127 this.onEvent(() => {
128
129 switch (event.type) {
130
131 case Events.EVENT_COLUMN_MOVED:
132 case Events.EVENT_COLUMN_VISIBLE:
133 case Events.EVENT_COLUMN_PINNED:
134 case Events.EVENT_COLUMN_RESIZED:
135 let colEvent = <ColumnEvent> event;
136 this.processColumnEvent(colEvent);
137 break;
138
139 case Events.EVENT_COLUMN_GROUP_OPENED:
140 let groupOpenedEvent = <ColumnGroupOpenedEvent> event;
141 this.processGroupOpenedEvent(groupOpenedEvent);
142 break;
143
144 case Events.EVENT_COLUMN_PIVOT_CHANGED:
145 // we cannot support pivoting with aligned grids as the columns will be out of sync as the
146 // grids will have columns created based on the row data of the grid.
147 console.warn('ag-Grid: pivoting is not supported with aligned grids. ' +
148 'You can only use one of these features at a time in a grid.');
149 break;
150 }
151
152 });
153 }
154
155 private processGroupOpenedEvent(groupOpenedEvent: ColumnGroupOpenedEvent): void {
156 // likewise for column group
157 let masterColumnGroup = groupOpenedEvent.columnGroup;
158 let otherColumnGroup: OriginalColumnGroup;
159 if (masterColumnGroup) {
160 let groupId = masterColumnGroup.getGroupId();
161 otherColumnGroup = this.columnController.getOriginalColumnGroup(groupId);
162 }
163 if (masterColumnGroup && !otherColumnGroup) { return; }
164
165 this.logger.log('onColumnEvent-> processing '+event+' expanded = '+ masterColumnGroup.isExpanded());
166 this.columnController.setColumnGroupOpened(otherColumnGroup, masterColumnGroup.isExpanded(), "alignedGridChanged");
167 }
168
169 private processColumnEvent(colEvent: ColumnEvent): void {
170 // the column in the event is from the master grid. need to
171 // look up the equivalent from this (other) grid
172 let masterColumn = colEvent.column;
173 let otherColumn: Column;
174 if (masterColumn) {
175 otherColumn = this.columnController.getPrimaryColumn(masterColumn.getColId());
176 }
177 // if event was with respect to a master column, that is not present in this
178 // grid, then we ignore the event
179 if (masterColumn && !otherColumn) { return; }
180
181 // in time, all the methods below should use the column ids, it's a more generic way
182 // of handling columns, and also allows for single or multi column events
183 let columnIds = this.getColumnIds(colEvent);
184 let masterColumns = this.getMasterColumns(colEvent);
185
186 switch (colEvent.type) {
187 case Events.EVENT_COLUMN_MOVED:
188 let movedEvent = <ColumnMovedEvent> colEvent;
189 this.logger.log('onColumnEvent-> processing '+colEvent.type+' toIndex = ' + movedEvent.toIndex);
190 this.columnController.moveColumns(columnIds, movedEvent.toIndex, "alignedGridChanged");
191 break;
192 case Events.EVENT_COLUMN_VISIBLE:
193 let visibleEvent = <ColumnVisibleEvent> colEvent;
194 this.logger.log('onColumnEvent-> processing '+colEvent.type+' visible = '+ visibleEvent.visible);
195 this.columnController.setColumnsVisible(columnIds, visibleEvent.visible, "alignedGridChanged");
196 break;
197 case Events.EVENT_COLUMN_PINNED:
198 let pinnedEvent = <ColumnPinnedEvent> colEvent;
199 this.logger.log('onColumnEvent-> processing '+colEvent.type+' pinned = '+ pinnedEvent.pinned);
200 this.columnController.setColumnsPinned(columnIds, pinnedEvent.pinned, "alignedGridChanged");
201 break;
202 case Events.EVENT_COLUMN_RESIZED:
203 let resizedEvent = <ColumnResizedEvent> colEvent;
204 masterColumns.forEach( (masterColumn: Column)=> {
205 this.logger.log('onColumnEvent-> processing '+colEvent.type+' actualWidth = '+ masterColumn.getActualWidth());
206 this.columnController.setColumnWidth(masterColumn.getColId(), masterColumn.getActualWidth(), false, resizedEvent.finished, "alignedGridChanged");
207 });
208 break;
209 }
210 }
211}