UNPKG

10.3 kBPlain TextView Raw
1import {ColumnGroupChild} from "./columnGroupChild";
2import {ColGroupDef} from "./colDef";
3import {Column} from "./column";
4import {AbstractColDef} from "./colDef";
5import {OriginalColumnGroup} from "./originalColumnGroup";
6import {EventService} from "../eventService";
7import {Autowired} from "../context/context";
8import {GridOptionsWrapper} from "../gridOptionsWrapper";
9import {AgEvent} from "../events";
10import {ColumnApi} from "../columnController/columnApi";
11import {GridApi} from "../gridApi";
12
13export class ColumnGroup implements ColumnGroupChild {
14
15 public static HEADER_GROUP_SHOW_OPEN = 'open';
16 public static HEADER_GROUP_SHOW_CLOSED = 'closed';
17
18 public static EVENT_LEFT_CHANGED = 'leftChanged';
19 public static EVENT_DISPLAYED_CHILDREN_CHANGED = 'displayedChildrenChanged';
20
21 // this is static, a it is used outside of this class
22 public static createUniqueId(groupId: string, instanceId: number): string {
23 return groupId + '_' + instanceId;
24 }
25
26 @Autowired('gridOptionsWrapper') gridOptionsWrapper: GridOptionsWrapper;
27 @Autowired('columnApi') private columnApi: ColumnApi;
28 @Autowired('gridApi') private gridApi: GridApi;
29
30 // all the children of this group, regardless of whether they are opened or closed
31 private children: ColumnGroupChild[];
32 // depends on the open/closed state of the group, only displaying columns are stored here
33 private displayedChildren: ColumnGroupChild[] = [];
34
35 private groupId: string;
36 private instanceId: number;
37 private originalColumnGroup: OriginalColumnGroup;
38
39 // private moving = false
40 private left: number;
41 private oldLeft: number;
42 private localEventService: EventService = new EventService();
43
44 private parent: ColumnGroup;
45
46 constructor(originalColumnGroup: OriginalColumnGroup, groupId: string, instanceId: number) {
47 this.groupId = groupId;
48 this.instanceId = instanceId;
49 this.originalColumnGroup = originalColumnGroup;
50 }
51
52 // as the user is adding and removing columns, the groups are recalculated.
53 // this reset clears out all children, ready for children to be added again
54 public reset(): void {
55 this.parent = null;
56 this.children = null;
57 this.displayedChildren = null;
58 }
59
60 public getParent(): ColumnGroup {
61 return this.parent;
62 }
63
64 public setParent(parent: ColumnGroup): void {
65 this.parent = parent;
66 }
67
68 public getUniqueId(): string {
69 return ColumnGroup.createUniqueId(this.groupId, this.instanceId);
70 }
71
72 public isEmptyGroup(): boolean {
73 return this.displayedChildren.length === 0;
74 }
75
76 public isMoving(): boolean {
77 let allLeafColumns = this.getOriginalColumnGroup().getLeafColumns();
78 if (!allLeafColumns || allLeafColumns.length===0) { return false; }
79
80 let allMoving = true;
81 allLeafColumns.forEach( col => {
82 if (!col.isMoving()) {
83 allMoving = false;
84 }
85 });
86 return allMoving;
87 }
88
89 public checkLeft(): void {
90 // first get all children to setLeft, as it impacts our decision below
91 this.displayedChildren.forEach( (child: ColumnGroupChild) => {
92 if (child instanceof ColumnGroup) {
93 (<ColumnGroup>child).checkLeft();
94 }
95 });
96
97 // set our left based on first displayed column
98 if (this.displayedChildren.length > 0) {
99 if (this.gridOptionsWrapper.isEnableRtl()) {
100 let lastChild = this.displayedChildren[this.displayedChildren.length-1];
101 let lastChildLeft = lastChild.getLeft();
102 this.setLeft(lastChildLeft);
103 } else {
104 let firstChildLeft = this.displayedChildren[0].getLeft();
105 this.setLeft(firstChildLeft);
106 }
107 } else {
108 // this should never happen, as if we have no displayed columns, then
109 // this groups should not even exist.
110 this.setLeft(null);
111 }
112 }
113
114 public getLeft(): number {
115 return this.left;
116 }
117
118 public getOldLeft(): number {
119 return this.oldLeft;
120 }
121
122 public setLeft(left: number) {
123 this.oldLeft = left;
124 if (this.left !== left) {
125 this.left = left;
126 this.localEventService.dispatchEvent(this.createAgEvent(ColumnGroup.EVENT_LEFT_CHANGED));
127 }
128 }
129
130 private createAgEvent(type: string): AgEvent {
131 return {
132 type: type,
133 };
134 }
135
136 public addEventListener(eventType: string, listener: Function): void {
137 this.localEventService.addEventListener(eventType, listener);
138 }
139
140 public removeEventListener(eventType: string, listener: Function): void {
141 this.localEventService.removeEventListener(eventType, listener);
142 }
143
144 public getGroupId(): string {
145 return this.groupId;
146 }
147
148 public getInstanceId(): number {
149 return this.instanceId;
150 }
151
152 public isChildInThisGroupDeepSearch(wantedChild: ColumnGroupChild): boolean {
153 let result = false;
154
155 this.children.forEach( (foundChild: ColumnGroupChild) => {
156 if (wantedChild === foundChild) {
157 result = true;
158 }
159 if (foundChild instanceof ColumnGroup) {
160 if ((<ColumnGroup>foundChild).isChildInThisGroupDeepSearch(wantedChild)) {
161 result = true;
162 }
163 }
164 });
165
166 return result;
167 }
168
169 public getActualWidth(): number {
170 let groupActualWidth = 0;
171 if (this.displayedChildren) {
172 this.displayedChildren.forEach( (child: ColumnGroupChild)=> {
173 groupActualWidth += child.getActualWidth();
174 });
175 }
176 return groupActualWidth;
177 }
178
179 public isResizable(): boolean {
180 if (!this.displayedChildren) { return false; }
181
182 // if at least one child is resizable, then the group is resizable
183 let result = false;
184 this.displayedChildren.forEach( (child: ColumnGroupChild)=> {
185 if (child.isResizable()) {
186 result = true;
187 }
188 });
189
190 return result;
191 }
192
193 public getMinWidth(): number {
194 let result = 0;
195 this.displayedChildren.forEach( (groupChild: ColumnGroupChild) => {
196 result += groupChild.getMinWidth();
197 });
198 return result;
199 }
200
201 public addChild(child: ColumnGroupChild): void {
202 if (!this.children) {
203 this.children = [];
204 }
205 this.children.push(child);
206 }
207
208 public getDisplayedChildren(): ColumnGroupChild[] {
209 return this.displayedChildren;
210 }
211
212 public getLeafColumns(): Column[] {
213 let result: Column[] = [];
214 this.addLeafColumns(result);
215 return result;
216 }
217
218 public getDisplayedLeafColumns(): Column[] {
219 let result: Column[] = [];
220 this.addDisplayedLeafColumns(result);
221 return result;
222 }
223
224 // why two methods here doing the same thing?
225 public getDefinition(): AbstractColDef {
226 return this.originalColumnGroup.getColGroupDef();
227 }
228
229 public getColGroupDef(): ColGroupDef {
230 return this.originalColumnGroup.getColGroupDef();
231 }
232
233 public isPadding(): boolean {
234 return this.originalColumnGroup.isPadding();
235 }
236
237 public isExpandable(): boolean {
238 return this.originalColumnGroup.isExpandable();
239 }
240
241 public isExpanded(): boolean {
242 return this.originalColumnGroup.isExpanded();
243 }
244
245 public setExpanded(expanded: boolean): void {
246 this.originalColumnGroup.setExpanded(expanded);
247 }
248
249 private addDisplayedLeafColumns(leafColumns: Column[]): void {
250 this.displayedChildren.forEach( (child: ColumnGroupChild) => {
251 if (child instanceof Column) {
252 leafColumns.push(<Column>child);
253 } else if (child instanceof ColumnGroup) {
254 (<ColumnGroup>child).addDisplayedLeafColumns(leafColumns);
255 }
256 });
257 }
258
259 private addLeafColumns(leafColumns: Column[]): void {
260 this.children.forEach( (child: ColumnGroupChild) => {
261 if (child instanceof Column) {
262 leafColumns.push(<Column>child);
263 } else if (child instanceof ColumnGroup) {
264 (<ColumnGroup>child).addLeafColumns(leafColumns);
265 }
266 });
267 }
268
269 public getChildren(): ColumnGroupChild[] {
270 return this.children;
271 }
272
273 public getColumnGroupShow(): string {
274 return this.originalColumnGroup.getColumnGroupShow();
275 }
276
277 public getOriginalColumnGroup(): OriginalColumnGroup {
278 return this.originalColumnGroup;
279 }
280
281 public calculateDisplayedColumns() {
282 // clear out last time we calculated
283 this.displayedChildren = [];
284 // it not expandable, everything is visible
285 if (!this.originalColumnGroup.isExpandable()) {
286 this.displayedChildren = this.children;
287 } else {
288 // and calculate again
289 this.children.forEach( abstractColumn => {
290 let headerGroupShow = abstractColumn.getColumnGroupShow();
291 switch (headerGroupShow) {
292 case ColumnGroup.HEADER_GROUP_SHOW_OPEN:
293 // when set to open, only show col if group is open
294 if (this.originalColumnGroup.isExpanded()) {
295 this.displayedChildren.push(abstractColumn);
296 }
297 break;
298 case ColumnGroup.HEADER_GROUP_SHOW_CLOSED:
299 // when set to open, only show col if group is open
300 if (!this.originalColumnGroup.isExpanded()) {
301 this.displayedChildren.push(abstractColumn);
302 }
303 break;
304 default:
305 // default is always show the column
306 this.displayedChildren.push(abstractColumn);
307 break;
308 }
309 });
310 }
311
312 this.localEventService.dispatchEvent(this.createAgEvent(ColumnGroup.EVENT_DISPLAYED_CHILDREN_CHANGED));
313 }
314}