@one-grid-core/angular 0.1.0-beta.5 → 0.2.0
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/README.md +49 -4
- package/esm2022/lib/components/one-grid/one-grid.component.mjs +67 -16
- package/esm2022/lib/components/one-grid-body/one-grid-body.component.mjs +282 -30
- package/esm2022/lib/components/one-grid-cell-group-renderer/one-grid-cell-group-renderer.component.mjs +10 -7
- package/esm2022/lib/components/one-grid-cell-option-menu/one-grid-cell-option-menu.component.mjs +60 -4
- package/esm2022/lib/components/one-grid-checkbox-header/one-grid-checkbox-header.component.mjs +14 -5
- package/esm2022/lib/components/one-grid-header/one-grid-header.component.mjs +50 -13
- package/esm2022/lib/components/one-grid-pagination/one-grid-pagination.component.mjs +39 -15
- package/esm2022/lib/components/one-grid-row-action/one-grid-row-action.component.mjs +54 -8
- package/esm2022/lib/components/one-grid-row-drag-handle/one-grid-row-drag-handle.component.mjs +110 -0
- package/esm2022/lib/core/directives/one-cell-renderer-component.directive.mjs +9 -2
- package/esm2022/lib/core/directives/one-cell-text-expand.directive.mjs +33 -51
- package/esm2022/lib/core/instants/one-grid-api.class.mjs +429 -166
- package/esm2022/lib/core/instants/one-row-node.class.mjs +103 -37
- package/esm2022/lib/core/models/one-column-def-types.model.mjs +1 -1
- package/esm2022/lib/core/models/one-event-types.model.mjs +1 -1
- package/esm2022/lib/core/models/one-grid-types.model.mjs +1 -1
- package/esm2022/lib/core/models/one-row-drag.model.mjs +2 -0
- package/esm2022/lib/core/models/one-row.model.mjs +1 -1
- package/esm2022/lib/core/models/one-tree-data.model.mjs +1 -1
- package/esm2022/lib/core/models/one-validation.model.mjs +1 -1
- package/esm2022/lib/core/pipes/cell-field-value-empty.pipe.mjs +8 -3
- package/esm2022/lib/core/pipes/column-sort-state.pipe.mjs +3 -1
- package/esm2022/lib/core/services/og-column.service.mjs +120 -13
- package/esm2022/lib/core/services/one-grid-cell.service.mjs +123 -20
- package/esm2022/lib/core/services/one-grid-row-drag.service.mjs +351 -0
- package/esm2022/lib/core/services/one-grid-selection.service.mjs +19 -6
- package/esm2022/lib/helpers/one-column-def.helper.mjs +27 -2
- package/esm2022/lib/helpers/one-filter.helper.mjs +71 -12
- package/esm2022/lib/helpers/one-validation.helper.mjs +7 -2
- package/esm2022/lib/index.mjs +8 -1
- package/esm2022/lib/one-grid.module.mjs +7 -16
- package/fesm2022/one-grid-core-angular.mjs +2046 -503
- package/fesm2022/one-grid-core-angular.mjs.map +1 -1
- package/lib/components/one-grid/one-grid.component.d.ts +16 -1
- package/lib/components/one-grid-body/one-grid-body.component.d.ts +132 -5
- package/lib/components/one-grid-cell-group-renderer/one-grid-cell-group-renderer.component.d.ts +6 -1
- package/lib/components/one-grid-cell-option-menu/one-grid-cell-option-menu.component.d.ts +19 -2
- package/lib/components/one-grid-checkbox-header/one-grid-checkbox-header.component.d.ts +5 -2
- package/lib/components/one-grid-header/one-grid-header.component.d.ts +15 -7
- package/lib/components/one-grid-pagination/one-grid-pagination.component.d.ts +24 -5
- package/lib/components/one-grid-row-action/one-grid-row-action.component.d.ts +44 -0
- package/lib/components/one-grid-row-drag-handle/one-grid-row-drag-handle.component.d.ts +39 -0
- package/lib/core/directives/one-cell-text-expand.directive.d.ts +21 -9
- package/lib/core/instants/one-grid-api.class.d.ts +212 -26
- package/lib/core/instants/one-row-node.class.d.ts +67 -14
- package/lib/core/models/one-column-def-types.model.d.ts +89 -15
- package/lib/core/models/one-event-types.model.d.ts +24 -1
- package/lib/core/models/one-grid-types.model.d.ts +36 -1
- package/lib/core/models/one-row-drag.model.d.ts +44 -0
- package/lib/core/models/one-row.model.d.ts +0 -5
- package/lib/core/models/one-tree-data.model.d.ts +13 -0
- package/lib/core/models/one-validation.model.d.ts +12 -2
- package/lib/core/pipes/column-sort-state.pipe.d.ts +1 -1
- package/lib/core/services/og-column.service.d.ts +44 -3
- package/lib/core/services/one-grid-cell.service.d.ts +52 -4
- package/lib/core/services/one-grid-row-drag.service.d.ts +113 -0
- package/lib/core/services/one-grid-selection.service.d.ts +9 -0
- package/lib/helpers/one-column-def.helper.d.ts +19 -1
- package/lib/helpers/one-filter.helper.d.ts +29 -4
- package/lib/index.d.ts +7 -0
- package/lib/one-grid.module.d.ts +17 -19
- package/package.json +1 -2
- package/scss/_one-grid.scss +389 -17
- package/esm2022/lib/core/pipes/cell-disable-resolver.pipe.mjs +0 -26
- package/lib/core/pipes/cell-disable-resolver.pipe.d.ts +0 -9
|
@@ -1,7 +1,42 @@
|
|
|
1
|
+
import type { Type } from "@angular/core";
|
|
1
2
|
import type { OneGridApi } from "../instants/one-grid-api.class";
|
|
2
3
|
import type { OneRowNode } from "../instants/one-row-node.class";
|
|
3
|
-
import type { OneColumnDef } from "./one-column-def-types.model";
|
|
4
|
+
import type { OneColumnDef, OneGroupColumnDef } from "./one-column-def-types.model";
|
|
5
|
+
import type { RowSelectionMode } from "./one-event-types.model";
|
|
6
|
+
import type { OneDetailCellRendererParams } from "./one-master-detail.model";
|
|
7
|
+
import type { OneCellRendererComponent } from "./one-tree-data.model";
|
|
4
8
|
export type OneGridType = 'simple' | 'master' | 'detail' | 'tree' | null;
|
|
9
|
+
/**
|
|
10
|
+
* Everything `OneGridApi.init` needs to stand a grid up.
|
|
11
|
+
*
|
|
12
|
+
* An options object rather than a positional list: the previous signature took
|
|
13
|
+
* ten positional arguments, four of them optional and two of them booleans, so
|
|
14
|
+
* a call site was unreadable and adding an option meant touching every caller.
|
|
15
|
+
*
|
|
16
|
+
* `OneGridComponent` calls this from `ngOnInit`. Applications should not.
|
|
17
|
+
*/
|
|
18
|
+
export interface OneGridInitOptions<T = any> {
|
|
19
|
+
/** Which role this instance plays. `OneGridComponent` derives it from its inputs. */
|
|
20
|
+
gridType: OneGridType;
|
|
21
|
+
/** Column definitions, before `defaultColumnDef` is merged in. */
|
|
22
|
+
columnDefs: OneColumnDef<T>[];
|
|
23
|
+
/** Merged into every column definition. */
|
|
24
|
+
defaultColumnDef?: OneColumnDef<T>;
|
|
25
|
+
/** Header groups. Columns join one by `groupId`. */
|
|
26
|
+
groupColumnDefs?: OneGroupColumnDef[];
|
|
27
|
+
/** Passed to renderers, getters and predicates; `componentParent.getRowId` is read from it. */
|
|
28
|
+
context?: any;
|
|
29
|
+
/** `null` disables row selection entirely. Read once, here. */
|
|
30
|
+
rowSelection?: RowSelectionMode;
|
|
31
|
+
/** Turns on the nested detail grid. Mutually exclusive with `treeData`. */
|
|
32
|
+
masterDetail?: boolean;
|
|
33
|
+
/** Detail grid options plus `getDetailRowData`. Required when `masterDetail` is on. */
|
|
34
|
+
detailCellRendererParams?: OneDetailCellRendererParams;
|
|
35
|
+
/** Render a component in the detail area instead of a nested grid. */
|
|
36
|
+
detailRendererComponent?: Type<OneCellRendererComponent>;
|
|
37
|
+
/** Turns on hierarchical row building. Mutually exclusive with `masterDetail`. */
|
|
38
|
+
treeData?: boolean;
|
|
39
|
+
}
|
|
5
40
|
export interface OneGridReadyEvent<T = any> {
|
|
6
41
|
api: OneGridApi<T>;
|
|
7
42
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { OneRowNode } from '../instants/one-row-node.class';
|
|
2
|
+
/**
|
|
3
|
+
* Why row reordering is unavailable right now.
|
|
4
|
+
*
|
|
5
|
+
* Reordering only means something when the order you see is the order the data
|
|
6
|
+
* is in. Each of these breaks that, so the handle is disabled rather than
|
|
7
|
+
* silently dropping the move:
|
|
8
|
+
*
|
|
9
|
+
* - `sorted` — the displayed order is derived from the sort model, and the
|
|
10
|
+
* next sort pass rebuilds it from scratch. A manual move would
|
|
11
|
+
* be discarded the moment anything re-sorted.
|
|
12
|
+
* - `filtered` — rows are hidden between the ones you can see, so "drop below
|
|
13
|
+
* this row" has no single answer.
|
|
14
|
+
* - `treeData` — moving a node between parents is a reparent, not a reorder.
|
|
15
|
+
* Not supported yet; see the docs.
|
|
16
|
+
*/
|
|
17
|
+
export type OneRowDragSuppressedReason = 'sorted' | 'filtered' | 'treeData';
|
|
18
|
+
/** Where a drag would land, and where it started. */
|
|
19
|
+
export interface OneRowDragEvent<T = any> {
|
|
20
|
+
/** The row being moved. */
|
|
21
|
+
node: OneRowNode<T>;
|
|
22
|
+
/** Index it started at, in the grid's row order. */
|
|
23
|
+
fromIndex: number;
|
|
24
|
+
/** Index it would land at once removed from `fromIndex` and reinserted. */
|
|
25
|
+
toIndex: number;
|
|
26
|
+
/** How the move was driven. Keyboard moves are one step at a time. */
|
|
27
|
+
source: 'pointer' | 'keyboard';
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The live state of a drag, published by the row-drag service so the body can
|
|
31
|
+
* render the handle and the drop indicator. `null` when no drag is in flight.
|
|
32
|
+
*/
|
|
33
|
+
export interface OneRowDragState {
|
|
34
|
+
rowId: string;
|
|
35
|
+
fromIndex: number;
|
|
36
|
+
/**
|
|
37
|
+
* Insertion boundary, in row units: 0 is above the first row, `n` is below
|
|
38
|
+
* the last. This is a gap index, not a row index — the drop indicator is
|
|
39
|
+
* drawn at `insertAt * itemSize`, and the resulting row index differs by
|
|
40
|
+
* one depending on the direction of travel.
|
|
41
|
+
*/
|
|
42
|
+
insertAt: number;
|
|
43
|
+
source: 'pointer' | 'keyboard';
|
|
44
|
+
}
|
|
@@ -29,10 +29,5 @@ export interface OneRowNodeEventMap<T> {
|
|
|
29
29
|
node: OneRowNode<T>;
|
|
30
30
|
expanded: boolean;
|
|
31
31
|
};
|
|
32
|
-
childrenChanged: {
|
|
33
|
-
node: OneRowNode<T>;
|
|
34
|
-
children: OneRowNode<T>[];
|
|
35
|
-
source: 'masterDetail' | 'treeData';
|
|
36
|
-
};
|
|
37
32
|
}
|
|
38
33
|
export type OneRowNodeListener<T, K extends keyof OneRowNodeEventMap<T>> = (event: OneRowNodeEventMap<T>[K]) => void;
|
|
@@ -4,6 +4,19 @@ export type TreeNode<T> = {
|
|
|
4
4
|
children?: TreeNode<T>[];
|
|
5
5
|
} & T;
|
|
6
6
|
export interface OneCellRendererComponent {
|
|
7
|
+
/**
|
|
8
|
+
* Called when the cell is created and again whenever its params change.
|
|
9
|
+
*
|
|
10
|
+
* The params stay loosely typed here, unlike `cellRenderer`'s: the same
|
|
11
|
+
* directive also mounts a master/detail row's custom detail renderer, and a
|
|
12
|
+
* detail row has no column — so `field` and `columnDef` genuinely cannot be
|
|
13
|
+
* promised. For a cell renderer they are always supplied.
|
|
14
|
+
*
|
|
15
|
+
* A component that does not implement this gets the params assigned onto its
|
|
16
|
+
* own fields instead, so a renderer with plain public properties works too —
|
|
17
|
+
* but not both: the fallback only applies when `oneInit` is absent.
|
|
18
|
+
*/
|
|
7
19
|
oneInit(params: OneCellRendererParams): void;
|
|
20
|
+
/** Part of the interface, but the renderer directive never calls it. */
|
|
8
21
|
refresh(params: OneCellRendererParams): boolean;
|
|
9
22
|
}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Validation errors for a single row, keyed by column field.
|
|
3
|
+
*
|
|
4
|
+
* A field is absent when it passed, which is why the values are optional —
|
|
5
|
+
* `errors[field]` is `string | undefined`, not `string`. Keying on
|
|
6
|
+
* `keyof T & string` matches `OneColumnDef<T>.field`, so a typo in a field name
|
|
7
|
+
* is a compile error rather than a lookup that silently returns undefined.
|
|
8
|
+
*/
|
|
9
|
+
export type OneRowValidationErrors<T = any> = Partial<Record<keyof T & string, string>>;
|
|
10
|
+
export interface OneValidationResult<T = any> {
|
|
2
11
|
valid: boolean;
|
|
3
12
|
invalid: boolean;
|
|
4
|
-
|
|
13
|
+
/** One entry per row, in the order the rows were given. */
|
|
14
|
+
errors: OneRowValidationErrors<T>[];
|
|
5
15
|
}
|
|
6
16
|
export type OneValidatorFn<T = any> = (value: any, row?: T) => string | null;
|
|
7
17
|
export type OneValidationRules<T = any> = {
|
|
@@ -2,7 +2,7 @@ import { PipeTransform } from '@angular/core';
|
|
|
2
2
|
import { OneSortModel } from '../models/one-grid-types.model';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
export declare class ColumnSortStatePipe implements PipeTransform {
|
|
5
|
-
transform(field: string, sortModel: OneSortModel[]): 'asc' | 'desc' | null;
|
|
5
|
+
transform(field: string, sortModel: readonly OneSortModel[]): 'asc' | 'desc' | null;
|
|
6
6
|
static ɵfac: i0.ɵɵFactoryDeclaration<ColumnSortStatePipe, never>;
|
|
7
7
|
static ɵpipe: i0.ɵɵPipeDeclaration<ColumnSortStatePipe, "columnSortState", false>;
|
|
8
8
|
}
|
|
@@ -1,14 +1,33 @@
|
|
|
1
|
-
import { OneCellRendererParams, OneColumnDef, OneGroupColumnDef } from '../models/one-column-def-types.model';
|
|
1
|
+
import { OneCellPresentationParams, OneCellRendererParams, OneColumnDef, OneGroupColumnDef } from '../models/one-column-def-types.model';
|
|
2
2
|
import { ColumnChangedEvent } from '../models/one-event-types.model';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
export declare class OgColumnService {
|
|
5
5
|
private defaultColumnDef;
|
|
6
|
+
/**
|
|
7
|
+
* The grid's `context`, so header callbacks receive the same one cell
|
|
8
|
+
* callbacks do. Set during init; null in a bare service.
|
|
9
|
+
*/
|
|
10
|
+
private context;
|
|
6
11
|
private columnDefs$;
|
|
7
12
|
private groupColumnDefs$;
|
|
8
|
-
initColumnDefs(defaultColumnDef: OneColumnDef, columnDefs: OneColumnDef[], groupColumnDefs: OneGroupColumnDef[]): void;
|
|
13
|
+
initColumnDefs(defaultColumnDef: OneColumnDef, columnDefs: OneColumnDef[], groupColumnDefs: OneGroupColumnDef[], context?: unknown): void;
|
|
9
14
|
getColumnState(): ColumnChangedEvent;
|
|
10
15
|
setGroupColumnDefs(groupColumnDefs: OneGroupColumnDef[]): void;
|
|
11
16
|
setColumnDefs(columnDefs: OneColumnDef[]): void;
|
|
17
|
+
/**
|
|
18
|
+
* Move pinned columns to their edge and measure how far in each one sits.
|
|
19
|
+
*
|
|
20
|
+
* Display order becomes left-pinned, unpinned, right-pinned, with declared
|
|
21
|
+
* order preserved inside each band. `_pinnedOffset` is the distance from that
|
|
22
|
+
* column's own edge — the sum of the widths of the pinned columns outside it
|
|
23
|
+
* — which is what the sticky `left` / `right` binding needs.
|
|
24
|
+
*
|
|
25
|
+
* With nothing pinned this returns the same array, in the same order, so a
|
|
26
|
+
* grid that does not use the feature is unaffected.
|
|
27
|
+
*/
|
|
28
|
+
private applyPinning;
|
|
29
|
+
/** Total width of the columns frozen against the given edge. */
|
|
30
|
+
getPinnedWidth(side: 'left' | 'right'): number;
|
|
12
31
|
updateColumnDef(id: string, changes: Partial<OneColumnDef>): void;
|
|
13
32
|
reorderColumnDefs(fromIndex: number, toIndex: number): void;
|
|
14
33
|
/**
|
|
@@ -16,7 +35,29 @@ export declare class OgColumnService {
|
|
|
16
35
|
*/
|
|
17
36
|
private recalculateGroups;
|
|
18
37
|
resolveGroupPresentation(col: OneGroupColumnDef, params?: OneCellRendererParams): OneGroupColumnDef;
|
|
19
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Resolve a column's header presentation. Once per column, when the columns
|
|
40
|
+
* are set — a header is one cell for the whole column, so there is no row to
|
|
41
|
+
* resolve it against and nothing to redo per render.
|
|
42
|
+
*
|
|
43
|
+
* This used to resolve the cell hooks too, from the same call, with no params
|
|
44
|
+
* at all. Two bugs came out of that: any callback touching `params` threw a
|
|
45
|
+
* TypeError at init, and the header's resolved value was then overwritten by
|
|
46
|
+
* every cell that rendered, since the body re-ran the same method per cell
|
|
47
|
+
* with row params. In dev mode the disagreement surfaced as NG0100.
|
|
48
|
+
*/
|
|
49
|
+
resolveHeaderPresentation(col: OneColumnDef): OneColumnDef;
|
|
50
|
+
/**
|
|
51
|
+
* Resolve one cell's class, for one row.
|
|
52
|
+
*
|
|
53
|
+
* Pure: the result is returned rather than written back onto the column def,
|
|
54
|
+
* which every row of that column shares. Writing to it worked only because
|
|
55
|
+
* the template resolved and read in the same expression — one render order
|
|
56
|
+
* away from every row showing the last row's class.
|
|
57
|
+
*/
|
|
58
|
+
resolveCellClass(col: OneColumnDef, params: OneCellPresentationParams): string | string[] | undefined;
|
|
59
|
+
/** Resolve one cell's inline style, for one row. Pure, as above. */
|
|
60
|
+
resolveCellStyle(col: OneColumnDef, params: OneCellPresentationParams): Record<string, string> | undefined;
|
|
20
61
|
static ɵfac: i0.ɵɵFactoryDeclaration<OgColumnService, never>;
|
|
21
62
|
static ɵprov: i0.ɵɵInjectableDeclaration<OgColumnService>;
|
|
22
63
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { OneCellState, OneCellStates, OneColumnDef } from '../models/one-column-def-types.model';
|
|
1
|
+
import { OneCellPresentationParams, OneCellState, OneCellStates, OneColumnDef } from '../models/one-column-def-types.model';
|
|
2
2
|
import { OneRowNode } from '../instants/one-row-node.class';
|
|
3
|
+
import type { OneGridApi } from '../instants/one-grid-api.class';
|
|
3
4
|
import * as i0 from "@angular/core";
|
|
4
5
|
export declare class OneGridCellService {
|
|
5
6
|
private _cellFieldValueEmpty;
|
|
@@ -7,22 +8,69 @@ export declare class OneGridCellService {
|
|
|
7
8
|
private _cellFieldValue;
|
|
8
9
|
private _columnDefs;
|
|
9
10
|
private _context;
|
|
11
|
+
private _api;
|
|
10
12
|
applyColumnDefs(columnDefs: OneColumnDef[], context: any): void;
|
|
13
|
+
/**
|
|
14
|
+
* Back-reference to the grid api, so predicate params can carry it.
|
|
15
|
+
*
|
|
16
|
+
* Pushed in rather than injected: `OneGridApi` already depends on this
|
|
17
|
+
* service, and injecting it back would close a DI cycle.
|
|
18
|
+
*/
|
|
19
|
+
setGridApi(api: OneGridApi | null): void;
|
|
20
|
+
/**
|
|
21
|
+
* The params every row-scoped column callback receives.
|
|
22
|
+
*
|
|
23
|
+
* One builder, deliberately: `editable`, `updatable`, `disable`, `rowDrag`,
|
|
24
|
+
* `hideActionButton`, `cellClass`, `cellStyle`, `cellRenderer` and
|
|
25
|
+
* `valueFormatter` are all "decide something about this cell", and a consumer
|
|
26
|
+
* should not have to remember which of them happens to be handed `value` or
|
|
27
|
+
* `field`. Each used to be called with a slightly different subset.
|
|
28
|
+
*/
|
|
29
|
+
cellParams(column: OneColumnDef, node: OneRowNode): OneCellPresentationParams;
|
|
11
30
|
/**
|
|
12
31
|
* Generate New Node States
|
|
13
32
|
*/
|
|
14
33
|
generateCellStates(node: OneRowNode): OneCellStates | null;
|
|
34
|
+
/**
|
|
35
|
+
* The cell's value: the `valueGetter`'s output where the column declares one,
|
|
36
|
+
* the raw field otherwise. This is the value, not the display text — see
|
|
37
|
+
* {@link formatValue}.
|
|
38
|
+
*/
|
|
39
|
+
private resolveValue;
|
|
40
|
+
/**
|
|
41
|
+
* Apply the column's `valueFormatter`.
|
|
42
|
+
*
|
|
43
|
+
* `valueFormatter` was declared on the column definition and called from
|
|
44
|
+
* nowhere — a consumer could write one, get no error, and see nothing happen.
|
|
45
|
+
* It runs on displayed text only, after the `valueGetter`, and is deliberately
|
|
46
|
+
* skipped for placeholders: an empty cell already has its own mechanism in
|
|
47
|
+
* `cellRendererParams.placeholder`, and two features competing to fill the
|
|
48
|
+
* same gap is worse than one.
|
|
49
|
+
*
|
|
50
|
+
* Note that sorting and filtering read the underlying row data, not this —
|
|
51
|
+
* which is exactly why formatting belongs here rather than in the getter.
|
|
52
|
+
*/
|
|
53
|
+
private formatValue;
|
|
15
54
|
/**
|
|
16
55
|
* Generate New Node State Based on Column Field
|
|
17
56
|
*/
|
|
18
57
|
generateCellState(node: OneRowNode, column: OneColumnDef): OneCellState;
|
|
58
|
+
/** Whether this cell may be edited at all. A capability: unset means no. */
|
|
59
|
+
editableFn: (column: OneColumnDef, node: OneRowNode) => boolean;
|
|
19
60
|
/**
|
|
20
|
-
*
|
|
61
|
+
* The second edit gate, ANDed with `editable`.
|
|
62
|
+
*
|
|
63
|
+
* A restriction, so unset means "no restriction". It used to resolve through
|
|
64
|
+
* `!!undefined` to `false`, closing the gate on every column that did not name
|
|
65
|
+
* it — so `editable: true` on its own made nothing editable.
|
|
21
66
|
*/
|
|
22
|
-
editableFn: (column: OneColumnDef, node: OneRowNode) => boolean;
|
|
23
67
|
updatableFn: (column: OneColumnDef, node: OneRowNode) => boolean;
|
|
68
|
+
/** Disables this column's row action buttons. Not an edit gate. */
|
|
24
69
|
disableFn: (column: OneColumnDef, node: OneRowNode) => boolean;
|
|
25
|
-
|
|
70
|
+
/** Hides this column's row action buttons entirely. */
|
|
71
|
+
hideActionButtonFn: (column: OneColumnDef, node: OneRowNode) => boolean;
|
|
72
|
+
/** Whether this cell carries a row drag handle. */
|
|
73
|
+
rowDragFn: (column: OneColumnDef, node: OneRowNode) => boolean;
|
|
26
74
|
valueGetterFn: (column: OneColumnDef, node: OneRowNode) => any;
|
|
27
75
|
static ɵfac: i0.ɵɵFactoryDeclaration<OneGridCellService, never>;
|
|
28
76
|
static ɵprov: i0.ɵɵInjectableDeclaration<OneGridCellService>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { OnDestroy } from '@angular/core';
|
|
2
|
+
import { BehaviorSubject } from 'rxjs';
|
|
3
|
+
import { OneRowDragEvent, OneRowDragState } from '../models/one-row-drag.model';
|
|
4
|
+
import { OneRowNode } from '../instants/one-row-node.class';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
/** What the body has to lend the service to run a drag. */
|
|
7
|
+
export interface OneRowDragContext<T = any> {
|
|
8
|
+
/** The scrolling element the rows live in. */
|
|
9
|
+
viewport: HTMLElement;
|
|
10
|
+
/** Fixed row height. The whole index calculation rests on rows being uniform. */
|
|
11
|
+
itemSize: number;
|
|
12
|
+
/** Current display order. Read fresh on every move — a drag mutates it. */
|
|
13
|
+
nodes: () => OneRowNode<T>[];
|
|
14
|
+
/** Apply the move. Returns false if the grid refused it. */
|
|
15
|
+
move: (fromIndex: number, toIndex: number) => boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Owns one row-drag gesture at a time.
|
|
19
|
+
*
|
|
20
|
+
* Built on pointer events rather than HTML5 drag-and-drop or the CDK's
|
|
21
|
+
* drag-drop:
|
|
22
|
+
*
|
|
23
|
+
* - HTML5 DnD does not fire for touch at all, and its drag image cannot be
|
|
24
|
+
* styled to match the grid.
|
|
25
|
+
* - `cdkDropList` assumes every item it manages is in the DOM. Inside a virtual
|
|
26
|
+
* scroll viewport rows unmount as they leave the buffer, so the list it
|
|
27
|
+
* thinks it is sorting is only ever the visible window.
|
|
28
|
+
* - Pointer events cover mouse, touch and pen in one path, and pointer capture
|
|
29
|
+
* keeps the gesture alive when the finger leaves the row it started on.
|
|
30
|
+
*
|
|
31
|
+
* Because rows are a fixed `itemSize`, the drop target is arithmetic on the
|
|
32
|
+
* pointer's Y rather than a hit test against row elements — which is also why
|
|
33
|
+
* it stays correct for rows that are scrolled out and not rendered.
|
|
34
|
+
*/
|
|
35
|
+
export declare class OneGridRowDragService<T = any> implements OnDestroy {
|
|
36
|
+
private readonly zone;
|
|
37
|
+
/** Live drag, for the body to render the handle state and the indicator. */
|
|
38
|
+
readonly state$: BehaviorSubject<OneRowDragState>;
|
|
39
|
+
/** Screen-reader narration for the keyboard path. */
|
|
40
|
+
readonly announcement$: BehaviorSubject<string>;
|
|
41
|
+
private context;
|
|
42
|
+
private pointerId;
|
|
43
|
+
private handle;
|
|
44
|
+
private startY;
|
|
45
|
+
private armed;
|
|
46
|
+
private lastClientY;
|
|
47
|
+
private scrollFrame;
|
|
48
|
+
/** A move already applied during this drag, so a cancel can undo it. */
|
|
49
|
+
private appliedFrom;
|
|
50
|
+
private onMove?;
|
|
51
|
+
private onEnd?;
|
|
52
|
+
attach(context: OneRowDragContext<T>): void;
|
|
53
|
+
get state(): OneRowDragState | null;
|
|
54
|
+
get dragging(): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Begin a pointer drag. Nothing visible happens until the pointer has moved
|
|
57
|
+
* {@link DRAG_THRESHOLD_PX}, so a click on the handle — which is also the
|
|
58
|
+
* keyboard affordance — is not swallowed by a zero-distance drag.
|
|
59
|
+
*/
|
|
60
|
+
startPointerDrag(event: PointerEvent, node: OneRowNode<T>, handlers?: {
|
|
61
|
+
onEnd?: (event: OneRowDragEvent<T> | null) => void;
|
|
62
|
+
}): void;
|
|
63
|
+
private handlePointerMove;
|
|
64
|
+
private handlePointerUp;
|
|
65
|
+
private handlePointerCancel;
|
|
66
|
+
/** Escape aborts a pointer drag, the same as it does a keyboard one. */
|
|
67
|
+
private handlePointerKeydown;
|
|
68
|
+
/**
|
|
69
|
+
* Turn the pointer's Y into an insertion boundary.
|
|
70
|
+
*
|
|
71
|
+
* Boundaries, not rows: the value is where the row would be *inserted*, so
|
|
72
|
+
* 0 is above the first row and `length` is below the last. Rounding rather
|
|
73
|
+
* than flooring puts the split at the middle of each row, which is what
|
|
74
|
+
* makes the indicator flip when you cross the halfway point.
|
|
75
|
+
*/
|
|
76
|
+
private updateFromPointer;
|
|
77
|
+
/**
|
|
78
|
+
* Scroll when the pointer sits near an edge, so rows outside the viewport
|
|
79
|
+
* are reachable without letting go. Runs on rAF while the pointer is parked
|
|
80
|
+
* in the zone, and re-derives the target each frame because the content
|
|
81
|
+
* moves while the pointer does not.
|
|
82
|
+
*/
|
|
83
|
+
private updateAutoScroll;
|
|
84
|
+
private stopAutoScroll;
|
|
85
|
+
private teardownPointer;
|
|
86
|
+
/** Space/Enter on the handle: pick the row up, or put it down. */
|
|
87
|
+
toggleKeyboardDrag(node: OneRowNode<T>, handlers?: {
|
|
88
|
+
onEnd?: (event: OneRowDragEvent<T> | null) => void;
|
|
89
|
+
}): void;
|
|
90
|
+
/**
|
|
91
|
+
* Arrow keys move the row a position at a time, applying as they go.
|
|
92
|
+
*
|
|
93
|
+
* Applied rather than previewed because the row has to be seen to move: a
|
|
94
|
+
* keyboard user gets no drag image, and a preview line alone tells someone
|
|
95
|
+
* relying on a screen reader nothing about where the row now sits. Escape
|
|
96
|
+
* still restores the original position.
|
|
97
|
+
*/
|
|
98
|
+
moveKeyboard(delta: number): boolean;
|
|
99
|
+
private commit;
|
|
100
|
+
/** Abort, restoring anything a keyboard drag already applied. */
|
|
101
|
+
cancel(): void;
|
|
102
|
+
private finish;
|
|
103
|
+
private reset;
|
|
104
|
+
private publish;
|
|
105
|
+
private announce;
|
|
106
|
+
private describe;
|
|
107
|
+
private indexOf;
|
|
108
|
+
private nodeAt;
|
|
109
|
+
private clamp;
|
|
110
|
+
ngOnDestroy(): void;
|
|
111
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<OneGridRowDragService<any>, never>;
|
|
112
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<OneGridRowDragService<any>>;
|
|
113
|
+
}
|
|
@@ -9,6 +9,15 @@ export declare class OneGridSelectionService {
|
|
|
9
9
|
setSelectionMode(mode: RowSelectionMode): void;
|
|
10
10
|
toggleSelection(rowId: string, selected: boolean): void;
|
|
11
11
|
toggleAllSelection(allIds: string[], selected: boolean): void;
|
|
12
|
+
/**
|
|
13
|
+
* Tri-state for the header checkbox, over the rows currently present.
|
|
14
|
+
*
|
|
15
|
+
* This compared `_selectedIds.size` with `allIds.length` and never checked
|
|
16
|
+
* that the selected ids were among the present ones. Selecting two rows and
|
|
17
|
+
* then swapping in two different rows reported `checked` with nothing
|
|
18
|
+
* actually selected, because the two counts happened to match. Counting the
|
|
19
|
+
* intersection is the only thing that answers the question being asked.
|
|
20
|
+
*/
|
|
12
21
|
getSelectAllState(allIds: (string)[]): OneCheckboxState;
|
|
13
22
|
selectAll(rowIds: string[]): void;
|
|
14
23
|
deselectAll(): void;
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { OneCellRendererParams, OneColumnDef, OneValueGetterParams } from "../core/models/one-column-def-types.model";
|
|
2
|
+
/** Width used when a column defines neither `width` nor `minWidth`. */
|
|
3
|
+
export declare const ONE_DEFAULT_COLUMN_WIDTH = 150;
|
|
4
|
+
/**
|
|
5
|
+
* The rendered width of a column, clamped to its bounds.
|
|
6
|
+
*
|
|
7
|
+
* `width`, `minWidth` and `maxWidth` are all optional, and the previous inline
|
|
8
|
+
* expression — repeated in two places — fell back to `minWidth` when `width`
|
|
9
|
+
* was absent. With neither set that produced `undefined`, and summing it gave
|
|
10
|
+
* a `NaN` row width, so the row collapsed. This is total: every combination of
|
|
11
|
+
* present and absent bounds resolves to a usable number.
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolveColumnWidth<T>(column: OneColumnDef<T>): number;
|
|
2
14
|
/**
|
|
3
15
|
* Apply Default Column Definitions
|
|
4
16
|
*/
|
|
@@ -6,7 +18,13 @@ export declare function applyDefaultColumnDef<T>(columnDefs: OneColumnDef<T>[],
|
|
|
6
18
|
/**
|
|
7
19
|
* One Column Params Resolver (Cell Renderer)
|
|
8
20
|
*/
|
|
9
|
-
export declare function resolveOneCellRendererParams<T>(prop: boolean | ((params: any) => boolean), params: OneCellRendererParams<T
|
|
21
|
+
export declare function resolveOneCellRendererParams<T>(prop: boolean | ((params: any) => boolean), params: OneCellRendererParams<T>,
|
|
22
|
+
/**
|
|
23
|
+
* What an unset property means: `false` for a capability you opt into,
|
|
24
|
+
* `true` for a restriction you opt out of. `!!prop` could not tell the two
|
|
25
|
+
* apart, which left `updatable` — a restriction — defaulting to "deny".
|
|
26
|
+
*/
|
|
27
|
+
whenUnset?: boolean): boolean;
|
|
10
28
|
/**
|
|
11
29
|
* One Column Params Resolver (Generics)
|
|
12
30
|
*/
|
|
@@ -5,16 +5,41 @@ import { OneFilterModel } from "../core/models/one-filter.model";
|
|
|
5
5
|
*
|
|
6
6
|
* Rules:
|
|
7
7
|
* - A node is visible if it matches the filters or has a matching descendant.
|
|
8
|
-
* -
|
|
8
|
+
* - While a filter is active, a node is expanded iff it has a matching
|
|
9
|
+
* descendant, so the hit is revealed.
|
|
10
|
+
*
|
|
11
|
+
* Overwriting `expanded` is only correct *while filtering*. This runs from
|
|
12
|
+
* `applyFilters`, which every `setRowData` / `updateRowData` calls, so doing it
|
|
13
|
+
* unconditionally force-expanded every parent on each data update: it made
|
|
14
|
+
* `groupDefaultExpanded` inert for tree data and collapsed expanded
|
|
15
|
+
* master-detail rows (they have no children, so `childMatch` is false).
|
|
9
16
|
*
|
|
10
17
|
* @returns True if the current node or any descendant matches.
|
|
11
18
|
*/
|
|
12
|
-
export declare function filterTreeNode<T = any>(node: OneRowNode<T>, filters: OneFilterModel[] | null, quick: string): boolean;
|
|
19
|
+
export declare function filterTreeNode<T = any>(node: OneRowNode<T>, filters: OneFilterModel[] | null, quick: string, fields?: readonly string[]): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Whether anything is actually filtering right now. A model entry with no
|
|
22
|
+
* conditions matches everything, so it does not count as active.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isFilterActive(filters: OneFilterModel[] | null, quick: string): boolean;
|
|
13
25
|
/**
|
|
14
26
|
* Apply advanced per-column filters
|
|
15
27
|
*/
|
|
16
28
|
export declare function matchesAdvancedFilters<T = any>(node: OneRowNode<T>, filters: OneFilterModel[] | null): boolean;
|
|
17
29
|
/**
|
|
18
|
-
* Apply quick filter
|
|
30
|
+
* Apply the quick filter to one row.
|
|
31
|
+
*
|
|
32
|
+
* Searches the fields the grid actually shows, when it is told what they are.
|
|
33
|
+
* It used to walk `Object.values(node.data)`, which had three consequences, all
|
|
34
|
+
* of them wrong:
|
|
35
|
+
*
|
|
36
|
+
* - a property with no column was searchable, so a user could match rows on
|
|
37
|
+
* data the grid never displayed;
|
|
38
|
+
* - a nested object stringified to `[object Object]`, so typing `object`
|
|
39
|
+
* matched every row holding one;
|
|
40
|
+
* - in a tree, `children` did the same, so most parents matched most queries.
|
|
41
|
+
*
|
|
42
|
+
* Non-primitive values are skipped regardless, so the `[object Object]` haystack
|
|
43
|
+
* cannot come back through a declared column either.
|
|
19
44
|
*/
|
|
20
|
-
export declare function matchesQuickFilter<T = any>(node: OneRowNode<T>, quick: string): boolean;
|
|
45
|
+
export declare function matchesQuickFilter<T = any>(node: OneRowNode<T>, quick: string, fields?: readonly string[]): boolean;
|
package/lib/index.d.ts
CHANGED
|
@@ -6,13 +6,20 @@ export * from './core/services/one-grid-event.service';
|
|
|
6
6
|
export * from './core/services/one-grid-selection.service';
|
|
7
7
|
export * from './core/services/one-grid-expansion.service';
|
|
8
8
|
export * from './core/services/one-grid-cell.service';
|
|
9
|
+
export * from './core/services/one-grid-row-drag.service';
|
|
9
10
|
export * from './core/services/one-grid-tree-data.service';
|
|
10
11
|
export * from './core/models/constants/one-pagination.constant';
|
|
11
12
|
export * from './core/models/one-column-def-types.model';
|
|
13
|
+
export * from './core/models/one-filter.model';
|
|
14
|
+
export * from './core/models/one-master-detail.model';
|
|
15
|
+
export * from './core/models/one-row.model';
|
|
16
|
+
export * from './core/models/one-row-drag.model';
|
|
12
17
|
export * from './core/models/one-event-types.model';
|
|
13
18
|
export * from './core/models/one-grid-types.model';
|
|
14
19
|
export * from './core/models/one-pagination-types.model';
|
|
15
20
|
export * from './core/models/one-validation.model';
|
|
16
21
|
export * from './core/models/one-tree-data.model';
|
|
17
22
|
export * from './components/one-grid/one-grid.component';
|
|
23
|
+
export * from './components/one-grid-status/one-grid-status.component';
|
|
24
|
+
export * from './components/one-grid-cell-currency/one-grid-cell-currency.component';
|
|
18
25
|
export * from './one-grid.module';
|
package/lib/one-grid.module.d.ts
CHANGED
|
@@ -17,29 +17,27 @@ import * as i15 from "./core/pipes/cell-invalid.pipe";
|
|
|
17
17
|
import * as i16 from "./core/pipes/cell-selected.pipe";
|
|
18
18
|
import * as i17 from "./core/pipes/cell-action-button-enable.pipe";
|
|
19
19
|
import * as i18 from "./core/pipes/cell-number-value.pipe";
|
|
20
|
-
import * as i19 from "./core/pipes/cell-
|
|
21
|
-
import * as i20 from "./core/pipes/cell-
|
|
22
|
-
import * as i21 from "./core/pipes/cell-
|
|
23
|
-
import * as i22 from "./core/pipes/
|
|
24
|
-
import * as i23 from "./core/pipes/
|
|
25
|
-
import * as i24 from "./core/pipes/header-checkbox-
|
|
26
|
-
import * as i25 from "./core/pipes/header-checkbox-
|
|
27
|
-
import * as i26 from "./core/pipes/
|
|
28
|
-
import * as i27 from "./core/pipes/cell-state-renderer.pipe";
|
|
29
|
-
import * as i28 from "./core/
|
|
30
|
-
import * as i29 from "./core/directives/one-cell-
|
|
31
|
-
import * as i30 from "./core/directives/one-cell-
|
|
32
|
-
import * as i31 from "./
|
|
33
|
-
import * as i32 from "./components/one-grid-cell-
|
|
34
|
-
import * as i33 from "./components/one-grid-
|
|
20
|
+
import * as i19 from "./core/pipes/cell-field.pipe";
|
|
21
|
+
import * as i20 from "./core/pipes/cell-key.pipe";
|
|
22
|
+
import * as i21 from "./core/pipes/cell-level-padding.pipe";
|
|
23
|
+
import * as i22 from "./core/pipes/column-sort-state.pipe";
|
|
24
|
+
import * as i23 from "./core/pipes/header-checkbox-disabled.pipe";
|
|
25
|
+
import * as i24 from "./core/pipes/header-checkbox-checked.pipe";
|
|
26
|
+
import * as i25 from "./core/pipes/header-checkbox-indeterminate.pipe";
|
|
27
|
+
import * as i26 from "./core/pipes/cell-state-renderer.pipe";
|
|
28
|
+
import * as i27 from "./core/pipes/cell-state-group-renderer.pipe";
|
|
29
|
+
import * as i28 from "./core/directives/one-cell-input-validator.directive";
|
|
30
|
+
import * as i29 from "./core/directives/one-cell-renderer-component.directive";
|
|
31
|
+
import * as i30 from "./core/directives/one-cell-text-expand.directive";
|
|
32
|
+
import * as i31 from "./components/one-grid-cell-currency/one-grid-cell-currency.component";
|
|
33
|
+
import * as i32 from "./components/one-grid-cell-option-menu/one-grid-cell-option-menu.component";
|
|
34
|
+
import * as i33 from "./components/one-grid-row-drag-handle/one-grid-row-drag-handle.component";
|
|
35
35
|
import * as i34 from "@angular/common";
|
|
36
36
|
import * as i35 from "@angular/forms";
|
|
37
37
|
import * as i36 from "@angular/cdk/scrolling";
|
|
38
|
-
import * as i37 from "
|
|
39
|
-
import * as i38 from "@angular/cdk/drag-drop";
|
|
40
|
-
import * as i39 from "lucide-angular";
|
|
38
|
+
import * as i37 from "lucide-angular";
|
|
41
39
|
export declare class OneGridModule {
|
|
42
40
|
static ɵfac: i0.ɵɵFactoryDeclaration<OneGridModule, never>;
|
|
43
|
-
static ɵmod: i0.ɵɵNgModuleDeclaration<OneGridModule, [typeof i1.OneGridComponent, typeof i2.OneGridHeaderComponent, typeof i3.OneGridBodyComponent, typeof i4.OneGridCheckboxComponent, typeof i5.OneGridCheckboxHeaderComponent, typeof i6.OneGridRowActionComponent, typeof i7.OneGridPaginationComponent, typeof i8.OneGridStatusComponent, typeof i9.OneGridCellGroupRendererComponent, typeof i10.CellFieldValueEmptyPipe, typeof i11.CellValueGetterPipe, typeof i12.CellFieldValuePipe, typeof i13.CellActionButtonVisiblePipe, typeof i14.CellEditablePipe, typeof i15.CellInvalidPipe, typeof i16.CellSelectedPipe, typeof i17.CellActionButtonEnablePipe, typeof i18.CellNumberValuePipe, typeof i19.
|
|
41
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<OneGridModule, [typeof i1.OneGridComponent, typeof i2.OneGridHeaderComponent, typeof i3.OneGridBodyComponent, typeof i4.OneGridCheckboxComponent, typeof i5.OneGridCheckboxHeaderComponent, typeof i6.OneGridRowActionComponent, typeof i7.OneGridPaginationComponent, typeof i8.OneGridStatusComponent, typeof i9.OneGridCellGroupRendererComponent, typeof i10.CellFieldValueEmptyPipe, typeof i11.CellValueGetterPipe, typeof i12.CellFieldValuePipe, typeof i13.CellActionButtonVisiblePipe, typeof i14.CellEditablePipe, typeof i15.CellInvalidPipe, typeof i16.CellSelectedPipe, typeof i17.CellActionButtonEnablePipe, typeof i18.CellNumberValuePipe, typeof i19.CellFieldPipe, typeof i20.CellKeyPipe, typeof i21.CellLevelPaddingPipe, typeof i22.ColumnSortStatePipe, typeof i23.HeaderCheckboxDisabledPipe, typeof i24.HeaderCheckboxCheckedPipe, typeof i25.HeaderCheckboxIndeterminatePipe, typeof i26.CellStateRendererPipe, typeof i27.CellStateGroupRendererPipe, typeof i28.OneCellInputValidatorDirective, typeof i29.OneCellRendererComponentDirective, typeof i30.OneCellTextExpandDirective, typeof i31.OneGridCellCurrencyComponent, typeof i32.OneGridCellOptionMenuComponent, typeof i33.OneGridRowDragHandleComponent], [typeof i34.CommonModule, typeof i35.FormsModule, typeof i36.ScrollingModule, typeof i35.ReactiveFormsModule, typeof i37.LucideAngularModule], [typeof i1.OneGridComponent]>;
|
|
44
42
|
static ɵinj: i0.ɵɵInjectorDeclaration<OneGridModule>;
|
|
45
43
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@one-grid-core/angular",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "OneGrid — a feature-rich Angular data grid component with tree data, master/detail, editing, selection, pagination, and virtual scrolling.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -33,7 +33,6 @@
|
|
|
33
33
|
"@angular/core": ">=17.0.0",
|
|
34
34
|
"@angular/forms": ">=17.0.0",
|
|
35
35
|
"@angular/cdk": ">=17.0.0",
|
|
36
|
-
"@ng-bootstrap/ng-bootstrap": ">=16.0.0",
|
|
37
36
|
"lucide-angular": ">=0.400.0",
|
|
38
37
|
"rxjs": "^6.5.3 || ^7.4.0"
|
|
39
38
|
},
|