@affino/datagrid-vue-app 0.1.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/LICENSE +21 -0
- package/README.md +1062 -0
- package/dist/DataGrid.d.ts +430 -0
- package/dist/DataGrid.js +565 -0
- package/dist/DataGridDefaultRenderer.d.ts +2 -0
- package/dist/DataGridDefaultRenderer.js +2 -0
- package/dist/DataGridModuleHost.d.ts +2 -0
- package/dist/DataGridModuleHost.js +2 -0
- package/dist/DataGridRuntimeHost.d.ts +1 -0
- package/dist/DataGridRuntimeHost.js +1 -0
- package/dist/config/dataGridAdvancedFilter.d.ts +9 -0
- package/dist/config/dataGridAdvancedFilter.js +21 -0
- package/dist/config/dataGridAggregations.d.ts +17 -0
- package/dist/config/dataGridAggregations.js +21 -0
- package/dist/config/dataGridColumnLayout.d.ts +9 -0
- package/dist/config/dataGridColumnLayout.js +21 -0
- package/dist/config/dataGridFormulaOptions.d.ts +25 -0
- package/dist/config/dataGridFormulaOptions.js +137 -0
- package/dist/config/dataGridPublicProps.d.ts +6 -0
- package/dist/config/dataGridPublicProps.js +58 -0
- package/dist/config/dataGridSavedView.d.ts +17 -0
- package/dist/config/dataGridSavedView.js +73 -0
- package/dist/config/dataGridVirtualization.d.ts +14 -0
- package/dist/config/dataGridVirtualization.js +32 -0
- package/dist/dataGridAdvancedFilter.d.ts +1 -0
- package/dist/dataGridAdvancedFilter.js +1 -0
- package/dist/dataGridAggregations.d.ts +1 -0
- package/dist/dataGridAggregations.js +1 -0
- package/dist/dataGridAppContext.d.ts +2 -0
- package/dist/dataGridAppContext.js +1 -0
- package/dist/dataGridCellComboboxState.d.ts +10 -0
- package/dist/dataGridCellComboboxState.js +67 -0
- package/dist/dataGridColumnLayout.d.ts +1 -0
- package/dist/dataGridColumnLayout.js +1 -0
- package/dist/dataGridColumnMenu.d.ts +9 -0
- package/dist/dataGridColumnMenu.js +21 -0
- package/dist/dataGridEditability.d.ts +9 -0
- package/dist/dataGridEditability.js +1 -0
- package/dist/dataGridFilterableCombobox.d.ts +1 -0
- package/dist/dataGridFilterableCombobox.js +1 -0
- package/dist/dataGridFormulaOptions.d.ts +1 -0
- package/dist/dataGridFormulaOptions.js +1 -0
- package/dist/dataGridGantt.d.ts +3 -0
- package/dist/dataGridGantt.js +1 -0
- package/dist/dataGridGanttDependencySelection.d.ts +7 -0
- package/dist/dataGridGanttDependencySelection.js +46 -0
- package/dist/dataGridGanttLabel.d.ts +2 -0
- package/dist/dataGridGanttLabel.js +30 -0
- package/dist/dataGridGanttSplit.d.ts +20 -0
- package/dist/dataGridGanttSplit.js +31 -0
- package/dist/dataGridGanttWheel.d.ts +10 -0
- package/dist/dataGridGanttWheel.js +30 -0
- package/dist/dataGridOverlayThemeVars.d.ts +1 -0
- package/dist/dataGridOverlayThemeVars.js +32 -0
- package/dist/dataGridPublicProps.d.ts +1 -0
- package/dist/dataGridPublicProps.js +1 -0
- package/dist/dataGridTableStage.types.d.ts +1 -0
- package/dist/dataGridTableStage.types.js +1 -0
- package/dist/dataGridTableStageBody.types.d.ts +1 -0
- package/dist/dataGridTableStageBody.types.js +1 -0
- package/dist/dataGridTableStageContext.d.ts +1 -0
- package/dist/dataGridTableStageContext.js +1 -0
- package/dist/dataGridTheme.d.ts +1 -0
- package/dist/dataGridTheme.js +1 -0
- package/dist/dataGridVirtualization.d.ts +1 -0
- package/dist/dataGridVirtualization.js +1 -0
- package/dist/ensureDataGridAppStyles.d.ts +1 -0
- package/dist/ensureDataGridAppStyles.js +1 -0
- package/dist/gantt/dataGridGantt.d.ts +3 -0
- package/dist/gantt/dataGridGantt.js +1 -0
- package/dist/gantt/dataGridGanttDependencySelection.d.ts +7 -0
- package/dist/gantt/dataGridGanttDependencySelection.js +46 -0
- package/dist/gantt/dataGridGanttLabel.d.ts +2 -0
- package/dist/gantt/dataGridGanttLabel.js +30 -0
- package/dist/gantt/dataGridGanttSplit.d.ts +20 -0
- package/dist/gantt/dataGridGanttSplit.js +31 -0
- package/dist/gantt/dataGridGanttWheel.d.ts +10 -0
- package/dist/gantt/dataGridGanttWheel.js +30 -0
- package/dist/host/DataGridDefaultRenderer.d.ts +298 -0
- package/dist/host/DataGridDefaultRenderer.js +1847 -0
- package/dist/host/DataGridModuleHost.d.ts +24 -0
- package/dist/host/DataGridModuleHost.js +23 -0
- package/dist/host/DataGridRuntimeHost.d.ts +104 -0
- package/dist/host/DataGridRuntimeHost.js +174 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +4 -0
- package/dist/internal.d.ts +21 -0
- package/dist/internal.js +14 -0
- package/dist/overlays/dataGridCellComboboxState.d.ts +10 -0
- package/dist/overlays/dataGridCellComboboxState.js +67 -0
- package/dist/overlays/dataGridColumnMenu.d.ts +47 -0
- package/dist/overlays/dataGridColumnMenu.js +190 -0
- package/dist/overlays/dataGridContextMenu.d.ts +80 -0
- package/dist/overlays/dataGridContextMenu.js +218 -0
- package/dist/overlays/dataGridFilterableCombobox.d.ts +5 -0
- package/dist/overlays/dataGridFilterableCombobox.js +74 -0
- package/dist/overlays/dataGridOverlayThemeVars.d.ts +1 -0
- package/dist/overlays/dataGridOverlayThemeVars.js +32 -0
- package/dist/stage/dataGridTableStage.types.d.ts +160 -0
- package/dist/stage/dataGridTableStage.types.js +1 -0
- package/dist/stage/dataGridTableStageBody.types.d.ts +105 -0
- package/dist/stage/dataGridTableStageBody.types.js +1 -0
- package/dist/stage/dataGridTableStageContext.d.ts +45 -0
- package/dist/stage/dataGridTableStageContext.js +88 -0
- package/dist/stage/useDataGridTableStageBindings.d.ts +11 -0
- package/dist/stage/useDataGridTableStageBindings.js +162 -0
- package/dist/stage/useDataGridTableStageCellIo.d.ts +28 -0
- package/dist/stage/useDataGridTableStageCellIo.js +62 -0
- package/dist/stage/useDataGridTableStageColumns.d.ts +22 -0
- package/dist/stage/useDataGridTableStageColumns.js +124 -0
- package/dist/stage/useDataGridTableStageFillAction.d.ts +19 -0
- package/dist/stage/useDataGridTableStageFillAction.js +28 -0
- package/dist/stage/useDataGridTableStageHistory.d.ts +31 -0
- package/dist/stage/useDataGridTableStageHistory.js +46 -0
- package/dist/stage/useDataGridTableStageRowSelection.d.ts +28 -0
- package/dist/stage/useDataGridTableStageRowSelection.js +107 -0
- package/dist/stage/useDataGridTableStageRuntime.d.ts +92 -0
- package/dist/stage/useDataGridTableStageRuntime.js +526 -0
- package/dist/stage/useDataGridTableStageScrollSync.d.ts +17 -0
- package/dist/stage/useDataGridTableStageScrollSync.js +49 -0
- package/dist/stage/useDataGridTableStageViewportKeyboard.d.ts +20 -0
- package/dist/stage/useDataGridTableStageViewportKeyboard.js +58 -0
- package/dist/stage/useDataGridTableStageVisualSelection.d.ts +24 -0
- package/dist/stage/useDataGridTableStageVisualSelection.js +83 -0
- package/dist/theme/dataGridTheme.d.ts +6 -0
- package/dist/theme/dataGridTheme.js +84 -0
- package/dist/theme/ensureDataGridAppStyles.d.ts +1 -0
- package/dist/theme/ensureDataGridAppStyles.js +2656 -0
- package/dist/useDataGridAppControlledState.d.ts +59 -0
- package/dist/useDataGridAppControlledState.js +390 -0
- package/dist/useDataGridAppRowModel.d.ts +14 -0
- package/dist/useDataGridAppRowModel.js +85 -0
- package/dist/useDataGridTableStageBindings.d.ts +1 -0
- package/dist/useDataGridTableStageBindings.js +1 -0
- package/dist/useDataGridTableStageCellIo.d.ts +28 -0
- package/dist/useDataGridTableStageCellIo.js +62 -0
- package/dist/useDataGridTableStageColumns.d.ts +21 -0
- package/dist/useDataGridTableStageColumns.js +122 -0
- package/dist/useDataGridTableStageFillAction.d.ts +19 -0
- package/dist/useDataGridTableStageFillAction.js +28 -0
- package/dist/useDataGridTableStageHistory.d.ts +31 -0
- package/dist/useDataGridTableStageHistory.js +46 -0
- package/dist/useDataGridTableStageRowSelection.d.ts +28 -0
- package/dist/useDataGridTableStageRowSelection.js +103 -0
- package/dist/useDataGridTableStageRuntime.d.ts +1 -0
- package/dist/useDataGridTableStageRuntime.js +1 -0
- package/dist/useDataGridTableStageScrollSync.d.ts +17 -0
- package/dist/useDataGridTableStageScrollSync.js +49 -0
- package/dist/useDataGridTableStageViewportKeyboard.d.ts +20 -0
- package/dist/useDataGridTableStageViewportKeyboard.js +58 -0
- package/dist/useDataGridTableStageVisualSelection.d.ts +24 -0
- package/dist/useDataGridTableStageVisualSelection.js +70 -0
- package/package.json +55 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { CreateClientRowModelOptions, DataGridColumnInput, DataGridComputedFieldDefinition, DataGridFormulaFieldDefinition, DataGridFormulaFunctionRegistry } from "@affino/datagrid-vue";
|
|
2
|
+
/**
|
|
3
|
+
* High-level authored column contract for `@affino/datagrid-vue-app`.
|
|
4
|
+
*/
|
|
5
|
+
export interface DataGridAppColumnInput extends DataGridColumnInput {
|
|
6
|
+
formula?: string | null;
|
|
7
|
+
}
|
|
8
|
+
export interface DataGridDeclarativeFormulaOptions<TRow = unknown> {
|
|
9
|
+
formulas?: readonly DataGridFormulaFieldDefinition[] | null;
|
|
10
|
+
computedFields?: readonly DataGridComputedFieldDefinition<TRow>[] | null;
|
|
11
|
+
formulaFunctions?: DataGridFormulaFunctionRegistry | null;
|
|
12
|
+
}
|
|
13
|
+
export type DataGridAppClientRowModelOptions<TRow = unknown> = Omit<CreateClientRowModelOptions<TRow>, "rows" | "computeMode" | "workerPatchDispatchThreshold" | "formulaColumnCacheMaxColumns">;
|
|
14
|
+
export interface DataGridAppEnterpriseFormulaRuntimeOptions {
|
|
15
|
+
computeMode?: "sync" | "worker";
|
|
16
|
+
workerPatchDispatchThreshold?: number | null;
|
|
17
|
+
formulaColumnCacheMaxColumns?: number | null;
|
|
18
|
+
}
|
|
19
|
+
export interface ResolveDataGridFormulaRowModelOptionsInput<TRow = unknown> extends DataGridDeclarativeFormulaOptions<TRow> {
|
|
20
|
+
columns?: readonly DataGridAppColumnInput[] | null | undefined;
|
|
21
|
+
clientRowModelOptions?: DataGridAppClientRowModelOptions<TRow> | undefined;
|
|
22
|
+
enterpriseClientRowModelOptions?: DataGridAppEnterpriseFormulaRuntimeOptions | undefined;
|
|
23
|
+
}
|
|
24
|
+
export declare function resolveDataGridColumns(columns: readonly DataGridAppColumnInput[] | null | undefined): readonly DataGridColumnInput[];
|
|
25
|
+
export declare function resolveDataGridFormulaRowModelOptions<TRow = unknown>(input: ResolveDataGridFormulaRowModelOptionsInput<TRow>): Omit<CreateClientRowModelOptions<TRow>, "rows"> | undefined;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
const CLIENT_ROW_MODEL_OPTIONS_CACHE = new WeakMap();
|
|
2
|
+
const MERGED_ROW_MODEL_OPTIONS_CACHE = new WeakMap();
|
|
3
|
+
function cloneClientRowModelOptions(options) {
|
|
4
|
+
if (!options) {
|
|
5
|
+
return undefined;
|
|
6
|
+
}
|
|
7
|
+
const cached = CLIENT_ROW_MODEL_OPTIONS_CACHE.get(options);
|
|
8
|
+
if (cached) {
|
|
9
|
+
return cached;
|
|
10
|
+
}
|
|
11
|
+
const normalizedExpandedByDefault = options.initialTreeData?.expandedByDefault ?? false;
|
|
12
|
+
if (options.initialTreeData?.expandedByDefault === normalizedExpandedByDefault) {
|
|
13
|
+
CLIENT_ROW_MODEL_OPTIONS_CACHE.set(options, options);
|
|
14
|
+
return options;
|
|
15
|
+
}
|
|
16
|
+
const cloned = {
|
|
17
|
+
...options,
|
|
18
|
+
};
|
|
19
|
+
if (options.initialTreeData) {
|
|
20
|
+
cloned.initialTreeData = {
|
|
21
|
+
...options.initialTreeData,
|
|
22
|
+
expandedByDefault: normalizedExpandedByDefault,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
CLIENT_ROW_MODEL_OPTIONS_CACHE.set(options, cloned);
|
|
26
|
+
return cloned;
|
|
27
|
+
}
|
|
28
|
+
function cloneFormulas(formulas) {
|
|
29
|
+
if (!formulas || formulas.length === 0) {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
return formulas.map(entry => ({ ...entry }));
|
|
33
|
+
}
|
|
34
|
+
function cloneComputedFields(computedFields) {
|
|
35
|
+
if (!computedFields || computedFields.length === 0) {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
return computedFields.map(entry => ({ ...entry }));
|
|
39
|
+
}
|
|
40
|
+
function cloneColumns(columns) {
|
|
41
|
+
if (!columns || columns.length === 0) {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
return columns.map(({ formula: _formula, ...column }) => ({ ...column }));
|
|
45
|
+
}
|
|
46
|
+
function extractEmbeddedFormulas(columns) {
|
|
47
|
+
if (!columns || columns.length === 0) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
return columns.flatMap(column => {
|
|
51
|
+
const formula = typeof column.formula === "string" ? column.formula.trim() : "";
|
|
52
|
+
if (!formula) {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
return [{
|
|
56
|
+
name: column.key,
|
|
57
|
+
formula,
|
|
58
|
+
}];
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function mergeFormulaDefinitions(embeddedFormulas, formulas) {
|
|
62
|
+
const merged = new Map();
|
|
63
|
+
for (const entry of embeddedFormulas) {
|
|
64
|
+
merged.set(entry.name, { ...entry });
|
|
65
|
+
}
|
|
66
|
+
for (const entry of cloneFormulas(formulas)) {
|
|
67
|
+
merged.set(entry.name, entry);
|
|
68
|
+
}
|
|
69
|
+
return Array.from(merged.values());
|
|
70
|
+
}
|
|
71
|
+
export function resolveDataGridColumns(columns) {
|
|
72
|
+
return cloneColumns(columns);
|
|
73
|
+
}
|
|
74
|
+
export function resolveDataGridFormulaRowModelOptions(input) {
|
|
75
|
+
const baseOptions = cloneClientRowModelOptions(input.clientRowModelOptions);
|
|
76
|
+
const enterpriseOptions = input.enterpriseClientRowModelOptions;
|
|
77
|
+
const embeddedFormulas = extractEmbeddedFormulas(input.columns);
|
|
78
|
+
const hasFormulaProp = input.formulas !== undefined;
|
|
79
|
+
const hasComputedFieldsProp = input.computedFields !== undefined;
|
|
80
|
+
const hasFormulaFunctionsProp = input.formulaFunctions !== undefined;
|
|
81
|
+
const hasEmbeddedFormulas = embeddedFormulas.length > 0;
|
|
82
|
+
const initialFormulaFields = hasFormulaProp || hasEmbeddedFormulas
|
|
83
|
+
? mergeFormulaDefinitions(embeddedFormulas, input.formulas)
|
|
84
|
+
: undefined;
|
|
85
|
+
const initialComputedFields = hasComputedFieldsProp ? cloneComputedFields(input.computedFields) : undefined;
|
|
86
|
+
const initialFormulaFunctionRegistry = hasFormulaFunctionsProp ? (input.formulaFunctions ?? {}) : undefined;
|
|
87
|
+
const hasFormulaOverrides = Boolean(hasEmbeddedFormulas
|
|
88
|
+
|| hasFormulaProp
|
|
89
|
+
|| hasComputedFieldsProp
|
|
90
|
+
|| hasFormulaFunctionsProp);
|
|
91
|
+
if (!baseOptions && !hasFormulaOverrides) {
|
|
92
|
+
if (!enterpriseOptions) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
...enterpriseOptions,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
if (!hasFormulaOverrides) {
|
|
100
|
+
if (baseOptions && !enterpriseOptions) {
|
|
101
|
+
return baseOptions;
|
|
102
|
+
}
|
|
103
|
+
if (!baseOptions && enterpriseOptions) {
|
|
104
|
+
return enterpriseOptions;
|
|
105
|
+
}
|
|
106
|
+
if (baseOptions && enterpriseOptions) {
|
|
107
|
+
let byEnterprise = MERGED_ROW_MODEL_OPTIONS_CACHE.get(baseOptions);
|
|
108
|
+
if (!byEnterprise) {
|
|
109
|
+
byEnterprise = new WeakMap();
|
|
110
|
+
MERGED_ROW_MODEL_OPTIONS_CACHE.set(baseOptions, byEnterprise);
|
|
111
|
+
}
|
|
112
|
+
const cached = byEnterprise.get(enterpriseOptions);
|
|
113
|
+
if (cached) {
|
|
114
|
+
return cached;
|
|
115
|
+
}
|
|
116
|
+
const merged = {
|
|
117
|
+
...baseOptions,
|
|
118
|
+
...enterpriseOptions,
|
|
119
|
+
};
|
|
120
|
+
byEnterprise.set(enterpriseOptions, merged);
|
|
121
|
+
return merged;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
...(baseOptions ?? {}),
|
|
126
|
+
...(hasComputedFieldsProp ? { initialComputedFields } : {}),
|
|
127
|
+
...(hasFormulaProp || hasEmbeddedFormulas ? { initialFormulaFields } : {}),
|
|
128
|
+
...(hasFormulaFunctionsProp ? { initialFormulaFunctionRegistry } : {}),
|
|
129
|
+
...(enterpriseOptions?.computeMode ? { computeMode: enterpriseOptions.computeMode } : {}),
|
|
130
|
+
...(enterpriseOptions?.workerPatchDispatchThreshold !== undefined
|
|
131
|
+
? { workerPatchDispatchThreshold: enterpriseOptions.workerPatchDispatchThreshold }
|
|
132
|
+
: {}),
|
|
133
|
+
...(enterpriseOptions?.formulaColumnCacheMaxColumns !== undefined
|
|
134
|
+
? { formulaColumnCacheMaxColumns: enterpriseOptions.formulaColumnCacheMaxColumns }
|
|
135
|
+
: {}),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { DataGridGroupBySpec, DataGridPaginationInput } from "@affino/datagrid-vue";
|
|
2
|
+
export type DataGridGroupByProp = string | readonly string[] | DataGridGroupBySpec | null;
|
|
3
|
+
export type DataGridPaginationProp = boolean | DataGridPaginationInput | null;
|
|
4
|
+
export declare function resolveDataGridGroupBy(input: DataGridGroupByProp | undefined): DataGridGroupBySpec | null | undefined;
|
|
5
|
+
export declare function resolveDataGridRenderMode(renderMode: "virtualization" | "pagination" | undefined, pagination: DataGridPaginationProp | undefined): "virtualization" | "pagination";
|
|
6
|
+
export declare function resolveDataGridPagination(pagination: DataGridPaginationProp | undefined, renderMode: "virtualization" | "pagination", pageSize: number | undefined, currentPage: number | undefined): DataGridPaginationInput | null;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
function normalizePageNumber(value, fallback) {
|
|
2
|
+
if (!Number.isFinite(value)) {
|
|
3
|
+
return fallback;
|
|
4
|
+
}
|
|
5
|
+
return Math.max(0, Math.trunc(value));
|
|
6
|
+
}
|
|
7
|
+
function normalizePageSize(value, fallback) {
|
|
8
|
+
if (!Number.isFinite(value)) {
|
|
9
|
+
return fallback;
|
|
10
|
+
}
|
|
11
|
+
return Math.max(1, Math.trunc(value));
|
|
12
|
+
}
|
|
13
|
+
export function resolveDataGridGroupBy(input) {
|
|
14
|
+
if (input === undefined) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
if (input == null) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
if (typeof input === "string") {
|
|
21
|
+
const field = input.trim();
|
|
22
|
+
return field ? { fields: [field], expandedByDefault: true } : null;
|
|
23
|
+
}
|
|
24
|
+
if (Array.isArray(input)) {
|
|
25
|
+
const fields = input
|
|
26
|
+
.map(field => field.trim())
|
|
27
|
+
.filter(field => field.length > 0);
|
|
28
|
+
return fields.length > 0 ? { fields: [...fields], expandedByDefault: true } : null;
|
|
29
|
+
}
|
|
30
|
+
return input;
|
|
31
|
+
}
|
|
32
|
+
export function resolveDataGridRenderMode(renderMode, pagination) {
|
|
33
|
+
if (pagination === true) {
|
|
34
|
+
return "pagination";
|
|
35
|
+
}
|
|
36
|
+
if (pagination && typeof pagination === "object") {
|
|
37
|
+
return "pagination";
|
|
38
|
+
}
|
|
39
|
+
return renderMode ?? "virtualization";
|
|
40
|
+
}
|
|
41
|
+
export function resolveDataGridPagination(pagination, renderMode, pageSize, currentPage) {
|
|
42
|
+
if (renderMode !== "pagination") {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const fallbackPageSize = 100;
|
|
46
|
+
const resolvedPageSize = normalizePageSize(pageSize, fallbackPageSize);
|
|
47
|
+
const resolvedCurrentPage = normalizePageNumber(currentPage, 0);
|
|
48
|
+
if (pagination === true || pagination === false || pagination == null) {
|
|
49
|
+
return {
|
|
50
|
+
pageSize: resolvedPageSize,
|
|
51
|
+
currentPage: resolvedCurrentPage,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
pageSize: normalizePageSize(pageSize ?? pagination.pageSize, fallbackPageSize),
|
|
56
|
+
currentPage: normalizePageNumber(currentPage ?? pagination.currentPage, 0),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { DataGridMigrateStateOptions, DataGridUnifiedState } from "@affino/datagrid-vue";
|
|
2
|
+
import type { DataGridAppViewMode } from "../gantt/dataGridGantt";
|
|
3
|
+
export interface DataGridSavedViewSnapshot<TRow extends Record<string, unknown> = Record<string, unknown>> {
|
|
4
|
+
state: DataGridUnifiedState<TRow>;
|
|
5
|
+
viewMode?: DataGridAppViewMode;
|
|
6
|
+
}
|
|
7
|
+
export interface DataGridSavedViewStorageLike {
|
|
8
|
+
getItem: (key: string) => string | null;
|
|
9
|
+
setItem: (key: string, value: string) => void;
|
|
10
|
+
removeItem: (key: string) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare function migrateDataGridSavedView<TRow extends Record<string, unknown> = Record<string, unknown>>(value: unknown, migrateState: (state: unknown, options?: DataGridMigrateStateOptions) => DataGridUnifiedState<TRow> | null, options?: DataGridMigrateStateOptions): DataGridSavedViewSnapshot<TRow> | null;
|
|
13
|
+
export declare function serializeDataGridSavedView<TRow extends Record<string, unknown> = Record<string, unknown>>(savedView: DataGridSavedViewSnapshot<TRow>): string;
|
|
14
|
+
export declare function parseDataGridSavedView<TRow extends Record<string, unknown> = Record<string, unknown>>(value: string, migrateState: (state: unknown, options?: DataGridMigrateStateOptions) => DataGridUnifiedState<TRow> | null, options?: DataGridMigrateStateOptions): DataGridSavedViewSnapshot<TRow> | null;
|
|
15
|
+
export declare function writeDataGridSavedViewToStorage<TRow extends Record<string, unknown> = Record<string, unknown>>(storage: DataGridSavedViewStorageLike | null | undefined, key: string, savedView: DataGridSavedViewSnapshot<TRow>): boolean;
|
|
16
|
+
export declare function readDataGridSavedViewFromStorage<TRow extends Record<string, unknown> = Record<string, unknown>>(storage: DataGridSavedViewStorageLike | null | undefined, key: string, migrateState: (state: unknown, options?: DataGridMigrateStateOptions) => DataGridUnifiedState<TRow> | null, options?: DataGridMigrateStateOptions): DataGridSavedViewSnapshot<TRow> | null;
|
|
17
|
+
export declare function clearDataGridSavedViewInStorage(storage: DataGridSavedViewStorageLike | null | undefined, key: string): boolean;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
function isRecord(value) {
|
|
2
|
+
return typeof value === "object" && value !== null;
|
|
3
|
+
}
|
|
4
|
+
export function migrateDataGridSavedView(value, migrateState, options) {
|
|
5
|
+
const record = isRecord(value) ? value : null;
|
|
6
|
+
const migratedState = migrateState(record && "state" in record ? record.state : value, options);
|
|
7
|
+
if (!migratedState) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
const rawViewMode = record?.viewMode;
|
|
11
|
+
const viewMode = rawViewMode === "gantt"
|
|
12
|
+
? "gantt"
|
|
13
|
+
: rawViewMode === "table"
|
|
14
|
+
? "table"
|
|
15
|
+
: undefined;
|
|
16
|
+
return {
|
|
17
|
+
state: migratedState,
|
|
18
|
+
...(viewMode ? { viewMode } : {}),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function serializeDataGridSavedView(savedView) {
|
|
22
|
+
return JSON.stringify(savedView);
|
|
23
|
+
}
|
|
24
|
+
export function parseDataGridSavedView(value, migrateState, options) {
|
|
25
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
return migrateDataGridSavedView(JSON.parse(value), migrateState, options);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export function writeDataGridSavedViewToStorage(storage, key, savedView) {
|
|
36
|
+
if (!storage || typeof key !== "string" || key.trim().length === 0) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
storage.setItem(key, serializeDataGridSavedView(savedView));
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function readDataGridSavedViewFromStorage(storage, key, migrateState, options) {
|
|
48
|
+
if (!storage || typeof key !== "string" || key.trim().length === 0) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const rawValue = storage.getItem(key);
|
|
53
|
+
if (!rawValue) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
return parseDataGridSavedView(rawValue, migrateState, options);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export function clearDataGridSavedViewInStorage(storage, key) {
|
|
63
|
+
if (!storage || typeof key !== "string" || key.trim().length === 0) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
storage.removeItem(key);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface DataGridVirtualizationOptions {
|
|
2
|
+
rows: boolean;
|
|
3
|
+
columns: boolean;
|
|
4
|
+
rowOverscan: number;
|
|
5
|
+
columnOverscan: number;
|
|
6
|
+
}
|
|
7
|
+
export type DataGridVirtualizationProp = boolean | {
|
|
8
|
+
overscan?: number;
|
|
9
|
+
rows?: boolean;
|
|
10
|
+
columns?: boolean;
|
|
11
|
+
rowOverscan?: number;
|
|
12
|
+
columnOverscan?: number;
|
|
13
|
+
};
|
|
14
|
+
export declare function resolveDataGridVirtualization(input: DataGridVirtualizationProp | undefined, renderMode: "virtualization" | "pagination"): DataGridVirtualizationOptions;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
function normalizeOverscan(value, fallback) {
|
|
2
|
+
if (!Number.isFinite(value)) {
|
|
3
|
+
return fallback;
|
|
4
|
+
}
|
|
5
|
+
return Math.max(0, Math.trunc(value));
|
|
6
|
+
}
|
|
7
|
+
export function resolveDataGridVirtualization(input, renderMode) {
|
|
8
|
+
const defaults = {
|
|
9
|
+
rows: true,
|
|
10
|
+
columns: false,
|
|
11
|
+
rowOverscan: 8,
|
|
12
|
+
columnOverscan: 2,
|
|
13
|
+
};
|
|
14
|
+
if (input === true) {
|
|
15
|
+
defaults.columns = true;
|
|
16
|
+
}
|
|
17
|
+
else if (input === false) {
|
|
18
|
+
defaults.rows = false;
|
|
19
|
+
defaults.columns = false;
|
|
20
|
+
}
|
|
21
|
+
else if (input && typeof input === "object") {
|
|
22
|
+
defaults.rows = input.rows ?? defaults.rows;
|
|
23
|
+
defaults.columns = input.columns ?? defaults.columns;
|
|
24
|
+
const sharedOverscan = normalizeOverscan(input.overscan, defaults.rowOverscan);
|
|
25
|
+
defaults.rowOverscan = normalizeOverscan(input.rowOverscan, sharedOverscan);
|
|
26
|
+
defaults.columnOverscan = normalizeOverscan(input.columnOverscan, normalizeOverscan(input.overscan, defaults.columnOverscan));
|
|
27
|
+
}
|
|
28
|
+
if (renderMode === "pagination") {
|
|
29
|
+
defaults.rows = false;
|
|
30
|
+
}
|
|
31
|
+
return defaults;
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./config/dataGridAdvancedFilter";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./config/dataGridAdvancedFilter";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./config/dataGridAggregations";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./config/dataGridAggregations";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const dataGridAppRootElementKey = Symbol("affino-datagrid-app-root-element");
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface DataGridCellComboboxState {
|
|
2
|
+
open: boolean;
|
|
3
|
+
filter: string;
|
|
4
|
+
activeIndex: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function createDataGridCellComboboxState(initial?: Partial<DataGridCellComboboxState>): DataGridCellComboboxState;
|
|
7
|
+
export declare function setDataGridCellComboboxOpen(state: DataGridCellComboboxState, open: boolean): DataGridCellComboboxState;
|
|
8
|
+
export declare function setDataGridCellComboboxFilter(state: DataGridCellComboboxState, filter: string): DataGridCellComboboxState;
|
|
9
|
+
export declare function activateDataGridCellComboboxIndex(state: DataGridCellComboboxState, index: number, optionCount: number): DataGridCellComboboxState;
|
|
10
|
+
export declare function moveDataGridCellComboboxFocus(state: DataGridCellComboboxState, delta: number, optionCount: number, loop?: boolean): DataGridCellComboboxState;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export function createDataGridCellComboboxState(initial = {}) {
|
|
2
|
+
return {
|
|
3
|
+
open: initial.open ?? false,
|
|
4
|
+
filter: initial.filter ?? "",
|
|
5
|
+
activeIndex: initial.activeIndex ?? -1,
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export function setDataGridCellComboboxOpen(state, open) {
|
|
9
|
+
if (state.open === open) {
|
|
10
|
+
return state;
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
...state,
|
|
14
|
+
open,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function setDataGridCellComboboxFilter(state, filter) {
|
|
18
|
+
if (state.filter === filter) {
|
|
19
|
+
return state;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
...state,
|
|
23
|
+
filter,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function activateDataGridCellComboboxIndex(state, index, optionCount) {
|
|
27
|
+
const nextIndex = clampIndex(index, optionCount);
|
|
28
|
+
if (nextIndex === state.activeIndex) {
|
|
29
|
+
return state;
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
...state,
|
|
33
|
+
activeIndex: nextIndex,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export function moveDataGridCellComboboxFocus(state, delta, optionCount, loop = true) {
|
|
37
|
+
if (optionCount <= 0 || delta === 0) {
|
|
38
|
+
return state;
|
|
39
|
+
}
|
|
40
|
+
if (state.activeIndex < 0) {
|
|
41
|
+
return activateDataGridCellComboboxIndex(state, delta > 0 ? 0 : optionCount - 1, optionCount);
|
|
42
|
+
}
|
|
43
|
+
const rawTarget = state.activeIndex + Math.trunc(delta);
|
|
44
|
+
if (loop) {
|
|
45
|
+
return activateDataGridCellComboboxIndex(state, modulo(rawTarget, optionCount), optionCount);
|
|
46
|
+
}
|
|
47
|
+
return activateDataGridCellComboboxIndex(state, rawTarget, optionCount);
|
|
48
|
+
}
|
|
49
|
+
function clampIndex(index, optionCount) {
|
|
50
|
+
if (optionCount <= 0) {
|
|
51
|
+
return -1;
|
|
52
|
+
}
|
|
53
|
+
if (!Number.isFinite(index)) {
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
const normalized = Math.trunc(index);
|
|
57
|
+
if (normalized < 0) {
|
|
58
|
+
return 0;
|
|
59
|
+
}
|
|
60
|
+
if (normalized >= optionCount) {
|
|
61
|
+
return optionCount - 1;
|
|
62
|
+
}
|
|
63
|
+
return normalized;
|
|
64
|
+
}
|
|
65
|
+
function modulo(value, divisor) {
|
|
66
|
+
return ((value % divisor) + divisor) % divisor;
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./config/dataGridColumnLayout";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./config/dataGridColumnLayout";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface DataGridColumnMenuOptions {
|
|
2
|
+
enabled: boolean;
|
|
3
|
+
maxFilterValues: number;
|
|
4
|
+
}
|
|
5
|
+
export type DataGridColumnMenuProp = boolean | {
|
|
6
|
+
enabled?: boolean;
|
|
7
|
+
maxFilterValues?: number;
|
|
8
|
+
} | null;
|
|
9
|
+
export declare function resolveDataGridColumnMenu(input: DataGridColumnMenuProp | undefined): DataGridColumnMenuOptions;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const DEFAULT_MAX_FILTER_VALUES = 120;
|
|
2
|
+
export function resolveDataGridColumnMenu(input) {
|
|
3
|
+
if (typeof input === "boolean") {
|
|
4
|
+
return {
|
|
5
|
+
enabled: input,
|
|
6
|
+
maxFilterValues: DEFAULT_MAX_FILTER_VALUES,
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
if (!input) {
|
|
10
|
+
return {
|
|
11
|
+
enabled: false,
|
|
12
|
+
maxFilterValues: DEFAULT_MAX_FILTER_VALUES,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
enabled: input.enabled ?? true,
|
|
17
|
+
maxFilterValues: Number.isFinite(input.maxFilterValues)
|
|
18
|
+
? Math.max(20, Math.trunc(input.maxFilterValues))
|
|
19
|
+
: DEFAULT_MAX_FILTER_VALUES,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DataGridColumnSnapshot, DataGridRowId } from "@affino/datagrid-vue";
|
|
2
|
+
export interface DataGridCellEditablePredicateContext<TRow> {
|
|
3
|
+
row: TRow;
|
|
4
|
+
rowId: DataGridRowId;
|
|
5
|
+
rowIndex: number;
|
|
6
|
+
column: DataGridColumnSnapshot["column"];
|
|
7
|
+
columnKey: string;
|
|
8
|
+
}
|
|
9
|
+
export type DataGridCellEditablePredicate<TRow> = (ctx: DataGridCellEditablePredicateContext<TRow>) => boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./overlays/dataGridFilterableCombobox";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./overlays/dataGridFilterableCombobox";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./config/dataGridFormulaOptions";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./config/dataGridFormulaOptions";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export type DataGridAppViewMode = "table" | "gantt";
|
|
2
|
+
export { DAY_MS, addDataGridWorkingDays, applyDataGridGanttDragDelta, buildDataGridGanttDependencyPaths, buildDataGridGanttRowEditPatch, buildDataGridNonWorkingDaySpans, buildDataGridTimelineModel, buildDataGridTimelineRenderModels, buildDataGridGanttVisibleBars, clampDataGridGanttScrollLeft, clampDataGridTimelineScrollLeft, formatDataGridGanttDayLabel, hitTestDataGridGanttBar, isDataGridWorkingDay, normalizeDataGridGanttOptions, resolveDataGridGanttDateOffset, resolveDataGridGanttDateMs, resolveDataGridGanttDependencies, resolveDataGridGanttDependencyRefs, resolveDataGridGanttProgress, resolveDataGridGanttRangeFrame, resolveDataGridGanttSnapDays, resolveDataGridGanttCriticalTaskIds, resolveDataGridGanttScrollLeftForDate, resolveDataGridGanttTimelineState, resolveDataGridWorkingCalendar, snapDataGridGanttDateMs, snapDataGridGanttDayDelta, snapDataGridDateToWorkingDay, startOfUtcDay, startOfUtcWeek, resolveDataGridTimelineDateToPixel, resolveDataGridTimelinePixelToDate, resolveDataGridTimelineRange, resolveDataGridTimelineScrollLeftForDate, resolveDataGridTimelineViewport, } from "@affino/datagrid-gantt";
|
|
3
|
+
export type { BuildDataGridGanttDependencyPathsInput, BuildDataGridGanttVisibleBarsInput, BuildDataGridTimelineModelInput, BuildDataGridTimelineRenderModelsInput, DataGridGanttBarFrame, DataGridGanttBarLayout, DataGridGanttCriticalTaskNode, DataGridGanttDependencyPath, DataGridGanttDependencyRef, DataGridGanttDependencyType, DataGridGanttDependencyValue, DataGridGanttDragRange, DataGridGanttHorizontalAlign, DataGridGanttHitMode, DataGridGanttHitTarget, DataGridGanttOptions, DataGridGanttProp, DataGridGanttRowEditPatch, DataGridGanttRowReader, DataGridGanttTimelineState, DataGridGanttZoomLevel, DataGridResolvedGanttOptions, DataGridResolvedWorkingCalendar, DataGridTimelineHorizontalAlign, DataGridTimelineLine, DataGridTimelineModel, DataGridTimelineRange, DataGridTimelineRenderModels, DataGridTimelineSegment, DataGridTimelineSpan, DataGridTimelineViewport, DataGridWorkingCalendar, ResolveDataGridTimelineRangeInput, } from "@affino/datagrid-gantt";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DAY_MS, addDataGridWorkingDays, applyDataGridGanttDragDelta, buildDataGridGanttDependencyPaths, buildDataGridGanttRowEditPatch, buildDataGridNonWorkingDaySpans, buildDataGridTimelineModel, buildDataGridTimelineRenderModels, buildDataGridGanttVisibleBars, clampDataGridGanttScrollLeft, clampDataGridTimelineScrollLeft, formatDataGridGanttDayLabel, hitTestDataGridGanttBar, isDataGridWorkingDay, normalizeDataGridGanttOptions, resolveDataGridGanttDateOffset, resolveDataGridGanttDateMs, resolveDataGridGanttDependencies, resolveDataGridGanttDependencyRefs, resolveDataGridGanttProgress, resolveDataGridGanttRangeFrame, resolveDataGridGanttSnapDays, resolveDataGridGanttCriticalTaskIds, resolveDataGridGanttScrollLeftForDate, resolveDataGridGanttTimelineState, resolveDataGridWorkingCalendar, snapDataGridGanttDateMs, snapDataGridGanttDayDelta, snapDataGridDateToWorkingDay, startOfUtcDay, startOfUtcWeek, resolveDataGridTimelineDateToPixel, resolveDataGridTimelinePixelToDate, resolveDataGridTimelineRange, resolveDataGridTimelineScrollLeftForDate, resolveDataGridTimelineViewport, } from "@affino/datagrid-gantt";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { DataGridGanttDependencyPath } from "./dataGridGantt";
|
|
2
|
+
export declare const DATAGRID_GANTT_DEPENDENCY_HIT_SLOP_PX = 6;
|
|
3
|
+
export declare function resolveDataGridGanttDependencyPathKey<TRow>(path: Pick<DataGridGanttDependencyPath<TRow>, "dependencyTaskId" | "dependencyType" | "sourceBar" | "targetBar">): string;
|
|
4
|
+
export declare function hitTestDataGridGanttDependencyPath<TRow>(paths: readonly DataGridGanttDependencyPath<TRow>[], point: {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
}, hitSlopPx?: number): DataGridGanttDependencyPath<TRow> | null;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export const DATAGRID_GANTT_DEPENDENCY_HIT_SLOP_PX = 6;
|
|
2
|
+
export function resolveDataGridGanttDependencyPathKey(path) {
|
|
3
|
+
return [
|
|
4
|
+
path.dependencyTaskId,
|
|
5
|
+
path.dependencyType,
|
|
6
|
+
path.sourceBar.rowId,
|
|
7
|
+
path.targetBar.rowId,
|
|
8
|
+
].join("::");
|
|
9
|
+
}
|
|
10
|
+
function resolveSquaredDistanceToSegment(point, start, end) {
|
|
11
|
+
const dx = end.x - start.x;
|
|
12
|
+
const dy = end.y - start.y;
|
|
13
|
+
if (dx === 0 && dy === 0) {
|
|
14
|
+
const distanceX = point.x - start.x;
|
|
15
|
+
const distanceY = point.y - start.y;
|
|
16
|
+
return (distanceX * distanceX) + (distanceY * distanceY);
|
|
17
|
+
}
|
|
18
|
+
const projection = (((point.x - start.x) * dx) + ((point.y - start.y) * dy)) / ((dx * dx) + (dy * dy));
|
|
19
|
+
const clampedProjection = Math.max(0, Math.min(1, projection));
|
|
20
|
+
const closestX = start.x + (dx * clampedProjection);
|
|
21
|
+
const closestY = start.y + (dy * clampedProjection);
|
|
22
|
+
const distanceX = point.x - closestX;
|
|
23
|
+
const distanceY = point.y - closestY;
|
|
24
|
+
return (distanceX * distanceX) + (distanceY * distanceY);
|
|
25
|
+
}
|
|
26
|
+
export function hitTestDataGridGanttDependencyPath(paths, point, hitSlopPx = DATAGRID_GANTT_DEPENDENCY_HIT_SLOP_PX) {
|
|
27
|
+
const maxDistanceSquared = Math.max(1, hitSlopPx) ** 2;
|
|
28
|
+
let bestPath = null;
|
|
29
|
+
let bestDistanceSquared = Number.POSITIVE_INFINITY;
|
|
30
|
+
for (const path of paths) {
|
|
31
|
+
for (let pointIndex = 1; pointIndex < path.points.length; pointIndex += 1) {
|
|
32
|
+
const start = path.points[pointIndex - 1];
|
|
33
|
+
const end = path.points[pointIndex];
|
|
34
|
+
if (!start || !end) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const distanceSquared = resolveSquaredDistanceToSegment(point, start, end);
|
|
38
|
+
if (distanceSquared > maxDistanceSquared || distanceSquared >= bestDistanceSquared) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
bestDistanceSquared = distanceSquared;
|
|
42
|
+
bestPath = path;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return bestPath;
|
|
46
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const DATAGRID_GANTT_MIN_INLINE_LABEL_WIDTH_PX = 44;
|
|
2
|
+
export function resolveDataGridGanttInlineLabel(label, availableWidth, measureTextWidth) {
|
|
3
|
+
const normalizedLabel = label.trim();
|
|
4
|
+
if (normalizedLabel.length === 0 || availableWidth < DATAGRID_GANTT_MIN_INLINE_LABEL_WIDTH_PX) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
if (measureTextWidth(normalizedLabel) <= availableWidth) {
|
|
8
|
+
return normalizedLabel;
|
|
9
|
+
}
|
|
10
|
+
const ellipsis = "...";
|
|
11
|
+
const ellipsisWidth = measureTextWidth(ellipsis);
|
|
12
|
+
if (ellipsisWidth > availableWidth) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
let low = 0;
|
|
16
|
+
let high = normalizedLabel.length;
|
|
17
|
+
let fitted = "";
|
|
18
|
+
while (low <= high) {
|
|
19
|
+
const middle = Math.floor((low + high) / 2);
|
|
20
|
+
const candidate = `${normalizedLabel.slice(0, middle).trimEnd()}${ellipsis}`;
|
|
21
|
+
if (measureTextWidth(candidate) <= availableWidth) {
|
|
22
|
+
fitted = candidate;
|
|
23
|
+
low = middle + 1;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
high = middle - 1;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return fitted.length > 0 ? fitted : null;
|
|
30
|
+
}
|