eru-grid 0.0.55 → 0.0.56
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/eru-grid.mjs +165 -38
- package/fesm2022/eru-grid.mjs.map +1 -1
- package/package.json +1 -1
- package/types/eru-grid.d.ts +105 -28
package/fesm2022/eru-grid.mjs
CHANGED
|
@@ -1163,6 +1163,30 @@ function parseCellDate(value, pattern, keepTime = false) {
|
|
|
1163
1163
|
* the interactive cell's job, and a composite that tried to host those would be
|
|
1164
1164
|
* a layout engine. A column needing that is a `page` cell.
|
|
1165
1165
|
*/
|
|
1166
|
+
/**
|
|
1167
|
+
* A status field with its `open_status` / `close_status` lists flattened into
|
|
1168
|
+
* the `options` array the status control actually reads for its colours.
|
|
1169
|
+
*
|
|
1170
|
+
* Shared rather than done at the call site: the status cell has always built
|
|
1171
|
+
* this, and a composite part handed the raw field instead rendered every pill
|
|
1172
|
+
* in the neutral fallback — the colour lives on the option, and without the
|
|
1173
|
+
* flattened list there is no option to match the value against.
|
|
1174
|
+
*/
|
|
1175
|
+
function toStatusOptionsField(field) {
|
|
1176
|
+
if (!field || normalizeDatatype(field.datatype) !== 'status')
|
|
1177
|
+
return null;
|
|
1178
|
+
const combined = [...(field.open_status || []), ...(field.close_status || [])];
|
|
1179
|
+
return {
|
|
1180
|
+
...field,
|
|
1181
|
+
options: combined.map((status) => ({
|
|
1182
|
+
name: status?.name,
|
|
1183
|
+
color: status?.color || '',
|
|
1184
|
+
df: status?.df || false,
|
|
1185
|
+
})),
|
|
1186
|
+
open_status: field.open_status || [],
|
|
1187
|
+
close_status: field.close_status || [],
|
|
1188
|
+
};
|
|
1189
|
+
}
|
|
1166
1190
|
function formatCellValue(value, field) {
|
|
1167
1191
|
if (value === null || value === undefined || value === '')
|
|
1168
1192
|
return '';
|
|
@@ -11165,11 +11189,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
11165
11189
|
* Several of the row's own columns rendered as one cell — a name over an email,
|
|
11166
11190
|
* an amount over a date.
|
|
11167
11191
|
*
|
|
11168
|
-
* View-only
|
|
11169
|
-
* field's rules (`formatCellValue`), so a currency part keeps its symbol and
|
|
11170
|
-
* decimals and a date part keeps its pattern; the composite itself decides only
|
|
11171
|
-
* arrangement and emphasis. Editing stays on the underlying columns, which are
|
|
11192
|
+
* View-only by design: editing stays on the underlying columns, which are
|
|
11172
11193
|
* usually hidden once composed.
|
|
11194
|
+
*
|
|
11195
|
+
* A part whose datatype has a visual form of its own — a rating, a progress
|
|
11196
|
+
* bar, a status pill, tags, a priority, people, a checkbox — is drawn with that
|
|
11197
|
+
* control rather than as text, since "4" and "75" tell a reader far less than
|
|
11198
|
+
* four stars and a bar. Everything else is formatted by its OWN field's rules
|
|
11199
|
+
* (`formatCellValue`), so a currency part keeps its symbol and decimals and a
|
|
11200
|
+
* date part keeps its pattern — wrapping those in a control would render the
|
|
11201
|
+
* same string in a heavier box. The composite itself decides only arrangement
|
|
11202
|
+
* and emphasis.
|
|
11173
11203
|
*/
|
|
11174
11204
|
class CompositeComponent {
|
|
11175
11205
|
row = input(null, ...(ngDevMode ? [{ debugName: "row" }] : []));
|
|
@@ -11186,6 +11216,25 @@ class CompositeComponent {
|
|
|
11186
11216
|
}, ...(ngDevMode ? [{ debugName: "labelPosition" }] : []));
|
|
11187
11217
|
primaryCss = computed(() => cellTextStyleToCss(this.column()?.cell_style), ...(ngDevMode ? [{ debugName: "primaryCss" }] : []));
|
|
11188
11218
|
secondaryCss = computed(() => cellTextStyleToCss(this.column()?.cell_style_secondary ?? DEFAULT_SECONDARY_STYLE), ...(ngDevMode ? [{ debugName: "secondaryCss" }] : []));
|
|
11219
|
+
/**
|
|
11220
|
+
* The third part and any beyond it.
|
|
11221
|
+
*
|
|
11222
|
+
* Falls back to the secondary style when unset, so every composite authored
|
|
11223
|
+
* before this existed keeps the look it had — three parts sharing one style
|
|
11224
|
+
* is precisely what this is for, not what it breaks.
|
|
11225
|
+
*/
|
|
11226
|
+
tertiaryCss = computed(() => cellTextStyleToCss(this.column()?.cell_style_tertiary
|
|
11227
|
+
?? this.column()?.cell_style_secondary
|
|
11228
|
+
?? DEFAULT_SECONDARY_STYLE), ...(ngDevMode ? [{ debugName: "tertiaryCss" }] : []));
|
|
11229
|
+
/**
|
|
11230
|
+
* Primary, secondary, then tertiary for the rest — keyed on the part's
|
|
11231
|
+
* configured slot, never on where it ended up after empty parts were dropped.
|
|
11232
|
+
*/
|
|
11233
|
+
cssForSlot(slot) {
|
|
11234
|
+
if (slot === 0)
|
|
11235
|
+
return this.primaryCss();
|
|
11236
|
+
return slot === 1 ? this.secondaryCss() : this.tertiaryCss();
|
|
11237
|
+
}
|
|
11189
11238
|
/**
|
|
11190
11239
|
* Falls back to the composite column itself when `composite_fields` is unset
|
|
11191
11240
|
* or names nothing that exists, so a column switched to `composite` before it
|
|
@@ -11200,7 +11249,8 @@ class CompositeComponent {
|
|
|
11200
11249
|
const row = this.row();
|
|
11201
11250
|
const labels = column.composite_labels || [];
|
|
11202
11251
|
const parts = names.map((name, index) => {
|
|
11203
|
-
const field = byName.get(name);
|
|
11252
|
+
const field = byName.get(name) ?? null;
|
|
11253
|
+
const value = readRowValue(row, name);
|
|
11204
11254
|
// Blank means no label for THIS part, never the field's own label as a
|
|
11205
11255
|
// fallback: a composite is usually built from columns whose labels are
|
|
11206
11256
|
// what the header already says, so falling back printed "Upload Date"
|
|
@@ -11209,15 +11259,98 @@ class CompositeComponent {
|
|
|
11209
11259
|
return {
|
|
11210
11260
|
name,
|
|
11211
11261
|
label: String(labels[index] ?? '').trim(),
|
|
11212
|
-
text: formatCellValue(
|
|
11262
|
+
text: formatCellValue(value, CompositeComponent.withRowSymbol(field, row)),
|
|
11263
|
+
field,
|
|
11264
|
+
value,
|
|
11265
|
+
numeric: CompositeComponent.isNumeric(field),
|
|
11266
|
+
render: CompositeComponent.selfDrawnDatatype(field),
|
|
11267
|
+
slot: index,
|
|
11213
11268
|
};
|
|
11214
11269
|
});
|
|
11215
|
-
|
|
11270
|
+
// A drawn part counts as populated even with an empty formatted string: an
|
|
11271
|
+
// unrated row still shows its empty stars, and a 0% bar is a real reading.
|
|
11272
|
+
const populated = parts.filter(part => part.text !== '' || part.render !== '');
|
|
11216
11273
|
if (populated.length > 0)
|
|
11217
11274
|
return populated;
|
|
11218
|
-
const own = formatCellValue(readRowValue(row, column.name), column);
|
|
11219
|
-
return own === '' ? [] : [{
|
|
11275
|
+
const own = formatCellValue(readRowValue(row, column.name), CompositeComponent.withRowSymbol(column, row));
|
|
11276
|
+
return own === '' ? [] : [{
|
|
11277
|
+
name: column.name,
|
|
11278
|
+
label: column.label,
|
|
11279
|
+
text: own,
|
|
11280
|
+
numeric: CompositeComponent.isNumeric(column),
|
|
11281
|
+
field: column,
|
|
11282
|
+
value: readRowValue(row, column.name),
|
|
11283
|
+
render: '',
|
|
11284
|
+
slot: 0,
|
|
11285
|
+
}];
|
|
11220
11286
|
}, ...(ngDevMode ? [{ debugName: "parts" }] : []));
|
|
11287
|
+
/**
|
|
11288
|
+
* Datatypes drawn with their own control instead of as text.
|
|
11289
|
+
*
|
|
11290
|
+
* The test is "does this type carry meaning a string cannot" — stars, a bar,
|
|
11291
|
+
* a coloured pill, chips, avatars, a tick. A currency or a date is already
|
|
11292
|
+
* fully said by `formatCellValue`, so it stays text.
|
|
11293
|
+
*/
|
|
11294
|
+
static SELF_DRAWN = new Set([
|
|
11295
|
+
'rating', 'progress', 'status', 'tag', 'priority', 'people', 'checkbox',
|
|
11296
|
+
]);
|
|
11297
|
+
/**
|
|
11298
|
+
* The field with this ROW's currency symbol resolved onto it.
|
|
11299
|
+
*
|
|
11300
|
+
* `formatCellValue` only knows the column's static `symbol`, but a
|
|
11301
|
+
* multi-currency column names a sibling column in `symbol_field` and takes
|
|
11302
|
+
* the symbol from each record — which is how the currency CELL renders it
|
|
11303
|
+
* (it is handed the row for exactly this). Without it a composed currency
|
|
11304
|
+
* part lost its symbol and read as a bare number.
|
|
11305
|
+
*/
|
|
11306
|
+
static withRowSymbol(field, row) {
|
|
11307
|
+
const symbolField = String(field?.symbol_field || '').trim();
|
|
11308
|
+
if (!field || !symbolField)
|
|
11309
|
+
return field;
|
|
11310
|
+
const raw = readRowValue(row, symbolField);
|
|
11311
|
+
const symbol = raw === null || raw === undefined ? '' : String(raw).trim();
|
|
11312
|
+
return symbol ? { ...field, symbol } : field;
|
|
11313
|
+
}
|
|
11314
|
+
/** Figures are right-aligned by their own cell, so a composed one is too. */
|
|
11315
|
+
static isNumeric(field) {
|
|
11316
|
+
const datatype = effectiveValueDatatype(field ?? undefined);
|
|
11317
|
+
return datatype === 'currency' || datatype === 'number';
|
|
11318
|
+
}
|
|
11319
|
+
static selfDrawnDatatype(field) {
|
|
11320
|
+
const datatype = normalizeDatatype(field?.datatype ?? '');
|
|
11321
|
+
return CompositeComponent.SELF_DRAWN.has(datatype) ? datatype : '';
|
|
11322
|
+
}
|
|
11323
|
+
/**
|
|
11324
|
+
* A status part needs its option colours flattened the same way the status
|
|
11325
|
+
* CELL does, or every pill renders in the neutral fallback.
|
|
11326
|
+
*/
|
|
11327
|
+
statusConfig(field) {
|
|
11328
|
+
return toStatusOptionsField(field);
|
|
11329
|
+
}
|
|
11330
|
+
/** Rating takes a shape of its own rather than the raw Field. */
|
|
11331
|
+
ratingConfig(field) {
|
|
11332
|
+
const config = field;
|
|
11333
|
+
return {
|
|
11334
|
+
startValue: config?.start_value || 1,
|
|
11335
|
+
endValue: config?.end_value || 5,
|
|
11336
|
+
emojiValue: config?.emoji_value || 'star',
|
|
11337
|
+
};
|
|
11338
|
+
}
|
|
11339
|
+
/** Controls want their own types; a row value can arrive as anything. */
|
|
11340
|
+
asNumber(value) {
|
|
11341
|
+
const n = Number(value);
|
|
11342
|
+
return Number.isFinite(n) ? n : 0;
|
|
11343
|
+
}
|
|
11344
|
+
asText(value) {
|
|
11345
|
+
return value === null || value === undefined ? null : String(value);
|
|
11346
|
+
}
|
|
11347
|
+
asList(value) {
|
|
11348
|
+
if (Array.isArray(value))
|
|
11349
|
+
return value.map(v => String(v));
|
|
11350
|
+
if (value === null || value === undefined || value === '')
|
|
11351
|
+
return null;
|
|
11352
|
+
return String(value).split(',').map(v => v.trim()).filter(Boolean);
|
|
11353
|
+
}
|
|
11221
11354
|
onDrilldown(event, part) {
|
|
11222
11355
|
if (!this.isDrillable())
|
|
11223
11356
|
return;
|
|
@@ -11225,11 +11358,20 @@ class CompositeComponent {
|
|
|
11225
11358
|
this.drilldownClick.emit(part.text);
|
|
11226
11359
|
}
|
|
11227
11360
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CompositeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
11228
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: CompositeComponent, isStandalone: true, selector: "eru-composite", inputs: { row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: false, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, isDrillable: { classPropertyName: "isDrillable", publicName: "isDrillable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { drilldownClick: "drilldownClick" }, ngImport: i0, template: "<div class=\"eru-composite\" [class.eru-composite--inline]=\"inline()\"\n [class.eru-composite--labelled]=\"labelPosition() !== 'none'\">\n @for (part of parts(); track part.name; let first = $first; let last = $last) {\n <span class=\"eru-composite__slot\">\n @if (labelPosition() === 'left' && part.label) {\n <span class=\"eru-composite__label\" [ngStyle]=\"
|
|
11361
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: CompositeComponent, isStandalone: true, selector: "eru-composite", inputs: { row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: false, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, isDrillable: { classPropertyName: "isDrillable", publicName: "isDrillable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { drilldownClick: "drilldownClick" }, ngImport: i0, template: "<div class=\"eru-composite\" [class.eru-composite--inline]=\"inline()\"\n [class.eru-composite--labelled]=\"labelPosition() !== 'none'\">\n @for (part of parts(); track part.name; let first = $first; let last = $last) {\n <span class=\"eru-composite__slot\">\n @if (labelPosition() === 'left' && part.label) {\n <span class=\"eru-composite__label\" [ngStyle]=\"cssForSlot(part.slot)\">{{ part.label }}</span>\n }\n @if (part.render) {\n <!-- A datatype that draws itself. Rendered read-only with pointer events\n off (see .eru-composite__control): a composite is a view, so a rating\n here must not take a click that would edit the underlying column. The\n secondary slot scales the control down so the primary still leads. -->\n <span class=\"eru-composite__control\" [ngClass]=\"'eru-composite__control--' + part.render\"\n [class.eru-composite__control--secondary]=\"part.slot > 0\">\n @switch (part.render) {\n @case ('rating') {\n <eru-rating [value]=\"asNumber(part.value)\" [config]=\"ratingConfig(part.field)\" [isEditable]=\"false\"></eru-rating>\n }\n @case ('progress') {\n <eru-progress [value]=\"asNumber(part.value)\" [config]=\"part.field\" [isEditable]=\"false\"></eru-progress>\n }\n @case ('status') {\n <eru-status [value]=\"asText(part.value)\" [config]=\"statusConfig(part.field)\" [isEditable]=\"false\"></eru-status>\n }\n @case ('tag') {\n <eru-tag [value]=\"asList(part.value)\" [config]=\"part.field\" [isEditable]=\"false\"></eru-tag>\n }\n @case ('priority') {\n <eru-priority [value]=\"asText(part.value)\" [config]=\"part.field\" [isEditable]=\"false\"></eru-priority>\n }\n @case ('people') {\n <eru-people [value]=\"asList(part.value)\" [config]=\"part.field\" [isEditable]=\"false\"></eru-people>\n }\n @case ('checkbox') {\n <eru-checkbox [value]=\"part.value\" [config]=\"part.field\" [isEditable]=\"false\"></eru-checkbox>\n }\n }\n </span>\n } @else {\n <span class=\"eru-composite__part\" [class.eru-composite__part--secondary]=\"part.slot > 0\"\n [class.eru-composite__part--numeric]=\"part.numeric\"\n [class.eru-composite__part--drillable]=\"isDrillable() && part.slot === 0\" [ngStyle]=\"cssForSlot(part.slot)\"\n [title]=\"part.text\" (click)=\"onDrilldown($event, part)\">{{ part.text }}</span>\n }\n @if (labelPosition() === 'right' && part.label) {\n <span class=\"eru-composite__label\" [ngStyle]=\"cssForSlot(part.slot)\">{{ part.label }}</span>\n }\n </span>\n @if (inline() && !last && separator()) {\n <span class=\"eru-composite__sep\" [ngStyle]=\"secondaryCss()\">{{ separator() }}</span>\n }\n }\n</div>\n", styles: [".eru-composite{display:flex;flex-direction:column;justify-content:center;gap:3px;min-width:0;width:100%;height:100%;line-height:1.3;box-sizing:border-box;padding:0 var(--grid-cell-inset-x, 8px)}.eru-composite--inline{flex-direction:row;align-items:baseline;justify-content:flex-start;gap:4px}.eru-composite__part{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.eru-composite__part--drillable{color:var(--grid-primary);cursor:pointer;text-decoration:underline}.eru-composite__sep{flex:0 0 auto}.eru-composite__part--secondary{line-height:1.15}.eru-composite__slot{display:contents}.eru-composite--labelled .eru-composite__slot{display:inline-flex;align-items:baseline;gap:4px;min-width:0}.eru-composite__label{flex:0 0 auto;white-space:nowrap;opacity:.75}.eru-composite__control{display:inline-flex;align-items:center;justify-content:flex-start;min-width:0;pointer-events:none}.eru-composite__control--progress{display:flex;width:100%}.eru-composite__control--progress>eru-progress{display:block;flex:1 1 auto;width:100%;min-width:0}.eru-composite--inline .eru-composite__control--progress{width:auto;min-width:72px}.eru-composite__control>*{margin-left:0;margin-right:0}.eru-composite__control--status .status-display,.eru-composite__control--status .status-dot-display{margin:0}.eru-composite__control--tag .tag-display,.eru-composite__control--priority .priority-display{padding:0}.eru-composite__control--progress .progress-view-container{padding:0;max-height:none}.eru-composite__control--secondary{transform:scale(.78);transform-origin:left center;margin-right:-22%}.eru-composite:not(.eru-composite--inline) .eru-composite__part--numeric{text-align:right}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: RatingComponent, selector: "eru-rating", inputs: ["value", "config", "isEditable", "isActive"], outputs: ["valueChange", "editModeChange"] }, { kind: "component", type: ProgressComponent, selector: "eru-progress", inputs: ["value", "config", "isEditable", "isActive", "isDrillable", "columnWidth", "fieldSize", "eruGridStore"], outputs: ["valueChange", "blur", "focus", "drilldownClick", "editModeChange"] }, { kind: "component", type: StatusComponent, selector: "eru-status", inputs: ["value", "config", "isEditable", "isActive", "isDrillable", "columnWidth", "fieldSize", "eruGridStore"], outputs: ["valueChange", "blur", "focus", "drilldownClick", "editModeChange"] }, { kind: "component", type: TagComponent, selector: "eru-tag", inputs: ["value", "config", "isEditable", "isActive", "isDrillable", "columnWidth", "fieldSize", "eruGridStore"], outputs: ["valueChange", "blur", "focus", "drilldownClick", "editModeChange", "newTagAdded"] }, { kind: "component", type: PriorityComponent, selector: "eru-priority", inputs: ["value", "config", "isEditable", "isActive", "isDrillable", "columnWidth", "fieldSize", "eruGridStore"], outputs: ["valueChange", "blur", "focus", "drilldownClick", "editModeChange"] }, { kind: "component", type: PeopleComponent, selector: "eru-people", inputs: ["value", "config", "isEditable", "isActive", "isDrillable", "columnWidth", "eruGridStore", "personCardTemplate"], outputs: ["valueChange", "blur", "focus", "drilldownClick", "editModeChange"] }, { kind: "component", type: CheckboxComponent, selector: "eru-checkbox", inputs: ["value", "config", "isEditable", "isActive", "isDrillable", "label"], outputs: ["valueChange", "change", "blur", "focus", "drilldownClick", "editModeChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
11229
11362
|
}
|
|
11230
11363
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CompositeComponent, decorators: [{
|
|
11231
11364
|
type: Component,
|
|
11232
|
-
args: [{ selector: 'eru-composite', standalone: true, imports: [
|
|
11365
|
+
args: [{ selector: 'eru-composite', standalone: true, imports: [
|
|
11366
|
+
CommonModule,
|
|
11367
|
+
RatingComponent,
|
|
11368
|
+
ProgressComponent,
|
|
11369
|
+
StatusComponent,
|
|
11370
|
+
TagComponent,
|
|
11371
|
+
PriorityComponent,
|
|
11372
|
+
PeopleComponent,
|
|
11373
|
+
CheckboxComponent,
|
|
11374
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"eru-composite\" [class.eru-composite--inline]=\"inline()\"\n [class.eru-composite--labelled]=\"labelPosition() !== 'none'\">\n @for (part of parts(); track part.name; let first = $first; let last = $last) {\n <span class=\"eru-composite__slot\">\n @if (labelPosition() === 'left' && part.label) {\n <span class=\"eru-composite__label\" [ngStyle]=\"cssForSlot(part.slot)\">{{ part.label }}</span>\n }\n @if (part.render) {\n <!-- A datatype that draws itself. Rendered read-only with pointer events\n off (see .eru-composite__control): a composite is a view, so a rating\n here must not take a click that would edit the underlying column. The\n secondary slot scales the control down so the primary still leads. -->\n <span class=\"eru-composite__control\" [ngClass]=\"'eru-composite__control--' + part.render\"\n [class.eru-composite__control--secondary]=\"part.slot > 0\">\n @switch (part.render) {\n @case ('rating') {\n <eru-rating [value]=\"asNumber(part.value)\" [config]=\"ratingConfig(part.field)\" [isEditable]=\"false\"></eru-rating>\n }\n @case ('progress') {\n <eru-progress [value]=\"asNumber(part.value)\" [config]=\"part.field\" [isEditable]=\"false\"></eru-progress>\n }\n @case ('status') {\n <eru-status [value]=\"asText(part.value)\" [config]=\"statusConfig(part.field)\" [isEditable]=\"false\"></eru-status>\n }\n @case ('tag') {\n <eru-tag [value]=\"asList(part.value)\" [config]=\"part.field\" [isEditable]=\"false\"></eru-tag>\n }\n @case ('priority') {\n <eru-priority [value]=\"asText(part.value)\" [config]=\"part.field\" [isEditable]=\"false\"></eru-priority>\n }\n @case ('people') {\n <eru-people [value]=\"asList(part.value)\" [config]=\"part.field\" [isEditable]=\"false\"></eru-people>\n }\n @case ('checkbox') {\n <eru-checkbox [value]=\"part.value\" [config]=\"part.field\" [isEditable]=\"false\"></eru-checkbox>\n }\n }\n </span>\n } @else {\n <span class=\"eru-composite__part\" [class.eru-composite__part--secondary]=\"part.slot > 0\"\n [class.eru-composite__part--numeric]=\"part.numeric\"\n [class.eru-composite__part--drillable]=\"isDrillable() && part.slot === 0\" [ngStyle]=\"cssForSlot(part.slot)\"\n [title]=\"part.text\" (click)=\"onDrilldown($event, part)\">{{ part.text }}</span>\n }\n @if (labelPosition() === 'right' && part.label) {\n <span class=\"eru-composite__label\" [ngStyle]=\"cssForSlot(part.slot)\">{{ part.label }}</span>\n }\n </span>\n @if (inline() && !last && separator()) {\n <span class=\"eru-composite__sep\" [ngStyle]=\"secondaryCss()\">{{ separator() }}</span>\n }\n }\n</div>\n", styles: [".eru-composite{display:flex;flex-direction:column;justify-content:center;gap:3px;min-width:0;width:100%;height:100%;line-height:1.3;box-sizing:border-box;padding:0 var(--grid-cell-inset-x, 8px)}.eru-composite--inline{flex-direction:row;align-items:baseline;justify-content:flex-start;gap:4px}.eru-composite__part{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.eru-composite__part--drillable{color:var(--grid-primary);cursor:pointer;text-decoration:underline}.eru-composite__sep{flex:0 0 auto}.eru-composite__part--secondary{line-height:1.15}.eru-composite__slot{display:contents}.eru-composite--labelled .eru-composite__slot{display:inline-flex;align-items:baseline;gap:4px;min-width:0}.eru-composite__label{flex:0 0 auto;white-space:nowrap;opacity:.75}.eru-composite__control{display:inline-flex;align-items:center;justify-content:flex-start;min-width:0;pointer-events:none}.eru-composite__control--progress{display:flex;width:100%}.eru-composite__control--progress>eru-progress{display:block;flex:1 1 auto;width:100%;min-width:0}.eru-composite--inline .eru-composite__control--progress{width:auto;min-width:72px}.eru-composite__control>*{margin-left:0;margin-right:0}.eru-composite__control--status .status-display,.eru-composite__control--status .status-dot-display{margin:0}.eru-composite__control--tag .tag-display,.eru-composite__control--priority .priority-display{padding:0}.eru-composite__control--progress .progress-view-container{padding:0;max-height:none}.eru-composite__control--secondary{transform:scale(.78);transform-origin:left center;margin-right:-22%}.eru-composite:not(.eru-composite--inline) .eru-composite__part--numeric{text-align:right}\n"] }]
|
|
11233
11375
|
}], propDecorators: { row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: false }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], isDrillable: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDrillable", required: false }] }], drilldownClick: [{ type: i0.Output, args: ["drilldownClick"] }] } });
|
|
11234
11376
|
const DEFAULT_SECONDARY_STYLE = {
|
|
11235
11377
|
font_size: 11,
|
|
@@ -11681,32 +11823,9 @@ class DataCellComponent {
|
|
|
11681
11823
|
onSelectDrilldown(value) {
|
|
11682
11824
|
this.handleDrilldown(value);
|
|
11683
11825
|
}
|
|
11684
|
-
// Status component handlers
|
|
11685
|
-
|
|
11686
|
-
|
|
11687
|
-
if (!config || config.datatype !== 'status') {
|
|
11688
|
-
return null;
|
|
11689
|
-
}
|
|
11690
|
-
// Combine open and close status
|
|
11691
|
-
const combinedStatus = [
|
|
11692
|
-
...(config.open_status || []),
|
|
11693
|
-
...(config.close_status || [])
|
|
11694
|
-
];
|
|
11695
|
-
// Transform to Field format with options array
|
|
11696
|
-
// Each option should have 'name' and 'color' properties
|
|
11697
|
-
const options = combinedStatus.map((status) => ({
|
|
11698
|
-
name: status.name,
|
|
11699
|
-
color: status.color || '',
|
|
11700
|
-
df: status.df || false
|
|
11701
|
-
}));
|
|
11702
|
-
// Return Field object with combined options and preserved open/close arrays
|
|
11703
|
-
return {
|
|
11704
|
-
...config,
|
|
11705
|
-
options: options,
|
|
11706
|
-
open_status: config.open_status || [],
|
|
11707
|
-
close_status: config.close_status || []
|
|
11708
|
-
};
|
|
11709
|
-
}, ...(ngDevMode ? [{ debugName: "getStatusConfig" }] : []));
|
|
11826
|
+
// Status component handlers. The flattening lives in the model so a composed
|
|
11827
|
+
// status part builds the same config from the same definition.
|
|
11828
|
+
getStatusConfig = computed(() => toStatusOptionsField(this.columnCellConfiguration()), ...(ngDevMode ? [{ debugName: "getStatusConfig" }] : []));
|
|
11710
11829
|
onStatusBlur(value) {
|
|
11711
11830
|
this.currentValue.set(value);
|
|
11712
11831
|
this.eruGridStore().setActiveCell(null);
|
|
@@ -13402,6 +13521,14 @@ const COMPOSITE_FIELDS = [
|
|
|
13402
13521
|
showWhen: f => f.composite_label_position === 'left' || f.composite_label_position === 'right',
|
|
13403
13522
|
},
|
|
13404
13523
|
{ key: 'cell_style_secondary', label: 'Secondary value style', control: 'text_style' },
|
|
13524
|
+
{
|
|
13525
|
+
// Only once a third part exists: on a two-part composite the control would
|
|
13526
|
+
// style nothing, and the panel already runs long.
|
|
13527
|
+
key: 'cell_style_tertiary',
|
|
13528
|
+
label: 'Third value style',
|
|
13529
|
+
control: 'text_style',
|
|
13530
|
+
showWhen: f => (f.composite_fields || []).filter(Boolean).length > 2,
|
|
13531
|
+
},
|
|
13405
13532
|
];
|
|
13406
13533
|
const PAGE_CELL_FIELDS = [
|
|
13407
13534
|
{ key: 'cell_page_id', label: 'Cell page', control: 'text' },
|
|
@@ -17124,5 +17251,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
17124
17251
|
* Generated bundle index. Do not edit.
|
|
17125
17252
|
*/
|
|
17126
17253
|
|
|
17127
|
-
export { ACTION_COLUMN_MIN_WIDTH, AttachmentComponent, CELL_RULE_OPERATORS, CheckboxComponent, ChipListComponent, ColumnConstraintsService, CompositeComponent, CurrencyComponent, CustomVirtualScrollStrategy, DATA_TYPES, DATETIME_FORMATS, DATE_FORMATS, DateComponent, DatetimeComponent, DurationComponent, EXPLICITLY_OVERRIDDEN_FIELD_KEYS, EmailComponent, EruGridComponent, EruGridService, EruGridStore, GRID_COLOR_TOKENS, INHERITED_FIELD_KEYS, LocationComponent, MATERIAL_MODULES, MATERIAL_PROVIDERS, MONTH_SHORT_NAMES, NumberComponent, NumericInputDirective, PRESENTATION_DATATYPES, PRESET_CONFIG_DEFAULTS, PRESET_MANAGED_FIELDS, PeopleComponent, PhoneComponent, PriorityComponent, ProgressComponent, RatingComponent, SEEDED_FIELD_KEYS, SELF_COLOURED_DATATYPES, SelectComponent, StatusComponent, TagComponent, TextareaComponent, TextboxComponent, ThemeService, ThemeToggleComponent, WebsiteComponent, abbreviateNumber, abbreviationScaleFor, cellRuleBarPercent, cellRuleMatches, cellRuleToCss, cellStatAlias, cellTextStyleToCss, collectColumnStatRequests, columnCellRules, composeColorValue, effectiveValueDatatype, evaluateRowCondition, formatCellValue, formatDateTimeWithPattern, formatDateWithPattern, formatNumberValue, hasOwnCellRules, matchCellRule, matchColorRange, normalizeCellRender, normalizeDatatype, normalizeDateFormat, normalizeDateTimeFormat, parseCellDate, parseCellDateTime, parseColorValue, parseDateWithPattern, readRowValue, resolveColumnRules, resolveRowValue, resolveStatValue, rowSelectionKey, statusPillColors, tagPillColors, toDateOnlyString, toDateTimeString };
|
|
17254
|
+
export { ACTION_COLUMN_MIN_WIDTH, AttachmentComponent, CELL_RULE_OPERATORS, CheckboxComponent, ChipListComponent, ColumnConstraintsService, CompositeComponent, CurrencyComponent, CustomVirtualScrollStrategy, DATA_TYPES, DATETIME_FORMATS, DATE_FORMATS, DateComponent, DatetimeComponent, DurationComponent, EXPLICITLY_OVERRIDDEN_FIELD_KEYS, EmailComponent, EruGridComponent, EruGridService, EruGridStore, GRID_COLOR_TOKENS, INHERITED_FIELD_KEYS, LocationComponent, MATERIAL_MODULES, MATERIAL_PROVIDERS, MONTH_SHORT_NAMES, NumberComponent, NumericInputDirective, PRESENTATION_DATATYPES, PRESET_CONFIG_DEFAULTS, PRESET_MANAGED_FIELDS, PeopleComponent, PhoneComponent, PriorityComponent, ProgressComponent, RatingComponent, SEEDED_FIELD_KEYS, SELF_COLOURED_DATATYPES, SelectComponent, StatusComponent, TagComponent, TextareaComponent, TextboxComponent, ThemeService, ThemeToggleComponent, WebsiteComponent, abbreviateNumber, abbreviationScaleFor, cellRuleBarPercent, cellRuleMatches, cellRuleToCss, cellStatAlias, cellTextStyleToCss, collectColumnStatRequests, columnCellRules, composeColorValue, effectiveValueDatatype, evaluateRowCondition, formatCellValue, formatDateTimeWithPattern, formatDateWithPattern, formatNumberValue, hasOwnCellRules, matchCellRule, matchColorRange, normalizeCellRender, normalizeDatatype, normalizeDateFormat, normalizeDateTimeFormat, parseCellDate, parseCellDateTime, parseColorValue, parseDateWithPattern, readRowValue, resolveColumnRules, resolveRowValue, resolveStatValue, rowSelectionKey, statusPillColors, tagPillColors, toDateOnlyString, toDateTimeString, toStatusOptionsField };
|
|
17128
17255
|
//# sourceMappingURL=eru-grid.mjs.map
|