barsa-user-workspace 0.0.0-watch

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +24 -0
  2. package/esm2022/barsa-user-workspace.mjs +5 -0
  3. package/esm2022/lib/barsa-user-workspace.module.mjs +82 -0
  4. package/esm2022/lib/coercion/boolean-property.mjs +5 -0
  5. package/esm2022/lib/coercion/number-property.mjs +14 -0
  6. package/esm2022/lib/directives/drag-handle.mjs +29 -0
  7. package/esm2022/lib/directives/placeholder.mjs +31 -0
  8. package/esm2022/lib/directives/resize-handle.mjs +29 -0
  9. package/esm2022/lib/grid/grid.component.mjs +609 -0
  10. package/esm2022/lib/grid-item/grid-item.component.mjs +196 -0
  11. package/esm2022/lib/grid.definitions.mjs +3 -0
  12. package/esm2022/lib/grid.service.mjs +49 -0
  13. package/esm2022/lib/layout-container/layout-container.component.mjs +213 -0
  14. package/esm2022/lib/layout-grid-mapper.pipe.mjs +29 -0
  15. package/esm2022/lib/nav-container/nav-container.component.mjs +27 -0
  16. package/esm2022/lib/report-grid-layout/report-grid-layout.component.mjs +15 -0
  17. package/esm2022/lib/utils/client-rect.mjs +57 -0
  18. package/esm2022/lib/utils/grid.utils.mjs +225 -0
  19. package/esm2022/lib/utils/operators.mjs +17 -0
  20. package/esm2022/lib/utils/passive-listeners.mjs +29 -0
  21. package/esm2022/lib/utils/pointer.utils.mjs +110 -0
  22. package/esm2022/lib/utils/react-grid-layout.utils.mjs +493 -0
  23. package/esm2022/lib/utils/scroll.mjs +233 -0
  24. package/esm2022/lib/utils/transition-duration.mjs +34 -0
  25. package/esm2022/lib/utils.mjs +14 -0
  26. package/esm2022/public-api.mjs +15 -0
  27. package/esm2022/types.mjs +2 -0
  28. package/fesm2022/barsa-user-workspace.mjs +2469 -0
  29. package/fesm2022/barsa-user-workspace.mjs.map +1 -0
  30. package/index.d.ts +5 -0
  31. package/lib/barsa-user-workspace.module.d.ts +34 -0
  32. package/lib/coercion/boolean-property.d.ts +7 -0
  33. package/lib/coercion/number-property.d.ts +9 -0
  34. package/lib/directives/drag-handle.d.ts +15 -0
  35. package/lib/directives/placeholder.d.ts +17 -0
  36. package/lib/directives/resize-handle.d.ts +15 -0
  37. package/lib/grid/grid.component.d.ts +147 -0
  38. package/lib/grid-item/grid-item.component.d.ts +83 -0
  39. package/lib/grid.definitions.d.ts +61 -0
  40. package/lib/grid.service.d.ts +15 -0
  41. package/lib/layout-container/layout-container.component.d.ts +79 -0
  42. package/lib/layout-grid-mapper.pipe.d.ts +9 -0
  43. package/lib/nav-container/nav-container.component.d.ts +10 -0
  44. package/lib/report-grid-layout/report-grid-layout.component.d.ts +7 -0
  45. package/lib/utils/client-rect.d.ts +36 -0
  46. package/lib/utils/grid.utils.d.ts +45 -0
  47. package/lib/utils/operators.d.ts +6 -0
  48. package/lib/utils/passive-listeners.d.ts +12 -0
  49. package/lib/utils/pointer.utils.d.ts +29 -0
  50. package/lib/utils/react-grid-layout.utils.d.ts +177 -0
  51. package/lib/utils/scroll.d.ts +28 -0
  52. package/lib/utils/transition-duration.d.ts +6 -0
  53. package/lib/utils.d.ts +6 -0
  54. package/package.json +25 -0
  55. package/public-api.d.ts +12 -0
  56. package/types.d.ts +3 -0
@@ -0,0 +1,2469 @@
1
+ import { iif, fromEvent, merge, Observable, Subject, BehaviorSubject, NEVER, interval, animationFrameScheduler, combineLatest, of, debounceTime, filter as filter$1 } from 'rxjs';
2
+ import { filter, switchMap, startWith, exhaustMap, takeUntil, take, map, tap, distinctUntilChanged } from 'rxjs/operators';
3
+ import * as i0 from '@angular/core';
4
+ import { InjectionToken, Directive, Input, Injectable, ElementRef, Component, ChangeDetectionStrategy, Inject, ContentChildren, ViewChild, ContentChild, EventEmitter, ViewEncapsulation, Output, inject, Pipe, NgModule } from '@angular/core';
5
+ import { Router, RouterModule } from '@angular/router';
6
+ import * as i1$2 from 'barsa-novin-ray-core';
7
+ import { BaseComponent, ReportViewBaseComponent, BaseModule, BarsaNovinRayCoreModule } from 'barsa-novin-ray-core';
8
+ import * as i1 from '@fundamental-ngx/platform/icon-tab-bar';
9
+ import { coerceNumberProperty as coerceNumberProperty$1 } from '@angular/cdk/coercion';
10
+ import * as i1$1 from '@angular/common';
11
+ import { DOCUMENT, CommonModule } from '@angular/common';
12
+ import { FormsModule } from '@angular/forms';
13
+ import { DragDropModule } from '@angular/cdk/drag-drop';
14
+ import { CdkTableModule } from '@angular/cdk/table';
15
+ import { FundamentalNgxCoreModule } from '@fundamental-ngx/core';
16
+ import { FundamentalNgxPlatformModule } from '@fundamental-ngx/platform';
17
+
18
+ /**
19
+ * IMPORTANT:
20
+ * This utils are taken from the project: https://github.com/STRML/react-grid-layout.
21
+ * The code should be as less modified as possible for easy maintenance.
22
+ */
23
+ const DEBUG = false;
24
+ /**
25
+ * Return the bottom coordinate of the layout.
26
+ *
27
+ * @param {Array} layout Layout array.
28
+ * @return {Number} Bottom coordinate.
29
+ */
30
+ function bottom(layout) {
31
+ let max = 0, bottomY;
32
+ for (let i = 0, len = layout.length; i < len; i++) {
33
+ bottomY = layout[i].y + layout[i].h;
34
+ if (bottomY > max) {
35
+ max = bottomY;
36
+ }
37
+ }
38
+ return max;
39
+ }
40
+ function cloneLayout(layout) {
41
+ const newLayout = Array(layout.length);
42
+ for (let i = 0, len = layout.length; i < len; i++) {
43
+ newLayout[i] = cloneLayoutItem(layout[i]);
44
+ }
45
+ return newLayout;
46
+ }
47
+ // Fast path to cloning, since this is monomorphic
48
+ /** NOTE: This code has been modified from the original source */
49
+ function cloneLayoutItem(layoutItem) {
50
+ const clonedLayoutItem = {
51
+ w: layoutItem.w,
52
+ h: layoutItem.h,
53
+ x: layoutItem.x,
54
+ y: layoutItem.y,
55
+ id: layoutItem.id,
56
+ moved: !!layoutItem.moved,
57
+ static: !!layoutItem.static,
58
+ };
59
+ if (layoutItem.minW !== undefined) {
60
+ clonedLayoutItem.minW = layoutItem.minW;
61
+ }
62
+ if (layoutItem.maxW !== undefined) {
63
+ clonedLayoutItem.maxW = layoutItem.maxW;
64
+ }
65
+ if (layoutItem.minH !== undefined) {
66
+ clonedLayoutItem.minH = layoutItem.minH;
67
+ }
68
+ if (layoutItem.maxH !== undefined) {
69
+ clonedLayoutItem.maxH = layoutItem.maxH;
70
+ }
71
+ // These can be null
72
+ if (layoutItem.isDraggable !== undefined) {
73
+ clonedLayoutItem.isDraggable = layoutItem.isDraggable;
74
+ }
75
+ if (layoutItem.isResizable !== undefined) {
76
+ clonedLayoutItem.isResizable = layoutItem.isResizable;
77
+ }
78
+ return clonedLayoutItem;
79
+ }
80
+ /**
81
+ * Given two layoutitems, check if they collide.
82
+ */
83
+ function collides(l1, l2) {
84
+ if (l1.id === l2.id) {
85
+ return false;
86
+ } // same element
87
+ if (l1.x + l1.w <= l2.x) {
88
+ return false;
89
+ } // l1 is left of l2
90
+ if (l1.x >= l2.x + l2.w) {
91
+ return false;
92
+ } // l1 is right of l2
93
+ if (l1.y + l1.h <= l2.y) {
94
+ return false;
95
+ } // l1 is above l2
96
+ if (l1.y >= l2.y + l2.h) {
97
+ return false;
98
+ } // l1 is below l2
99
+ return true; // boxes overlap
100
+ }
101
+ /**
102
+ * Given a layout, compact it. This involves going down each y coordinate and removing gaps
103
+ * between items.
104
+ *
105
+ * @param {Array} layout Layout.
106
+ * @param {Boolean} verticalCompact Whether or not to compact the layout
107
+ * vertically.
108
+ * @return {Array} Compacted Layout.
109
+ */
110
+ function compact(layout, compactType, cols) {
111
+ // Statics go in the compareWith array right away so items flow around them.
112
+ const compareWith = getStatics(layout);
113
+ // We go through the items by row and column.
114
+ const sorted = sortLayoutItems(layout, compactType);
115
+ // Holding for new items.
116
+ const out = Array(layout.length);
117
+ for (let i = 0, len = sorted.length; i < len; i++) {
118
+ let l = cloneLayoutItem(sorted[i]);
119
+ // Don't move static elements
120
+ if (!l.static) {
121
+ l = compactItem(compareWith, l, compactType, cols, sorted);
122
+ // Add to comparison array. We only collide with items before this one.
123
+ // Statics are already in this array.
124
+ compareWith.push(l);
125
+ }
126
+ // Add to output array to make sure they still come out in the right order.
127
+ out[layout.indexOf(sorted[i])] = l;
128
+ // Clear moved flag, if it exists.
129
+ l.moved = false;
130
+ }
131
+ return out;
132
+ }
133
+ const heightWidth = { x: 'w', y: 'h' };
134
+ /**
135
+ * Before moving item down, it will check if the movement will cause collisions and move those items down before.
136
+ */
137
+ function resolveCompactionCollision(layout, item, moveToCoord, axis) {
138
+ const sizeProp = heightWidth[axis];
139
+ item[axis] += 1;
140
+ const itemIndex = layout
141
+ .map(layoutItem => {
142
+ return layoutItem.id;
143
+ })
144
+ .indexOf(item.id);
145
+ // Go through each item we collide with.
146
+ for (let i = itemIndex + 1; i < layout.length; i++) {
147
+ const otherItem = layout[i];
148
+ // Ignore static items
149
+ if (otherItem.static) {
150
+ continue;
151
+ }
152
+ // Optimization: we can break early if we know we're past this el
153
+ // We can do this b/c it's a sorted layout
154
+ if (otherItem.y > item.y + item.h) {
155
+ break;
156
+ }
157
+ if (collides(item, otherItem)) {
158
+ resolveCompactionCollision(layout, otherItem, moveToCoord + item[sizeProp], axis);
159
+ }
160
+ }
161
+ item[axis] = moveToCoord;
162
+ }
163
+ /**
164
+ * Compact an item in the layout.
165
+ */
166
+ function compactItem(compareWith, l, compactType, cols, fullLayout) {
167
+ const compactV = compactType === 'vertical';
168
+ const compactH = compactType === 'horizontal';
169
+ if (compactV) {
170
+ // Bottom 'y' possible is the bottom of the layout.
171
+ // This allows you to do nice stuff like specify {y: Infinity}
172
+ // This is here because the layout must be sorted in order to get the correct bottom `y`.
173
+ l.y = Math.min(bottom(compareWith), l.y);
174
+ // Move the element up as far as it can go without colliding.
175
+ while (l.y > 0 && !getFirstCollision(compareWith, l)) {
176
+ l.y--;
177
+ }
178
+ }
179
+ else if (compactH) {
180
+ // Move the element left as far as it can go without colliding.
181
+ while (l.x > 0 && !getFirstCollision(compareWith, l)) {
182
+ l.x--;
183
+ }
184
+ }
185
+ // Move it down, and keep moving it down if it's colliding.
186
+ let collides;
187
+ while ((collides = getFirstCollision(compareWith, l))) {
188
+ if (compactH) {
189
+ resolveCompactionCollision(fullLayout, l, collides.x + collides.w, 'x');
190
+ }
191
+ else {
192
+ resolveCompactionCollision(fullLayout, l, collides.y + collides.h, 'y');
193
+ }
194
+ // Since we can't grow without bounds horizontally, if we've overflown, let's move it down and try again.
195
+ if (compactH && l.x + l.w > cols) {
196
+ l.x = cols - l.w;
197
+ l.y++;
198
+ // ALso move element as left as much as we can (buw-custom-change)
199
+ while (l.x > 0 && !getFirstCollision(compareWith, l)) {
200
+ l.x--;
201
+ }
202
+ }
203
+ }
204
+ // Ensure that there are no negative positions
205
+ l.y = Math.max(l.y, 0);
206
+ l.x = Math.max(l.x, 0);
207
+ return l;
208
+ }
209
+ /**
210
+ * Given a layout, make sure all elements fit within its bounds.
211
+ *
212
+ * @param {Array} layout Layout array.
213
+ * @param {Number} bounds Number of columns.
214
+ */
215
+ function correctBounds(layout, bounds) {
216
+ const collidesWith = getStatics(layout);
217
+ for (let i = 0, len = layout.length; i < len; i++) {
218
+ const l = layout[i];
219
+ // Overflows right
220
+ if (l.x + l.w > bounds.cols) {
221
+ l.x = bounds.cols - l.w;
222
+ }
223
+ // Overflows left
224
+ if (l.x < 0) {
225
+ l.x = 0;
226
+ l.w = bounds.cols;
227
+ }
228
+ if (!l.static) {
229
+ collidesWith.push(l);
230
+ }
231
+ else {
232
+ // If this is static and collides with other statics, we must move it down.
233
+ // We have to do something nicer than just letting them overlap.
234
+ while (getFirstCollision(collidesWith, l)) {
235
+ l.y++;
236
+ }
237
+ }
238
+ }
239
+ return layout;
240
+ }
241
+ /**
242
+ * Get a layout item by ID. Used so we can override later on if necessary.
243
+ *
244
+ * @param {Array} layout Layout array.
245
+ * @param {String} id ID
246
+ * @return {LayoutItem} Item at ID.
247
+ */
248
+ function getLayoutItem(layout, id) {
249
+ for (let i = 0, len = layout.length; i < len; i++) {
250
+ if (layout[i].id === id) {
251
+ return layout[i];
252
+ }
253
+ }
254
+ return null;
255
+ }
256
+ /**
257
+ * Returns the first item this layout collides with.
258
+ * It doesn't appear to matter which order we approach this from, although
259
+ * perhaps that is the wrong thing to do.
260
+ *
261
+ * @param {Object} layoutItem Layout item.
262
+ * @return {Object|undefined} A colliding layout item, or undefined.
263
+ */
264
+ function getFirstCollision(layout, layoutItem) {
265
+ for (let i = 0, len = layout.length; i < len; i++) {
266
+ if (collides(layout[i], layoutItem)) {
267
+ return layout[i];
268
+ }
269
+ }
270
+ return null;
271
+ }
272
+ function getAllCollisions(layout, layoutItem) {
273
+ return layout.filter(l => collides(l, layoutItem));
274
+ }
275
+ /**
276
+ * Get all static elements.
277
+ * @param {Array} layout Array of layout objects.
278
+ * @return {Array} Array of static layout items..
279
+ */
280
+ function getStatics(layout) {
281
+ return layout.filter(l => l.static);
282
+ }
283
+ /**
284
+ * Move an element. Responsible for doing cascading movements of other elements.
285
+ *
286
+ * @param {Array} layout Full layout to modify.
287
+ * @param {LayoutItem} l element to move.
288
+ * @param {Number} [x] X position in grid units.
289
+ * @param {Number} [y] Y position in grid units.
290
+ */
291
+ function moveElement(layout, l, x, y, isUserAction, preventCollision, compactType, cols) {
292
+ // If this is static and not explicitly enabled as draggable,
293
+ // no move is possible, so we can short-circuit this immediately.
294
+ if (l.static && l.isDraggable !== true) {
295
+ return layout;
296
+ }
297
+ // Short-circuit if nothing to do.
298
+ if (l.y === y && l.x === x) {
299
+ return layout;
300
+ }
301
+ log(`Moving element ${l.id} to [${String(x)},${String(y)}] from [${l.x},${l.y}]`);
302
+ const oldX = l.x;
303
+ const oldY = l.y;
304
+ // This is quite a bit faster than extending the object
305
+ if (typeof x === 'number') {
306
+ l.x = x;
307
+ }
308
+ if (typeof y === 'number') {
309
+ l.y = y;
310
+ }
311
+ l.moved = true;
312
+ // If this collides with anything, move it.
313
+ // When doing this comparison, we have to sort the items we compare with
314
+ // to ensure, in the case of multiple collisions, that we're getting the
315
+ // nearest collision.
316
+ let sorted = sortLayoutItems(layout, compactType);
317
+ const movingUp = compactType === 'vertical' && typeof y === 'number'
318
+ ? oldY >= y
319
+ : compactType === 'horizontal' && typeof x === 'number'
320
+ ? oldX >= x
321
+ : false;
322
+ if (movingUp) {
323
+ sorted = sorted.reverse();
324
+ }
325
+ const collisions = getAllCollisions(sorted, l);
326
+ // There was a collision; abort
327
+ if (preventCollision && collisions.length) {
328
+ log(`Collision prevented on ${l.id}, reverting.`);
329
+ l.x = oldX;
330
+ l.y = oldY;
331
+ l.moved = false;
332
+ return layout;
333
+ }
334
+ // Move each item that collides away from this element.
335
+ for (let i = 0, len = collisions.length; i < len; i++) {
336
+ const collision = collisions[i];
337
+ log(`Resolving collision between ${l.id} at [${l.x},${l.y}] and ${collision.id} at [${collision.x},${collision.y}]`);
338
+ // Short circuit so we can't infinite loop
339
+ if (collision.moved) {
340
+ continue;
341
+ }
342
+ // Don't move static items - we have to move *this* element away
343
+ if (collision.static) {
344
+ layout = moveElementAwayFromCollision(layout, collision, l, isUserAction, compactType, cols);
345
+ }
346
+ else {
347
+ layout = moveElementAwayFromCollision(layout, l, collision, isUserAction, compactType, cols);
348
+ }
349
+ }
350
+ return layout;
351
+ }
352
+ /**
353
+ * This is where the magic needs to happen - given a collision, move an element away from the collision.
354
+ * We attempt to move it up if there's room, otherwise it goes below.
355
+ *
356
+ * @param {Array} layout Full layout to modify.
357
+ * @param {LayoutItem} collidesWith Layout item we're colliding with.
358
+ * @param {LayoutItem} itemToMove Layout item we're moving.
359
+ */
360
+ function moveElementAwayFromCollision(layout, collidesWith, itemToMove, isUserAction, compactType, cols) {
361
+ const compactH = compactType === 'horizontal';
362
+ // Compact vertically if not set to horizontal
363
+ const compactV = compactType !== 'horizontal';
364
+ const preventCollision = collidesWith.static; // we're already colliding (not for static items)
365
+ // If there is enough space above the collision to put this element, move it there.
366
+ // We only do this on the main collision as this can get funky in cascades and cause
367
+ // unwanted swapping behavior.
368
+ if (isUserAction) {
369
+ // Reset isUserAction flag because we're not in the main collision anymore.
370
+ isUserAction = false;
371
+ // Make a mock item so we don't modify the item here, only modify in moveElement.
372
+ const fakeItem = {
373
+ x: compactH
374
+ ? Math.max(collidesWith.x - itemToMove.w, 0)
375
+ : itemToMove.x,
376
+ y: compactV
377
+ ? Math.max(collidesWith.y - itemToMove.h, 0)
378
+ : itemToMove.y,
379
+ w: itemToMove.w,
380
+ h: itemToMove.h,
381
+ id: '-1',
382
+ };
383
+ // No collision? If so, we can go up there; otherwise, we'll end up moving down as normal
384
+ if (!getFirstCollision(layout, fakeItem)) {
385
+ log(`Doing reverse collision on ${itemToMove.id} up to [${fakeItem.x},${fakeItem.y}].`);
386
+ return moveElement(layout, itemToMove, compactH ? fakeItem.x : undefined, compactV ? fakeItem.y : undefined, isUserAction, preventCollision, compactType, cols);
387
+ }
388
+ }
389
+ return moveElement(layout, itemToMove, compactH ? itemToMove.x + 1 : undefined, compactV ? itemToMove.y + 1 : undefined, isUserAction, preventCollision, compactType, cols);
390
+ }
391
+ /**
392
+ * Helper to convert a number to a percentage string.
393
+ *
394
+ * @param {Number} num Any number
395
+ * @return {String} That number as a percentage.
396
+ */
397
+ function perc(num) {
398
+ return num * 100 + '%';
399
+ }
400
+ function setTransform({ top, left, width, height }) {
401
+ // Replace unitless items with px
402
+ const translate = `translate(${left}px,${top}px)`;
403
+ return {
404
+ transform: translate,
405
+ WebkitTransform: translate,
406
+ MozTransform: translate,
407
+ msTransform: translate,
408
+ OTransform: translate,
409
+ width: `${width}px`,
410
+ height: `${height}px`,
411
+ position: 'absolute',
412
+ };
413
+ }
414
+ function setTopLeft({ top, left, width, height }) {
415
+ return {
416
+ top: `${top}px`,
417
+ left: `${left}px`,
418
+ width: `${width}px`,
419
+ height: `${height}px`,
420
+ position: 'absolute',
421
+ };
422
+ }
423
+ /**
424
+ * Get layout items sorted from top left to right and down.
425
+ *
426
+ * @return {Array} Array of layout objects.
427
+ * @return {Array} Layout, sorted static items first.
428
+ */
429
+ function sortLayoutItems(layout, compactType) {
430
+ if (compactType === 'horizontal') {
431
+ return sortLayoutItemsByColRow(layout);
432
+ }
433
+ else {
434
+ return sortLayoutItemsByRowCol(layout);
435
+ }
436
+ }
437
+ function sortLayoutItemsByRowCol(layout) {
438
+ return [].concat(layout).sort(function (a, b) {
439
+ if (a.y > b.y || (a.y === b.y && a.x > b.x)) {
440
+ return 1;
441
+ }
442
+ else if (a.y === b.y && a.x === b.x) {
443
+ // Without this, we can get different sort results in IE vs. Chrome/FF
444
+ return 0;
445
+ }
446
+ return -1;
447
+ });
448
+ }
449
+ function sortLayoutItemsByColRow(layout) {
450
+ return [].concat(layout).sort(function (a, b) {
451
+ if (a.x > b.x || (a.x === b.x && a.y > b.y)) {
452
+ return 1;
453
+ }
454
+ return -1;
455
+ });
456
+ }
457
+ /**
458
+ * Validate a layout. Throws errors.
459
+ *
460
+ * @param {Array} layout Array of layout items.
461
+ * @param {String} [contextName] Context name for errors.
462
+ * @throw {Error} Validation error.
463
+ */
464
+ function validateLayout(layout, contextName = 'Layout') {
465
+ const subProps = ['x', 'y', 'w', 'h'];
466
+ if (!Array.isArray(layout)) {
467
+ throw new Error(contextName + ' must be an array!');
468
+ }
469
+ for (let i = 0, len = layout.length; i < len; i++) {
470
+ const item = layout[i];
471
+ for (let j = 0; j < subProps.length; j++) {
472
+ if (typeof item[subProps[j]] !== 'number') {
473
+ throw new Error('ReactGridLayout: ' +
474
+ contextName +
475
+ '[' +
476
+ i +
477
+ '].' +
478
+ subProps[j] +
479
+ ' must be a number!');
480
+ }
481
+ }
482
+ if (item.id && typeof item.id !== 'string') {
483
+ throw new Error('ReactGridLayout: ' +
484
+ contextName +
485
+ '[' +
486
+ i +
487
+ '].i must be a string!');
488
+ }
489
+ if (item.static !== undefined && typeof item.static !== 'boolean') {
490
+ throw new Error('ReactGridLayout: ' +
491
+ contextName +
492
+ '[' +
493
+ i +
494
+ '].static must be a boolean!');
495
+ }
496
+ }
497
+ }
498
+ // Flow can't really figure this out, so we just use Object
499
+ function autoBindHandlers(el, fns) {
500
+ fns.forEach(key => (el[key] = el[key].bind(el)));
501
+ }
502
+ function log(...args) {
503
+ if (!DEBUG) {
504
+ return;
505
+ }
506
+ // eslint-disable-next-line no-console
507
+ console.log(...args);
508
+ }
509
+ const noop = () => { };
510
+
511
+ /** Cached result of whether the user's browser supports passive event listeners. */
512
+ let supportsPassiveEvents;
513
+ /**
514
+ * Checks whether the user's browser supports passive event listeners.
515
+ * See: https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
516
+ */
517
+ function ktdSupportsPassiveEventListeners() {
518
+ if (supportsPassiveEvents == null && typeof window !== 'undefined') {
519
+ try {
520
+ window.addEventListener('test', null, Object.defineProperty({}, 'passive', {
521
+ get: () => supportsPassiveEvents = true
522
+ }));
523
+ }
524
+ finally {
525
+ supportsPassiveEvents = supportsPassiveEvents || false;
526
+ }
527
+ }
528
+ return supportsPassiveEvents;
529
+ }
530
+ /**
531
+ * Normalizes an `AddEventListener` object to something that can be passed
532
+ * to `addEventListener` on any browser, no matter whether it supports the
533
+ * `options` parameter.
534
+ * @param options Object to be normalized.
535
+ */
536
+ function ktdNormalizePassiveListenerOptions(options) {
537
+ return ktdSupportsPassiveEventListeners() ? options : !!options.capture;
538
+ }
539
+
540
+ /** Options that can be used to bind a passive event listener. */
541
+ const passiveEventListenerOptions = ktdNormalizePassiveListenerOptions({ passive: true });
542
+ /** Options that can be used to bind an active event listener. */
543
+ const activeEventListenerOptions = ktdNormalizePassiveListenerOptions({ passive: false });
544
+ let isMobile = null;
545
+ function ktdIsMobileOrTablet() {
546
+ if (isMobile != null) {
547
+ return isMobile;
548
+ }
549
+ // Generic match pattern to identify mobile or tablet devices
550
+ const isMobileDevice = /Android|webOS|BlackBerry|Windows Phone|iPad|iPhone|iPod/i.test(navigator.userAgent);
551
+ // Since IOS 13 is not safe to just check for the generic solution. See: https://stackoverflow.com/questions/58019463/how-to-detect-device-name-in-safari-on-ios-13-while-it-doesnt-show-the-correct
552
+ const isIOSMobileDevice = /iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
553
+ isMobile = isMobileDevice || isIOSMobileDevice;
554
+ return isMobile;
555
+ }
556
+ function ktdIsMouseEvent(event) {
557
+ return event.clientX != null;
558
+ }
559
+ function ktdIsTouchEvent(event) {
560
+ return event.touches != null && event.touches.length != null;
561
+ }
562
+ function ktdPointerClientX(event) {
563
+ return ktdIsMouseEvent(event) ? event.clientX : event.touches[0].clientX;
564
+ }
565
+ function ktdPointerClientY(event) {
566
+ return ktdIsMouseEvent(event) ? event.clientY : event.touches[0].clientY;
567
+ }
568
+ function ktdPointerClient(event) {
569
+ return {
570
+ clientX: ktdIsMouseEvent(event) ? event.clientX : event.touches[0].clientX,
571
+ clientY: ktdIsMouseEvent(event) ? event.clientY : event.touches[0].clientY
572
+ };
573
+ }
574
+ function ktdIsMouseEventOrMousePointerEvent(event) {
575
+ return event.type === 'mousedown'
576
+ || (event.type === 'pointerdown' && event.pointerType === 'mouse');
577
+ }
578
+ /** Returns true if browser supports pointer events */
579
+ function ktdSupportsPointerEvents() {
580
+ return !!window.PointerEvent;
581
+ }
582
+ /**
583
+ * Emits when a mousedown or touchstart emits. Avoids conflicts between both events.
584
+ * @param element, html element where to listen the events.
585
+ * @param touchNumber number of the touch to track the event, default to the first one.
586
+ */
587
+ function ktdMouseOrTouchDown(element, touchNumber = 1) {
588
+ return iif(() => ktdIsMobileOrTablet(), fromEvent(element, 'touchstart', passiveEventListenerOptions).pipe(filter((touchEvent) => touchEvent.touches.length === touchNumber)), fromEvent(element, 'mousedown', activeEventListenerOptions).pipe(filter((mouseEvent) => {
589
+ /**
590
+ * 0 : Left mouse button
591
+ * 1 : Wheel button or middle button (if present)
592
+ * 2 : Right mouse button
593
+ */
594
+ return mouseEvent.button === 0; // Mouse down to be only fired if is left click
595
+ })));
596
+ }
597
+ /**
598
+ * Emits when a 'mousemove' or a 'touchmove' event gets fired.
599
+ * @param element, html element where to listen the events.
600
+ * @param touchNumber number of the touch to track the event, default to the first one.
601
+ */
602
+ function ktdMouseOrTouchMove(element, touchNumber = 1) {
603
+ return iif(() => ktdIsMobileOrTablet(), fromEvent(element, 'touchmove', activeEventListenerOptions).pipe(filter((touchEvent) => touchEvent.touches.length === touchNumber)), fromEvent(element, 'mousemove', activeEventListenerOptions));
604
+ }
605
+ function ktdTouchEnd(element, touchNumber = 1) {
606
+ return merge(fromEvent(element, 'touchend').pipe(filter((touchEvent) => touchEvent.touches.length === touchNumber - 1)), fromEvent(element, 'touchcancel').pipe(filter((touchEvent) => touchEvent.touches.length === touchNumber - 1)));
607
+ }
608
+ /**
609
+ * Emits when a there is a 'mouseup' or the touch ends.
610
+ * @param element, html element where to listen the events.
611
+ * @param touchNumber number of the touch to track the event, default to the first one.
612
+ */
613
+ function ktdMouserOrTouchEnd(element, touchNumber = 1) {
614
+ return iif(() => ktdIsMobileOrTablet(), ktdTouchEnd(element, touchNumber), fromEvent(element, 'mouseup'));
615
+ }
616
+ /**
617
+ * Emits when a 'pointerdown' event occurs (only for the primary pointer). Fallbacks to 'mousemove' or a 'touchmove' if pointer events are not supported.
618
+ * @param element, html element where to listen the events.
619
+ */
620
+ function ktdPointerDown(element) {
621
+ if (!ktdSupportsPointerEvents()) {
622
+ return ktdMouseOrTouchDown(element);
623
+ }
624
+ return fromEvent(element, 'pointerdown', activeEventListenerOptions).pipe(filter((pointerEvent) => pointerEvent.isPrimary));
625
+ }
626
+ /**
627
+ * Emits when a 'pointermove' event occurs (only for the primary pointer). Fallbacks to 'mousemove' or a 'touchmove' if pointer events are not supported.
628
+ * @param element, html element where to listen the events.
629
+ */
630
+ function ktdPointerMove(element) {
631
+ if (!ktdSupportsPointerEvents()) {
632
+ return ktdMouseOrTouchMove(element);
633
+ }
634
+ return fromEvent(element, 'pointermove', activeEventListenerOptions).pipe(filter((pointerEvent) => pointerEvent.isPrimary));
635
+ }
636
+ /**
637
+ * Emits when a 'pointerup' event occurs (only for the primary pointer). Fallbacks to 'mousemove' or a 'touchmove' if pointer events are not supported.
638
+ * @param element, html element where to listen the events.
639
+ */
640
+ function ktdPointerUp(element) {
641
+ if (!ktdSupportsPointerEvents()) {
642
+ return ktdMouserOrTouchEnd(element);
643
+ }
644
+ return fromEvent(element, 'pointerup').pipe(filter(pointerEvent => pointerEvent.isPrimary));
645
+ }
646
+
647
+ /** Tracks items by id. This function is mean to be used in conjunction with the ngFor that renders the 'buw-grid-items' */
648
+ function ktdTrackById(index, item) {
649
+ return item.id;
650
+ }
651
+ /** Given a layout, the gridHeight and the gap return the resulting rowHeight */
652
+ function ktdGetGridItemRowHeight(layout, gridHeight, gap) {
653
+ const numberOfRows = layout.reduce((acc, cur) => Math.max(acc, Math.max(cur.y + cur.h, 0)), 0);
654
+ const gapTotalHeight = (numberOfRows - 1) * gap;
655
+ const gridHeightMinusGap = gridHeight - gapTotalHeight;
656
+ return gridHeightMinusGap / numberOfRows;
657
+ }
658
+ /**
659
+ * Call react-grid-layout utils 'compact()' function and return the compacted layout.
660
+ * @param layout to be compacted.
661
+ * @param compactType, type of compaction.
662
+ * @param cols, number of columns of the grid.
663
+ */
664
+ function ktdGridCompact(layout, compactType, cols) {
665
+ return (compact(layout, compactType, cols)
666
+ // Prune react-grid-layout compact extra properties.
667
+ .map((item) => ({
668
+ id: item.id,
669
+ x: item.x,
670
+ y: item.y,
671
+ w: item.w,
672
+ h: item.h,
673
+ minW: item.minW,
674
+ minH: item.minH,
675
+ maxW: item.maxW,
676
+ maxH: item.maxH
677
+ })));
678
+ }
679
+ function screenXToGridX(screenXPos, cols, width, gap) {
680
+ const widthMinusGaps = width - gap * (cols - 1);
681
+ const itemWidth = widthMinusGaps / cols;
682
+ const widthMinusOneItem = width - itemWidth;
683
+ const colWidthWithGap = widthMinusOneItem / (cols - 1);
684
+ return Math.round(screenXPos / colWidthWithGap);
685
+ }
686
+ function screenYToGridY(screenYPos, rowHeight, height, gap) {
687
+ return Math.round(screenYPos / (rowHeight + gap));
688
+ }
689
+ function screenWidthToGridWidth(gridScreenWidth, cols, width, gap) {
690
+ const widthMinusGaps = width - gap * (cols - 1);
691
+ const itemWidth = widthMinusGaps / cols;
692
+ const gridScreenWidthMinusFirst = gridScreenWidth - itemWidth;
693
+ return Math.round(gridScreenWidthMinusFirst / (itemWidth + gap)) + 1;
694
+ }
695
+ function screenHeightToGridHeight(gridScreenHeight, rowHeight, height, gap) {
696
+ const gridScreenHeightMinusFirst = gridScreenHeight - rowHeight;
697
+ return Math.round(gridScreenHeightMinusFirst / (rowHeight + gap)) + 1;
698
+ }
699
+ /** Returns a Dictionary where the key is the id and the value is the change applied to that item. If no changes Dictionary is empty. */
700
+ function ktdGetGridLayoutDiff(gridLayoutA, gridLayoutB) {
701
+ const diff = {};
702
+ gridLayoutA.forEach((itemA) => {
703
+ const itemB = gridLayoutB.find((_itemB) => _itemB.id === itemA.id);
704
+ if (itemB != null) {
705
+ const posChanged = itemA.x !== itemB.x || itemA.y !== itemB.y;
706
+ const sizeChanged = itemA.w !== itemB.w || itemA.h !== itemB.h;
707
+ const change = posChanged && sizeChanged ? 'moveresize' : posChanged ? 'move' : sizeChanged ? 'resize' : null;
708
+ if (change) {
709
+ diff[itemB.id] = { change };
710
+ }
711
+ }
712
+ });
713
+ return diff;
714
+ }
715
+ /**
716
+ * Given the grid config & layout data and the current drag position & information, returns the corresponding layout and drag item position
717
+ * @param gridItem grid item that is been dragged
718
+ * @param config current grid configuration
719
+ * @param compactionType type of compaction that will be performed
720
+ * @param draggingData contains all the information about the drag
721
+ */
722
+ function ktdGridItemDragging(gridItem, config, compactionType, draggingData) {
723
+ const { pointerDownEvent, pointerDragEvent, gridElemClientRect, dragElemClientRect, scrollDifference } = draggingData;
724
+ const gridItemId = gridItem.id;
725
+ const draggingElemPrevItem = config.layout.find((item) => item.id === gridItemId);
726
+ const clientStartX = ktdPointerClientX(pointerDownEvent);
727
+ const clientStartY = ktdPointerClientY(pointerDownEvent);
728
+ const clientX = ktdPointerClientX(pointerDragEvent);
729
+ const clientY = ktdPointerClientY(pointerDragEvent);
730
+ const offsetX = clientStartX - dragElemClientRect.left;
731
+ const offsetY = clientStartY - dragElemClientRect.top;
732
+ // Grid element positions taking into account the possible scroll total difference from the beginning.
733
+ const gridElementLeftPosition = gridElemClientRect.left + scrollDifference.left;
734
+ const gridElementTopPosition = gridElemClientRect.top + scrollDifference.top;
735
+ // Calculate position relative to the grid element.
736
+ const gridRelXPos = clientX - gridElementLeftPosition - offsetX;
737
+ const gridRelYPos = clientY - gridElementTopPosition - offsetY;
738
+ const rowHeightInPixels = config.rowHeight === 'fit'
739
+ ? ktdGetGridItemRowHeight(config.layout, config.height ?? gridElemClientRect.height, config.gap)
740
+ : config.rowHeight;
741
+ // Get layout item position
742
+ const layoutItem = {
743
+ ...draggingElemPrevItem,
744
+ x: screenXToGridX(gridRelXPos, config.cols, gridElemClientRect.width, config.gap),
745
+ y: screenYToGridY(gridRelYPos, rowHeightInPixels, gridElemClientRect.height, config.gap)
746
+ };
747
+ // Correct the values if they overflow, since 'moveElement' function doesn't do it
748
+ layoutItem.x = Math.max(0, layoutItem.x);
749
+ layoutItem.y = Math.max(0, layoutItem.y);
750
+ if (layoutItem.x + layoutItem.w > config.cols) {
751
+ layoutItem.x = Math.max(0, config.cols - layoutItem.w);
752
+ }
753
+ // Parse to LayoutItem array data in order to use 'react.grid-layout' utils
754
+ const layoutItems = config.layout;
755
+ const draggedLayoutItem = layoutItems.find((item) => item.id === gridItemId);
756
+ let newLayoutItems = moveElement(layoutItems, draggedLayoutItem, layoutItem.x, layoutItem.y, true, config.preventCollision, compactionType, config.cols);
757
+ newLayoutItems = compact(newLayoutItems, compactionType, config.cols);
758
+ return {
759
+ layout: newLayoutItems,
760
+ draggedItemPos: {
761
+ top: gridRelYPos,
762
+ left: gridRelXPos,
763
+ width: dragElemClientRect.width,
764
+ height: dragElemClientRect.height
765
+ }
766
+ };
767
+ }
768
+ /**
769
+ * Given the grid config & layout data and the current drag position & information, returns the corresponding layout and drag item position
770
+ * @param gridItem grid item that is been dragged
771
+ * @param config current grid configuration
772
+ * @param compactionType type of compaction that will be performed
773
+ * @param draggingData contains all the information about the drag
774
+ */
775
+ function ktdGridItemResizing(gridItem, config, compactionType, draggingData) {
776
+ const { pointerDownEvent, pointerDragEvent, gridElemClientRect, dragElemClientRect, scrollDifference } = draggingData;
777
+ const gridItemId = gridItem.id;
778
+ const clientStartX = ktdPointerClientX(pointerDownEvent);
779
+ const clientStartY = ktdPointerClientY(pointerDownEvent);
780
+ const clientX = ktdPointerClientX(pointerDragEvent);
781
+ const clientY = ktdPointerClientY(pointerDragEvent);
782
+ // Get the difference between the mouseDown and the position 'right' of the resize element.
783
+ const resizeElemOffsetX = dragElemClientRect.width - (clientStartX - dragElemClientRect.left);
784
+ const resizeElemOffsetY = dragElemClientRect.height - (clientStartY - dragElemClientRect.top);
785
+ const draggingElemPrevItem = config.layout.find((item) => item.id === gridItemId);
786
+ const width = clientX + resizeElemOffsetX - (dragElemClientRect.left + scrollDifference.left);
787
+ const height = clientY + resizeElemOffsetY - (dragElemClientRect.top + scrollDifference.top);
788
+ const rowHeightInPixels = config.rowHeight === 'fit'
789
+ ? ktdGetGridItemRowHeight(config.layout, config.height ?? gridElemClientRect.height, config.gap)
790
+ : config.rowHeight;
791
+ // Get layout item grid position
792
+ const layoutItem = {
793
+ ...draggingElemPrevItem,
794
+ w: screenWidthToGridWidth(width, config.cols, gridElemClientRect.width, config.gap),
795
+ h: screenHeightToGridHeight(height, rowHeightInPixels, gridElemClientRect.height, config.gap)
796
+ };
797
+ layoutItem.w = limitNumberWithinRange(layoutItem.w, gridItem.minW ?? layoutItem.minW, gridItem.maxW ?? layoutItem.maxW);
798
+ layoutItem.h = limitNumberWithinRange(layoutItem.h, gridItem.minH ?? layoutItem.minH, gridItem.maxH ?? layoutItem.maxH);
799
+ if (layoutItem.x + layoutItem.w > config.cols) {
800
+ layoutItem.w = Math.max(1, config.cols - layoutItem.x);
801
+ }
802
+ if (config.preventCollision) {
803
+ const maxW = layoutItem.w;
804
+ const maxH = layoutItem.h;
805
+ let colliding = hasCollision(config.layout, layoutItem);
806
+ let shrunkDimension;
807
+ while (colliding) {
808
+ shrunkDimension = getDimensionToShrink(layoutItem, shrunkDimension);
809
+ layoutItem[shrunkDimension]--;
810
+ colliding = hasCollision(config.layout, layoutItem);
811
+ }
812
+ if (shrunkDimension === 'w') {
813
+ layoutItem.h = maxH;
814
+ colliding = hasCollision(config.layout, layoutItem);
815
+ while (colliding) {
816
+ layoutItem.h--;
817
+ colliding = hasCollision(config.layout, layoutItem);
818
+ }
819
+ }
820
+ if (shrunkDimension === 'h') {
821
+ layoutItem.w = maxW;
822
+ colliding = hasCollision(config.layout, layoutItem);
823
+ while (colliding) {
824
+ layoutItem.w--;
825
+ colliding = hasCollision(config.layout, layoutItem);
826
+ }
827
+ }
828
+ }
829
+ const newLayoutItems = config.layout.map((item) => (item.id === gridItemId ? layoutItem : item));
830
+ return {
831
+ layout: compact(newLayoutItems, compactionType, config.cols),
832
+ draggedItemPos: {
833
+ top: dragElemClientRect.top - gridElemClientRect.top,
834
+ left: dragElemClientRect.left - gridElemClientRect.left,
835
+ width,
836
+ height
837
+ }
838
+ };
839
+ }
840
+ function hasCollision(layout, layoutItem) {
841
+ return !!getFirstCollision(layout, layoutItem);
842
+ }
843
+ function getDimensionToShrink(layoutItem, lastShrunk) {
844
+ if (layoutItem.h <= 1) {
845
+ return 'w';
846
+ }
847
+ if (layoutItem.w <= 1) {
848
+ return 'h';
849
+ }
850
+ return lastShrunk === 'w' ? 'h' : 'w';
851
+ }
852
+ /**
853
+ * Given the current number and min/max values, returns the number within the range
854
+ * @param number can be any numeric value
855
+ * @param min minimum value of range
856
+ * @param max maximum value of range
857
+ */
858
+ function limitNumberWithinRange(num, min = 1, max = Infinity) {
859
+ return Math.min(Math.max(num, min < 1 ? 1 : min), max);
860
+ }
861
+ /** Returns true if both item1 and item2 KtdGridLayoutItems are equivalent. */
862
+ function ktdGridItemLayoutItemAreEqual(item1, item2) {
863
+ return (item1.id === item2.id &&
864
+ item1.x === item2.x &&
865
+ item1.y === item2.y &&
866
+ item1.w === item2.w &&
867
+ item1.h === item2.h);
868
+ }
869
+
870
+ /**
871
+ * Injection token that can be used to reference instances of `KtdGridDragHandle`. It serves as
872
+ * alternative token to the actual `KtdGridDragHandle` class which could cause unnecessary
873
+ * retention of the class and its directive metadata.
874
+ */
875
+ const KTD_GRID_DRAG_HANDLE = new InjectionToken('KtdGridDragHandle');
876
+ /** Handle that can be used to drag a KtdGridItem instance. */
877
+ // eslint-disable-next-line @angular-eslint/directive-class-suffix
878
+ class KtdGridDragHandle {
879
+ constructor(element) {
880
+ this.element = element;
881
+ }
882
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KtdGridDragHandle, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
883
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: KtdGridDragHandle, selector: "[buwGridDragHandle]", host: { classAttribute: "buw-grid-drag-handle" }, providers: [{ provide: KTD_GRID_DRAG_HANDLE, useExisting: KtdGridDragHandle }], ngImport: i0 }); }
884
+ }
885
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KtdGridDragHandle, decorators: [{
886
+ type: Directive,
887
+ args: [{
888
+ selector: '[buwGridDragHandle]',
889
+ // eslint-disable-next-line @angular-eslint/no-host-metadata-property
890
+ host: {
891
+ class: 'buw-grid-drag-handle'
892
+ },
893
+ providers: [{ provide: KTD_GRID_DRAG_HANDLE, useExisting: KtdGridDragHandle }]
894
+ }]
895
+ }], ctorParameters: () => [{ type: i0.ElementRef }] });
896
+
897
+ /**
898
+ * Injection token that can be used to reference instances of `KtdGridResizeHandle`. It serves as
899
+ * alternative token to the actual `KtdGridResizeHandle` class which could cause unnecessary
900
+ * retention of the class and its directive metadata.
901
+ */
902
+ const KTD_GRID_RESIZE_HANDLE = new InjectionToken('KtdGridResizeHandle');
903
+ /** Handle that can be used to drag a KtdGridItem instance. */
904
+ // eslint-disable-next-line @angular-eslint/directive-class-suffix
905
+ class KtdGridResizeHandle {
906
+ constructor(element) {
907
+ this.element = element;
908
+ }
909
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KtdGridResizeHandle, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
910
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: KtdGridResizeHandle, selector: "[buwGridResizeHandle]", host: { classAttribute: "buw-grid-resize-handle" }, providers: [{ provide: KTD_GRID_RESIZE_HANDLE, useExisting: KtdGridResizeHandle }], ngImport: i0 }); }
911
+ }
912
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KtdGridResizeHandle, decorators: [{
913
+ type: Directive,
914
+ args: [{
915
+ selector: '[buwGridResizeHandle]',
916
+ // eslint-disable-next-line @angular-eslint/no-host-metadata-property
917
+ host: {
918
+ class: 'buw-grid-resize-handle'
919
+ },
920
+ providers: [{ provide: KTD_GRID_RESIZE_HANDLE, useExisting: KtdGridResizeHandle }]
921
+ }]
922
+ }], ctorParameters: () => [{ type: i0.ElementRef }] });
923
+
924
+ /**
925
+ * Injection token that can be used to reference instances of `KtdGridItemPlaceholder`. It serves as
926
+ * alternative token to the actual `KtdGridItemPlaceholder` class which could cause unnecessary
927
+ * retention of the class and its directive metadata.
928
+ */
929
+ const KTD_GRID_ITEM_PLACEHOLDER = new InjectionToken('KtdGridItemPlaceholder');
930
+ /** Directive that can be used to create a custom placeholder for a KtdGridItem instance. */
931
+ // eslint-disable-next-line @angular-eslint/directive-class-suffix
932
+ class KtdGridItemPlaceholder {
933
+ constructor(templateRef) {
934
+ this.templateRef = templateRef;
935
+ }
936
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KtdGridItemPlaceholder, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); }
937
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: KtdGridItemPlaceholder, selector: "ng-template[buwGridItemPlaceholder]", inputs: { data: "data" }, host: { classAttribute: "buw-grid-item-placeholder-content" }, providers: [{ provide: KTD_GRID_ITEM_PLACEHOLDER, useExisting: KtdGridItemPlaceholder }], ngImport: i0 }); }
938
+ }
939
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KtdGridItemPlaceholder, decorators: [{
940
+ type: Directive,
941
+ args: [{
942
+ selector: 'ng-template[buwGridItemPlaceholder]',
943
+ // eslint-disable-next-line @angular-eslint/no-host-metadata-property
944
+ host: {
945
+ class: 'buw-grid-item-placeholder-content'
946
+ },
947
+ providers: [{ provide: KTD_GRID_ITEM_PLACEHOLDER, useExisting: KtdGridItemPlaceholder }]
948
+ }]
949
+ }], ctorParameters: () => [{ type: i0.TemplateRef }], propDecorators: { data: [{
950
+ type: Input
951
+ }] } });
952
+
953
+ /** Coerces a data-bound value (typically a string) to a boolean. */
954
+ function coerceBooleanProperty(value) {
955
+ return value != null && `${value}` !== 'false';
956
+ }
957
+
958
+ function coerceNumberProperty(value, fallbackValue = 0) {
959
+ return _isNumberValue(value) ? Number(value) : fallbackValue;
960
+ }
961
+ /**
962
+ * Whether the provided value is considered a number.
963
+ * @docs-private
964
+ */
965
+ function _isNumberValue(value) {
966
+ // parseFloat(value) handles most of the cases we're interested in (it treats null, empty string,
967
+ // and other non-number values as NaN, where Number just uses 0) but it considers the string
968
+ // '123hello' to be a valid number. Therefore we also check if Number(value) is NaN.
969
+ return !isNaN(parseFloat(value)) && !isNaN(Number(value));
970
+ }
971
+
972
+ const GRID_ITEM_GET_RENDER_DATA_TOKEN = new InjectionToken('GRID_ITEM_GET_RENDER_DATA_TOKEN');
973
+
974
+ /** Runs source observable outside the zone */
975
+ function ktdOutsideZone(zone) {
976
+ return (source) => {
977
+ return new Observable(observer => {
978
+ return zone.runOutsideAngular(() => source.subscribe(observer));
979
+ });
980
+ };
981
+ }
982
+ /** Rxjs operator that makes source observable to no emit any data */
983
+ function ktdNoEmit() {
984
+ return (source$) => {
985
+ return source$.pipe(filter(() => false));
986
+ };
987
+ }
988
+
989
+ /** Event options that can be used to bind an active, capturing event. */
990
+ const activeCapturingEventOptions = ktdNormalizePassiveListenerOptions({
991
+ passive: false,
992
+ capture: true
993
+ });
994
+ class KtdGridService {
995
+ constructor(ngZone) {
996
+ this.ngZone = ngZone;
997
+ this.touchMoveSubject = new Subject();
998
+ this.touchMove$ = this.touchMoveSubject.asObservable();
999
+ this.registerTouchMoveSubscription();
1000
+ }
1001
+ ngOnDestroy() {
1002
+ this.touchMoveSubscription.unsubscribe();
1003
+ }
1004
+ mouseOrTouchMove$(element) {
1005
+ if (!ktdSupportsPointerEvents()) {
1006
+ return iif(() => ktdIsMobileOrTablet(), this.touchMove$, fromEvent(element, 'mousemove', activeCapturingEventOptions)
1007
+ // TODO: Fix rxjs typings, boolean should be a good param too.
1008
+ );
1009
+ }
1010
+ return fromEvent(element, 'pointermove', activeCapturingEventOptions);
1011
+ }
1012
+ registerTouchMoveSubscription() {
1013
+ // The `touchmove` event gets bound once, ahead of time, because WebKit
1014
+ // won't preventDefault on a dynamically-added `touchmove` listener.
1015
+ // See https://bugs.webkit.org/show_bug.cgi?id=184250.
1016
+ this.touchMoveSubscription = this.ngZone.runOutsideAngular(() =>
1017
+ // The event handler has to be explicitly active,
1018
+ // because newer browsers make it passive by default.
1019
+ fromEvent(document, 'touchmove', activeCapturingEventOptions)
1020
+ // TODO: Fix rxjs typings, boolean should be a good param too.
1021
+ .pipe(filter((touchEvent) => touchEvent.touches.length === 1))
1022
+ .subscribe((touchEvent) => this.touchMoveSubject.next(touchEvent)));
1023
+ }
1024
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KtdGridService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); }
1025
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KtdGridService, providedIn: 'root' }); }
1026
+ }
1027
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KtdGridService, decorators: [{
1028
+ type: Injectable,
1029
+ args: [{ providedIn: 'root' }]
1030
+ }], ctorParameters: () => [{ type: i0.NgZone }] });
1031
+
1032
+ class KtdGridItemComponent {
1033
+ /** Id of the grid item. This property is strictly compulsory. */
1034
+ get id() {
1035
+ return this._id;
1036
+ }
1037
+ set id(val) {
1038
+ this._id = val;
1039
+ }
1040
+ /** Minimum amount of pixels that the user should move before it starts the drag sequence. */
1041
+ get dragStartThreshold() {
1042
+ return this._dragStartThreshold;
1043
+ }
1044
+ set dragStartThreshold(val) {
1045
+ this._dragStartThreshold = coerceNumberProperty(val);
1046
+ }
1047
+ /** Whether the item is draggable or not. Defaults to true. Does not affect manual dragging using the startDragManually method. */
1048
+ get draggable() {
1049
+ return this._draggable;
1050
+ }
1051
+ set draggable(val) {
1052
+ this._draggable = coerceBooleanProperty(val);
1053
+ this._draggable$.next(this._draggable);
1054
+ }
1055
+ /** Whether the item is resizable or not. Defaults to true. */
1056
+ get resizable() {
1057
+ return this._resizable;
1058
+ }
1059
+ set resizable(val) {
1060
+ this._resizable = coerceBooleanProperty(val);
1061
+ this._resizable$.next(this._resizable);
1062
+ }
1063
+ constructor(elementRef, gridService, renderer, ngZone, getItemRenderData) {
1064
+ this.elementRef = elementRef;
1065
+ this.gridService = gridService;
1066
+ this.renderer = renderer;
1067
+ this.ngZone = ngZone;
1068
+ this.getItemRenderData = getItemRenderData;
1069
+ /** CSS transition style. Note that for more performance is preferable only make transition on transform property. */
1070
+ this.transition = 'transform 500ms ease, width 500ms ease, height 500ms ease';
1071
+ this._dragStartThreshold = 0;
1072
+ this._draggable = true;
1073
+ this._draggable$ = new BehaviorSubject(this._draggable);
1074
+ this._manualDragEvents$ = new Subject();
1075
+ this._resizable = true;
1076
+ this._resizable$ = new BehaviorSubject(this._resizable);
1077
+ this.dragStartSubject = new Subject();
1078
+ this.resizeStartSubject = new Subject();
1079
+ this.subscriptions = [];
1080
+ this.dragStart$ = this.dragStartSubject.asObservable();
1081
+ this.resizeStart$ = this.resizeStartSubject.asObservable();
1082
+ }
1083
+ ngOnInit() {
1084
+ const gridItemRenderData = this.getItemRenderData(this.id);
1085
+ this.setStyles(gridItemRenderData);
1086
+ }
1087
+ ngAfterContentInit() {
1088
+ this.subscriptions.push(this._dragStart$().subscribe(this.dragStartSubject), this._resizeStart$().subscribe(this.resizeStartSubject));
1089
+ }
1090
+ ngOnDestroy() {
1091
+ this.subscriptions.forEach((sub) => sub.unsubscribe());
1092
+ }
1093
+ /**
1094
+ * To manually start dragging, route the desired pointer events to this method.
1095
+ * Dragging initiated by this method will work regardless of the value of the draggable Input.
1096
+ * It is the caller's responsibility to call this method with only the events that are desired to cause a drag.
1097
+ * For example, if you only want left clicks to cause a drag, it is your responsibility to filter out other mouse button events.
1098
+ * @param startEvent The pointer event that should initiate the drag.
1099
+ */
1100
+ startDragManually(startEvent) {
1101
+ this._manualDragEvents$.next(startEvent);
1102
+ }
1103
+ setStyles({ top, left, width, height }) {
1104
+ // transform is 6x times faster than top/left
1105
+ this.renderer.setStyle(this.elementRef.nativeElement, 'transform', `translateX(${left}) translateY(${top})`);
1106
+ this.renderer.setStyle(this.elementRef.nativeElement, 'display', `block`);
1107
+ this.renderer.setStyle(this.elementRef.nativeElement, 'transition', this.transition);
1108
+ if (width != null) {
1109
+ this.renderer.setStyle(this.elementRef.nativeElement, 'width', width);
1110
+ }
1111
+ if (height != null) {
1112
+ this.renderer.setStyle(this.elementRef.nativeElement, 'height', height);
1113
+ }
1114
+ }
1115
+ _dragStart$() {
1116
+ return merge(this._manualDragEvents$, this._draggable$.pipe(switchMap((draggable) => {
1117
+ if (!draggable) {
1118
+ return NEVER;
1119
+ }
1120
+ return this._dragHandles.changes.pipe(startWith(this._dragHandles), switchMap((dragHandles) => iif(() => dragHandles.length > 0, merge(...dragHandles
1121
+ .toArray()
1122
+ .map((dragHandle) => ktdPointerDown(dragHandle.element.nativeElement))), ktdPointerDown(this.elementRef.nativeElement))));
1123
+ }))).pipe(exhaustMap((startEvent) => {
1124
+ // If the event started from an element with the native HTML drag&drop, it'll interfere
1125
+ // with our own dragging (e.g. `img` tags do it by default). Prevent the default action
1126
+ // to stop it from happening. Note that preventing on `dragstart` also seems to work, but
1127
+ // it's flaky and it fails if the user drags it away quickly. Also note that we only want
1128
+ // to do this for `mousedown` and `pointerdown` since doing the same for `touchstart` will
1129
+ // stop any `click` events from firing on touch devices.
1130
+ if (ktdIsMouseEventOrMousePointerEvent(startEvent)) {
1131
+ startEvent.preventDefault();
1132
+ }
1133
+ const startPointer = ktdPointerClient(startEvent);
1134
+ return this.gridService.mouseOrTouchMove$(document).pipe(takeUntil(ktdPointerUp(document)), ktdOutsideZone(this.ngZone), filter((moveEvent) => {
1135
+ moveEvent.preventDefault();
1136
+ const movePointer = ktdPointerClient(moveEvent);
1137
+ const distanceX = Math.abs(startPointer.clientX - movePointer.clientX);
1138
+ const distanceY = Math.abs(startPointer.clientY - movePointer.clientY);
1139
+ // When this conditions returns true mean that we are over threshold.
1140
+ return distanceX + distanceY >= this.dragStartThreshold;
1141
+ }), take(1),
1142
+ // Return the original start event
1143
+ map(() => startEvent));
1144
+ }));
1145
+ }
1146
+ _resizeStart$() {
1147
+ return this._resizable$.pipe(switchMap((resizable) => {
1148
+ if (!resizable) {
1149
+ // Side effect to hide the resizeElem if resize is disabled.
1150
+ this.renderer.setStyle(this.resizeElem.nativeElement, 'display', 'none');
1151
+ return NEVER;
1152
+ }
1153
+ else {
1154
+ return this._resizeHandles.changes.pipe(startWith(this._resizeHandles), switchMap((resizeHandles) => {
1155
+ if (resizeHandles.length > 0) {
1156
+ // Side effect to hide the resizeElem if there are resize handles.
1157
+ this.renderer.setStyle(this.resizeElem.nativeElement, 'display', 'none');
1158
+ return merge(...resizeHandles
1159
+ .toArray()
1160
+ .map((resizeHandle) => ktdPointerDown(resizeHandle.element.nativeElement)));
1161
+ }
1162
+ else {
1163
+ this.renderer.setStyle(this.resizeElem.nativeElement, 'display', 'block');
1164
+ return ktdPointerDown(this.resizeElem.nativeElement);
1165
+ }
1166
+ }), tap((startEvent) => {
1167
+ if (ktdIsMouseEventOrMousePointerEvent(startEvent)) {
1168
+ startEvent.preventDefault();
1169
+ }
1170
+ }));
1171
+ }
1172
+ }));
1173
+ }
1174
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KtdGridItemComponent, deps: [{ token: i0.ElementRef }, { token: KtdGridService }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: GRID_ITEM_GET_RENDER_DATA_TOKEN }], target: i0.ɵɵFactoryTarget.Component }); }
1175
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: KtdGridItemComponent, selector: "buw-grid-item", inputs: { minW: "minW", minH: "minH", maxW: "maxW", maxH: "maxH", transition: "transition", id: "id", dragStartThreshold: "dragStartThreshold", draggable: "draggable", resizable: "resizable" }, queries: [{ propertyName: "placeholder", first: true, predicate: KTD_GRID_ITEM_PLACEHOLDER, descendants: true }, { propertyName: "_dragHandles", predicate: KTD_GRID_DRAG_HANDLE, descendants: true }, { propertyName: "_resizeHandles", predicate: KTD_GRID_RESIZE_HANDLE, descendants: true }], viewQueries: [{ propertyName: "resizeElem", first: true, predicate: ["resizeElem"], descendants: true, read: ElementRef, static: true }], ngImport: i0, template: "<ng-content></ng-content>\n<div #resizeElem class=\"grid-item-resize-icon\"></div>", styles: [":host{display:none;position:absolute;z-index:1;overflow:hidden;touch-action:none;border:1px dashed #000}:host div{position:absolute;-webkit-user-select:none;user-select:none;z-index:10}:host div.grid-item-resize-icon{cursor:se-resize;width:20px;height:20px;bottom:0;right:0;color:inherit}:host div.grid-item-resize-icon:after{content:\"\";position:absolute;right:3px;bottom:3px;width:5px;height:5px;border-right:2px solid;border-bottom:2px solid}.display-none{display:none!important}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1176
+ }
1177
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KtdGridItemComponent, decorators: [{
1178
+ type: Component,
1179
+ args: [{ selector: 'buw-grid-item', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content></ng-content>\n<div #resizeElem class=\"grid-item-resize-icon\"></div>", styles: [":host{display:none;position:absolute;z-index:1;overflow:hidden;touch-action:none;border:1px dashed #000}:host div{position:absolute;-webkit-user-select:none;user-select:none;z-index:10}:host div.grid-item-resize-icon{cursor:se-resize;width:20px;height:20px;bottom:0;right:0;color:inherit}:host div.grid-item-resize-icon:after{content:\"\";position:absolute;right:3px;bottom:3px;width:5px;height:5px;border-right:2px solid;border-bottom:2px solid}.display-none{display:none!important}\n"] }]
1180
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: KtdGridService }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: undefined, decorators: [{
1181
+ type: Inject,
1182
+ args: [GRID_ITEM_GET_RENDER_DATA_TOKEN]
1183
+ }] }], propDecorators: { _dragHandles: [{
1184
+ type: ContentChildren,
1185
+ args: [KTD_GRID_DRAG_HANDLE, { descendants: true }]
1186
+ }], _resizeHandles: [{
1187
+ type: ContentChildren,
1188
+ args: [KTD_GRID_RESIZE_HANDLE, { descendants: true }]
1189
+ }], resizeElem: [{
1190
+ type: ViewChild,
1191
+ args: ['resizeElem', { static: true, read: ElementRef }]
1192
+ }], placeholder: [{
1193
+ type: ContentChild,
1194
+ args: [KTD_GRID_ITEM_PLACEHOLDER]
1195
+ }], minW: [{
1196
+ type: Input
1197
+ }], minH: [{
1198
+ type: Input
1199
+ }], maxW: [{
1200
+ type: Input
1201
+ }], maxH: [{
1202
+ type: Input
1203
+ }], transition: [{
1204
+ type: Input
1205
+ }], id: [{
1206
+ type: Input
1207
+ }], dragStartThreshold: [{
1208
+ type: Input
1209
+ }], draggable: [{
1210
+ type: Input
1211
+ }], resizable: [{
1212
+ type: Input
1213
+ }] } });
1214
+
1215
+ /**
1216
+ * Client rect utilities.
1217
+ * This file is taken from Angular Material repository.
1218
+ */
1219
+ /** Gets a mutable version of an element's bounding `ClientRect`. */
1220
+ function getMutableClientRect(element) {
1221
+ const clientRect = element.getBoundingClientRect();
1222
+ // We need to clone the `clientRect` here, because all the values on it are readonly
1223
+ // and we need to be able to update them. Also we can't use a spread here, because
1224
+ // the values on a `ClientRect` aren't own properties. See:
1225
+ // https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect#Notes
1226
+ return {
1227
+ top: clientRect.top,
1228
+ right: clientRect.right,
1229
+ bottom: clientRect.bottom,
1230
+ left: clientRect.left,
1231
+ width: clientRect.width,
1232
+ height: clientRect.height
1233
+ };
1234
+ }
1235
+ /**
1236
+ * Checks whether some coordinates are within a `ClientRect`.
1237
+ * @param clientRect ClientRect that is being checked.
1238
+ * @param x Coordinates along the X axis.
1239
+ * @param y Coordinates along the Y axis.
1240
+ */
1241
+ function isInsideClientRect(clientRect, x, y) {
1242
+ const { top, bottom, left, right } = clientRect;
1243
+ return y >= top && y <= bottom && x >= left && x <= right;
1244
+ }
1245
+ /**
1246
+ * Updates the top/left positions of a `ClientRect`, as well as their bottom/right counterparts.
1247
+ * @param clientRect `ClientRect` that should be updated.
1248
+ * @param top Amount to add to the `top` position.
1249
+ * @param left Amount to add to the `left` position.
1250
+ */
1251
+ function adjustClientRect(clientRect, top, left) {
1252
+ clientRect.top += top;
1253
+ clientRect.bottom = clientRect.top + clientRect.height;
1254
+ clientRect.left += left;
1255
+ clientRect.right = clientRect.left + clientRect.width;
1256
+ }
1257
+ /**
1258
+ * Checks whether the pointer coordinates are close to a ClientRect.
1259
+ * @param rect ClientRect to check against.
1260
+ * @param threshold Threshold around the ClientRect.
1261
+ * @param pointerX Coordinates along the X axis.
1262
+ * @param pointerY Coordinates along the Y axis.
1263
+ */
1264
+ function isPointerNearClientRect(rect, threshold, pointerX, pointerY) {
1265
+ const { top, right, bottom, left, width, height } = rect;
1266
+ const xThreshold = width * threshold;
1267
+ const yThreshold = height * threshold;
1268
+ return pointerY > top - yThreshold && pointerY < bottom + yThreshold &&
1269
+ pointerX > left - xThreshold && pointerX < right + xThreshold;
1270
+ }
1271
+
1272
+ /**
1273
+ * Proximity, as a ratio to width/height at which to start auto-scrolling.
1274
+ * The value comes from trying it out manually until it feels right.
1275
+ */
1276
+ const SCROLL_PROXIMITY_THRESHOLD = 0.05;
1277
+ /**
1278
+ * Increments the vertical scroll position of a node.
1279
+ * @param node Node whose scroll position should change.
1280
+ * @param amount Amount of pixels that the `node` should be scrolled.
1281
+ */
1282
+ function incrementVerticalScroll(node, amount) {
1283
+ if (node === window) {
1284
+ node.scrollBy(0, amount);
1285
+ }
1286
+ else {
1287
+ // Ideally we could use `Element.scrollBy` here as well, but IE and Edge don't support it.
1288
+ node.scrollTop += amount;
1289
+ }
1290
+ }
1291
+ /**
1292
+ * Increments the horizontal scroll position of a node.
1293
+ * @param node Node whose scroll position should change.
1294
+ * @param amount Amount of pixels that the `node` should be scrolled.
1295
+ */
1296
+ function incrementHorizontalScroll(node, amount) {
1297
+ if (node === window) {
1298
+ node.scrollBy(amount, 0);
1299
+ }
1300
+ else {
1301
+ // Ideally we could use `Element.scrollBy` here as well, but IE and Edge don't support it.
1302
+ node.scrollLeft += amount;
1303
+ }
1304
+ }
1305
+ /**
1306
+ * Gets whether the vertical auto-scroll direction of a node.
1307
+ * @param clientRect Dimensions of the node.
1308
+ * @param pointerY Position of the user's pointer along the y axis.
1309
+ */
1310
+ function getVerticalScrollDirection(clientRect, pointerY) {
1311
+ const { top, bottom, height } = clientRect;
1312
+ const yThreshold = height * SCROLL_PROXIMITY_THRESHOLD;
1313
+ if (pointerY >= top - yThreshold && pointerY <= top + yThreshold) {
1314
+ return 1 /* AutoScrollVerticalDirection.UP */;
1315
+ }
1316
+ else if (pointerY >= bottom - yThreshold && pointerY <= bottom + yThreshold) {
1317
+ return 2 /* AutoScrollVerticalDirection.DOWN */;
1318
+ }
1319
+ return 0 /* AutoScrollVerticalDirection.NONE */;
1320
+ }
1321
+ /**
1322
+ * Gets whether the horizontal auto-scroll direction of a node.
1323
+ * @param clientRect Dimensions of the node.
1324
+ * @param pointerX Position of the user's pointer along the x axis.
1325
+ */
1326
+ function getHorizontalScrollDirection(clientRect, pointerX) {
1327
+ const { left, right, width } = clientRect;
1328
+ const xThreshold = width * SCROLL_PROXIMITY_THRESHOLD;
1329
+ if (pointerX >= left - xThreshold && pointerX <= left + xThreshold) {
1330
+ return 1 /* AutoScrollHorizontalDirection.LEFT */;
1331
+ }
1332
+ else if (pointerX >= right - xThreshold && pointerX <= right + xThreshold) {
1333
+ return 2 /* AutoScrollHorizontalDirection.RIGHT */;
1334
+ }
1335
+ return 0 /* AutoScrollHorizontalDirection.NONE */;
1336
+ }
1337
+ /**
1338
+ * Returns an observable that schedules a loop and apply scroll on the scrollNode into the specified direction/s.
1339
+ * This observable doesn't emit, it just performs the 'scroll' side effect.
1340
+ * @param scrollNode, node where the scroll would be applied.
1341
+ * @param verticalScrollDirection, vertical direction of the scroll.
1342
+ * @param horizontalScrollDirection, horizontal direction of the scroll.
1343
+ * @param scrollStep, scroll step in CSS pixels that would be applied in every loop.
1344
+ */
1345
+ function scrollToDirectionInterval$(scrollNode, verticalScrollDirection, horizontalScrollDirection, scrollStep = 2) {
1346
+ return interval(0, animationFrameScheduler)
1347
+ .pipe(tap(() => {
1348
+ if (verticalScrollDirection === 1 /* AutoScrollVerticalDirection.UP */) {
1349
+ incrementVerticalScroll(scrollNode, -scrollStep);
1350
+ }
1351
+ else if (verticalScrollDirection === 2 /* AutoScrollVerticalDirection.DOWN */) {
1352
+ incrementVerticalScroll(scrollNode, scrollStep);
1353
+ }
1354
+ if (horizontalScrollDirection === 1 /* AutoScrollHorizontalDirection.LEFT */) {
1355
+ incrementHorizontalScroll(scrollNode, -scrollStep);
1356
+ }
1357
+ else if (horizontalScrollDirection === 2 /* AutoScrollHorizontalDirection.RIGHT */) {
1358
+ incrementHorizontalScroll(scrollNode, scrollStep);
1359
+ }
1360
+ }), ktdNoEmit());
1361
+ }
1362
+ /**
1363
+ * Given a source$ observable with pointer location, scroll the scrollNode if the pointer is near to it.
1364
+ * This observable doesn't emit, it just performs a 'scroll' side effect.
1365
+ * @param scrollableParent, parent node in which the scroll would be performed.
1366
+ * @param options, configuration options.
1367
+ */
1368
+ function ktdScrollIfNearElementClientRect$(scrollableParent, options) {
1369
+ let scrollNode;
1370
+ let scrollableParentClientRect;
1371
+ let scrollableParentScrollWidth;
1372
+ if (scrollableParent === document) {
1373
+ scrollNode = document.defaultView;
1374
+ const { width, height } = getViewportSize();
1375
+ scrollableParentClientRect = { width, height, top: 0, right: width, bottom: height, left: 0 };
1376
+ scrollableParentScrollWidth = getDocumentScrollWidth();
1377
+ }
1378
+ else {
1379
+ scrollNode = scrollableParent;
1380
+ scrollableParentClientRect = getMutableClientRect(scrollableParent);
1381
+ scrollableParentScrollWidth = scrollableParent.scrollWidth;
1382
+ }
1383
+ /**
1384
+ * IMPORTANT: By design, only let scroll horizontal if the scrollable parent has explicitly an scroll horizontal.
1385
+ * This layout solution is not designed in mind to have any scroll horizontal, but exceptionally we allow it in this
1386
+ * specific use case.
1387
+ */
1388
+ options = options || {};
1389
+ if (options.disableHorizontal == null && scrollableParentScrollWidth <= scrollableParentClientRect.width) {
1390
+ options.disableHorizontal = true;
1391
+ }
1392
+ return (source$) => source$.pipe(map(({ pointerX, pointerY }) => {
1393
+ let verticalScrollDirection = getVerticalScrollDirection(scrollableParentClientRect, pointerY);
1394
+ let horizontalScrollDirection = getHorizontalScrollDirection(scrollableParentClientRect, pointerX);
1395
+ // Check if scroll directions are disabled.
1396
+ if (options?.disableVertical) {
1397
+ verticalScrollDirection = 0 /* AutoScrollVerticalDirection.NONE */;
1398
+ }
1399
+ if (options?.disableHorizontal) {
1400
+ horizontalScrollDirection = 0 /* AutoScrollHorizontalDirection.NONE */;
1401
+ }
1402
+ return { verticalScrollDirection, horizontalScrollDirection };
1403
+ }), distinctUntilChanged((prev, actual) => {
1404
+ return prev.verticalScrollDirection === actual.verticalScrollDirection
1405
+ && prev.horizontalScrollDirection === actual.horizontalScrollDirection;
1406
+ }), switchMap(({ verticalScrollDirection, horizontalScrollDirection }) => {
1407
+ if (verticalScrollDirection || horizontalScrollDirection) {
1408
+ return scrollToDirectionInterval$(scrollNode, verticalScrollDirection, horizontalScrollDirection, options?.scrollStep);
1409
+ }
1410
+ else {
1411
+ return NEVER;
1412
+ }
1413
+ }));
1414
+ }
1415
+ /**
1416
+ * Emits on EVERY scroll event and returns the accumulated scroll offset relative to the initial scroll position.
1417
+ * @param scrollableParent, node in which scroll events would be listened.
1418
+ */
1419
+ function ktdGetScrollTotalRelativeDifference$(scrollableParent) {
1420
+ let scrollInitialPosition;
1421
+ // Calculate initial scroll position
1422
+ if (scrollableParent === document) {
1423
+ scrollInitialPosition = getViewportScrollPosition();
1424
+ }
1425
+ else {
1426
+ scrollInitialPosition = {
1427
+ top: scrollableParent.scrollTop,
1428
+ left: scrollableParent.scrollLeft
1429
+ };
1430
+ }
1431
+ return fromEvent(scrollableParent, 'scroll', ktdNormalizePassiveListenerOptions({ capture: true })).pipe(map(() => {
1432
+ let newTop;
1433
+ let newLeft;
1434
+ if (scrollableParent === document) {
1435
+ const viewportScrollPosition = getViewportScrollPosition();
1436
+ newTop = viewportScrollPosition.top;
1437
+ newLeft = viewportScrollPosition.left;
1438
+ }
1439
+ else {
1440
+ newTop = scrollableParent.scrollTop;
1441
+ newLeft = scrollableParent.scrollLeft;
1442
+ }
1443
+ const topDifference = scrollInitialPosition.top - newTop;
1444
+ const leftDifference = scrollInitialPosition.left - newLeft;
1445
+ return { top: topDifference, left: leftDifference };
1446
+ }));
1447
+ }
1448
+ /** Returns the viewport's width and height. */
1449
+ function getViewportSize() {
1450
+ const _window = document.defaultView || window;
1451
+ return {
1452
+ width: _window.innerWidth,
1453
+ height: _window.innerHeight
1454
+ };
1455
+ }
1456
+ /** Gets a ClientRect for the viewport's bounds. */
1457
+ function getViewportRect() {
1458
+ // Use the document element's bounding rect rather than the window scroll properties
1459
+ // (e.g. pageYOffset, scrollY) due to in issue in Chrome and IE where window scroll
1460
+ // properties and client coordinates (boundingClientRect, clientX/Y, etc.) are in different
1461
+ // conceptual viewports. Under most circumstances these viewports are equivalent, but they
1462
+ // can disagree when the page is pinch-zoomed (on devices that support touch).
1463
+ // See https://bugs.chromium.org/p/chromium/issues/detail?id=489206#c4
1464
+ // We use the documentElement instead of the body because, by default (without a css reset)
1465
+ // browsers typically give the document body an 8px margin, which is not included in
1466
+ // getBoundingClientRect().
1467
+ const scrollPosition = getViewportScrollPosition();
1468
+ const { width, height } = getViewportSize();
1469
+ return {
1470
+ top: scrollPosition.top,
1471
+ left: scrollPosition.left,
1472
+ bottom: scrollPosition.top + height,
1473
+ right: scrollPosition.left + width,
1474
+ height,
1475
+ width,
1476
+ };
1477
+ }
1478
+ /** Gets the (top, left) scroll position of the viewport. */
1479
+ function getViewportScrollPosition() {
1480
+ // The top-left-corner of the viewport is determined by the scroll position of the document
1481
+ // body, normally just (scrollLeft, scrollTop). However, Chrome and Firefox disagree about
1482
+ // whether `document.body` or `document.documentElement` is the scrolled element, so reading
1483
+ // `scrollTop` and `scrollLeft` is inconsistent. However, using the bounding rect of
1484
+ // `document.documentElement` works consistently, where the `top` and `left` values will
1485
+ // equal negative the scroll position.
1486
+ const windowRef = document.defaultView || window;
1487
+ const documentElement = document.documentElement;
1488
+ const documentRect = documentElement.getBoundingClientRect();
1489
+ const top = -documentRect.top || document.body.scrollTop || windowRef.scrollY ||
1490
+ documentElement.scrollTop || 0;
1491
+ const left = -documentRect.left || document.body.scrollLeft || windowRef.scrollX ||
1492
+ documentElement.scrollLeft || 0;
1493
+ return { top, left };
1494
+ }
1495
+ /** Returns the document scroll width */
1496
+ function getDocumentScrollWidth() {
1497
+ return Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
1498
+ }
1499
+
1500
+ /**
1501
+ * Transition duration utilities.
1502
+ * This file is taken from Angular Material repository.
1503
+ */
1504
+ /* eslint-disable @katoid/prefix-exported-code */
1505
+ /** Parses a CSS time value to milliseconds. */
1506
+ function parseCssTimeUnitsToMs(value) {
1507
+ // Some browsers will return it in seconds, whereas others will return milliseconds.
1508
+ const multiplier = value.toLowerCase().indexOf('ms') > -1 ? 1 : 1000;
1509
+ return parseFloat(value) * multiplier;
1510
+ }
1511
+ /** Gets the transform transition duration, including the delay, of an element in milliseconds. */
1512
+ function getTransformTransitionDurationInMs(element) {
1513
+ const computedStyle = getComputedStyle(element);
1514
+ const transitionedProperties = parseCssPropertyValue(computedStyle, 'transition-property');
1515
+ const property = transitionedProperties.find(prop => prop === 'transform' || prop === 'all');
1516
+ // If there's no transition for `all` or `transform`, we shouldn't do anything.
1517
+ if (!property) {
1518
+ return 0;
1519
+ }
1520
+ // Get the index of the property that we're interested in and match
1521
+ // it up to the same index in `transition-delay` and `transition-duration`.
1522
+ const propertyIndex = transitionedProperties.indexOf(property);
1523
+ const rawDurations = parseCssPropertyValue(computedStyle, 'transition-duration');
1524
+ const rawDelays = parseCssPropertyValue(computedStyle, 'transition-delay');
1525
+ return parseCssTimeUnitsToMs(rawDurations[propertyIndex]) +
1526
+ parseCssTimeUnitsToMs(rawDelays[propertyIndex]);
1527
+ }
1528
+ /** Parses out multiple values from a computed style into an array. */
1529
+ function parseCssPropertyValue(computedStyle, name) {
1530
+ const value = computedStyle.getPropertyValue(name);
1531
+ return value.split(',').map(part => part.trim());
1532
+ }
1533
+
1534
+ function getDragResizeEventData(gridItem, layout) {
1535
+ return {
1536
+ layout,
1537
+ layoutItem: layout.find((item) => item.id === gridItem.id),
1538
+ gridItemRef: gridItem
1539
+ };
1540
+ }
1541
+ function getColumnWidth(config, width) {
1542
+ const { cols, gap } = config;
1543
+ const widthExcludingGap = width - Math.max(gap * (cols - 1), 0);
1544
+ return widthExcludingGap / cols;
1545
+ }
1546
+ function getRowHeightInPixels(config, height) {
1547
+ const { rowHeight, layout, gap } = config;
1548
+ return rowHeight === 'fit' ? ktdGetGridItemRowHeight(layout, height, gap) : rowHeight;
1549
+ }
1550
+ function layoutToRenderItems(config, width, height) {
1551
+ const { layout, gap } = config;
1552
+ const rowHeightInPixels = getRowHeightInPixels(config, height);
1553
+ const itemWidthPerColumn = getColumnWidth(config, width);
1554
+ const renderItems = {};
1555
+ for (const item of layout) {
1556
+ renderItems[item.id] = {
1557
+ id: item.id,
1558
+ top: item.y * rowHeightInPixels + gap * item.y,
1559
+ left: item.x * itemWidthPerColumn + gap * item.x,
1560
+ width: item.w * itemWidthPerColumn + gap * Math.max(item.w - 1, 0),
1561
+ height: item.h * rowHeightInPixels + gap * Math.max(item.h - 1, 0)
1562
+ };
1563
+ }
1564
+ return renderItems;
1565
+ }
1566
+ function getGridHeight(layout, rowHeight, gap) {
1567
+ return layout.reduce((acc, cur) => Math.max(acc, (cur.y + cur.h) * rowHeight + Math.max(cur.y + cur.h - 1, 0) * gap), 0);
1568
+ }
1569
+ // eslint-disable-next-line
1570
+ function parseRenderItemToPixels(renderItem) {
1571
+ return {
1572
+ id: renderItem.id,
1573
+ top: `${renderItem.top}px`,
1574
+ left: `${renderItem.left}px`,
1575
+ width: `${renderItem.width}px`,
1576
+ height: `${renderItem.height}px`
1577
+ };
1578
+ }
1579
+ // eslint-disable-next-line
1580
+ function __gridItemGetRenderDataFactoryFunc(gridCmp) {
1581
+ return function (id) {
1582
+ return parseRenderItemToPixels(gridCmp.getItemRenderData(id));
1583
+ };
1584
+ }
1585
+ function ktdGridItemGetRenderDataFactoryFunc(gridCmp) {
1586
+ // Workaround explained: https://github.com/ng-packagr/ng-packagr/issues/696#issuecomment-387114613
1587
+ const resultFunc = __gridItemGetRenderDataFactoryFunc(gridCmp);
1588
+ return resultFunc;
1589
+ }
1590
+ const defaultBackgroundConfig = {
1591
+ borderColor: '#ffa72678',
1592
+ gapColor: 'transparent',
1593
+ rowColor: 'transparent',
1594
+ columnColor: 'transparent',
1595
+ borderWidth: 1
1596
+ };
1597
+ class KtdGridComponent {
1598
+ /** Whether or not to update the internal layout when some dependent property change. */
1599
+ get compactOnPropsChange() {
1600
+ return this._compactOnPropsChange;
1601
+ }
1602
+ set compactOnPropsChange(value) {
1603
+ this._compactOnPropsChange = coerceBooleanProperty(value);
1604
+ }
1605
+ /** If true, grid items won't change position when being dragged over. Handy when using no compaction */
1606
+ get preventCollision() {
1607
+ return this._preventCollision;
1608
+ }
1609
+ set preventCollision(value) {
1610
+ this._preventCollision = coerceBooleanProperty(value);
1611
+ }
1612
+ /** Number of CSS pixels that would be scrolled on each 'tick' when auto scroll is performed. */
1613
+ get scrollSpeed() {
1614
+ return this._scrollSpeed;
1615
+ }
1616
+ set scrollSpeed(value) {
1617
+ this._scrollSpeed = coerceNumberProperty(value, 2);
1618
+ }
1619
+ /** Type of compaction that will be applied to the layout (vertical, horizontal or free). Defaults to 'vertical' */
1620
+ get compactType() {
1621
+ return this._compactType;
1622
+ }
1623
+ set compactType(val) {
1624
+ this._compactType = val;
1625
+ }
1626
+ /**
1627
+ * Row height as number or as 'fit'.
1628
+ * If rowHeight is a number value, it means that each row would have those css pixels in height.
1629
+ * if rowHeight is 'fit', it means that rows will fit in the height available. If 'fit' value is set, a 'height' should be also provided.
1630
+ */
1631
+ get rowHeight() {
1632
+ return this._rowHeight;
1633
+ }
1634
+ set rowHeight(val) {
1635
+ this._rowHeight = val === 'fit' ? val : Math.max(1, Math.round(coerceNumberProperty(val)));
1636
+ }
1637
+ /** Number of columns */
1638
+ get cols() {
1639
+ return this._cols;
1640
+ }
1641
+ set cols(val) {
1642
+ this._cols = Math.max(1, Math.round(coerceNumberProperty(val)));
1643
+ }
1644
+ /** Layout of the grid. Array of all the grid items with its 'id' and position on the grid. */
1645
+ get layout() {
1646
+ return this._layout;
1647
+ }
1648
+ set layout(layout) {
1649
+ /**
1650
+ * Enhancement:
1651
+ * Only set layout if it's reference has changed and use a boolean to track whenever recalculate the layout on ngOnChanges.
1652
+ *
1653
+ * Why:
1654
+ * The normal use of this lib is having the variable layout in the outer component or in a store, assigning it whenever it changes and
1655
+ * binded in the component with it's input [layout]. In this scenario, we would always calculate one unnecessary change on the layout when
1656
+ * it is re-binded on the input.
1657
+ */
1658
+ this._layout = layout;
1659
+ }
1660
+ /** Grid gap in css pixels */
1661
+ get gap() {
1662
+ return this._gap;
1663
+ }
1664
+ set gap(val) {
1665
+ this._gap = Math.max(coerceNumberProperty(val), 0);
1666
+ }
1667
+ /**
1668
+ * If height is a number, fixes the height of the grid to it, recommended when rowHeight = 'fit' is used.
1669
+ * If height is null, height will be automatically set according to its inner grid items.
1670
+ * Defaults to null.
1671
+ * */
1672
+ get height() {
1673
+ return this._height;
1674
+ }
1675
+ set height(val) {
1676
+ this._height = typeof val === 'number' ? Math.max(val, 0) : null;
1677
+ }
1678
+ get backgroundConfig() {
1679
+ return this._backgroundConfig;
1680
+ }
1681
+ set backgroundConfig(val) {
1682
+ this._backgroundConfig = val;
1683
+ // If there is background configuration, add main grid background class. Grid background class comes with opacity 0.
1684
+ // It is done this way for adding opacity animation and to don't add any styles when grid background is null.
1685
+ const classList = this.elementRef.nativeElement.classList;
1686
+ this._backgroundConfig !== null
1687
+ ? classList.add('buw-grid-background')
1688
+ : classList.remove('buw-grid-background');
1689
+ // Set background visibility
1690
+ this.setGridBackgroundVisible(this._backgroundConfig?.show === 'always');
1691
+ }
1692
+ get config() {
1693
+ return {
1694
+ cols: this.cols,
1695
+ rowHeight: this.rowHeight,
1696
+ height: this.height,
1697
+ layout: this.layout,
1698
+ preventCollision: this.preventCollision,
1699
+ gap: this.gap
1700
+ };
1701
+ }
1702
+ constructor(gridService, elementRef, viewContainerRef, renderer, ngZone) {
1703
+ this.gridService = gridService;
1704
+ this.elementRef = elementRef;
1705
+ this.viewContainerRef = viewContainerRef;
1706
+ this.renderer = renderer;
1707
+ this.ngZone = ngZone;
1708
+ /** Emits when layout change */
1709
+ this.layoutUpdated = new EventEmitter();
1710
+ /** Emits when drag starts */
1711
+ this.dragStarted = new EventEmitter();
1712
+ /** Emits when resize starts */
1713
+ this.resizeStarted = new EventEmitter();
1714
+ /** Emits when drag ends */
1715
+ this.dragEnded = new EventEmitter();
1716
+ /** Emits when resize ends */
1717
+ this.resizeEnded = new EventEmitter();
1718
+ /** Emits when a grid item is being resized and its bounds have changed */
1719
+ this.gridItemResize = new EventEmitter();
1720
+ /**
1721
+ * Parent element that contains the scroll. If an string is provided it would search that element by id on the dom.
1722
+ * If no data provided or null autoscroll is not performed.
1723
+ */
1724
+ this.scrollableParent = null;
1725
+ this._compactOnPropsChange = true;
1726
+ this._preventCollision = false;
1727
+ this._scrollSpeed = 2;
1728
+ this._compactType = 'vertical';
1729
+ this._rowHeight = 100;
1730
+ this._cols = 6;
1731
+ this._gap = 0;
1732
+ this._height = null;
1733
+ this._backgroundConfig = null;
1734
+ this.subscriptions = [];
1735
+ }
1736
+ ngOnChanges(changes) {
1737
+ if (this.rowHeight === 'fit' && this.height == null) {
1738
+ console.warn(`KtdGridComponent: The @Input() height should not be null when using rowHeight 'fit'`);
1739
+ }
1740
+ let needsCompactLayout = false;
1741
+ let needsRecalculateRenderData = false;
1742
+ // TODO: Does fist change need to be compacted by default?
1743
+ // Compact layout whenever some dependent prop changes.
1744
+ if (changes.compactType || changes.cols || changes.layout) {
1745
+ needsCompactLayout = true;
1746
+ }
1747
+ // Check if wee need to recalculate rendering data.
1748
+ if (needsCompactLayout || changes.rowHeight || changes.height || changes.gap || changes.backgroundConfig) {
1749
+ needsRecalculateRenderData = true;
1750
+ }
1751
+ // Only compact layout if lib user has provided it. Lib users that want to save/store always the same layout as it is represented (compacted)
1752
+ // can use KtdCompactGrid utility and pre-compact the layout. This is the recommended behaviour for always having a the same layout on this component
1753
+ // and the ones that uses it.
1754
+ if (needsCompactLayout && this.compactOnPropsChange) {
1755
+ this.compactLayout();
1756
+ }
1757
+ if (needsRecalculateRenderData) {
1758
+ this.calculateRenderData();
1759
+ }
1760
+ }
1761
+ ngAfterContentInit() {
1762
+ this.initSubscriptions();
1763
+ }
1764
+ ngAfterContentChecked() {
1765
+ this.render();
1766
+ }
1767
+ resize() {
1768
+ this.calculateRenderData();
1769
+ this.render();
1770
+ }
1771
+ ngOnDestroy() {
1772
+ this.subscriptions.forEach((sub) => sub.unsubscribe());
1773
+ }
1774
+ compactLayout() {
1775
+ this.layout = compact(this.layout, this.compactType, this.cols);
1776
+ }
1777
+ getItemsRenderData() {
1778
+ return { ...this._gridItemsRenderData };
1779
+ }
1780
+ getItemRenderData(itemId) {
1781
+ return this._gridItemsRenderData[itemId];
1782
+ }
1783
+ calculateRenderData() {
1784
+ const clientRect = this.elementRef.nativeElement.getBoundingClientRect();
1785
+ this.gridCurrentHeight =
1786
+ this.height ??
1787
+ (this.rowHeight === 'fit' ? clientRect.height : getGridHeight(this.layout, this.rowHeight, this.gap));
1788
+ this._gridItemsRenderData = layoutToRenderItems(this.config, clientRect.width, this.gridCurrentHeight);
1789
+ // Set Background CSS variables
1790
+ this.setBackgroundCssVariables(getRowHeightInPixels(this.config, this.gridCurrentHeight));
1791
+ }
1792
+ render() {
1793
+ this.renderer.setStyle(this.elementRef.nativeElement, 'height', `${this.gridCurrentHeight}px`);
1794
+ this.updateGridItemsStyles();
1795
+ }
1796
+ setBackgroundCssVariables(rowHeight) {
1797
+ const style = this.elementRef.nativeElement.style;
1798
+ if (this._backgroundConfig) {
1799
+ // structure
1800
+ style.setProperty('--gap', this.gap + 'px');
1801
+ style.setProperty('--row-height', rowHeight + 'px');
1802
+ style.setProperty('--columns', `${this.cols}`);
1803
+ style.setProperty('--border-width', (this._backgroundConfig.borderWidth ?? defaultBackgroundConfig.borderWidth) + 'px');
1804
+ // colors
1805
+ style.setProperty('--border-color', this._backgroundConfig.borderColor ?? defaultBackgroundConfig.borderColor);
1806
+ style.setProperty('--gap-color', this._backgroundConfig.gapColor ?? defaultBackgroundConfig.gapColor);
1807
+ style.setProperty('--row-color', this._backgroundConfig.rowColor ?? defaultBackgroundConfig.rowColor);
1808
+ style.setProperty('--column-color', this._backgroundConfig.columnColor ?? defaultBackgroundConfig.columnColor);
1809
+ }
1810
+ else {
1811
+ style.removeProperty('--gap');
1812
+ style.removeProperty('--row-height');
1813
+ style.removeProperty('--columns');
1814
+ style.removeProperty('--border-width');
1815
+ style.removeProperty('--border-color');
1816
+ style.removeProperty('--gap-color');
1817
+ style.removeProperty('--row-color');
1818
+ style.removeProperty('--column-color');
1819
+ }
1820
+ }
1821
+ updateGridItemsStyles() {
1822
+ this._gridItems.forEach((item) => {
1823
+ const gridItemRenderData = this._gridItemsRenderData[item.id];
1824
+ if (gridItemRenderData == null) {
1825
+ console.error(`Couldn't find the specified grid item for the id: ${item.id}`);
1826
+ }
1827
+ else {
1828
+ item.setStyles(parseRenderItemToPixels(gridItemRenderData));
1829
+ }
1830
+ });
1831
+ }
1832
+ setGridBackgroundVisible(visible) {
1833
+ const classList = this.elementRef.nativeElement.classList;
1834
+ visible ? classList.add('buw-grid-background-visible') : classList.remove('buw-grid-background-visible');
1835
+ }
1836
+ initSubscriptions() {
1837
+ this.subscriptions = [
1838
+ this._gridItems.changes
1839
+ .pipe(startWith(this._gridItems), switchMap((gridItems) => merge(...gridItems.map((gridItem) => gridItem.dragStart$.pipe(map((event) => ({ event, gridItem, type: 'drag' })))), ...gridItems.map((gridItem) => gridItem.resizeStart$.pipe(map((event) => ({
1840
+ event,
1841
+ gridItem,
1842
+ type: 'resize'
1843
+ }))))).pipe(exhaustMap(({ event, gridItem, type }) => {
1844
+ // Emit drag or resize start events. Ensure that is start event is inside the zone.
1845
+ this.ngZone.run(() => (type === 'drag' ? this.dragStarted : this.resizeStarted).emit(getDragResizeEventData(gridItem, this.layout)));
1846
+ this.setGridBackgroundVisible(this._backgroundConfig?.show === 'whenDragging' ||
1847
+ this._backgroundConfig?.show === 'always');
1848
+ // Perform drag sequence
1849
+ return this.performDragSequence$(gridItem, event, type).pipe(map((layout) => ({ layout, gridItem, type })));
1850
+ }))))
1851
+ .subscribe(({ layout, gridItem, type }) => {
1852
+ this.layout = layout;
1853
+ // Calculate new rendering data given the new layout.
1854
+ this.calculateRenderData();
1855
+ // Emit drag or resize end events.
1856
+ (type === 'drag' ? this.dragEnded : this.resizeEnded).emit(getDragResizeEventData(gridItem, layout));
1857
+ // Notify that the layout has been updated.
1858
+ this.layoutUpdated.emit(layout);
1859
+ this.setGridBackgroundVisible(this._backgroundConfig?.show === 'always');
1860
+ })
1861
+ ];
1862
+ }
1863
+ /**
1864
+ * Perform a general grid drag action, from start to end. A general grid drag action basically includes creating the placeholder element and adding
1865
+ * some class animations. calcNewStateFunc needs to be provided in order to calculate the new state of the layout.
1866
+ * @param gridItem that is been dragged
1867
+ * @param pointerDownEvent event (mousedown or touchdown) where the user initiated the drag
1868
+ * @param calcNewStateFunc function that return the new layout state and the drag element position
1869
+ */
1870
+ performDragSequence$(gridItem, pointerDownEvent, type) {
1871
+ return new Observable((observer) => {
1872
+ // Retrieve grid (parent) and gridItem (draggedElem) client rects.
1873
+ const gridElemClientRect = getMutableClientRect(this.elementRef.nativeElement);
1874
+ const dragElemClientRect = getMutableClientRect(gridItem.elementRef.nativeElement);
1875
+ const scrollableParent = typeof this.scrollableParent === 'string'
1876
+ ? document.getElementById(this.scrollableParent)
1877
+ : this.scrollableParent;
1878
+ this.renderer.addClass(gridItem.elementRef.nativeElement, 'no-transitions');
1879
+ this.renderer.addClass(gridItem.elementRef.nativeElement, 'buw-grid-item-dragging');
1880
+ const placeholderClientRect = {
1881
+ ...dragElemClientRect,
1882
+ left: dragElemClientRect.left - gridElemClientRect.left,
1883
+ top: dragElemClientRect.top - gridElemClientRect.top
1884
+ };
1885
+ this.createPlaceholderElement(placeholderClientRect, gridItem.placeholder);
1886
+ let newLayout;
1887
+ // TODO (enhancement): consider move this 'side effect' observable inside the main drag loop.
1888
+ // - Pros are that we would not repeat subscriptions and takeUntil would shut down observables at the same time.
1889
+ // - Cons are that moving this functionality as a side effect inside the main drag loop would be confusing.
1890
+ const scrollSubscription = this.ngZone.runOutsideAngular(() => (!scrollableParent
1891
+ ? NEVER
1892
+ : this.gridService.mouseOrTouchMove$(document).pipe(map((event) => ({
1893
+ pointerX: ktdPointerClientX(event),
1894
+ pointerY: ktdPointerClientY(event)
1895
+ })), ktdScrollIfNearElementClientRect$(scrollableParent, { scrollStep: this.scrollSpeed })))
1896
+ .pipe(takeUntil(ktdPointerUp(document)))
1897
+ .subscribe());
1898
+ /**
1899
+ * Main subscription, it listens for 'pointer move' and 'scroll' events and recalculates the layout on each emission
1900
+ */
1901
+ const subscription = this.ngZone.runOutsideAngular(() => merge(combineLatest([
1902
+ this.gridService.mouseOrTouchMove$(document),
1903
+ ...(!scrollableParent
1904
+ ? [of({ top: 0, left: 0 })]
1905
+ : [
1906
+ ktdGetScrollTotalRelativeDifference$(scrollableParent).pipe(startWith({ top: 0, left: 0 }) // Force first emission to allow CombineLatest to emit even no scroll event has occurred
1907
+ )
1908
+ ])
1909
+ ]))
1910
+ .pipe(takeUntil(ktdPointerUp(document)))
1911
+ .subscribe(([pointerDragEvent, scrollDifference]) => {
1912
+ pointerDragEvent.preventDefault();
1913
+ /**
1914
+ * Set the new layout to be the layout in which the calcNewStateFunc would be executed.
1915
+ * NOTE: using the mutated layout is the way to go by 'react-grid-layout' utils. If we don't use the previous layout,
1916
+ * some utilities from 'react-grid-layout' would not work as expected.
1917
+ */
1918
+ const currentLayout = newLayout || this.layout;
1919
+ // Get the correct newStateFunc depending on if we are dragging or resizing
1920
+ const calcNewStateFunc = type === 'drag' ? ktdGridItemDragging : ktdGridItemResizing;
1921
+ const { layout, draggedItemPos } = calcNewStateFunc(gridItem, {
1922
+ layout: currentLayout,
1923
+ rowHeight: this.rowHeight,
1924
+ height: this.height,
1925
+ cols: this.cols,
1926
+ preventCollision: this.preventCollision,
1927
+ gap: this.gap
1928
+ }, this.compactType, {
1929
+ pointerDownEvent,
1930
+ pointerDragEvent,
1931
+ gridElemClientRect,
1932
+ dragElemClientRect,
1933
+ scrollDifference
1934
+ });
1935
+ newLayout = layout;
1936
+ this.gridCurrentHeight =
1937
+ this.height ??
1938
+ (this.rowHeight === 'fit'
1939
+ ? gridElemClientRect.height
1940
+ : getGridHeight(newLayout, this.rowHeight, this.gap));
1941
+ this._gridItemsRenderData = layoutToRenderItems({
1942
+ cols: this.cols,
1943
+ rowHeight: this.rowHeight,
1944
+ height: this.height,
1945
+ layout: newLayout,
1946
+ preventCollision: this.preventCollision,
1947
+ gap: this.gap
1948
+ }, gridElemClientRect.width, gridElemClientRect.height);
1949
+ const newGridItemRenderData = { ...this._gridItemsRenderData[gridItem.id] };
1950
+ const placeholderStyles = parseRenderItemToPixels(newGridItemRenderData);
1951
+ // Put the real final position to the placeholder element
1952
+ this.placeholder.style.width = placeholderStyles.width;
1953
+ this.placeholder.style.height = placeholderStyles.height;
1954
+ this.placeholder.style.transform = `translateX(${placeholderStyles.left}) translateY(${placeholderStyles.top})`;
1955
+ // modify the position of the dragged item to be the once we want (for example the mouse position or whatever)
1956
+ this._gridItemsRenderData[gridItem.id] = {
1957
+ ...draggedItemPos,
1958
+ id: this._gridItemsRenderData[gridItem.id].id
1959
+ };
1960
+ this.setBackgroundCssVariables(this.rowHeight === 'fit'
1961
+ ? ktdGetGridItemRowHeight(newLayout, gridElemClientRect.height, this.gap)
1962
+ : this.rowHeight);
1963
+ this.render();
1964
+ // If we are performing a resize, and bounds have changed, emit event.
1965
+ // NOTE: Only emit on resize for now. Use case for normal drag is not justified for now. Emitting on resize is,
1966
+ // since we may want to re-render the grid item or the placeholder in order to fit the new bounds.
1967
+ if (type === 'resize') {
1968
+ const prevGridItem = currentLayout.find((item) => item.id === gridItem.id);
1969
+ const newGridItem = newLayout.find((item) => item.id === gridItem.id);
1970
+ // Check if item resized has changed, if so, emit resize change event
1971
+ if (!ktdGridItemLayoutItemAreEqual(prevGridItem, newGridItem)) {
1972
+ this.gridItemResize.emit({
1973
+ width: newGridItemRenderData.width,
1974
+ height: newGridItemRenderData.height,
1975
+ gridItemRef: getDragResizeEventData(gridItem, newLayout).gridItemRef
1976
+ });
1977
+ }
1978
+ }
1979
+ }, (error) => observer.error(error), () => {
1980
+ this.ngZone.run(() => {
1981
+ // Remove drag classes
1982
+ this.renderer.removeClass(gridItem.elementRef.nativeElement, 'no-transitions');
1983
+ this.renderer.removeClass(gridItem.elementRef.nativeElement, 'buw-grid-item-dragging');
1984
+ this.addGridItemAnimatingClass(gridItem).subscribe();
1985
+ // Consider destroying the placeholder after the animation has finished.
1986
+ this.destroyPlaceholder();
1987
+ if (newLayout) {
1988
+ // TODO: newLayout should already be pruned. If not, it should have type Layout, not KtdGridLayout as it is now.
1989
+ // Prune react-grid-layout compact extra properties.
1990
+ observer.next(newLayout.map((item) => ({
1991
+ id: item.id,
1992
+ x: item.x,
1993
+ y: item.y,
1994
+ w: item.w,
1995
+ h: item.h,
1996
+ minW: item.minW,
1997
+ minH: item.minH,
1998
+ maxW: item.maxW,
1999
+ maxH: item.maxH
2000
+ })));
2001
+ }
2002
+ else {
2003
+ // TODO: Need we really to emit if there is no layout change but drag started and ended?
2004
+ observer.next(this.layout);
2005
+ }
2006
+ observer.complete();
2007
+ });
2008
+ }));
2009
+ return () => {
2010
+ scrollSubscription.unsubscribe();
2011
+ subscription.unsubscribe();
2012
+ };
2013
+ });
2014
+ }
2015
+ /**
2016
+ * It adds the `buw-grid-item-animating` class and removes it when the animated transition is complete.
2017
+ * This function is meant to be executed when the drag has ended.
2018
+ * @param gridItem that has been dragged
2019
+ */
2020
+ addGridItemAnimatingClass(gridItem) {
2021
+ return new Observable((observer) => {
2022
+ const duration = getTransformTransitionDurationInMs(gridItem.elementRef.nativeElement);
2023
+ if (duration === 0) {
2024
+ observer.next();
2025
+ observer.complete();
2026
+ return;
2027
+ }
2028
+ this.renderer.addClass(gridItem.elementRef.nativeElement, 'buw-grid-item-animating');
2029
+ const handler = ((event) => {
2030
+ if (!event ||
2031
+ (event.target === gridItem.elementRef.nativeElement && event.propertyName === 'transform')) {
2032
+ this.renderer.removeClass(gridItem.elementRef.nativeElement, 'buw-grid-item-animating');
2033
+ removeEventListener();
2034
+ clearTimeout(timeout);
2035
+ observer.next();
2036
+ observer.complete();
2037
+ }
2038
+ });
2039
+ // If a transition is short enough, the browser might not fire the `transitionend` event.
2040
+ // Since we know how long it's supposed to take, add a timeout with a 50% buffer that'll
2041
+ // fire if the transition hasn't completed when it was supposed to.
2042
+ const timeout = setTimeout(handler, duration * 1.5);
2043
+ const removeEventListener = this.renderer.listen(gridItem.elementRef.nativeElement, 'transitionend', handler);
2044
+ });
2045
+ }
2046
+ /** Creates placeholder element */
2047
+ createPlaceholderElement(clientRect, gridItemPlaceholder) {
2048
+ this.placeholder = this.renderer.createElement('div');
2049
+ this.placeholder.style.width = `${clientRect.width}px`;
2050
+ this.placeholder.style.height = `${clientRect.height}px`;
2051
+ this.placeholder.style.transform = `translateX(${clientRect.left}px) translateY(${clientRect.top}px)`;
2052
+ this.placeholder.classList.add('buw-grid-item-placeholder');
2053
+ this.renderer.appendChild(this.elementRef.nativeElement, this.placeholder);
2054
+ // Create and append custom placeholder if provided.
2055
+ // Important: Append it after creating & appending the container placeholder. This way we ensure parent bounds are set when creating the embeddedView.
2056
+ if (gridItemPlaceholder) {
2057
+ this.placeholderRef = this.viewContainerRef.createEmbeddedView(gridItemPlaceholder.templateRef, gridItemPlaceholder.data);
2058
+ this.placeholderRef.rootNodes.forEach((node) => this.placeholder.appendChild(node));
2059
+ this.placeholderRef.detectChanges();
2060
+ }
2061
+ else {
2062
+ this.placeholder.classList.add('buw-grid-item-placeholder-default');
2063
+ }
2064
+ }
2065
+ /** Destroys the placeholder element and its ViewRef. */
2066
+ destroyPlaceholder() {
2067
+ this.placeholder?.remove();
2068
+ this.placeholderRef?.destroy();
2069
+ this.placeholder = this.placeholderRef = null;
2070
+ }
2071
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KtdGridComponent, deps: [{ token: KtdGridService }, { token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
2072
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: KtdGridComponent, selector: "buw-grid", inputs: { scrollableParent: "scrollableParent", compactOnPropsChange: "compactOnPropsChange", preventCollision: "preventCollision", scrollSpeed: "scrollSpeed", compactType: "compactType", rowHeight: "rowHeight", cols: "cols", layout: "layout", gap: "gap", height: "height", backgroundConfig: "backgroundConfig" }, outputs: { layoutUpdated: "layoutUpdated", dragStarted: "dragStarted", resizeStarted: "resizeStarted", dragEnded: "dragEnded", resizeEnded: "resizeEnded", gridItemResize: "gridItemResize" }, providers: [
2073
+ {
2074
+ provide: GRID_ITEM_GET_RENDER_DATA_TOKEN,
2075
+ useFactory: ktdGridItemGetRenderDataFactoryFunc,
2076
+ deps: [KtdGridComponent]
2077
+ }
2078
+ ], queries: [{ propertyName: "_gridItems", predicate: KtdGridItemComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-content></ng-content>", styles: ["buw-grid{display:block;position:relative;width:100%}buw-grid.buw-grid-background:before{content:\"\";border:none;position:absolute;inset:0;z-index:0;transition:opacity .2s;opacity:0;background-image:repeating-linear-gradient(var(--border-color) 0 var(--border-width),var(--row-color) var(--border-width) calc(var(--row-height) - var(--border-width)),var(--border-color) calc(var(--row-height) - var(--border-width)) calc(var(--row-height)),var(--gap-color) calc(var(--row-height)) calc(var(--row-height) + var(--gap))),repeating-linear-gradient(90deg,var(--border-color) 0 var(--border-width),var(--column-color) var(--border-width) calc(100% - (var(--border-width) + var(--gap))),var(--border-color) calc(100% - (var(--border-width) + var(--gap))) calc(100% - var(--gap)),var(--gap-color) calc(100% - var(--gap)) 100%);background-size:calc((100% + var(--gap)) / var(--columns)) calc(var(--row-height) + var(--gap));background-position:0 0}buw-grid.buw-grid-background.buw-grid-background-visible:before{opacity:1}buw-grid buw-grid-item.buw-grid-item-dragging,buw-grid buw-grid-item.buw-grid-item-animating{z-index:1000}buw-grid buw-grid-item.no-transitions{transition:none!important}buw-grid .buw-grid-item-placeholder{position:absolute;z-index:0;transition-property:transform;transition:all .15s ease}buw-grid .buw-grid-item-placeholder-default{background-color:#8b0000;opacity:.6}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
2079
+ }
2080
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KtdGridComponent, decorators: [{
2081
+ type: Component,
2082
+ args: [{ selector: 'buw-grid', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
2083
+ {
2084
+ provide: GRID_ITEM_GET_RENDER_DATA_TOKEN,
2085
+ useFactory: ktdGridItemGetRenderDataFactoryFunc,
2086
+ deps: [KtdGridComponent]
2087
+ }
2088
+ ], template: "<ng-content></ng-content>", styles: ["buw-grid{display:block;position:relative;width:100%}buw-grid.buw-grid-background:before{content:\"\";border:none;position:absolute;inset:0;z-index:0;transition:opacity .2s;opacity:0;background-image:repeating-linear-gradient(var(--border-color) 0 var(--border-width),var(--row-color) var(--border-width) calc(var(--row-height) - var(--border-width)),var(--border-color) calc(var(--row-height) - var(--border-width)) calc(var(--row-height)),var(--gap-color) calc(var(--row-height)) calc(var(--row-height) + var(--gap))),repeating-linear-gradient(90deg,var(--border-color) 0 var(--border-width),var(--column-color) var(--border-width) calc(100% - (var(--border-width) + var(--gap))),var(--border-color) calc(100% - (var(--border-width) + var(--gap))) calc(100% - var(--gap)),var(--gap-color) calc(100% - var(--gap)) 100%);background-size:calc((100% + var(--gap)) / var(--columns)) calc(var(--row-height) + var(--gap));background-position:0 0}buw-grid.buw-grid-background.buw-grid-background-visible:before{opacity:1}buw-grid buw-grid-item.buw-grid-item-dragging,buw-grid buw-grid-item.buw-grid-item-animating{z-index:1000}buw-grid buw-grid-item.no-transitions{transition:none!important}buw-grid .buw-grid-item-placeholder{position:absolute;z-index:0;transition-property:transform;transition:all .15s ease}buw-grid .buw-grid-item-placeholder-default{background-color:#8b0000;opacity:.6}\n"] }]
2089
+ }], ctorParameters: () => [{ type: KtdGridService }, { type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i0.Renderer2 }, { type: i0.NgZone }], propDecorators: { _gridItems: [{
2090
+ type: ContentChildren,
2091
+ args: [KtdGridItemComponent, { descendants: true }]
2092
+ }], layoutUpdated: [{
2093
+ type: Output
2094
+ }], dragStarted: [{
2095
+ type: Output
2096
+ }], resizeStarted: [{
2097
+ type: Output
2098
+ }], dragEnded: [{
2099
+ type: Output
2100
+ }], resizeEnded: [{
2101
+ type: Output
2102
+ }], gridItemResize: [{
2103
+ type: Output
2104
+ }], scrollableParent: [{
2105
+ type: Input
2106
+ }], compactOnPropsChange: [{
2107
+ type: Input
2108
+ }], preventCollision: [{
2109
+ type: Input
2110
+ }], scrollSpeed: [{
2111
+ type: Input
2112
+ }], compactType: [{
2113
+ type: Input
2114
+ }], rowHeight: [{
2115
+ type: Input
2116
+ }], cols: [{
2117
+ type: Input
2118
+ }], layout: [{
2119
+ type: Input
2120
+ }], gap: [{
2121
+ type: Input
2122
+ }], height: [{
2123
+ type: Input
2124
+ }], backgroundConfig: [{
2125
+ type: Input
2126
+ }] } });
2127
+
2128
+ class NavContainerComponent extends BaseComponent {
2129
+ constructor() {
2130
+ super(...arguments);
2131
+ this._router = inject(Router);
2132
+ }
2133
+ onTabSelect(e) {
2134
+ console.log(e);
2135
+ if (e.label === 'صفحه اصلی') {
2136
+ this._router.navigate(['/home']);
2137
+ }
2138
+ if (e.label === 'برنامه ها') {
2139
+ this._router.navigate(['/home/launchpad']);
2140
+ }
2141
+ }
2142
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NavContainerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2143
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: NavContainerComponent, selector: "buw-nav-container", providers: [], usesInheritance: true, ngImport: i0, template: "<div class=\"fd-shellbar fd-shellbar--xl\">\r\n <fdp-icon-tab-bar layoutMode=\"row\" maxContentHeight=\"250px\" (iconTabSelected)=\"onTabSelect($event)\">\r\n <fdp-icon-tab-bar-tab label=\"\u0635\u0641\u062D\u0647 \u0627\u0635\u0644\u06CC\" active> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632 \u06A9\u0627\u0631 \u0645\u0646\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u062A\u06CC\u06A9\u062A\u06CC\u0646\u06AF\">\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06311\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06312\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06313\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06314\"> </fdp-icon-tab-bar-tab>\r\n </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u0646\u0627\u0628\u0639 \u0627\u0646\u0633\u0627\u0646\u06CC\">\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06311\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06312\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06313\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06314\"> </fdp-icon-tab-bar-tab>\r\n </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u0631\u0647\u0627\">\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06311\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06312\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06313\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06314\"> </fdp-icon-tab-bar-tab>\r\n </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0627\u0628\u0632\u0627\u0631\u0647\u0627\"> </fdp-icon-tab-bar-tab>\r\n </fdp-icon-tab-bar>\r\n</div>", styles: [":host{display:block}:host ::ng-deep>div ul{background-color:transparent}:host ::ng-deep>div ul .fd-icon-tab-bar__tag{color:#fff}:host ::ng-deep>div ul fd-icon,:host ::ng-deep>div ul .fd-icon-tab-bar__arrow{color:#fff!important}:host ::ng-deep>div ul .fd-icon-tab-bar__tab[aria-selected=true]:after{background-color:#fff}\n"], dependencies: [{ kind: "component", type: i1.IconTabBarComponent, selector: "fdp-icon-tab-bar", inputs: ["stackContent", "iconTabType", "tabsConfig", "densityMode", "iconTabFont", "enableTabReordering", "showTotalTab", "multiClick", "layoutMode", "iconTabBackground", "iconTabSize", "colorAssociations", "maxContentHeight"], outputs: ["tabsConfigChange", "densityModeChange", "iconTabSelected", "iconTabReordered", "closeTab"] }, { kind: "component", type: i1.IconTabBarTabComponent, selector: "fdp-icon-tab-bar-tab", inputs: ["label", "color", "icon", "iconFont", "counter", "active", "badge", "closable", "id"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2144
+ }
2145
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NavContainerComponent, decorators: [{
2146
+ type: Component,
2147
+ args: [{ selector: 'buw-nav-container', providers: [], changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<div class=\"fd-shellbar fd-shellbar--xl\">\r\n <fdp-icon-tab-bar layoutMode=\"row\" maxContentHeight=\"250px\" (iconTabSelected)=\"onTabSelect($event)\">\r\n <fdp-icon-tab-bar-tab label=\"\u0635\u0641\u062D\u0647 \u0627\u0635\u0644\u06CC\" active> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632 \u06A9\u0627\u0631 \u0645\u0646\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u062A\u06CC\u06A9\u062A\u06CC\u0646\u06AF\">\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06311\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06312\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06313\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06314\"> </fdp-icon-tab-bar-tab>\r\n </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u0646\u0627\u0628\u0639 \u0627\u0646\u0633\u0627\u0646\u06CC\">\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06311\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06312\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06313\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06314\"> </fdp-icon-tab-bar-tab>\r\n </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u0631\u0647\u0627\">\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06311\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06312\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06313\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0645\u06CC\u0632\u06A9\u0627\u06314\"> </fdp-icon-tab-bar-tab>\r\n </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\"> </fdp-icon-tab-bar-tab>\r\n <fdp-icon-tab-bar-tab label=\"\u0627\u0628\u0632\u0627\u0631\u0647\u0627\"> </fdp-icon-tab-bar-tab>\r\n </fdp-icon-tab-bar>\r\n</div>", styles: [":host{display:block}:host ::ng-deep>div ul{background-color:transparent}:host ::ng-deep>div ul .fd-icon-tab-bar__tag{color:#fff}:host ::ng-deep>div ul fd-icon,:host ::ng-deep>div ul .fd-icon-tab-bar__arrow{color:#fff!important}:host ::ng-deep>div ul .fd-icon-tab-bar__tab[aria-selected=true]:after{background-color:#fff}\n"] }]
2148
+ }] });
2149
+
2150
+ /**
2151
+ * Removes and item from an array. Returns a new array instance (it doesn't mutate the source array).
2152
+ * @param array source array to be returned without the element to remove
2153
+ * @param condition function that will return true for the item that we want to remove
2154
+ */
2155
+ function ktdArrayRemoveItem(array, condition) {
2156
+ const arrayCopy = [...array];
2157
+ const index = array.findIndex((item) => condition(item));
2158
+ if (index > -1) {
2159
+ arrayCopy.splice(index, 1);
2160
+ }
2161
+ return arrayCopy;
2162
+ }
2163
+
2164
+ class LayoutContainerComponent extends BaseComponent {
2165
+ constructor(ngZone, elementRef, document) {
2166
+ // this.ngZone.onUnstable.subscribe(() => console.log('UnStable'));
2167
+ super();
2168
+ this.ngZone = ngZone;
2169
+ this.elementRef = elementRef;
2170
+ this.document = document;
2171
+ // @Input() layout: KtdGridLayout = [{ id: '0', x: 5, y: 0, w: 2, h: 3 }];
2172
+ this.layout = [];
2173
+ this.moDataList = [];
2174
+ this.trackById = ktdTrackById;
2175
+ this.cols = 12;
2176
+ this.rowHeight = 50;
2177
+ this.rowHeightFit = false;
2178
+ this.gridHeight = null;
2179
+ this.compactType = 'vertical';
2180
+ this.transitions = [
2181
+ { name: 'ease', value: 'transform 500ms ease, width 500ms ease, height 500ms ease' },
2182
+ { name: 'ease-out', value: 'transform 500ms ease-out, width 500ms ease-out, height 500ms ease-out' },
2183
+ { name: 'linear', value: 'transform 500ms linear, width 500ms linear, height 500ms linear' },
2184
+ {
2185
+ name: 'overflowing',
2186
+ value: 'transform 500ms cubic-bezier(.28,.49,.79,1.35), width 500ms cubic-bezier(.28,.49,.79,1.35), height 500ms cubic-bezier(.28,.49,.79,1.35)'
2187
+ },
2188
+ { name: 'fast', value: 'transform 200ms ease, width 200ms linear, height 200ms linear' },
2189
+ { name: 'slow-motion', value: 'transform 1000ms linear, width 1000ms linear, height 1000ms linear' },
2190
+ { name: 'transform-only', value: 'transform 500ms ease' }
2191
+ ];
2192
+ this.currentTransition = this.transitions[0].value;
2193
+ this.placeholders = ['None', 'Default', 'Custom 1', 'Custom 2', 'Custom 3'];
2194
+ this.currentPlaceholder = 'Default';
2195
+ this.dragStartThreshold = 0;
2196
+ this.gap = 10;
2197
+ this.autoScroll = true;
2198
+ this.disableDrag = false;
2199
+ this.disableResize = false;
2200
+ this.disableRemove = false;
2201
+ this.autoResize = true;
2202
+ this.preventCollision = false;
2203
+ this.isDragging = false;
2204
+ this.isResizing = false;
2205
+ this.showBackground = false;
2206
+ this.gridBackgroundVisibilityOptions = ['never', 'always', 'whenDragging'];
2207
+ this.gridBackgroundConfig = {
2208
+ show: 'always',
2209
+ borderColor: 'rgba(255, 128, 0, 0.25)',
2210
+ gapColor: 'transparent',
2211
+ borderWidth: 1,
2212
+ rowColor: 'rgba(128, 128, 128, 0.10)',
2213
+ columnColor: 'rgba(128, 128, 128, 0.10)'
2214
+ };
2215
+ }
2216
+ ngOnInit() {
2217
+ this.resizeSubscription = merge(fromEvent(window, 'resize'), fromEvent(window, 'orientationchange'))
2218
+ .pipe(debounceTime(50), filter$1(() => this.autoResize))
2219
+ .subscribe(() => {
2220
+ this.grid.resize();
2221
+ });
2222
+ }
2223
+ ngOnDestroy() {
2224
+ this.resizeSubscription.unsubscribe();
2225
+ }
2226
+ ngOnChanges(changes) {
2227
+ super.ngOnChanges(changes);
2228
+ const { layout } = changes;
2229
+ if (layout && !layout.firstChange) {
2230
+ this.grid.resize();
2231
+ }
2232
+ }
2233
+ onDragStarted(event) {
2234
+ this.isDragging = true;
2235
+ }
2236
+ onResizeStarted(event) {
2237
+ this.isResizing = true;
2238
+ }
2239
+ onDragEnded(event) {
2240
+ this.isDragging = false;
2241
+ }
2242
+ onResizeEnded(event) {
2243
+ this.isResizing = false;
2244
+ }
2245
+ onLayoutUpdated(layout) {
2246
+ console.log('on layout updated', layout);
2247
+ this.layout = layout;
2248
+ }
2249
+ onAutoScrollChange(checked) {
2250
+ this.autoScroll = checked;
2251
+ }
2252
+ onDisableDragChange(checked) {
2253
+ this.disableDrag = checked;
2254
+ }
2255
+ onDisableResizeChange(checked) {
2256
+ this.disableResize = checked;
2257
+ }
2258
+ onShowBackgroundChange(checked) {
2259
+ this.showBackground = checked;
2260
+ }
2261
+ onDisableRemoveChange(checked) {
2262
+ this.disableRemove = checked;
2263
+ }
2264
+ onAutoResizeChange(checked) {
2265
+ this.autoResize = checked;
2266
+ }
2267
+ onPreventCollisionChange(checked) {
2268
+ this.preventCollision = checked;
2269
+ }
2270
+ onColsChange(event) {
2271
+ this.cols = coerceNumberProperty$1(event.target.value);
2272
+ }
2273
+ onRowHeightChange(event) {
2274
+ this.rowHeight = coerceNumberProperty$1(event.target.value);
2275
+ }
2276
+ onGridHeightChange(event) {
2277
+ this.gridHeight = coerceNumberProperty$1(event.target.value);
2278
+ }
2279
+ onDragStartThresholdChange(event) {
2280
+ this.dragStartThreshold = coerceNumberProperty$1(event.target.value);
2281
+ }
2282
+ onGapChange(event) {
2283
+ this.gap = coerceNumberProperty$1(event.target.value);
2284
+ }
2285
+ generateLayout() {
2286
+ const layout = [];
2287
+ for (let i = 0; i < this.cols; i++) {
2288
+ const y = Math.ceil(Math.random() * 4) + 1;
2289
+ layout.push({
2290
+ x: Math.round(Math.random() * Math.floor(this.cols / 2 - 1)) * 2,
2291
+ y: Math.floor(i / 6) * y,
2292
+ w: 2,
2293
+ h: y,
2294
+ id: i.toString()
2295
+ // static: Math.random() < 0.05
2296
+ });
2297
+ }
2298
+ this.layout = ktdGridCompact(layout, this.compactType, this.cols);
2299
+ console.log('generateLayout', this.layout);
2300
+ }
2301
+ /** Adds a grid item to the layout */
2302
+ addItemToLayout() {
2303
+ const maxId = this.layout.reduce((acc, cur) => Math.max(acc, parseInt(cur.id, 10)), -1);
2304
+ const nextId = maxId + 1;
2305
+ const newLayoutItem = {
2306
+ id: nextId.toString(),
2307
+ x: -1,
2308
+ y: -1,
2309
+ w: 2,
2310
+ h: 2
2311
+ };
2312
+ // Important: Don't mutate the array, create new instance. This way notifies the Grid component that the layout has changed.
2313
+ this.layout = [newLayoutItem, ...this.layout];
2314
+ this.layout = ktdGridCompact(this.layout, this.compactType, this.cols);
2315
+ }
2316
+ /**
2317
+ * Fired when a mousedown happens on the remove grid item button.
2318
+ * Stops the event from propagating an causing the drag to start.
2319
+ * We don't want to drag when mousedown is fired on remove icon button.
2320
+ */
2321
+ stopEventPropagation(event) {
2322
+ event.preventDefault();
2323
+ event.stopPropagation();
2324
+ }
2325
+ /** Removes the item from the layout */
2326
+ removeItem(id) {
2327
+ // Important: Don't mutate the array. Let Angular know that the layout has changed creating a new reference.
2328
+ this.layout = ktdArrayRemoveItem(this.layout, (item) => item.id === id);
2329
+ }
2330
+ updateGridBgBorderWidth(borderWidth) {
2331
+ this.gridBackgroundConfig = {
2332
+ ...this.gridBackgroundConfig,
2333
+ borderWidth: Number(borderWidth)
2334
+ };
2335
+ }
2336
+ updateGridBgColor(color, property) {
2337
+ this.gridBackgroundConfig = {
2338
+ ...this.gridBackgroundConfig,
2339
+ [property]: color
2340
+ };
2341
+ }
2342
+ getCurrentBackgroundVisibility() {
2343
+ return this.gridBackgroundConfig?.show ?? 'never';
2344
+ }
2345
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LayoutContainerComponent, deps: [{ token: i0.NgZone }, { token: i0.ElementRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); }
2346
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: LayoutContainerComponent, selector: "buw-layout-container", inputs: { layout: "layout", moDataList: "moDataList" }, providers: [], viewQueries: [{ propertyName: "grid", first: true, predicate: KtdGridComponent, descendants: true, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div style=\"position: relative\" dir=\"ltr\" fillEmptySpace [setMinHeight]=\"true\">\r\n <buw-grid\r\n [cols]=\"cols\"\r\n [backgroundConfig]=\"gridBackgroundConfig\"\r\n [height]=\"rowHeightFit && gridHeight ? gridHeight : null\"\r\n [rowHeight]=\"rowHeightFit ? 'fit' : rowHeight\"\r\n [layout]=\"layout\"\r\n [compactType]=\"compactType\"\r\n [preventCollision]=\"preventCollision\"\r\n [scrollableParent]=\"autoScroll ? document : null\"\r\n [gap]=\"gap\"\r\n [scrollSpeed]=\"4\"\r\n (dragStarted)=\"onDragStarted($event)\"\r\n (resizeStarted)=\"onResizeStarted($event)\"\r\n (dragEnded)=\"onDragEnded($event)\"\r\n (resizeEnded)=\"onResizeEnded($event)\"\r\n (layoutUpdated)=\"onLayoutUpdated($event)\"\r\n >\r\n <buw-grid-item\r\n *ngFor=\"let item of layout; trackBy: trackById; let i = index\"\r\n [id]=\"item.id\"\r\n [transition]=\"currentTransition\"\r\n [dragStartThreshold]=\"dragStartThreshold\"\r\n [draggable]=\"!disableDrag\"\r\n [resizable]=\"!disableResize\"\r\n >\r\n <div class=\"grid-item-content\">\r\n @if(moDataList?.length && moDataList[i]?.EjrayOlgo ){\r\n <bnrc-dynamic-item-component [component]=\"moDataList[i].EjrayOlgo\"> </bnrc-dynamic-item-component>\r\n }\r\n \r\n </div>\r\n <div\r\n class=\"grid-item-remove-handle\"\r\n *ngIf=\"!disableRemove\"\r\n (mousedown)=\"stopEventPropagation($event)\"\r\n (click)=\"removeItem(item.id)\"\r\n ></div>\r\n <ng-template *ngIf=\"currentPlaceholder !== 'Default'\" buwGridItemPlaceholder>\r\n <div\r\n *ngIf=\"currentPlaceholder === 'Custom 1'\"\r\n class=\"grid-item-content custom-placeholder custom-placeholder-1\"\r\n >\r\n {{ item.id }}\r\n </div>\r\n <div\r\n *ngIf=\"currentPlaceholder === 'Custom 2'\"\r\n class=\"grid-item-content custom-placeholder custom-placeholder-2\"\r\n >\r\n {{ item.id }}\r\n </div>\r\n <div\r\n *ngIf=\"currentPlaceholder === 'Custom 3'\"\r\n class=\"grid-item-content custom-placeholder custom-placeholder-3\"\r\n >\r\n {{ item.id }}\r\n </div>\r\n </ng-template>\r\n </buw-grid-item>\r\n </buw-grid>\r\n</div>\r\n", styles: [":host{display:block}:host ::ng-deep .grid-item-content{box-sizing:border-box;background:#ccc;border:1px solid;width:100%;height:100%;-webkit-user-select:none;user-select:none;display:flex;align-items:center;justify-content:center}:host ::ng-deep .grid-item-remove-handle{position:absolute;cursor:pointer;display:flex;justify-content:center;width:20px;height:20px;top:0;right:0}:host ::ng-deep .grid-item-remove-handle:after{content:\"x\";color:#121212;font-size:16px;font-weight:300;font-family:Arial,sans-serif}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i1$2.DynamicItemComponent, selector: "bnrc-dynamic-item-component", inputs: ["mo", "allColumns", "moDataList", "columns", "column", "index", "last", "hideOpenIcon", "deviceName", "deviceSize", "rtl", "editMode", "setting", "parameters", "contextMenuItems", "canView", "showRowNumber", "rowNumber", "formSetting", "conditionalFormats", "disableOverflowContextMenu", "navigationArrow", "isCheckList", "fields", "isChecked", "layout94$", "inlineEditMode", "isNewInlineMo", "allowInlineEdit", "typeDefId", "rowIndicator", "rowIndicatorColor", "UlvMainCtrlr"] }, { kind: "directive", type: i1$2.FillEmptySpaceDirective, selector: "[fillEmptySpace]", inputs: ["containerDom", "decrement", "disable", "height", "dontUseTopBound", "setMinHeight"], exportAs: ["fillEmptySpace"] }, { kind: "component", type: KtdGridComponent, selector: "buw-grid", inputs: ["scrollableParent", "compactOnPropsChange", "preventCollision", "scrollSpeed", "compactType", "rowHeight", "cols", "layout", "gap", "height", "backgroundConfig"], outputs: ["layoutUpdated", "dragStarted", "resizeStarted", "dragEnded", "resizeEnded", "gridItemResize"] }, { kind: "component", type: KtdGridItemComponent, selector: "buw-grid-item", inputs: ["minW", "minH", "maxW", "maxH", "transition", "id", "dragStartThreshold", "draggable", "resizable"] }, { kind: "directive", type: KtdGridItemPlaceholder, selector: "ng-template[buwGridItemPlaceholder]", inputs: ["data"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2347
+ }
2348
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LayoutContainerComponent, decorators: [{
2349
+ type: Component,
2350
+ args: [{ selector: 'buw-layout-container', providers: [], changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<div style=\"position: relative\" dir=\"ltr\" fillEmptySpace [setMinHeight]=\"true\">\r\n <buw-grid\r\n [cols]=\"cols\"\r\n [backgroundConfig]=\"gridBackgroundConfig\"\r\n [height]=\"rowHeightFit && gridHeight ? gridHeight : null\"\r\n [rowHeight]=\"rowHeightFit ? 'fit' : rowHeight\"\r\n [layout]=\"layout\"\r\n [compactType]=\"compactType\"\r\n [preventCollision]=\"preventCollision\"\r\n [scrollableParent]=\"autoScroll ? document : null\"\r\n [gap]=\"gap\"\r\n [scrollSpeed]=\"4\"\r\n (dragStarted)=\"onDragStarted($event)\"\r\n (resizeStarted)=\"onResizeStarted($event)\"\r\n (dragEnded)=\"onDragEnded($event)\"\r\n (resizeEnded)=\"onResizeEnded($event)\"\r\n (layoutUpdated)=\"onLayoutUpdated($event)\"\r\n >\r\n <buw-grid-item\r\n *ngFor=\"let item of layout; trackBy: trackById; let i = index\"\r\n [id]=\"item.id\"\r\n [transition]=\"currentTransition\"\r\n [dragStartThreshold]=\"dragStartThreshold\"\r\n [draggable]=\"!disableDrag\"\r\n [resizable]=\"!disableResize\"\r\n >\r\n <div class=\"grid-item-content\">\r\n @if(moDataList?.length && moDataList[i]?.EjrayOlgo ){\r\n <bnrc-dynamic-item-component [component]=\"moDataList[i].EjrayOlgo\"> </bnrc-dynamic-item-component>\r\n }\r\n \r\n </div>\r\n <div\r\n class=\"grid-item-remove-handle\"\r\n *ngIf=\"!disableRemove\"\r\n (mousedown)=\"stopEventPropagation($event)\"\r\n (click)=\"removeItem(item.id)\"\r\n ></div>\r\n <ng-template *ngIf=\"currentPlaceholder !== 'Default'\" buwGridItemPlaceholder>\r\n <div\r\n *ngIf=\"currentPlaceholder === 'Custom 1'\"\r\n class=\"grid-item-content custom-placeholder custom-placeholder-1\"\r\n >\r\n {{ item.id }}\r\n </div>\r\n <div\r\n *ngIf=\"currentPlaceholder === 'Custom 2'\"\r\n class=\"grid-item-content custom-placeholder custom-placeholder-2\"\r\n >\r\n {{ item.id }}\r\n </div>\r\n <div\r\n *ngIf=\"currentPlaceholder === 'Custom 3'\"\r\n class=\"grid-item-content custom-placeholder custom-placeholder-3\"\r\n >\r\n {{ item.id }}\r\n </div>\r\n </ng-template>\r\n </buw-grid-item>\r\n </buw-grid>\r\n</div>\r\n", styles: [":host{display:block}:host ::ng-deep .grid-item-content{box-sizing:border-box;background:#ccc;border:1px solid;width:100%;height:100%;-webkit-user-select:none;user-select:none;display:flex;align-items:center;justify-content:center}:host ::ng-deep .grid-item-remove-handle{position:absolute;cursor:pointer;display:flex;justify-content:center;width:20px;height:20px;top:0;right:0}:host ::ng-deep .grid-item-remove-handle:after{content:\"x\";color:#121212;font-size:16px;font-weight:300;font-family:Arial,sans-serif}\n"] }]
2351
+ }], ctorParameters: () => [{ type: i0.NgZone }, { type: i0.ElementRef }, { type: Document, decorators: [{
2352
+ type: Inject,
2353
+ args: [DOCUMENT]
2354
+ }] }], propDecorators: { grid: [{
2355
+ type: ViewChild,
2356
+ args: [KtdGridComponent, { static: true }]
2357
+ }], layout: [{
2358
+ type: Input
2359
+ }], moDataList: [{
2360
+ type: Input
2361
+ }] } });
2362
+
2363
+ class LayoutGridMapperPipe {
2364
+ transform(molist) {
2365
+ const x = molist.map((c) => ({
2366
+ id: c.Id,
2367
+ x: +c.x,
2368
+ y: +c.y,
2369
+ w: +c.w,
2370
+ h: +c.h,
2371
+ minW: c.minW,
2372
+ minH: c.minH,
2373
+ maxW: c.maxW,
2374
+ maxH: c.maxH,
2375
+ ejrayOlgo: c.EjrayOlgo
2376
+ }));
2377
+ return x;
2378
+ }
2379
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LayoutGridMapperPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
2380
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: LayoutGridMapperPipe, name: "layoutGridMapper" }); }
2381
+ }
2382
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LayoutGridMapperPipe, decorators: [{
2383
+ type: Pipe,
2384
+ args: [{
2385
+ name: 'layoutGridMapper',
2386
+ standalone: false
2387
+ }]
2388
+ }] });
2389
+
2390
+ class ReportGridLayoutComponent extends ReportViewBaseComponent {
2391
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ReportGridLayoutComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2392
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ReportGridLayoutComponent, selector: "buw-report-grid-layout", providers: [], usesInheritance: true, ngImport: i0, template: "<div style=\"position: relative\" dir=\"ltr\" fillEmptySpace [setMinHeight]=\"true\">\r\n <buw-layout-container [moDataList]=\"moDataList\" [layout]=\"moDataList | layoutGridMapper\"> </buw-layout-container>\r\n</div>\r\n", styles: [":host{display:block}:host ::ng-deep .grid-item-content{box-sizing:border-box;background:#ccc;border:1px solid;width:100%;height:100%;-webkit-user-select:none;user-select:none;display:flex;align-items:center;justify-content:center}:host ::ng-deep .grid-item-remove-handle{position:absolute;cursor:pointer;display:flex;justify-content:center;width:20px;height:20px;top:0;right:0}:host ::ng-deep .grid-item-remove-handle:after{content:\"x\";color:#121212;font-size:16px;font-weight:300;font-family:Arial,sans-serif}\n"], dependencies: [{ kind: "directive", type: i1$2.FillEmptySpaceDirective, selector: "[fillEmptySpace]", inputs: ["containerDom", "decrement", "disable", "height", "dontUseTopBound", "setMinHeight"], exportAs: ["fillEmptySpace"] }, { kind: "component", type: LayoutContainerComponent, selector: "buw-layout-container", inputs: ["layout", "moDataList"] }, { kind: "pipe", type: LayoutGridMapperPipe, name: "layoutGridMapper" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2393
+ }
2394
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ReportGridLayoutComponent, decorators: [{
2395
+ type: Component,
2396
+ args: [{ selector: 'buw-report-grid-layout', providers: [], changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<div style=\"position: relative\" dir=\"ltr\" fillEmptySpace [setMinHeight]=\"true\">\r\n <buw-layout-container [moDataList]=\"moDataList\" [layout]=\"moDataList | layoutGridMapper\"> </buw-layout-container>\r\n</div>\r\n", styles: [":host{display:block}:host ::ng-deep .grid-item-content{box-sizing:border-box;background:#ccc;border:1px solid;width:100%;height:100%;-webkit-user-select:none;user-select:none;display:flex;align-items:center;justify-content:center}:host ::ng-deep .grid-item-remove-handle{position:absolute;cursor:pointer;display:flex;justify-content:center;width:20px;height:20px;top:0;right:0}:host ::ng-deep .grid-item-remove-handle:after{content:\"x\";color:#121212;font-size:16px;font-weight:300;font-family:Arial,sans-serif}\n"] }]
2397
+ }] });
2398
+
2399
+ const components = [
2400
+ KtdGridComponent,
2401
+ KtdGridItemComponent,
2402
+ NavContainerComponent,
2403
+ LayoutContainerComponent,
2404
+ ReportGridLayoutComponent
2405
+ ];
2406
+ const pipes = [LayoutGridMapperPipe];
2407
+ const directives = [KtdGridDragHandle, KtdGridResizeHandle, KtdGridItemPlaceholder];
2408
+ class BarsaUserWorkspaceModule extends BaseModule {
2409
+ constructor(dcm, componentFactoryResolver) {
2410
+ super(dcm, componentFactoryResolver, 'BarsaUserWorkspaceModule');
2411
+ this.dcm = dcm;
2412
+ this.componentFactoryResolver = componentFactoryResolver;
2413
+ this.dynamicComponents = [...components];
2414
+ }
2415
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BarsaUserWorkspaceModule, deps: [{ token: i1$2.DynamicComponentService }, { token: i0.ComponentFactoryResolver }], target: i0.ɵɵFactoryTarget.NgModule }); }
2416
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: BarsaUserWorkspaceModule, declarations: [KtdGridComponent,
2417
+ KtdGridItemComponent,
2418
+ NavContainerComponent,
2419
+ LayoutContainerComponent,
2420
+ ReportGridLayoutComponent, KtdGridDragHandle, KtdGridResizeHandle, KtdGridItemPlaceholder, LayoutGridMapperPipe], imports: [CommonModule,
2421
+ FormsModule,
2422
+ RouterModule,
2423
+ DragDropModule,
2424
+ CdkTableModule,
2425
+ FundamentalNgxCoreModule,
2426
+ FundamentalNgxPlatformModule,
2427
+ BarsaNovinRayCoreModule], exports: [KtdGridComponent,
2428
+ KtdGridItemComponent,
2429
+ NavContainerComponent,
2430
+ LayoutContainerComponent,
2431
+ ReportGridLayoutComponent, KtdGridDragHandle, KtdGridResizeHandle, KtdGridItemPlaceholder] }); }
2432
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BarsaUserWorkspaceModule, providers: [KtdGridService, ...pipes], imports: [CommonModule,
2433
+ FormsModule,
2434
+ RouterModule,
2435
+ DragDropModule,
2436
+ CdkTableModule,
2437
+ FundamentalNgxCoreModule,
2438
+ FundamentalNgxPlatformModule,
2439
+ BarsaNovinRayCoreModule] }); }
2440
+ }
2441
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BarsaUserWorkspaceModule, decorators: [{
2442
+ type: NgModule,
2443
+ args: [{
2444
+ imports: [
2445
+ CommonModule,
2446
+ FormsModule,
2447
+ RouterModule,
2448
+ DragDropModule,
2449
+ CdkTableModule,
2450
+ FundamentalNgxCoreModule,
2451
+ FundamentalNgxPlatformModule,
2452
+ BarsaNovinRayCoreModule
2453
+ ],
2454
+ declarations: [...components, ...directives, ...pipes],
2455
+ providers: [KtdGridService, ...pipes],
2456
+ exports: [...components, ...directives]
2457
+ }]
2458
+ }], ctorParameters: () => [{ type: i1$2.DynamicComponentService }, { type: i0.ComponentFactoryResolver }] });
2459
+
2460
+ /*
2461
+ * Public API Surface of grid
2462
+ */
2463
+
2464
+ /**
2465
+ * Generated bundle index. Do not edit.
2466
+ */
2467
+
2468
+ export { BarsaUserWorkspaceModule, GRID_ITEM_GET_RENDER_DATA_TOKEN, KTD_GRID_DRAG_HANDLE, KTD_GRID_ITEM_PLACEHOLDER, KTD_GRID_RESIZE_HANDLE, KtdGridComponent, KtdGridDragHandle, KtdGridItemComponent, KtdGridItemPlaceholder, KtdGridResizeHandle, LayoutContainerComponent, NavContainerComponent, ReportGridLayoutComponent, __gridItemGetRenderDataFactoryFunc, ktdGridCompact, ktdGridItemGetRenderDataFactoryFunc, ktdTrackById, parseRenderItemToPixels };
2469
+ //# sourceMappingURL=barsa-user-workspace.mjs.map