@progress/kendo-angular-grid 14.4.0-develop.8 → 15.0.0-develop.1
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.
- package/NOTICE.txt +146 -593
- package/common/clipboard-types.d.ts +102 -0
- package/common/clipboard.directive.d.ts +49 -0
- package/common/clipboard.service.d.ts +28 -0
- package/common/dom-events.service.d.ts +1 -0
- package/common/error-messages.d.ts +12 -0
- package/databinding.directive.d.ts +1 -1
- package/esm2020/column-menu/column-menu-item-base.mjs +2 -1
- package/esm2020/column-menu/column-menu.component.mjs +8 -5
- package/esm2020/columns/column-base.mjs +3 -2
- package/esm2020/columns/column-group.component.mjs +2 -1
- package/esm2020/columns/span-column.component.mjs +2 -1
- package/esm2020/common/clipboard-types.mjs +5 -0
- package/esm2020/common/clipboard.directive.mjs +185 -0
- package/esm2020/common/clipboard.service.mjs +218 -0
- package/esm2020/common/dom-events.service.mjs +1 -0
- package/esm2020/common/error-messages.mjs +45 -1
- package/esm2020/databinding.directive.mjs +3 -2
- package/esm2020/editing-directives/local-edit.service.mjs +2 -2
- package/esm2020/excel/excel.service.mjs +2 -1
- package/esm2020/filtering/cell/autocomplete-filter-cell.component.mjs +1 -1
- package/esm2020/filtering/cell/numeric-filter-cell.component.mjs +1 -1
- package/esm2020/filtering/menu/filter-menu-container.component.mjs +2 -2
- package/esm2020/filtering/menu/numeric-filter-menu-input.component.mjs +1 -1
- package/esm2020/grid.component.mjs +40 -34
- package/esm2020/grid.module.mjs +8 -4
- package/esm2020/grouping/group-scroll-binding.directive.mjs +2 -3
- package/esm2020/index.mjs +2 -0
- package/esm2020/package-metadata.mjs +2 -2
- package/esm2020/pager/pager-input.component.mjs +1 -1
- package/esm2020/pager/pager.component.mjs +1 -5
- package/esm2020/pdf/pdf.component.mjs +3 -2
- package/esm2020/pdf/pdf.service.mjs +2 -1
- package/esm2020/rendering/cell.component.mjs +33 -25
- package/esm2020/rendering/details/detail-template.directive.mjs +2 -1
- package/esm2020/rendering/header/header.component.mjs +16 -12
- package/esm2020/rendering/table-body.component.mjs +4 -4
- package/esm2020/selection/marquee.directive.mjs +11 -17
- package/esm2020/selection/selection-default.mjs +11 -5
- package/esm2020/utils.mjs +10 -0
- package/fesm2015/progress-kendo-angular-grid.mjs +598 -145
- package/fesm2020/progress-kendo-angular-grid.mjs +594 -145
- package/grid.component.d.ts +7 -1
- package/grid.module.d.ts +99 -98
- package/index.d.ts +3 -1
- package/package.json +16 -16
- package/pager/pager.component.d.ts +0 -1
- package/schematics/ngAdd/index.js +3 -3
- package/selection/marquee.directive.d.ts +4 -3
- package/selection/selection-default.d.ts +10 -4
- package/selection/types.d.ts +6 -0
- package/utils.d.ts +8 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**-----------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright © 2024 Progress Software Corporation. All rights reserved.
|
|
3
|
+
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
+
*-------------------------------------------------------------------------------------------*/
|
|
5
|
+
/**
|
|
6
|
+
* Represents the starting point (Grid cell) of the Grid clipboard operations.
|
|
7
|
+
*/
|
|
8
|
+
export declare type GridClipboardTargetType = 'selection' | 'activeCell';
|
|
9
|
+
/**
|
|
10
|
+
* The possible values of the Grid [`GridClipboardEvent`]({% slug api_grid_gridclipboardevent %}) `type` property.
|
|
11
|
+
*/
|
|
12
|
+
export declare type GridClipboardEventType = 'copy' | 'cut' | 'paste';
|
|
13
|
+
/**
|
|
14
|
+
* The Grid data items and their respective fields, affected by the current clipboard operation.
|
|
15
|
+
*/
|
|
16
|
+
export interface GridClipboardItem {
|
|
17
|
+
dataItem: any;
|
|
18
|
+
fields: string[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The event data, exposed in the `GridClipboardDirective` `clipboard` event.
|
|
22
|
+
*/
|
|
23
|
+
export interface GridClipboardEvent {
|
|
24
|
+
/**
|
|
25
|
+
* The type of the original clipboard event.
|
|
26
|
+
*/
|
|
27
|
+
type: GridClipboardEventType;
|
|
28
|
+
/**
|
|
29
|
+
* The data of the original DOM event.
|
|
30
|
+
*/
|
|
31
|
+
originalEvent: ClipboardEvent;
|
|
32
|
+
/**
|
|
33
|
+
* When the action is `copy` or `cut` - the Grid data, copied to the clipboard, in Excel-compatible format.
|
|
34
|
+
* When the action is `paste` - the current clipboard data, available in the original DOM event.
|
|
35
|
+
*/
|
|
36
|
+
clipboardData: string;
|
|
37
|
+
/**
|
|
38
|
+
* The Grid data items and their respective fields, affected by the clipboard action.
|
|
39
|
+
*/
|
|
40
|
+
gridData: GridClipboardItem[];
|
|
41
|
+
/**
|
|
42
|
+
* The Grid cell used as a target of the current clipboard operation.
|
|
43
|
+
*/
|
|
44
|
+
target: GridClipboardTargetCell;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
*
|
|
48
|
+
*/
|
|
49
|
+
export interface GridClipboardTargetCell {
|
|
50
|
+
/**
|
|
51
|
+
* The data index of the clipboard target cell parent row.
|
|
52
|
+
*/
|
|
53
|
+
dataRowIndex: number;
|
|
54
|
+
/**
|
|
55
|
+
* The field of the Grid column the clipboard target cell is in.
|
|
56
|
+
*/
|
|
57
|
+
colField: string;
|
|
58
|
+
/**
|
|
59
|
+
* The Grid data item corresponding to the clipboard target cell.
|
|
60
|
+
*/
|
|
61
|
+
dataItem: any;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The `GridClipboardDirective` settings.
|
|
65
|
+
*/
|
|
66
|
+
export interface GridClipboardSettings {
|
|
67
|
+
/**
|
|
68
|
+
* Determines whether the clipboard actions will affect the whole data row
|
|
69
|
+
* when it is either partially selected, or contains the active cell.
|
|
70
|
+
*
|
|
71
|
+
* Defaults to `false`.
|
|
72
|
+
*/
|
|
73
|
+
wholeRow?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Determines whether column titles or field names will be included in the generated data
|
|
76
|
+
* during the `copy` and `cut` actions.
|
|
77
|
+
*
|
|
78
|
+
* Defaults to `false`.
|
|
79
|
+
*/
|
|
80
|
+
copyHeaders?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Determines whether the `copy` operation will modify the Clipboard content
|
|
83
|
+
* and trigger the `clipboard` event.
|
|
84
|
+
*
|
|
85
|
+
* Defaults to `true`.
|
|
86
|
+
*/
|
|
87
|
+
copy?: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Determines whether the `cut` operation will modify the Clipboard content
|
|
90
|
+
* and trigger the `clipboard` event.
|
|
91
|
+
*
|
|
92
|
+
* Defaults to `true`.
|
|
93
|
+
*/
|
|
94
|
+
cut?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Determines whether the `paste` operation will modify the Clipboard content
|
|
97
|
+
* and trigger the `clipboard` event.
|
|
98
|
+
*
|
|
99
|
+
* Defaults to `true`.
|
|
100
|
+
*/
|
|
101
|
+
paste?: boolean;
|
|
102
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**-----------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright © 2024 Progress Software Corporation. All rights reserved.
|
|
3
|
+
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
+
*-------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { AfterViewInit, EventEmitter, NgZone, OnDestroy, Renderer2 } from '@angular/core';
|
|
6
|
+
import { ClipboardService } from './clipboard.service';
|
|
7
|
+
import { GridComponent } from '../grid.component';
|
|
8
|
+
import { GridClipboardTargetType, GridClipboardEvent, GridClipboardSettings } from './clipboard-types';
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
/**
|
|
11
|
+
* The directive that enables the Grid built-in clipboard support. Allows copy, cut, and paste interactions
|
|
12
|
+
* with the Grid.
|
|
13
|
+
*/
|
|
14
|
+
export declare class GridClipboardDirective implements AfterViewInit, OnDestroy {
|
|
15
|
+
private host;
|
|
16
|
+
private clipboardService;
|
|
17
|
+
private renderer;
|
|
18
|
+
private zone;
|
|
19
|
+
/**
|
|
20
|
+
* Determines the target of the clipboard operation ([see example]({% slug clipboard_grid %}#toc-clipboard-target)). The possible options are:
|
|
21
|
+
* - `activeCell`
|
|
22
|
+
* - `selection`
|
|
23
|
+
*
|
|
24
|
+
* @default 'selection'
|
|
25
|
+
*/
|
|
26
|
+
set clipboardTarget(value: GridClipboardTargetType);
|
|
27
|
+
get clipboardTarget(): GridClipboardTargetType;
|
|
28
|
+
/**
|
|
29
|
+
* The `GridClipboardDirective` settings.
|
|
30
|
+
*
|
|
31
|
+
* @default { wholeRow: false, copyHeaders: false copy: true, cut: true, paste: true }
|
|
32
|
+
*/
|
|
33
|
+
set clipboardSettings(value: GridClipboardSettings);
|
|
34
|
+
get clipboardSettings(): GridClipboardSettings;
|
|
35
|
+
/**
|
|
36
|
+
* Fires when the user performs `cut`, `copy` or `paste` action within the Grid content area.
|
|
37
|
+
*/
|
|
38
|
+
clipboard: EventEmitter<GridClipboardEvent>;
|
|
39
|
+
private _target;
|
|
40
|
+
private _clipboardSettings;
|
|
41
|
+
private subs;
|
|
42
|
+
constructor(host: GridComponent, clipboardService: ClipboardService, renderer: Renderer2, zone: NgZone);
|
|
43
|
+
ngAfterViewInit(): void;
|
|
44
|
+
ngOnDestroy(): void;
|
|
45
|
+
private onClipboard;
|
|
46
|
+
private inGrid;
|
|
47
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<GridClipboardDirective, never>;
|
|
48
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<GridClipboardDirective, "[kendoGridClipboard]", ["kendoGridClipboard"], { "clipboardTarget": "clipboardTarget"; "clipboardSettings": "clipboardSettings"; }, { "clipboard": "clipboard"; }, never>;
|
|
49
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**-----------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright © 2024 Progress Software Corporation. All rights reserved.
|
|
3
|
+
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
+
*-------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { ColumnBase } from '../columns/column-base';
|
|
6
|
+
import { ContextService } from './provider.service';
|
|
7
|
+
import { GridClipboardTargetType, GridClipboardItem } from './clipboard-types';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
/**
|
|
10
|
+
* @hidden
|
|
11
|
+
*/
|
|
12
|
+
export declare class ClipboardService {
|
|
13
|
+
private contextService;
|
|
14
|
+
targetColField: string;
|
|
15
|
+
targetRowIndex: number;
|
|
16
|
+
constructor(contextService: ContextService);
|
|
17
|
+
createClipboardData(data: any[], columns: ColumnBase[], options: any): {
|
|
18
|
+
dataString: string;
|
|
19
|
+
gridItems: GridClipboardItem[];
|
|
20
|
+
};
|
|
21
|
+
getGridData(data: string, columns: ColumnBase[], targetType: GridClipboardTargetType, targetRowIndex: number, options: any): GridClipboardItem[];
|
|
22
|
+
private itemToString;
|
|
23
|
+
private groupSelection;
|
|
24
|
+
private areEqual;
|
|
25
|
+
private addHeaders;
|
|
26
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ClipboardService, never>;
|
|
27
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ClipboardService>;
|
|
28
|
+
}
|
|
@@ -17,6 +17,7 @@ export declare class DomEventsService {
|
|
|
17
17
|
focusIn: EventEmitter<any>;
|
|
18
18
|
focusOut: EventEmitter<any>;
|
|
19
19
|
windowBlur: EventEmitter<any>;
|
|
20
|
+
paste: EventEmitter<any>;
|
|
20
21
|
static ɵfac: i0.ɵɵFactoryDeclaration<DomEventsService, never>;
|
|
21
22
|
static ɵprov: i0.ɵɵInjectableDeclaration<DomEventsService>;
|
|
22
23
|
}
|
|
@@ -6,3 +6,15 @@
|
|
|
6
6
|
* @hidden
|
|
7
7
|
*/
|
|
8
8
|
export declare const ColumnMenuErrorMessages: any;
|
|
9
|
+
/**
|
|
10
|
+
* @hidden
|
|
11
|
+
*/
|
|
12
|
+
export declare const ClipboardErrorMessages: any;
|
|
13
|
+
/**
|
|
14
|
+
* @hidden
|
|
15
|
+
*/
|
|
16
|
+
export declare const ColumnConfigurationErrorMessages: any;
|
|
17
|
+
/**
|
|
18
|
+
* @hidden
|
|
19
|
+
*/
|
|
20
|
+
export declare const GridConfigurationErrorMessages: any;
|
|
@@ -93,5 +93,5 @@ export declare class DataBindingDirective implements OnInit, OnDestroy, DoCheck,
|
|
|
93
93
|
protected applyState({ skip, take, sort, group, filter }: State): void;
|
|
94
94
|
protected updateGridData(): void;
|
|
95
95
|
static ɵfac: i0.ɵɵFactoryDeclaration<DataBindingDirective, never>;
|
|
96
|
-
static ɵdir: i0.ɵɵDirectiveDeclaration<DataBindingDirective, "[kendoGridBinding]",
|
|
96
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<DataBindingDirective, "[kendoGridBinding]", ["kendoGridBinding"], { "skip": "skip"; "sort": "sort"; "filter": "filter"; "pageSize": "pageSize"; "group": "group"; "data": "kendoGridBinding"; }, {}, never>;
|
|
97
97
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*-------------------------------------------------------------------------------------------*/
|
|
5
5
|
import { Input, isDevMode, HostBinding, Component } from '@angular/core';
|
|
6
6
|
import { ColumnMenuService } from './column-menu.service';
|
|
7
|
+
import { ColumnMenuErrorMessages } from '../common/error-messages';
|
|
7
8
|
import * as i0 from "@angular/core";
|
|
8
9
|
/**
|
|
9
10
|
* @hidden
|
|
@@ -14,7 +15,7 @@ export class ColumnMenuItemBase {
|
|
|
14
15
|
}
|
|
15
16
|
ngOnInit() {
|
|
16
17
|
if (isDevMode() && !this.service) {
|
|
17
|
-
throw new Error(
|
|
18
|
+
throw new Error(ColumnMenuErrorMessages.serviceInput);
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
21
|
/**
|
|
@@ -39,7 +39,7 @@ import * as i18 from "../filtering/menu/filter-menu-container.component";
|
|
|
39
39
|
import * as i19 from "./column-list.component";
|
|
40
40
|
import * as i20 from "@angular/common";
|
|
41
41
|
import * as i21 from "./column-menu-item.directive";
|
|
42
|
-
const
|
|
42
|
+
const POPUP_CLASSES = 'k-grid-columnmenu-popup k-column-menu';
|
|
43
43
|
let id = 0;
|
|
44
44
|
const getId = (gridId) => `${gridId}-column-menu-${id++}`;
|
|
45
45
|
/**
|
|
@@ -232,7 +232,7 @@ export class ColumnMenuComponent {
|
|
|
232
232
|
this.expandedFilter = this.getExpandedState(this.settings.filter);
|
|
233
233
|
this.expandedColumns = this.getExpandedState(this.settings.columnChooser);
|
|
234
234
|
this.expandedPosition = this.getExpandedState(this.settings.setColumnPosition);
|
|
235
|
-
this.popupRef = this.popupService.open(anchor, template, this.popupRef,
|
|
235
|
+
this.popupRef = this.popupService.open(anchor, template, this.popupRef, POPUP_CLASSES);
|
|
236
236
|
// Needed as changes to 'popupRef' and 'popupId' are not reflected
|
|
237
237
|
// automatically when the Popup is closed by clicking outside the anchor
|
|
238
238
|
const ariaRoot = this.isNavigable ? anchor.closest('.k-table-th') : anchor;
|
|
@@ -253,7 +253,8 @@ export class ColumnMenuComponent {
|
|
|
253
253
|
ariaRoot && this.renderer.setAttribute(ariaRoot, 'aria-expanded', 'true');
|
|
254
254
|
}
|
|
255
255
|
if (this.settings.view === 'tabbed') {
|
|
256
|
-
this.renderer.addClass(
|
|
256
|
+
this.renderer.addClass(popupAriaElement, 'k-column-menu-tabbed');
|
|
257
|
+
this.renderer.addClass(popupAriaElement, 'k-column-menu');
|
|
257
258
|
this.cdr.detectChanges();
|
|
258
259
|
this.tabStrip?.selectTab(0);
|
|
259
260
|
}
|
|
@@ -379,7 +380,8 @@ ColumnMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", ve
|
|
|
379
380
|
</kendo-grid-columnmenu-container>
|
|
380
381
|
</ng-template>
|
|
381
382
|
<ng-template #tabbedInterfaceTemplate>
|
|
382
|
-
<kendo-tabstrip #tabstrip
|
|
383
|
+
<kendo-tabstrip #tabstrip
|
|
384
|
+
(keydown.escape)="close(true)">
|
|
383
385
|
<kendo-tabstrip-tab *ngIf="hasFilter">
|
|
384
386
|
<ng-template kendoTabTitle>
|
|
385
387
|
<kendo-icon-wrapper
|
|
@@ -554,7 +556,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
|
|
|
554
556
|
</kendo-grid-columnmenu-container>
|
|
555
557
|
</ng-template>
|
|
556
558
|
<ng-template #tabbedInterfaceTemplate>
|
|
557
|
-
<kendo-tabstrip #tabstrip
|
|
559
|
+
<kendo-tabstrip #tabstrip
|
|
560
|
+
(keydown.escape)="close(true)">
|
|
558
561
|
<kendo-tabstrip-tab *ngIf="hasFilter">
|
|
559
562
|
<ng-template kendoTabTitle>
|
|
560
563
|
<kendo-icon-wrapper
|
|
@@ -7,6 +7,7 @@ import { HeaderTemplateDirective } from '../rendering/header/header-template.dir
|
|
|
7
7
|
import { FooterTemplateDirective } from '../rendering/footer/footer-template.directive';
|
|
8
8
|
import { ColumnMenuTemplateDirective } from '../column-menu/column-menu-template.directive';
|
|
9
9
|
import { IdService } from '../common/id.service';
|
|
10
|
+
import { ColumnConfigurationErrorMessages } from '../common/error-messages';
|
|
10
11
|
import * as i0 from "@angular/core";
|
|
11
12
|
import * as i1 from "../common/id.service";
|
|
12
13
|
/**
|
|
@@ -102,7 +103,7 @@ export class ColumnBase {
|
|
|
102
103
|
this.columnMenuTemplates = new QueryList();
|
|
103
104
|
this.idService = idService;
|
|
104
105
|
if (parent && idService && parent.idService.gridId() === idService.gridId() && !isColumnContainer(parent)) {
|
|
105
|
-
throw new Error(
|
|
106
|
+
throw new Error(ColumnConfigurationErrorMessages.columnNested);
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
/**
|
|
@@ -124,7 +125,7 @@ export class ColumnBase {
|
|
|
124
125
|
if (typeof value === 'string') {
|
|
125
126
|
const parsedValue = this._width = parseInt(value, 10);
|
|
126
127
|
if (isDevMode()) {
|
|
127
|
-
console.warn(
|
|
128
|
+
console.warn(ColumnConfigurationErrorMessages.width(value, parsedValue));
|
|
128
129
|
}
|
|
129
130
|
}
|
|
130
131
|
else {
|
|
@@ -6,6 +6,7 @@ import { Component, forwardRef, SkipSelf, Host, Optional, QueryList, ContentChil
|
|
|
6
6
|
import { IdService } from '../common/id.service';
|
|
7
7
|
import { ColumnBase } from './column-base';
|
|
8
8
|
import { columnsSpan } from './column-common';
|
|
9
|
+
import { ColumnConfigurationErrorMessages } from '../common/error-messages';
|
|
9
10
|
import * as i0 from "@angular/core";
|
|
10
11
|
import * as i1 from "./column-base";
|
|
11
12
|
import * as i2 from "../common/id.service";
|
|
@@ -47,7 +48,7 @@ export class ColumnGroupComponent extends ColumnBase {
|
|
|
47
48
|
*/
|
|
48
49
|
this.minResizableWidth = 10;
|
|
49
50
|
if (parent && parent.isSpanColumn) {
|
|
50
|
-
throw new Error('ColumnGroupComponent
|
|
51
|
+
throw new Error(ColumnConfigurationErrorMessages.nestedInside('ColumnGroupComponent', 'SpanColumnComponent'));
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
/**
|
|
@@ -9,6 +9,7 @@ import { ColumnBase } from './column-base';
|
|
|
9
9
|
import { ColumnComponent } from "./column.component";
|
|
10
10
|
import { isPresent } from "../utils";
|
|
11
11
|
import { IdService } from '../common/id.service';
|
|
12
|
+
import { ColumnConfigurationErrorMessages } from '../common/error-messages';
|
|
12
13
|
import * as i0 from "@angular/core";
|
|
13
14
|
import * as i1 from "./column-base";
|
|
14
15
|
import * as i2 from "../common/id.service";
|
|
@@ -56,7 +57,7 @@ export class SpanColumnComponent extends ColumnBase {
|
|
|
56
57
|
this.includeInChooser = false;
|
|
57
58
|
this._editable = true;
|
|
58
59
|
if (parent && parent.isSpanColumn) {
|
|
59
|
-
throw new Error('
|
|
60
|
+
throw new Error(ColumnConfigurationErrorMessages.nestedInside('SpanColumnComponent', 'SpanColumnComponent'));
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
63
|
/**
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**-----------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright © 2024 Progress Software Corporation. All rights reserved.
|
|
3
|
+
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
+
*-------------------------------------------------------------------------------------------*/
|
|
5
|
+
export {};
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**-----------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright © 2024 Progress Software Corporation. All rights reserved.
|
|
3
|
+
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
+
*-------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { Directive, EventEmitter, Input, NgZone, Output, Renderer2, isDevMode } from '@angular/core';
|
|
6
|
+
import { ClipboardService } from './clipboard.service';
|
|
7
|
+
import { GridComponent } from '../grid.component';
|
|
8
|
+
import { hasObservers, isDocumentAvailable } from '@progress/kendo-angular-common';
|
|
9
|
+
import { Subscription } from 'rxjs';
|
|
10
|
+
import { take } from 'rxjs/operators';
|
|
11
|
+
import { closest, contains } from '../rendering/common/dom-queries';
|
|
12
|
+
import { recursiveFlatMap } from '../utils';
|
|
13
|
+
import { ClipboardErrorMessages } from './error-messages';
|
|
14
|
+
import * as i0 from "@angular/core";
|
|
15
|
+
import * as i1 from "../grid.component";
|
|
16
|
+
import * as i2 from "./clipboard.service";
|
|
17
|
+
/**
|
|
18
|
+
* The directive that enables the Grid built-in clipboard support. Allows copy, cut, and paste interactions
|
|
19
|
+
* with the Grid.
|
|
20
|
+
*/
|
|
21
|
+
export class GridClipboardDirective {
|
|
22
|
+
constructor(host, clipboardService, renderer, zone) {
|
|
23
|
+
this.host = host;
|
|
24
|
+
this.clipboardService = clipboardService;
|
|
25
|
+
this.renderer = renderer;
|
|
26
|
+
this.zone = zone;
|
|
27
|
+
/**
|
|
28
|
+
* Fires when the user performs `cut`, `copy` or `paste` action within the Grid content area.
|
|
29
|
+
*/
|
|
30
|
+
this.clipboard = new EventEmitter();
|
|
31
|
+
this._target = 'selection';
|
|
32
|
+
this._clipboardSettings = {
|
|
33
|
+
wholeRow: false,
|
|
34
|
+
copyHeaders: false,
|
|
35
|
+
copy: true,
|
|
36
|
+
cut: true,
|
|
37
|
+
paste: true
|
|
38
|
+
};
|
|
39
|
+
this.subs = new Subscription();
|
|
40
|
+
this.onClipboard = (operationType, args) => {
|
|
41
|
+
if (!this.clipboardSettings[operationType] || !this.inGrid(args)) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const gridData = Array.isArray(this.host.data) ? this.host.data : this.host.data.data;
|
|
45
|
+
const gridDataItems = gridData.flatMap(recursiveFlatMap);
|
|
46
|
+
const selection = this.host.selection;
|
|
47
|
+
const selectionDirective = this.host.selectionDirective;
|
|
48
|
+
const targetType = this.clipboardTarget;
|
|
49
|
+
const isCellSelection = (this.host.selectable?.cell || selectionDirective.isCellSelectionMode);
|
|
50
|
+
let clipboardData = [];
|
|
51
|
+
switch (targetType) {
|
|
52
|
+
case 'activeCell':
|
|
53
|
+
{
|
|
54
|
+
const targetCell = { ...this.host.activeCell };
|
|
55
|
+
clipboardData = targetCell && [{ dataItem: targetCell.dataItem, dataRowIndex: targetCell.dataRowIndex, colIndex: targetCell.colIndex }];
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
case 'selection':
|
|
59
|
+
{
|
|
60
|
+
const identifier = selectionDirective.selectionKey;
|
|
61
|
+
clipboardData = gridDataItems.flatMap((item, index) => {
|
|
62
|
+
if (identifier) {
|
|
63
|
+
const key = typeof identifier === 'string' ? item[identifier] : identifier({ index: index + this.host.skip, dataItem: item });
|
|
64
|
+
return isCellSelection ?
|
|
65
|
+
selection.some(s => s.itemKey === key) ? [{ dataItem: item, dataRowIndex: index + this.host.skip }] : [] :
|
|
66
|
+
selection.indexOf(key) > -1 ? [{ dataItem: item, dataRowIndex: index + this.host.skip }] : [];
|
|
67
|
+
}
|
|
68
|
+
return isCellSelection ?
|
|
69
|
+
selection.some(s => s.itemKey === index + this.host.skip) ? [{ dataItem: item, dataRowIndex: index + this.host.skip }] : [] :
|
|
70
|
+
selection.indexOf(index + this.host.skip) > -1 ? [{ dataItem: item, dataRowIndex: index + this.host.skip }] : [];
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
const isPaste = operationType === 'paste';
|
|
76
|
+
const pastedData = args.clipboardData.getData('text').trim();
|
|
77
|
+
const visibleCols = this.host.columns.toArray().filter(c => c.isVisible);
|
|
78
|
+
const data = isPaste ?
|
|
79
|
+
{
|
|
80
|
+
dataString: pastedData,
|
|
81
|
+
gridItems: this.clipboardService.getGridData(pastedData, visibleCols, this.clipboardTarget, clipboardData[0]?.dataRowIndex, {
|
|
82
|
+
wholeRow: this.clipboardSettings.wholeRow,
|
|
83
|
+
isCellSelection
|
|
84
|
+
})
|
|
85
|
+
} :
|
|
86
|
+
this.clipboardService.createClipboardData(clipboardData || [], visibleCols, {
|
|
87
|
+
wholeRow: this.clipboardSettings.wholeRow || (this.clipboardTarget === 'selection' && !isCellSelection),
|
|
88
|
+
target: this.clipboardTarget,
|
|
89
|
+
copyHeaders: this.clipboardSettings.copyHeaders,
|
|
90
|
+
operationType
|
|
91
|
+
});
|
|
92
|
+
!isPaste && navigator.clipboard.writeText(data.dataString);
|
|
93
|
+
if (hasObservers(this.clipboard)) {
|
|
94
|
+
this.zone.run(() => {
|
|
95
|
+
this.clipboard.emit({
|
|
96
|
+
type: operationType,
|
|
97
|
+
originalEvent: args,
|
|
98
|
+
clipboardData: data.dataString,
|
|
99
|
+
gridData: data.gridItems,
|
|
100
|
+
target: {
|
|
101
|
+
dataRowIndex: this.clipboardService.targetRowIndex,
|
|
102
|
+
colField: this.clipboardService.targetColField,
|
|
103
|
+
dataItem: clipboardData.find(item => item.dataRowIndex === this.clipboardService.targetRowIndex)?.dataItem
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
this.clipboardService.targetColField = this.clipboardService.targetRowIndex = null;
|
|
109
|
+
};
|
|
110
|
+
this.inGrid = (args) => {
|
|
111
|
+
const target = document.activeElement.matches('.k-table-td') ? document.activeElement : args.target;
|
|
112
|
+
const inContentArea = closest(target, node => node.parentElement?.classList.contains('k-grid-container'));
|
|
113
|
+
const inHost = contains(this.host.wrapper.nativeElement, target);
|
|
114
|
+
return target && inHost && inContentArea;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Determines the target of the clipboard operation ([see example]({% slug clipboard_grid %}#toc-clipboard-target)). The possible options are:
|
|
119
|
+
* - `activeCell`
|
|
120
|
+
* - `selection`
|
|
121
|
+
*
|
|
122
|
+
* @default 'selection'
|
|
123
|
+
*/
|
|
124
|
+
set clipboardTarget(value) {
|
|
125
|
+
if (isDevMode()) {
|
|
126
|
+
this.zone.onStable.pipe(take(1)).subscribe(() => {
|
|
127
|
+
if (value === 'activeCell' && !(this.host.navigable.length)) {
|
|
128
|
+
console.warn(ClipboardErrorMessages.clipboardTarget.activeCellNavigable);
|
|
129
|
+
}
|
|
130
|
+
else if (value === 'selection' && !(this.host.selectable || this.host.selectionDirective)) {
|
|
131
|
+
console.warn(ClipboardErrorMessages.selectionSelectable);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
this._target = value;
|
|
136
|
+
}
|
|
137
|
+
get clipboardTarget() {
|
|
138
|
+
return this._target;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* The `GridClipboardDirective` settings.
|
|
142
|
+
*
|
|
143
|
+
* @default { wholeRow: false, copyHeaders: false copy: true, cut: true, paste: true }
|
|
144
|
+
*/
|
|
145
|
+
set clipboardSettings(value) {
|
|
146
|
+
this._clipboardSettings = Object.assign({}, this._clipboardSettings, value);
|
|
147
|
+
}
|
|
148
|
+
get clipboardSettings() {
|
|
149
|
+
return this._clipboardSettings;
|
|
150
|
+
}
|
|
151
|
+
ngAfterViewInit() {
|
|
152
|
+
if (!isDocumentAvailable()) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (this.clipboardTarget === 'selection' && !(this.host.selectable || this.host.selectionDirective)) {
|
|
156
|
+
console.warn(ClipboardErrorMessages.selectionSelectable);
|
|
157
|
+
}
|
|
158
|
+
// needed due to the following issue in Chrome
|
|
159
|
+
// https://bugs.chromium.org/p/chromium/issues/detail?id=1156117&q=focus%20programmatically%20paste&can=2
|
|
160
|
+
this.zone.runOutsideAngular(() => {
|
|
161
|
+
this.subs.add(this.renderer.listen(document, 'copy', (args) => this.onClipboard('copy', args)));
|
|
162
|
+
this.subs.add(this.renderer.listen(document, 'cut', (args) => this.onClipboard('cut', args)));
|
|
163
|
+
this.subs.add(this.renderer.listen(document, 'paste', (args) => this.onClipboard('paste', args)));
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
ngOnDestroy() {
|
|
167
|
+
this.subs.unsubscribe();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
GridClipboardDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: GridClipboardDirective, deps: [{ token: i1.GridComponent }, { token: i2.ClipboardService }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
|
|
171
|
+
GridClipboardDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: GridClipboardDirective, selector: "[kendoGridClipboard]", inputs: { clipboardTarget: "clipboardTarget", clipboardSettings: "clipboardSettings" }, outputs: { clipboard: "clipboard" }, providers: [ClipboardService], exportAs: ["kendoGridClipboard"], ngImport: i0 });
|
|
172
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: GridClipboardDirective, decorators: [{
|
|
173
|
+
type: Directive,
|
|
174
|
+
args: [{
|
|
175
|
+
selector: '[kendoGridClipboard]',
|
|
176
|
+
exportAs: 'kendoGridClipboard',
|
|
177
|
+
providers: [ClipboardService]
|
|
178
|
+
}]
|
|
179
|
+
}], ctorParameters: function () { return [{ type: i1.GridComponent }, { type: i2.ClipboardService }, { type: i0.Renderer2 }, { type: i0.NgZone }]; }, propDecorators: { clipboardTarget: [{
|
|
180
|
+
type: Input
|
|
181
|
+
}], clipboardSettings: [{
|
|
182
|
+
type: Input
|
|
183
|
+
}], clipboard: [{
|
|
184
|
+
type: Output
|
|
185
|
+
}] } });
|