@mozaic-ds/angular 2.0.43 → 2.0.45
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/fesm2022/mozaic-ds-angular.mjs +1136 -282
- package/fesm2022/mozaic-ds-angular.mjs.map +1 -1
- package/package.json +1 -1
- package/types/mozaic-ds-angular.d.ts +199 -29
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, computed, ChangeDetectionStrategy, Component, contentChild, ViewEncapsulation, signal, forwardRef, output, ContentChild, viewChild, inject, model, InjectionToken, HostListener, Injector, Injectable, TemplateRef, afterNextRender, Directive, linkedSignal, EnvironmentInjector, createComponent, ChangeDetectorRef, NgZone, viewChildren, EventEmitter, effect, Output, ContentChildren, ApplicationRef, Renderer2, ElementRef, Input, booleanAttribute, contentChildren, DestroyRef } from '@angular/core';
|
|
2
|
+
import { input, computed, ChangeDetectionStrategy, Component, contentChild, ViewEncapsulation, signal, forwardRef, output, ContentChild, viewChild, inject, model, InjectionToken, HostListener, Injector, Injectable, TemplateRef, afterNextRender, Directive, linkedSignal, EnvironmentInjector, createComponent, ChangeDetectorRef, NgZone, viewChildren, EventEmitter, effect, Output, ContentChildren, ApplicationRef, Renderer2, ElementRef, Input, booleanAttribute, contentChildren, DestroyRef, untracked } from '@angular/core';
|
|
3
3
|
import { RouterLink, RouterLinkActive, RouterLinkWithHref } from '@angular/router';
|
|
4
4
|
import { NgTemplateOutlet, NgClass, NgComponentOutlet, JsonPipe, DOCUMENT } from '@angular/common';
|
|
5
5
|
import * as i1 from '@angular/forms';
|
|
6
6
|
import { FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
7
|
-
import { WarningCircle32, Uploading32, CheckCircle32, CrossCircleFilled20, Refresh32, Refresh20, Eye20, Upload24, Cross24, ChevronLeft24, ChevronRight24, ChevronLeft20, ChevronRight20, CrossCircleFilled24, More24, Less24, InfoCircle32, CrossCircle32, Cross20, CrossCircle24, ImageAlt32, ChevronDown24, CheckCircleFilled32, WarningCircleFilled32, CrossCircleFilled32, InfoCircleFilled32, SidebarExpand24, ChevronDown20, InfoCircleFilled24, WarningCircleFilled24, CheckCircleFilled24, ArrowBottomRight24, ArrowTopRight24, StarHalf32, StarFilled32, Star32, StarHalf24, StarFilled24, Star24, StarHalf20, StarFilled20, Star20, Check20, Check24, ArrowBack24, ArrowNext24, HelpCircle24, Menu24, Notification24, Search24, PauseCircle24, PlayCircle24,
|
|
7
|
+
import { WarningCircle32, Uploading32, CheckCircle32, CrossCircleFilled20, Refresh32, Refresh20, Eye20, Upload24, Cross24, ChevronLeft24, ChevronRight24, ChevronLeft20, ChevronRight20, CrossCircleFilled24, More24, Less24, InfoCircle32, CrossCircle32, Cross20, CrossCircle24, ImageAlt32, ChevronDown24, CheckCircleFilled32, WarningCircleFilled32, CrossCircleFilled32, InfoCircleFilled32, SidebarExpand24, ChevronDown20, InfoCircleFilled24, WarningCircleFilled24, CheckCircleFilled24, ArrowBottomRight24, ArrowTopRight24, StarHalf32, StarFilled32, Star32, StarHalf24, StarFilled24, Star24, StarHalf20, StarFilled20, Star20, Check20, Check24, ArrowBack24, ArrowNext24, HelpCircle24, Menu24, Notification24, Search24, PauseCircle24, PlayCircle24, Drag20, ListAdd20, ChevronUp20, Filter20, Settings20, ErrorFilled24, ViewGridX420, FullscreenEnter20, FullscreenExit20, Download20, Keyboard20, CheckCircle24 } from '@mozaic-ds/icons-angular';
|
|
8
8
|
import { Overlay, OverlayConfig, OverlayPositionBuilder, CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay';
|
|
9
9
|
import { CdkPortalOutlet, ComponentPortal } from '@angular/cdk/portal';
|
|
10
10
|
import { Subject, take, tap, of, firstValueFrom } from 'rxjs';
|
|
11
11
|
import parsePhoneNumberFromString, { getCountries, getExampleNumber, isValidPhoneNumber, getCountryCallingCode } from 'libphonenumber-js';
|
|
12
12
|
import examples from 'libphonenumber-js/mobile/examples';
|
|
13
|
+
import { moveItemInArray, CdkDropList, CdkDrag, CdkDragHandle } from '@angular/cdk/drag-drop';
|
|
13
14
|
import * as i1$1 from '@angular/cdk/scrolling';
|
|
14
15
|
import { VIRTUAL_SCROLL_STRATEGY, ScrollingModule } from '@angular/cdk/scrolling';
|
|
15
|
-
import { moveItemInArray, CdkDropList, CdkDrag, CdkDragHandle } from '@angular/cdk/drag-drop';
|
|
16
16
|
import { ComponentHarness, TestKey } from '@angular/cdk/testing';
|
|
17
17
|
|
|
18
18
|
class MozBreadcrumbComponent {
|
|
@@ -4887,8 +4887,11 @@ class GridStateManager {
|
|
|
4887
4887
|
groupColumns = signal([], ...(ngDevMode ? [{ debugName: "groupColumns" }] : /* istanbul ignore next */ []));
|
|
4888
4888
|
expandedGroups = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedGroups" }] : /* istanbul ignore next */ []));
|
|
4889
4889
|
// --- Filter ---
|
|
4890
|
-
|
|
4891
|
-
|
|
4890
|
+
/**
|
|
4891
|
+
* Unified filter state: single source of truth for the multi-condition
|
|
4892
|
+
* builder. The tag-bar displays a derived view via `FilterEngine.toLabel()`.
|
|
4893
|
+
*/
|
|
4894
|
+
filterModel = signal({ conditions: [] }, ...(ngDevMode ? [{ debugName: "filterModel" }] : /* istanbul ignore next */ []));
|
|
4892
4895
|
// --- Pagination ---
|
|
4893
4896
|
pageIndex = signal(0, ...(ngDevMode ? [{ debugName: "pageIndex" }] : /* istanbul ignore next */ []));
|
|
4894
4897
|
pageSize = signal(20, ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
|
|
@@ -5168,87 +5171,257 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
5168
5171
|
type: Injectable
|
|
5169
5172
|
}] });
|
|
5170
5173
|
|
|
5174
|
+
/**
|
|
5175
|
+
* Filter model — multi-condition filter builder with AND/OR combinators.
|
|
5176
|
+
*
|
|
5177
|
+
* Evaluation is left-associative (no operator precedence). Grouped / parenthesised
|
|
5178
|
+
* conditions (`(a AND b) OR c`) are out of scope for the MVP; see docs.
|
|
5179
|
+
*/
|
|
5180
|
+
/**
|
|
5181
|
+
* Default operator sets per data type. Consumers can restrict the set via
|
|
5182
|
+
* `ColumnDef.filterOperators`.
|
|
5183
|
+
*/
|
|
5184
|
+
const DEFAULT_OPERATORS = {
|
|
5185
|
+
text: [
|
|
5186
|
+
'contains',
|
|
5187
|
+
'notContains',
|
|
5188
|
+
'equals',
|
|
5189
|
+
'notEquals',
|
|
5190
|
+
'startsWith',
|
|
5191
|
+
'endsWith',
|
|
5192
|
+
'blank',
|
|
5193
|
+
'notBlank',
|
|
5194
|
+
],
|
|
5195
|
+
number: ['equals', 'notEquals', 'gt', 'gte', 'lt', 'lte', 'between', 'blank', 'notBlank'],
|
|
5196
|
+
date: ['equals', 'notEquals', 'gt', 'gte', 'lt', 'lte', 'between', 'blank', 'notBlank'],
|
|
5197
|
+
set: ['in', 'notIn', 'blank', 'notBlank'],
|
|
5198
|
+
boolean: ['equals', 'blank', 'notBlank'],
|
|
5199
|
+
};
|
|
5200
|
+
const DEFAULT_OPERATOR_PER_TYPE = {
|
|
5201
|
+
text: 'contains',
|
|
5202
|
+
number: 'equals',
|
|
5203
|
+
date: 'equals',
|
|
5204
|
+
set: 'in',
|
|
5205
|
+
boolean: 'equals',
|
|
5206
|
+
};
|
|
5207
|
+
/** Human-readable operator labels (used by `toLabel`). */
|
|
5208
|
+
const OPERATOR_LABELS = {
|
|
5209
|
+
contains: 'contains',
|
|
5210
|
+
notContains: 'does not contain',
|
|
5211
|
+
equals: 'equals',
|
|
5212
|
+
notEquals: 'does not equal',
|
|
5213
|
+
startsWith: 'starts with',
|
|
5214
|
+
endsWith: 'ends with',
|
|
5215
|
+
gt: '>',
|
|
5216
|
+
gte: '≥',
|
|
5217
|
+
lt: '<',
|
|
5218
|
+
lte: '≤',
|
|
5219
|
+
between: 'between',
|
|
5220
|
+
in: 'in',
|
|
5221
|
+
notIn: 'not in',
|
|
5222
|
+
blank: 'is blank',
|
|
5223
|
+
notBlank: 'is not blank',
|
|
5224
|
+
};
|
|
5225
|
+
/** Operators that do not require a user-entered value. */
|
|
5226
|
+
const VALUELESS_OPERATORS = new Set([
|
|
5227
|
+
'blank',
|
|
5228
|
+
'notBlank',
|
|
5229
|
+
]);
|
|
5230
|
+
/** Operators that need a secondary value (`between`). */
|
|
5231
|
+
const RANGE_OPERATORS = new Set(['between']);
|
|
5232
|
+
/** Small helper for generating condition ids without pulling in a uuid dep. */
|
|
5233
|
+
function generateConditionId() {
|
|
5234
|
+
return `cond-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
5235
|
+
}
|
|
5236
|
+
/** True when a condition has enough information to participate in evaluation. */
|
|
5237
|
+
function isConditionComplete(condition) {
|
|
5238
|
+
if (!condition.field)
|
|
5239
|
+
return false;
|
|
5240
|
+
if (VALUELESS_OPERATORS.has(condition.operator))
|
|
5241
|
+
return true;
|
|
5242
|
+
const { value, valueTo } = condition.value;
|
|
5243
|
+
if (value == null || value === '')
|
|
5244
|
+
return false;
|
|
5245
|
+
if (RANGE_OPERATORS.has(condition.operator)) {
|
|
5246
|
+
if (valueTo == null || valueTo === '')
|
|
5247
|
+
return false;
|
|
5248
|
+
}
|
|
5249
|
+
return true;
|
|
5250
|
+
}
|
|
5251
|
+
|
|
5171
5252
|
class FilterEngine {
|
|
5172
5253
|
state = inject(GridStateManager);
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
});
|
|
5191
|
-
this.state.
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5254
|
+
/** Latest mutation, used by the grid shell to emit `filterChange` once. */
|
|
5255
|
+
lastChange = signal(null, ...(ngDevMode ? [{ debugName: "lastChange" }] : /* istanbul ignore next */ []));
|
|
5256
|
+
conditions = computed(() => this.state.filterModel().conditions, ...(ngDevMode ? [{ debugName: "conditions" }] : /* istanbul ignore next */ []));
|
|
5257
|
+
hasActiveFilters = computed(() => this.conditions().length > 0, ...(ngDevMode ? [{ debugName: "hasActiveFilters" }] : /* istanbul ignore next */ []));
|
|
5258
|
+
lastEvent = this.lastChange.asReadonly();
|
|
5259
|
+
// ------------------------------------------------------------------
|
|
5260
|
+
// Mutations
|
|
5261
|
+
// ------------------------------------------------------------------
|
|
5262
|
+
/** Replaces the whole model in one go. Used by the drawer's Apply button. */
|
|
5263
|
+
setModel(model, reason = 'replace') {
|
|
5264
|
+
this.state.filterModel.set({ conditions: [...model.conditions] });
|
|
5265
|
+
this.state.pageIndex.set(0);
|
|
5266
|
+
this.notify(reason, null);
|
|
5267
|
+
}
|
|
5268
|
+
addCondition(condition) {
|
|
5269
|
+
this.state.filterModel.update((m) => ({
|
|
5270
|
+
conditions: [...m.conditions, condition],
|
|
5271
|
+
}));
|
|
5272
|
+
this.state.pageIndex.set(0);
|
|
5273
|
+
this.notify('add', condition);
|
|
5274
|
+
}
|
|
5275
|
+
updateCondition(id, patch) {
|
|
5276
|
+
let updated = null;
|
|
5277
|
+
this.state.filterModel.update((m) => ({
|
|
5278
|
+
conditions: m.conditions.map((c) => {
|
|
5279
|
+
if (c.id !== id)
|
|
5280
|
+
return c;
|
|
5281
|
+
const next = { ...c, ...patch, value: { ...c.value, ...(patch.value ?? {}) } };
|
|
5282
|
+
updated = next;
|
|
5197
5283
|
return next;
|
|
5198
|
-
}
|
|
5199
|
-
|
|
5284
|
+
}),
|
|
5285
|
+
}));
|
|
5286
|
+
this.state.pageIndex.set(0);
|
|
5287
|
+
if (updated)
|
|
5288
|
+
this.notify('update', updated);
|
|
5289
|
+
}
|
|
5290
|
+
removeCondition(id) {
|
|
5291
|
+
const removed = this.state.filterModel().conditions.find((c) => c.id === id) ?? null;
|
|
5292
|
+
this.state.filterModel.update((m) => ({
|
|
5293
|
+
conditions: m.conditions.filter((c) => c.id !== id),
|
|
5294
|
+
}));
|
|
5295
|
+
this.state.pageIndex.set(0);
|
|
5296
|
+
this.notify('remove', removed);
|
|
5297
|
+
}
|
|
5298
|
+
reorderConditions(fromIndex, toIndex) {
|
|
5299
|
+
this.state.filterModel.update((m) => {
|
|
5300
|
+
if (fromIndex === toIndex)
|
|
5301
|
+
return m;
|
|
5302
|
+
const next = [...m.conditions];
|
|
5303
|
+
const [item] = next.splice(fromIndex, 1);
|
|
5304
|
+
if (!item)
|
|
5305
|
+
return m;
|
|
5306
|
+
next.splice(toIndex, 0, item);
|
|
5307
|
+
return { conditions: next };
|
|
5200
5308
|
});
|
|
5201
5309
|
this.state.pageIndex.set(0);
|
|
5310
|
+
this.notify('reorder', null);
|
|
5202
5311
|
}
|
|
5203
|
-
|
|
5204
|
-
this.state.
|
|
5205
|
-
|
|
5312
|
+
clearAll() {
|
|
5313
|
+
if (this.state.filterModel().conditions.length === 0)
|
|
5314
|
+
return;
|
|
5315
|
+
this.state.filterModel.set({ conditions: [] });
|
|
5206
5316
|
this.state.pageIndex.set(0);
|
|
5317
|
+
this.notify('clear', null);
|
|
5207
5318
|
}
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
this.state.
|
|
5319
|
+
/** Convenience: drop all conditions that target a given field. */
|
|
5320
|
+
removeByField(field) {
|
|
5321
|
+
const before = this.state.filterModel().conditions;
|
|
5322
|
+
const after = before.filter((c) => c.field !== field);
|
|
5323
|
+
if (after.length === before.length)
|
|
5324
|
+
return;
|
|
5325
|
+
this.state.filterModel.set({ conditions: after });
|
|
5211
5326
|
this.state.pageIndex.set(0);
|
|
5327
|
+
this.notify('replace', null);
|
|
5212
5328
|
}
|
|
5329
|
+
// ------------------------------------------------------------------
|
|
5330
|
+
// Evaluation
|
|
5331
|
+
// ------------------------------------------------------------------
|
|
5332
|
+
/**
|
|
5333
|
+
* Evaluates the current model against the provided data. In `server` mode,
|
|
5334
|
+
* the grid delegates filtering to the consumer so we return the input as-is.
|
|
5335
|
+
*/
|
|
5213
5336
|
filterData(data) {
|
|
5214
|
-
|
|
5215
|
-
|
|
5337
|
+
if (this.state.mode() === 'server')
|
|
5338
|
+
return data;
|
|
5339
|
+
const conditions = this.state.filterModel().conditions.filter(isConditionComplete);
|
|
5340
|
+
if (conditions.length === 0)
|
|
5216
5341
|
return data;
|
|
5217
5342
|
const defMap = this.state.columnDefMap();
|
|
5343
|
+
const prepared = conditions.map((c) => ({
|
|
5344
|
+
cond: c,
|
|
5345
|
+
col: defMap.get(c.field),
|
|
5346
|
+
type: resolveFilterType(defMap.get(c.field)),
|
|
5347
|
+
}));
|
|
5218
5348
|
return data.filter((row) => {
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
const
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5349
|
+
let pass = matchOne(row, prepared[0].cond, prepared[0].col, prepared[0].type);
|
|
5350
|
+
for (let i = 1; i < prepared.length; i++) {
|
|
5351
|
+
const step = prepared[i];
|
|
5352
|
+
const result = matchOne(row, step.cond, step.col, step.type);
|
|
5353
|
+
pass = step.cond.combinator === 'and' ? pass && result : pass || result;
|
|
5354
|
+
}
|
|
5355
|
+
return pass;
|
|
5226
5356
|
});
|
|
5227
5357
|
}
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
const
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
return strValue === strFilter;
|
|
5239
|
-
case 'startsWith':
|
|
5240
|
-
return strValue.startsWith(strFilter);
|
|
5241
|
-
case 'gt':
|
|
5242
|
-
return Number(value) > Number(filterValue);
|
|
5243
|
-
case 'lt':
|
|
5244
|
-
return Number(value) < Number(filterValue);
|
|
5245
|
-
case 'in': {
|
|
5246
|
-
const arr = Array.isArray(filterValue) ? filterValue : [filterValue];
|
|
5247
|
-
return arr.some((v) => String(v).toLowerCase() === strValue);
|
|
5248
|
-
}
|
|
5249
|
-
default:
|
|
5250
|
-
return true;
|
|
5358
|
+
// ------------------------------------------------------------------
|
|
5359
|
+
// Helpers
|
|
5360
|
+
// ------------------------------------------------------------------
|
|
5361
|
+
/** Returns a human-readable label for a condition ("Status equals En stock"). */
|
|
5362
|
+
toLabel(condition) {
|
|
5363
|
+
const def = this.state.columnDefMap().get(condition.field);
|
|
5364
|
+
const col = def?.headerName ?? condition.field;
|
|
5365
|
+
const op = OPERATOR_LABELS[condition.operator] ?? condition.operator;
|
|
5366
|
+
if (VALUELESS_OPERATORS.has(condition.operator)) {
|
|
5367
|
+
return `${col} ${op}`;
|
|
5251
5368
|
}
|
|
5369
|
+
const value = formatValue(condition.value.value, def);
|
|
5370
|
+
if (RANGE_OPERATORS.has(condition.operator)) {
|
|
5371
|
+
const to = formatValue(condition.value.valueTo, def);
|
|
5372
|
+
return `${col} ${op} ${value} – ${to}`;
|
|
5373
|
+
}
|
|
5374
|
+
return `${col} ${op} ${value}`;
|
|
5375
|
+
}
|
|
5376
|
+
/** Returns the filter data type inferred for a column. */
|
|
5377
|
+
getFilterType(field) {
|
|
5378
|
+
return resolveFilterType(this.state.columnDefMap().get(field));
|
|
5379
|
+
}
|
|
5380
|
+
/**
|
|
5381
|
+
* Builds the column descriptors consumed by the filter builder UI. The
|
|
5382
|
+
* returned list includes only filterable columns.
|
|
5383
|
+
*/
|
|
5384
|
+
describeFilterableColumns() {
|
|
5385
|
+
const defs = this.state.columnDefs();
|
|
5386
|
+
return defs.filter((d) => d.filterable && !d.filterTemplate).map((d) => this.describeColumn(d));
|
|
5387
|
+
}
|
|
5388
|
+
describeColumn(def) {
|
|
5389
|
+
const type = resolveFilterType(def);
|
|
5390
|
+
const operators = def.filterOperators && def.filterOperators.length > 0
|
|
5391
|
+
? def.filterOperators
|
|
5392
|
+
: DEFAULT_OPERATORS[type];
|
|
5393
|
+
const defaultOp = def.defaultFilterOperator ?? DEFAULT_OPERATOR_PER_TYPE[type];
|
|
5394
|
+
return {
|
|
5395
|
+
field: def.field,
|
|
5396
|
+
headerName: def.headerName ?? def.field,
|
|
5397
|
+
filterType: type,
|
|
5398
|
+
operators,
|
|
5399
|
+
defaultOperator: operators.includes(defaultOp) ? defaultOp : operators[0],
|
|
5400
|
+
options: def.filterOptions ?? inferOptionsFromData(this.state.sourceData(), def, type),
|
|
5401
|
+
};
|
|
5402
|
+
}
|
|
5403
|
+
/** Factory for new conditions created by the UI. */
|
|
5404
|
+
makeCondition(field, isFirst, overrides = {}) {
|
|
5405
|
+
const def = this.state.columnDefMap().get(field);
|
|
5406
|
+
const descriptor = def ? this.describeColumn(def) : null;
|
|
5407
|
+
return {
|
|
5408
|
+
id: generateConditionId(),
|
|
5409
|
+
combinator: isFirst ? 'and' : 'and',
|
|
5410
|
+
field,
|
|
5411
|
+
operator: descriptor?.defaultOperator ?? 'contains',
|
|
5412
|
+
value: {},
|
|
5413
|
+
...overrides,
|
|
5414
|
+
};
|
|
5415
|
+
}
|
|
5416
|
+
// ------------------------------------------------------------------
|
|
5417
|
+
// Internal
|
|
5418
|
+
// ------------------------------------------------------------------
|
|
5419
|
+
notify(reason, condition) {
|
|
5420
|
+
this.lastChange.set({
|
|
5421
|
+
model: { conditions: this.state.filterModel().conditions.slice() },
|
|
5422
|
+
condition,
|
|
5423
|
+
reason,
|
|
5424
|
+
});
|
|
5252
5425
|
}
|
|
5253
5426
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FilterEngine, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
5254
5427
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FilterEngine });
|
|
@@ -5256,6 +5429,181 @@ class FilterEngine {
|
|
|
5256
5429
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FilterEngine, decorators: [{
|
|
5257
5430
|
type: Injectable
|
|
5258
5431
|
}] });
|
|
5432
|
+
// --------------------------------------------------------------------
|
|
5433
|
+
// Pure helpers
|
|
5434
|
+
// --------------------------------------------------------------------
|
|
5435
|
+
function resolveFilterType(def) {
|
|
5436
|
+
if (!def)
|
|
5437
|
+
return 'text';
|
|
5438
|
+
if (def.filterType)
|
|
5439
|
+
return def.filterType;
|
|
5440
|
+
switch (def.cellEditor) {
|
|
5441
|
+
case 'number':
|
|
5442
|
+
return 'number';
|
|
5443
|
+
case 'date':
|
|
5444
|
+
return 'date';
|
|
5445
|
+
case 'select':
|
|
5446
|
+
return 'set';
|
|
5447
|
+
case 'checkbox':
|
|
5448
|
+
case 'toggle':
|
|
5449
|
+
return 'boolean';
|
|
5450
|
+
default:
|
|
5451
|
+
return 'text';
|
|
5452
|
+
}
|
|
5453
|
+
}
|
|
5454
|
+
function matchOne(row, condition, col, type) {
|
|
5455
|
+
const raw = col?.valueGetter
|
|
5456
|
+
? col.valueGetter(row)
|
|
5457
|
+
: row[condition.field];
|
|
5458
|
+
const predicate = PREDICATES[type]?.[condition.operator];
|
|
5459
|
+
if (!predicate)
|
|
5460
|
+
return true;
|
|
5461
|
+
return predicate(raw, condition.value);
|
|
5462
|
+
}
|
|
5463
|
+
function formatValue(value, def) {
|
|
5464
|
+
if (value == null || value === '')
|
|
5465
|
+
return '';
|
|
5466
|
+
if (Array.isArray(value)) {
|
|
5467
|
+
return value.map((v) => formatSingleOption(v, def)).join(', ');
|
|
5468
|
+
}
|
|
5469
|
+
return formatSingleOption(value, def);
|
|
5470
|
+
}
|
|
5471
|
+
function formatSingleOption(value, def) {
|
|
5472
|
+
if (def?.filterOptions) {
|
|
5473
|
+
const opt = def.filterOptions.find((o) => String(o.value) === String(value));
|
|
5474
|
+
if (opt)
|
|
5475
|
+
return String(opt.label);
|
|
5476
|
+
}
|
|
5477
|
+
return String(value);
|
|
5478
|
+
}
|
|
5479
|
+
function inferOptionsFromData(data, def, type) {
|
|
5480
|
+
if (type !== 'set')
|
|
5481
|
+
return undefined;
|
|
5482
|
+
const seen = new Set();
|
|
5483
|
+
const out = [];
|
|
5484
|
+
for (const row of data) {
|
|
5485
|
+
const v = def.valueGetter ? def.valueGetter(row) : row[def.field];
|
|
5486
|
+
if (v == null)
|
|
5487
|
+
continue;
|
|
5488
|
+
const key = String(v);
|
|
5489
|
+
if (seen.has(key))
|
|
5490
|
+
continue;
|
|
5491
|
+
seen.add(key);
|
|
5492
|
+
out.push({ value: v, label: key });
|
|
5493
|
+
if (out.length >= 200)
|
|
5494
|
+
break;
|
|
5495
|
+
}
|
|
5496
|
+
return out;
|
|
5497
|
+
}
|
|
5498
|
+
// --------------------------------------------------------------------
|
|
5499
|
+
// Predicate table — dispatched by (filterType, operator)
|
|
5500
|
+
// --------------------------------------------------------------------
|
|
5501
|
+
const textContains = (cell, { value }) => String(cell ?? '')
|
|
5502
|
+
.toLowerCase()
|
|
5503
|
+
.includes(String(value ?? '').toLowerCase());
|
|
5504
|
+
const textNotContains = (cell, v) => !textContains(cell, v);
|
|
5505
|
+
const textEquals = (cell, { value }) => String(cell ?? '').toLowerCase() === String(value ?? '').toLowerCase();
|
|
5506
|
+
const textNotEquals = (cell, v) => !textEquals(cell, v);
|
|
5507
|
+
const textStartsWith = (cell, { value }) => String(cell ?? '')
|
|
5508
|
+
.toLowerCase()
|
|
5509
|
+
.startsWith(String(value ?? '').toLowerCase());
|
|
5510
|
+
const textEndsWith = (cell, { value }) => String(cell ?? '')
|
|
5511
|
+
.toLowerCase()
|
|
5512
|
+
.endsWith(String(value ?? '').toLowerCase());
|
|
5513
|
+
const blank = (cell) => cell == null || cell === '';
|
|
5514
|
+
const notBlank = (cell) => !blank(cell, { value: undefined });
|
|
5515
|
+
const numEquals = (cell, { value }) => toNum(cell) === toNum(value);
|
|
5516
|
+
const numNotEquals = (cell, v) => !numEquals(cell, v);
|
|
5517
|
+
const numGt = (cell, { value }) => toNum(cell) > toNum(value);
|
|
5518
|
+
const numGte = (cell, { value }) => toNum(cell) >= toNum(value);
|
|
5519
|
+
const numLt = (cell, { value }) => toNum(cell) < toNum(value);
|
|
5520
|
+
const numLte = (cell, { value }) => toNum(cell) <= toNum(value);
|
|
5521
|
+
const numBetween = (cell, { value, valueTo }) => {
|
|
5522
|
+
const n = toNum(cell);
|
|
5523
|
+
return n >= toNum(value) && n <= toNum(valueTo);
|
|
5524
|
+
};
|
|
5525
|
+
const dateEquals = (cell, { value }) => toTime(cell) === toTime(value);
|
|
5526
|
+
const dateNotEquals = (cell, v) => !dateEquals(cell, v);
|
|
5527
|
+
const dateGt = (cell, { value }) => toTime(cell) > toTime(value);
|
|
5528
|
+
const dateGte = (cell, { value }) => toTime(cell) >= toTime(value);
|
|
5529
|
+
const dateLt = (cell, { value }) => toTime(cell) < toTime(value);
|
|
5530
|
+
const dateLte = (cell, { value }) => toTime(cell) <= toTime(value);
|
|
5531
|
+
const dateBetween = (cell, { value, valueTo }) => {
|
|
5532
|
+
const t = toTime(cell);
|
|
5533
|
+
return t >= toTime(value) && t <= toTime(valueTo);
|
|
5534
|
+
};
|
|
5535
|
+
const setIn = (cell, { value }) => {
|
|
5536
|
+
const arr = Array.isArray(value) ? value : [value];
|
|
5537
|
+
if (arr.length === 0)
|
|
5538
|
+
return true;
|
|
5539
|
+
return arr.some((v) => String(v) === String(cell));
|
|
5540
|
+
};
|
|
5541
|
+
const setNotIn = (cell, v) => !setIn(cell, v);
|
|
5542
|
+
const boolEquals = (cell, { value }) => {
|
|
5543
|
+
const expected = value === true || value === 'true' || value === 1;
|
|
5544
|
+
const actual = cell === true || cell === 'true' || cell === 1;
|
|
5545
|
+
return expected === actual;
|
|
5546
|
+
};
|
|
5547
|
+
function toNum(v) {
|
|
5548
|
+
const n = typeof v === 'number' ? v : Number(v);
|
|
5549
|
+
return Number.isFinite(n) ? n : NaN;
|
|
5550
|
+
}
|
|
5551
|
+
function toTime(v) {
|
|
5552
|
+
if (v instanceof Date)
|
|
5553
|
+
return v.getTime();
|
|
5554
|
+
if (typeof v === 'number')
|
|
5555
|
+
return v;
|
|
5556
|
+
if (typeof v === 'string') {
|
|
5557
|
+
const parsed = Date.parse(v);
|
|
5558
|
+
return Number.isFinite(parsed) ? parsed : NaN;
|
|
5559
|
+
}
|
|
5560
|
+
return NaN;
|
|
5561
|
+
}
|
|
5562
|
+
const PREDICATES = {
|
|
5563
|
+
text: {
|
|
5564
|
+
contains: textContains,
|
|
5565
|
+
notContains: textNotContains,
|
|
5566
|
+
equals: textEquals,
|
|
5567
|
+
notEquals: textNotEquals,
|
|
5568
|
+
startsWith: textStartsWith,
|
|
5569
|
+
endsWith: textEndsWith,
|
|
5570
|
+
blank,
|
|
5571
|
+
notBlank,
|
|
5572
|
+
},
|
|
5573
|
+
number: {
|
|
5574
|
+
equals: numEquals,
|
|
5575
|
+
notEquals: numNotEquals,
|
|
5576
|
+
gt: numGt,
|
|
5577
|
+
gte: numGte,
|
|
5578
|
+
lt: numLt,
|
|
5579
|
+
lte: numLte,
|
|
5580
|
+
between: numBetween,
|
|
5581
|
+
blank,
|
|
5582
|
+
notBlank,
|
|
5583
|
+
},
|
|
5584
|
+
date: {
|
|
5585
|
+
equals: dateEquals,
|
|
5586
|
+
notEquals: dateNotEquals,
|
|
5587
|
+
gt: dateGt,
|
|
5588
|
+
gte: dateGte,
|
|
5589
|
+
lt: dateLt,
|
|
5590
|
+
lte: dateLte,
|
|
5591
|
+
between: dateBetween,
|
|
5592
|
+
blank,
|
|
5593
|
+
notBlank,
|
|
5594
|
+
},
|
|
5595
|
+
set: {
|
|
5596
|
+
in: setIn,
|
|
5597
|
+
notIn: setNotIn,
|
|
5598
|
+
blank,
|
|
5599
|
+
notBlank,
|
|
5600
|
+
},
|
|
5601
|
+
boolean: {
|
|
5602
|
+
equals: boolEquals,
|
|
5603
|
+
blank,
|
|
5604
|
+
notBlank,
|
|
5605
|
+
},
|
|
5606
|
+
};
|
|
5259
5607
|
|
|
5260
5608
|
class GroupEngine {
|
|
5261
5609
|
state = inject(GridStateManager);
|
|
@@ -5458,6 +5806,19 @@ class GridEngine {
|
|
|
5458
5806
|
return this.state.totalItems();
|
|
5459
5807
|
return this.filteredData().length;
|
|
5460
5808
|
}, ...(ngDevMode ? [{ debugName: "computedTotalItems" }] : /* istanbul ignore next */ []));
|
|
5809
|
+
/**
|
|
5810
|
+
* Resolves a display row index (as emitted via `DisplayRow.index`) to the
|
|
5811
|
+
* actual index in `sourceData()`. When sort/filter/group is active these do
|
|
5812
|
+
* not match, so we look up the display row's data object and search for it
|
|
5813
|
+
* in sourceData. Returns -1 when the display index is unknown.
|
|
5814
|
+
*/
|
|
5815
|
+
displayIndexToSourceIndex(displayIndex) {
|
|
5816
|
+
const rows = this.displayRows();
|
|
5817
|
+
const row = rows.find((r) => r.type === 'data' && r.index === displayIndex);
|
|
5818
|
+
if (!row || row.type !== 'data')
|
|
5819
|
+
return -1;
|
|
5820
|
+
return this.state.sourceData().indexOf(row.data);
|
|
5821
|
+
}
|
|
5461
5822
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GridEngine, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
5462
5823
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GridEngine });
|
|
5463
5824
|
}
|
|
@@ -5527,7 +5888,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
5527
5888
|
type: Injectable
|
|
5528
5889
|
}] });
|
|
5529
5890
|
|
|
5530
|
-
const PASTE_SKIP
|
|
5891
|
+
const PASTE_SKIP = Symbol('PASTE_SKIP');
|
|
5531
5892
|
/**
|
|
5532
5893
|
* Applies a set of cell-level mutations to sourceData and returns the list of
|
|
5533
5894
|
* actual changes that occurred, so the caller (usually the history engine) can
|
|
@@ -5535,8 +5896,23 @@ const PASTE_SKIP$1 = Symbol('PASTE_SKIP');
|
|
|
5535
5896
|
*/
|
|
5536
5897
|
class ClipboardEngine {
|
|
5537
5898
|
state = inject(GridStateManager);
|
|
5899
|
+
gridEngine = inject(GridEngine);
|
|
5538
5900
|
/** Derived by components (marching-ants outline). */
|
|
5539
5901
|
cutRange = computed(() => this.state.cutSource(), ...(ngDevMode ? [{ debugName: "cutRange" }] : /* istanbul ignore next */ []));
|
|
5902
|
+
/**
|
|
5903
|
+
* Maps every display row index inside `range` to its actual sourceData
|
|
5904
|
+
* index. Unknown indices (e.g. outside the current page) are skipped so
|
|
5905
|
+
* callers can safely iterate only over rows that exist in sourceData.
|
|
5906
|
+
*/
|
|
5907
|
+
resolveRangeSourceIndices(range) {
|
|
5908
|
+
const out = [];
|
|
5909
|
+
for (let r = range.start.row; r <= range.end.row; r++) {
|
|
5910
|
+
const srcIdx = this.gridEngine.displayIndexToSourceIndex(r);
|
|
5911
|
+
if (srcIdx >= 0)
|
|
5912
|
+
out.push(srcIdx);
|
|
5913
|
+
}
|
|
5914
|
+
return out;
|
|
5915
|
+
}
|
|
5540
5916
|
markCut(range) {
|
|
5541
5917
|
this.state.cutSource.set(range);
|
|
5542
5918
|
}
|
|
@@ -5550,15 +5926,19 @@ class ClipboardEngine {
|
|
|
5550
5926
|
const cols = this.state.visibleColumns();
|
|
5551
5927
|
const defMap = this.state.columnDefMap();
|
|
5552
5928
|
const changes = [];
|
|
5929
|
+
const sourceIndices = this.resolveRangeSourceIndices(range);
|
|
5930
|
+
if (sourceIndices.length < 2)
|
|
5931
|
+
return [];
|
|
5932
|
+
const [sourceIdx, ...targetIndices] = sourceIndices;
|
|
5553
5933
|
this.state.sourceData.update((data) => {
|
|
5554
5934
|
const updated = [...data];
|
|
5555
|
-
const sourceRow = updated[
|
|
5935
|
+
const sourceRow = updated[sourceIdx];
|
|
5556
5936
|
if (!sourceRow)
|
|
5557
5937
|
return updated;
|
|
5558
|
-
for (
|
|
5559
|
-
if (!updated[
|
|
5938
|
+
for (const targetIdx of targetIndices) {
|
|
5939
|
+
if (!updated[targetIdx])
|
|
5560
5940
|
continue;
|
|
5561
|
-
const rowCopy = { ...updated[
|
|
5941
|
+
const rowCopy = { ...updated[targetIdx] };
|
|
5562
5942
|
let changed = false;
|
|
5563
5943
|
for (let c = range.start.col; c <= range.end.col; c++) {
|
|
5564
5944
|
const field = cols[c]?.field;
|
|
@@ -5570,18 +5950,18 @@ class ClipboardEngine {
|
|
|
5570
5950
|
const sourceValue = def.valueGetter
|
|
5571
5951
|
? def.valueGetter(sourceRow)
|
|
5572
5952
|
: sourceRow[field];
|
|
5573
|
-
const coerced = this.coerceAndValidate(field, sourceValue, updated[
|
|
5574
|
-
if (coerced === PASTE_SKIP
|
|
5953
|
+
const coerced = this.coerceAndValidate(field, sourceValue, updated[targetIdx]);
|
|
5954
|
+
if (coerced === PASTE_SKIP)
|
|
5575
5955
|
continue;
|
|
5576
|
-
const before = updated[
|
|
5956
|
+
const before = updated[targetIdx][field];
|
|
5577
5957
|
if (before === coerced)
|
|
5578
5958
|
continue;
|
|
5579
5959
|
rowCopy[field] = coerced;
|
|
5580
|
-
changes.push({ rowIndex:
|
|
5960
|
+
changes.push({ rowIndex: targetIdx, field, before, after: coerced });
|
|
5581
5961
|
changed = true;
|
|
5582
5962
|
}
|
|
5583
5963
|
if (changed)
|
|
5584
|
-
updated[
|
|
5964
|
+
updated[targetIdx] = rowCopy;
|
|
5585
5965
|
}
|
|
5586
5966
|
return updated;
|
|
5587
5967
|
});
|
|
@@ -5600,10 +5980,11 @@ class ClipboardEngine {
|
|
|
5600
5980
|
if (!sourceDef)
|
|
5601
5981
|
return [];
|
|
5602
5982
|
const changes = [];
|
|
5983
|
+
const sourceIndices = this.resolveRangeSourceIndices(range);
|
|
5603
5984
|
this.state.sourceData.update((data) => {
|
|
5604
5985
|
const updated = [...data];
|
|
5605
|
-
for (
|
|
5606
|
-
const row = updated[
|
|
5986
|
+
for (const sourceIdx of sourceIndices) {
|
|
5987
|
+
const row = updated[sourceIdx];
|
|
5607
5988
|
if (!row)
|
|
5608
5989
|
continue;
|
|
5609
5990
|
const sourceValue = sourceDef.valueGetter
|
|
@@ -5619,17 +6000,17 @@ class ClipboardEngine {
|
|
|
5619
6000
|
if (!def?.editable)
|
|
5620
6001
|
continue;
|
|
5621
6002
|
const coerced = this.coerceAndValidate(field, sourceValue, row);
|
|
5622
|
-
if (coerced === PASTE_SKIP
|
|
6003
|
+
if (coerced === PASTE_SKIP)
|
|
5623
6004
|
continue;
|
|
5624
6005
|
const before = row[field];
|
|
5625
6006
|
if (before === coerced)
|
|
5626
6007
|
continue;
|
|
5627
6008
|
rowCopy[field] = coerced;
|
|
5628
|
-
changes.push({ rowIndex:
|
|
6009
|
+
changes.push({ rowIndex: sourceIdx, field, before, after: coerced });
|
|
5629
6010
|
changed = true;
|
|
5630
6011
|
}
|
|
5631
6012
|
if (changed)
|
|
5632
|
-
updated[
|
|
6013
|
+
updated[sourceIdx] = rowCopy;
|
|
5633
6014
|
}
|
|
5634
6015
|
return updated;
|
|
5635
6016
|
});
|
|
@@ -5640,10 +6021,11 @@ class ClipboardEngine {
|
|
|
5640
6021
|
const cols = this.state.visibleColumns();
|
|
5641
6022
|
const defMap = this.state.columnDefMap();
|
|
5642
6023
|
const changes = [];
|
|
6024
|
+
const sourceIndices = this.resolveRangeSourceIndices(range);
|
|
5643
6025
|
this.state.sourceData.update((data) => {
|
|
5644
6026
|
const updated = [...data];
|
|
5645
|
-
for (
|
|
5646
|
-
const row = updated[
|
|
6027
|
+
for (const sourceIdx of sourceIndices) {
|
|
6028
|
+
const row = updated[sourceIdx];
|
|
5647
6029
|
if (!row)
|
|
5648
6030
|
continue;
|
|
5649
6031
|
const rowCopy = { ...row };
|
|
@@ -5656,17 +6038,17 @@ class ClipboardEngine {
|
|
|
5656
6038
|
if (!def?.editable)
|
|
5657
6039
|
continue;
|
|
5658
6040
|
const coerced = this.coerceAndValidate(field, value, row);
|
|
5659
|
-
if (coerced === PASTE_SKIP
|
|
6041
|
+
if (coerced === PASTE_SKIP)
|
|
5660
6042
|
continue;
|
|
5661
6043
|
const before = row[field];
|
|
5662
6044
|
if (before === coerced)
|
|
5663
6045
|
continue;
|
|
5664
6046
|
rowCopy[field] = coerced;
|
|
5665
|
-
changes.push({ rowIndex:
|
|
6047
|
+
changes.push({ rowIndex: sourceIdx, field, before, after: coerced });
|
|
5666
6048
|
changed = true;
|
|
5667
6049
|
}
|
|
5668
6050
|
if (changed)
|
|
5669
|
-
updated[
|
|
6051
|
+
updated[sourceIdx] = rowCopy;
|
|
5670
6052
|
}
|
|
5671
6053
|
return updated;
|
|
5672
6054
|
});
|
|
@@ -5677,10 +6059,11 @@ class ClipboardEngine {
|
|
|
5677
6059
|
const cols = this.state.visibleColumns();
|
|
5678
6060
|
const defMap = this.state.columnDefMap();
|
|
5679
6061
|
const changes = [];
|
|
6062
|
+
const sourceIndices = this.resolveRangeSourceIndices(range);
|
|
5680
6063
|
this.state.sourceData.update((data) => {
|
|
5681
6064
|
const updated = [...data];
|
|
5682
|
-
for (
|
|
5683
|
-
const row = updated[
|
|
6065
|
+
for (const sourceIdx of sourceIndices) {
|
|
6066
|
+
const row = updated[sourceIdx];
|
|
5684
6067
|
if (!row)
|
|
5685
6068
|
continue;
|
|
5686
6069
|
const rowCopy = { ...row };
|
|
@@ -5693,17 +6076,17 @@ class ClipboardEngine {
|
|
|
5693
6076
|
if (!def?.editable)
|
|
5694
6077
|
continue;
|
|
5695
6078
|
const coerced = this.coerceAndValidate(field, null, row);
|
|
5696
|
-
if (coerced === PASTE_SKIP
|
|
6079
|
+
if (coerced === PASTE_SKIP)
|
|
5697
6080
|
continue;
|
|
5698
6081
|
const before = row[field];
|
|
5699
6082
|
if (before === coerced)
|
|
5700
6083
|
continue;
|
|
5701
6084
|
rowCopy[field] = coerced;
|
|
5702
|
-
changes.push({ rowIndex:
|
|
6085
|
+
changes.push({ rowIndex: sourceIdx, field, before, after: coerced });
|
|
5703
6086
|
changed = true;
|
|
5704
6087
|
}
|
|
5705
6088
|
if (changed)
|
|
5706
|
-
updated[
|
|
6089
|
+
updated[sourceIdx] = rowCopy;
|
|
5707
6090
|
}
|
|
5708
6091
|
return updated;
|
|
5709
6092
|
});
|
|
@@ -5716,10 +6099,11 @@ class ClipboardEngine {
|
|
|
5716
6099
|
this.state.sourceData.update((data) => {
|
|
5717
6100
|
const updated = [...data];
|
|
5718
6101
|
for (let ri = 0; ri < pasteRows.length; ri++) {
|
|
5719
|
-
const
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
6102
|
+
const targetDisplayRow = range.start.row + ri;
|
|
6103
|
+
const sourceIdx = this.gridEngine.displayIndexToSourceIndex(targetDisplayRow);
|
|
6104
|
+
if (sourceIdx < 0)
|
|
6105
|
+
continue;
|
|
6106
|
+
const row = updated[sourceIdx];
|
|
5723
6107
|
if (!row)
|
|
5724
6108
|
continue;
|
|
5725
6109
|
const rowCopy = { ...row };
|
|
@@ -5732,17 +6116,17 @@ class ClipboardEngine {
|
|
|
5732
6116
|
if (!field)
|
|
5733
6117
|
continue;
|
|
5734
6118
|
const coerced = this.coerceAndValidate(field, pasteRows[ri][ci], row);
|
|
5735
|
-
if (coerced === PASTE_SKIP
|
|
6119
|
+
if (coerced === PASTE_SKIP)
|
|
5736
6120
|
continue;
|
|
5737
6121
|
const before = row[field];
|
|
5738
6122
|
if (before === coerced)
|
|
5739
6123
|
continue;
|
|
5740
6124
|
rowCopy[field] = coerced;
|
|
5741
|
-
changes.push({ rowIndex:
|
|
6125
|
+
changes.push({ rowIndex: sourceIdx, field, before, after: coerced });
|
|
5742
6126
|
changed = true;
|
|
5743
6127
|
}
|
|
5744
6128
|
if (changed)
|
|
5745
|
-
updated[
|
|
6129
|
+
updated[sourceIdx] = rowCopy;
|
|
5746
6130
|
}
|
|
5747
6131
|
return updated;
|
|
5748
6132
|
});
|
|
@@ -5785,7 +6169,7 @@ class ClipboardEngine {
|
|
|
5785
6169
|
coerceAndValidate(field, rawValue, row) {
|
|
5786
6170
|
const def = this.state.columnDefMap().get(field);
|
|
5787
6171
|
if (!def?.editable)
|
|
5788
|
-
return PASTE_SKIP
|
|
6172
|
+
return PASTE_SKIP;
|
|
5789
6173
|
const editorType = def.cellEditor;
|
|
5790
6174
|
if (rawValue === null) {
|
|
5791
6175
|
let clearValue;
|
|
@@ -5802,7 +6186,7 @@ class ClipboardEngine {
|
|
|
5802
6186
|
if (def.cellEditorValidator) {
|
|
5803
6187
|
const result = def.cellEditorValidator(clearValue, row);
|
|
5804
6188
|
if (result === false || typeof result === 'string')
|
|
5805
|
-
return PASTE_SKIP
|
|
6189
|
+
return PASTE_SKIP;
|
|
5806
6190
|
}
|
|
5807
6191
|
return clearValue;
|
|
5808
6192
|
}
|
|
@@ -5810,7 +6194,7 @@ class ClipboardEngine {
|
|
|
5810
6194
|
if (editorType === 'number') {
|
|
5811
6195
|
const num = Number(rawValue);
|
|
5812
6196
|
if (isNaN(num))
|
|
5813
|
-
return PASTE_SKIP
|
|
6197
|
+
return PASTE_SKIP;
|
|
5814
6198
|
value = num;
|
|
5815
6199
|
}
|
|
5816
6200
|
else if (editorType === 'checkbox') {
|
|
@@ -5821,19 +6205,19 @@ class ClipboardEngine {
|
|
|
5821
6205
|
value = false;
|
|
5822
6206
|
}
|
|
5823
6207
|
else {
|
|
5824
|
-
return PASTE_SKIP
|
|
6208
|
+
return PASTE_SKIP;
|
|
5825
6209
|
}
|
|
5826
6210
|
}
|
|
5827
6211
|
else if (editorType === 'select' && def.cellEditorOptions?.length) {
|
|
5828
6212
|
const allowed = def.cellEditorOptions.map((o) => String(o.value));
|
|
5829
6213
|
if (!allowed.includes(String(rawValue)))
|
|
5830
|
-
return PASTE_SKIP
|
|
6214
|
+
return PASTE_SKIP;
|
|
5831
6215
|
value = rawValue;
|
|
5832
6216
|
}
|
|
5833
6217
|
if (def.cellEditorValidator) {
|
|
5834
6218
|
const result = def.cellEditorValidator(value, row);
|
|
5835
6219
|
if (result === false || typeof result === 'string')
|
|
5836
|
-
return PASTE_SKIP
|
|
6220
|
+
return PASTE_SKIP;
|
|
5837
6221
|
}
|
|
5838
6222
|
return value;
|
|
5839
6223
|
}
|
|
@@ -6006,6 +6390,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
6006
6390
|
class InlineEditEngine {
|
|
6007
6391
|
state = inject(GridStateManager);
|
|
6008
6392
|
history = inject(HistoryEngine);
|
|
6393
|
+
gridEngine = inject(GridEngine);
|
|
6009
6394
|
startEdit(rowIndex, field) {
|
|
6010
6395
|
const defMap = this.state.columnDefMap();
|
|
6011
6396
|
const def = defMap.get(field);
|
|
@@ -6014,7 +6399,8 @@ class InlineEditEngine {
|
|
|
6014
6399
|
const colIndex = this.state.visibleColumns().findIndex((c) => c.field === field);
|
|
6015
6400
|
if (colIndex < 0)
|
|
6016
6401
|
return;
|
|
6017
|
-
const
|
|
6402
|
+
const sourceIndex = this.gridEngine.displayIndexToSourceIndex(rowIndex);
|
|
6403
|
+
const row = sourceIndex >= 0 ? this.state.sourceData()[sourceIndex] : undefined;
|
|
6018
6404
|
if (!row)
|
|
6019
6405
|
return;
|
|
6020
6406
|
const value = def.valueGetter ? def.valueGetter(row) : row[field];
|
|
@@ -6039,7 +6425,8 @@ class InlineEditEngine {
|
|
|
6039
6425
|
const colIndex = this.state.visibleColumns().findIndex((c) => c.field === field);
|
|
6040
6426
|
if (colIndex < 0)
|
|
6041
6427
|
return;
|
|
6042
|
-
const
|
|
6428
|
+
const sourceIndex = this.gridEngine.displayIndexToSourceIndex(rowIndex);
|
|
6429
|
+
const row = sourceIndex >= 0 ? this.state.sourceData()[sourceIndex] : undefined;
|
|
6043
6430
|
if (!row)
|
|
6044
6431
|
return;
|
|
6045
6432
|
const currentValue = def.valueGetter
|
|
@@ -6086,7 +6473,10 @@ class InlineEditEngine {
|
|
|
6086
6473
|
if (!field)
|
|
6087
6474
|
return null;
|
|
6088
6475
|
const def = this.state.columnDefMap().get(field);
|
|
6089
|
-
|
|
6476
|
+
const sourceIndex = this.gridEngine.displayIndexToSourceIndex(rowIndex);
|
|
6477
|
+
if (sourceIndex < 0)
|
|
6478
|
+
return null;
|
|
6479
|
+
let row = this.state.sourceData()[sourceIndex];
|
|
6090
6480
|
if (!row)
|
|
6091
6481
|
return null;
|
|
6092
6482
|
// Validation
|
|
@@ -6107,26 +6497,25 @@ class InlineEditEngine {
|
|
|
6107
6497
|
return null;
|
|
6108
6498
|
}
|
|
6109
6499
|
}
|
|
6110
|
-
//
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
}
|
|
6500
|
+
// Always update data immutably so signals detect the change, regardless
|
|
6501
|
+
// of client/server mode. Consumers can still re-fetch/override via output.
|
|
6502
|
+
this.state.sourceData.update((data) => {
|
|
6503
|
+
const updated = [...data];
|
|
6504
|
+
updated[sourceIndex] = { ...updated[sourceIndex], [field]: editState.draftValue };
|
|
6505
|
+
return updated;
|
|
6506
|
+
});
|
|
6507
|
+
// Re-read the updated row for the event
|
|
6508
|
+
row = this.state.sourceData()[sourceIndex];
|
|
6120
6509
|
const event = {
|
|
6121
6510
|
row,
|
|
6122
|
-
rowIndex,
|
|
6511
|
+
rowIndex: sourceIndex,
|
|
6123
6512
|
field,
|
|
6124
6513
|
oldValue: editState.originalValue,
|
|
6125
6514
|
newValue: editState.draftValue,
|
|
6126
6515
|
};
|
|
6127
|
-
if (
|
|
6516
|
+
if (event.oldValue !== event.newValue) {
|
|
6128
6517
|
this.history.record('edit', [
|
|
6129
|
-
{ rowIndex, field, before: event.oldValue, after: event.newValue },
|
|
6518
|
+
{ rowIndex: sourceIndex, field, before: event.oldValue, after: event.newValue },
|
|
6130
6519
|
]);
|
|
6131
6520
|
}
|
|
6132
6521
|
this.state.cellEditState.set({
|
|
@@ -6182,7 +6571,13 @@ class RowSelectionEngine {
|
|
|
6182
6571
|
engine = inject(GridEngine);
|
|
6183
6572
|
selectedIds = computed(() => this.state.selectedRowIds(), ...(ngDevMode ? [{ debugName: "selectedIds" }] : /* istanbul ignore next */ []));
|
|
6184
6573
|
excludedIds = computed(() => this.state.excludedRowIds(), ...(ngDevMode ? [{ debugName: "excludedIds" }] : /* istanbul ignore next */ []));
|
|
6185
|
-
|
|
6574
|
+
/**
|
|
6575
|
+
* Anchor row for shift-click range selection. We track the row object
|
|
6576
|
+
* (not its index) so the anchor stays valid across grouping, sorting and
|
|
6577
|
+
* filtering — where display indices shift without the underlying row
|
|
6578
|
+
* changing.
|
|
6579
|
+
*/
|
|
6580
|
+
lastToggledRow = signal(null, ...(ngDevMode ? [{ debugName: "lastToggledRow" }] : /* istanbul ignore next */ []));
|
|
6186
6581
|
count = computed(() => {
|
|
6187
6582
|
const mode = this.state.selectAllMode();
|
|
6188
6583
|
if (mode === 'all') {
|
|
@@ -6208,23 +6603,41 @@ class RowSelectionEngine {
|
|
|
6208
6603
|
const pageSelected = pageData.filter((row) => this.isRowSelected(row)).length;
|
|
6209
6604
|
return pageSelected > 0 && pageSelected < pageData.length;
|
|
6210
6605
|
}, ...(ngDevMode ? [{ debugName: "isIndeterminate" }] : /* istanbul ignore next */ []));
|
|
6211
|
-
|
|
6606
|
+
/**
|
|
6607
|
+
* Extends the selection from the last-toggled row (the anchor) to `endRow`,
|
|
6608
|
+
* resolving positions by object identity against the currently paginated
|
|
6609
|
+
* data. This is robust to grouping / sorting / filtering because we don't
|
|
6610
|
+
* rely on numeric indices, and works across any visible page slice.
|
|
6611
|
+
*/
|
|
6612
|
+
selectRowRangeToRow(endRow) {
|
|
6613
|
+
const anchor = this.lastToggledRow();
|
|
6614
|
+
if (!anchor) {
|
|
6615
|
+
this.toggleRow(endRow);
|
|
6616
|
+
this.lastToggledRow.set(endRow);
|
|
6617
|
+
return;
|
|
6618
|
+
}
|
|
6212
6619
|
const pageData = this.engine.paginatedData();
|
|
6213
|
-
const
|
|
6214
|
-
const
|
|
6620
|
+
const anchorIdx = pageData.indexOf(anchor);
|
|
6621
|
+
const endIdx = pageData.indexOf(endRow);
|
|
6622
|
+
if (anchorIdx < 0 || endIdx < 0) {
|
|
6623
|
+
// Anchor left the visible page — fall back to a plain toggle
|
|
6624
|
+
this.toggleRow(endRow);
|
|
6625
|
+
this.lastToggledRow.set(endRow);
|
|
6626
|
+
return;
|
|
6627
|
+
}
|
|
6628
|
+
const start = Math.min(anchorIdx, endIdx);
|
|
6629
|
+
const end = Math.max(anchorIdx, endIdx);
|
|
6215
6630
|
this.state.selectedRowIds.update((ids) => {
|
|
6216
6631
|
const next = new Set(ids);
|
|
6217
6632
|
for (let i = start; i <= end; i++) {
|
|
6218
|
-
|
|
6219
|
-
next.add(this.getRowId(pageData[i]));
|
|
6220
|
-
}
|
|
6633
|
+
next.add(this.getRowId(pageData[i]));
|
|
6221
6634
|
}
|
|
6222
6635
|
return next;
|
|
6223
6636
|
});
|
|
6224
6637
|
if (this.state.selectAllMode() === 'none') {
|
|
6225
6638
|
this.state.selectAllMode.set('page');
|
|
6226
6639
|
}
|
|
6227
|
-
this.
|
|
6640
|
+
this.lastToggledRow.set(endRow);
|
|
6228
6641
|
}
|
|
6229
6642
|
toggleRow(row) {
|
|
6230
6643
|
const id = this.getRowId(row);
|
|
@@ -7672,6 +8085,7 @@ class StatePersistenceEngine {
|
|
|
7672
8085
|
pinned: col.pinned,
|
|
7673
8086
|
})),
|
|
7674
8087
|
sorts: this.state.activeSorts(),
|
|
8088
|
+
filters: this.state.filterModel().conditions.map(({ id: _id, ...rest }) => rest),
|
|
7675
8089
|
};
|
|
7676
8090
|
try {
|
|
7677
8091
|
localStorage.setItem(storageKey, JSON.stringify(persisted));
|
|
@@ -7715,6 +8129,11 @@ class StatePersistenceEngine {
|
|
|
7715
8129
|
: { ...s, sort: null, sortIndex: null };
|
|
7716
8130
|
}));
|
|
7717
8131
|
}
|
|
8132
|
+
if (persisted.filters?.length) {
|
|
8133
|
+
this.state.filterModel.set({
|
|
8134
|
+
conditions: persisted.filters.map((f) => ({ ...f, id: generateConditionId() })),
|
|
8135
|
+
});
|
|
8136
|
+
}
|
|
7718
8137
|
return true;
|
|
7719
8138
|
}
|
|
7720
8139
|
catch {
|
|
@@ -8082,13 +8501,272 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
8082
8501
|
}]
|
|
8083
8502
|
}], propDecorators: { slot: [{ type: i0.Input, args: [{ isSignal: true, alias: "mozGridToolbarDef", required: false }] }] } });
|
|
8084
8503
|
|
|
8504
|
+
class MozGridFilterBuilderComponent {
|
|
8505
|
+
model = input.required(...(ngDevMode ? [{ debugName: "model" }] : /* istanbul ignore next */ []));
|
|
8506
|
+
availableColumns = input.required(...(ngDevMode ? [{ debugName: "availableColumns" }] : /* istanbul ignore next */ []));
|
|
8507
|
+
applyMode = input('auto', ...(ngDevMode ? [{ debugName: "applyMode" }] : /* istanbul ignore next */ []));
|
|
8508
|
+
/** Hint: when true, renders a "Show rows" sub-title (used inside the overlay). */
|
|
8509
|
+
showSubtitle = input(true, ...(ngDevMode ? [{ debugName: "showSubtitle" }] : /* istanbul ignore next */ []));
|
|
8510
|
+
modelChange = output();
|
|
8511
|
+
// Draft (what the user sees). Synced from `model` input on change.
|
|
8512
|
+
draft = signal([], ...(ngDevMode ? [{ debugName: "draft" }] : /* istanbul ignore next */ []));
|
|
8513
|
+
constructor() {
|
|
8514
|
+
effect(() => {
|
|
8515
|
+
const incoming = this.model().conditions;
|
|
8516
|
+
// Avoid clobbering local mutations: only sync when the incoming model
|
|
8517
|
+
// differs by id-set or values from the current draft.
|
|
8518
|
+
const current = untracked(() => this.draft());
|
|
8519
|
+
if (!conditionsEqual(incoming, current)) {
|
|
8520
|
+
this.draft.set(incoming.map((c) => ({ ...c, value: { ...c.value } })));
|
|
8521
|
+
}
|
|
8522
|
+
});
|
|
8523
|
+
}
|
|
8524
|
+
columnsById = computed(() => {
|
|
8525
|
+
const m = new Map();
|
|
8526
|
+
for (const c of this.availableColumns())
|
|
8527
|
+
m.set(c.field, c);
|
|
8528
|
+
return m;
|
|
8529
|
+
}, ...(ngDevMode ? [{ debugName: "columnsById" }] : /* istanbul ignore next */ []));
|
|
8530
|
+
operatorLabels = OPERATOR_LABELS;
|
|
8531
|
+
// ------------------------------------------------------------------
|
|
8532
|
+
// Mutations
|
|
8533
|
+
// ------------------------------------------------------------------
|
|
8534
|
+
addCondition() {
|
|
8535
|
+
const cols = this.availableColumns();
|
|
8536
|
+
if (cols.length === 0)
|
|
8537
|
+
return;
|
|
8538
|
+
const first = cols[0];
|
|
8539
|
+
const isFirst = this.draft().length === 0;
|
|
8540
|
+
const condition = {
|
|
8541
|
+
id: generateConditionId(),
|
|
8542
|
+
combinator: isFirst ? 'and' : 'and',
|
|
8543
|
+
field: first.field,
|
|
8544
|
+
operator: first.defaultOperator,
|
|
8545
|
+
value: {},
|
|
8546
|
+
};
|
|
8547
|
+
this.draft.update((list) => [...list, condition]);
|
|
8548
|
+
this.commit();
|
|
8549
|
+
}
|
|
8550
|
+
removeCondition(id) {
|
|
8551
|
+
this.draft.update((list) => list.filter((c) => c.id !== id));
|
|
8552
|
+
this.commit();
|
|
8553
|
+
}
|
|
8554
|
+
onCombinatorChange(id, combinator) {
|
|
8555
|
+
this.draft.update((list) => list.map((c) => (c.id === id ? { ...c, combinator } : c)));
|
|
8556
|
+
this.commit();
|
|
8557
|
+
}
|
|
8558
|
+
onFieldChange(id, field) {
|
|
8559
|
+
const col = this.columnsById().get(field);
|
|
8560
|
+
this.draft.update((list) => list.map((c) => c.id === id
|
|
8561
|
+
? {
|
|
8562
|
+
...c,
|
|
8563
|
+
field,
|
|
8564
|
+
operator: col?.defaultOperator ?? c.operator,
|
|
8565
|
+
value: {},
|
|
8566
|
+
}
|
|
8567
|
+
: c));
|
|
8568
|
+
this.commit();
|
|
8569
|
+
}
|
|
8570
|
+
onOperatorChange(id, operator) {
|
|
8571
|
+
this.draft.update((list) => list.map((c) => (c.id === id ? { ...c, operator, value: resetValueFor(operator, c.value) } : c)));
|
|
8572
|
+
this.commit();
|
|
8573
|
+
}
|
|
8574
|
+
onValueChange(id, patch) {
|
|
8575
|
+
this.draft.update((list) => list.map((c) => c.id === id
|
|
8576
|
+
? {
|
|
8577
|
+
...c,
|
|
8578
|
+
value: { ...c.value, ...patch },
|
|
8579
|
+
}
|
|
8580
|
+
: c));
|
|
8581
|
+
this.commit();
|
|
8582
|
+
}
|
|
8583
|
+
onSetValueChange(id, event) {
|
|
8584
|
+
const select = event.target;
|
|
8585
|
+
const values = Array.from(select.selectedOptions).map((o) => o.value);
|
|
8586
|
+
this.onValueChange(id, { value: values });
|
|
8587
|
+
}
|
|
8588
|
+
onDrop(event) {
|
|
8589
|
+
this.draft.update((list) => {
|
|
8590
|
+
const next = [...list];
|
|
8591
|
+
moveItemInArray(next, event.previousIndex, event.currentIndex);
|
|
8592
|
+
return next;
|
|
8593
|
+
});
|
|
8594
|
+
this.commit();
|
|
8595
|
+
}
|
|
8596
|
+
// ------------------------------------------------------------------
|
|
8597
|
+
// Value editor helpers (for the template)
|
|
8598
|
+
// ------------------------------------------------------------------
|
|
8599
|
+
needsValue(op) {
|
|
8600
|
+
return !VALUELESS_OPERATORS.has(op);
|
|
8601
|
+
}
|
|
8602
|
+
needsRange(op) {
|
|
8603
|
+
return RANGE_OPERATORS.has(op);
|
|
8604
|
+
}
|
|
8605
|
+
getSelectedSetValues(condition) {
|
|
8606
|
+
const v = condition.value.value;
|
|
8607
|
+
if (Array.isArray(v))
|
|
8608
|
+
return v.map((x) => String(x));
|
|
8609
|
+
if (v == null || v === '')
|
|
8610
|
+
return [];
|
|
8611
|
+
return [String(v)];
|
|
8612
|
+
}
|
|
8613
|
+
isSetValueSelected(condition, value) {
|
|
8614
|
+
return this.getSelectedSetValues(condition).includes(String(value));
|
|
8615
|
+
}
|
|
8616
|
+
inputTypeFor(op, type) {
|
|
8617
|
+
if (type === 'number')
|
|
8618
|
+
return 'number';
|
|
8619
|
+
if (type === 'date')
|
|
8620
|
+
return 'date';
|
|
8621
|
+
return 'text';
|
|
8622
|
+
}
|
|
8623
|
+
// ------------------------------------------------------------------
|
|
8624
|
+
// Internals
|
|
8625
|
+
// ------------------------------------------------------------------
|
|
8626
|
+
commit() {
|
|
8627
|
+
this.modelChange.emit({ conditions: this.draft().map((c) => ({ ...c, value: { ...c.value } })) });
|
|
8628
|
+
}
|
|
8629
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MozGridFilterBuilderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8630
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: MozGridFilterBuilderComponent, isStandalone: true, selector: "moz-grid-filter-builder", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, availableColumns: { classPropertyName: "availableColumns", publicName: "availableColumns", isSignal: true, isRequired: true, transformFunction: null }, applyMode: { classPropertyName: "applyMode", publicName: "applyMode", isSignal: true, isRequired: false, transformFunction: null }, showSubtitle: { classPropertyName: "showSubtitle", publicName: "showSubtitle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { modelChange: "modelChange" }, ngImport: i0, template: "<div class=\"filter-builder\">\n @if (showSubtitle()) {\n <p class=\"filter-builder__subtitle\">Show rows</p>\n }\n\n <div class=\"filter-builder__rows\" cdkDropList (cdkDropListDropped)=\"onDrop($event)\">\n @for (cond of draft(); track cond.id; let idx = $index; let first = $first) {\n <div class=\"filter-builder__row\" cdkDrag>\n <!-- Combinator -->\n <div class=\"filter-builder__combinator\">\n @if (first) {\n <span class=\"filter-builder__combinator-label\">Where</span>\n } @else {\n <select\n class=\"filter-builder__select filter-builder__select--combinator\"\n [value]=\"cond.combinator\"\n [attr.aria-label]=\"'Combinator for condition ' + (idx + 1)\"\n (change)=\"onCombinatorChange(cond.id, $any($event.target).value)\"\n >\n <option value=\"and\">And</option>\n <option value=\"or\">Or</option>\n </select>\n }\n </div>\n\n <!-- Column -->\n <select\n class=\"filter-builder__select filter-builder__select--column\"\n [value]=\"cond.field\"\n [attr.aria-label]=\"'Column for condition ' + (idx + 1)\"\n (change)=\"onFieldChange(cond.id, $any($event.target).value)\"\n >\n @for (col of availableColumns(); track col.field) {\n <option [value]=\"col.field\">{{ col.headerName }}</option>\n }\n </select>\n\n <!-- Operator -->\n <select\n class=\"filter-builder__select filter-builder__select--operator\"\n [value]=\"cond.operator\"\n [attr.aria-label]=\"'Operator for condition ' + (idx + 1)\"\n (change)=\"onOperatorChange(cond.id, $any($event.target).value)\"\n >\n @for (op of columnsById().get(cond.field)?.operators ?? []; track op) {\n <option [value]=\"op\">{{ operatorLabels[op] }}</option>\n }\n </select>\n\n <!-- Value -->\n <div class=\"filter-builder__value\">\n @if (needsValue(cond.operator)) { @let col = columnsById().get(cond.field); @if\n (col?.filterType === 'set') {\n <select\n class=\"filter-builder__select filter-builder__select--set\"\n multiple\n size=\"4\"\n [attr.aria-label]=\"'Values for condition ' + (idx + 1)\"\n (change)=\"onSetValueChange(cond.id, $event)\"\n >\n @for (opt of col?.options ?? []; track $any(opt.value)) {\n <option [value]=\"opt.value\" [selected]=\"isSetValueSelected(cond, opt.value)\">\n {{ opt.label }}\n </option>\n }\n </select>\n } @else if (col?.filterType === 'boolean') {\n <select\n class=\"filter-builder__select\"\n [value]=\"cond.value.value === true ? 'true' : 'false'\"\n [attr.aria-label]=\"'Value for condition ' + (idx + 1)\"\n (change)=\"onValueChange(cond.id, { value: $any($event.target).value === 'true' })\"\n >\n <option value=\"true\">True</option>\n <option value=\"false\">False</option>\n </select>\n } @else {\n <input\n class=\"filter-builder__input\"\n [type]=\"inputTypeFor(cond.operator, col?.filterType ?? 'text')\"\n [value]=\"cond.value.value ?? ''\"\n [attr.aria-label]=\"'Value for condition ' + (idx + 1)\"\n (input)=\"onValueChange(cond.id, { value: $any($event.target).value })\"\n />\n @if (needsRange(cond.operator)) {\n <span class=\"filter-builder__range-sep\">\u2013</span>\n <input\n class=\"filter-builder__input\"\n [type]=\"inputTypeFor(cond.operator, col?.filterType ?? 'text')\"\n [value]=\"cond.value.valueTo ?? ''\"\n [attr.aria-label]=\"'Upper bound for condition ' + (idx + 1)\"\n (input)=\"onValueChange(cond.id, { valueTo: $any($event.target).value })\"\n />\n } } }\n </div>\n\n <!-- Delete -->\n <button\n type=\"button\"\n moz-button\n [ghost]=\"true\"\n [size]=\"'s'\"\n [iconPosition]=\"'only'\"\n [attr.aria-label]=\"'Remove condition ' + (idx + 1)\"\n (click)=\"removeCondition(cond.id)\"\n >\n <Cross20 icon />\n </button>\n\n <!-- Drag handle -->\n <span\n class=\"filter-builder__drag\"\n cdkDragHandle\n [attr.aria-label]=\"'Reorder condition ' + (idx + 1)\"\n >\n <Drag20 />\n </span>\n </div>\n }\n </div>\n\n <button\n type=\"button\"\n class=\"filter-builder__add\"\n [disabled]=\"availableColumns().length === 0\"\n (click)=\"addCondition()\"\n >\n <ListAdd20 />\n <span>Add condition</span>\n </button>\n</div>\n", styles: [":host{display:block;background:var(--Background-Primary, #fff);border:1px solid var(--Border-Primary, #cdd4d8);border-radius:6px;box-shadow:0 4px 16px #0000001f}.filter-builder{display:flex;flex-direction:column;gap:12px;min-width:560px;padding:16px}.filter-builder__subtitle{margin:0;font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--Text-Secondary, #555)}.filter-builder__rows{display:flex;flex-direction:column;gap:8px}.filter-builder__row{display:flex;align-items:center;gap:8px;padding:6px 8px;border:1px solid var(--Border-Primary, #e0e0e0);border-radius:6px;background:var(--Background-Primary, #fff)}.filter-builder__row.cdk-drag-preview{box-shadow:0 2px 8px #0000001f}.filter-builder__row.cdk-drag-placeholder{opacity:.3}.filter-builder__combinator{min-width:64px;flex:0 0 64px}.filter-builder__combinator-label{display:inline-block;width:100%;padding:6px 8px;font-weight:600;color:var(--Text-Secondary, #555)}.filter-builder__select,.filter-builder__input{font:inherit;padding:6px 8px;border:1px solid var(--Border-Primary, #ccc);border-radius:4px;background:#fff;min-height:32px;box-sizing:border-box}.filter-builder__select--combinator{width:100%}.filter-builder__select--column,.filter-builder__select--operator{flex:1 1 120px;min-width:0}.filter-builder__select--set{min-width:160px;height:auto}.filter-builder__value{display:flex;align-items:center;gap:4px;flex:1 1 160px;min-width:0}.filter-builder__input{flex:1 1 0;min-width:0}.filter-builder__range-sep{color:var(--Text-Secondary, #777)}.filter-builder__drag{display:inline-flex;cursor:grab;color:var(--Text-Secondary, #777)}.filter-builder__drag:active{cursor:grabbing}.filter-builder__add{display:inline-flex;align-items:center;gap:6px;align-self:flex-start;padding:6px 10px;background:transparent;border:none;color:var(--Status-Standalone-element-Primary, #0071ce);font:inherit;cursor:pointer;border-radius:4px}.filter-builder__add:hover:not([disabled]){background:var(--Background-Secondary, #f4f4f4)}.filter-builder__add[disabled]{cursor:not-allowed;opacity:.5}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: MozButtonComponent, selector: "button[moz-button]", inputs: ["appearance", "size", "disabled", "ghost", "outlined", "iconPosition", "type", "isLoading"] }, { kind: "component", type: Drag20, selector: "Drag20", inputs: ["hostClass"] }, { kind: "component", type: Cross20, selector: "Cross20", inputs: ["hostClass"] }, { kind: "component", type: ListAdd20, selector: "ListAdd20", inputs: ["hostClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8631
|
+
}
|
|
8632
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MozGridFilterBuilderComponent, decorators: [{
|
|
8633
|
+
type: Component,
|
|
8634
|
+
args: [{ selector: 'moz-grid-filter-builder', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
8635
|
+
FormsModule,
|
|
8636
|
+
CdkDropList,
|
|
8637
|
+
CdkDrag,
|
|
8638
|
+
CdkDragHandle,
|
|
8639
|
+
MozButtonComponent,
|
|
8640
|
+
Drag20,
|
|
8641
|
+
Cross20,
|
|
8642
|
+
ListAdd20,
|
|
8643
|
+
], template: "<div class=\"filter-builder\">\n @if (showSubtitle()) {\n <p class=\"filter-builder__subtitle\">Show rows</p>\n }\n\n <div class=\"filter-builder__rows\" cdkDropList (cdkDropListDropped)=\"onDrop($event)\">\n @for (cond of draft(); track cond.id; let idx = $index; let first = $first) {\n <div class=\"filter-builder__row\" cdkDrag>\n <!-- Combinator -->\n <div class=\"filter-builder__combinator\">\n @if (first) {\n <span class=\"filter-builder__combinator-label\">Where</span>\n } @else {\n <select\n class=\"filter-builder__select filter-builder__select--combinator\"\n [value]=\"cond.combinator\"\n [attr.aria-label]=\"'Combinator for condition ' + (idx + 1)\"\n (change)=\"onCombinatorChange(cond.id, $any($event.target).value)\"\n >\n <option value=\"and\">And</option>\n <option value=\"or\">Or</option>\n </select>\n }\n </div>\n\n <!-- Column -->\n <select\n class=\"filter-builder__select filter-builder__select--column\"\n [value]=\"cond.field\"\n [attr.aria-label]=\"'Column for condition ' + (idx + 1)\"\n (change)=\"onFieldChange(cond.id, $any($event.target).value)\"\n >\n @for (col of availableColumns(); track col.field) {\n <option [value]=\"col.field\">{{ col.headerName }}</option>\n }\n </select>\n\n <!-- Operator -->\n <select\n class=\"filter-builder__select filter-builder__select--operator\"\n [value]=\"cond.operator\"\n [attr.aria-label]=\"'Operator for condition ' + (idx + 1)\"\n (change)=\"onOperatorChange(cond.id, $any($event.target).value)\"\n >\n @for (op of columnsById().get(cond.field)?.operators ?? []; track op) {\n <option [value]=\"op\">{{ operatorLabels[op] }}</option>\n }\n </select>\n\n <!-- Value -->\n <div class=\"filter-builder__value\">\n @if (needsValue(cond.operator)) { @let col = columnsById().get(cond.field); @if\n (col?.filterType === 'set') {\n <select\n class=\"filter-builder__select filter-builder__select--set\"\n multiple\n size=\"4\"\n [attr.aria-label]=\"'Values for condition ' + (idx + 1)\"\n (change)=\"onSetValueChange(cond.id, $event)\"\n >\n @for (opt of col?.options ?? []; track $any(opt.value)) {\n <option [value]=\"opt.value\" [selected]=\"isSetValueSelected(cond, opt.value)\">\n {{ opt.label }}\n </option>\n }\n </select>\n } @else if (col?.filterType === 'boolean') {\n <select\n class=\"filter-builder__select\"\n [value]=\"cond.value.value === true ? 'true' : 'false'\"\n [attr.aria-label]=\"'Value for condition ' + (idx + 1)\"\n (change)=\"onValueChange(cond.id, { value: $any($event.target).value === 'true' })\"\n >\n <option value=\"true\">True</option>\n <option value=\"false\">False</option>\n </select>\n } @else {\n <input\n class=\"filter-builder__input\"\n [type]=\"inputTypeFor(cond.operator, col?.filterType ?? 'text')\"\n [value]=\"cond.value.value ?? ''\"\n [attr.aria-label]=\"'Value for condition ' + (idx + 1)\"\n (input)=\"onValueChange(cond.id, { value: $any($event.target).value })\"\n />\n @if (needsRange(cond.operator)) {\n <span class=\"filter-builder__range-sep\">\u2013</span>\n <input\n class=\"filter-builder__input\"\n [type]=\"inputTypeFor(cond.operator, col?.filterType ?? 'text')\"\n [value]=\"cond.value.valueTo ?? ''\"\n [attr.aria-label]=\"'Upper bound for condition ' + (idx + 1)\"\n (input)=\"onValueChange(cond.id, { valueTo: $any($event.target).value })\"\n />\n } } }\n </div>\n\n <!-- Delete -->\n <button\n type=\"button\"\n moz-button\n [ghost]=\"true\"\n [size]=\"'s'\"\n [iconPosition]=\"'only'\"\n [attr.aria-label]=\"'Remove condition ' + (idx + 1)\"\n (click)=\"removeCondition(cond.id)\"\n >\n <Cross20 icon />\n </button>\n\n <!-- Drag handle -->\n <span\n class=\"filter-builder__drag\"\n cdkDragHandle\n [attr.aria-label]=\"'Reorder condition ' + (idx + 1)\"\n >\n <Drag20 />\n </span>\n </div>\n }\n </div>\n\n <button\n type=\"button\"\n class=\"filter-builder__add\"\n [disabled]=\"availableColumns().length === 0\"\n (click)=\"addCondition()\"\n >\n <ListAdd20 />\n <span>Add condition</span>\n </button>\n</div>\n", styles: [":host{display:block;background:var(--Background-Primary, #fff);border:1px solid var(--Border-Primary, #cdd4d8);border-radius:6px;box-shadow:0 4px 16px #0000001f}.filter-builder{display:flex;flex-direction:column;gap:12px;min-width:560px;padding:16px}.filter-builder__subtitle{margin:0;font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--Text-Secondary, #555)}.filter-builder__rows{display:flex;flex-direction:column;gap:8px}.filter-builder__row{display:flex;align-items:center;gap:8px;padding:6px 8px;border:1px solid var(--Border-Primary, #e0e0e0);border-radius:6px;background:var(--Background-Primary, #fff)}.filter-builder__row.cdk-drag-preview{box-shadow:0 2px 8px #0000001f}.filter-builder__row.cdk-drag-placeholder{opacity:.3}.filter-builder__combinator{min-width:64px;flex:0 0 64px}.filter-builder__combinator-label{display:inline-block;width:100%;padding:6px 8px;font-weight:600;color:var(--Text-Secondary, #555)}.filter-builder__select,.filter-builder__input{font:inherit;padding:6px 8px;border:1px solid var(--Border-Primary, #ccc);border-radius:4px;background:#fff;min-height:32px;box-sizing:border-box}.filter-builder__select--combinator{width:100%}.filter-builder__select--column,.filter-builder__select--operator{flex:1 1 120px;min-width:0}.filter-builder__select--set{min-width:160px;height:auto}.filter-builder__value{display:flex;align-items:center;gap:4px;flex:1 1 160px;min-width:0}.filter-builder__input{flex:1 1 0;min-width:0}.filter-builder__range-sep{color:var(--Text-Secondary, #777)}.filter-builder__drag{display:inline-flex;cursor:grab;color:var(--Text-Secondary, #777)}.filter-builder__drag:active{cursor:grabbing}.filter-builder__add{display:inline-flex;align-items:center;gap:6px;align-self:flex-start;padding:6px 10px;background:transparent;border:none;color:var(--Status-Standalone-element-Primary, #0071ce);font:inherit;cursor:pointer;border-radius:4px}.filter-builder__add:hover:not([disabled]){background:var(--Background-Secondary, #f4f4f4)}.filter-builder__add[disabled]{cursor:not-allowed;opacity:.5}\n"] }]
|
|
8644
|
+
}], ctorParameters: () => [], propDecorators: { model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], availableColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableColumns", required: true }] }], applyMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "applyMode", required: false }] }], showSubtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSubtitle", required: false }] }], modelChange: [{ type: i0.Output, args: ["modelChange"] }] } });
|
|
8645
|
+
function resetValueFor(op, previous) {
|
|
8646
|
+
if (VALUELESS_OPERATORS.has(op))
|
|
8647
|
+
return {};
|
|
8648
|
+
if (RANGE_OPERATORS.has(op))
|
|
8649
|
+
return { value: previous.value ?? '', valueTo: previous.valueTo ?? '' };
|
|
8650
|
+
return { value: previous.value ?? '' };
|
|
8651
|
+
}
|
|
8652
|
+
function conditionsEqual(a, b) {
|
|
8653
|
+
if (a.length !== b.length)
|
|
8654
|
+
return false;
|
|
8655
|
+
for (let i = 0; i < a.length; i++) {
|
|
8656
|
+
const ca = a[i];
|
|
8657
|
+
const cb = b[i];
|
|
8658
|
+
if (ca.id !== cb.id ||
|
|
8659
|
+
ca.combinator !== cb.combinator ||
|
|
8660
|
+
ca.field !== cb.field ||
|
|
8661
|
+
ca.operator !== cb.operator ||
|
|
8662
|
+
ca.value.value !== cb.value.value ||
|
|
8663
|
+
ca.value.valueTo !== cb.value.valueTo) {
|
|
8664
|
+
return false;
|
|
8665
|
+
}
|
|
8666
|
+
}
|
|
8667
|
+
return true;
|
|
8668
|
+
}
|
|
8669
|
+
|
|
8670
|
+
/**
|
|
8671
|
+
* Programmatically opens a CDK overlay anchored on the host element that
|
|
8672
|
+
* renders the filter builder. Unlike the action-listbox directive, the
|
|
8673
|
+
* overlay does not toggle on click — the host is simply the anchor. Open
|
|
8674
|
+
* the overlay by injecting this directive via a template ref (`#filter`)
|
|
8675
|
+
* and calling `filter.open(options)`.
|
|
8676
|
+
*/
|
|
8677
|
+
class MozGridFilterOverlayDirective {
|
|
8678
|
+
overlay = inject(Overlay);
|
|
8679
|
+
host = inject((ElementRef));
|
|
8680
|
+
injector = inject(Injector);
|
|
8681
|
+
engine = inject(FilterEngine, { optional: true });
|
|
8682
|
+
overlayRef = null;
|
|
8683
|
+
componentRef = null;
|
|
8684
|
+
/** Opens the overlay anchored on the host. No-op if already open. */
|
|
8685
|
+
open(options) {
|
|
8686
|
+
if (this.overlayRef)
|
|
8687
|
+
return;
|
|
8688
|
+
if (!this.engine)
|
|
8689
|
+
return;
|
|
8690
|
+
const positions = [
|
|
8691
|
+
{ originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },
|
|
8692
|
+
{ originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 4 },
|
|
8693
|
+
{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },
|
|
8694
|
+
];
|
|
8695
|
+
const positionStrategy = this.overlay
|
|
8696
|
+
.position()
|
|
8697
|
+
.flexibleConnectedTo(this.host)
|
|
8698
|
+
.withPositions(positions)
|
|
8699
|
+
.withPush(true)
|
|
8700
|
+
.withViewportMargin(8);
|
|
8701
|
+
const config = new OverlayConfig({
|
|
8702
|
+
hasBackdrop: true,
|
|
8703
|
+
backdropClass: 'cdk-overlay-transparent-backdrop',
|
|
8704
|
+
panelClass: 'moz-grid-filter-overlay',
|
|
8705
|
+
positionStrategy,
|
|
8706
|
+
scrollStrategy: this.overlay.scrollStrategies.reposition(),
|
|
8707
|
+
});
|
|
8708
|
+
const overlayRef = this.overlay.create(config);
|
|
8709
|
+
this.overlayRef = overlayRef;
|
|
8710
|
+
// Seed the draft with a new condition targeting the clicked column, if any
|
|
8711
|
+
const seededModel = options.seedField && options.model.conditions.length === 0
|
|
8712
|
+
? { conditions: [this.engine.makeCondition(options.seedField, true)] }
|
|
8713
|
+
: options.model;
|
|
8714
|
+
const portal = new ComponentPortal(MozGridFilterBuilderComponent, null, this.injector);
|
|
8715
|
+
const compRef = overlayRef.attach(portal);
|
|
8716
|
+
compRef.setInput('model', seededModel);
|
|
8717
|
+
compRef.setInput('availableColumns', options.columns);
|
|
8718
|
+
compRef.setInput('applyMode', 'auto');
|
|
8719
|
+
compRef.setInput('showSubtitle', true);
|
|
8720
|
+
compRef.instance.modelChange.subscribe((next) => {
|
|
8721
|
+
compRef.setInput('model', next);
|
|
8722
|
+
options.onChange(next);
|
|
8723
|
+
});
|
|
8724
|
+
this.componentRef = compRef;
|
|
8725
|
+
overlayRef.backdropClick().subscribe(() => this.close());
|
|
8726
|
+
overlayRef.keydownEvents().subscribe((event) => {
|
|
8727
|
+
if (event.key === 'Escape')
|
|
8728
|
+
this.close();
|
|
8729
|
+
});
|
|
8730
|
+
}
|
|
8731
|
+
close() {
|
|
8732
|
+
this.overlayRef?.dispose();
|
|
8733
|
+
this.overlayRef = null;
|
|
8734
|
+
this.componentRef = null;
|
|
8735
|
+
}
|
|
8736
|
+
ngOnDestroy() {
|
|
8737
|
+
this.close();
|
|
8738
|
+
}
|
|
8739
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MozGridFilterOverlayDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
8740
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: MozGridFilterOverlayDirective, isStandalone: true, selector: "[mozGridFilterOverlay]", exportAs: ["mozGridFilterOverlay"], ngImport: i0 });
|
|
8741
|
+
}
|
|
8742
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MozGridFilterOverlayDirective, decorators: [{
|
|
8743
|
+
type: Directive,
|
|
8744
|
+
args: [{
|
|
8745
|
+
selector: '[mozGridFilterOverlay]',
|
|
8746
|
+
exportAs: 'mozGridFilterOverlay',
|
|
8747
|
+
}]
|
|
8748
|
+
}] });
|
|
8749
|
+
|
|
8085
8750
|
class MozGridHeaderCellComponent {
|
|
8086
8751
|
state = inject(GridStateManager);
|
|
8752
|
+
filterEngine = inject(FilterEngine);
|
|
8087
8753
|
columnState = input.required(...(ngDevMode ? [{ debugName: "columnState" }] : /* istanbul ignore next */ []));
|
|
8088
8754
|
def = input.required(...(ngDevMode ? [{ debugName: "def" }] : /* istanbul ignore next */ []));
|
|
8089
8755
|
isLast = input(false, ...(ngDevMode ? [{ debugName: "isLast" }] : /* istanbul ignore next */ []));
|
|
8090
8756
|
pinnedEnd = input(false, ...(ngDevMode ? [{ debugName: "pinnedEnd" }] : /* istanbul ignore next */ []));
|
|
8091
8757
|
reorderable = input(false, ...(ngDevMode ? [{ debugName: "reorderable" }] : /* istanbul ignore next */ []));
|
|
8758
|
+
filterOverlay = viewChild(MozGridFilterOverlayDirective, ...(ngDevMode ? [{ debugName: "filterOverlay" }] : /* istanbul ignore next */ []));
|
|
8759
|
+
/** True when at least one active condition targets this column. */
|
|
8760
|
+
hasActiveFilter = computed(() => this.filterEngine.conditions().some((c) => c.field === this.columnState().field), ...(ngDevMode ? [{ debugName: "hasActiveFilter" }] : /* istanbul ignore next */ []));
|
|
8761
|
+
/** Tooltip for the gear / filter button (count + short summary). */
|
|
8762
|
+
filterTooltip = computed(() => {
|
|
8763
|
+
const field = this.columnState().field;
|
|
8764
|
+
const matching = this.filterEngine.conditions().filter((c) => c.field === field);
|
|
8765
|
+
if (matching.length === 0)
|
|
8766
|
+
return 'Column settings';
|
|
8767
|
+
const summary = matching.map((c) => this.filterEngine.toLabel(c)).join(', ');
|
|
8768
|
+
return `${matching.length} filter${matching.length > 1 ? 's' : ''}: ${summary}`;
|
|
8769
|
+
}, ...(ngDevMode ? [{ debugName: "filterTooltip" }] : /* istanbul ignore next */ []));
|
|
8092
8770
|
resolvedMinWidth = computed(() => {
|
|
8093
8771
|
const def = this.def();
|
|
8094
8772
|
return def.minWidth ? parseInt(def.minWidth, 10) || 50 : 50;
|
|
@@ -8114,6 +8792,7 @@ class MozGridHeaderCellComponent {
|
|
|
8114
8792
|
items.push({
|
|
8115
8793
|
id: 'filter-column',
|
|
8116
8794
|
label: 'Filter in this column',
|
|
8795
|
+
icon: Filter20,
|
|
8117
8796
|
divider: items.length > 0,
|
|
8118
8797
|
});
|
|
8119
8798
|
}
|
|
@@ -8151,11 +8830,6 @@ class MozGridHeaderCellComponent {
|
|
|
8151
8830
|
divider: items.length > 0,
|
|
8152
8831
|
});
|
|
8153
8832
|
}
|
|
8154
|
-
items.push({
|
|
8155
|
-
id: 'toggle-column-search',
|
|
8156
|
-
label: colState.searchVisible ? 'Hide search by column' : 'Show search by column',
|
|
8157
|
-
divider: def.hideable === false && items.length > 0,
|
|
8158
|
-
});
|
|
8159
8833
|
return items;
|
|
8160
8834
|
}, ...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
|
|
8161
8835
|
onHeaderClick(event) {
|
|
@@ -8167,24 +8841,58 @@ class MozGridHeaderCellComponent {
|
|
|
8167
8841
|
}
|
|
8168
8842
|
}
|
|
8169
8843
|
onMenuItemClick(item) {
|
|
8170
|
-
this.
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8844
|
+
const field = this.columnState().field;
|
|
8845
|
+
const actionId = item.id;
|
|
8846
|
+
// Intercept "Filter in this column": when the column does not provide a
|
|
8847
|
+
// custom `filterTemplate`, open the overlay anchored on the gear button
|
|
8848
|
+
// instead of delegating to the grid shell (which would toggle the legacy
|
|
8849
|
+
// per-column search input). Columns that ship a filterTemplate keep their
|
|
8850
|
+
// legacy behaviour — the grid handles them via `onMenuAction`.
|
|
8851
|
+
if (actionId === 'filter-column' && !this.def().filterTemplate) {
|
|
8852
|
+
this.openFilterOverlay(field);
|
|
8853
|
+
return;
|
|
8854
|
+
}
|
|
8855
|
+
this.menuAction.emit({ field, actionId });
|
|
8856
|
+
}
|
|
8857
|
+
openFilterOverlay(seedField) {
|
|
8858
|
+
// Defer so the action-listbox has time to tear down its overlay before
|
|
8859
|
+
// we attach a new one at roughly the same location. Without this, the
|
|
8860
|
+
// lingering mouseup from the menu-item click can land on the freshly
|
|
8861
|
+
// mounted filter backdrop and close it instantly.
|
|
8862
|
+
setTimeout(() => {
|
|
8863
|
+
const overlay = this.filterOverlay();
|
|
8864
|
+
if (!overlay)
|
|
8865
|
+
return;
|
|
8866
|
+
overlay.open({
|
|
8867
|
+
columns: this.filterEngine.describeFilterableColumns(),
|
|
8868
|
+
model: { conditions: this.filterEngine.conditions().slice() },
|
|
8869
|
+
seedField,
|
|
8870
|
+
onChange: (next) => {
|
|
8871
|
+
this.filterEngine.setModel(next, 'replace');
|
|
8872
|
+
},
|
|
8873
|
+
});
|
|
8874
|
+
}, 0);
|
|
8174
8875
|
}
|
|
8175
8876
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MozGridHeaderCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8176
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: MozGridHeaderCellComponent, isStandalone: true, selector: "moz-grid-header-cell", inputs: { columnState: { classPropertyName: "columnState", publicName: "columnState", isSignal: true, isRequired: true, transformFunction: null }, def: { classPropertyName: "def", publicName: "def", isSignal: true, isRequired: true, transformFunction: null }, isLast: { classPropertyName: "isLast", publicName: "isLast", isSignal: true, isRequired: false, transformFunction: null }, pinnedEnd: { classPropertyName: "pinnedEnd", publicName: "pinnedEnd", isSignal: true, isRequired: false, transformFunction: null }, reorderable: { classPropertyName: "reorderable", publicName: "reorderable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sortClick: "sortClick", menuAction: "menuAction", resizeStart: "resizeStart" }, host: { properties: { "style.flex": "isLast() ? \"1 0 auto\" : \"0 0 auto\"", "style.width.px": "isLast() ? undefined : columnState().currentWidth", "style.min-width.px": "isLast() ? columnState().currentWidth : resolvedMinWidth()", "class.grid-header-cell-host--dragging": "isDragging()", "class.grid-header-cell-host--reorderable": "reorderable()" } }, ngImport: i0, template: "<div\n class=\"grid-header-cell\"\n [class.grid-header-cell--sorted]=\"columnState().sort !== null\"\n [class.grid-header-cell--last]=\"isLast()\"\n [class.grid-header-cell--pinned-end]=\"pinnedEnd()\"\n>\n <div class=\"grid-header-cell__content\" (click)=\"onHeaderClick($event)\">\n <span class=\"grid-header-cell__label\">{{ label() }}</span>\n @if (columnState().sort === 'asc') {\n <ChevronUp20 class=\"grid-header-cell__sort-icon\" />\n } @if (columnState().sort === 'desc') {\n <ChevronDown20 class=\"grid-header-cell__sort-icon\" />\n }\n </div>\n\n @if (!def().headerMenuDisabled) {\n <button\n type=\"button\"\n class=\"grid-header-cell__menu-trigger\"\n [attr.aria-label]=\"'Column settings for ' + label()\"\n [mozActionListboxTrigger]=\"menuItems()\"\n actionListboxPosition=\"below\"\n (itemClick)=\"onMenuItemClick($event)\"\n (click)=\"$event.stopPropagation()\"\n >\n <Settings20 />\n </button>\n } @if (def().resizable !== false && (!isLast() || pinnedEnd())) {\n <div\n class=\"grid-header-cell__resize-handle\"\n [class.grid-header-cell__resize-handle--left]=\"pinnedEnd()\"\n (mousedown)=\"resizeStart.emit($event)\"\n ></div>\n }\n</div>\n", styles: [":host{display:block;height:100%}.grid-header-cell{display:flex;align-items:center;position:relative;height:100%;padding:0 var(--spacing-s, 8px);border-right:1px solid var(--color-border-primary);-webkit-user-select:none;user-select:none;box-sizing:border-box;min-width:0;background:inherit}.grid-header-cell--pinned-end{border-right:none;border-left:1px solid var(--color-border-primary)}:host(:first-child) .grid-header-cell--pinned-end{border-left:none}.grid-header-cell--last{border-right:none}.grid-header-cell__content{display:flex;align-items:center;gap:var(--spacing-xs, 4px);flex:1;min-width:0;cursor:pointer}.grid-header-cell__label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text-secondary);font-family:LeroyMerlin,sans-serif;font-size:var(--font-size-50);font-weight:700;text-transform:uppercase}.grid-header-cell__sort-icon{flex-shrink:0;color:var(--color-text-primary)}.grid-header-cell__menu-trigger{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:28px;height:28px;padding:0;border:none;border-radius:var(--border-radius-s, 4px);background:transparent;cursor:pointer;color:var(--color-text-secondary);opacity:0;transition:opacity .15s ease}.grid-header-cell__menu-trigger:hover{background:var(--color-background-tertiary, rgba(0, 0, 0, .06));color:var(--color-text-primary)}.grid-header-cell:hover .grid-header-cell__menu-trigger{opacity:1}.grid-header-cell__resize-handle{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;z-index:1}.grid-header-cell__resize-handle:hover{background:var(--color-background-accent-inverse)}.grid-header-cell__resize-handle--left{right:auto;left:0}:host(.grid-header-cell-host--reorderable) .grid-header-cell__content{cursor:grab}:host(.grid-header-cell-host--dragging){outline:2px solid var(--color-background-accent-inverse);outline-offset:-2px;opacity:.85;z-index:1}\n"], dependencies: [{ kind: "component", type: ChevronDown20, selector: "ChevronDown20", inputs: ["hostClass"] }, { kind: "component", type: ChevronUp20, selector: "ChevronUp20", inputs: ["hostClass"] }, { kind: "component", type: Settings20, selector: "Settings20", inputs: ["hostClass"] }, { kind: "directive", type: MozActionListboxTriggerDirective, selector: "[mozActionListboxTrigger]", inputs: ["mozActionListboxTrigger", "actionListboxTitle", "actionListboxPosition"], outputs: ["itemClick"], exportAs: ["mozActionListboxTrigger"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8877
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: MozGridHeaderCellComponent, isStandalone: true, selector: "moz-grid-header-cell", inputs: { columnState: { classPropertyName: "columnState", publicName: "columnState", isSignal: true, isRequired: true, transformFunction: null }, def: { classPropertyName: "def", publicName: "def", isSignal: true, isRequired: true, transformFunction: null }, isLast: { classPropertyName: "isLast", publicName: "isLast", isSignal: true, isRequired: false, transformFunction: null }, pinnedEnd: { classPropertyName: "pinnedEnd", publicName: "pinnedEnd", isSignal: true, isRequired: false, transformFunction: null }, reorderable: { classPropertyName: "reorderable", publicName: "reorderable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sortClick: "sortClick", menuAction: "menuAction", resizeStart: "resizeStart" }, host: { properties: { "style.flex": "isLast() ? \"1 0 auto\" : \"0 0 auto\"", "style.width.px": "isLast() ? undefined : columnState().currentWidth", "style.min-width.px": "isLast() ? columnState().currentWidth : resolvedMinWidth()", "class.grid-header-cell-host--dragging": "isDragging()", "class.grid-header-cell-host--reorderable": "reorderable()" } }, viewQueries: [{ propertyName: "filterOverlay", first: true, predicate: MozGridFilterOverlayDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"grid-header-cell\"\n [class.grid-header-cell--sorted]=\"columnState().sort !== null\"\n [class.grid-header-cell--last]=\"isLast()\"\n [class.grid-header-cell--pinned-end]=\"pinnedEnd()\"\n>\n <div class=\"grid-header-cell__content\" (click)=\"onHeaderClick($event)\">\n <span class=\"grid-header-cell__label\">{{ label() }}</span>\n @if (columnState().sort === 'asc') {\n <ChevronUp20 class=\"grid-header-cell__sort-icon\" />\n } @if (columnState().sort === 'desc') {\n <ChevronDown20 class=\"grid-header-cell__sort-icon\" />\n }\n </div>\n\n @if (!def().headerMenuDisabled) {\n <button\n type=\"button\"\n class=\"grid-header-cell__menu-trigger\"\n [class.grid-header-cell__menu-trigger--filtered]=\"hasActiveFilter()\"\n [attr.aria-label]=\"'Column settings for ' + label()\"\n [attr.title]=\"filterTooltip()\"\n [mozActionListboxTrigger]=\"menuItems()\"\n actionListboxPosition=\"below\"\n mozGridFilterOverlay\n (itemClick)=\"onMenuItemClick($event)\"\n (click)=\"$event.stopPropagation()\"\n >\n @if (hasActiveFilter()) {\n <Filter20 />\n } @else {\n <Settings20 />\n }\n </button>\n } @if (def().resizable !== false && (!isLast() || pinnedEnd())) {\n <div\n class=\"grid-header-cell__resize-handle\"\n [class.grid-header-cell__resize-handle--left]=\"pinnedEnd()\"\n (mousedown)=\"resizeStart.emit($event)\"\n ></div>\n }\n</div>\n", styles: [":host{display:block;height:100%}.grid-header-cell{display:flex;align-items:center;position:relative;height:100%;padding:0 var(--spacing-s, 8px);border-right:1px solid var(--color-border-primary);-webkit-user-select:none;user-select:none;box-sizing:border-box;min-width:0;background:inherit}.grid-header-cell--pinned-end{border-right:none;border-left:1px solid var(--color-border-primary)}:host(:first-child) .grid-header-cell--pinned-end{border-left:none}.grid-header-cell--last{border-right:none}.grid-header-cell__content{display:flex;align-items:center;gap:var(--spacing-xs, 4px);flex:1;min-width:0;cursor:pointer}.grid-header-cell__label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text-secondary);font-family:LeroyMerlin,sans-serif;font-size:var(--font-size-50);font-weight:700;text-transform:uppercase}.grid-header-cell__sort-icon{flex-shrink:0;color:var(--color-text-primary)}.grid-header-cell__menu-trigger{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:28px;height:28px;padding:0;border:none;border-radius:var(--border-radius-s, 4px);background:transparent;cursor:pointer;color:var(--color-text-secondary);opacity:0;transition:opacity .15s ease}.grid-header-cell__menu-trigger:hover{background:var(--color-background-tertiary, rgba(0, 0, 0, .06));color:var(--color-text-primary)}.grid-header-cell:hover .grid-header-cell__menu-trigger{opacity:1}.grid-header-cell__menu-trigger--filtered{opacity:1;color:var(--Status-Standalone-element-Primary, #0071ce)}.grid-header-cell__resize-handle{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;z-index:1}.grid-header-cell__resize-handle:hover{background:var(--color-background-accent-inverse)}.grid-header-cell__resize-handle--left{right:auto;left:0}:host(.grid-header-cell-host--reorderable) .grid-header-cell__content{cursor:grab}:host(.grid-header-cell-host--dragging){outline:2px solid var(--color-background-accent-inverse);outline-offset:-2px;opacity:.85;z-index:1}\n"], dependencies: [{ kind: "component", type: ChevronDown20, selector: "ChevronDown20", inputs: ["hostClass"] }, { kind: "component", type: ChevronUp20, selector: "ChevronUp20", inputs: ["hostClass"] }, { kind: "component", type: Settings20, selector: "Settings20", inputs: ["hostClass"] }, { kind: "component", type: Filter20, selector: "Filter20", inputs: ["hostClass"] }, { kind: "directive", type: MozActionListboxTriggerDirective, selector: "[mozActionListboxTrigger]", inputs: ["mozActionListboxTrigger", "actionListboxTitle", "actionListboxPosition"], outputs: ["itemClick"], exportAs: ["mozActionListboxTrigger"] }, { kind: "directive", type: MozGridFilterOverlayDirective, selector: "[mozGridFilterOverlay]", exportAs: ["mozGridFilterOverlay"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8177
8878
|
}
|
|
8178
8879
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MozGridHeaderCellComponent, decorators: [{
|
|
8179
8880
|
type: Component,
|
|
8180
|
-
args: [{ selector: 'moz-grid-header-cell', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
8881
|
+
args: [{ selector: 'moz-grid-header-cell', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
8882
|
+
ChevronDown20,
|
|
8883
|
+
ChevronUp20,
|
|
8884
|
+
Settings20,
|
|
8885
|
+
Filter20,
|
|
8886
|
+
MozActionListboxTriggerDirective,
|
|
8887
|
+
MozGridFilterOverlayDirective,
|
|
8888
|
+
], host: {
|
|
8181
8889
|
'[style.flex]': 'isLast() ? "1 0 auto" : "0 0 auto"',
|
|
8182
8890
|
'[style.width.px]': 'isLast() ? undefined : columnState().currentWidth',
|
|
8183
8891
|
'[style.min-width.px]': 'isLast() ? columnState().currentWidth : resolvedMinWidth()',
|
|
8184
8892
|
'[class.grid-header-cell-host--dragging]': 'isDragging()',
|
|
8185
8893
|
'[class.grid-header-cell-host--reorderable]': 'reorderable()',
|
|
8186
|
-
}, template: "<div\n class=\"grid-header-cell\"\n [class.grid-header-cell--sorted]=\"columnState().sort !== null\"\n [class.grid-header-cell--last]=\"isLast()\"\n [class.grid-header-cell--pinned-end]=\"pinnedEnd()\"\n>\n <div class=\"grid-header-cell__content\" (click)=\"onHeaderClick($event)\">\n <span class=\"grid-header-cell__label\">{{ label() }}</span>\n @if (columnState().sort === 'asc') {\n <ChevronUp20 class=\"grid-header-cell__sort-icon\" />\n } @if (columnState().sort === 'desc') {\n <ChevronDown20 class=\"grid-header-cell__sort-icon\" />\n }\n </div>\n\n @if (!def().headerMenuDisabled) {\n <button\n type=\"button\"\n class=\"grid-header-cell__menu-trigger\"\n [attr.aria-label]=\"'Column settings for ' + label()\"\n [mozActionListboxTrigger]=\"menuItems()\"\n actionListboxPosition=\"below\"\n (itemClick)=\"onMenuItemClick($event)\"\n (click)=\"$event.stopPropagation()\"\n >\n <Settings20 />\n </button>\n } @if (def().resizable !== false && (!isLast() || pinnedEnd())) {\n <div\n class=\"grid-header-cell__resize-handle\"\n [class.grid-header-cell__resize-handle--left]=\"pinnedEnd()\"\n (mousedown)=\"resizeStart.emit($event)\"\n ></div>\n }\n</div>\n", styles: [":host{display:block;height:100%}.grid-header-cell{display:flex;align-items:center;position:relative;height:100%;padding:0 var(--spacing-s, 8px);border-right:1px solid var(--color-border-primary);-webkit-user-select:none;user-select:none;box-sizing:border-box;min-width:0;background:inherit}.grid-header-cell--pinned-end{border-right:none;border-left:1px solid var(--color-border-primary)}:host(:first-child) .grid-header-cell--pinned-end{border-left:none}.grid-header-cell--last{border-right:none}.grid-header-cell__content{display:flex;align-items:center;gap:var(--spacing-xs, 4px);flex:1;min-width:0;cursor:pointer}.grid-header-cell__label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text-secondary);font-family:LeroyMerlin,sans-serif;font-size:var(--font-size-50);font-weight:700;text-transform:uppercase}.grid-header-cell__sort-icon{flex-shrink:0;color:var(--color-text-primary)}.grid-header-cell__menu-trigger{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:28px;height:28px;padding:0;border:none;border-radius:var(--border-radius-s, 4px);background:transparent;cursor:pointer;color:var(--color-text-secondary);opacity:0;transition:opacity .15s ease}.grid-header-cell__menu-trigger:hover{background:var(--color-background-tertiary, rgba(0, 0, 0, .06));color:var(--color-text-primary)}.grid-header-cell:hover .grid-header-cell__menu-trigger{opacity:1}.grid-header-cell__resize-handle{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;z-index:1}.grid-header-cell__resize-handle:hover{background:var(--color-background-accent-inverse)}.grid-header-cell__resize-handle--left{right:auto;left:0}:host(.grid-header-cell-host--reorderable) .grid-header-cell__content{cursor:grab}:host(.grid-header-cell-host--dragging){outline:2px solid var(--color-background-accent-inverse);outline-offset:-2px;opacity:.85;z-index:1}\n"] }]
|
|
8187
|
-
}], propDecorators: { columnState: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnState", required: true }] }], def: [{ type: i0.Input, args: [{ isSignal: true, alias: "def", required: true }] }], isLast: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLast", required: false }] }], pinnedEnd: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedEnd", required: false }] }], reorderable: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderable", required: false }] }], sortClick: [{ type: i0.Output, args: ["sortClick"] }], menuAction: [{ type: i0.Output, args: ["menuAction"] }], resizeStart: [{ type: i0.Output, args: ["resizeStart"] }] } });
|
|
8894
|
+
}, template: "<div\n class=\"grid-header-cell\"\n [class.grid-header-cell--sorted]=\"columnState().sort !== null\"\n [class.grid-header-cell--last]=\"isLast()\"\n [class.grid-header-cell--pinned-end]=\"pinnedEnd()\"\n>\n <div class=\"grid-header-cell__content\" (click)=\"onHeaderClick($event)\">\n <span class=\"grid-header-cell__label\">{{ label() }}</span>\n @if (columnState().sort === 'asc') {\n <ChevronUp20 class=\"grid-header-cell__sort-icon\" />\n } @if (columnState().sort === 'desc') {\n <ChevronDown20 class=\"grid-header-cell__sort-icon\" />\n }\n </div>\n\n @if (!def().headerMenuDisabled) {\n <button\n type=\"button\"\n class=\"grid-header-cell__menu-trigger\"\n [class.grid-header-cell__menu-trigger--filtered]=\"hasActiveFilter()\"\n [attr.aria-label]=\"'Column settings for ' + label()\"\n [attr.title]=\"filterTooltip()\"\n [mozActionListboxTrigger]=\"menuItems()\"\n actionListboxPosition=\"below\"\n mozGridFilterOverlay\n (itemClick)=\"onMenuItemClick($event)\"\n (click)=\"$event.stopPropagation()\"\n >\n @if (hasActiveFilter()) {\n <Filter20 />\n } @else {\n <Settings20 />\n }\n </button>\n } @if (def().resizable !== false && (!isLast() || pinnedEnd())) {\n <div\n class=\"grid-header-cell__resize-handle\"\n [class.grid-header-cell__resize-handle--left]=\"pinnedEnd()\"\n (mousedown)=\"resizeStart.emit($event)\"\n ></div>\n }\n</div>\n", styles: [":host{display:block;height:100%}.grid-header-cell{display:flex;align-items:center;position:relative;height:100%;padding:0 var(--spacing-s, 8px);border-right:1px solid var(--color-border-primary);-webkit-user-select:none;user-select:none;box-sizing:border-box;min-width:0;background:inherit}.grid-header-cell--pinned-end{border-right:none;border-left:1px solid var(--color-border-primary)}:host(:first-child) .grid-header-cell--pinned-end{border-left:none}.grid-header-cell--last{border-right:none}.grid-header-cell__content{display:flex;align-items:center;gap:var(--spacing-xs, 4px);flex:1;min-width:0;cursor:pointer}.grid-header-cell__label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text-secondary);font-family:LeroyMerlin,sans-serif;font-size:var(--font-size-50);font-weight:700;text-transform:uppercase}.grid-header-cell__sort-icon{flex-shrink:0;color:var(--color-text-primary)}.grid-header-cell__menu-trigger{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:28px;height:28px;padding:0;border:none;border-radius:var(--border-radius-s, 4px);background:transparent;cursor:pointer;color:var(--color-text-secondary);opacity:0;transition:opacity .15s ease}.grid-header-cell__menu-trigger:hover{background:var(--color-background-tertiary, rgba(0, 0, 0, .06));color:var(--color-text-primary)}.grid-header-cell:hover .grid-header-cell__menu-trigger{opacity:1}.grid-header-cell__menu-trigger--filtered{opacity:1;color:var(--Status-Standalone-element-Primary, #0071ce)}.grid-header-cell__resize-handle{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;z-index:1}.grid-header-cell__resize-handle:hover{background:var(--color-background-accent-inverse)}.grid-header-cell__resize-handle--left{right:auto;left:0}:host(.grid-header-cell-host--reorderable) .grid-header-cell__content{cursor:grab}:host(.grid-header-cell-host--dragging){outline:2px solid var(--color-background-accent-inverse);outline-offset:-2px;opacity:.85;z-index:1}\n"] }]
|
|
8895
|
+
}], propDecorators: { columnState: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnState", required: true }] }], def: [{ type: i0.Input, args: [{ isSignal: true, alias: "def", required: true }] }], isLast: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLast", required: false }] }], pinnedEnd: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedEnd", required: false }] }], reorderable: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderable", required: false }] }], filterOverlay: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MozGridFilterOverlayDirective), { isSignal: true }] }], sortClick: [{ type: i0.Output, args: ["sortClick"] }], menuAction: [{ type: i0.Output, args: ["menuAction"] }], resizeStart: [{ type: i0.Output, args: ["resizeStart"] }] } });
|
|
8188
8896
|
|
|
8189
8897
|
function trackDisplayRow(_index, row) {
|
|
8190
8898
|
if (row.type === 'group') {
|
|
@@ -8437,6 +9145,12 @@ class AutoSizeVirtualScrollStrategy {
|
|
|
8437
9145
|
const viewportSize = this._viewport.getViewportSize();
|
|
8438
9146
|
const dataLength = this._viewport.getDataLength();
|
|
8439
9147
|
if (dataLength === 0) {
|
|
9148
|
+
// IMPORTANT: also reset the cache. Otherwise, when data comes back to
|
|
9149
|
+
// the same length as before the empty state (e.g. filter matching N,
|
|
9150
|
+
// then 0, then N again), the range we compute below equals the stale
|
|
9151
|
+
// `_lastRenderedRange` and `setRenderedRange` is skipped — the viewport
|
|
9152
|
+
// stays stuck on empty until a scroll event forces a re-render.
|
|
9153
|
+
this._lastRenderedRange = { start: 0, end: 0 };
|
|
8440
9154
|
this._viewport.setRenderedRange({ start: 0, end: 0 });
|
|
8441
9155
|
this._viewport.setRenderedContentOffset(0);
|
|
8442
9156
|
return;
|
|
@@ -8584,8 +9298,9 @@ class AutoSizeVirtualScrollStrategy {
|
|
|
8584
9298
|
// Quick check: if the first child matches the default height,
|
|
8585
9299
|
// assume all rows are uniform and skip the full measurement pass.
|
|
8586
9300
|
const firstHeight = children[0].offsetHeight;
|
|
8587
|
-
if (firstHeight > 0 &&
|
|
8588
|
-
|
|
9301
|
+
if (firstHeight > 0 &&
|
|
9302
|
+
Math.abs(firstHeight - this._defaultItemSize) <= 0.5 &&
|
|
9303
|
+
this._heightMap.size === 0) {
|
|
8589
9304
|
return;
|
|
8590
9305
|
}
|
|
8591
9306
|
let changed = false;
|
|
@@ -8669,6 +9384,7 @@ class MozGridCellComponent {
|
|
|
8669
9384
|
cellSelectionEngine = inject(CellSelectionEngine);
|
|
8670
9385
|
validationEngine = inject(CellValidationEngine);
|
|
8671
9386
|
clipboard = inject(ClipboardEngine);
|
|
9387
|
+
gridEngine = inject(GridEngine);
|
|
8672
9388
|
elRef = inject((ElementRef));
|
|
8673
9389
|
preEditWidth = null;
|
|
8674
9390
|
constructor() {
|
|
@@ -8711,13 +9427,36 @@ class MozGridCellComponent {
|
|
|
8711
9427
|
const editorEl = this.elRef.nativeElement.querySelector('.grid-cell__editor');
|
|
8712
9428
|
if (!editorEl)
|
|
8713
9429
|
return;
|
|
8714
|
-
// Temporarily remove overflow constraint to measure natural content width
|
|
8715
9430
|
const cell = this.elRef.nativeElement.querySelector('.grid-cell');
|
|
9431
|
+
// The cell-level `overflow: hidden`, the editor's `width: 100%`, the
|
|
9432
|
+
// `flex-wrap: wrap` on `.grid-cell__editor-custom` and the global
|
|
9433
|
+
// `.grid-cell__editor ::ng-deep * { max-width: 100% }` rule all collapse
|
|
9434
|
+
// the editor's content back inside the current column width. Lift each of
|
|
9435
|
+
// those — on the editor and every descendant — so scrollWidth reports
|
|
9436
|
+
// the true natural width. Restore everything after measuring.
|
|
9437
|
+
const prevCellOverflow = cell?.style.overflow ?? '';
|
|
9438
|
+
const prevEditorCss = editorEl.style.cssText;
|
|
9439
|
+
const descendants = editorEl.querySelectorAll('*');
|
|
9440
|
+
const prevDescendantCss = [];
|
|
9441
|
+
descendants.forEach((el) => {
|
|
9442
|
+
prevDescendantCss.push(el.style.cssText);
|
|
9443
|
+
el.style.maxWidth = 'none';
|
|
9444
|
+
el.style.minWidth = 'max-content';
|
|
9445
|
+
el.style.flexWrap = 'nowrap';
|
|
9446
|
+
el.style.overflow = 'visible';
|
|
9447
|
+
});
|
|
8716
9448
|
if (cell)
|
|
8717
9449
|
cell.style.overflow = 'visible';
|
|
9450
|
+
editorEl.style.width = 'max-content';
|
|
9451
|
+
editorEl.style.maxWidth = 'none';
|
|
9452
|
+
editorEl.style.overflow = 'visible';
|
|
8718
9453
|
const contentWidth = editorEl.scrollWidth + 16; // 16 = cell horizontal padding (8px × 2)
|
|
8719
9454
|
if (cell)
|
|
8720
|
-
cell.style.overflow =
|
|
9455
|
+
cell.style.overflow = prevCellOverflow;
|
|
9456
|
+
editorEl.style.cssText = prevEditorCss;
|
|
9457
|
+
descendants.forEach((el, i) => {
|
|
9458
|
+
el.style.cssText = prevDescendantCss[i];
|
|
9459
|
+
});
|
|
8721
9460
|
if (contentWidth > currentWidth) {
|
|
8722
9461
|
this.state.updateColumnState(field, { currentWidth: contentWidth });
|
|
8723
9462
|
}
|
|
@@ -8784,7 +9523,15 @@ class MozGridCellComponent {
|
|
|
8784
9523
|
return this.cellSelectionEngine.isCellInFillRejectRange(this.rowIndex(), this.colIndex());
|
|
8785
9524
|
}, ...(ngDevMode ? [{ debugName: "isInFillRejectRange" }] : /* istanbul ignore next */ []));
|
|
8786
9525
|
cutEdges = computed(() => this.clipboard.cutEdges(this.rowIndex(), this.colIndex()), ...(ngDevMode ? [{ debugName: "cutEdges" }] : /* istanbul ignore next */ []));
|
|
8787
|
-
cellError = computed(() =>
|
|
9526
|
+
cellError = computed(() => {
|
|
9527
|
+
// Validation errors are keyed by sourceData index, but `rowIndex()` is a
|
|
9528
|
+
// display/paginated index. Resolve to the source index so errors show on
|
|
9529
|
+
// the right cells when sort / filter / grouping is active.
|
|
9530
|
+
const sourceIndex = this.gridEngine.displayIndexToSourceIndex(this.rowIndex());
|
|
9531
|
+
if (sourceIndex < 0)
|
|
9532
|
+
return null;
|
|
9533
|
+
return this.validationEngine.getCellError(sourceIndex, this.def().field);
|
|
9534
|
+
}, ...(ngDevMode ? [{ debugName: "cellError" }] : /* istanbul ignore next */ []));
|
|
8788
9535
|
onCellClick(event) {
|
|
8789
9536
|
// Shift+click: extend range from current focused cell to this cell
|
|
8790
9537
|
if (event.shiftKey) {
|
|
@@ -8888,7 +9635,7 @@ class MozGridCellComponent {
|
|
|
8888
9635
|
});
|
|
8889
9636
|
}
|
|
8890
9637
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MozGridCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8891
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: MozGridCellComponent, isStandalone: true, selector: "moz-grid-cell", inputs: { row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null }, rowIndex: { classPropertyName: "rowIndex", publicName: "rowIndex", isSignal: true, isRequired: true, transformFunction: null }, colIndex: { classPropertyName: "colIndex", publicName: "colIndex", isSignal: true, isRequired: true, transformFunction: null }, colState: { classPropertyName: "colState", publicName: "colState", isSignal: true, isRequired: true, transformFunction: null }, def: { classPropertyName: "def", publicName: "def", isSignal: true, isRequired: true, transformFunction: null }, isLast: { classPropertyName: "isLast", publicName: "isLast", isSignal: true, isRequired: false, transformFunction: null }, pinnedEnd: { classPropertyName: "pinnedEnd", publicName: "pinnedEnd", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { commitEdit: "commitEdit", cancelEdit: "cancelEdit" }, host: { properties: { "style.flex": "isLast() ? \"1 0 auto\" : \"0 0 auto\"", "style.width.px": "isLast() ? undefined : colState().currentWidth", "style.min-width.px": "isLast() ? colState().currentWidth : resolvedMinWidth()" } }, ngImport: i0, template: "<div\n class=\"grid-cell\"\n [class.grid-cell--focused]=\"isFocused()\"\n [class.grid-cell--in-range]=\"isInRange()\"\n [class.grid-cell--in-fill-range]=\"isInFillRange()\"\n [class.grid-cell--in-fill-reject-range]=\"isInFillRejectRange()\"\n [class.grid-cell--cut]=\"cutEdges().any\"\n [class.grid-cell--last]=\"isLast()\"\n [class.grid-cell--pinned-end]=\"pinnedEnd()\"\n [class.grid-cell--readonly]=\"!def().editable\"\n [class.grid-cell--error]=\"cellError()\"\n [attr.aria-invalid]=\"cellError() ? 'true' : null\"\n (click)=\"onCellClick($event)\"\n (dblclick)=\"onDoubleClick()\"\n (mousedown)=\"onMouseDown($event)\"\n (mouseenter)=\"onMouseEnter()\"\n>\n @if (isEditing()) {\n <div class=\"grid-cell__editor\" (focusout)=\"onEditorBlur($event)\">\n @if (editTemplate()) {\n <div class=\"grid-cell__editor-custom\">\n <ng-container\n [ngTemplateOutlet]=\"editTemplate()!\"\n [ngTemplateOutletContext]=\"{\n $implicit: value(),\n row: row(),\n field: def().field,\n draft: editState().draftValue,\n updateDraft: updateDraftFn,\n commitEdit: commitEditFn\n }\"\n />\n </div>\n } @else { @switch (editorType()) { @case ('text') {\n <input\n class=\"grid-cell__input grid-cell__input--plain\"\n type=\"text\"\n [value]=\"editState().draftValue\"\n (input)=\"onEditorInput($event)\"\n />\n } @case ('number') {\n <input\n class=\"grid-cell__input grid-cell__input--plain\"\n type=\"number\"\n [value]=\"editState().draftValue\"\n (input)=\"onEditorInput($event)\"\n />\n } @case ('select') {\n <moz-select\n name=\"cell-editor\"\n [options]=\"def().cellEditorOptions ?? []\"\n [ngModel]=\"editState().draftValue\"\n (change)=\"onSelectChange($event)\"\n [size]=\"'s'\"\n />\n } @case ('checkbox') {\n <moz-checkbox\n [id]=\"'grid-cell-editor-' + rowIndex() + '-' + colIndex()\"\n [ngModel]=\"!!editState().draftValue\"\n (change)=\"onCheckboxChange($event)\"\n />\n } @case ('date') {\n <moz-datepicker\n [id]=\"'grid-cell-editor-' + rowIndex() + '-' + colIndex()\"\n size=\"s\"\n [ngModel]=\"editState().draftValue\"\n (ngModelChange)=\"onDateChange($event)\"\n />\n } @default {\n <input\n class=\"grid-cell__input grid-cell__input--plain\"\n type=\"text\"\n [value]=\"editState().draftValue\"\n (input)=\"onEditorInput($event)\"\n />\n } } }\n </div>\n } @else { @if (cellTemplate()) {\n <div class=\"grid-cell__custom\">\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate()!\"\n [ngTemplateOutletContext]=\"{ $implicit: value(), row: row(), field: def().field }\"\n />\n </div>\n } @else {\n <span class=\"grid-cell__value\">{{ displayValue() }}</span>\n } } @if (cutEdges(); as edges) { @if (edges.top) {\n <div class=\"grid-cell__cut-mark grid-cell__cut-mark--top\"></div>\n } @if (edges.bottom) {\n <div class=\"grid-cell__cut-mark grid-cell__cut-mark--bottom\"></div>\n } @if (edges.left) {\n <div class=\"grid-cell__cut-mark grid-cell__cut-mark--left\"></div>\n } @if (edges.right) {\n <div class=\"grid-cell__cut-mark grid-cell__cut-mark--right\"></div>\n } } @if (isFocused() && !isEditing() && def().editable) {\n <div class=\"grid-cell__fill-handle\" (mousedown)=\"onFillHandleMouseDown($event)\"></div>\n } @if (cellError(); as error) {\n <div\n class=\"grid-cell__error-icon\"\n [mozTooltip]=\"error.message\"\n tooltipPosition=\"top\"\n aria-label=\"Erreur de validation\"\n >\n <ErrorFilled24 />\n </div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%;min-width:0}.grid-cell{display:flex;align-items:center;position:relative;padding:0 var(--spacing-s, 8px);height:100%;border-right:1px solid var(--color-border-primary);overflow:hidden;box-sizing:border-box;min-width:0;background:inherit;cursor:pointer}.grid-cell--last{border-right:none}.grid-cell--pinned-end{border-right:none;border-left:1px solid var(--color-border-primary)}:host(:first-child) .grid-cell--pinned-end{border-left:none}.grid-cell__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--font-size-s, 14px);color:var(--color-text-primary);position:relative;z-index:1}.grid-cell__editor{width:100%;min-width:0;max-width:100%;height:100%;display:flex;align-items:center;overflow:hidden;box-sizing:border-box;position:relative;z-index:1}.grid-cell__editor-custom{width:100%;min-width:0;max-width:100%;overflow:hidden;box-sizing:border-box;display:flex;align-items:center;flex-wrap:wrap;gap:4px}.grid-cell__editor input,.grid-cell__editor moz-select{width:100%;min-width:0;box-sizing:border-box}.grid-cell__input--plain{border:none;outline:none;background:transparent;font-family:inherit;font-size:var(--font-size-s, 14px);color:var(--color-text-primary);padding:0;height:100%;width:100%;min-width:0;box-sizing:border-box}.grid-cell__input--plain:focus{outline:none}.grid-cell__input--plain[type=number]::-webkit-inner-spin-button,.grid-cell__input--plain[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.grid-cell__input--plain[type=number]{-moz-appearance:textfield}.grid-cell__editor ::ng-deep .text-input{width:100%;min-width:0;box-sizing:border-box}.grid-cell__editor ::ng-deep .select,.grid-cell__editor ::ng-deep .select__trigger{min-width:0;width:100%}.grid-cell__editor ::ng-deep *{max-width:100%}.grid-cell__editor moz-datepicker{width:100%;min-width:0;box-sizing:border-box}.grid-cell__editor ::ng-deep .mc-datepicker,.grid-cell__editor ::ng-deep .mc-text-input{width:100%;min-width:0;box-sizing:border-box;height:28px;font-size:var(--font-size-xs, 12px)}.grid-cell__editor ::ng-deep moz-datepicker label{display:none}.grid-cell>*:not(.grid-cell__fill-handle){position:relative;z-index:1}.grid-cell:before{content:\"\";position:absolute;inset:3px;border-radius:4px;pointer-events:none;z-index:0}.grid-cell:hover:before{background:#f1f3f4}.grid-cell--focused:hover:before,.grid-cell--in-range:hover:before,.grid-cell--in-fill-range:hover:before,.grid-cell--in-fill-reject-range:hover:before{background:transparent}.grid-cell--focused{z-index:2}.grid-cell--focused:after{content:\"\";position:absolute;inset:0;border:2px solid var(--color-background-accent-inverse);border-radius:4px;pointer-events:none}.grid-cell--in-range{background:var(--color-background-accent)}.grid-cell--readonly .grid-cell__value{color:var(--color-text-secondary, #666)}.grid-cell--in-fill-range{background:#34a85314}.grid-cell--in-fill-range:after{content:\"\";position:absolute;inset:0;border:1px dashed var(--color-success, #34a853);border-radius:4px;pointer-events:none}.grid-cell--in-fill-reject-range{background:#ea302d1f;cursor:not-allowed;z-index:2}.grid-cell--in-fill-reject-range:after{content:\"\";position:absolute;inset:0;border:2px dashed var(--Status-Standalone-element-Error, #ea302d);border-radius:4px;pointer-events:none;z-index:3}.grid-cell--cut{background:#1a73e80f}.grid-cell__cut-mark{position:absolute;pointer-events:none;z-index:5;--cut-color: var(--color-background-accent-inverse, #1a73e8)}.grid-cell__cut-mark--top,.grid-cell__cut-mark--bottom{left:0;right:0;height:2px;background-image:linear-gradient(90deg,var(--cut-color) 50%,transparent 50%);background-size:8px 2px;background-repeat:repeat-x;animation:moz-grid-marching-ants-x .5s linear infinite}.grid-cell__cut-mark--top{top:0}.grid-cell__cut-mark--bottom{bottom:0}.grid-cell__cut-mark--left,.grid-cell__cut-mark--right{top:0;bottom:0;width:2px;background-image:linear-gradient(180deg,var(--cut-color) 50%,transparent 50%);background-size:2px 8px;background-repeat:repeat-y;animation:moz-grid-marching-ants-y .5s linear infinite}.grid-cell__cut-mark--left{left:0}.grid-cell__cut-mark--right{right:0}@keyframes moz-grid-marching-ants-x{0%{background-position-x:0}to{background-position-x:8px}}@keyframes moz-grid-marching-ants-y{0%{background-position-y:0}to{background-position-y:8px}}.grid-cell__fill-handle{position:absolute;right:0;bottom:0;width:8px;height:8px;background:var(--color-background-accent-inverse);cursor:crosshair;z-index:4}.grid-cell--error{background:var(--Background-Primary, #fff);outline:2px solid var(--Status-Border-Error, #ef5f5c);outline-offset:-2px;z-index:1}.grid-cell--error:hover:before{background:transparent}.grid-cell__error-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-left:auto;cursor:help;position:relative;z-index:2}.grid-cell__error-icon ::ng-deep svg{fill:var(--Status-Standalone-element-Error, #ea302d)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MozSelectComponent, selector: "moz-select", inputs: ["id", "name", "options", "placeholder", "isInvalid", "disabled", "readonly", "size"] }, { kind: "component", type: MozCheckboxComponent, selector: "moz-checkbox", inputs: ["id", "name", "label", "indeterminate", "isInvalid", "disabled", "indented"] }, { kind: "component", type: MozDatepickerComponent, selector: "moz-datepicker", inputs: ["id", "disabled", "readonly", "invalid", "error", "clearable", "size", "label"] }, { kind: "directive", type: MozTooltipDirective, selector: "[mozTooltip]", inputs: ["mozTooltip", "tooltipPosition", "tooltipNoPointer"] }, { kind: "component", type: ErrorFilled24, selector: "ErrorFilled24", inputs: ["hostClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
9638
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: MozGridCellComponent, isStandalone: true, selector: "moz-grid-cell", inputs: { row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null }, rowIndex: { classPropertyName: "rowIndex", publicName: "rowIndex", isSignal: true, isRequired: true, transformFunction: null }, colIndex: { classPropertyName: "colIndex", publicName: "colIndex", isSignal: true, isRequired: true, transformFunction: null }, colState: { classPropertyName: "colState", publicName: "colState", isSignal: true, isRequired: true, transformFunction: null }, def: { classPropertyName: "def", publicName: "def", isSignal: true, isRequired: true, transformFunction: null }, isLast: { classPropertyName: "isLast", publicName: "isLast", isSignal: true, isRequired: false, transformFunction: null }, pinnedEnd: { classPropertyName: "pinnedEnd", publicName: "pinnedEnd", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { commitEdit: "commitEdit", cancelEdit: "cancelEdit" }, host: { properties: { "style.flex": "isLast() ? \"1 0 auto\" : \"0 0 auto\"", "style.width.px": "isLast() ? undefined : colState().currentWidth", "style.min-width.px": "isLast() ? colState().currentWidth : resolvedMinWidth()" } }, ngImport: i0, template: "<div\n class=\"grid-cell\"\n [class.grid-cell--focused]=\"isFocused()\"\n [class.grid-cell--in-range]=\"isInRange()\"\n [class.grid-cell--in-fill-range]=\"isInFillRange()\"\n [class.grid-cell--in-fill-reject-range]=\"isInFillRejectRange()\"\n [class.grid-cell--cut]=\"cutEdges().any\"\n [class.grid-cell--last]=\"isLast()\"\n [class.grid-cell--pinned-end]=\"pinnedEnd()\"\n [class.grid-cell--readonly]=\"!def().editable\"\n [class.grid-cell--error]=\"cellError()\"\n [attr.aria-invalid]=\"cellError() ? 'true' : null\"\n (click)=\"onCellClick($event)\"\n (dblclick)=\"onDoubleClick()\"\n (mousedown)=\"onMouseDown($event)\"\n (mouseenter)=\"onMouseEnter()\"\n>\n @if (isEditing()) {\n <div class=\"grid-cell__editor\" (focusout)=\"onEditorBlur($event)\">\n @if (editTemplate()) {\n <div class=\"grid-cell__editor-custom\">\n <ng-container\n [ngTemplateOutlet]=\"editTemplate()!\"\n [ngTemplateOutletContext]=\"{\n $implicit: value(),\n row: row(),\n field: def().field,\n draft: editState().draftValue,\n updateDraft: updateDraftFn,\n commitEdit: commitEditFn\n }\"\n />\n </div>\n } @else { @switch (editorType()) { @case ('text') {\n <input\n class=\"grid-cell__input grid-cell__input--plain\"\n type=\"text\"\n [value]=\"editState().draftValue\"\n (input)=\"onEditorInput($event)\"\n />\n } @case ('number') {\n <input\n class=\"grid-cell__input grid-cell__input--plain\"\n type=\"number\"\n [value]=\"editState().draftValue\"\n (input)=\"onEditorInput($event)\"\n />\n } @case ('select') {\n <moz-select\n name=\"cell-editor\"\n [options]=\"def().cellEditorOptions ?? []\"\n [ngModel]=\"editState().draftValue\"\n (change)=\"onSelectChange($event)\"\n [size]=\"'s'\"\n />\n } @case ('checkbox') {\n <moz-checkbox\n [id]=\"'grid-cell-editor-' + rowIndex() + '-' + colIndex()\"\n [ngModel]=\"!!editState().draftValue\"\n (change)=\"onCheckboxChange($event)\"\n />\n } @case ('date') {\n <moz-datepicker\n [id]=\"'grid-cell-editor-' + rowIndex() + '-' + colIndex()\"\n size=\"s\"\n [ngModel]=\"editState().draftValue\"\n (ngModelChange)=\"onDateChange($event)\"\n />\n } @default {\n <input\n class=\"grid-cell__input grid-cell__input--plain\"\n type=\"text\"\n [value]=\"editState().draftValue\"\n (input)=\"onEditorInput($event)\"\n />\n } } }\n </div>\n } @else { @if (cellTemplate()) {\n <div class=\"grid-cell__custom\">\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate()!\"\n [ngTemplateOutletContext]=\"{ $implicit: value(), row: row(), field: def().field }\"\n />\n </div>\n } @else {\n <span class=\"grid-cell__value\">{{ displayValue() }}</span>\n } } @if (cutEdges(); as edges) { @if (edges.top) {\n <div class=\"grid-cell__cut-mark grid-cell__cut-mark--top\"></div>\n } @if (edges.bottom) {\n <div class=\"grid-cell__cut-mark grid-cell__cut-mark--bottom\"></div>\n } @if (edges.left) {\n <div class=\"grid-cell__cut-mark grid-cell__cut-mark--left\"></div>\n } @if (edges.right) {\n <div class=\"grid-cell__cut-mark grid-cell__cut-mark--right\"></div>\n } } @if (isFocused() && !isEditing() && def().editable) {\n <div class=\"grid-cell__fill-handle\" (mousedown)=\"onFillHandleMouseDown($event)\"></div>\n } @if (cellError(); as error) {\n <div\n class=\"grid-cell__error-icon\"\n [mozTooltip]=\"error.message\"\n tooltipPosition=\"top\"\n aria-label=\"Erreur de validation\"\n >\n <ErrorFilled24 />\n </div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%;min-width:0}.grid-cell{display:flex;align-items:center;position:relative;padding:0 var(--spacing-s, 8px);height:100%;border-right:1px solid var(--color-border-primary);overflow:hidden;box-sizing:border-box;min-width:0;background:inherit;cursor:pointer}.grid-cell--last{border-right:none}.grid-cell--pinned-end{border-right:none;border-left:1px solid var(--color-border-primary)}:host(:first-child) .grid-cell--pinned-end{border-left:none}.grid-cell__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--font-size-s, 14px);color:var(--color-text-primary);position:relative;z-index:1}.grid-cell__editor{width:100%;min-width:0;max-width:100%;height:100%;display:flex;align-items:center;overflow:hidden;box-sizing:border-box;position:relative;z-index:1}.grid-cell__editor-custom{width:100%;min-width:0;max-width:100%;overflow:hidden;box-sizing:border-box;display:flex;align-items:center;flex-wrap:wrap;gap:4px}.grid-cell__editor input,.grid-cell__editor moz-select{width:100%;min-width:0;box-sizing:border-box}.grid-cell__input--plain{border:none;outline:none;background:transparent;font-family:inherit;font-size:var(--font-size-s, 14px);color:var(--color-text-primary);padding:0;height:100%;width:100%;min-width:0;box-sizing:border-box}.grid-cell__input--plain:focus{outline:none}.grid-cell__input--plain[type=number]::-webkit-inner-spin-button,.grid-cell__input--plain[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.grid-cell__input--plain[type=number]{-moz-appearance:textfield}.grid-cell__editor ::ng-deep .text-input{width:100%;min-width:0;box-sizing:border-box}.grid-cell__editor ::ng-deep .select,.grid-cell__editor ::ng-deep .select__trigger{min-width:0;width:100%}.grid-cell__editor ::ng-deep *{max-width:100%}.grid-cell__editor moz-datepicker{width:100%;min-width:0;box-sizing:border-box}.grid-cell__editor ::ng-deep .mc-datepicker,.grid-cell__editor ::ng-deep .mc-text-input{width:100%;min-width:0;box-sizing:border-box;height:28px;font-size:var(--font-size-xs, 12px)}.grid-cell__editor ::ng-deep moz-datepicker label{display:none}.grid-cell>*:not(.grid-cell__fill-handle){position:relative;z-index:1}.grid-cell:before{content:\"\";position:absolute;inset:3px;border-radius:4px;pointer-events:none;z-index:0}.grid-cell:hover:before{background:#f1f3f4}.grid-cell--focused:hover:before,.grid-cell--in-range:hover:before,.grid-cell--in-fill-range:hover:before,.grid-cell--in-fill-reject-range:hover:before{background:transparent}.grid-cell--focused{z-index:2}.grid-cell--focused:after{content:\"\";position:absolute;inset:0;border:2px solid var(--color-background-accent-inverse);border-radius:4px;pointer-events:none}.grid-cell--in-range{background:var(--color-background-accent)}.grid-cell--readonly .grid-cell__value{color:var(--color-text-secondary, #666)}.grid-cell--in-fill-range{background:#34a85314}.grid-cell--in-fill-range:after{content:\"\";position:absolute;inset:0;border:1px dashed var(--color-success, #34a853);border-radius:4px;pointer-events:none}.grid-cell--in-fill-reject-range{background:#ea302d1f;cursor:not-allowed;z-index:2}.grid-cell--in-fill-reject-range:after{content:\"\";position:absolute;inset:0;border:2px dashed var(--Status-Standalone-element-Error, #ea302d);border-radius:4px;pointer-events:none;z-index:3}.grid-cell--cut{background:#1a73e80f}.grid-cell__cut-mark{position:absolute;pointer-events:none;z-index:5;--cut-color: var(--color-background-accent-inverse, #1a73e8)}.grid-cell__cut-mark--top,.grid-cell__cut-mark--bottom{left:0;right:0;height:2px;background-image:linear-gradient(90deg,var(--cut-color) 50%,transparent 50%);background-size:8px 2px;background-repeat:repeat-x;animation:moz-grid-marching-ants-x .5s linear infinite}.grid-cell__cut-mark--top{top:0}.grid-cell__cut-mark--bottom{bottom:0}.grid-cell__cut-mark--left,.grid-cell__cut-mark--right{top:0;bottom:0;width:2px;background-image:linear-gradient(180deg,var(--cut-color) 50%,transparent 50%);background-size:2px 8px;background-repeat:repeat-y;animation:moz-grid-marching-ants-y .5s linear infinite}.grid-cell__cut-mark--left{left:0}.grid-cell__cut-mark--right{right:0}@keyframes moz-grid-marching-ants-x{0%{background-position-x:0}to{background-position-x:8px}}@keyframes moz-grid-marching-ants-y{0%{background-position-y:0}to{background-position-y:8px}}.grid-cell__fill-handle{position:absolute;right:0;bottom:0;width:8px;height:8px;background:var(--color-background-accent-inverse);cursor:crosshair;z-index:4}.grid-cell--error{outline:1px solid var(--Status-Border-Error, #ef5f5c);outline-offset:-2px;z-index:1;border-radius:4px}.grid-cell--error:hover:before{background:transparent}.grid-cell__error-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-left:auto;cursor:help;position:relative;z-index:2;fill:var(--Status-Standalone-element-Error, #ea302d)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MozSelectComponent, selector: "moz-select", inputs: ["id", "name", "options", "placeholder", "isInvalid", "disabled", "readonly", "size"] }, { kind: "component", type: MozCheckboxComponent, selector: "moz-checkbox", inputs: ["id", "name", "label", "indeterminate", "isInvalid", "disabled", "indented"] }, { kind: "component", type: MozDatepickerComponent, selector: "moz-datepicker", inputs: ["id", "disabled", "readonly", "invalid", "error", "clearable", "size", "label"] }, { kind: "directive", type: MozTooltipDirective, selector: "[mozTooltip]", inputs: ["mozTooltip", "tooltipPosition", "tooltipNoPointer"] }, { kind: "component", type: ErrorFilled24, selector: "ErrorFilled24", inputs: ["hostClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8892
9639
|
}
|
|
8893
9640
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MozGridCellComponent, decorators: [{
|
|
8894
9641
|
type: Component,
|
|
@@ -8904,7 +9651,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
8904
9651
|
'[style.flex]': 'isLast() ? "1 0 auto" : "0 0 auto"',
|
|
8905
9652
|
'[style.width.px]': 'isLast() ? undefined : colState().currentWidth',
|
|
8906
9653
|
'[style.min-width.px]': 'isLast() ? colState().currentWidth : resolvedMinWidth()',
|
|
8907
|
-
}, template: "<div\n class=\"grid-cell\"\n [class.grid-cell--focused]=\"isFocused()\"\n [class.grid-cell--in-range]=\"isInRange()\"\n [class.grid-cell--in-fill-range]=\"isInFillRange()\"\n [class.grid-cell--in-fill-reject-range]=\"isInFillRejectRange()\"\n [class.grid-cell--cut]=\"cutEdges().any\"\n [class.grid-cell--last]=\"isLast()\"\n [class.grid-cell--pinned-end]=\"pinnedEnd()\"\n [class.grid-cell--readonly]=\"!def().editable\"\n [class.grid-cell--error]=\"cellError()\"\n [attr.aria-invalid]=\"cellError() ? 'true' : null\"\n (click)=\"onCellClick($event)\"\n (dblclick)=\"onDoubleClick()\"\n (mousedown)=\"onMouseDown($event)\"\n (mouseenter)=\"onMouseEnter()\"\n>\n @if (isEditing()) {\n <div class=\"grid-cell__editor\" (focusout)=\"onEditorBlur($event)\">\n @if (editTemplate()) {\n <div class=\"grid-cell__editor-custom\">\n <ng-container\n [ngTemplateOutlet]=\"editTemplate()!\"\n [ngTemplateOutletContext]=\"{\n $implicit: value(),\n row: row(),\n field: def().field,\n draft: editState().draftValue,\n updateDraft: updateDraftFn,\n commitEdit: commitEditFn\n }\"\n />\n </div>\n } @else { @switch (editorType()) { @case ('text') {\n <input\n class=\"grid-cell__input grid-cell__input--plain\"\n type=\"text\"\n [value]=\"editState().draftValue\"\n (input)=\"onEditorInput($event)\"\n />\n } @case ('number') {\n <input\n class=\"grid-cell__input grid-cell__input--plain\"\n type=\"number\"\n [value]=\"editState().draftValue\"\n (input)=\"onEditorInput($event)\"\n />\n } @case ('select') {\n <moz-select\n name=\"cell-editor\"\n [options]=\"def().cellEditorOptions ?? []\"\n [ngModel]=\"editState().draftValue\"\n (change)=\"onSelectChange($event)\"\n [size]=\"'s'\"\n />\n } @case ('checkbox') {\n <moz-checkbox\n [id]=\"'grid-cell-editor-' + rowIndex() + '-' + colIndex()\"\n [ngModel]=\"!!editState().draftValue\"\n (change)=\"onCheckboxChange($event)\"\n />\n } @case ('date') {\n <moz-datepicker\n [id]=\"'grid-cell-editor-' + rowIndex() + '-' + colIndex()\"\n size=\"s\"\n [ngModel]=\"editState().draftValue\"\n (ngModelChange)=\"onDateChange($event)\"\n />\n } @default {\n <input\n class=\"grid-cell__input grid-cell__input--plain\"\n type=\"text\"\n [value]=\"editState().draftValue\"\n (input)=\"onEditorInput($event)\"\n />\n } } }\n </div>\n } @else { @if (cellTemplate()) {\n <div class=\"grid-cell__custom\">\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate()!\"\n [ngTemplateOutletContext]=\"{ $implicit: value(), row: row(), field: def().field }\"\n />\n </div>\n } @else {\n <span class=\"grid-cell__value\">{{ displayValue() }}</span>\n } } @if (cutEdges(); as edges) { @if (edges.top) {\n <div class=\"grid-cell__cut-mark grid-cell__cut-mark--top\"></div>\n } @if (edges.bottom) {\n <div class=\"grid-cell__cut-mark grid-cell__cut-mark--bottom\"></div>\n } @if (edges.left) {\n <div class=\"grid-cell__cut-mark grid-cell__cut-mark--left\"></div>\n } @if (edges.right) {\n <div class=\"grid-cell__cut-mark grid-cell__cut-mark--right\"></div>\n } } @if (isFocused() && !isEditing() && def().editable) {\n <div class=\"grid-cell__fill-handle\" (mousedown)=\"onFillHandleMouseDown($event)\"></div>\n } @if (cellError(); as error) {\n <div\n class=\"grid-cell__error-icon\"\n [mozTooltip]=\"error.message\"\n tooltipPosition=\"top\"\n aria-label=\"Erreur de validation\"\n >\n <ErrorFilled24 />\n </div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%;min-width:0}.grid-cell{display:flex;align-items:center;position:relative;padding:0 var(--spacing-s, 8px);height:100%;border-right:1px solid var(--color-border-primary);overflow:hidden;box-sizing:border-box;min-width:0;background:inherit;cursor:pointer}.grid-cell--last{border-right:none}.grid-cell--pinned-end{border-right:none;border-left:1px solid var(--color-border-primary)}:host(:first-child) .grid-cell--pinned-end{border-left:none}.grid-cell__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--font-size-s, 14px);color:var(--color-text-primary);position:relative;z-index:1}.grid-cell__editor{width:100%;min-width:0;max-width:100%;height:100%;display:flex;align-items:center;overflow:hidden;box-sizing:border-box;position:relative;z-index:1}.grid-cell__editor-custom{width:100%;min-width:0;max-width:100%;overflow:hidden;box-sizing:border-box;display:flex;align-items:center;flex-wrap:wrap;gap:4px}.grid-cell__editor input,.grid-cell__editor moz-select{width:100%;min-width:0;box-sizing:border-box}.grid-cell__input--plain{border:none;outline:none;background:transparent;font-family:inherit;font-size:var(--font-size-s, 14px);color:var(--color-text-primary);padding:0;height:100%;width:100%;min-width:0;box-sizing:border-box}.grid-cell__input--plain:focus{outline:none}.grid-cell__input--plain[type=number]::-webkit-inner-spin-button,.grid-cell__input--plain[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.grid-cell__input--plain[type=number]{-moz-appearance:textfield}.grid-cell__editor ::ng-deep .text-input{width:100%;min-width:0;box-sizing:border-box}.grid-cell__editor ::ng-deep .select,.grid-cell__editor ::ng-deep .select__trigger{min-width:0;width:100%}.grid-cell__editor ::ng-deep *{max-width:100%}.grid-cell__editor moz-datepicker{width:100%;min-width:0;box-sizing:border-box}.grid-cell__editor ::ng-deep .mc-datepicker,.grid-cell__editor ::ng-deep .mc-text-input{width:100%;min-width:0;box-sizing:border-box;height:28px;font-size:var(--font-size-xs, 12px)}.grid-cell__editor ::ng-deep moz-datepicker label{display:none}.grid-cell>*:not(.grid-cell__fill-handle){position:relative;z-index:1}.grid-cell:before{content:\"\";position:absolute;inset:3px;border-radius:4px;pointer-events:none;z-index:0}.grid-cell:hover:before{background:#f1f3f4}.grid-cell--focused:hover:before,.grid-cell--in-range:hover:before,.grid-cell--in-fill-range:hover:before,.grid-cell--in-fill-reject-range:hover:before{background:transparent}.grid-cell--focused{z-index:2}.grid-cell--focused:after{content:\"\";position:absolute;inset:0;border:2px solid var(--color-background-accent-inverse);border-radius:4px;pointer-events:none}.grid-cell--in-range{background:var(--color-background-accent)}.grid-cell--readonly .grid-cell__value{color:var(--color-text-secondary, #666)}.grid-cell--in-fill-range{background:#34a85314}.grid-cell--in-fill-range:after{content:\"\";position:absolute;inset:0;border:1px dashed var(--color-success, #34a853);border-radius:4px;pointer-events:none}.grid-cell--in-fill-reject-range{background:#ea302d1f;cursor:not-allowed;z-index:2}.grid-cell--in-fill-reject-range:after{content:\"\";position:absolute;inset:0;border:2px dashed var(--Status-Standalone-element-Error, #ea302d);border-radius:4px;pointer-events:none;z-index:3}.grid-cell--cut{background:#1a73e80f}.grid-cell__cut-mark{position:absolute;pointer-events:none;z-index:5;--cut-color: var(--color-background-accent-inverse, #1a73e8)}.grid-cell__cut-mark--top,.grid-cell__cut-mark--bottom{left:0;right:0;height:2px;background-image:linear-gradient(90deg,var(--cut-color) 50%,transparent 50%);background-size:8px 2px;background-repeat:repeat-x;animation:moz-grid-marching-ants-x .5s linear infinite}.grid-cell__cut-mark--top{top:0}.grid-cell__cut-mark--bottom{bottom:0}.grid-cell__cut-mark--left,.grid-cell__cut-mark--right{top:0;bottom:0;width:2px;background-image:linear-gradient(180deg,var(--cut-color) 50%,transparent 50%);background-size:2px 8px;background-repeat:repeat-y;animation:moz-grid-marching-ants-y .5s linear infinite}.grid-cell__cut-mark--left{left:0}.grid-cell__cut-mark--right{right:0}@keyframes moz-grid-marching-ants-x{0%{background-position-x:0}to{background-position-x:8px}}@keyframes moz-grid-marching-ants-y{0%{background-position-y:0}to{background-position-y:8px}}.grid-cell__fill-handle{position:absolute;right:0;bottom:0;width:8px;height:8px;background:var(--color-background-accent-inverse);cursor:crosshair;z-index:4}.grid-cell--error{
|
|
9654
|
+
}, template: "<div\n class=\"grid-cell\"\n [class.grid-cell--focused]=\"isFocused()\"\n [class.grid-cell--in-range]=\"isInRange()\"\n [class.grid-cell--in-fill-range]=\"isInFillRange()\"\n [class.grid-cell--in-fill-reject-range]=\"isInFillRejectRange()\"\n [class.grid-cell--cut]=\"cutEdges().any\"\n [class.grid-cell--last]=\"isLast()\"\n [class.grid-cell--pinned-end]=\"pinnedEnd()\"\n [class.grid-cell--readonly]=\"!def().editable\"\n [class.grid-cell--error]=\"cellError()\"\n [attr.aria-invalid]=\"cellError() ? 'true' : null\"\n (click)=\"onCellClick($event)\"\n (dblclick)=\"onDoubleClick()\"\n (mousedown)=\"onMouseDown($event)\"\n (mouseenter)=\"onMouseEnter()\"\n>\n @if (isEditing()) {\n <div class=\"grid-cell__editor\" (focusout)=\"onEditorBlur($event)\">\n @if (editTemplate()) {\n <div class=\"grid-cell__editor-custom\">\n <ng-container\n [ngTemplateOutlet]=\"editTemplate()!\"\n [ngTemplateOutletContext]=\"{\n $implicit: value(),\n row: row(),\n field: def().field,\n draft: editState().draftValue,\n updateDraft: updateDraftFn,\n commitEdit: commitEditFn\n }\"\n />\n </div>\n } @else { @switch (editorType()) { @case ('text') {\n <input\n class=\"grid-cell__input grid-cell__input--plain\"\n type=\"text\"\n [value]=\"editState().draftValue\"\n (input)=\"onEditorInput($event)\"\n />\n } @case ('number') {\n <input\n class=\"grid-cell__input grid-cell__input--plain\"\n type=\"number\"\n [value]=\"editState().draftValue\"\n (input)=\"onEditorInput($event)\"\n />\n } @case ('select') {\n <moz-select\n name=\"cell-editor\"\n [options]=\"def().cellEditorOptions ?? []\"\n [ngModel]=\"editState().draftValue\"\n (change)=\"onSelectChange($event)\"\n [size]=\"'s'\"\n />\n } @case ('checkbox') {\n <moz-checkbox\n [id]=\"'grid-cell-editor-' + rowIndex() + '-' + colIndex()\"\n [ngModel]=\"!!editState().draftValue\"\n (change)=\"onCheckboxChange($event)\"\n />\n } @case ('date') {\n <moz-datepicker\n [id]=\"'grid-cell-editor-' + rowIndex() + '-' + colIndex()\"\n size=\"s\"\n [ngModel]=\"editState().draftValue\"\n (ngModelChange)=\"onDateChange($event)\"\n />\n } @default {\n <input\n class=\"grid-cell__input grid-cell__input--plain\"\n type=\"text\"\n [value]=\"editState().draftValue\"\n (input)=\"onEditorInput($event)\"\n />\n } } }\n </div>\n } @else { @if (cellTemplate()) {\n <div class=\"grid-cell__custom\">\n <ng-container\n [ngTemplateOutlet]=\"cellTemplate()!\"\n [ngTemplateOutletContext]=\"{ $implicit: value(), row: row(), field: def().field }\"\n />\n </div>\n } @else {\n <span class=\"grid-cell__value\">{{ displayValue() }}</span>\n } } @if (cutEdges(); as edges) { @if (edges.top) {\n <div class=\"grid-cell__cut-mark grid-cell__cut-mark--top\"></div>\n } @if (edges.bottom) {\n <div class=\"grid-cell__cut-mark grid-cell__cut-mark--bottom\"></div>\n } @if (edges.left) {\n <div class=\"grid-cell__cut-mark grid-cell__cut-mark--left\"></div>\n } @if (edges.right) {\n <div class=\"grid-cell__cut-mark grid-cell__cut-mark--right\"></div>\n } } @if (isFocused() && !isEditing() && def().editable) {\n <div class=\"grid-cell__fill-handle\" (mousedown)=\"onFillHandleMouseDown($event)\"></div>\n } @if (cellError(); as error) {\n <div\n class=\"grid-cell__error-icon\"\n [mozTooltip]=\"error.message\"\n tooltipPosition=\"top\"\n aria-label=\"Erreur de validation\"\n >\n <ErrorFilled24 />\n </div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%;min-width:0}.grid-cell{display:flex;align-items:center;position:relative;padding:0 var(--spacing-s, 8px);height:100%;border-right:1px solid var(--color-border-primary);overflow:hidden;box-sizing:border-box;min-width:0;background:inherit;cursor:pointer}.grid-cell--last{border-right:none}.grid-cell--pinned-end{border-right:none;border-left:1px solid var(--color-border-primary)}:host(:first-child) .grid-cell--pinned-end{border-left:none}.grid-cell__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--font-size-s, 14px);color:var(--color-text-primary);position:relative;z-index:1}.grid-cell__editor{width:100%;min-width:0;max-width:100%;height:100%;display:flex;align-items:center;overflow:hidden;box-sizing:border-box;position:relative;z-index:1}.grid-cell__editor-custom{width:100%;min-width:0;max-width:100%;overflow:hidden;box-sizing:border-box;display:flex;align-items:center;flex-wrap:wrap;gap:4px}.grid-cell__editor input,.grid-cell__editor moz-select{width:100%;min-width:0;box-sizing:border-box}.grid-cell__input--plain{border:none;outline:none;background:transparent;font-family:inherit;font-size:var(--font-size-s, 14px);color:var(--color-text-primary);padding:0;height:100%;width:100%;min-width:0;box-sizing:border-box}.grid-cell__input--plain:focus{outline:none}.grid-cell__input--plain[type=number]::-webkit-inner-spin-button,.grid-cell__input--plain[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.grid-cell__input--plain[type=number]{-moz-appearance:textfield}.grid-cell__editor ::ng-deep .text-input{width:100%;min-width:0;box-sizing:border-box}.grid-cell__editor ::ng-deep .select,.grid-cell__editor ::ng-deep .select__trigger{min-width:0;width:100%}.grid-cell__editor ::ng-deep *{max-width:100%}.grid-cell__editor moz-datepicker{width:100%;min-width:0;box-sizing:border-box}.grid-cell__editor ::ng-deep .mc-datepicker,.grid-cell__editor ::ng-deep .mc-text-input{width:100%;min-width:0;box-sizing:border-box;height:28px;font-size:var(--font-size-xs, 12px)}.grid-cell__editor ::ng-deep moz-datepicker label{display:none}.grid-cell>*:not(.grid-cell__fill-handle){position:relative;z-index:1}.grid-cell:before{content:\"\";position:absolute;inset:3px;border-radius:4px;pointer-events:none;z-index:0}.grid-cell:hover:before{background:#f1f3f4}.grid-cell--focused:hover:before,.grid-cell--in-range:hover:before,.grid-cell--in-fill-range:hover:before,.grid-cell--in-fill-reject-range:hover:before{background:transparent}.grid-cell--focused{z-index:2}.grid-cell--focused:after{content:\"\";position:absolute;inset:0;border:2px solid var(--color-background-accent-inverse);border-radius:4px;pointer-events:none}.grid-cell--in-range{background:var(--color-background-accent)}.grid-cell--readonly .grid-cell__value{color:var(--color-text-secondary, #666)}.grid-cell--in-fill-range{background:#34a85314}.grid-cell--in-fill-range:after{content:\"\";position:absolute;inset:0;border:1px dashed var(--color-success, #34a853);border-radius:4px;pointer-events:none}.grid-cell--in-fill-reject-range{background:#ea302d1f;cursor:not-allowed;z-index:2}.grid-cell--in-fill-reject-range:after{content:\"\";position:absolute;inset:0;border:2px dashed var(--Status-Standalone-element-Error, #ea302d);border-radius:4px;pointer-events:none;z-index:3}.grid-cell--cut{background:#1a73e80f}.grid-cell__cut-mark{position:absolute;pointer-events:none;z-index:5;--cut-color: var(--color-background-accent-inverse, #1a73e8)}.grid-cell__cut-mark--top,.grid-cell__cut-mark--bottom{left:0;right:0;height:2px;background-image:linear-gradient(90deg,var(--cut-color) 50%,transparent 50%);background-size:8px 2px;background-repeat:repeat-x;animation:moz-grid-marching-ants-x .5s linear infinite}.grid-cell__cut-mark--top{top:0}.grid-cell__cut-mark--bottom{bottom:0}.grid-cell__cut-mark--left,.grid-cell__cut-mark--right{top:0;bottom:0;width:2px;background-image:linear-gradient(180deg,var(--cut-color) 50%,transparent 50%);background-size:2px 8px;background-repeat:repeat-y;animation:moz-grid-marching-ants-y .5s linear infinite}.grid-cell__cut-mark--left{left:0}.grid-cell__cut-mark--right{right:0}@keyframes moz-grid-marching-ants-x{0%{background-position-x:0}to{background-position-x:8px}}@keyframes moz-grid-marching-ants-y{0%{background-position-y:0}to{background-position-y:8px}}.grid-cell__fill-handle{position:absolute;right:0;bottom:0;width:8px;height:8px;background:var(--color-background-accent-inverse);cursor:crosshair;z-index:4}.grid-cell--error{outline:1px solid var(--Status-Border-Error, #ef5f5c);outline-offset:-2px;z-index:1;border-radius:4px}.grid-cell--error:hover:before{background:transparent}.grid-cell__error-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-left:auto;cursor:help;position:relative;z-index:2;fill:var(--Status-Standalone-element-Error, #ea302d)}\n"] }]
|
|
8908
9655
|
}], ctorParameters: () => [], propDecorators: { row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: true }] }], rowIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowIndex", required: true }] }], colIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "colIndex", required: true }] }], colState: [{ type: i0.Input, args: [{ isSignal: true, alias: "colState", required: true }] }], def: [{ type: i0.Input, args: [{ isSignal: true, alias: "def", required: true }] }], isLast: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLast", required: false }] }], pinnedEnd: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedEnd", required: false }] }], commitEdit: [{ type: i0.Output, args: ["commitEdit"] }], cancelEdit: [{ type: i0.Output, args: ["cancelEdit"] }] } });
|
|
8909
9656
|
|
|
8910
9657
|
class MozGridRowComponent {
|
|
@@ -8944,12 +9691,12 @@ class MozGridRowComponent {
|
|
|
8944
9691
|
}
|
|
8945
9692
|
onCheckboxClick(event) {
|
|
8946
9693
|
event.stopPropagation();
|
|
8947
|
-
if (event.shiftKey && this.rowSelection.
|
|
8948
|
-
this.rowSelection.
|
|
9694
|
+
if (event.shiftKey && this.rowSelection.lastToggledRow() !== null) {
|
|
9695
|
+
this.rowSelection.selectRowRangeToRow(this.row());
|
|
8949
9696
|
}
|
|
8950
9697
|
else {
|
|
8951
9698
|
this.rowSelection.toggleRow(this.row());
|
|
8952
|
-
this.rowSelection.
|
|
9699
|
+
this.rowSelection.lastToggledRow.set(this.row());
|
|
8953
9700
|
}
|
|
8954
9701
|
this.rowSelectionToggle.emit();
|
|
8955
9702
|
}
|
|
@@ -8992,11 +9739,11 @@ class MozGridGroupRowComponent {
|
|
|
8992
9739
|
return String(this.groupRow().value ?? '');
|
|
8993
9740
|
}, ...(ngDevMode ? [{ debugName: "groupValue" }] : /* istanbul ignore next */ []));
|
|
8994
9741
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MozGridGroupRowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8995
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: MozGridGroupRowComponent, isStandalone: true, selector: "moz-grid-group-row", inputs: { groupRow: { classPropertyName: "groupRow", publicName: "groupRow", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { toggleExpand: "toggleExpand" }, ngImport: i0, template: "<div\n class=\"grid-group-row\"\n role=\"row\"\n [style.padding-left.px]=\"groupRow().depth * 24 + 16\"\n (click)=\"toggleExpand.emit(groupRow().groupKey)\"\n>\n <span\n class=\"grid-group-row__toggle\"\n [class.grid-group-row__toggle--expanded]=\"groupRow().expanded\"\n >\n <ChevronRight20 />\n </span>\n <div class=\"grid-group-row__info\">\n <span class=\"grid-group-row__field\">{{ fieldLabel() }}</span>\n <span class=\"grid-group-row__value\">{{ groupValue() }}</span>\n </div>\n <span class=\"grid-group-row__count\">{{ groupRow().count }}</span>\n</div>\n", styles: [":host{display:block;position:sticky;left:0;overflow:hidden;box-sizing:border-box}.grid-group-row{display:flex;align-items:center;gap:var(--spacing-s, 8px);height:73px;background:var(--color-background-secondary);border-bottom:1px solid var(--color-border-primary);cursor:pointer;-webkit-user-select:none;user-select:none;box-sizing:border-box}.grid-group-row:hover{background:var(--color-background-tertiary, #f0f0f0)}.grid-group-row__toggle{display:flex;align-items:center;color:var(--color-text-secondary);flex-shrink:0;transition:transform .2s ease}.grid-group-row__toggle--expanded{transform:rotate(90deg)}.grid-group-row__info{display:flex;flex-direction:column;gap:2px;min-width:0}.grid-group-row__field{font-size:var(--font-size-xs, 12px);font-weight:500;color:var(--color-text-secondary);text-transform:uppercase;letter-spacing:.5px}.grid-group-row__value{font-size:var(--font-size-l, 18px);font-weight:700;color:var(--color-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.grid-group-row__count{
|
|
9742
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: MozGridGroupRowComponent, isStandalone: true, selector: "moz-grid-group-row", inputs: { groupRow: { classPropertyName: "groupRow", publicName: "groupRow", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { toggleExpand: "toggleExpand" }, ngImport: i0, template: "<div\n class=\"grid-group-row\"\n role=\"row\"\n [style.padding-left.px]=\"groupRow().depth * 24 + 16\"\n (click)=\"toggleExpand.emit(groupRow().groupKey)\"\n>\n <span\n class=\"grid-group-row__toggle\"\n [class.grid-group-row__toggle--expanded]=\"groupRow().expanded\"\n >\n <ChevronRight20 />\n </span>\n <div class=\"grid-group-row__info\">\n <span class=\"grid-group-row__field\">{{ fieldLabel() }}</span>\n <span class=\"grid-group-row__value\">{{ groupValue() }}</span>\n </div>\n <span class=\"grid-group-row__count\">{{ groupRow().count }}</span>\n</div>\n", styles: [":host{display:block;position:sticky;left:0;overflow:hidden;box-sizing:border-box}.grid-group-row{display:flex;align-items:center;gap:var(--spacing-s, 8px);height:73px;background:var(--color-background-secondary);border-bottom:1px solid var(--color-border-primary);cursor:pointer;-webkit-user-select:none;user-select:none;box-sizing:border-box}.grid-group-row:hover{background:var(--color-background-tertiary, #f0f0f0)}.grid-group-row__toggle{display:flex;align-items:center;color:var(--color-text-secondary);flex-shrink:0;transition:transform .2s ease}.grid-group-row__toggle--expanded{transform:rotate(90deg)}.grid-group-row__info{display:flex;flex-direction:column;gap:2px;min-width:0}.grid-group-row__field{font-size:var(--font-size-xs, 12px);font-weight:500;color:var(--color-text-secondary);text-transform:uppercase;letter-spacing:.5px}.grid-group-row__value{font-size:var(--font-size-l, 18px);font-weight:700;color:var(--color-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.grid-group-row__count{align-self:center;font-size:var(--font-size-s, 14px);color:var(--color-text-secondary);font-weight:400;padding-right:16px;padding-left:12px}\n"], dependencies: [{ kind: "component", type: ChevronRight20, selector: "ChevronRight20", inputs: ["hostClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8996
9743
|
}
|
|
8997
9744
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MozGridGroupRowComponent, decorators: [{
|
|
8998
9745
|
type: Component,
|
|
8999
|
-
args: [{ selector: 'moz-grid-group-row', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ChevronRight20], template: "<div\n class=\"grid-group-row\"\n role=\"row\"\n [style.padding-left.px]=\"groupRow().depth * 24 + 16\"\n (click)=\"toggleExpand.emit(groupRow().groupKey)\"\n>\n <span\n class=\"grid-group-row__toggle\"\n [class.grid-group-row__toggle--expanded]=\"groupRow().expanded\"\n >\n <ChevronRight20 />\n </span>\n <div class=\"grid-group-row__info\">\n <span class=\"grid-group-row__field\">{{ fieldLabel() }}</span>\n <span class=\"grid-group-row__value\">{{ groupValue() }}</span>\n </div>\n <span class=\"grid-group-row__count\">{{ groupRow().count }}</span>\n</div>\n", styles: [":host{display:block;position:sticky;left:0;overflow:hidden;box-sizing:border-box}.grid-group-row{display:flex;align-items:center;gap:var(--spacing-s, 8px);height:73px;background:var(--color-background-secondary);border-bottom:1px solid var(--color-border-primary);cursor:pointer;-webkit-user-select:none;user-select:none;box-sizing:border-box}.grid-group-row:hover{background:var(--color-background-tertiary, #f0f0f0)}.grid-group-row__toggle{display:flex;align-items:center;color:var(--color-text-secondary);flex-shrink:0;transition:transform .2s ease}.grid-group-row__toggle--expanded{transform:rotate(90deg)}.grid-group-row__info{display:flex;flex-direction:column;gap:2px;min-width:0}.grid-group-row__field{font-size:var(--font-size-xs, 12px);font-weight:500;color:var(--color-text-secondary);text-transform:uppercase;letter-spacing:.5px}.grid-group-row__value{font-size:var(--font-size-l, 18px);font-weight:700;color:var(--color-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.grid-group-row__count{
|
|
9746
|
+
args: [{ selector: 'moz-grid-group-row', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ChevronRight20], template: "<div\n class=\"grid-group-row\"\n role=\"row\"\n [style.padding-left.px]=\"groupRow().depth * 24 + 16\"\n (click)=\"toggleExpand.emit(groupRow().groupKey)\"\n>\n <span\n class=\"grid-group-row__toggle\"\n [class.grid-group-row__toggle--expanded]=\"groupRow().expanded\"\n >\n <ChevronRight20 />\n </span>\n <div class=\"grid-group-row__info\">\n <span class=\"grid-group-row__field\">{{ fieldLabel() }}</span>\n <span class=\"grid-group-row__value\">{{ groupValue() }}</span>\n </div>\n <span class=\"grid-group-row__count\">{{ groupRow().count }}</span>\n</div>\n", styles: [":host{display:block;position:sticky;left:0;overflow:hidden;box-sizing:border-box}.grid-group-row{display:flex;align-items:center;gap:var(--spacing-s, 8px);height:73px;background:var(--color-background-secondary);border-bottom:1px solid var(--color-border-primary);cursor:pointer;-webkit-user-select:none;user-select:none;box-sizing:border-box}.grid-group-row:hover{background:var(--color-background-tertiary, #f0f0f0)}.grid-group-row__toggle{display:flex;align-items:center;color:var(--color-text-secondary);flex-shrink:0;transition:transform .2s ease}.grid-group-row__toggle--expanded{transform:rotate(90deg)}.grid-group-row__info{display:flex;flex-direction:column;gap:2px;min-width:0}.grid-group-row__field{font-size:var(--font-size-xs, 12px);font-weight:500;color:var(--color-text-secondary);text-transform:uppercase;letter-spacing:.5px}.grid-group-row__value{font-size:var(--font-size-l, 18px);font-weight:700;color:var(--color-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.grid-group-row__count{align-self:center;font-size:var(--font-size-s, 14px);color:var(--color-text-secondary);font-weight:400;padding-right:16px;padding-left:12px}\n"] }]
|
|
9000
9747
|
}], propDecorators: { groupRow: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupRow", required: true }] }], toggleExpand: [{ type: i0.Output, args: ["toggleExpand"] }] } });
|
|
9001
9748
|
|
|
9002
9749
|
class MozGridDetailRowComponent {
|
|
@@ -9317,7 +10064,7 @@ class GridSettingsDrawerComponent {
|
|
|
9317
10064
|
this.searchQuery.set('');
|
|
9318
10065
|
}
|
|
9319
10066
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GridSettingsDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9320
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: GridSettingsDrawerComponent, isStandalone: true, selector: "moz-grid-settings-drawer", ngImport: i0, template: "@switch (screen()) { @case ('main') {\n<div class=\"settings-list\">\n <button type=\"button\" class=\"settings-list__item\" (click)=\"goTo('density')\">\n <div class=\"settings-list__item-text\">\n <span class=\"settings-list__item-title\">Data density</span>\n <span class=\"settings-list__item-subtitle\">{{ densityLabel() }}</span>\n </div>\n <ChevronRight20 />\n </button>\n <button type=\"button\" class=\"settings-list__item\" (click)=\"goTo('columns')\">\n <div class=\"settings-list__item-text\">\n <span class=\"settings-list__item-title\">Display columns</span>\n <span class=\"settings-list__item-subtitle\">{{ columnsLabel() }}</span>\n </div>\n <ChevronRight20 />\n </button>\n</div>\n} @case ('density') {\n<div class=\"settings-density\">\n <label class=\"settings-density__label\">Data density</label>\n <moz-select\n name=\"density\"\n [options]=\"densityOptions\"\n [ngModel]=\"draftDensity()\"\n (ngModelChange)=\"draftDensity.set($event)\"\n />\n</div>\n} @case ('columns') {\n<div class=\"settings-columns\">\n <input\n class=\"settings-columns__search\"\n type=\"text\"\n placeholder=\"Find a column\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n aria-label=\"Search columns\"\n />\n <div class=\"settings-columns__list\" cdkDropList (cdkDropListDropped)=\"onColumnDrop($event)\">\n @for (col of filteredColumns(); track col.field) {\n <div class=\"settings-columns__item\" cdkDrag>\n <div class=\"settings-columns__item-left\">\n <span class=\"settings-columns__drag-handle\" cdkDragHandle>\n <Drag20 />\n </span>\n <span class=\"settings-columns__item-label\">{{ col.headerName }}</span>\n </div>\n <moz-toggle\n [id]=\"'col-toggle-' + col.field\"\n [ngModel]=\"col.visible\"\n (ngModelChange)=\"onColumnToggle(col.field, $event)\"\n />\n </div>\n }\n </div>\n <div class=\"settings-columns__bulk-actions\">\n <button type=\"button\" class=\"settings-columns__bulk-btn\" (click)=\"hideAll()\"
|
|
10067
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: GridSettingsDrawerComponent, isStandalone: true, selector: "moz-grid-settings-drawer", ngImport: i0, template: "@switch (screen()) { @case ('main') {\n<div class=\"settings-list\">\n <button type=\"button\" class=\"settings-list__item\" (click)=\"goTo('density')\">\n <div class=\"settings-list__item-text\">\n <span class=\"settings-list__item-title\">Data density</span>\n <span class=\"settings-list__item-subtitle\">{{ densityLabel() }}</span>\n </div>\n <ChevronRight20 />\n </button>\n <button type=\"button\" class=\"settings-list__item\" (click)=\"goTo('columns')\">\n <div class=\"settings-list__item-text\">\n <span class=\"settings-list__item-title\">Display columns</span>\n <span class=\"settings-list__item-subtitle\">{{ columnsLabel() }}</span>\n </div>\n <ChevronRight20 />\n </button>\n</div>\n} @case ('density') {\n<div class=\"settings-density\">\n <label class=\"settings-density__label\">Data density</label>\n <moz-select\n name=\"density\"\n [options]=\"densityOptions\"\n [ngModel]=\"draftDensity()\"\n (ngModelChange)=\"draftDensity.set($event)\"\n />\n</div>\n} @case ('columns') {\n<div class=\"settings-columns\">\n <input\n class=\"settings-columns__search\"\n type=\"text\"\n placeholder=\"Find a column\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n aria-label=\"Search columns\"\n />\n <div class=\"settings-columns__list\" cdkDropList (cdkDropListDropped)=\"onColumnDrop($event)\">\n @for (col of filteredColumns(); track col.field) {\n <div class=\"settings-columns__item\" cdkDrag>\n <div class=\"settings-columns__item-left\">\n <span class=\"settings-columns__drag-handle\" cdkDragHandle>\n <Drag20 />\n </span>\n <span class=\"settings-columns__item-label\">{{ col.headerName }}</span>\n </div>\n <moz-toggle\n [id]=\"'col-toggle-' + col.field\"\n [ngModel]=\"col.visible\"\n (ngModelChange)=\"onColumnToggle(col.field, $event)\"\n />\n </div>\n }\n </div>\n <div class=\"settings-columns__bulk-actions\">\n <button type=\"button\" class=\"settings-columns__bulk-btn\" (click)=\"hideAll()\">Hide all</button>\n <button type=\"button\" class=\"settings-columns__bulk-btn\" (click)=\"showAll()\">Show all</button>\n </div>\n</div>\n} }\n\n<ng-template mozDrawerFooter>\n <button moz-button (click)=\"apply()\" [appearance]=\"'accent'\">Apply</button>\n <button moz-button [outlined]=\"true\" (click)=\"reset()\">Reset</button>\n</ng-template>\n", styles: [".settings-list{display:flex;flex-direction:column;border:1px solid var(--color-border-primary);border-radius:var(--border-radius-m, 8px);overflow:hidden}.settings-list__item{display:flex;align-items:center;justify-content:space-between;padding:16px;background:var(--color-background-primary);border:none;border-bottom:1px solid var(--color-border-primary);cursor:pointer;text-align:left;width:100%}.settings-list__item:last-child{border-bottom:none}.settings-list__item:hover{background:var(--color-background-secondary)}.settings-list__item-text{display:flex;flex-direction:column;gap:2px}.settings-list__item-title{font-weight:600;font-size:var(--font-size-m, 16px);color:var(--color-text-primary)}.settings-list__item-subtitle{font-size:var(--font-size-s, 14px);color:var(--color-text-secondary)}.settings-density{display:flex;flex-direction:column;gap:8px}.settings-density__label{font-weight:600;font-size:var(--font-size-s, 14px);color:var(--color-text-primary)}.settings-columns{display:flex;flex-direction:column;gap:12px}.settings-columns__search{width:100%;padding:8px 12px;border:1px solid var(--color-border-primary);border-radius:var(--border-radius-s, 4px);font-size:var(--font-size-s, 14px);color:var(--color-text-primary);background:var(--color-background-primary, #fff);box-sizing:border-box}.settings-columns__search::placeholder{color:var(--color-text-secondary)}.settings-columns__search:focus{outline:2px solid var(--color-background-accent-inverse);outline-offset:-1px}.settings-columns__list{display:flex;flex-direction:column}.settings-columns__bulk-actions{display:flex;gap:8px;padding-top:8px;border-top:1px solid var(--color-border-primary)}.settings-columns__bulk-btn{flex:1;padding:8px 12px;border:1px solid var(--color-border-primary);border-radius:var(--border-radius-s, 4px);background:var(--color-background-primary, #fff);font-size:var(--font-size-s, 14px);font-weight:500;color:var(--color-text-primary);cursor:pointer}.settings-columns__bulk-btn:hover{background:var(--color-background-secondary, #f5f5f5)}.settings-columns__item{display:flex;align-items:center;justify-content:space-between;padding:16px 0;border-bottom:1px solid var(--color-border-primary);background:var(--color-background-primary, #fff)}.settings-columns__item:last-child{border-bottom:none}.settings-columns__item-left{display:flex;align-items:center;gap:8px}.settings-columns__drag-handle{display:flex;align-items:center;cursor:grab;color:var(--color-text-secondary)}.settings-columns__drag-handle:active{cursor:grabbing}.settings-columns__item-label{font-size:var(--font-size-m, 16px);color:var(--color-text-primary)}.cdk-drag-preview{display:flex;align-items:center;justify-content:space-between;padding:16px 8px;background:var(--color-background-primary, #fff);border:1px solid var(--color-border-primary);border-radius:4px;box-shadow:0 4px 12px #00000026;font-size:var(--font-size-m, 16px)}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .2s ease}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: MozButtonComponent, selector: "button[moz-button]", inputs: ["appearance", "size", "disabled", "ghost", "outlined", "iconPosition", "type", "isLoading"] }, { kind: "directive", type: MozDrawerFooterDirective, selector: "[mozDrawerFooter]" }, { kind: "component", type: MozSelectComponent, selector: "moz-select", inputs: ["id", "name", "options", "placeholder", "isInvalid", "disabled", "readonly", "size"] }, { kind: "component", type: MozToggleComponent, selector: "moz-toggle", inputs: ["id", "name", "size", "disabled"] }, { kind: "component", type: ChevronRight20, selector: "ChevronRight20", inputs: ["hostClass"] }, { kind: "component", type: Drag20, selector: "Drag20", inputs: ["hostClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
9321
10068
|
}
|
|
9322
10069
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GridSettingsDrawerComponent, decorators: [{
|
|
9323
10070
|
type: Component,
|
|
@@ -9332,7 +10079,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
9332
10079
|
MozToggleComponent,
|
|
9333
10080
|
ChevronRight20,
|
|
9334
10081
|
Drag20,
|
|
9335
|
-
], template: "@switch (screen()) { @case ('main') {\n<div class=\"settings-list\">\n <button type=\"button\" class=\"settings-list__item\" (click)=\"goTo('density')\">\n <div class=\"settings-list__item-text\">\n <span class=\"settings-list__item-title\">Data density</span>\n <span class=\"settings-list__item-subtitle\">{{ densityLabel() }}</span>\n </div>\n <ChevronRight20 />\n </button>\n <button type=\"button\" class=\"settings-list__item\" (click)=\"goTo('columns')\">\n <div class=\"settings-list__item-text\">\n <span class=\"settings-list__item-title\">Display columns</span>\n <span class=\"settings-list__item-subtitle\">{{ columnsLabel() }}</span>\n </div>\n <ChevronRight20 />\n </button>\n</div>\n} @case ('density') {\n<div class=\"settings-density\">\n <label class=\"settings-density__label\">Data density</label>\n <moz-select\n name=\"density\"\n [options]=\"densityOptions\"\n [ngModel]=\"draftDensity()\"\n (ngModelChange)=\"draftDensity.set($event)\"\n />\n</div>\n} @case ('columns') {\n<div class=\"settings-columns\">\n <input\n class=\"settings-columns__search\"\n type=\"text\"\n placeholder=\"Find a column\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n aria-label=\"Search columns\"\n />\n <div class=\"settings-columns__list\" cdkDropList (cdkDropListDropped)=\"onColumnDrop($event)\">\n @for (col of filteredColumns(); track col.field) {\n <div class=\"settings-columns__item\" cdkDrag>\n <div class=\"settings-columns__item-left\">\n <span class=\"settings-columns__drag-handle\" cdkDragHandle>\n <Drag20 />\n </span>\n <span class=\"settings-columns__item-label\">{{ col.headerName }}</span>\n </div>\n <moz-toggle\n [id]=\"'col-toggle-' + col.field\"\n [ngModel]=\"col.visible\"\n (ngModelChange)=\"onColumnToggle(col.field, $event)\"\n />\n </div>\n }\n </div>\n <div class=\"settings-columns__bulk-actions\">\n <button type=\"button\" class=\"settings-columns__bulk-btn\" (click)=\"hideAll()\"
|
|
10082
|
+
], template: "@switch (screen()) { @case ('main') {\n<div class=\"settings-list\">\n <button type=\"button\" class=\"settings-list__item\" (click)=\"goTo('density')\">\n <div class=\"settings-list__item-text\">\n <span class=\"settings-list__item-title\">Data density</span>\n <span class=\"settings-list__item-subtitle\">{{ densityLabel() }}</span>\n </div>\n <ChevronRight20 />\n </button>\n <button type=\"button\" class=\"settings-list__item\" (click)=\"goTo('columns')\">\n <div class=\"settings-list__item-text\">\n <span class=\"settings-list__item-title\">Display columns</span>\n <span class=\"settings-list__item-subtitle\">{{ columnsLabel() }}</span>\n </div>\n <ChevronRight20 />\n </button>\n</div>\n} @case ('density') {\n<div class=\"settings-density\">\n <label class=\"settings-density__label\">Data density</label>\n <moz-select\n name=\"density\"\n [options]=\"densityOptions\"\n [ngModel]=\"draftDensity()\"\n (ngModelChange)=\"draftDensity.set($event)\"\n />\n</div>\n} @case ('columns') {\n<div class=\"settings-columns\">\n <input\n class=\"settings-columns__search\"\n type=\"text\"\n placeholder=\"Find a column\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n aria-label=\"Search columns\"\n />\n <div class=\"settings-columns__list\" cdkDropList (cdkDropListDropped)=\"onColumnDrop($event)\">\n @for (col of filteredColumns(); track col.field) {\n <div class=\"settings-columns__item\" cdkDrag>\n <div class=\"settings-columns__item-left\">\n <span class=\"settings-columns__drag-handle\" cdkDragHandle>\n <Drag20 />\n </span>\n <span class=\"settings-columns__item-label\">{{ col.headerName }}</span>\n </div>\n <moz-toggle\n [id]=\"'col-toggle-' + col.field\"\n [ngModel]=\"col.visible\"\n (ngModelChange)=\"onColumnToggle(col.field, $event)\"\n />\n </div>\n }\n </div>\n <div class=\"settings-columns__bulk-actions\">\n <button type=\"button\" class=\"settings-columns__bulk-btn\" (click)=\"hideAll()\">Hide all</button>\n <button type=\"button\" class=\"settings-columns__bulk-btn\" (click)=\"showAll()\">Show all</button>\n </div>\n</div>\n} }\n\n<ng-template mozDrawerFooter>\n <button moz-button (click)=\"apply()\" [appearance]=\"'accent'\">Apply</button>\n <button moz-button [outlined]=\"true\" (click)=\"reset()\">Reset</button>\n</ng-template>\n", styles: [".settings-list{display:flex;flex-direction:column;border:1px solid var(--color-border-primary);border-radius:var(--border-radius-m, 8px);overflow:hidden}.settings-list__item{display:flex;align-items:center;justify-content:space-between;padding:16px;background:var(--color-background-primary);border:none;border-bottom:1px solid var(--color-border-primary);cursor:pointer;text-align:left;width:100%}.settings-list__item:last-child{border-bottom:none}.settings-list__item:hover{background:var(--color-background-secondary)}.settings-list__item-text{display:flex;flex-direction:column;gap:2px}.settings-list__item-title{font-weight:600;font-size:var(--font-size-m, 16px);color:var(--color-text-primary)}.settings-list__item-subtitle{font-size:var(--font-size-s, 14px);color:var(--color-text-secondary)}.settings-density{display:flex;flex-direction:column;gap:8px}.settings-density__label{font-weight:600;font-size:var(--font-size-s, 14px);color:var(--color-text-primary)}.settings-columns{display:flex;flex-direction:column;gap:12px}.settings-columns__search{width:100%;padding:8px 12px;border:1px solid var(--color-border-primary);border-radius:var(--border-radius-s, 4px);font-size:var(--font-size-s, 14px);color:var(--color-text-primary);background:var(--color-background-primary, #fff);box-sizing:border-box}.settings-columns__search::placeholder{color:var(--color-text-secondary)}.settings-columns__search:focus{outline:2px solid var(--color-background-accent-inverse);outline-offset:-1px}.settings-columns__list{display:flex;flex-direction:column}.settings-columns__bulk-actions{display:flex;gap:8px;padding-top:8px;border-top:1px solid var(--color-border-primary)}.settings-columns__bulk-btn{flex:1;padding:8px 12px;border:1px solid var(--color-border-primary);border-radius:var(--border-radius-s, 4px);background:var(--color-background-primary, #fff);font-size:var(--font-size-s, 14px);font-weight:500;color:var(--color-text-primary);cursor:pointer}.settings-columns__bulk-btn:hover{background:var(--color-background-secondary, #f5f5f5)}.settings-columns__item{display:flex;align-items:center;justify-content:space-between;padding:16px 0;border-bottom:1px solid var(--color-border-primary);background:var(--color-background-primary, #fff)}.settings-columns__item:last-child{border-bottom:none}.settings-columns__item-left{display:flex;align-items:center;gap:8px}.settings-columns__drag-handle{display:flex;align-items:center;cursor:grab;color:var(--color-text-secondary)}.settings-columns__drag-handle:active{cursor:grabbing}.settings-columns__item-label{font-size:var(--font-size-m, 16px);color:var(--color-text-primary)}.cdk-drag-preview{display:flex;align-items:center;justify-content:space-between;padding:16px 8px;background:var(--color-background-primary, #fff);border:1px solid var(--color-border-primary);border-radius:4px;box-shadow:0 4px 12px #00000026;font-size:var(--font-size-m, 16px)}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .2s ease}\n"] }]
|
|
9336
10083
|
}], ctorParameters: () => [] });
|
|
9337
10084
|
|
|
9338
10085
|
class GridGroupDrawerComponent {
|
|
@@ -9384,7 +10131,7 @@ class GridGroupDrawerComponent {
|
|
|
9384
10131
|
this.draftGrouped.set([]);
|
|
9385
10132
|
}
|
|
9386
10133
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GridGroupDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9387
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: GridGroupDrawerComponent, isStandalone: true, selector: "moz-grid-group-drawer", ngImport: i0, template: "<div class=\"group-drawer__list\" cdkDropList (cdkDropListDropped)=\"onDrop($event)\">\n @for (item of draftGrouped(); track item.field; let idx = $index) {\n <div class=\"group-drawer__item\" cdkDrag>\n <span class=\"group-drawer__drag-handle\" cdkDragHandle>\n <Drag20 />\n </span>\n <span class=\"group-drawer__item-label\">{{ item.headerName }}</span>\n <select\n class=\"group-drawer__sort-select\"\n [value]=\"item.sortDirection\"\n [attr.aria-label]=\"'Sort direction for ' + item.headerName\"\n (change)=\"onSortDirectionChange(idx, $event)\"\n >\n <option value=\"asc\">A \u2192 Z</option>\n <option value=\"desc\">Z \u2192 A</option>\n </select>\n <button\n type=\"button\"\n moz-button\n [attr.aria-label]=\"'Remove ' + item.headerName\"\n (click)=\"removeGroup(item.field)\"\n [iconPosition]=\"'only'\"\n [size]=\"'s'\"\n [ghost]=\"true\"\n >\n <Cross20 icon />\n </button>\n </div>\n }\n</div>\n\n@if (available().length > 0) {\n<div class=\"group-drawer__available\">\n <h4 class=\"group-drawer__section-title\">Available columns</h4>\n @for (col of available(); track col.field) {\n <div class=\"group-drawer__available-item\">\n <span class=\"group-drawer__available-label\">{{ col.headerName }}</span>\n <button\n type=\"button\"\n class=\"group-drawer__add-btn\"\n [attr.aria-label]=\"'Add ' + col.headerName + ' as group'\"\n (click)=\"addGroup(col.field)\"\n >\n <ListAdd20 />\n </button>\n </div>\n }\n</div>\n} @if (draftGrouped().length === 0 && available().length === 0) {\n<p class=\"group-drawer__empty\">No groupable columns available.</p>\n}\n\n<ng-template mozDrawerFooter>\n <button moz-button (click)=\"apply()\">Apply</button>\n <button moz-button [outlined]=\"true\" (click)=\"reset()\">Reset</button>\n</ng-template>\n", styles: [".group-drawer__list{display:flex;flex-direction:column}.group-drawer__item{display:flex;align-items:center;gap:8px;padding:12px 0;border-bottom:1px solid var(--color-border-primary);background:var(--color-background-primary, #fff)}.group-drawer__item:last-child{border-bottom:none}.group-drawer__drag-handle{display:flex;align-items:center;cursor:grab;color:var(--color-text-secondary);flex-shrink:0}.group-drawer__drag-handle:active{cursor:grabbing}.group-drawer__item-label{flex:1;font-size:var(--font-size-m, 16px);color:var(--color-text-primary);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.group-drawer__sort-select{flex-shrink:0;padding:4px 8px;border:1px solid var(--color-border-primary);border-radius:var(--border-radius-s, 4px);background:var(--color-background-primary, #fff);font-size:var(--font-size-s, 14px);color:var(--color-text-primary);cursor:pointer}.group-drawer__sort-select:focus{outline:2px solid var(--color-background-accent-inverse);outline-offset:-1px}.group-drawer__available{margin-top:16px;margin-bottom:32px}.group-drawer__section-title{font-size:var(--font-size-s, 14px);font-weight:600;color:var(--color-text-secondary);margin:0 0 8px;text-transform:uppercase;letter-spacing:.5px}.group-drawer__available-item{display:flex;align-items:center;justify-content:space-between;padding:10px 0;border-bottom:1px solid var(--color-border-primary)}.group-drawer__available-item:last-child{border-bottom:none}.group-drawer__available-label{font-size:var(--font-size-m, 16px);color:var(--color-text-primary)}.group-drawer__add-btn{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:28px;height:28px;padding:0;border:none;border-radius:var(--border-radius-s, 4px);background:transparent;cursor:pointer;color:var(--color-background-accent-inverse)}.group-drawer__add-btn:hover{background:#1a73e814;color:var(--color-primary-dark, #1557b0)}.group-drawer__empty{font-size:var(--font-size-s, 14px);color:var(--color-text-secondary);text-align:center;padding:24px 0}.cdk-drag-preview{display:flex;align-items:center;gap:8px;padding:12px 8px;background:var(--color-background-primary, #fff);border:1px solid var(--color-border-primary);border-radius:4px;box-shadow:0 4px 12px #00000026;font-size:var(--font-size-m, 16px)}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .2s ease}\n"], dependencies: [{ kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: MozButtonComponent, selector: "button[moz-button]", inputs: ["appearance", "size", "disabled", "ghost", "outlined", "iconPosition", "type", "isLoading"] }, { kind: "directive", type: MozDrawerFooterDirective, selector: "[mozDrawerFooter]" }, { kind: "component", type: Drag20, selector: "Drag20", inputs: ["hostClass"] }, { kind: "component", type: Cross20, selector: "Cross20", inputs: ["hostClass"] }, { kind: "component", type: ListAdd20, selector: "ListAdd20", inputs: ["hostClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
10134
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: GridGroupDrawerComponent, isStandalone: true, selector: "moz-grid-group-drawer", ngImport: i0, template: "<div class=\"group-drawer__list\" cdkDropList (cdkDropListDropped)=\"onDrop($event)\">\n @for (item of draftGrouped(); track item.field; let idx = $index) {\n <div class=\"group-drawer__item\" cdkDrag>\n <span class=\"group-drawer__drag-handle\" cdkDragHandle>\n <Drag20 />\n </span>\n <span class=\"group-drawer__item-label\">{{ item.headerName }}</span>\n <select\n class=\"group-drawer__sort-select\"\n [value]=\"item.sortDirection\"\n [attr.aria-label]=\"'Sort direction for ' + item.headerName\"\n (change)=\"onSortDirectionChange(idx, $event)\"\n >\n <option value=\"asc\">A \u2192 Z</option>\n <option value=\"desc\">Z \u2192 A</option>\n </select>\n <button\n type=\"button\"\n moz-button\n [attr.aria-label]=\"'Remove ' + item.headerName\"\n (click)=\"removeGroup(item.field)\"\n [iconPosition]=\"'only'\"\n [size]=\"'s'\"\n [ghost]=\"true\"\n >\n <Cross20 icon />\n </button>\n </div>\n }\n</div>\n\n@if (available().length > 0) {\n<div class=\"group-drawer__available\">\n <h4 class=\"group-drawer__section-title\">Available columns</h4>\n @for (col of available(); track col.field) {\n <div class=\"group-drawer__available-item\">\n <span class=\"group-drawer__available-label\">{{ col.headerName }}</span>\n <button\n type=\"button\"\n class=\"group-drawer__add-btn\"\n [attr.aria-label]=\"'Add ' + col.headerName + ' as group'\"\n (click)=\"addGroup(col.field)\"\n >\n <ListAdd20 />\n </button>\n </div>\n }\n</div>\n} @if (draftGrouped().length === 0 && available().length === 0) {\n<p class=\"group-drawer__empty\">No groupable columns available.</p>\n}\n\n<ng-template mozDrawerFooter>\n <button moz-button (click)=\"apply()\" [appearance]=\"'accent'\">Apply</button>\n <button moz-button [outlined]=\"true\" (click)=\"reset()\">Reset</button>\n</ng-template>\n", styles: [".group-drawer__list{display:flex;flex-direction:column}.group-drawer__item{display:flex;align-items:center;gap:8px;padding:12px 0;border-bottom:1px solid var(--color-border-primary);background:var(--color-background-primary, #fff)}.group-drawer__item:last-child{border-bottom:none}.group-drawer__drag-handle{display:flex;align-items:center;cursor:grab;color:var(--color-text-secondary);flex-shrink:0}.group-drawer__drag-handle:active{cursor:grabbing}.group-drawer__item-label{flex:1;font-size:var(--font-size-m, 16px);color:var(--color-text-primary);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.group-drawer__sort-select{flex-shrink:0;padding:4px 8px;border:1px solid var(--color-border-primary);border-radius:var(--border-radius-s, 4px);background:var(--color-background-primary, #fff);font-size:var(--font-size-s, 14px);color:var(--color-text-primary);cursor:pointer}.group-drawer__sort-select:focus{outline:2px solid var(--color-background-accent-inverse);outline-offset:-1px}.group-drawer__available{margin-top:16px;margin-bottom:32px}.group-drawer__section-title{font-size:var(--font-size-s, 14px);font-weight:600;color:var(--color-text-secondary);margin:0 0 8px;text-transform:uppercase;letter-spacing:.5px}.group-drawer__available-item{display:flex;align-items:center;justify-content:space-between;padding:10px 0;border-bottom:1px solid var(--color-border-primary)}.group-drawer__available-item:last-child{border-bottom:none}.group-drawer__available-label{font-size:var(--font-size-m, 16px);color:var(--color-text-primary)}.group-drawer__add-btn{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:28px;height:28px;padding:0;border:none;border-radius:var(--border-radius-s, 4px);background:transparent;cursor:pointer;color:var(--color-background-accent-inverse)}.group-drawer__add-btn:hover{background:#1a73e814;color:var(--color-primary-dark, #1557b0)}.group-drawer__empty{font-size:var(--font-size-s, 14px);color:var(--color-text-secondary);text-align:center;padding:24px 0}.cdk-drag-preview{display:flex;align-items:center;gap:8px;padding:12px 8px;background:var(--color-background-primary, #fff);border:1px solid var(--color-border-primary);border-radius:4px;box-shadow:0 4px 12px #00000026;font-size:var(--font-size-m, 16px)}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .2s ease}\n"], dependencies: [{ kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: MozButtonComponent, selector: "button[moz-button]", inputs: ["appearance", "size", "disabled", "ghost", "outlined", "iconPosition", "type", "isLoading"] }, { kind: "directive", type: MozDrawerFooterDirective, selector: "[mozDrawerFooter]" }, { kind: "component", type: Drag20, selector: "Drag20", inputs: ["hostClass"] }, { kind: "component", type: Cross20, selector: "Cross20", inputs: ["hostClass"] }, { kind: "component", type: ListAdd20, selector: "ListAdd20", inputs: ["hostClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
9388
10135
|
}
|
|
9389
10136
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GridGroupDrawerComponent, decorators: [{
|
|
9390
10137
|
type: Component,
|
|
@@ -9397,7 +10144,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
9397
10144
|
Drag20,
|
|
9398
10145
|
Cross20,
|
|
9399
10146
|
ListAdd20,
|
|
9400
|
-
], template: "<div class=\"group-drawer__list\" cdkDropList (cdkDropListDropped)=\"onDrop($event)\">\n @for (item of draftGrouped(); track item.field; let idx = $index) {\n <div class=\"group-drawer__item\" cdkDrag>\n <span class=\"group-drawer__drag-handle\" cdkDragHandle>\n <Drag20 />\n </span>\n <span class=\"group-drawer__item-label\">{{ item.headerName }}</span>\n <select\n class=\"group-drawer__sort-select\"\n [value]=\"item.sortDirection\"\n [attr.aria-label]=\"'Sort direction for ' + item.headerName\"\n (change)=\"onSortDirectionChange(idx, $event)\"\n >\n <option value=\"asc\">A \u2192 Z</option>\n <option value=\"desc\">Z \u2192 A</option>\n </select>\n <button\n type=\"button\"\n moz-button\n [attr.aria-label]=\"'Remove ' + item.headerName\"\n (click)=\"removeGroup(item.field)\"\n [iconPosition]=\"'only'\"\n [size]=\"'s'\"\n [ghost]=\"true\"\n >\n <Cross20 icon />\n </button>\n </div>\n }\n</div>\n\n@if (available().length > 0) {\n<div class=\"group-drawer__available\">\n <h4 class=\"group-drawer__section-title\">Available columns</h4>\n @for (col of available(); track col.field) {\n <div class=\"group-drawer__available-item\">\n <span class=\"group-drawer__available-label\">{{ col.headerName }}</span>\n <button\n type=\"button\"\n class=\"group-drawer__add-btn\"\n [attr.aria-label]=\"'Add ' + col.headerName + ' as group'\"\n (click)=\"addGroup(col.field)\"\n >\n <ListAdd20 />\n </button>\n </div>\n }\n</div>\n} @if (draftGrouped().length === 0 && available().length === 0) {\n<p class=\"group-drawer__empty\">No groupable columns available.</p>\n}\n\n<ng-template mozDrawerFooter>\n <button moz-button (click)=\"apply()\">Apply</button>\n <button moz-button [outlined]=\"true\" (click)=\"reset()\">Reset</button>\n</ng-template>\n", styles: [".group-drawer__list{display:flex;flex-direction:column}.group-drawer__item{display:flex;align-items:center;gap:8px;padding:12px 0;border-bottom:1px solid var(--color-border-primary);background:var(--color-background-primary, #fff)}.group-drawer__item:last-child{border-bottom:none}.group-drawer__drag-handle{display:flex;align-items:center;cursor:grab;color:var(--color-text-secondary);flex-shrink:0}.group-drawer__drag-handle:active{cursor:grabbing}.group-drawer__item-label{flex:1;font-size:var(--font-size-m, 16px);color:var(--color-text-primary);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.group-drawer__sort-select{flex-shrink:0;padding:4px 8px;border:1px solid var(--color-border-primary);border-radius:var(--border-radius-s, 4px);background:var(--color-background-primary, #fff);font-size:var(--font-size-s, 14px);color:var(--color-text-primary);cursor:pointer}.group-drawer__sort-select:focus{outline:2px solid var(--color-background-accent-inverse);outline-offset:-1px}.group-drawer__available{margin-top:16px;margin-bottom:32px}.group-drawer__section-title{font-size:var(--font-size-s, 14px);font-weight:600;color:var(--color-text-secondary);margin:0 0 8px;text-transform:uppercase;letter-spacing:.5px}.group-drawer__available-item{display:flex;align-items:center;justify-content:space-between;padding:10px 0;border-bottom:1px solid var(--color-border-primary)}.group-drawer__available-item:last-child{border-bottom:none}.group-drawer__available-label{font-size:var(--font-size-m, 16px);color:var(--color-text-primary)}.group-drawer__add-btn{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:28px;height:28px;padding:0;border:none;border-radius:var(--border-radius-s, 4px);background:transparent;cursor:pointer;color:var(--color-background-accent-inverse)}.group-drawer__add-btn:hover{background:#1a73e814;color:var(--color-primary-dark, #1557b0)}.group-drawer__empty{font-size:var(--font-size-s, 14px);color:var(--color-text-secondary);text-align:center;padding:24px 0}.cdk-drag-preview{display:flex;align-items:center;gap:8px;padding:12px 8px;background:var(--color-background-primary, #fff);border:1px solid var(--color-border-primary);border-radius:4px;box-shadow:0 4px 12px #00000026;font-size:var(--font-size-m, 16px)}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .2s ease}\n"] }]
|
|
10147
|
+
], template: "<div class=\"group-drawer__list\" cdkDropList (cdkDropListDropped)=\"onDrop($event)\">\n @for (item of draftGrouped(); track item.field; let idx = $index) {\n <div class=\"group-drawer__item\" cdkDrag>\n <span class=\"group-drawer__drag-handle\" cdkDragHandle>\n <Drag20 />\n </span>\n <span class=\"group-drawer__item-label\">{{ item.headerName }}</span>\n <select\n class=\"group-drawer__sort-select\"\n [value]=\"item.sortDirection\"\n [attr.aria-label]=\"'Sort direction for ' + item.headerName\"\n (change)=\"onSortDirectionChange(idx, $event)\"\n >\n <option value=\"asc\">A \u2192 Z</option>\n <option value=\"desc\">Z \u2192 A</option>\n </select>\n <button\n type=\"button\"\n moz-button\n [attr.aria-label]=\"'Remove ' + item.headerName\"\n (click)=\"removeGroup(item.field)\"\n [iconPosition]=\"'only'\"\n [size]=\"'s'\"\n [ghost]=\"true\"\n >\n <Cross20 icon />\n </button>\n </div>\n }\n</div>\n\n@if (available().length > 0) {\n<div class=\"group-drawer__available\">\n <h4 class=\"group-drawer__section-title\">Available columns</h4>\n @for (col of available(); track col.field) {\n <div class=\"group-drawer__available-item\">\n <span class=\"group-drawer__available-label\">{{ col.headerName }}</span>\n <button\n type=\"button\"\n class=\"group-drawer__add-btn\"\n [attr.aria-label]=\"'Add ' + col.headerName + ' as group'\"\n (click)=\"addGroup(col.field)\"\n >\n <ListAdd20 />\n </button>\n </div>\n }\n</div>\n} @if (draftGrouped().length === 0 && available().length === 0) {\n<p class=\"group-drawer__empty\">No groupable columns available.</p>\n}\n\n<ng-template mozDrawerFooter>\n <button moz-button (click)=\"apply()\" [appearance]=\"'accent'\">Apply</button>\n <button moz-button [outlined]=\"true\" (click)=\"reset()\">Reset</button>\n</ng-template>\n", styles: [".group-drawer__list{display:flex;flex-direction:column}.group-drawer__item{display:flex;align-items:center;gap:8px;padding:12px 0;border-bottom:1px solid var(--color-border-primary);background:var(--color-background-primary, #fff)}.group-drawer__item:last-child{border-bottom:none}.group-drawer__drag-handle{display:flex;align-items:center;cursor:grab;color:var(--color-text-secondary);flex-shrink:0}.group-drawer__drag-handle:active{cursor:grabbing}.group-drawer__item-label{flex:1;font-size:var(--font-size-m, 16px);color:var(--color-text-primary);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.group-drawer__sort-select{flex-shrink:0;padding:4px 8px;border:1px solid var(--color-border-primary);border-radius:var(--border-radius-s, 4px);background:var(--color-background-primary, #fff);font-size:var(--font-size-s, 14px);color:var(--color-text-primary);cursor:pointer}.group-drawer__sort-select:focus{outline:2px solid var(--color-background-accent-inverse);outline-offset:-1px}.group-drawer__available{margin-top:16px;margin-bottom:32px}.group-drawer__section-title{font-size:var(--font-size-s, 14px);font-weight:600;color:var(--color-text-secondary);margin:0 0 8px;text-transform:uppercase;letter-spacing:.5px}.group-drawer__available-item{display:flex;align-items:center;justify-content:space-between;padding:10px 0;border-bottom:1px solid var(--color-border-primary)}.group-drawer__available-item:last-child{border-bottom:none}.group-drawer__available-label{font-size:var(--font-size-m, 16px);color:var(--color-text-primary)}.group-drawer__add-btn{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:28px;height:28px;padding:0;border:none;border-radius:var(--border-radius-s, 4px);background:transparent;cursor:pointer;color:var(--color-background-accent-inverse)}.group-drawer__add-btn:hover{background:#1a73e814;color:var(--color-primary-dark, #1557b0)}.group-drawer__empty{font-size:var(--font-size-s, 14px);color:var(--color-text-secondary);text-align:center;padding:24px 0}.cdk-drag-preview{display:flex;align-items:center;gap:8px;padding:12px 8px;background:var(--color-background-primary, #fff);border:1px solid var(--color-border-primary);border-radius:4px;box-shadow:0 4px 12px #00000026;font-size:var(--font-size-m, 16px)}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .2s ease}\n"] }]
|
|
9401
10148
|
}] });
|
|
9402
10149
|
|
|
9403
10150
|
const EXCEL_SHORTCUTS = [
|
|
@@ -9479,6 +10226,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
9479
10226
|
args: [{ selector: 'moz-grid-keyboard-shortcuts-drawer', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MozButtonComponent, MozDrawerFooterDirective], template: "<div class=\"shortcuts\">\n @for (group of groups; track group.title) {\n <section class=\"shortcuts__group\">\n <h4 class=\"shortcuts__group-title\">{{ group.title }}</h4>\n <dl class=\"shortcuts__list\">\n @for (item of group.items; track item.keys) {\n <div class=\"shortcuts__item\">\n <dt class=\"shortcuts__keys\">\n @for (part of item.parts; track $index) { @if (part === '+' || part === '/') {\n <span class=\"shortcuts__separator\">{{ part }}</span>\n } @else {\n <kbd class=\"shortcuts__key\">{{ part }}</kbd>\n } }\n </dt>\n <dd class=\"shortcuts__label\">{{ item.label }}</dd>\n </div>\n }\n </dl>\n </section>\n }\n</div>\n\n<ng-template mozDrawerFooter>\n <button moz-button (click)=\"close()\">Close</button>\n</ng-template>\n", styles: [".shortcuts{padding-bottom:24px}.shortcuts__group{margin-bottom:24px}.shortcuts__group:last-child{margin-bottom:0}.shortcuts__group-title{margin:0 0 8px;font-size:var(--font-size-s, 14px);font-weight:700;color:var(--color-text-secondary);text-transform:uppercase;letter-spacing:.5px}.shortcuts__list{display:flex;flex-direction:column;margin:0;padding:0}.shortcuts__item{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:10px 0;border-bottom:1px solid var(--color-border-primary)}.shortcuts__item:last-child{border-bottom:none}.shortcuts__label{margin:0;flex:1;font-size:var(--font-size-s, 14px);color:var(--color-text-primary)}.shortcuts__keys{display:flex;align-items:center;flex-wrap:wrap;gap:4px;flex-shrink:0;margin:0}.shortcuts__key{display:inline-flex;align-items:center;justify-content:center;min-width:24px;height:24px;padding:0 6px;background:var(--color-background-secondary, #f5f5f5);border:1px solid var(--color-border-primary);border-radius:var(--border-radius-s, 4px);font-family:var(--font-family-monospace, \"SFMono-Regular\", Consolas, monospace);font-size:var(--font-size-50, 12px);font-weight:600;color:var(--color-text-primary);box-shadow:inset 0 -1px #00000014}.shortcuts__separator{font-size:var(--font-size-s, 14px);color:var(--color-text-secondary);padding:0 2px}\n"] }]
|
|
9480
10227
|
}] });
|
|
9481
10228
|
|
|
10229
|
+
class MozGridFilterDrawerComponent {
|
|
10230
|
+
drawerRef = inject(MozDrawerRef);
|
|
10231
|
+
data = inject(DRAWER_DATA);
|
|
10232
|
+
availableColumns = this.data.availableColumns;
|
|
10233
|
+
draft = signal({
|
|
10234
|
+
conditions: this.data.model.conditions.map((c) => ({ ...c, value: { ...c.value } })),
|
|
10235
|
+
}, ...(ngDevMode ? [{ debugName: "draft" }] : /* istanbul ignore next */ []));
|
|
10236
|
+
activeCount = computed(() => this.draft().conditions.length, ...(ngDevMode ? [{ debugName: "activeCount" }] : /* istanbul ignore next */ []));
|
|
10237
|
+
onDraftChange(model) {
|
|
10238
|
+
this.draft.set(model);
|
|
10239
|
+
}
|
|
10240
|
+
apply() {
|
|
10241
|
+
this.drawerRef.close({ model: this.draft(), applied: true });
|
|
10242
|
+
}
|
|
10243
|
+
clearAll() {
|
|
10244
|
+
this.draft.set({ conditions: [] });
|
|
10245
|
+
}
|
|
10246
|
+
cancel() {
|
|
10247
|
+
this.drawerRef.close({ model: this.data.model, applied: false });
|
|
10248
|
+
}
|
|
10249
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MozGridFilterDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10250
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: MozGridFilterDrawerComponent, isStandalone: true, selector: "moz-grid-filter-drawer", ngImport: i0, template: "<div class=\"filter-drawer\">\n <p class=\"filter-drawer__subtitle\">{{ activeCount() }} active filter(s)</p>\n <moz-grid-filter-builder\n [model]=\"draft()\"\n [availableColumns]=\"availableColumns\"\n [applyMode]=\"'manual'\"\n [showSubtitle]=\"false\"\n (modelChange)=\"onDraftChange($event)\"\n />\n</div>\n\n<ng-template mozDrawerFooter>\n <button moz-button [appearance]=\"'accent'\" (click)=\"apply()\">Apply</button>\n <button moz-button [outlined]=\"true\" (click)=\"clearAll()\">Clear all</button>\n</ng-template>\n", styles: [".filter-drawer{padding-bottom:16px}.filter-drawer__subtitle{margin:0 16px 8px;font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--Text-Secondary, #555)}\n"], dependencies: [{ kind: "component", type: MozGridFilterBuilderComponent, selector: "moz-grid-filter-builder", inputs: ["model", "availableColumns", "applyMode", "showSubtitle"], outputs: ["modelChange"] }, { kind: "component", type: MozButtonComponent, selector: "button[moz-button]", inputs: ["appearance", "size", "disabled", "ghost", "outlined", "iconPosition", "type", "isLoading"] }, { kind: "directive", type: MozDrawerFooterDirective, selector: "[mozDrawerFooter]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
10251
|
+
}
|
|
10252
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MozGridFilterDrawerComponent, decorators: [{
|
|
10253
|
+
type: Component,
|
|
10254
|
+
args: [{ selector: 'moz-grid-filter-drawer', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MozGridFilterBuilderComponent, MozButtonComponent, MozDrawerFooterDirective], template: "<div class=\"filter-drawer\">\n <p class=\"filter-drawer__subtitle\">{{ activeCount() }} active filter(s)</p>\n <moz-grid-filter-builder\n [model]=\"draft()\"\n [availableColumns]=\"availableColumns\"\n [applyMode]=\"'manual'\"\n [showSubtitle]=\"false\"\n (modelChange)=\"onDraftChange($event)\"\n />\n</div>\n\n<ng-template mozDrawerFooter>\n <button moz-button [appearance]=\"'accent'\" (click)=\"apply()\">Apply</button>\n <button moz-button [outlined]=\"true\" (click)=\"clearAll()\">Clear all</button>\n</ng-template>\n", styles: [".filter-drawer{padding-bottom:16px}.filter-drawer__subtitle{margin:0 16px 8px;font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--Text-Secondary, #555)}\n"] }]
|
|
10255
|
+
}] });
|
|
10256
|
+
|
|
9482
10257
|
class MozGridComponent {
|
|
9483
10258
|
state = inject(GridStateManager);
|
|
9484
10259
|
gridEngine = inject(GridEngine);
|
|
@@ -9546,7 +10321,28 @@ class MozGridComponent {
|
|
|
9546
10321
|
// --- Internal ---
|
|
9547
10322
|
isFullscreen = signal(false, ...(ngDevMode ? [{ debugName: "isFullscreen" }] : /* istanbul ignore next */ []));
|
|
9548
10323
|
groupPanelOpen = signal(false, ...(ngDevMode ? [{ debugName: "groupPanelOpen" }] : /* istanbul ignore next */ []));
|
|
9549
|
-
|
|
10324
|
+
/**
|
|
10325
|
+
* Mode controlling how the builder emits `filterChange`:
|
|
10326
|
+
* - `auto` : each mutation triggers an event (default in `client` mode).
|
|
10327
|
+
* - `manual` : only an explicit Apply emits (default in `server` mode).
|
|
10328
|
+
*/
|
|
10329
|
+
filterApplyMode = input(null, ...(ngDevMode ? [{ debugName: "filterApplyMode" }] : /* istanbul ignore next */ []));
|
|
10330
|
+
resolvedFilterApplyMode = computed(() => {
|
|
10331
|
+
const override = this.filterApplyMode();
|
|
10332
|
+
if (override)
|
|
10333
|
+
return override;
|
|
10334
|
+
return this.state.mode() === 'server' ? 'manual' : 'auto';
|
|
10335
|
+
}, ...(ngDevMode ? [{ debugName: "resolvedFilterApplyMode" }] : /* istanbul ignore next */ []));
|
|
10336
|
+
/** Display descriptors for the "FILTERED BY" tag bar. */
|
|
10337
|
+
activeFilters = computed(() => {
|
|
10338
|
+
return this.filterEngine.conditions().map((c) => ({
|
|
10339
|
+
id: c.id,
|
|
10340
|
+
field: c.field,
|
|
10341
|
+
label: this.filterEngine.toLabel(c),
|
|
10342
|
+
removable: true,
|
|
10343
|
+
}));
|
|
10344
|
+
}, ...(ngDevMode ? [{ debugName: "activeFilters" }] : /* istanbul ignore next */ []));
|
|
10345
|
+
activeFilterCount = computed(() => this.filterEngine.conditions().length, ...(ngDevMode ? [{ debugName: "activeFilterCount" }] : /* istanbul ignore next */ []));
|
|
9550
10346
|
hasHiddenColumns = computed(() => this.state.columnStates().some((col) => !col.visible), ...(ngDevMode ? [{ debugName: "hasHiddenColumns" }] : /* istanbul ignore next */ []));
|
|
9551
10347
|
hiddenColumnsList = computed(() => {
|
|
9552
10348
|
const defMap = this.state.columnDefMap();
|
|
@@ -9737,7 +10533,7 @@ class MozGridComponent {
|
|
|
9737
10533
|
this.persistenceEngine.restore(key);
|
|
9738
10534
|
}
|
|
9739
10535
|
}, { allowSignalWrites: true });
|
|
9740
|
-
// Auto-save state on column/sort changes
|
|
10536
|
+
// Auto-save state on column/sort/filter changes
|
|
9741
10537
|
effect(() => {
|
|
9742
10538
|
const key = this.stateKey();
|
|
9743
10539
|
if (!key)
|
|
@@ -9745,8 +10541,19 @@ class MozGridComponent {
|
|
|
9745
10541
|
// Read signals to track them
|
|
9746
10542
|
this.state.columnStates();
|
|
9747
10543
|
this.state.activeSorts();
|
|
10544
|
+
this.state.filterModel();
|
|
9748
10545
|
this.persistenceEngine.save(key);
|
|
9749
10546
|
});
|
|
10547
|
+
// Emit `filterChange` once per mutation. The engine's `lastEvent` signal
|
|
10548
|
+
// is set synchronously from every mutation path, guaranteeing we emit
|
|
10549
|
+
// exactly once per reason (add / update / remove / reorder / clear / replace).
|
|
10550
|
+
effect(() => {
|
|
10551
|
+
const event = this.filterEngine.lastEvent();
|
|
10552
|
+
if (!event)
|
|
10553
|
+
return;
|
|
10554
|
+
this.filterChange.emit(event);
|
|
10555
|
+
this.resetInfiniteScrollIfActive();
|
|
10556
|
+
});
|
|
9750
10557
|
// Initialize plugins
|
|
9751
10558
|
effect(() => {
|
|
9752
10559
|
const pluginList = this.plugins();
|
|
@@ -10013,8 +10820,6 @@ class MozGridComponent {
|
|
|
10013
10820
|
const range = this.cellSelectionEngine.getNormalizedRange();
|
|
10014
10821
|
if (!range)
|
|
10015
10822
|
return;
|
|
10016
|
-
if (this.state.mode() !== 'client')
|
|
10017
|
-
return;
|
|
10018
10823
|
const changes = this.clipboardEngine.fillDown(range);
|
|
10019
10824
|
if (changes.length === 0)
|
|
10020
10825
|
return;
|
|
@@ -10025,8 +10830,6 @@ class MozGridComponent {
|
|
|
10025
10830
|
const range = this.cellSelectionEngine.getNormalizedRange();
|
|
10026
10831
|
if (!range)
|
|
10027
10832
|
return;
|
|
10028
|
-
if (this.state.mode() !== 'client')
|
|
10029
|
-
return;
|
|
10030
10833
|
const changes = this.clipboardEngine.fillRight(range);
|
|
10031
10834
|
if (changes.length === 0)
|
|
10032
10835
|
return;
|
|
@@ -10121,37 +10924,35 @@ class MozGridComponent {
|
|
|
10121
10924
|
const affected = maxRow - minRow;
|
|
10122
10925
|
if (affected === 0)
|
|
10123
10926
|
return;
|
|
10124
|
-
|
|
10125
|
-
|
|
10126
|
-
|
|
10127
|
-
|
|
10128
|
-
|
|
10927
|
+
// Build a map of display index → sourceData index for the fill range
|
|
10928
|
+
const indexMap = new Map();
|
|
10929
|
+
for (let r = minRow; r <= maxRow; r++) {
|
|
10930
|
+
if (r === anchor.row)
|
|
10931
|
+
continue;
|
|
10932
|
+
const srcIdx = this.displayIndexToSourceIndex(r);
|
|
10933
|
+
if (srcIdx >= 0)
|
|
10934
|
+
indexMap.set(r, srcIdx);
|
|
10935
|
+
}
|
|
10936
|
+
const changes = [];
|
|
10937
|
+
this.state.sourceData.update((d) => {
|
|
10938
|
+
const updated = [...d];
|
|
10939
|
+
for (const [, srcIdx] of indexMap) {
|
|
10940
|
+
if (!updated[srcIdx])
|
|
10129
10941
|
continue;
|
|
10130
|
-
const
|
|
10131
|
-
if (
|
|
10132
|
-
|
|
10133
|
-
|
|
10134
|
-
|
|
10135
|
-
|
|
10136
|
-
|
|
10137
|
-
for (const [, srcIdx] of indexMap) {
|
|
10138
|
-
if (!updated[srcIdx])
|
|
10139
|
-
continue;
|
|
10140
|
-
const before = updated[srcIdx][field];
|
|
10141
|
-
if (before === sourceValue)
|
|
10142
|
-
continue;
|
|
10143
|
-
const rowCopy = { ...updated[srcIdx] };
|
|
10144
|
-
rowCopy[field] = sourceValue;
|
|
10145
|
-
updated[srcIdx] = rowCopy;
|
|
10146
|
-
changes.push({ rowIndex: srcIdx, field, before, after: sourceValue });
|
|
10147
|
-
}
|
|
10148
|
-
return updated;
|
|
10149
|
-
});
|
|
10150
|
-
if (changes.length > 0) {
|
|
10151
|
-
this.historyEngine.record('fill', changes);
|
|
10942
|
+
const before = updated[srcIdx][field];
|
|
10943
|
+
if (before === sourceValue)
|
|
10944
|
+
continue;
|
|
10945
|
+
const rowCopy = { ...updated[srcIdx] };
|
|
10946
|
+
rowCopy[field] = sourceValue;
|
|
10947
|
+
updated[srcIdx] = rowCopy;
|
|
10948
|
+
changes.push({ rowIndex: srcIdx, field, before, after: sourceValue });
|
|
10152
10949
|
}
|
|
10153
|
-
|
|
10950
|
+
return updated;
|
|
10951
|
+
});
|
|
10952
|
+
if (changes.length > 0) {
|
|
10953
|
+
this.historyEngine.record('fill', changes);
|
|
10154
10954
|
}
|
|
10955
|
+
this.clipboardEngine.clearCut();
|
|
10155
10956
|
this.fillDown.emit({
|
|
10156
10957
|
sourceCell: anchor,
|
|
10157
10958
|
sourceValue,
|
|
@@ -10190,29 +10991,27 @@ class MozGridComponent {
|
|
|
10190
10991
|
}
|
|
10191
10992
|
if (targetFields.length === 0)
|
|
10192
10993
|
return;
|
|
10193
|
-
|
|
10194
|
-
|
|
10195
|
-
|
|
10196
|
-
|
|
10197
|
-
|
|
10198
|
-
if (!src)
|
|
10199
|
-
return updated;
|
|
10200
|
-
const rowCopy = { ...src };
|
|
10201
|
-
for (const f of targetFields) {
|
|
10202
|
-
const before = src[f];
|
|
10203
|
-
if (before === sourceValue)
|
|
10204
|
-
continue;
|
|
10205
|
-
rowCopy[f] = sourceValue;
|
|
10206
|
-
changes.push({ rowIndex: anchorSourceIdx, field: f, before, after: sourceValue });
|
|
10207
|
-
}
|
|
10208
|
-
updated[anchorSourceIdx] = rowCopy;
|
|
10994
|
+
const changes = [];
|
|
10995
|
+
this.state.sourceData.update((d) => {
|
|
10996
|
+
const updated = [...d];
|
|
10997
|
+
const src = updated[anchorSourceIdx];
|
|
10998
|
+
if (!src)
|
|
10209
10999
|
return updated;
|
|
10210
|
-
}
|
|
10211
|
-
|
|
10212
|
-
|
|
11000
|
+
const rowCopy = { ...src };
|
|
11001
|
+
for (const f of targetFields) {
|
|
11002
|
+
const before = src[f];
|
|
11003
|
+
if (before === sourceValue)
|
|
11004
|
+
continue;
|
|
11005
|
+
rowCopy[f] = sourceValue;
|
|
11006
|
+
changes.push({ rowIndex: anchorSourceIdx, field: f, before, after: sourceValue });
|
|
10213
11007
|
}
|
|
10214
|
-
|
|
11008
|
+
updated[anchorSourceIdx] = rowCopy;
|
|
11009
|
+
return updated;
|
|
11010
|
+
});
|
|
11011
|
+
if (changes.length > 0) {
|
|
11012
|
+
this.historyEngine.record('fill', changes);
|
|
10215
11013
|
}
|
|
11014
|
+
this.clipboardEngine.clearCut();
|
|
10216
11015
|
this.fillDown.emit({
|
|
10217
11016
|
sourceCell: anchor,
|
|
10218
11017
|
sourceValue,
|
|
@@ -10252,17 +11051,27 @@ class MozGridComponent {
|
|
|
10252
11051
|
this.state.activeSelectionMode.set('none');
|
|
10253
11052
|
this.selectionChange.emit(this.rowSelectionEngine.getSelectionEvent());
|
|
10254
11053
|
}
|
|
10255
|
-
|
|
10256
|
-
|
|
10257
|
-
this.
|
|
10258
|
-
this.resetInfiniteScrollIfActive();
|
|
11054
|
+
/** Removes a single condition by id (tag "×" button). */
|
|
11055
|
+
onRemoveFilter(id) {
|
|
11056
|
+
this.filterEngine.removeCondition(id);
|
|
10259
11057
|
}
|
|
11058
|
+
/** Clears the whole filter model ("Remove all" button). */
|
|
10260
11059
|
onRemoveAllFilters() {
|
|
10261
|
-
|
|
10262
|
-
|
|
10263
|
-
|
|
10264
|
-
|
|
10265
|
-
|
|
11060
|
+
this.filterEngine.clearAll();
|
|
11061
|
+
}
|
|
11062
|
+
// --- Filter drawer ---
|
|
11063
|
+
onFiltersClick() {
|
|
11064
|
+
const data = {
|
|
11065
|
+
model: { conditions: this.filterEngine.conditions().slice() },
|
|
11066
|
+
availableColumns: this.filterEngine.describeFilterableColumns(),
|
|
11067
|
+
applyMode: this.resolvedFilterApplyMode(),
|
|
11068
|
+
};
|
|
11069
|
+
const ref = this.drawerService.open(MozGridFilterDrawerComponent, { title: 'Filters', data, extended: true });
|
|
11070
|
+
ref.afterClosed().subscribe((result) => {
|
|
11071
|
+
if (result?.applied) {
|
|
11072
|
+
this.filterEngine.setModel(result.model, 'replace');
|
|
11073
|
+
}
|
|
11074
|
+
});
|
|
10266
11075
|
}
|
|
10267
11076
|
onRestoreColumn(field) {
|
|
10268
11077
|
this.state.updateColumnState(field, { visible: true });
|
|
@@ -10457,8 +11266,9 @@ class MozGridComponent {
|
|
|
10457
11266
|
try {
|
|
10458
11267
|
const text = await navigator.clipboard.readText();
|
|
10459
11268
|
const pasteRows = text.split('\n').map((line) => line.split('\t'));
|
|
10460
|
-
|
|
10461
|
-
|
|
11269
|
+
const changes = this.applyPasteToSelectedRows(event.selectedRows, pasteRows);
|
|
11270
|
+
if (changes.length > 0) {
|
|
11271
|
+
this.historyEngine.record('paste', changes);
|
|
10462
11272
|
}
|
|
10463
11273
|
this.bulkPaste.emit({
|
|
10464
11274
|
range: null,
|
|
@@ -10480,28 +11290,42 @@ class MozGridComponent {
|
|
|
10480
11290
|
return;
|
|
10481
11291
|
try {
|
|
10482
11292
|
const text = await navigator.clipboard.readText();
|
|
10483
|
-
const rows = text
|
|
11293
|
+
const rows = text
|
|
11294
|
+
.replace(/\r?\n$/, '')
|
|
11295
|
+
.split('\n')
|
|
11296
|
+
.map((line) => line.split('\t'));
|
|
10484
11297
|
const cols = this.state.visibleColumns();
|
|
10485
|
-
//
|
|
10486
|
-
|
|
10487
|
-
|
|
10488
|
-
|
|
10489
|
-
|
|
10490
|
-
|
|
10491
|
-
|
|
10492
|
-
|
|
10493
|
-
if (
|
|
10494
|
-
|
|
10495
|
-
|
|
10496
|
-
|
|
10497
|
-
|
|
10498
|
-
|
|
10499
|
-
|
|
10500
|
-
|
|
10501
|
-
|
|
10502
|
-
|
|
10503
|
-
|
|
11298
|
+
// Excel-style: a single clipboard value pasted over a multi-cell selection
|
|
11299
|
+
// fills the entire selection rather than only the focused anchor.
|
|
11300
|
+
const isSingleValue = rows.length === 1 && rows[0].length === 1;
|
|
11301
|
+
const selection = this.cellSelectionEngine.getNormalizedRange();
|
|
11302
|
+
const isMultiCellSelection = !!selection &&
|
|
11303
|
+
(selection.start.row !== selection.end.row || selection.start.col !== selection.end.col);
|
|
11304
|
+
let pasteRange;
|
|
11305
|
+
let pasteChanges;
|
|
11306
|
+
if (isSingleValue && isMultiCellSelection && selection) {
|
|
11307
|
+
pasteRange = selection;
|
|
11308
|
+
pasteChanges = this.clipboardEngine.fillSelection(selection, rows[0][0]);
|
|
11309
|
+
}
|
|
11310
|
+
else {
|
|
11311
|
+
pasteRange = {
|
|
11312
|
+
start: { row: focused.row, col: focused.col },
|
|
11313
|
+
end: {
|
|
11314
|
+
row: Math.min(focused.row + rows.length - 1, this.state.sourceData().length - 1),
|
|
11315
|
+
col: Math.min(focused.col + (rows[0]?.length ?? 1) - 1, cols.length - 1),
|
|
11316
|
+
},
|
|
11317
|
+
};
|
|
11318
|
+
pasteChanges = this.clipboardEngine.applyPaste(pasteRange, rows);
|
|
10504
11319
|
}
|
|
11320
|
+
// If a cut is pending, first wipe the source cells so cut+paste == move,
|
|
11321
|
+
// and fold both halves into a single undoable history op.
|
|
11322
|
+
const cutSource = this.state.cutSource();
|
|
11323
|
+
const clearChanges = cutSource ? this.clipboardEngine.clearRange(cutSource) : [];
|
|
11324
|
+
const allChanges = [...clearChanges, ...pasteChanges];
|
|
11325
|
+
if (allChanges.length > 0) {
|
|
11326
|
+
this.historyEngine.record(cutSource ? 'cut' : 'paste', allChanges);
|
|
11327
|
+
}
|
|
11328
|
+
this.clipboardEngine.clearCut();
|
|
10505
11329
|
this.bulkPaste.emit({
|
|
10506
11330
|
range: pasteRange,
|
|
10507
11331
|
data: rows,
|
|
@@ -10541,9 +11365,12 @@ class MozGridComponent {
|
|
|
10541
11365
|
onBulkDelete() {
|
|
10542
11366
|
if (this.state.activeSelectionMode() === 'rows') {
|
|
10543
11367
|
const event = this.rowSelectionEngine.getSelectionEvent();
|
|
10544
|
-
|
|
10545
|
-
|
|
11368
|
+
const changes = this.deleteSelectedRows(event.selectedRows);
|
|
11369
|
+
if (changes.length > 0) {
|
|
11370
|
+
this.historyEngine.record('delete', changes);
|
|
10546
11371
|
}
|
|
11372
|
+
// Intentionally keep the selection active so users can chain actions
|
|
11373
|
+
// (undo, then paste, etc.) — the overlay only closes via the ✕ button.
|
|
10547
11374
|
this.bulkDelete.emit({
|
|
10548
11375
|
range: null,
|
|
10549
11376
|
cellCount: event.count,
|
|
@@ -10564,13 +11391,11 @@ class MozGridComponent {
|
|
|
10564
11391
|
return;
|
|
10565
11392
|
const rows = range.end.row - range.start.row + 1;
|
|
10566
11393
|
const colCount = range.end.col - range.start.col + 1;
|
|
10567
|
-
|
|
10568
|
-
|
|
10569
|
-
|
|
10570
|
-
this.historyEngine.record('delete', changes);
|
|
10571
|
-
}
|
|
10572
|
-
this.clipboardEngine.clearCut();
|
|
11394
|
+
const changes = this.clipboardEngine.clearRange(range);
|
|
11395
|
+
if (changes.length > 0) {
|
|
11396
|
+
this.historyEngine.record('delete', changes);
|
|
10573
11397
|
}
|
|
11398
|
+
this.clipboardEngine.clearCut();
|
|
10574
11399
|
this.bulkDelete.emit({
|
|
10575
11400
|
range,
|
|
10576
11401
|
cellCount: rows * colCount,
|
|
@@ -10623,6 +11448,7 @@ class MozGridComponent {
|
|
|
10623
11448
|
applyPasteToSelectedRows(selectedRows, pasteRows) {
|
|
10624
11449
|
const cols = this.state.visibleColumns();
|
|
10625
11450
|
const idField = this.state.rowIdField?.() ?? 'id';
|
|
11451
|
+
const changes = [];
|
|
10626
11452
|
this.state.sourceData.update((data) => {
|
|
10627
11453
|
const updated = [...data];
|
|
10628
11454
|
for (let ri = 0; ri < Math.min(selectedRows.length, pasteRows.length); ri++) {
|
|
@@ -10638,10 +11464,14 @@ class MozGridComponent {
|
|
|
10638
11464
|
if (!field)
|
|
10639
11465
|
continue;
|
|
10640
11466
|
const coerced = this.coerceAndValidate(field, pasteRows[ri][ci], updated[dataIndex]);
|
|
10641
|
-
if (coerced
|
|
10642
|
-
|
|
10643
|
-
|
|
10644
|
-
|
|
11467
|
+
if (coerced === PASTE_SKIP)
|
|
11468
|
+
continue;
|
|
11469
|
+
const before = updated[dataIndex][field];
|
|
11470
|
+
if (before === coerced)
|
|
11471
|
+
continue;
|
|
11472
|
+
rowCopy[field] = coerced;
|
|
11473
|
+
changes.push({ rowIndex: dataIndex, field, before, after: coerced });
|
|
11474
|
+
changed = true;
|
|
10645
11475
|
}
|
|
10646
11476
|
if (changed) {
|
|
10647
11477
|
updated[dataIndex] = rowCopy;
|
|
@@ -10649,10 +11479,12 @@ class MozGridComponent {
|
|
|
10649
11479
|
}
|
|
10650
11480
|
return updated;
|
|
10651
11481
|
});
|
|
11482
|
+
return changes;
|
|
10652
11483
|
}
|
|
10653
11484
|
deleteSelectedRows(selectedRows) {
|
|
10654
11485
|
const cols = this.state.visibleColumns();
|
|
10655
11486
|
const idField = this.state.rowIdField?.() ?? 'id';
|
|
11487
|
+
const changes = [];
|
|
10656
11488
|
this.state.sourceData.update((data) => {
|
|
10657
11489
|
const updated = [...data];
|
|
10658
11490
|
for (const selectedRow of selectedRows) {
|
|
@@ -10664,10 +11496,14 @@ class MozGridComponent {
|
|
|
10664
11496
|
let changed = false;
|
|
10665
11497
|
for (const col of cols) {
|
|
10666
11498
|
const coerced = this.coerceAndValidate(col.field, null, updated[dataIndex]);
|
|
10667
|
-
if (coerced
|
|
10668
|
-
|
|
10669
|
-
|
|
10670
|
-
|
|
11499
|
+
if (coerced === PASTE_SKIP)
|
|
11500
|
+
continue;
|
|
11501
|
+
const before = updated[dataIndex][col.field];
|
|
11502
|
+
if (before === coerced)
|
|
11503
|
+
continue;
|
|
11504
|
+
rowCopy[col.field] = coerced;
|
|
11505
|
+
changes.push({ rowIndex: dataIndex, field: col.field, before, after: coerced });
|
|
11506
|
+
changed = true;
|
|
10671
11507
|
}
|
|
10672
11508
|
if (changed) {
|
|
10673
11509
|
updated[dataIndex] = rowCopy;
|
|
@@ -10675,6 +11511,7 @@ class MozGridComponent {
|
|
|
10675
11511
|
}
|
|
10676
11512
|
return updated;
|
|
10677
11513
|
});
|
|
11514
|
+
return changes;
|
|
10678
11515
|
}
|
|
10679
11516
|
coerceAndValidate(field, rawValue, row) {
|
|
10680
11517
|
const def = this.state.columnDefMap().get(field);
|
|
@@ -10734,7 +11571,7 @@ class MozGridComponent {
|
|
|
10734
11571
|
return value;
|
|
10735
11572
|
}
|
|
10736
11573
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MozGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10737
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: MozGridComponent, isStandalone: true, selector: "moz-grid", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: false, transformFunction: null }, pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, rowSelection: { classPropertyName: "rowSelection", publicName: "rowSelection", isSignal: true, isRequired: false, transformFunction: null }, expandable: { classPropertyName: "expandable", publicName: "expandable", isSignal: true, isRequired: false, transformFunction: null }, rowIdField: { classPropertyName: "rowIdField", publicName: "rowIdField", isSignal: true, isRequired: false, transformFunction: null }, detailTemplate: { classPropertyName: "detailTemplate", publicName: "detailTemplate", isSignal: true, isRequired: false, transformFunction: null }, fullscreen: { classPropertyName: "fullscreen", publicName: "fullscreen", isSignal: true, isRequired: false, transformFunction: null }, reorderable: { classPropertyName: "reorderable", publicName: "reorderable", isSignal: true, isRequired: false, transformFunction: null }, stateKey: { classPropertyName: "stateKey", publicName: "stateKey", isSignal: true, isRequired: false, transformFunction: null }, exportable: { classPropertyName: "exportable", publicName: "exportable", isSignal: true, isRequired: false, transformFunction: null }, horizontalVirtualScroll: { classPropertyName: "horizontalVirtualScroll", publicName: "horizontalVirtualScroll", isSignal: true, isRequired: false, transformFunction: null }, loadingStrategy: { classPropertyName: "loadingStrategy", publicName: "loadingStrategy", isSignal: true, isRequired: false, transformFunction: null }, scrollThreshold: { classPropertyName: "scrollThreshold", publicName: "scrollThreshold", isSignal: true, isRequired: false, transformFunction: null }, plugins: { classPropertyName: "plugins", publicName: "plugins", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sortChange: "sortChange", pageChange: "pageChange", loadMore: "loadMore", cellEdit: "cellEdit", cellEditCancel: "cellEditCancel", selectionChange: "selectionChange", cellSelectionChange: "cellSelectionChange", groupChange: "groupChange", filterChange: "filterChange", bulkEdit: "bulkEdit", bulkCopy: "bulkCopy", bulkPaste: "bulkPaste", bulkDelete: "bulkDelete", fillDown: "fillDown", settingsChange: "settingsChange" }, providers: [
|
|
11574
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: MozGridComponent, isStandalone: true, selector: "moz-grid", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: false, transformFunction: null }, pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, rowSelection: { classPropertyName: "rowSelection", publicName: "rowSelection", isSignal: true, isRequired: false, transformFunction: null }, expandable: { classPropertyName: "expandable", publicName: "expandable", isSignal: true, isRequired: false, transformFunction: null }, rowIdField: { classPropertyName: "rowIdField", publicName: "rowIdField", isSignal: true, isRequired: false, transformFunction: null }, detailTemplate: { classPropertyName: "detailTemplate", publicName: "detailTemplate", isSignal: true, isRequired: false, transformFunction: null }, fullscreen: { classPropertyName: "fullscreen", publicName: "fullscreen", isSignal: true, isRequired: false, transformFunction: null }, reorderable: { classPropertyName: "reorderable", publicName: "reorderable", isSignal: true, isRequired: false, transformFunction: null }, stateKey: { classPropertyName: "stateKey", publicName: "stateKey", isSignal: true, isRequired: false, transformFunction: null }, exportable: { classPropertyName: "exportable", publicName: "exportable", isSignal: true, isRequired: false, transformFunction: null }, horizontalVirtualScroll: { classPropertyName: "horizontalVirtualScroll", publicName: "horizontalVirtualScroll", isSignal: true, isRequired: false, transformFunction: null }, loadingStrategy: { classPropertyName: "loadingStrategy", publicName: "loadingStrategy", isSignal: true, isRequired: false, transformFunction: null }, scrollThreshold: { classPropertyName: "scrollThreshold", publicName: "scrollThreshold", isSignal: true, isRequired: false, transformFunction: null }, plugins: { classPropertyName: "plugins", publicName: "plugins", isSignal: true, isRequired: false, transformFunction: null }, filterApplyMode: { classPropertyName: "filterApplyMode", publicName: "filterApplyMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sortChange: "sortChange", pageChange: "pageChange", loadMore: "loadMore", cellEdit: "cellEdit", cellEditCancel: "cellEditCancel", selectionChange: "selectionChange", cellSelectionChange: "cellSelectionChange", groupChange: "groupChange", filterChange: "filterChange", bulkEdit: "bulkEdit", bulkCopy: "bulkCopy", bulkPaste: "bulkPaste", bulkDelete: "bulkDelete", fillDown: "fillDown", settingsChange: "settingsChange" }, providers: [
|
|
10738
11575
|
GridStateManager,
|
|
10739
11576
|
GridEngine,
|
|
10740
11577
|
SortEngine,
|
|
@@ -10788,15 +11625,24 @@ class MozGridComponent {
|
|
|
10788
11625
|
<Download20 icon />
|
|
10789
11626
|
</moz-icon-button>
|
|
10790
11627
|
}
|
|
10791
|
-
<
|
|
11628
|
+
<button
|
|
11629
|
+
type="button"
|
|
11630
|
+
moz-button
|
|
10792
11631
|
id="grid-filter"
|
|
10793
11632
|
size="s"
|
|
10794
11633
|
[ghost]="true"
|
|
10795
|
-
ariaLabel="
|
|
10796
|
-
|
|
11634
|
+
[ariaLabel]="'Filters'"
|
|
11635
|
+
class="moz-grid__toolbar-filter-btn"
|
|
11636
|
+
(click)="onFiltersClick()"
|
|
10797
11637
|
>
|
|
10798
11638
|
<Filter20 icon />
|
|
10799
|
-
|
|
11639
|
+
<span>Filters</span>
|
|
11640
|
+
@if (activeFilterCount() > 0) {
|
|
11641
|
+
<span class="moz-grid__toolbar-filter-badge" aria-hidden="true">
|
|
11642
|
+
{{ activeFilterCount() }}
|
|
11643
|
+
</span>
|
|
11644
|
+
}
|
|
11645
|
+
</button>
|
|
10800
11646
|
<moz-icon-button
|
|
10801
11647
|
id="grid-settings"
|
|
10802
11648
|
size="s"
|
|
@@ -10906,15 +11752,15 @@ class MozGridComponent {
|
|
|
10906
11752
|
</button>
|
|
10907
11753
|
}
|
|
10908
11754
|
</div>
|
|
10909
|
-
} @if (
|
|
11755
|
+
} @if (activeFilters().length > 0) {
|
|
10910
11756
|
<div class="moz-grid__tag-bar">
|
|
10911
11757
|
<span class="moz-grid__tag-bar-label">FILTERED BY</span>
|
|
10912
|
-
@for (filter of
|
|
11758
|
+
@for (filter of activeFilters(); track filter.id) {
|
|
10913
11759
|
<moz-tag
|
|
10914
11760
|
[type]="filter.removable ? 'removable' : 'informative'"
|
|
10915
11761
|
size="s"
|
|
10916
|
-
[id]="'filter-' + filter.
|
|
10917
|
-
(removeTag)="onRemoveFilter(filter.
|
|
11762
|
+
[id]="'filter-' + filter.id"
|
|
11763
|
+
(removeTag)="onRemoveFilter(filter.id)"
|
|
10918
11764
|
>{{ filter.label }}</moz-tag
|
|
10919
11765
|
>
|
|
10920
11766
|
}
|
|
@@ -10976,7 +11822,7 @@ class MozGridComponent {
|
|
|
10976
11822
|
/>
|
|
10977
11823
|
</div>
|
|
10978
11824
|
</div>
|
|
10979
|
-
`, isInline: true, styles: [":host{display:block;height:100%}.moz-grid-wrapper{display:flex;flex-direction:column;font-family:var(--font-family-primary);height:100%;min-height:0;gap:16px}.moz-grid-wrapper--fullscreen{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999;background:var(--color-background-primary)}.moz-grid{display:flex;flex-direction:column;border-radius:var(--border-radius-l);overflow:hidden;background:var(--color-background-primary);flex:1;min-height:0;position:relative;box-shadow:0 0 6px #cdd4d8}.moz-grid:focus{outline:none}.moz-grid--loading{opacity:.6;pointer-events:none}.moz-grid__toolbar{display:flex;align-items:center;justify-content:space-between;flex-shrink:0;min-height:48px;gap:var(--spacing-s, 8px)}.moz-grid__toolbar-left,.moz-grid__toolbar-right{display:flex;align-items:center;gap:var(--spacing-xs, 4px)}.moz-grid__selection-banner{display:flex;align-items:center;gap:var(--spacing-s, 8px);flex:1;justify-content:center;border-radius:var(--border-radius-s);border:1px solid var(--Border-Primary, #cdd4d8);background:var(--Neutral-Grey-000, #fff)}.moz-grid__selection-text{font-size:var(--font-size-s, 14px);color:var(--color-text-primary);white-space:nowrap}.moz-grid__selection-link{padding:0;border:none;background:transparent;color:var(--color-background-accent-inverse);font-size:var(--font-size-s, 14px);font-weight:600;cursor:pointer;white-space:nowrap;text-decoration:underline}.moz-grid__selection-link:hover{color:var(--color-primary-dark, #1557b0)}.moz-grid__tag-bar{display:flex;align-items:center;flex-wrap:wrap;gap:var(--spacing-xs, 4px);padding:var(--spacing-xxs, 2px) var(--spacing-s, 8px);flex-shrink:0}.moz-grid__tag-bar-label{width:100%;font-size:var(--font-size-xs, 12px);text-transform:uppercase;white-space:nowrap;color:var(--text-icon-tertiary);font-size:var(--Typography-Font-size-Body-XS, 12px);font-weight:400}.moz-grid__tag-action-btn{padding:2px 8px;border:none;background:transparent;color:var(--color-background-accent-inverse);font-size:var(--font-size-xs, 12px);font-weight:600;cursor:pointer}.moz-grid__tag-action-btn:hover{text-decoration:underline}.moz-grid__group-tag-btn{display:inline-flex;align-items:center;gap:2px;padding:0;border:none;background:transparent;cursor:pointer;font:inherit;color:inherit;line-height:1}.moz-grid__group-tag-btn ::ng-deep svg{fill:#fff!important;width:16px;height:16px}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: MozGridHeaderComponent, selector: "moz-grid-header", inputs: ["showCheckbox", "showExpand", "reorderable"], outputs: ["sortClick", "menuAction", "resizeStart", "selectAllToggle", "columnReorder"] }, { kind: "component", type: MozGridBodyComponent, selector: "moz-grid-body", inputs: ["showCheckbox", "showExpand", "detailTemplate"], outputs: ["cellEdit", "cellEditCancel", "rowSelectionToggle", "groupToggle"] }, { kind: "component", type: MozGridFooterComponent, selector: "moz-grid-footer", inputs: ["pageSizeOptions"], outputs: ["pageChange"] }, { kind: "component", type: MozGridLoadingIndicatorComponent, selector: "moz-grid-loading-indicator" }, { kind: "component", type: MozGridSelectionBarComponent, selector: "moz-grid-selection-bar", outputs: ["editClick", "copyClick", "pasteClick", "deleteClick", "exportClick"] }, { kind: "component", type: MozTagComponent, selector: "moz-tag", inputs: ["type", "size", "id", "name", "disabled", "contextualisedNumber", "removableLabel"], outputs: ["removeTag"] }, { kind: "component", type: MozIconButtonComponent, selector: "moz-icon-button", inputs: ["id", "appearance", "size", "disabled", "ghost", "outlined", "type", "ariaLabel"], outputs: ["activated"] }, { kind: "component", type: ViewGridX420, selector: "ViewGridX420", inputs: ["hostClass"] }, { kind: "component", type: Filter20, selector: "Filter20", inputs: ["hostClass"] }, { kind: "component", type: Settings20, selector: "Settings20", inputs: ["hostClass"] }, { kind: "component", type: FullscreenEnter20, selector: "FullscreenEnter20", inputs: ["hostClass"] }, { kind: "component", type: FullscreenExit20, selector: "FullscreenExit20", inputs: ["hostClass"] }, { kind: "component", type: Download20, selector: "Download20", inputs: ["hostClass"] }, { kind: "component", type: ChevronUp20, selector: "ChevronUp20", inputs: ["hostClass"] }, { kind: "component", type: ChevronDown20, selector: "ChevronDown20", inputs: ["hostClass"] }, { kind: "component", type: Keyboard20, selector: "Keyboard20", inputs: ["hostClass"] }, { kind: "component", type: MozButtonComponent, selector: "button[moz-button]", inputs: ["appearance", "size", "disabled", "ghost", "outlined", "iconPosition", "type", "isLoading"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
11825
|
+
`, isInline: true, styles: [":host{display:block;height:100%}.moz-grid-wrapper{display:flex;flex-direction:column;font-family:var(--font-family-primary);height:100%;min-height:0;gap:16px}.moz-grid-wrapper--fullscreen{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999;background:var(--color-background-primary)}.moz-grid{display:flex;flex-direction:column;border-radius:var(--border-radius-l);overflow:hidden;background:var(--color-background-primary);flex:1;min-height:0;position:relative;box-shadow:0 0 6px #cdd4d8}.moz-grid:focus{outline:none}.moz-grid--loading{opacity:.6;pointer-events:none}.moz-grid__toolbar{display:flex;align-items:center;justify-content:space-between;flex-shrink:0;min-height:48px;gap:var(--spacing-s, 8px)}.moz-grid__toolbar-left,.moz-grid__toolbar-right{display:flex;align-items:center;gap:var(--spacing-xs, 4px)}.moz-grid__toolbar-filter-btn{display:inline-flex;align-items:center;gap:4px}.moz-grid__toolbar-filter-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 6px;border-radius:9px;background:var(--Status-Standalone-element-Primary, #0071ce);color:#fff;font-size:11px;font-weight:600;line-height:1}.moz-grid__selection-banner{display:flex;align-items:center;gap:var(--spacing-s, 8px);flex:1;justify-content:center;border-radius:var(--border-radius-s);border:1px solid var(--Border-Primary, #cdd4d8);background:var(--Neutral-Grey-000, #fff)}.moz-grid__selection-text{font-size:var(--font-size-s, 14px);color:var(--color-text-primary);white-space:nowrap}.moz-grid__selection-link{padding:0;border:none;background:transparent;color:var(--color-background-accent-inverse);font-size:var(--font-size-s, 14px);font-weight:600;cursor:pointer;white-space:nowrap;text-decoration:underline}.moz-grid__selection-link:hover{color:var(--color-primary-dark, #1557b0)}.moz-grid__tag-bar{display:flex;align-items:center;flex-wrap:wrap;gap:var(--spacing-xs, 4px);padding:var(--spacing-xxs, 2px) var(--spacing-s, 8px);flex-shrink:0}.moz-grid__tag-bar-label{width:100%;font-size:var(--font-size-xs, 12px);text-transform:uppercase;white-space:nowrap;color:var(--text-icon-tertiary);font-size:var(--Typography-Font-size-Body-XS, 12px);font-weight:400}.moz-grid__tag-action-btn{padding:2px 8px;border:none;background:transparent;color:var(--color-background-accent-inverse);font-size:var(--font-size-xs, 12px);font-weight:600;cursor:pointer}.moz-grid__tag-action-btn:hover{text-decoration:underline}.moz-grid__group-tag-btn{display:inline-flex;align-items:center;gap:2px;padding:0;border:none;background:transparent;cursor:pointer;font:inherit;color:inherit;line-height:1}.moz-grid__group-tag-btn ::ng-deep svg{fill:#fff!important;width:16px;height:16px}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: MozGridHeaderComponent, selector: "moz-grid-header", inputs: ["showCheckbox", "showExpand", "reorderable"], outputs: ["sortClick", "menuAction", "resizeStart", "selectAllToggle", "columnReorder"] }, { kind: "component", type: MozGridBodyComponent, selector: "moz-grid-body", inputs: ["showCheckbox", "showExpand", "detailTemplate"], outputs: ["cellEdit", "cellEditCancel", "rowSelectionToggle", "groupToggle"] }, { kind: "component", type: MozGridFooterComponent, selector: "moz-grid-footer", inputs: ["pageSizeOptions"], outputs: ["pageChange"] }, { kind: "component", type: MozGridLoadingIndicatorComponent, selector: "moz-grid-loading-indicator" }, { kind: "component", type: MozGridSelectionBarComponent, selector: "moz-grid-selection-bar", outputs: ["editClick", "copyClick", "pasteClick", "deleteClick", "exportClick"] }, { kind: "component", type: MozTagComponent, selector: "moz-tag", inputs: ["type", "size", "id", "name", "disabled", "contextualisedNumber", "removableLabel"], outputs: ["removeTag"] }, { kind: "component", type: MozIconButtonComponent, selector: "moz-icon-button", inputs: ["id", "appearance", "size", "disabled", "ghost", "outlined", "type", "ariaLabel"], outputs: ["activated"] }, { kind: "component", type: ViewGridX420, selector: "ViewGridX420", inputs: ["hostClass"] }, { kind: "component", type: Filter20, selector: "Filter20", inputs: ["hostClass"] }, { kind: "component", type: Settings20, selector: "Settings20", inputs: ["hostClass"] }, { kind: "component", type: FullscreenEnter20, selector: "FullscreenEnter20", inputs: ["hostClass"] }, { kind: "component", type: FullscreenExit20, selector: "FullscreenExit20", inputs: ["hostClass"] }, { kind: "component", type: Download20, selector: "Download20", inputs: ["hostClass"] }, { kind: "component", type: ChevronUp20, selector: "ChevronUp20", inputs: ["hostClass"] }, { kind: "component", type: ChevronDown20, selector: "ChevronDown20", inputs: ["hostClass"] }, { kind: "component", type: Keyboard20, selector: "Keyboard20", inputs: ["hostClass"] }, { kind: "component", type: MozButtonComponent, selector: "button[moz-button]", inputs: ["appearance", "size", "disabled", "ghost", "outlined", "iconPosition", "type", "isLoading"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
10980
11826
|
}
|
|
10981
11827
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: MozGridComponent, decorators: [{
|
|
10982
11828
|
type: Component,
|
|
@@ -11053,15 +11899,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
11053
11899
|
<Download20 icon />
|
|
11054
11900
|
</moz-icon-button>
|
|
11055
11901
|
}
|
|
11056
|
-
<
|
|
11902
|
+
<button
|
|
11903
|
+
type="button"
|
|
11904
|
+
moz-button
|
|
11057
11905
|
id="grid-filter"
|
|
11058
11906
|
size="s"
|
|
11059
11907
|
[ghost]="true"
|
|
11060
|
-
ariaLabel="
|
|
11061
|
-
|
|
11908
|
+
[ariaLabel]="'Filters'"
|
|
11909
|
+
class="moz-grid__toolbar-filter-btn"
|
|
11910
|
+
(click)="onFiltersClick()"
|
|
11062
11911
|
>
|
|
11063
11912
|
<Filter20 icon />
|
|
11064
|
-
|
|
11913
|
+
<span>Filters</span>
|
|
11914
|
+
@if (activeFilterCount() > 0) {
|
|
11915
|
+
<span class="moz-grid__toolbar-filter-badge" aria-hidden="true">
|
|
11916
|
+
{{ activeFilterCount() }}
|
|
11917
|
+
</span>
|
|
11918
|
+
}
|
|
11919
|
+
</button>
|
|
11065
11920
|
<moz-icon-button
|
|
11066
11921
|
id="grid-settings"
|
|
11067
11922
|
size="s"
|
|
@@ -11171,15 +12026,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
11171
12026
|
</button>
|
|
11172
12027
|
}
|
|
11173
12028
|
</div>
|
|
11174
|
-
} @if (
|
|
12029
|
+
} @if (activeFilters().length > 0) {
|
|
11175
12030
|
<div class="moz-grid__tag-bar">
|
|
11176
12031
|
<span class="moz-grid__tag-bar-label">FILTERED BY</span>
|
|
11177
|
-
@for (filter of
|
|
12032
|
+
@for (filter of activeFilters(); track filter.id) {
|
|
11178
12033
|
<moz-tag
|
|
11179
12034
|
[type]="filter.removable ? 'removable' : 'informative'"
|
|
11180
12035
|
size="s"
|
|
11181
|
-
[id]="'filter-' + filter.
|
|
11182
|
-
(removeTag)="onRemoveFilter(filter.
|
|
12036
|
+
[id]="'filter-' + filter.id"
|
|
12037
|
+
(removeTag)="onRemoveFilter(filter.id)"
|
|
11183
12038
|
>{{ filter.label }}</moz-tag
|
|
11184
12039
|
>
|
|
11185
12040
|
}
|
|
@@ -11241,9 +12096,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
11241
12096
|
/>
|
|
11242
12097
|
</div>
|
|
11243
12098
|
</div>
|
|
11244
|
-
`, styles: [":host{display:block;height:100%}.moz-grid-wrapper{display:flex;flex-direction:column;font-family:var(--font-family-primary);height:100%;min-height:0;gap:16px}.moz-grid-wrapper--fullscreen{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999;background:var(--color-background-primary)}.moz-grid{display:flex;flex-direction:column;border-radius:var(--border-radius-l);overflow:hidden;background:var(--color-background-primary);flex:1;min-height:0;position:relative;box-shadow:0 0 6px #cdd4d8}.moz-grid:focus{outline:none}.moz-grid--loading{opacity:.6;pointer-events:none}.moz-grid__toolbar{display:flex;align-items:center;justify-content:space-between;flex-shrink:0;min-height:48px;gap:var(--spacing-s, 8px)}.moz-grid__toolbar-left,.moz-grid__toolbar-right{display:flex;align-items:center;gap:var(--spacing-xs, 4px)}.moz-grid__selection-banner{display:flex;align-items:center;gap:var(--spacing-s, 8px);flex:1;justify-content:center;border-radius:var(--border-radius-s);border:1px solid var(--Border-Primary, #cdd4d8);background:var(--Neutral-Grey-000, #fff)}.moz-grid__selection-text{font-size:var(--font-size-s, 14px);color:var(--color-text-primary);white-space:nowrap}.moz-grid__selection-link{padding:0;border:none;background:transparent;color:var(--color-background-accent-inverse);font-size:var(--font-size-s, 14px);font-weight:600;cursor:pointer;white-space:nowrap;text-decoration:underline}.moz-grid__selection-link:hover{color:var(--color-primary-dark, #1557b0)}.moz-grid__tag-bar{display:flex;align-items:center;flex-wrap:wrap;gap:var(--spacing-xs, 4px);padding:var(--spacing-xxs, 2px) var(--spacing-s, 8px);flex-shrink:0}.moz-grid__tag-bar-label{width:100%;font-size:var(--font-size-xs, 12px);text-transform:uppercase;white-space:nowrap;color:var(--text-icon-tertiary);font-size:var(--Typography-Font-size-Body-XS, 12px);font-weight:400}.moz-grid__tag-action-btn{padding:2px 8px;border:none;background:transparent;color:var(--color-background-accent-inverse);font-size:var(--font-size-xs, 12px);font-weight:600;cursor:pointer}.moz-grid__tag-action-btn:hover{text-decoration:underline}.moz-grid__group-tag-btn{display:inline-flex;align-items:center;gap:2px;padding:0;border:none;background:transparent;cursor:pointer;font:inherit;color:inherit;line-height:1}.moz-grid__group-tag-btn ::ng-deep svg{fill:#fff!important;width:16px;height:16px}\n"] }]
|
|
11245
|
-
}], ctorParameters: () => [], propDecorators: { gridBody: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MozGridBodyComponent), { isSignal: true }] }], gridContainer: [{ type: i0.ViewChild, args: ['gridContainer', { isSignal: true }] }], columnDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => MozGridColumnDef), { isSignal: true }] }], toolbarDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => MozGridToolbarDef), { isSignal: true }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], totalItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalItems", required: false }] }], pagination: [{ type: i0.Input, args: [{ isSignal: true, alias: "pagination", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], rowSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowSelection", required: false }] }], expandable: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandable", required: false }] }], rowIdField: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowIdField", required: false }] }], detailTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "detailTemplate", required: false }] }], fullscreen: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullscreen", required: false }] }], reorderable: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderable", required: false }] }], stateKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "stateKey", required: false }] }], exportable: [{ type: i0.Input, args: [{ isSignal: true, alias: "exportable", required: false }] }], horizontalVirtualScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "horizontalVirtualScroll", required: false }] }], loadingStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingStrategy", required: false }] }], scrollThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollThreshold", required: false }] }], plugins: [{ type: i0.Input, args: [{ isSignal: true, alias: "plugins", required: false }] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], loadMore: [{ type: i0.Output, args: ["loadMore"] }], cellEdit: [{ type: i0.Output, args: ["cellEdit"] }], cellEditCancel: [{ type: i0.Output, args: ["cellEditCancel"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], cellSelectionChange: [{ type: i0.Output, args: ["cellSelectionChange"] }], groupChange: [{ type: i0.Output, args: ["groupChange"] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }], bulkEdit: [{ type: i0.Output, args: ["bulkEdit"] }], bulkCopy: [{ type: i0.Output, args: ["bulkCopy"] }], bulkPaste: [{ type: i0.Output, args: ["bulkPaste"] }], bulkDelete: [{ type: i0.Output, args: ["bulkDelete"] }], fillDown: [{ type: i0.Output, args: ["fillDown"] }], settingsChange: [{ type: i0.Output, args: ["settingsChange"] }] } });
|
|
11246
|
-
const PASTE_SKIP = Symbol('PASTE_SKIP');
|
|
12099
|
+
`, styles: [":host{display:block;height:100%}.moz-grid-wrapper{display:flex;flex-direction:column;font-family:var(--font-family-primary);height:100%;min-height:0;gap:16px}.moz-grid-wrapper--fullscreen{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999;background:var(--color-background-primary)}.moz-grid{display:flex;flex-direction:column;border-radius:var(--border-radius-l);overflow:hidden;background:var(--color-background-primary);flex:1;min-height:0;position:relative;box-shadow:0 0 6px #cdd4d8}.moz-grid:focus{outline:none}.moz-grid--loading{opacity:.6;pointer-events:none}.moz-grid__toolbar{display:flex;align-items:center;justify-content:space-between;flex-shrink:0;min-height:48px;gap:var(--spacing-s, 8px)}.moz-grid__toolbar-left,.moz-grid__toolbar-right{display:flex;align-items:center;gap:var(--spacing-xs, 4px)}.moz-grid__toolbar-filter-btn{display:inline-flex;align-items:center;gap:4px}.moz-grid__toolbar-filter-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 6px;border-radius:9px;background:var(--Status-Standalone-element-Primary, #0071ce);color:#fff;font-size:11px;font-weight:600;line-height:1}.moz-grid__selection-banner{display:flex;align-items:center;gap:var(--spacing-s, 8px);flex:1;justify-content:center;border-radius:var(--border-radius-s);border:1px solid var(--Border-Primary, #cdd4d8);background:var(--Neutral-Grey-000, #fff)}.moz-grid__selection-text{font-size:var(--font-size-s, 14px);color:var(--color-text-primary);white-space:nowrap}.moz-grid__selection-link{padding:0;border:none;background:transparent;color:var(--color-background-accent-inverse);font-size:var(--font-size-s, 14px);font-weight:600;cursor:pointer;white-space:nowrap;text-decoration:underline}.moz-grid__selection-link:hover{color:var(--color-primary-dark, #1557b0)}.moz-grid__tag-bar{display:flex;align-items:center;flex-wrap:wrap;gap:var(--spacing-xs, 4px);padding:var(--spacing-xxs, 2px) var(--spacing-s, 8px);flex-shrink:0}.moz-grid__tag-bar-label{width:100%;font-size:var(--font-size-xs, 12px);text-transform:uppercase;white-space:nowrap;color:var(--text-icon-tertiary);font-size:var(--Typography-Font-size-Body-XS, 12px);font-weight:400}.moz-grid__tag-action-btn{padding:2px 8px;border:none;background:transparent;color:var(--color-background-accent-inverse);font-size:var(--font-size-xs, 12px);font-weight:600;cursor:pointer}.moz-grid__tag-action-btn:hover{text-decoration:underline}.moz-grid__group-tag-btn{display:inline-flex;align-items:center;gap:2px;padding:0;border:none;background:transparent;cursor:pointer;font:inherit;color:inherit;line-height:1}.moz-grid__group-tag-btn ::ng-deep svg{fill:#fff!important;width:16px;height:16px}\n"] }]
|
|
12100
|
+
}], ctorParameters: () => [], propDecorators: { gridBody: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MozGridBodyComponent), { isSignal: true }] }], gridContainer: [{ type: i0.ViewChild, args: ['gridContainer', { isSignal: true }] }], columnDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => MozGridColumnDef), { isSignal: true }] }], toolbarDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => MozGridToolbarDef), { isSignal: true }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], totalItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalItems", required: false }] }], pagination: [{ type: i0.Input, args: [{ isSignal: true, alias: "pagination", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], rowSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowSelection", required: false }] }], expandable: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandable", required: false }] }], rowIdField: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowIdField", required: false }] }], detailTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "detailTemplate", required: false }] }], fullscreen: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullscreen", required: false }] }], reorderable: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderable", required: false }] }], stateKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "stateKey", required: false }] }], exportable: [{ type: i0.Input, args: [{ isSignal: true, alias: "exportable", required: false }] }], horizontalVirtualScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "horizontalVirtualScroll", required: false }] }], loadingStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingStrategy", required: false }] }], scrollThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollThreshold", required: false }] }], plugins: [{ type: i0.Input, args: [{ isSignal: true, alias: "plugins", required: false }] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], loadMore: [{ type: i0.Output, args: ["loadMore"] }], cellEdit: [{ type: i0.Output, args: ["cellEdit"] }], cellEditCancel: [{ type: i0.Output, args: ["cellEditCancel"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], cellSelectionChange: [{ type: i0.Output, args: ["cellSelectionChange"] }], groupChange: [{ type: i0.Output, args: ["groupChange"] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }], bulkEdit: [{ type: i0.Output, args: ["bulkEdit"] }], bulkCopy: [{ type: i0.Output, args: ["bulkCopy"] }], bulkPaste: [{ type: i0.Output, args: ["bulkPaste"] }], bulkDelete: [{ type: i0.Output, args: ["bulkDelete"] }], fillDown: [{ type: i0.Output, args: ["fillDown"] }], settingsChange: [{ type: i0.Output, args: ["settingsChange"] }], filterApplyMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterApplyMode", required: false }] }] } });
|
|
11247
12101
|
|
|
11248
12102
|
const DEFAULT_GRID_OPTIONS = {
|
|
11249
12103
|
mode: 'client',
|