chrv-components 1.12.230 → 1.12.232
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.
|
@@ -7596,1851 +7596,1883 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
7596
7596
|
}]
|
|
7597
7597
|
}], propDecorators: { columnName: [{ type: i0.Input, args: [{ isSignal: true, alias: "chrCellDef", required: false }] }], dataType: [{ type: i0.Input, args: [{ isSignal: true, alias: "chrCellDefType", required: false }] }] } });
|
|
7598
7598
|
|
|
7599
|
-
class
|
|
7600
|
-
constructor() {
|
|
7601
|
-
this.
|
|
7602
|
-
this.
|
|
7603
|
-
|
|
7604
|
-
this.
|
|
7605
|
-
|
|
7606
|
-
this.
|
|
7607
|
-
|
|
7608
|
-
this.
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
this.
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
this.
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
this.
|
|
7630
|
-
|
|
7631
|
-
|
|
7632
|
-
|
|
7633
|
-
|
|
7634
|
-
|
|
7635
|
-
this.
|
|
7636
|
-
|
|
7637
|
-
|
|
7638
|
-
|
|
7639
|
-
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
7645
|
-
|
|
7646
|
-
|
|
7647
|
-
|
|
7648
|
-
|
|
7649
|
-
|
|
7650
|
-
|
|
7651
|
-
|
|
7652
|
-
|
|
7653
|
-
|
|
7654
|
-
|
|
7655
|
-
|
|
7656
|
-
|
|
7657
|
-
|
|
7658
|
-
|
|
7659
|
-
|
|
7660
|
-
this.
|
|
7661
|
-
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
this.
|
|
7671
|
-
|
|
7672
|
-
this.
|
|
7673
|
-
|
|
7674
|
-
this.
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
this.
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
this.
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
}, /* @ts-ignore */
|
|
7705
|
-
...(ngDevMode ? [{ debugName: "templatesByType" }] : /* istanbul ignore next */ []));
|
|
7706
|
-
this.columnSuggestions = computed(() => {
|
|
7707
|
-
const distinctVals = this.distinctValues();
|
|
7708
|
-
// Si des valeurs distinctes sont fournies par le parent, on les utilise
|
|
7709
|
-
if (Object.keys(distinctVals).length > 0) {
|
|
7710
|
-
return distinctVals;
|
|
7711
|
-
}
|
|
7712
|
-
// Sinon, on utilise l'ancien comportement (valeurs locales)
|
|
7713
|
-
const suggestions = {};
|
|
7714
|
-
this.columns().forEach((column) => {
|
|
7715
|
-
suggestions[column.columnName] = new Set();
|
|
7716
|
-
});
|
|
7717
|
-
this.table()?.rows.forEach((row) => {
|
|
7718
|
-
this.columns().forEach((column) => {
|
|
7719
|
-
const value = row[column.columnName];
|
|
7720
|
-
if (value !== null && value !== undefined) {
|
|
7721
|
-
suggestions[column.columnName].add(value);
|
|
7722
|
-
}
|
|
7723
|
-
});
|
|
7724
|
-
});
|
|
7725
|
-
return Object.entries(suggestions).reduce((acc, [key, value]) => {
|
|
7726
|
-
acc[key] = Array.from(value);
|
|
7727
|
-
return acc;
|
|
7728
|
-
}, {});
|
|
7729
|
-
}, /* @ts-ignore */
|
|
7730
|
-
...(ngDevMode ? [{ debugName: "columnSuggestions" }] : /* istanbul ignore next */ []));
|
|
7731
|
-
// protected _addedRows = computed(() => this.addedRows().map((r) => r.row));
|
|
7732
|
-
this.trackByMode = model('index', /* @ts-ignore */
|
|
7733
|
-
...(ngDevMode ? [{ debugName: "trackByMode" }] : /* istanbul ignore next */ []));
|
|
7734
|
-
this.hasChanges = computed(() => {
|
|
7735
|
-
return (this.addedRows().length > 0 ||
|
|
7736
|
-
this.modifiedRows().length > 0 ||
|
|
7737
|
-
this.deletedRows().length > 0);
|
|
7738
|
-
}, /* @ts-ignore */
|
|
7739
|
-
...(ngDevMode ? [{ debugName: "hasChanges" }] : /* istanbul ignore next */ []));
|
|
7740
|
-
this.groupByMap = computed(() => {
|
|
7741
|
-
const includedMap = {};
|
|
7742
|
-
this.groupBy()?.included.forEach((col) => {
|
|
7743
|
-
includedMap[col] = true;
|
|
7744
|
-
});
|
|
7745
|
-
return includedMap;
|
|
7746
|
-
}, /* @ts-ignore */
|
|
7747
|
-
...(ngDevMode ? [{ debugName: "groupByMap" }] : /* istanbul ignore next */ []));
|
|
7748
|
-
this.columns = computed(() => {
|
|
7749
|
-
const table = this.table();
|
|
7750
|
-
const metadatas = table?.columnMetadatas || [];
|
|
7751
|
-
const groupedColumns = this.groupBy()?.included || [];
|
|
7752
|
-
//Sort grouped columns first then computed columns then the rest
|
|
7753
|
-
if (this.groupBy() !== null)
|
|
7754
|
-
return [
|
|
7755
|
-
...metadatas.filter((col) => groupedColumns.includes(col.columnName)),
|
|
7756
|
-
...metadatas.filter((col) => !groupedColumns.includes(col.columnName) && !col.tableName),
|
|
7757
|
-
...metadatas.filter((col) => !groupedColumns.includes(col.columnName) && col.tableName),
|
|
7758
|
-
];
|
|
7759
|
-
else
|
|
7760
|
-
return metadatas;
|
|
7761
|
-
}, /* @ts-ignore */
|
|
7762
|
-
...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
7763
|
-
this.rows = computed(() => {
|
|
7764
|
-
const table = this.table();
|
|
7765
|
-
if (!table)
|
|
7766
|
-
return [];
|
|
7767
|
-
const computedRows = [];
|
|
7768
|
-
for (const row of table.rows) {
|
|
7769
|
-
const rowId = table.getRowIdentifier(row);
|
|
7770
|
-
const updated = this.modifiedRows().find((mr) => table.getRowIdentifier(mr.current) === rowId);
|
|
7771
|
-
const deleted = this.deletedRows().find((dr) => table.getRowIdentifier(dr.row) === rowId);
|
|
7772
|
-
computedRows.push({
|
|
7773
|
-
id: rowId,
|
|
7774
|
-
data: updated ? updated.current : row,
|
|
7775
|
-
flag: deleted ? 'deleted' : updated ? 'modified' : 'unchanged',
|
|
7776
|
-
valid: this.validateRow(deleted ? deleted.row : updated ? updated.current : row),
|
|
7777
|
-
});
|
|
7778
|
-
}
|
|
7779
|
-
for (const addedEntry of this.addedRows()) {
|
|
7780
|
-
const rowId = table.getRowIdentifier(addedEntry.row);
|
|
7781
|
-
computedRows.push({
|
|
7782
|
-
id: rowId,
|
|
7783
|
-
data: addedEntry.row,
|
|
7784
|
-
flag: 'added',
|
|
7785
|
-
valid: this.validateRow(addedEntry.row),
|
|
7786
|
-
});
|
|
7787
|
-
}
|
|
7788
|
-
return computedRows;
|
|
7789
|
-
}, /* @ts-ignore */
|
|
7790
|
-
...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
7791
|
-
this.totalItems = computed(() => {
|
|
7792
|
-
return 'total' in (this.table() || {})
|
|
7793
|
-
? this.table()?.total || -1
|
|
7794
|
-
: this.table()?.count || -1;
|
|
7795
|
-
}, /* @ts-ignore */
|
|
7796
|
-
...(ngDevMode ? [{ debugName: "totalItems" }] : /* istanbul ignore next */ []));
|
|
7797
|
-
this.currentItems = computed(() => {
|
|
7798
|
-
return 'total' in (this.table() || {})
|
|
7799
|
-
? this.table()?.total || 0
|
|
7800
|
-
: this.table()?.count || 0;
|
|
7801
|
-
}, /* @ts-ignore */
|
|
7802
|
-
...(ngDevMode ? [{ debugName: "currentItems" }] : /* istanbul ignore next */ []));
|
|
7803
|
-
this.onFilterValue = (columnName, value) => {
|
|
7804
|
-
if (this.allowFetchDistinctValues()) {
|
|
7805
|
-
this.onFilterValueChange.emit({
|
|
7806
|
-
column: columnName,
|
|
7807
|
-
value: value,
|
|
7808
|
-
});
|
|
7809
|
-
}
|
|
7810
|
-
};
|
|
7811
|
-
this.onGroupByIncludedChange = (columnName, included) => {
|
|
7812
|
-
this.groupBy.update((currentGroup) => {
|
|
7813
|
-
if (currentGroup === null)
|
|
7814
|
-
return currentGroup;
|
|
7815
|
-
if (included) {
|
|
7816
|
-
currentGroup?.included.push(columnName);
|
|
7817
|
-
}
|
|
7818
|
-
else {
|
|
7819
|
-
currentGroup.included = currentGroup.included.filter((c) => c !== columnName);
|
|
7820
|
-
}
|
|
7821
|
-
return { ...currentGroup };
|
|
7822
|
-
});
|
|
7823
|
-
};
|
|
7824
|
-
this.onCellChange = (index, row, column, value) => {
|
|
7825
|
-
const initial = { ...row.data };
|
|
7826
|
-
row.data[column.columnName] = value;
|
|
7827
|
-
// If the row is created, we don't track it as modified
|
|
7828
|
-
switch (row.flag) {
|
|
7829
|
-
case 'added':
|
|
7830
|
-
this.addedRows.update((rows) => rows.map((r) => {
|
|
7831
|
-
if (this.table()?.getRowIdentifier(r.row) ===
|
|
7832
|
-
this.table()?.getRowIdentifier(row.data)) {
|
|
7833
|
-
r.row[column.columnName] = value;
|
|
7834
|
-
}
|
|
7835
|
-
return r;
|
|
7836
|
-
}));
|
|
7837
|
-
// this.addedRows.update((rows) => {
|
|
7838
|
-
// rows.find(
|
|
7839
|
-
// (r) =>
|
|
7840
|
-
// this.table()?.getRowIdentifier(r.row) ===
|
|
7841
|
-
// this.table()?.getRowIdentifier(row.data)
|
|
7842
|
-
// )!.row[column.columnName] = value;
|
|
7843
|
-
// return [...rows];
|
|
7844
|
-
// });
|
|
7845
|
-
return;
|
|
7846
|
-
case 'modified':
|
|
7847
|
-
this.modifiedRows.update((rows) => rows.map((r) => {
|
|
7848
|
-
if (r.index === index) {
|
|
7849
|
-
r.current = row.data;
|
|
7850
|
-
}
|
|
7851
|
-
return r;
|
|
7852
|
-
}));
|
|
7853
|
-
// this.modifiedRows.update((rows) => {
|
|
7854
|
-
// const changed = this.modifiedRows().find(
|
|
7855
|
-
// (modifiedRow) => modifiedRow.index === index
|
|
7856
|
-
// );
|
|
7857
|
-
// changed!.current = row.data;
|
|
7858
|
-
// return [...rows];
|
|
7859
|
-
// });
|
|
7860
|
-
break;
|
|
7861
|
-
case 'unchanged':
|
|
7862
|
-
this.modifiedRows.set([
|
|
7863
|
-
...this.modifiedRows(),
|
|
7864
|
-
{ index: index, original: initial, current: row.data },
|
|
7865
|
-
]);
|
|
7866
|
-
break;
|
|
7599
|
+
class TableConstraint {
|
|
7600
|
+
constructor(data = {}) {
|
|
7601
|
+
this.columns = [];
|
|
7602
|
+
this.constraintCatalog = data.constraintCatalog || '';
|
|
7603
|
+
this.constraintSchema = data.constraintSchema || '';
|
|
7604
|
+
this.constraintName = data.constraintName || '';
|
|
7605
|
+
this.constraintType = data.constraintType || '';
|
|
7606
|
+
this.tableCatalog = data.tableCatalog || '';
|
|
7607
|
+
this.tableName = data.tableName || '';
|
|
7608
|
+
this.tableSchema = data.tableSchema || '';
|
|
7609
|
+
this.columns = data.columns
|
|
7610
|
+
? data.columns.map((d) => new TableConstraintColumn(d))
|
|
7611
|
+
: [];
|
|
7612
|
+
}
|
|
7613
|
+
fullTableName() {
|
|
7614
|
+
return `${this.tableSchema}.${this.tableName}`;
|
|
7615
|
+
}
|
|
7616
|
+
fullConstraintName() {
|
|
7617
|
+
return `${this.constraintSchema}.${this.constraintName}`;
|
|
7618
|
+
}
|
|
7619
|
+
isPrimaryKey() {
|
|
7620
|
+
return this.constraintType === 'PRIMARY KEY';
|
|
7621
|
+
}
|
|
7622
|
+
isForeignKey() {
|
|
7623
|
+
return this.constraintType === 'FOREIGN KEY';
|
|
7624
|
+
}
|
|
7625
|
+
isUnique() {
|
|
7626
|
+
return this.constraintType === 'UNIQUE';
|
|
7627
|
+
}
|
|
7628
|
+
isCheck() {
|
|
7629
|
+
return this.constraintType === 'CHECK';
|
|
7630
|
+
}
|
|
7631
|
+
}
|
|
7632
|
+
|
|
7633
|
+
class BaseTable {
|
|
7634
|
+
addRow(row) {
|
|
7635
|
+
this.rows.push(row);
|
|
7636
|
+
this.count += 1;
|
|
7637
|
+
return row;
|
|
7638
|
+
}
|
|
7639
|
+
updateRow(row) {
|
|
7640
|
+
const index = this.rows.findIndex((r) => this.compareRows(r, row));
|
|
7641
|
+
if (index !== -1) {
|
|
7642
|
+
this.rows[index] = row;
|
|
7643
|
+
return true;
|
|
7644
|
+
}
|
|
7645
|
+
return false;
|
|
7646
|
+
}
|
|
7647
|
+
removeRow(row) {
|
|
7648
|
+
const index = this.rows.findIndex((r) => this.compareRows(r, row));
|
|
7649
|
+
if (index !== -1) {
|
|
7650
|
+
this.rows.splice(index, 1);
|
|
7651
|
+
this.count -= 1;
|
|
7652
|
+
return true;
|
|
7653
|
+
}
|
|
7654
|
+
return false;
|
|
7655
|
+
}
|
|
7656
|
+
compareRows(row1, row2) {
|
|
7657
|
+
return JSON.stringify(row1) === JSON.stringify(row2);
|
|
7658
|
+
}
|
|
7659
|
+
getColumnByName(columnName) {
|
|
7660
|
+
return this.columnMetadatas.find((cmd) => cmd.columnName === columnName);
|
|
7661
|
+
}
|
|
7662
|
+
getConstraintsByType(type) {
|
|
7663
|
+
return this.tableConstraints.filter((tc) => tc.constraintType === type);
|
|
7664
|
+
}
|
|
7665
|
+
}
|
|
7666
|
+
class AnonymousTable extends BaseTable {
|
|
7667
|
+
constructor(data) {
|
|
7668
|
+
super();
|
|
7669
|
+
this.catalog = data.catalog;
|
|
7670
|
+
this.schema = data.schema;
|
|
7671
|
+
this.name = data.name;
|
|
7672
|
+
this.description = data.description;
|
|
7673
|
+
this.isReadOnly = data.isReadOnly;
|
|
7674
|
+
this.rowNumberIdentity = data.rowNumberIdentity;
|
|
7675
|
+
this.columnMetadatas = data.columnMetadatas
|
|
7676
|
+
? data.columnMetadatas
|
|
7677
|
+
.map((d) => new ColumnMetadata(d))
|
|
7678
|
+
.sort((a, b) => a.ordinalPosition - b.ordinalPosition)
|
|
7679
|
+
: [];
|
|
7680
|
+
this.tableConstraints = data.tableConstraints
|
|
7681
|
+
? data.tableConstraints.map((d) => new TableConstraint(d))
|
|
7682
|
+
: [];
|
|
7683
|
+
this.hasPrimaryKey =
|
|
7684
|
+
data.hasPrimaryKey === undefined ? false : Boolean(data.hasPrimaryKey);
|
|
7685
|
+
this.rows = data.rows || [];
|
|
7686
|
+
this.count = data.count || 0;
|
|
7687
|
+
this.total = data.total || 0;
|
|
7688
|
+
}
|
|
7689
|
+
fullName() {
|
|
7690
|
+
return `${this.schema}.${this.name}`;
|
|
7691
|
+
}
|
|
7692
|
+
primaryKeyColumns() {
|
|
7693
|
+
const pkColumns = this.tableConstraints.filter((tc) => tc.isPrimaryKey())?.[0]?.columns;
|
|
7694
|
+
if (!pkColumns || pkColumns.length === 0) {
|
|
7695
|
+
const rn = this.columnMetadatas.find((cmd) => cmd.columnName === 'ROW_NUMBER');
|
|
7696
|
+
return rn ? [rn] : [];
|
|
7697
|
+
}
|
|
7698
|
+
return this.columnMetadatas.filter((cmd) => pkColumns?.some((pc) => pc.columnName === cmd.columnName));
|
|
7699
|
+
}
|
|
7700
|
+
getRowIdentifier(row) {
|
|
7701
|
+
if (!this.hasPrimaryKey) {
|
|
7702
|
+
if (row[this.rowNumberIdentity] !== undefined) {
|
|
7703
|
+
return `${row[this.rowNumberIdentity]}`;
|
|
7867
7704
|
}
|
|
7868
|
-
}
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
return table?.getRowNumber(row) ? table.getRowNumber(row) : index;
|
|
7880
|
-
};
|
|
7881
|
-
this.hasInvalidRows = () => {
|
|
7882
|
-
const allRows = [
|
|
7883
|
-
...this.addedRows().map((r) => r.row),
|
|
7884
|
-
...this.modifiedRows().map((r) => r.current),
|
|
7885
|
-
];
|
|
7886
|
-
return allRows.some((row) => !this.validateRow(row));
|
|
7887
|
-
};
|
|
7888
|
-
this.validateRow = (row) => {
|
|
7889
|
-
if (this.groupBy() !== null)
|
|
7890
|
-
return true;
|
|
7891
|
-
return this.formatterService.validateRow(row, this.columns());
|
|
7892
|
-
};
|
|
7893
|
-
this.canEdit = (column) => {
|
|
7894
|
-
const formatter = this.formatterService.getFormatter(null, column);
|
|
7895
|
-
if (!formatter)
|
|
7896
|
-
return false && this.allowUpdate();
|
|
7897
|
-
return this.allowUpdate() && formatter.canEdit(null, column);
|
|
7898
|
-
};
|
|
7899
|
-
this.isPrimaryKeyColumn = (column) => {
|
|
7900
|
-
const table = this.table();
|
|
7901
|
-
if (!table)
|
|
7902
|
-
return false;
|
|
7903
|
-
return table
|
|
7904
|
-
.primaryKeyColumns()
|
|
7905
|
-
.some((pk) => pk.columnName === column.columnName);
|
|
7906
|
-
};
|
|
7907
|
-
this.isUniqueKeyColumn = (column) => {
|
|
7908
|
-
const table = this.table();
|
|
7909
|
-
if (!table)
|
|
7910
|
-
return false;
|
|
7911
|
-
const uniqueConstraints = table.tableConstraints.filter((tc) => tc.constraintType === 'UNIQUE');
|
|
7912
|
-
for (const uc of uniqueConstraints) {
|
|
7913
|
-
if (uc.columns.some((col) => col.columnName === column.columnName)) {
|
|
7914
|
-
return true;
|
|
7705
|
+
}
|
|
7706
|
+
const pkColumns = this.primaryKeyColumns();
|
|
7707
|
+
if (this.hasPrimaryKey && pkColumns.length > 0) {
|
|
7708
|
+
let key = '';
|
|
7709
|
+
let index = 0;
|
|
7710
|
+
for (const pc of pkColumns) {
|
|
7711
|
+
if (row[pc.columnName] === undefined || row[pc.columnName] === null) {
|
|
7712
|
+
if (row[this.rowNumberIdentity] !== undefined)
|
|
7713
|
+
return `${row[this.rowNumberIdentity]}`;
|
|
7714
|
+
else
|
|
7715
|
+
break;
|
|
7915
7716
|
}
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
};
|
|
7919
|
-
this.isEditSafe = (column) => {
|
|
7920
|
-
if (this.groupBy() !== null)
|
|
7921
|
-
return false;
|
|
7922
|
-
if (this.trackByMode() === 'index')
|
|
7923
|
-
return true;
|
|
7924
|
-
if (this.crossRequestTrackingPersistence() === false)
|
|
7925
|
-
return true;
|
|
7926
|
-
return (this.trackByMode() === 'primaryKey' &&
|
|
7927
|
-
this.table()
|
|
7928
|
-
?.primaryKeyColumns()
|
|
7929
|
-
.some((pk) => pk.columnName === column.columnName) == false);
|
|
7930
|
-
};
|
|
7931
|
-
this.isForeignKeyColumn = (column) => {
|
|
7932
|
-
const table = this.table();
|
|
7933
|
-
if (!table)
|
|
7934
|
-
return false;
|
|
7935
|
-
const fkConstraints = table.tableConstraints.filter((tc) => tc.constraintType === 'FOREIGN KEY');
|
|
7936
|
-
for (const fk of fkConstraints) {
|
|
7937
|
-
if (fk.columns.some((col) => col.columnName === column.columnName)) {
|
|
7938
|
-
return true;
|
|
7717
|
+
if (index == pkColumns.length - 1) {
|
|
7718
|
+
key += `${pc.columnName}:${row[pc.columnName]}`;
|
|
7939
7719
|
}
|
|
7720
|
+
else
|
|
7721
|
+
key += `${pc.columnName}:${row[pc.columnName]}|`;
|
|
7722
|
+
index++;
|
|
7940
7723
|
}
|
|
7941
|
-
return
|
|
7942
|
-
}
|
|
7943
|
-
|
|
7944
|
-
const actions = [
|
|
7945
|
-
{
|
|
7946
|
-
label: 'Trier par ordre croissant',
|
|
7947
|
-
icon: 'arrow_upward',
|
|
7948
|
-
action: () => this.setSort(column, true),
|
|
7949
|
-
},
|
|
7950
|
-
{
|
|
7951
|
-
label: 'Trier par ordre décroissant',
|
|
7952
|
-
icon: 'arrow_downward',
|
|
7953
|
-
action: () => this.setSort(column, false),
|
|
7954
|
-
},
|
|
7955
|
-
{
|
|
7956
|
-
label: 'Effacer le tri',
|
|
7957
|
-
icon: 'clear',
|
|
7958
|
-
action: () => this.sort.set(null),
|
|
7959
|
-
},
|
|
7960
|
-
];
|
|
7961
|
-
if (filterElement && this.allowFiltering()) {
|
|
7962
|
-
actions.push({
|
|
7963
|
-
label: 'Filtrer sur cette colonne...',
|
|
7964
|
-
icon: 'filter_list',
|
|
7965
|
-
action: () => filterElement.toggle(),
|
|
7966
|
-
});
|
|
7967
|
-
}
|
|
7968
|
-
if (groupElement && this.allowGrouping()) {
|
|
7969
|
-
actions.push({
|
|
7970
|
-
label: 'Grouper par cette colonne',
|
|
7971
|
-
icon: 'group',
|
|
7972
|
-
action: () => groupElement.isOpen.set(true),
|
|
7973
|
-
});
|
|
7974
|
-
}
|
|
7975
|
-
return actions;
|
|
7976
|
-
};
|
|
7977
|
-
this.datarowContextMenuActions = (row, rowIndex) => {
|
|
7978
|
-
const items = [];
|
|
7979
|
-
for (const action of this.actions()) {
|
|
7980
|
-
items.push({
|
|
7981
|
-
label: action.display,
|
|
7982
|
-
action: action.callback.bind(null, row.data),
|
|
7983
|
-
color: action.color,
|
|
7984
|
-
icon: action.icon,
|
|
7985
|
-
});
|
|
7986
|
-
}
|
|
7987
|
-
switch (row.flag) {
|
|
7988
|
-
case 'deleted':
|
|
7989
|
-
items.push({
|
|
7990
|
-
label: 'Annuler la suppression',
|
|
7991
|
-
action: () => this.deletedRows.set(this.deletedRows().filter((r) => r.index !== rowIndex)),
|
|
7992
|
-
icon: 'undo',
|
|
7993
|
-
color: 'primary',
|
|
7994
|
-
});
|
|
7995
|
-
break;
|
|
7996
|
-
case 'added':
|
|
7997
|
-
items.push({
|
|
7998
|
-
label: 'Supprimer la ligne ajoutée',
|
|
7999
|
-
action: () => {
|
|
8000
|
-
this.addedRows.update((rows) => rows.filter((r) => this.table().getRowIdentifier(r.row) !== row.id));
|
|
8001
|
-
this.table()?.removeRow(row);
|
|
8002
|
-
},
|
|
8003
|
-
icon: 'delete',
|
|
8004
|
-
color: 'error',
|
|
8005
|
-
});
|
|
8006
|
-
break;
|
|
8007
|
-
default:
|
|
8008
|
-
if (this.allowInsert() && this.allowDuplicate()) {
|
|
8009
|
-
items.push({
|
|
8010
|
-
label: 'Dupliquer la ligne',
|
|
8011
|
-
action: () => {
|
|
8012
|
-
const newRow = {
|
|
8013
|
-
[`${this.table()?.getRowIdentifier(row.data)}`]: this.addedRows().length + 1,
|
|
8014
|
-
...row.data,
|
|
8015
|
-
};
|
|
8016
|
-
this.addedRows.set([
|
|
8017
|
-
...this.addedRows(),
|
|
8018
|
-
{ index: this.addedRows().length, row: newRow },
|
|
8019
|
-
]);
|
|
8020
|
-
},
|
|
8021
|
-
icon: 'file_copy',
|
|
8022
|
-
color: 'primary',
|
|
8023
|
-
});
|
|
8024
|
-
}
|
|
8025
|
-
if (this.allowDelete()) {
|
|
8026
|
-
items.push({
|
|
8027
|
-
label: 'Supprimer la ligne',
|
|
8028
|
-
action: () => this.deleteRow(rowIndex, row.data),
|
|
8029
|
-
icon: 'delete',
|
|
8030
|
-
color: 'error',
|
|
8031
|
-
});
|
|
8032
|
-
}
|
|
8033
|
-
break;
|
|
8034
|
-
}
|
|
8035
|
-
return items;
|
|
8036
|
-
};
|
|
8037
|
-
this.onAdd = () => {
|
|
8038
|
-
this.onAddRow.emit();
|
|
8039
|
-
setTimeout(() => {
|
|
8040
|
-
this.viewport()?.scrollTo({ bottom: 0 });
|
|
8041
|
-
}, 250);
|
|
8042
|
-
};
|
|
8043
|
-
this.log = (event) => {
|
|
8044
|
-
console.log(`[DataGrid-${this.id()}]`, event);
|
|
8045
|
-
};
|
|
8046
|
-
effect(() => {
|
|
8047
|
-
if (this.table() && !this.crossRequestTrackingPersistence()) {
|
|
8048
|
-
this.resetChanges();
|
|
8049
|
-
}
|
|
8050
|
-
});
|
|
8051
|
-
effect(() => {
|
|
8052
|
-
const mode = this.table()?.hasPrimaryKey ? 'primaryKey' : 'index';
|
|
8053
|
-
this.trackByMode.set(mode);
|
|
8054
|
-
});
|
|
7724
|
+
return key;
|
|
7725
|
+
}
|
|
7726
|
+
return JSON.stringify(row);
|
|
8055
7727
|
}
|
|
8056
|
-
|
|
8057
|
-
this.
|
|
7728
|
+
getRowNumber(row) {
|
|
7729
|
+
return row[this.rowNumberIdentity];
|
|
7730
|
+
}
|
|
7731
|
+
compareRows(row1, row2) {
|
|
7732
|
+
if (!this.hasPrimaryKey) {
|
|
7733
|
+
if (row1[this.rowNumberIdentity] !== undefined &&
|
|
7734
|
+
row2[this.rowNumberIdentity] !== undefined) {
|
|
7735
|
+
return row1[this.rowNumberIdentity] === row2[this.rowNumberIdentity];
|
|
7736
|
+
}
|
|
7737
|
+
}
|
|
7738
|
+
const pkColumns = this.primaryKeyColumns();
|
|
7739
|
+
if (this.hasPrimaryKey && pkColumns.length > 0) {
|
|
7740
|
+
return pkColumns.every((pc) => row1[pc.columnName] === row2[pc.columnName]);
|
|
7741
|
+
}
|
|
7742
|
+
return super.compareRows(row1, row2);
|
|
8058
7743
|
}
|
|
8059
|
-
|
|
8060
|
-
|
|
8061
|
-
return
|
|
7744
|
+
addRow(row) {
|
|
7745
|
+
row[this.rowNumberIdentity] = this.generateTempRowIdentifier();
|
|
7746
|
+
return super.addRow(row);
|
|
8062
7747
|
}
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
let isAsc = true;
|
|
8066
|
-
if (currentSort?.column === columnName)
|
|
8067
|
-
isAsc = !currentSort.isAsc;
|
|
8068
|
-
this.sort.set({ column: columnName, isAsc: isAsc });
|
|
7748
|
+
generateTempRowIdentifier() {
|
|
7749
|
+
return crypto.randomUUID();
|
|
8069
7750
|
}
|
|
8070
|
-
|
|
8071
|
-
|
|
7751
|
+
}
|
|
7752
|
+
|
|
7753
|
+
class AutoDataTable extends BaseTable {
|
|
7754
|
+
get columnMetadatas() {
|
|
7755
|
+
return this._columnMetadatas.sort((a, b) => a.ordinalPosition - b.ordinalPosition);
|
|
8072
7756
|
}
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
if (filter.value) {
|
|
8076
|
-
currentFilters[columnName] = {
|
|
8077
|
-
column: filter.column,
|
|
8078
|
-
mode: filter.mode,
|
|
8079
|
-
value: filter.value,
|
|
8080
|
-
};
|
|
8081
|
-
}
|
|
8082
|
-
else {
|
|
8083
|
-
delete currentFilters[columnName];
|
|
8084
|
-
}
|
|
8085
|
-
this.filter.set(currentFilters);
|
|
7757
|
+
set columnMetadatas(value) {
|
|
7758
|
+
this._columnMetadatas = value;
|
|
8086
7759
|
}
|
|
8087
|
-
|
|
8088
|
-
|
|
8089
|
-
this.groupBy.set(null);
|
|
8090
|
-
else {
|
|
8091
|
-
// group.included =
|
|
8092
|
-
// this.table()?.columnMetadatas.map((c) => c.columnName) || [];
|
|
8093
|
-
group.included = [group.column];
|
|
8094
|
-
this.groupBy.set(group);
|
|
8095
|
-
}
|
|
7760
|
+
get rows() {
|
|
7761
|
+
return this._rows;
|
|
8096
7762
|
}
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
this.
|
|
7763
|
+
set rows(value) {
|
|
7764
|
+
this.count = value.length;
|
|
7765
|
+
this._rows = value.map((row, index) => {
|
|
7766
|
+
if (!this.hasPrimaryKey && !row.hasOwnProperty(this.rowNumberIdentity)) {
|
|
7767
|
+
return { [this.rowNumberIdentity]: index + 1, ...row };
|
|
7768
|
+
}
|
|
7769
|
+
return row;
|
|
7770
|
+
});
|
|
7771
|
+
this.deduceColumnTypes();
|
|
8100
7772
|
}
|
|
8101
|
-
|
|
8102
|
-
|
|
7773
|
+
constructor(name, primaryKey = null, metadatas = [], rowIdentifier = 'ROW_NUMBER') {
|
|
7774
|
+
super();
|
|
7775
|
+
this.name = '';
|
|
7776
|
+
this.schema = '';
|
|
7777
|
+
this.total = 0;
|
|
7778
|
+
this._columnMetadatas = [];
|
|
7779
|
+
this.tableConstraints = [];
|
|
7780
|
+
this._primaryKey = null;
|
|
7781
|
+
this.hasPrimaryKey = this._primaryKey !== null;
|
|
7782
|
+
this._rows = [];
|
|
7783
|
+
this.count = 0;
|
|
7784
|
+
this.getRowIdentifier = (row) => {
|
|
7785
|
+
if (this._primaryKey && row.hasOwnProperty(this._primaryKey)) {
|
|
7786
|
+
if (Array.isArray(this._primaryKey)) {
|
|
7787
|
+
return this._primaryKey.map((key) => row[key]).join('_');
|
|
7788
|
+
}
|
|
7789
|
+
return row[this._primaryKey].toString();
|
|
7790
|
+
}
|
|
7791
|
+
return row[this.rowNumberIdentity].toString();
|
|
7792
|
+
};
|
|
7793
|
+
this.getRowNumber = (row) => {
|
|
7794
|
+
return row[this.rowNumberIdentity];
|
|
7795
|
+
};
|
|
7796
|
+
this.primaryKeyColumns = () => {
|
|
7797
|
+
if (!this._primaryKey) {
|
|
7798
|
+
return [];
|
|
7799
|
+
}
|
|
7800
|
+
return this.columnMetadatas.filter((col) => col.columnName === this._primaryKey);
|
|
7801
|
+
};
|
|
7802
|
+
this.deduceColumnTypes = () => {
|
|
7803
|
+
if (this.rows.length === 0) {
|
|
7804
|
+
return;
|
|
7805
|
+
}
|
|
7806
|
+
if (this.columnMetadatas.length !== 0)
|
|
7807
|
+
return;
|
|
7808
|
+
for (const key of Object.keys(this.rows[0])) {
|
|
7809
|
+
const inferredType = typeof this.rows[0][key];
|
|
7810
|
+
const existingIndex = this.columnMetadatas.findIndex((md) => md.columnName === key);
|
|
7811
|
+
const existingMetadata = this.columnMetadatas[existingIndex];
|
|
7812
|
+
if (!existingMetadata) {
|
|
7813
|
+
const md = {
|
|
7814
|
+
ordinalPosition: this.columnMetadatas.length + 1,
|
|
7815
|
+
length: 0,
|
|
7816
|
+
tableName: this.name,
|
|
7817
|
+
tableSchema: this.schema,
|
|
7818
|
+
isIdentity: false,
|
|
7819
|
+
isGenerated: false,
|
|
7820
|
+
isUpdatable: false,
|
|
7821
|
+
tooltip: `${inferredType} ${length ? `(${inferredType})` : ''}`,
|
|
7822
|
+
columnName: key,
|
|
7823
|
+
dataType: inferredType,
|
|
7824
|
+
isNullable: false,
|
|
7825
|
+
};
|
|
7826
|
+
this.columnMetadatas.push(md);
|
|
7827
|
+
}
|
|
7828
|
+
}
|
|
7829
|
+
};
|
|
7830
|
+
/**
|
|
7831
|
+
* Retourne une copie de l'AutoDataTable
|
|
7832
|
+
*/
|
|
7833
|
+
this.clone = () => {
|
|
7834
|
+
const copy = new AutoDataTable(this.name, this._primaryKey, this.columnMetadatas, this.rowNumberIdentity);
|
|
7835
|
+
for (const key of Object.keys(this)) {
|
|
7836
|
+
if (Array.isArray(this[key])) {
|
|
7837
|
+
copy[key] = [...this[key]];
|
|
7838
|
+
}
|
|
7839
|
+
else {
|
|
7840
|
+
copy[key] = this[key];
|
|
7841
|
+
}
|
|
7842
|
+
}
|
|
7843
|
+
return copy;
|
|
7844
|
+
};
|
|
7845
|
+
this.name = name;
|
|
7846
|
+
this._primaryKey = primaryKey;
|
|
7847
|
+
this.hasPrimaryKey = this._primaryKey !== null;
|
|
7848
|
+
this.rowNumberIdentity = rowIdentifier;
|
|
7849
|
+
this.columnMetadatas = metadatas.map((md, index) => ({
|
|
7850
|
+
displayName: md.displayName || md.columnName,
|
|
7851
|
+
ordinalPosition: index + 1,
|
|
7852
|
+
length: 0,
|
|
7853
|
+
tableName: this.name,
|
|
7854
|
+
tableSchema: this.schema,
|
|
7855
|
+
isIdentity: false,
|
|
7856
|
+
isGenerated: false,
|
|
7857
|
+
isUpdatable: false,
|
|
7858
|
+
tooltip: `${md.dataType?.toUpperCase()} ${md.length ? `(${md.length})` : ''}`,
|
|
7859
|
+
...md,
|
|
7860
|
+
}));
|
|
8103
7861
|
}
|
|
8104
|
-
|
|
8105
|
-
|
|
8106
|
-
|
|
8107
|
-
|
|
7862
|
+
}
|
|
7863
|
+
|
|
7864
|
+
class AutoDataSource {
|
|
7865
|
+
constructor(config) {
|
|
7866
|
+
this._subscriptions = [];
|
|
7867
|
+
// Signaux internes
|
|
7868
|
+
this._datagrid = signal(null, /* @ts-ignore */
|
|
7869
|
+
...(ngDevMode ? [{ debugName: "_datagrid" }] : /* istanbul ignore next */ []));
|
|
7870
|
+
this._datagridElement = signal(null, /* @ts-ignore */
|
|
7871
|
+
...(ngDevMode ? [{ debugName: "_datagridElement" }] : /* istanbul ignore next */ []));
|
|
7872
|
+
this._data = signal(undefined, /* @ts-ignore */
|
|
7873
|
+
...(ngDevMode ? [{ debugName: "_data" }] : /* istanbul ignore next */ []));
|
|
7874
|
+
// protected _currentPage = signal(1);
|
|
7875
|
+
// protected _pageSize = signal(10);
|
|
7876
|
+
this._sort = signal(null, /* @ts-ignore */
|
|
7877
|
+
...(ngDevMode ? [{ debugName: "_sort" }] : /* istanbul ignore next */ []));
|
|
7878
|
+
this._filter = signal({}, /* @ts-ignore */
|
|
7879
|
+
...(ngDevMode ? [{ debugName: "_filter" }] : /* istanbul ignore next */ []));
|
|
7880
|
+
this._groupBy = signal(null, /* @ts-ignore */
|
|
7881
|
+
...(ngDevMode ? [{ debugName: "_groupBy" }] : /* istanbul ignore next */ []));
|
|
7882
|
+
this._loading = signal(false, /* @ts-ignore */
|
|
7883
|
+
...(ngDevMode ? [{ debugName: "_loading" }] : /* istanbul ignore next */ []));
|
|
7884
|
+
this._error = signal(null, /* @ts-ignore */
|
|
7885
|
+
...(ngDevMode ? [{ debugName: "_error" }] : /* istanbul ignore next */ []));
|
|
7886
|
+
// Données exposées (read-only)
|
|
7887
|
+
this.data = this._data.asReadonly();
|
|
7888
|
+
// public readonly currentPage: Signal<number> = this._currentPage.asReadonly();
|
|
7889
|
+
// public readonly pageSize: Signal<number> = this._pageSize.asReadonly();
|
|
7890
|
+
this.sort = this._sort.asReadonly();
|
|
7891
|
+
this.filter = this._filter.asReadonly();
|
|
7892
|
+
this.groupBy = this._groupBy.asReadonly();
|
|
7893
|
+
this.loading = this._loading.asReadonly();
|
|
7894
|
+
this.error = this._error.asReadonly();
|
|
7895
|
+
// Données traitées
|
|
7896
|
+
this.processedData = computed(() => {
|
|
7897
|
+
let result = this._data();
|
|
7898
|
+
if (!result)
|
|
7899
|
+
return undefined;
|
|
7900
|
+
result.total = result.rows.length ?? -1;
|
|
7901
|
+
// Filtrage côté client
|
|
7902
|
+
if (this.config.enableClientSideFiltering) {
|
|
7903
|
+
result = this.applyFilters(result, this.filter());
|
|
7904
|
+
}
|
|
7905
|
+
// Tri côté client
|
|
7906
|
+
if (this.config.enableClientSideSorting) {
|
|
7907
|
+
result = this.applySort(result, this._sort());
|
|
7908
|
+
}
|
|
7909
|
+
// Pagination côté client
|
|
7910
|
+
if (this.config.enableClientSidePagination) {
|
|
7911
|
+
// Do nothing, it is handled by the data grid directly
|
|
7912
|
+
}
|
|
7913
|
+
result.count = result.rows.length;
|
|
7914
|
+
return result;
|
|
7915
|
+
}, /* @ts-ignore */
|
|
7916
|
+
...(ngDevMode ? [{ debugName: "processedData" }] : /* istanbul ignore next */ []));
|
|
7917
|
+
this.config = {
|
|
7918
|
+
initialData: config?.initialData,
|
|
7919
|
+
pageSize: config?.pageSize ?? 10,
|
|
7920
|
+
enableClientSidePagination: config?.enableClientSidePagination ?? true,
|
|
7921
|
+
enableClientSideFiltering: config?.enableClientSideFiltering ?? true,
|
|
7922
|
+
enableClientSideSorting: config?.enableClientSideSorting ?? true,
|
|
7923
|
+
};
|
|
7924
|
+
if (this.config.initialData) {
|
|
7925
|
+
this._data.set(this.config.initialData);
|
|
7926
|
+
}
|
|
7927
|
+
// this._pageSize.set(this.config.pageSize);
|
|
7928
|
+
effect(() => {
|
|
7929
|
+
if (this.processedData() && this._datagrid()) {
|
|
7930
|
+
this._datagrid().table.set(this.processedData());
|
|
7931
|
+
this._datagrid().ngOnDestroy = () => {
|
|
7932
|
+
this._datagrid()?.ngOnDestroy();
|
|
7933
|
+
this._datagrid.set(null);
|
|
7934
|
+
for (const sub of this._subscriptions) {
|
|
7935
|
+
sub.unsubscribe();
|
|
7936
|
+
}
|
|
7937
|
+
};
|
|
7938
|
+
}
|
|
7939
|
+
});
|
|
8108
7940
|
}
|
|
8109
|
-
|
|
8110
|
-
|
|
7941
|
+
// Méthode pour enregistrer la datagrid et écouter les événements de base
|
|
7942
|
+
registerDataGrid(element) {
|
|
7943
|
+
if (!element)
|
|
7944
|
+
return;
|
|
7945
|
+
this._datagridElement.set(element instanceof ElementRef ? element : null);
|
|
7946
|
+
const datagrid = (element instanceof ElementRef ? element.nativeElement : element);
|
|
7947
|
+
this._datagrid.set(datagrid);
|
|
7948
|
+
this._subscriptions.push(
|
|
7949
|
+
// datagrid.pageChange.subscribe((page: number) => {
|
|
7950
|
+
// console.log(
|
|
7951
|
+
// 'Page change event received:',
|
|
7952
|
+
// page,
|
|
7953
|
+
// this._datagridElement(),
|
|
7954
|
+
// element,
|
|
7955
|
+
// );
|
|
7956
|
+
// // this._subscriptions.push(this.handlePageChange(page).subscribe());
|
|
7957
|
+
// }),
|
|
7958
|
+
// datagrid.pageSizeChange.subscribe((pageSize: number) => {
|
|
7959
|
+
// // this._subscriptions
|
|
7960
|
+
// // .push(
|
|
7961
|
+
// // this.handlePageSizeChange(pageSize).subscribe(),
|
|
7962
|
+
// // );
|
|
7963
|
+
// }),
|
|
7964
|
+
datagrid.sort.subscribe((sort) => {
|
|
7965
|
+
this._subscriptions.push(this.handleSortChange(sort).subscribe());
|
|
7966
|
+
}), datagrid.filter.subscribe((filter) => {
|
|
7967
|
+
this._subscriptions.push(this.handleFilterChange(filter).subscribe());
|
|
7968
|
+
}), datagrid.groupBy.subscribe((group) => {
|
|
7969
|
+
this._subscriptions.push(this.handleGroupChange(group).subscribe());
|
|
7970
|
+
}));
|
|
8111
7971
|
}
|
|
8112
|
-
|
|
8113
|
-
|
|
7972
|
+
// Méthodes publiques pour gérer les événements de la datagrid
|
|
7973
|
+
// public handlePageChange(page: number): Observable<void> {
|
|
7974
|
+
// this._currentPage.set(page);
|
|
7975
|
+
// return this.onPageChange(page);
|
|
7976
|
+
// }
|
|
7977
|
+
// public handlePageSizeChange(pageSize: number): Observable<void> {
|
|
7978
|
+
// this._pageSize.set(pageSize);
|
|
7979
|
+
// this._currentPage.set(1); // Reset à la première page
|
|
7980
|
+
// return this.onPageSizeChange(pageSize);
|
|
7981
|
+
// }
|
|
7982
|
+
handleSortChange(sort) {
|
|
7983
|
+
this._sort.set(sort);
|
|
7984
|
+
return this.onSortChange(sort);
|
|
8114
7985
|
}
|
|
8115
|
-
|
|
8116
|
-
|
|
7986
|
+
handleFilterChange(filter) {
|
|
7987
|
+
this._filter.set(filter);
|
|
7988
|
+
this._datagrid()?.currentPage.set(1); // Reset à la première page
|
|
7989
|
+
return this.onFilterChange(filter);
|
|
8117
7990
|
}
|
|
8118
|
-
|
|
8119
|
-
|
|
7991
|
+
handleGroupChange(group) {
|
|
7992
|
+
this._groupBy.set(group);
|
|
7993
|
+
this._datagrid()?.currentPage.set(1); // Reset à la première page
|
|
7994
|
+
return this.onGroupChange(group);
|
|
8120
7995
|
}
|
|
8121
|
-
|
|
8122
|
-
return this.
|
|
7996
|
+
refresh() {
|
|
7997
|
+
return this.loadData();
|
|
8123
7998
|
}
|
|
8124
|
-
|
|
8125
|
-
|
|
8126
|
-
if (this.isRowChanged(row, index)) {
|
|
8127
|
-
const original = this.modifiedRows().find((modifiedRow) => modifiedRow.index === index)
|
|
8128
|
-
?.original || row;
|
|
8129
|
-
this.deletedRows.set([...this.deletedRows(), { index, row: original }]);
|
|
8130
|
-
this.modifiedRows.set(this.modifiedRows().filter((modifiedRow) => modifiedRow.index !== index));
|
|
7999
|
+
setRows(rows) {
|
|
8000
|
+
if (!this._data()) {
|
|
8131
8001
|
return;
|
|
8132
8002
|
}
|
|
8133
|
-
|
|
8134
|
-
|
|
8135
|
-
|
|
8136
|
-
|
|
8137
|
-
if (!this.isRowDeleted(row, index)) {
|
|
8138
|
-
this.deletedRows.set([...this.deletedRows(), { index, row }]);
|
|
8139
|
-
}
|
|
8140
|
-
this.onDeleteRow.emit({ index, row });
|
|
8003
|
+
const updated = this._data().clone();
|
|
8004
|
+
updated.rows = rows;
|
|
8005
|
+
updated.total = rows.length;
|
|
8006
|
+
this._data.set(updated);
|
|
8141
8007
|
}
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
return;
|
|
8145
|
-
if (column instanceof ColumnMetadata) {
|
|
8146
|
-
this.table()
|
|
8147
|
-
?.getConstraintsByType('FOREIGN KEY')
|
|
8148
|
-
.forEach((constraint) => {
|
|
8149
|
-
const cstCol = constraint.columns.find((c) => c.columnName === column.columnName);
|
|
8150
|
-
if (cstCol && cstCol instanceof TableConstraintColumn) {
|
|
8151
|
-
const reference = cstCol
|
|
8152
|
-
.reference;
|
|
8153
|
-
if (reference) {
|
|
8154
|
-
return this.onForeignTableNavigate.emit({
|
|
8155
|
-
targetTable: cstCol.reference.otherKey.tableName,
|
|
8156
|
-
targetSchema: cstCol.reference.otherKey.tableSchema,
|
|
8157
|
-
});
|
|
8158
|
-
}
|
|
8159
|
-
}
|
|
8160
|
-
});
|
|
8161
|
-
}
|
|
8162
|
-
else {
|
|
8163
|
-
this.onNavigate.emit({ targetColumnMetadata: column });
|
|
8164
|
-
}
|
|
8008
|
+
setData(data) {
|
|
8009
|
+
this._data.set(data);
|
|
8165
8010
|
}
|
|
8166
|
-
|
|
8167
|
-
|
|
8168
|
-
|
|
8169
|
-
|
|
8011
|
+
// Méthodes virtuelles à surcharger pour créer une data source serveur-side
|
|
8012
|
+
onPageChange(page) {
|
|
8013
|
+
// Comportement par défaut : rien (pagination côté client)
|
|
8014
|
+
return of(void 0);
|
|
8170
8015
|
}
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
const deleted = this.deletedRows();
|
|
8175
|
-
return {
|
|
8176
|
-
modified,
|
|
8177
|
-
added,
|
|
8178
|
-
deleted,
|
|
8179
|
-
hasChanges: modified.length > 0 || added.length > 0 || deleted.length > 0,
|
|
8180
|
-
};
|
|
8016
|
+
onPageSizeChange(pageSize) {
|
|
8017
|
+
// Comportement par défaut : rien (pagination côté client)
|
|
8018
|
+
return of(void 0);
|
|
8181
8019
|
}
|
|
8182
|
-
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
return colMatch.template;
|
|
8186
|
-
const typeMatch = this.templatesByType().get(dataType.toLowerCase());
|
|
8187
|
-
if (typeMatch)
|
|
8188
|
-
return typeMatch.template;
|
|
8189
|
-
return null;
|
|
8020
|
+
onSortChange(sort) {
|
|
8021
|
+
// Comportement par défaut : rien (tri côté client)
|
|
8022
|
+
return of(void 0);
|
|
8190
8023
|
}
|
|
8191
|
-
|
|
8192
|
-
|
|
8024
|
+
onFilterChange(filter) {
|
|
8025
|
+
// Comportement par défaut : rien (filtrage côté client)
|
|
8026
|
+
return of(void 0);
|
|
8193
8027
|
}
|
|
8194
|
-
|
|
8195
|
-
|
|
8028
|
+
onGroupChange(group) {
|
|
8029
|
+
// Comportement par défaut : rien
|
|
8030
|
+
return of(void 0);
|
|
8196
8031
|
}
|
|
8197
|
-
|
|
8198
|
-
|
|
8199
|
-
|
|
8200
|
-
if (headerScrollElement) {
|
|
8201
|
-
headerScrollElement.scrollLeft = viewport.scrollLeft;
|
|
8202
|
-
}
|
|
8032
|
+
loadData() {
|
|
8033
|
+
// À surcharger pour charger les données
|
|
8034
|
+
return of(void 0);
|
|
8203
8035
|
}
|
|
8204
|
-
|
|
8205
|
-
|
|
8206
|
-
|
|
8207
|
-
|
|
8208
|
-
|
|
8209
|
-
|
|
8210
|
-
|
|
8211
|
-
|
|
8212
|
-
|
|
8213
|
-
|
|
8214
|
-
|
|
8215
|
-
], queries: [{ propertyName: "cellTemplates", predicate: ChrCellDefDirective, isSignal: true }], viewQueries: [{ propertyName: "viewport", first: true, predicate: ["viewport"], descendants: true, isSignal: true }, { propertyName: "headerScroll", first: true, predicate: ["headerScroll"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (table()) {\r\n<div class=\"data-grid-container\">\r\n <div class=\"data-grid-header\">\r\n <h3>{{ title() ? title() : `${table()?.schema ? `${table()?.schema}.` : ''}${table()?.name}` }}</h3>\r\n @if(table()?.description){\r\n <span class=\"table-description\">{{ table()?.description }}</span>\r\n }\r\n <div class=\"data-grid-info\">\r\n <!-- {{allowSync()}} {{hasChanges()}} {{!hasInvalidRows()}} -->\r\n @if(allowManageDistincValueFetching()){\r\n <div>\r\n <span class=\"mat-icon icon-button tracking-persistence-button\"\r\n [attr.data-enabled]=\"allowFetchDistinctValues()\" (click)=\"toggleAllowFetchDistinctValues()\"\r\n title=\"R\u00E9cup\u00E9ration des valeurs distinctes d'une colonne lors du filtrage\">filter_list</span>\r\n </div>\r\n }\r\n @if (allowSync() && allowManageTrackingPersistence()) {\r\n <div>\r\n <span class=\"mat-icon icon-button tracking-persistence-button\"\r\n [attr.data-enabled]=\"crossRequestTrackingPersistence()\"\r\n (click)=\"toggleCrossRequestTrackingPersistence()\"\r\n title=\"Persistance du suivi des modifications entre les requ\u00EAtes\">track_changes</span>\r\n </div>\r\n }\r\n @if(allowSync() && hasChanges() && !hasInvalidRows()){\r\n <span class=\"mat-icon icon-button sync-button\" (click)=\"onSync.emit()\"\r\n title=\"Synchroniser les changements\">file_upload</span>\r\n }\r\n @if(allowRefresh()){\r\n <span class=\"mat-icon icon-button\" (click)=\"refresh()\" title=\"Recharger les donn\u00E9es\">refresh</span>\r\n }\r\n @if(allowInsert()){\r\n <span class=\"mat-icon icon-button\" (click)=\"onAdd()\" title=\"Ajouter une ligne\">add</span>\r\n }\r\n @if(allowExport()){\r\n <span class=\"mat-icon icon-button\" (click)=\"onExport.emit()\"\r\n title=\"T\u00E9l\u00E9charger les donn\u00E9es\">file_download</span>\r\n }\r\n @if(totalItems() !== -1){\r\n <span>Total: {{ totalItems() }} enregistrements</span>\r\n }\r\n </div>\r\n </div>\r\n <div class=\"grid-container data-grid-wrapper\"\r\n [style.grid-template-columns]=\"'repeat(' + columns().length + ', minmax(15rem, auto))'\"\r\n [style.max-height]=\"maxHeight()\" [style.overflow-y]=\"enableVirtualization() ? 'clip': 'auto'\">\r\n <div class=\"grid-header\" [style.column-span]=\"'all'\">\r\n @for (column of columns(); track column.columnName) {\r\n @let isForeignKey = isForeignKeyColumn(column);\r\n @let isPrimaryKey = isPrimaryKeyColumn(column);\r\n @let isComputedColumn = column.isGenerated;\r\n @let isUniqueColumn = isUniqueKeyColumn(column);\r\n <ng-container [ngTemplateOutlet]=\"headerTemplate\"\r\n [ngTemplateOutletContext]=\"{column: column, isForeignKey: isForeignKey, isPrimaryKey: isPrimaryKey, isComputedColumn: isComputedColumn, isUniqueColumn: isUniqueColumn}\"></ng-container>\r\n }\r\n </div>\r\n <div class=\"grid-body\">\r\n @if(enableVirtualization()){\r\n <cdk-virtual-scroll-viewport #viewport [itemSize]=\"41\" [style.height]=\"maxHeight()\" class=\"viewport\">\r\n <ng-container *cdkVirtualFor=\"let row of rows() | paginate: {itemsPerPage: pageSize(), currentPage: currentPage(), id:\r\n this.id(),\r\n totalItems: totalItems()}; let $index = index\" [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: row, index: getRowTrackBy(row.data, $index)}\">\r\n </ng-container>\r\n </cdk-virtual-scroll-viewport>\r\n } @else {\r\n @for (row of rows() | paginate: {itemsPerPage: pageSize(), currentPage: currentPage(), id:\r\n this.id(),\r\n totalItems: currentItems()};\r\n track getRowTrackBy(row.data, $index)) {\r\n <ng-container [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: row, index: getRowTrackBy(row.data, $index)}\">\r\n </ng-container>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n <ng-template #headerTemplate let-column=\"column\" let-isForeignKey=\"isForeignKey\" let-isPrimaryKey=\"isPrimaryKey\"\r\n let-isComputedColumn=\"isComputedColumn\" let-isUniqueColumn=\"isUniqueColumn\">\r\n <div class=\"grid-header-cell\" [attr.data-selected]=\"selectedColumn() === column.columnName\"\r\n [contextMenu]=\"datagridContextMenuActions(column.columnName, filterElement, groupElement)\"\r\n [title]=\"getColumnTooltip(column)\">\r\n @if(allowNavigation() && isForeignKey){\r\n <span ControlClick class=\"sort-receiver\" (click)=\"toggleSort(column.columnName)\"\r\n (ctrlClick)=\"navigateToForeignTable(column)\">{{ column.displayName || column.columnName\r\n }}</span>\r\n } @else {\r\n <span class=\"sort-receiver\" (click)=\"toggleSort(column.columnName)\">{{ column.displayName ||\r\n column.columnName\r\n }}</span>\r\n }\r\n <small class=\"sort-receiver column-type\" (click)=\"toggleSort(column.columnName)\">{{\r\n column.dataType }}\r\n {{column.length ?\r\n `(${column.length}${column.scale ? `, ${column.scale}` : ''})`: ''}}</small>\r\n <div class=\"column-icons\">\r\n @if(isUniqueColumn){\r\n <span class=\"mat-icon unique-key-icon\" title=\"Colonne avec contrainte d'unicit\u00E9\">looks_one</span>\r\n }\r\n @if(isPrimaryKey || isForeignKey){\r\n <span class=\"mat-icon\" [class.primary-key-icon]=\"isPrimaryKey\" [title]=\"'Colonne de la clef ' + (isPrimaryKey ?\r\n 'primaire' : '\u00E9trang\u00E8re')\" [class.key-icon]=\"isForeignKey\">key</span>\r\n }\r\n @if(allowSync() && (!canEdit(column) || !isEditSafe(column))){\r\n <span class=\"lock-icon mat-icon\" title=\"Colonne verrouill\u00E9e\">lock</span>\r\n }\r\n </div>\r\n @if (sort()?.column === column.columnName) {\r\n @if (sort()?.isAsc) {\r\n <span class=\"sort-icon mat-icon\" (click)=\"toggleSort(column.columnName)\">arrow_upward</span>\r\n } @else {\r\n <span class=\"sort-icon mat-icon\" (click)=\"toggleSort(column.columnName)\">arrow_downward</span>\r\n }\r\n }\r\n <div class=\"filter-group-controls\" #controls>\r\n <chr-column-filter #filterElement [class.hidden]=\"!allowFiltering()\" [by]=\"column.columnName\"\r\n [mode]=\"filter()[column.columnName]?.mode ?? null\" [attr.data-applied]=\"\"\r\n [value]=\"filter()[column.columnName]?.value ?? ''\" [columnMetadata]=\"column\"\r\n [suggestions]=\"columnSuggestions()[column.columnName]\"\r\n (valueChange)=\"onFilterValue(column.columnName, $event)\"\r\n (filterChange)=\"onFilterBy(column.columnName, $event)\" title=\"Double-clic pour d\u00E9finir un filtre\"\r\n class=\"filter\"></chr-column-filter>\r\n @let isGroupBySource = groupBy() == null || groupBy()?.column === column.columnName;\r\n <chr-column-group #groupElement [class.hidden]=\"!allowGrouping()\"\r\n [style.display]=\"!isGroupBySource ? 'none' : ''\" [by]=\"column.columnName\"\r\n [mode]=\"groupBy()?.mode ?? null\" (groupChange)=\"onGroupBy($event)\" class=\"group\"\r\n title=\"Double-clic pour d\u00E9finir un groupement\"></chr-column-group>\r\n @if(isComputedColumn){\r\n <span class=\"filter-icon mat-icon\" title=\"Colonne calcul\u00E9e\">functions</span>\r\n }@else if(!isGroupBySource && groupBy() !== null){\r\n <div class=\"group-by-include\" title=\"Inclure cette colonne dans le r\u00E9sultat group\u00E9\">\r\n <span class=\"mat-icon filter-icon disabled\">stack</span>\r\n <span class=\"toggle faded\">Inclure</span>\r\n <input #checkbox [checked]=\"groupByMap()[column.columnName]\"\r\n (change)=\"onGroupByIncludedChange(column.columnName, checkbox.checked)\"\r\n [name]=\"column.columnName+'-include'\" type=\"checkbox\" />\r\n </div>\r\n }\r\n\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #rowTemplate let-row let-index=\"index\">\r\n @let contextMenuItems = datarowContextMenuActions(row, index);\r\n <div #rowElement class=\"grid-row\"\r\n [style.grid-template-columns]=\"'repeat(' + columns().length + ', minmax(15rem, auto))'\"\r\n [attr.data-is-added]=\"row.flag === 'added'\" [scrollIntoView]=\"!row.valid\" [attr.data-is-valid]=\"row.valid\"\r\n (click)=\"rowClick.emit({ rowIndex: index, row: row.data, event: $event })\" [contextMenu]=\"contextMenuItems\"\r\n [attr.data-has-changed]=\"row.flag === 'modified'\" [attr.data-is-deleted]=\"row.flag === 'deleted'\">\r\n @for (column of columns(); track column.columnName) {\r\n <div class=\"grid-cell\" [attr.data-selected]=\"selectedColumn() === column.columnName\">\r\n <chr-editable-cell class=\"cell\" [value]=\"row.data[column.columnName]\" [row]=\"row.data\"\r\n [customTemplate]=\"getCellTemplate(column.columnName, column.dataType ?? 'varchar')\"\r\n (isEditingChange)=\"$event ? selectedColumn.set(column.columnName) : selectedColumn.set(null)\"\r\n (valueChange)=\"onCellChange(index, row, column, $event)\"\r\n [allowUpdate]=\"allowUpdate() && (isEditSafe(column)||row.flag === 'added') && row.flag !== 'deleted' && canEdit(column)\"\r\n [columnMetadata]=\"column\"></chr-editable-cell>\r\n @if($last){\r\n @if(actions().length > 0){\r\n <div class=\"actions-menu\">\r\n <span class=\"actions-menu-trigger mat-icon icon-button\" [style.cursor]=\"'pointer'\"\r\n [openOnClick]=\"true\" [contextMenu]=\"contextMenuItems\">more_vert</span>\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n <chr-paginator [id]=\"id()\" [page]=\"currentPage()\" [pageSize]=\"pageSize()\" (pageChange)=\"onPageChange($event)\"\r\n (pageSizeChange)=\"onPageSizeChange($event)\"></chr-paginator>\r\n</div>\r\n} @else {\r\n<div class=\"empty-state\">\r\n <p>Aucune donn\u00E9e</p>\r\n</div>\r\n}", styles: ["@import\"https://fonts.googleapis.com/css2?family=Material+Symbols:opsz,wght,FILL,GRAD@24,400,0,0\";@import\"https://fonts.googleapis.com/css2?family=Material+Icons\";.mat-icon:not(mat-icon),.material-symbols{font-family:Material Symbols;font-size:1.5rem;display:flex;align-items:center;justify-content:center}.mat-icon:not(mat-icon).small,.material-symbols.small{font-size:1rem}.mat-icon:not(mat-icon).large,.material-symbols.large{font-size:2rem}.hidden{display:none}.data-grid-wrapper{position:relative;display:grid!important;overflow:auto}.data-grid-container{background:inherit;border-radius:8px;box-shadow:0 2px 4px #0000001a;margin:1rem 0;--faded-text-color: color-mix( in srgb, var(--text-color) 40%, var(--background-color) 50% )}.data-grid-container .data-grid-header{border-top-left-radius:inherit;border-top-right-radius:inherit;background:var(--primary-color);padding:1rem 1.5rem;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:1rem}.data-grid-container .data-grid-header h3{margin:0;color:var(--primary-contrast-color);font-size:1.25rem;font-weight:600}.data-grid-container .data-grid-header .table-description{color:var(--primary-contrast-color);font-size:.875rem;font-style:italic}.data-grid-container .data-grid-header .data-grid-info{display:flex;align-items:center;gap:1rem;color:var(--text-color);font-size:.875rem}.data-grid-container .data-grid-header .data-grid-info span{background:var(--background-color);padding:.25rem .75rem;border-radius:1.25rem}.data-grid-container .data-grid-header .data-grid-info .sync-button{border:2px solid var(--warn-color);box-shadow:0 0 .5rem .15rem var(--warn-color)}.data-grid-container .data-grid-header .data-grid-info .sync-button:hover{background-color:var(--warn-color);color:var(--warn-contrast-color)}.data-grid-container .data-grid-header .data-grid-info .tracking-persistence-button{color:var(--success-contrast-color);background-color:var(--error-color)}.data-grid-container .data-grid-header .data-grid-info .tracking-persistence-button[data-enabled=true]{background-color:var(--success-color)}.data-grid-container .data-grid-header .data-grid-info .icon-button{cursor:pointer;padding:.1rem .25rem;font-size:1rem;transition:background-color .2s ease-in-out,color .2s ease-in-out}.data-grid-container .data-grid-header .data-grid-info .icon-button:hover{background-color:color-mix(in srgb,var(--background-color) 80%,var(--secondary-color) 80%);color:var(--secondary-contrast-color)}.data-grid-container .viewport{font-size:.875rem;scrollbar-width:none;grid-column:1/-1}.data-grid-container .viewport ::-webkit-scrollbar{display:none}.data-grid-container .viewport{-ms-overflow-style:none}.data-grid-container .grid-header,.data-grid-container .grid-body{display:grid;grid-template-columns:subgrid;grid-column:1/-1;font-size:.875rem}.data-grid-container .grid-row{display:grid!important;grid-column:1/-1}.data-grid-container .grid-header{position:sticky!important;top:0;z-index:10;background:color-mix(in srgb,var(--background-color) 80%,transparent 40%);-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);border-bottom:2px solid color-mix(in srgb,var(--text-color) 20%,var(--background-color) 90%)}.data-grid-container .grid-header-cell{position:relative;padding:.75rem 1rem;text-align:left;font-weight:600;color:color-mix(in srgb,var(--text-color) 90%,var(--background-color) 30%);-webkit-user-select:none;user-select:none}.data-grid-container .grid-header-cell .sort-receiver{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}.data-grid-container .grid-header-cell .sort-icon{position:absolute;right:.75rem;top:calc(50% - .75rem);font-size:1rem;color:var(--tertiary-color)}.data-grid-container .grid-header-cell .column-icons{position:absolute;right:.75rem;top:.5rem;display:flex;gap:.25rem;align-items:center}.data-grid-container .grid-header-cell .column-icons span,.data-grid-container .grid-header-cell .column-icons .mat-icon{font-size:1rem}.data-grid-container .grid-header-cell .primary-key-icon{color:var(--primary-color)}.data-grid-container .grid-header-cell .key-icon{color:var(--tertiary-color)}.data-grid-container .grid-header-cell .lock-icon{color:var(--warn-color)}.data-grid-container .grid-header-cell .column-type{font-weight:400;color:var(--faded-text-color);font-size:.75rem;text-transform:uppercase}.data-grid-container .grid-header-cell .filter-group-controls{display:flex;flex-direction:column;justify-content:center;gap:.25rem;width:calc(100% - .875rem)}.data-grid-container .grid-header-cell .group-by-include{display:flex;align-items:center;gap:.25rem;margin-top:.25rem;accent-color:var(--primary-color)}.data-grid-container .grid-header-cell .filter-icon{font-size:1rem}.data-grid-container .grid-row{border-bottom:1px solid color-mix(in srgb,var(--text-color) 20%,var(--background-color) 90%);transition:background-color .2s ease;position:relative}.data-grid-container .grid-row:nth-child(2n){background-color:color-mix(in srgb,var(--background-color) 90%,var(--neutral-color) 20%)}.data-grid-container .grid-row:after{content:\"\";position:absolute;left:0;top:0;bottom:0;width:.25rem;background-color:transparent}.data-grid-container .grid-row[data-is-deleted=true]{background-color:color-mix(in srgb,var(--background-color) 90%,var(--error-color) 20%)}.data-grid-container .grid-row[data-is-deleted=true]:after{background-color:var(--error-color)}.data-grid-container .grid-row[data-has-changed=true]{background-color:color-mix(in srgb,var(--background-color) 90%,var(--warn-color) 20%)}.data-grid-container .grid-row[data-has-changed=true]:after{background-color:var(--warn-color)}.data-grid-container .grid-row[data-is-added=true]{background-color:color-mix(in srgb,var(--background-color) 90%,var(--primary-color) 20%)}.data-grid-container .grid-row[data-is-added=true]:after{background-color:var(--primary-color)}.data-grid-container .grid-row[data-is-valid=false]{box-shadow:inset 0 0 .25rem var(--error-color)}.data-grid-container .grid-row:hover{background-color:var(--neutral-color)}.data-grid-container .grid-cell{position:relative;padding:.75rem 1rem;border-right:1px solid color-mix(in srgb,var(--background-color) 90%,var(--neutral-color) 20%)}.data-grid-container .grid-cell .cell{display:inline-block;min-width:100%;max-width:12rem}.data-grid-container .grid-cell .cell[data-changed=true]{font-weight:600;color:var(--warn-color)}.data-grid-container .grid-cell:last-child{border-right:none}.data-grid-container .grid-cell .actions-menu{position:absolute;right:0rem;top:50%;transform:translateY(-50%)}.data-grid-container .no-data-row{padding:2rem;text-align:center}.data-grid-container .no-data-row .no-data{color:var(--faded-text-color);font-style:italic}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ChrPaginatorComponent, selector: "app-chr-paginator,chr-paginator, chr-paginator", inputs: ["page", "pageSize", "id", "allowSizeChange", "allowPageEdit", "isPageEditing"], outputs: ["pageChange", "pageSizeChange", "isPageEditingChange"] }, { kind: "ngmodule", type: NgxPaginationModule }, { kind: "component", type: EditableCell, selector: "chr-editable-cell", inputs: ["allowUpdate", "customTemplate", "row", "value", "columnMetadata"], outputs: ["valueChange", "isEditingChange"] }, { kind: "directive", type: ContextMenuDirective, selector: "[contextMenu], [chrContextMenu], [chr-right-click]", inputs: ["contextMenu", "openOnClick"] }, { kind: "directive", type: ScrollIntoViewDirective, selector: "[scrollIntoView]", inputs: ["scrollIntoView"] }, { kind: "directive", type: ControlClickDirective, selector: "[CtrlClick], [ControlClick]", inputs: ["callback"], outputs: ["ctrlClick"] }, { kind: "component", type: ColumnFilter, selector: "chr-column-filter", inputs: ["isOpen", "by", "suggestions", "mode", "columnMetadata", "value"], outputs: ["isOpenChange", "modeChange", "valueChange", "filterChange"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1$1.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1$1.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1$1.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: ColumnGroup, selector: "chr-column-group", inputs: ["isOpen", "by", "mode"], outputs: ["isOpenChange", "modeChange", "groupChange"] }, { kind: "directive", type: ChrHoverTitleDirective, selector: "[chrTitle], [title]", inputs: ["chrTitle", "chrTitlePosition", "chrTitleSnap", "chrTitleDebounce"], outputs: ["chrTitleChange"] }, { kind: "pipe", type: i2.PaginatePipe, name: "paginate" }] }); }
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
|
|
8220
|
-
|
|
8221
|
-
|
|
8222
|
-
|
|
8223
|
-
|
|
8224
|
-
|
|
8225
|
-
|
|
8226
|
-
|
|
8227
|
-
|
|
8228
|
-
|
|
8229
|
-
|
|
8230
|
-
|
|
8231
|
-
|
|
8232
|
-
|
|
8233
|
-
|
|
8234
|
-
|
|
8235
|
-
|
|
8236
|
-
},
|
|
8237
|
-
// {
|
|
8238
|
-
// provide: VIRTUAL_SCROLL_STRATEGY,
|
|
8239
|
-
// useClass: DynamicSizeScrollStrategy,
|
|
8240
|
-
// },
|
|
8241
|
-
], template: "@if (table()) {\r\n<div class=\"data-grid-container\">\r\n <div class=\"data-grid-header\">\r\n <h3>{{ title() ? title() : `${table()?.schema ? `${table()?.schema}.` : ''}${table()?.name}` }}</h3>\r\n @if(table()?.description){\r\n <span class=\"table-description\">{{ table()?.description }}</span>\r\n }\r\n <div class=\"data-grid-info\">\r\n <!-- {{allowSync()}} {{hasChanges()}} {{!hasInvalidRows()}} -->\r\n @if(allowManageDistincValueFetching()){\r\n <div>\r\n <span class=\"mat-icon icon-button tracking-persistence-button\"\r\n [attr.data-enabled]=\"allowFetchDistinctValues()\" (click)=\"toggleAllowFetchDistinctValues()\"\r\n title=\"R\u00E9cup\u00E9ration des valeurs distinctes d'une colonne lors du filtrage\">filter_list</span>\r\n </div>\r\n }\r\n @if (allowSync() && allowManageTrackingPersistence()) {\r\n <div>\r\n <span class=\"mat-icon icon-button tracking-persistence-button\"\r\n [attr.data-enabled]=\"crossRequestTrackingPersistence()\"\r\n (click)=\"toggleCrossRequestTrackingPersistence()\"\r\n title=\"Persistance du suivi des modifications entre les requ\u00EAtes\">track_changes</span>\r\n </div>\r\n }\r\n @if(allowSync() && hasChanges() && !hasInvalidRows()){\r\n <span class=\"mat-icon icon-button sync-button\" (click)=\"onSync.emit()\"\r\n title=\"Synchroniser les changements\">file_upload</span>\r\n }\r\n @if(allowRefresh()){\r\n <span class=\"mat-icon icon-button\" (click)=\"refresh()\" title=\"Recharger les donn\u00E9es\">refresh</span>\r\n }\r\n @if(allowInsert()){\r\n <span class=\"mat-icon icon-button\" (click)=\"onAdd()\" title=\"Ajouter une ligne\">add</span>\r\n }\r\n @if(allowExport()){\r\n <span class=\"mat-icon icon-button\" (click)=\"onExport.emit()\"\r\n title=\"T\u00E9l\u00E9charger les donn\u00E9es\">file_download</span>\r\n }\r\n @if(totalItems() !== -1){\r\n <span>Total: {{ totalItems() }} enregistrements</span>\r\n }\r\n </div>\r\n </div>\r\n <div class=\"grid-container data-grid-wrapper\"\r\n [style.grid-template-columns]=\"'repeat(' + columns().length + ', minmax(15rem, auto))'\"\r\n [style.max-height]=\"maxHeight()\" [style.overflow-y]=\"enableVirtualization() ? 'clip': 'auto'\">\r\n <div class=\"grid-header\" [style.column-span]=\"'all'\">\r\n @for (column of columns(); track column.columnName) {\r\n @let isForeignKey = isForeignKeyColumn(column);\r\n @let isPrimaryKey = isPrimaryKeyColumn(column);\r\n @let isComputedColumn = column.isGenerated;\r\n @let isUniqueColumn = isUniqueKeyColumn(column);\r\n <ng-container [ngTemplateOutlet]=\"headerTemplate\"\r\n [ngTemplateOutletContext]=\"{column: column, isForeignKey: isForeignKey, isPrimaryKey: isPrimaryKey, isComputedColumn: isComputedColumn, isUniqueColumn: isUniqueColumn}\"></ng-container>\r\n }\r\n </div>\r\n <div class=\"grid-body\">\r\n @if(enableVirtualization()){\r\n <cdk-virtual-scroll-viewport #viewport [itemSize]=\"41\" [style.height]=\"maxHeight()\" class=\"viewport\">\r\n <ng-container *cdkVirtualFor=\"let row of rows() | paginate: {itemsPerPage: pageSize(), currentPage: currentPage(), id:\r\n this.id(),\r\n totalItems: totalItems()}; let $index = index\" [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: row, index: getRowTrackBy(row.data, $index)}\">\r\n </ng-container>\r\n </cdk-virtual-scroll-viewport>\r\n } @else {\r\n @for (row of rows() | paginate: {itemsPerPage: pageSize(), currentPage: currentPage(), id:\r\n this.id(),\r\n totalItems: currentItems()};\r\n track getRowTrackBy(row.data, $index)) {\r\n <ng-container [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: row, index: getRowTrackBy(row.data, $index)}\">\r\n </ng-container>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n <ng-template #headerTemplate let-column=\"column\" let-isForeignKey=\"isForeignKey\" let-isPrimaryKey=\"isPrimaryKey\"\r\n let-isComputedColumn=\"isComputedColumn\" let-isUniqueColumn=\"isUniqueColumn\">\r\n <div class=\"grid-header-cell\" [attr.data-selected]=\"selectedColumn() === column.columnName\"\r\n [contextMenu]=\"datagridContextMenuActions(column.columnName, filterElement, groupElement)\"\r\n [title]=\"getColumnTooltip(column)\">\r\n @if(allowNavigation() && isForeignKey){\r\n <span ControlClick class=\"sort-receiver\" (click)=\"toggleSort(column.columnName)\"\r\n (ctrlClick)=\"navigateToForeignTable(column)\">{{ column.displayName || column.columnName\r\n }}</span>\r\n } @else {\r\n <span class=\"sort-receiver\" (click)=\"toggleSort(column.columnName)\">{{ column.displayName ||\r\n column.columnName\r\n }}</span>\r\n }\r\n <small class=\"sort-receiver column-type\" (click)=\"toggleSort(column.columnName)\">{{\r\n column.dataType }}\r\n {{column.length ?\r\n `(${column.length}${column.scale ? `, ${column.scale}` : ''})`: ''}}</small>\r\n <div class=\"column-icons\">\r\n @if(isUniqueColumn){\r\n <span class=\"mat-icon unique-key-icon\" title=\"Colonne avec contrainte d'unicit\u00E9\">looks_one</span>\r\n }\r\n @if(isPrimaryKey || isForeignKey){\r\n <span class=\"mat-icon\" [class.primary-key-icon]=\"isPrimaryKey\" [title]=\"'Colonne de la clef ' + (isPrimaryKey ?\r\n 'primaire' : '\u00E9trang\u00E8re')\" [class.key-icon]=\"isForeignKey\">key</span>\r\n }\r\n @if(allowSync() && (!canEdit(column) || !isEditSafe(column))){\r\n <span class=\"lock-icon mat-icon\" title=\"Colonne verrouill\u00E9e\">lock</span>\r\n }\r\n </div>\r\n @if (sort()?.column === column.columnName) {\r\n @if (sort()?.isAsc) {\r\n <span class=\"sort-icon mat-icon\" (click)=\"toggleSort(column.columnName)\">arrow_upward</span>\r\n } @else {\r\n <span class=\"sort-icon mat-icon\" (click)=\"toggleSort(column.columnName)\">arrow_downward</span>\r\n }\r\n }\r\n <div class=\"filter-group-controls\" #controls>\r\n <chr-column-filter #filterElement [class.hidden]=\"!allowFiltering()\" [by]=\"column.columnName\"\r\n [mode]=\"filter()[column.columnName]?.mode ?? null\" [attr.data-applied]=\"\"\r\n [value]=\"filter()[column.columnName]?.value ?? ''\" [columnMetadata]=\"column\"\r\n [suggestions]=\"columnSuggestions()[column.columnName]\"\r\n (valueChange)=\"onFilterValue(column.columnName, $event)\"\r\n (filterChange)=\"onFilterBy(column.columnName, $event)\" title=\"Double-clic pour d\u00E9finir un filtre\"\r\n class=\"filter\"></chr-column-filter>\r\n @let isGroupBySource = groupBy() == null || groupBy()?.column === column.columnName;\r\n <chr-column-group #groupElement [class.hidden]=\"!allowGrouping()\"\r\n [style.display]=\"!isGroupBySource ? 'none' : ''\" [by]=\"column.columnName\"\r\n [mode]=\"groupBy()?.mode ?? null\" (groupChange)=\"onGroupBy($event)\" class=\"group\"\r\n title=\"Double-clic pour d\u00E9finir un groupement\"></chr-column-group>\r\n @if(isComputedColumn){\r\n <span class=\"filter-icon mat-icon\" title=\"Colonne calcul\u00E9e\">functions</span>\r\n }@else if(!isGroupBySource && groupBy() !== null){\r\n <div class=\"group-by-include\" title=\"Inclure cette colonne dans le r\u00E9sultat group\u00E9\">\r\n <span class=\"mat-icon filter-icon disabled\">stack</span>\r\n <span class=\"toggle faded\">Inclure</span>\r\n <input #checkbox [checked]=\"groupByMap()[column.columnName]\"\r\n (change)=\"onGroupByIncludedChange(column.columnName, checkbox.checked)\"\r\n [name]=\"column.columnName+'-include'\" type=\"checkbox\" />\r\n </div>\r\n }\r\n\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #rowTemplate let-row let-index=\"index\">\r\n @let contextMenuItems = datarowContextMenuActions(row, index);\r\n <div #rowElement class=\"grid-row\"\r\n [style.grid-template-columns]=\"'repeat(' + columns().length + ', minmax(15rem, auto))'\"\r\n [attr.data-is-added]=\"row.flag === 'added'\" [scrollIntoView]=\"!row.valid\" [attr.data-is-valid]=\"row.valid\"\r\n (click)=\"rowClick.emit({ rowIndex: index, row: row.data, event: $event })\" [contextMenu]=\"contextMenuItems\"\r\n [attr.data-has-changed]=\"row.flag === 'modified'\" [attr.data-is-deleted]=\"row.flag === 'deleted'\">\r\n @for (column of columns(); track column.columnName) {\r\n <div class=\"grid-cell\" [attr.data-selected]=\"selectedColumn() === column.columnName\">\r\n <chr-editable-cell class=\"cell\" [value]=\"row.data[column.columnName]\" [row]=\"row.data\"\r\n [customTemplate]=\"getCellTemplate(column.columnName, column.dataType ?? 'varchar')\"\r\n (isEditingChange)=\"$event ? selectedColumn.set(column.columnName) : selectedColumn.set(null)\"\r\n (valueChange)=\"onCellChange(index, row, column, $event)\"\r\n [allowUpdate]=\"allowUpdate() && (isEditSafe(column)||row.flag === 'added') && row.flag !== 'deleted' && canEdit(column)\"\r\n [columnMetadata]=\"column\"></chr-editable-cell>\r\n @if($last){\r\n @if(actions().length > 0){\r\n <div class=\"actions-menu\">\r\n <span class=\"actions-menu-trigger mat-icon icon-button\" [style.cursor]=\"'pointer'\"\r\n [openOnClick]=\"true\" [contextMenu]=\"contextMenuItems\">more_vert</span>\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n <chr-paginator [id]=\"id()\" [page]=\"currentPage()\" [pageSize]=\"pageSize()\" (pageChange)=\"onPageChange($event)\"\r\n (pageSizeChange)=\"onPageSizeChange($event)\"></chr-paginator>\r\n</div>\r\n} @else {\r\n<div class=\"empty-state\">\r\n <p>Aucune donn\u00E9e</p>\r\n</div>\r\n}", styles: ["@import\"https://fonts.googleapis.com/css2?family=Material+Symbols:opsz,wght,FILL,GRAD@24,400,0,0\";@import\"https://fonts.googleapis.com/css2?family=Material+Icons\";.mat-icon:not(mat-icon),.material-symbols{font-family:Material Symbols;font-size:1.5rem;display:flex;align-items:center;justify-content:center}.mat-icon:not(mat-icon).small,.material-symbols.small{font-size:1rem}.mat-icon:not(mat-icon).large,.material-symbols.large{font-size:2rem}.hidden{display:none}.data-grid-wrapper{position:relative;display:grid!important;overflow:auto}.data-grid-container{background:inherit;border-radius:8px;box-shadow:0 2px 4px #0000001a;margin:1rem 0;--faded-text-color: color-mix( in srgb, var(--text-color) 40%, var(--background-color) 50% )}.data-grid-container .data-grid-header{border-top-left-radius:inherit;border-top-right-radius:inherit;background:var(--primary-color);padding:1rem 1.5rem;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:1rem}.data-grid-container .data-grid-header h3{margin:0;color:var(--primary-contrast-color);font-size:1.25rem;font-weight:600}.data-grid-container .data-grid-header .table-description{color:var(--primary-contrast-color);font-size:.875rem;font-style:italic}.data-grid-container .data-grid-header .data-grid-info{display:flex;align-items:center;gap:1rem;color:var(--text-color);font-size:.875rem}.data-grid-container .data-grid-header .data-grid-info span{background:var(--background-color);padding:.25rem .75rem;border-radius:1.25rem}.data-grid-container .data-grid-header .data-grid-info .sync-button{border:2px solid var(--warn-color);box-shadow:0 0 .5rem .15rem var(--warn-color)}.data-grid-container .data-grid-header .data-grid-info .sync-button:hover{background-color:var(--warn-color);color:var(--warn-contrast-color)}.data-grid-container .data-grid-header .data-grid-info .tracking-persistence-button{color:var(--success-contrast-color);background-color:var(--error-color)}.data-grid-container .data-grid-header .data-grid-info .tracking-persistence-button[data-enabled=true]{background-color:var(--success-color)}.data-grid-container .data-grid-header .data-grid-info .icon-button{cursor:pointer;padding:.1rem .25rem;font-size:1rem;transition:background-color .2s ease-in-out,color .2s ease-in-out}.data-grid-container .data-grid-header .data-grid-info .icon-button:hover{background-color:color-mix(in srgb,var(--background-color) 80%,var(--secondary-color) 80%);color:var(--secondary-contrast-color)}.data-grid-container .viewport{font-size:.875rem;scrollbar-width:none;grid-column:1/-1}.data-grid-container .viewport ::-webkit-scrollbar{display:none}.data-grid-container .viewport{-ms-overflow-style:none}.data-grid-container .grid-header,.data-grid-container .grid-body{display:grid;grid-template-columns:subgrid;grid-column:1/-1;font-size:.875rem}.data-grid-container .grid-row{display:grid!important;grid-column:1/-1}.data-grid-container .grid-header{position:sticky!important;top:0;z-index:10;background:color-mix(in srgb,var(--background-color) 80%,transparent 40%);-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);border-bottom:2px solid color-mix(in srgb,var(--text-color) 20%,var(--background-color) 90%)}.data-grid-container .grid-header-cell{position:relative;padding:.75rem 1rem;text-align:left;font-weight:600;color:color-mix(in srgb,var(--text-color) 90%,var(--background-color) 30%);-webkit-user-select:none;user-select:none}.data-grid-container .grid-header-cell .sort-receiver{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}.data-grid-container .grid-header-cell .sort-icon{position:absolute;right:.75rem;top:calc(50% - .75rem);font-size:1rem;color:var(--tertiary-color)}.data-grid-container .grid-header-cell .column-icons{position:absolute;right:.75rem;top:.5rem;display:flex;gap:.25rem;align-items:center}.data-grid-container .grid-header-cell .column-icons span,.data-grid-container .grid-header-cell .column-icons .mat-icon{font-size:1rem}.data-grid-container .grid-header-cell .primary-key-icon{color:var(--primary-color)}.data-grid-container .grid-header-cell .key-icon{color:var(--tertiary-color)}.data-grid-container .grid-header-cell .lock-icon{color:var(--warn-color)}.data-grid-container .grid-header-cell .column-type{font-weight:400;color:var(--faded-text-color);font-size:.75rem;text-transform:uppercase}.data-grid-container .grid-header-cell .filter-group-controls{display:flex;flex-direction:column;justify-content:center;gap:.25rem;width:calc(100% - .875rem)}.data-grid-container .grid-header-cell .group-by-include{display:flex;align-items:center;gap:.25rem;margin-top:.25rem;accent-color:var(--primary-color)}.data-grid-container .grid-header-cell .filter-icon{font-size:1rem}.data-grid-container .grid-row{border-bottom:1px solid color-mix(in srgb,var(--text-color) 20%,var(--background-color) 90%);transition:background-color .2s ease;position:relative}.data-grid-container .grid-row:nth-child(2n){background-color:color-mix(in srgb,var(--background-color) 90%,var(--neutral-color) 20%)}.data-grid-container .grid-row:after{content:\"\";position:absolute;left:0;top:0;bottom:0;width:.25rem;background-color:transparent}.data-grid-container .grid-row[data-is-deleted=true]{background-color:color-mix(in srgb,var(--background-color) 90%,var(--error-color) 20%)}.data-grid-container .grid-row[data-is-deleted=true]:after{background-color:var(--error-color)}.data-grid-container .grid-row[data-has-changed=true]{background-color:color-mix(in srgb,var(--background-color) 90%,var(--warn-color) 20%)}.data-grid-container .grid-row[data-has-changed=true]:after{background-color:var(--warn-color)}.data-grid-container .grid-row[data-is-added=true]{background-color:color-mix(in srgb,var(--background-color) 90%,var(--primary-color) 20%)}.data-grid-container .grid-row[data-is-added=true]:after{background-color:var(--primary-color)}.data-grid-container .grid-row[data-is-valid=false]{box-shadow:inset 0 0 .25rem var(--error-color)}.data-grid-container .grid-row:hover{background-color:var(--neutral-color)}.data-grid-container .grid-cell{position:relative;padding:.75rem 1rem;border-right:1px solid color-mix(in srgb,var(--background-color) 90%,var(--neutral-color) 20%)}.data-grid-container .grid-cell .cell{display:inline-block;min-width:100%;max-width:12rem}.data-grid-container .grid-cell .cell[data-changed=true]{font-weight:600;color:var(--warn-color)}.data-grid-container .grid-cell:last-child{border-right:none}.data-grid-container .grid-cell .actions-menu{position:absolute;right:0rem;top:50%;transform:translateY(-50%)}.data-grid-container .no-data-row{padding:2rem;text-align:center}.data-grid-container .no-data-row .no-data{color:var(--faded-text-color);font-style:italic}\n"] }]
|
|
8242
|
-
}], ctorParameters: () => [], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], table: [{ type: i0.Input, args: [{ isSignal: true, alias: "table", required: false }] }, { type: i0.Output, args: ["tableChange"] }], viewport: [{ type: i0.ViewChild, args: ['viewport', { isSignal: true }] }], headerScroll: [{ type: i0.ViewChild, args: ['headerScroll', { isSignal: true }] }], currentPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentPage", required: false }] }, { type: i0.Output, args: ["currentPageChange"] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }, { type: i0.Output, args: ["pageSizeChange"] }], onInit: [{ type: i0.Output, args: ["onInit"] }], sort: [{ type: i0.Input, args: [{ isSignal: true, alias: "sort", required: false }] }, { type: i0.Output, args: ["sortChange"] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }, { type: i0.Output, args: ["filterChange"] }], groupBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupBy", required: false }] }, { type: i0.Output, args: ["groupByChange"] }], cellChange: [{ type: i0.Output, args: ["cellChange"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], enableVirtualization: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableVirtualization", required: false }] }], allowFiltering: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowFiltering", required: false }] }], allowGrouping: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowGrouping", required: false }] }], allowInsert: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowInsert", required: false }] }], allowUpdate: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowUpdate", required: false }] }], allowDelete: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowDelete", required: false }] }], allowDuplicate: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowDuplicate", required: false }] }], allowSync: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowSync", required: false }] }], allowRefresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowRefresh", required: false }] }], allowNavigation: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowNavigation", required: false }] }], allowExport: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowExport", required: false }] }], allowManageTrackingPersistence: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowManageTrackingPersistence", required: false }] }], allowManageDistincValueFetching: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowManageDistincValueFetching", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], onExport: [{ type: i0.Output, args: ["onExport"] }], onSync: [{ type: i0.Output, args: ["onSync"] }], onRefresh: [{ type: i0.Output, args: ["onRefresh"] }], onAddRow: [{ type: i0.Output, args: ["onAddRow"] }], onDeleteRow: [{ type: i0.Output, args: ["onDeleteRow"] }], onForeignTableNavigate: [{ type: i0.Output, args: ["onForeignTableNavigate"] }], onNavigate: [{ type: i0.Output, args: ["onNavigate"] }], onFilterValueChange: [{ type: i0.Output, args: ["onFilterValueChange"] }], allowFetchDistinctValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowFetchDistinctValues", required: false }] }, { type: i0.Output, args: ["allowFetchDistinctValuesChange"] }], crossRequestTrackingPersistence: [{ type: i0.Input, args: [{ isSignal: true, alias: "crossRequestTrackingPersistence", required: false }] }, { type: i0.Output, args: ["crossRequestTrackingPersistenceChange"] }], modifiedCells: [{ type: i0.Input, args: [{ isSignal: true, alias: "modifiedCells", required: false }] }, { type: i0.Output, args: ["modifiedCellsChange"] }], modifiedRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "modifiedRows", required: false }] }, { type: i0.Output, args: ["modifiedRowsChange"] }], addedRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "addedRows", required: false }] }, { type: i0.Output, args: ["addedRowsChange"] }], deletedRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "deletedRows", required: false }] }, { type: i0.Output, args: ["deletedRowsChange"] }], distinctValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "distinctValues", required: false }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], cellTemplates: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => ChrCellDefDirective), { isSignal: true }] }], trackByMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackByMode", required: false }] }, { type: i0.Output, args: ["trackByModeChange"] }] } });
|
|
8243
|
-
|
|
8244
|
-
class MessageBanner {
|
|
8245
|
-
constructor() {
|
|
8246
|
-
this.isVisible = signal(true, /* @ts-ignore */
|
|
8247
|
-
...(ngDevMode ? [{ debugName: "isVisible" }] : /* istanbul ignore next */ []));
|
|
8248
|
-
this.closable = input(false, /* @ts-ignore */
|
|
8249
|
-
...(ngDevMode ? [{ debugName: "closable" }] : /* istanbul ignore next */ []));
|
|
8250
|
-
this.title = input(null, /* @ts-ignore */
|
|
8251
|
-
...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
8252
|
-
this.icon = input(null, /* @ts-ignore */
|
|
8253
|
-
...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
8254
|
-
this.message = input(/* @ts-ignore */
|
|
8255
|
-
...(ngDevMode ? [undefined, { debugName: "message" }] : /* istanbul ignore next */ []));
|
|
8256
|
-
this.type = input('none', /* @ts-ignore */
|
|
8257
|
-
...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
8258
|
-
this.close = () => {
|
|
8259
|
-
this.isVisible.set(false);
|
|
8260
|
-
};
|
|
8036
|
+
// Méthodes de traitement côté client (peuvent être surchargées)
|
|
8037
|
+
applyFilters(data, filters) {
|
|
8038
|
+
if (Object.keys(filters).length === 0)
|
|
8039
|
+
return data;
|
|
8040
|
+
const filteredRows = data.rows.filter((row) => {
|
|
8041
|
+
return Object.values(filters).every((filter) => {
|
|
8042
|
+
const value = row[filter.column];
|
|
8043
|
+
const filterValue = String(filter.value).toLowerCase();
|
|
8044
|
+
const stringValue = String(value ?? '').toLowerCase();
|
|
8045
|
+
switch (filter.mode) {
|
|
8046
|
+
case DGFilterMode.CONTAINS:
|
|
8047
|
+
return stringValue.includes(filterValue);
|
|
8048
|
+
case DGFilterMode.STARTS_WITH:
|
|
8049
|
+
return stringValue.startsWith(filterValue);
|
|
8050
|
+
case DGFilterMode.ENDS_WITH:
|
|
8051
|
+
return stringValue.endsWith(filterValue);
|
|
8052
|
+
case DGFilterMode.EQUALS:
|
|
8053
|
+
return stringValue === filterValue;
|
|
8054
|
+
case DGFilterMode.NOT_EQUALS:
|
|
8055
|
+
return stringValue !== filterValue;
|
|
8056
|
+
case DGFilterMode.GREATER_OR_EQUAL:
|
|
8057
|
+
return Number(value) >= Number(filter.value);
|
|
8058
|
+
case DGFilterMode.LOWER_OR_EQUAL:
|
|
8059
|
+
return Number(value) <= Number(filter.value);
|
|
8060
|
+
default:
|
|
8061
|
+
return true;
|
|
8062
|
+
}
|
|
8063
|
+
});
|
|
8064
|
+
});
|
|
8065
|
+
const cloned = data.clone();
|
|
8066
|
+
cloned.rows = filteredRows;
|
|
8067
|
+
return cloned;
|
|
8261
8068
|
}
|
|
8262
|
-
|
|
8263
|
-
|
|
8264
|
-
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
8270
|
-
|
|
8271
|
-
|
|
8272
|
-
|
|
8273
|
-
|
|
8274
|
-
|
|
8275
|
-
|
|
8276
|
-
|
|
8277
|
-
|
|
8069
|
+
applySort(data, sort) {
|
|
8070
|
+
if (!sort)
|
|
8071
|
+
return data;
|
|
8072
|
+
const sortedRows = [...data.rows].sort((a, b) => {
|
|
8073
|
+
const aValue = a[sort.column];
|
|
8074
|
+
const bValue = b[sort.column];
|
|
8075
|
+
if (aValue === bValue)
|
|
8076
|
+
return 0;
|
|
8077
|
+
if (aValue === null || aValue === undefined)
|
|
8078
|
+
return 1;
|
|
8079
|
+
if (bValue === null || bValue === undefined)
|
|
8080
|
+
return -1;
|
|
8081
|
+
const comparison = aValue > bValue ? 1 : -1;
|
|
8082
|
+
return sort.isAsc ? comparison : -comparison;
|
|
8083
|
+
});
|
|
8084
|
+
const cloned = data.clone();
|
|
8085
|
+
cloned.rows = sortedRows;
|
|
8086
|
+
return cloned;
|
|
8278
8087
|
}
|
|
8279
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: Spinner, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8280
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: Spinner, isStandalone: true, selector: "chr-spinner", inputs: { shown: { classPropertyName: "shown", publicName: "shown", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (shouldShow()) {\r\n<div class=\"spinner-backdrop\">\r\n <div class=\"spinner-container\">\r\n <div class=\"pulse-rings\">\r\n <div class=\"pulse-ring pulse-ring-1\"></div>\r\n <div class=\"pulse-ring pulse-ring-2\"></div>\r\n <div class=\"pulse-ring pulse-ring-3\"></div>\r\n <div class=\"pulse-ring pulse-ring-4\"></div>\r\n </div>\r\n\r\n <div class=\"loading-text\">\r\n <p>Chargement...</p>\r\n </div>\r\n </div>\r\n</div>\r\n}", styles: ["@charset \"UTF-8\";.spinner-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background-color:color-mix(in srgb,black 40%,transparent);display:flex;justify-content:center;align-items:center;z-index:9997;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);animation:fadeIn .3s ease-in-out}.spinner-container{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2rem;padding:3rem;border-radius:1.5rem;min-width:250px;animation:slideUp .4s ease-out}.pulse-rings{position:relative;width:120px;height:120px;display:flex;align-items:center;justify-content:center}.pulse-ring{position:absolute;border:3px solid transparent;border-radius:50%;animation:pulse-ring 2.5s cubic-bezier(.25,.46,.45,.94) infinite}.pulse-ring-1{width:40px;height:40px;border-color:var(--primary-color);animation-delay:0s;box-shadow:0 0 20px color-mix(in srgb,var(--primary-color) 30%,transparent)}.pulse-ring-2{width:60px;height:60px;border-color:var(--tertiary-color);animation-delay:.6s;box-shadow:0 0 25px color-mix(in srgb,var(--tertiary-color) 25%,transparent)}.pulse-ring-3{width:80px;height:80px;border-color:var(--secondary-color);animation-delay:1.2s;box-shadow:0 0 30px color-mix(in srgb,var(--secondary-color) 20%,transparent)}.pulse-ring-4{width:100px;height:100px;border-color:var(--primary-color);animation-delay:1.8s;opacity:.7;box-shadow:0 0 35px color-mix(in srgb,var(--primary-color) 15%,transparent)}.loading-text{text-align:center;color:var(--text-color);font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif}.loading-text p{margin:0;font-size:1.2rem;font-weight:500;color:var(--primary-color);letter-spacing:.5px;animation:text-pulse 2s ease-in-out infinite}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(30px) scale(.9)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes pulse-ring{0%{transform:scale(.6);opacity:1;border-width:4px}50%{opacity:.8;border-width:2px}to{transform:scale(1.3);opacity:0;border-width:1px}}@keyframes text-pulse{0%,to{opacity:.8}50%{opacity:1;text-shadow:0 0 10px color-mix(in srgb,var(--primary-color) 30%,transparent)}}@media(max-width:768px){.spinner-container{min-width:200px;padding:2rem;gap:1.5rem}.pulse-rings{width:100px;height:100px}.pulse-ring-1{width:35px;height:35px}.pulse-ring-2{width:50px;height:50px}.pulse-ring-3{width:65px;height:65px}.pulse-ring-4{width:80px;height:80px}.loading-text p{font-size:1rem}}.dark-theme .spinner-container{box-shadow:0 20px 40px color-mix(in srgb,black 40%,transparent);border-color:var(--neutral-color)}.dark-theme .pulse-ring-1{box-shadow:0 0 20px color-mix(in srgb,var(--primary-color) 50%,transparent)}.dark-theme .pulse-ring-2{box-shadow:0 0 25px color-mix(in srgb,var(--tertiary-color) 40%,transparent)}.as400-theme .pulse-ring{filter:drop-shadow(0 0 8px var(--primary-color))}.as400-theme .loading-text p{text-shadow:0 0 10px var(--primary-color)}\n"] }); }
|
|
8281
8088
|
}
|
|
8282
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: Spinner, decorators: [{
|
|
8283
|
-
type: Component,
|
|
8284
|
-
args: [{ selector: 'chr-spinner', imports: [], template: "@if (shouldShow()) {\r\n<div class=\"spinner-backdrop\">\r\n <div class=\"spinner-container\">\r\n <div class=\"pulse-rings\">\r\n <div class=\"pulse-ring pulse-ring-1\"></div>\r\n <div class=\"pulse-ring pulse-ring-2\"></div>\r\n <div class=\"pulse-ring pulse-ring-3\"></div>\r\n <div class=\"pulse-ring pulse-ring-4\"></div>\r\n </div>\r\n\r\n <div class=\"loading-text\">\r\n <p>Chargement...</p>\r\n </div>\r\n </div>\r\n</div>\r\n}", styles: ["@charset \"UTF-8\";.spinner-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background-color:color-mix(in srgb,black 40%,transparent);display:flex;justify-content:center;align-items:center;z-index:9997;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);animation:fadeIn .3s ease-in-out}.spinner-container{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2rem;padding:3rem;border-radius:1.5rem;min-width:250px;animation:slideUp .4s ease-out}.pulse-rings{position:relative;width:120px;height:120px;display:flex;align-items:center;justify-content:center}.pulse-ring{position:absolute;border:3px solid transparent;border-radius:50%;animation:pulse-ring 2.5s cubic-bezier(.25,.46,.45,.94) infinite}.pulse-ring-1{width:40px;height:40px;border-color:var(--primary-color);animation-delay:0s;box-shadow:0 0 20px color-mix(in srgb,var(--primary-color) 30%,transparent)}.pulse-ring-2{width:60px;height:60px;border-color:var(--tertiary-color);animation-delay:.6s;box-shadow:0 0 25px color-mix(in srgb,var(--tertiary-color) 25%,transparent)}.pulse-ring-3{width:80px;height:80px;border-color:var(--secondary-color);animation-delay:1.2s;box-shadow:0 0 30px color-mix(in srgb,var(--secondary-color) 20%,transparent)}.pulse-ring-4{width:100px;height:100px;border-color:var(--primary-color);animation-delay:1.8s;opacity:.7;box-shadow:0 0 35px color-mix(in srgb,var(--primary-color) 15%,transparent)}.loading-text{text-align:center;color:var(--text-color);font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif}.loading-text p{margin:0;font-size:1.2rem;font-weight:500;color:var(--primary-color);letter-spacing:.5px;animation:text-pulse 2s ease-in-out infinite}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(30px) scale(.9)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes pulse-ring{0%{transform:scale(.6);opacity:1;border-width:4px}50%{opacity:.8;border-width:2px}to{transform:scale(1.3);opacity:0;border-width:1px}}@keyframes text-pulse{0%,to{opacity:.8}50%{opacity:1;text-shadow:0 0 10px color-mix(in srgb,var(--primary-color) 30%,transparent)}}@media(max-width:768px){.spinner-container{min-width:200px;padding:2rem;gap:1.5rem}.pulse-rings{width:100px;height:100px}.pulse-ring-1{width:35px;height:35px}.pulse-ring-2{width:50px;height:50px}.pulse-ring-3{width:65px;height:65px}.pulse-ring-4{width:80px;height:80px}.loading-text p{font-size:1rem}}.dark-theme .spinner-container{box-shadow:0 20px 40px color-mix(in srgb,black 40%,transparent);border-color:var(--neutral-color)}.dark-theme .pulse-ring-1{box-shadow:0 0 20px color-mix(in srgb,var(--primary-color) 50%,transparent)}.dark-theme .pulse-ring-2{box-shadow:0 0 25px color-mix(in srgb,var(--tertiary-color) 40%,transparent)}.as400-theme .pulse-ring{filter:drop-shadow(0 0 8px var(--primary-color))}.as400-theme .loading-text p{text-shadow:0 0 10px var(--primary-color)}\n"] }]
|
|
8285
|
-
}], propDecorators: { shown: [{ type: i0.Input, args: [{ isSignal: true, alias: "shown", required: false }] }] } });
|
|
8286
8089
|
|
|
8287
|
-
class
|
|
8090
|
+
class DataGrid {
|
|
8288
8091
|
constructor() {
|
|
8289
|
-
this.
|
|
8092
|
+
this.formatterService = inject(DataFormatterService);
|
|
8093
|
+
this.id = signal(crypto.randomUUID(), /* @ts-ignore */
|
|
8290
8094
|
...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
8291
|
-
this.
|
|
8292
|
-
...(ngDevMode ? [{ debugName: "
|
|
8293
|
-
this.
|
|
8294
|
-
...(ngDevMode ? [{ debugName: "
|
|
8295
|
-
this.
|
|
8296
|
-
...(ngDevMode ? [{ debugName: "
|
|
8095
|
+
this.title = input(null, /* @ts-ignore */
|
|
8096
|
+
...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
8097
|
+
this.table = model(/* @ts-ignore */
|
|
8098
|
+
...(ngDevMode ? [undefined, { debugName: "table" }] : /* istanbul ignore next */ []));
|
|
8099
|
+
this.viewport = viewChild('viewport', /* @ts-ignore */
|
|
8100
|
+
...(ngDevMode ? [{ debugName: "viewport" }] : /* istanbul ignore next */ []));
|
|
8101
|
+
this.headerScroll = viewChild('headerScroll', /* @ts-ignore */
|
|
8102
|
+
...(ngDevMode ? [{ debugName: "headerScroll" }] : /* istanbul ignore next */ []));
|
|
8103
|
+
this.currentPage = model(1, /* @ts-ignore */
|
|
8104
|
+
...(ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []));
|
|
8297
8105
|
this.pageSize = model(10, /* @ts-ignore */
|
|
8298
8106
|
...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
|
|
8299
|
-
|
|
8300
|
-
|
|
8301
|
-
|
|
8302
|
-
|
|
8303
|
-
|
|
8304
|
-
|
|
8305
|
-
|
|
8306
|
-
|
|
8307
|
-
|
|
8308
|
-
|
|
8309
|
-
|
|
8310
|
-
|
|
8311
|
-
|
|
8312
|
-
|
|
8313
|
-
|
|
8314
|
-
|
|
8315
|
-
|
|
8316
|
-
|
|
8317
|
-
|
|
8318
|
-
|
|
8319
|
-
|
|
8320
|
-
|
|
8321
|
-
|
|
8322
|
-
|
|
8323
|
-
|
|
8324
|
-
|
|
8325
|
-
|
|
8326
|
-
|
|
8327
|
-
|
|
8328
|
-
|
|
8107
|
+
// public pageChange = output<number>();
|
|
8108
|
+
// public pageSizeChange = output<number>();
|
|
8109
|
+
this.onInit = output();
|
|
8110
|
+
this.selectedColumn = signal(null, /* @ts-ignore */
|
|
8111
|
+
...(ngDevMode ? [{ debugName: "selectedColumn" }] : /* istanbul ignore next */ []));
|
|
8112
|
+
this.sort = model(null, /* @ts-ignore */
|
|
8113
|
+
...(ngDevMode ? [{ debugName: "sort" }] : /* istanbul ignore next */ []));
|
|
8114
|
+
this.filter = model({}, /* @ts-ignore */
|
|
8115
|
+
...(ngDevMode ? [{ debugName: "filter" }] : /* istanbul ignore next */ []));
|
|
8116
|
+
this.groupBy = model(null, /* @ts-ignore */
|
|
8117
|
+
...(ngDevMode ? [{ debugName: "groupBy" }] : /* istanbul ignore next */ []));
|
|
8118
|
+
this.cellChange = output();
|
|
8119
|
+
this.rowClick = output();
|
|
8120
|
+
this.enableVirtualization = input(false, /* @ts-ignore */
|
|
8121
|
+
...(ngDevMode ? [{ debugName: "enableVirtualization" }] : /* istanbul ignore next */ []));
|
|
8122
|
+
this.allowFiltering = input(true, /* @ts-ignore */
|
|
8123
|
+
...(ngDevMode ? [{ debugName: "allowFiltering" }] : /* istanbul ignore next */ []));
|
|
8124
|
+
this.allowGrouping = input(true, /* @ts-ignore */
|
|
8125
|
+
...(ngDevMode ? [{ debugName: "allowGrouping" }] : /* istanbul ignore next */ []));
|
|
8126
|
+
this.allowInsert = input(false, /* @ts-ignore */
|
|
8127
|
+
...(ngDevMode ? [{ debugName: "allowInsert" }] : /* istanbul ignore next */ []));
|
|
8128
|
+
this.allowUpdate = input(false, /* @ts-ignore */
|
|
8129
|
+
...(ngDevMode ? [{ debugName: "allowUpdate" }] : /* istanbul ignore next */ []));
|
|
8130
|
+
this.allowDelete = input(false, /* @ts-ignore */
|
|
8131
|
+
...(ngDevMode ? [{ debugName: "allowDelete" }] : /* istanbul ignore next */ []));
|
|
8132
|
+
this.allowDuplicate = input(false, /* @ts-ignore */
|
|
8133
|
+
...(ngDevMode ? [{ debugName: "allowDuplicate" }] : /* istanbul ignore next */ []));
|
|
8134
|
+
this.allowSync = input(true, /* @ts-ignore */
|
|
8135
|
+
...(ngDevMode ? [{ debugName: "allowSync" }] : /* istanbul ignore next */ []));
|
|
8136
|
+
this.allowRefresh = input(false, /* @ts-ignore */
|
|
8137
|
+
...(ngDevMode ? [{ debugName: "allowRefresh" }] : /* istanbul ignore next */ []));
|
|
8138
|
+
this.allowNavigation = input(false, /* @ts-ignore */
|
|
8139
|
+
...(ngDevMode ? [{ debugName: "allowNavigation" }] : /* istanbul ignore next */ []));
|
|
8140
|
+
this.allowExport = input(false, /* @ts-ignore */
|
|
8141
|
+
...(ngDevMode ? [{ debugName: "allowExport" }] : /* istanbul ignore next */ []));
|
|
8142
|
+
this.allowManageTrackingPersistence = input(false, /* @ts-ignore */
|
|
8143
|
+
...(ngDevMode ? [{ debugName: "allowManageTrackingPersistence" }] : /* istanbul ignore next */ []));
|
|
8144
|
+
this.allowManageDistincValueFetching = input(false, /* @ts-ignore */
|
|
8145
|
+
...(ngDevMode ? [{ debugName: "allowManageDistincValueFetching" }] : /* istanbul ignore next */ []));
|
|
8146
|
+
this.maxHeight = input('100%', /* @ts-ignore */
|
|
8147
|
+
...(ngDevMode ? [{ debugName: "maxHeight" }] : /* istanbul ignore next */ []));
|
|
8148
|
+
this.onExport = output();
|
|
8149
|
+
this.onSync = output();
|
|
8150
|
+
this.onRefresh = output();
|
|
8151
|
+
this.onAddRow = output();
|
|
8152
|
+
this.onDeleteRow = output();
|
|
8153
|
+
/**
|
|
8154
|
+
* Only supported for DB2 tables. For other types, use the onNavigate event.
|
|
8155
|
+
*/
|
|
8156
|
+
this.onForeignTableNavigate = output();
|
|
8157
|
+
this.onNavigate = output();
|
|
8158
|
+
this.onFilterValueChange = output();
|
|
8159
|
+
this.allowFetchDistinctValues = model(false, /* @ts-ignore */
|
|
8160
|
+
...(ngDevMode ? [{ debugName: "allowFetchDistinctValues" }] : /* istanbul ignore next */ []));
|
|
8161
|
+
this.crossRequestTrackingPersistence = model(false, /* @ts-ignore */
|
|
8162
|
+
...(ngDevMode ? [{ debugName: "crossRequestTrackingPersistence" }] : /* istanbul ignore next */ []));
|
|
8163
|
+
this.modifiedCells = model([], /* @ts-ignore */
|
|
8164
|
+
...(ngDevMode ? [{ debugName: "modifiedCells" }] : /* istanbul ignore next */ []));
|
|
8165
|
+
this.modifiedRows = model([], /* @ts-ignore */
|
|
8166
|
+
...(ngDevMode ? [{ debugName: "modifiedRows" }] : /* istanbul ignore next */ []));
|
|
8167
|
+
this.addedRows = model([], /* @ts-ignore */
|
|
8168
|
+
...(ngDevMode ? [{ debugName: "addedRows" }] : /* istanbul ignore next */ []));
|
|
8169
|
+
this.deletedRows = model([], /* @ts-ignore */
|
|
8170
|
+
...(ngDevMode ? [{ debugName: "deletedRows" }] : /* istanbul ignore next */ []));
|
|
8171
|
+
this.distinctValues = input({}, /* @ts-ignore */
|
|
8172
|
+
...(ngDevMode ? [{ debugName: "distinctValues" }] : /* istanbul ignore next */ []));
|
|
8173
|
+
this.actions = input([], /* @ts-ignore */
|
|
8174
|
+
...(ngDevMode ? [{ debugName: "actions" }] : /* istanbul ignore next */ []));
|
|
8175
|
+
this.cellTemplates = contentChildren(ChrCellDefDirective, /* @ts-ignore */
|
|
8176
|
+
...(ngDevMode ? [{ debugName: "cellTemplates" }] : /* istanbul ignore next */ []));
|
|
8177
|
+
this.templatesByColumn = computed(() => {
|
|
8178
|
+
const map = new Map();
|
|
8179
|
+
for (const t of this.cellTemplates()) {
|
|
8180
|
+
const col = t.columnName();
|
|
8181
|
+
if (col)
|
|
8182
|
+
map.set(col.toLowerCase(), t);
|
|
8183
|
+
}
|
|
8184
|
+
return map;
|
|
8185
|
+
}, /* @ts-ignore */
|
|
8186
|
+
...(ngDevMode ? [{ debugName: "templatesByColumn" }] : /* istanbul ignore next */ []));
|
|
8187
|
+
this.templatesByType = computed(() => {
|
|
8188
|
+
const map = new Map();
|
|
8189
|
+
for (const t of this.cellTemplates()) {
|
|
8190
|
+
const type = t.dataType();
|
|
8191
|
+
if (type)
|
|
8192
|
+
map.set(type.toLowerCase(), t);
|
|
8193
|
+
}
|
|
8194
|
+
return map;
|
|
8195
|
+
}, /* @ts-ignore */
|
|
8196
|
+
...(ngDevMode ? [{ debugName: "templatesByType" }] : /* istanbul ignore next */ []));
|
|
8197
|
+
this.columnSuggestions = computed(() => {
|
|
8198
|
+
const distinctVals = this.distinctValues();
|
|
8199
|
+
// Si des valeurs distinctes sont fournies par le parent, on les utilise
|
|
8200
|
+
if (Object.keys(distinctVals).length > 0) {
|
|
8201
|
+
return distinctVals;
|
|
8202
|
+
}
|
|
8203
|
+
// Sinon, on utilise l'ancien comportement (valeurs locales)
|
|
8204
|
+
const suggestions = {};
|
|
8205
|
+
this.columns().forEach((column) => {
|
|
8206
|
+
suggestions[column.columnName] = new Set();
|
|
8329
8207
|
});
|
|
8330
|
-
|
|
8331
|
-
|
|
8332
|
-
|
|
8333
|
-
|
|
8334
|
-
|
|
8335
|
-
}
|
|
8336
|
-
|
|
8337
|
-
|
|
8338
|
-
|
|
8339
|
-
|
|
8340
|
-
|
|
8341
|
-
|
|
8342
|
-
}
|
|
8343
|
-
|
|
8344
|
-
|
|
8345
|
-
|
|
8346
|
-
|
|
8347
|
-
|
|
8348
|
-
|
|
8349
|
-
|
|
8350
|
-
|
|
8351
|
-
|
|
8352
|
-
|
|
8353
|
-
|
|
8354
|
-
|
|
8355
|
-
|
|
8356
|
-
|
|
8357
|
-
|
|
8358
|
-
|
|
8359
|
-
|
|
8360
|
-
|
|
8361
|
-
|
|
8362
|
-
|
|
8363
|
-
|
|
8364
|
-
|
|
8365
|
-
|
|
8366
|
-
|
|
8367
|
-
|
|
8368
|
-
|
|
8369
|
-
|
|
8370
|
-
|
|
8371
|
-
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
|
|
8208
|
+
this.table()?.rows.forEach((row) => {
|
|
8209
|
+
this.columns().forEach((column) => {
|
|
8210
|
+
const value = row[column.columnName];
|
|
8211
|
+
if (value !== null && value !== undefined) {
|
|
8212
|
+
suggestions[column.columnName].add(value);
|
|
8213
|
+
}
|
|
8214
|
+
});
|
|
8215
|
+
});
|
|
8216
|
+
return Object.entries(suggestions).reduce((acc, [key, value]) => {
|
|
8217
|
+
acc[key] = Array.from(value);
|
|
8218
|
+
return acc;
|
|
8219
|
+
}, {});
|
|
8220
|
+
}, /* @ts-ignore */
|
|
8221
|
+
...(ngDevMode ? [{ debugName: "columnSuggestions" }] : /* istanbul ignore next */ []));
|
|
8222
|
+
// protected _addedRows = computed(() => this.addedRows().map((r) => r.row));
|
|
8223
|
+
this.trackByMode = model('index', /* @ts-ignore */
|
|
8224
|
+
...(ngDevMode ? [{ debugName: "trackByMode" }] : /* istanbul ignore next */ []));
|
|
8225
|
+
this.hasChanges = computed(() => {
|
|
8226
|
+
return (this.addedRows().length > 0 ||
|
|
8227
|
+
this.modifiedRows().length > 0 ||
|
|
8228
|
+
this.deletedRows().length > 0);
|
|
8229
|
+
}, /* @ts-ignore */
|
|
8230
|
+
...(ngDevMode ? [{ debugName: "hasChanges" }] : /* istanbul ignore next */ []));
|
|
8231
|
+
this.groupByMap = computed(() => {
|
|
8232
|
+
const includedMap = {};
|
|
8233
|
+
this.groupBy()?.included.forEach((col) => {
|
|
8234
|
+
includedMap[col] = true;
|
|
8235
|
+
});
|
|
8236
|
+
return includedMap;
|
|
8237
|
+
}, /* @ts-ignore */
|
|
8238
|
+
...(ngDevMode ? [{ debugName: "groupByMap" }] : /* istanbul ignore next */ []));
|
|
8239
|
+
this.columns = computed(() => {
|
|
8240
|
+
const table = this.table();
|
|
8241
|
+
const metadatas = table?.columnMetadatas || [];
|
|
8242
|
+
const groupedColumns = this.groupBy()?.included || [];
|
|
8243
|
+
//Sort grouped columns first then computed columns then the rest
|
|
8244
|
+
if (this.groupBy() !== null)
|
|
8245
|
+
return [
|
|
8246
|
+
...metadatas.filter((col) => groupedColumns.includes(col.columnName)),
|
|
8247
|
+
...metadatas.filter((col) => !groupedColumns.includes(col.columnName) && !col.tableName),
|
|
8248
|
+
...metadatas.filter((col) => !groupedColumns.includes(col.columnName) && col.tableName),
|
|
8249
|
+
];
|
|
8250
|
+
else
|
|
8251
|
+
return metadatas;
|
|
8252
|
+
}, /* @ts-ignore */
|
|
8253
|
+
...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
8254
|
+
this.rows = computed(() => {
|
|
8255
|
+
const table = this.table();
|
|
8256
|
+
if (!table)
|
|
8257
|
+
return [];
|
|
8258
|
+
const computedRows = [];
|
|
8259
|
+
for (const row of table.rows) {
|
|
8260
|
+
const rowId = table.getRowIdentifier(row);
|
|
8261
|
+
const updated = this.modifiedRows().find((mr) => table.getRowIdentifier(mr.current) === rowId);
|
|
8262
|
+
const deleted = this.deletedRows().find((dr) => table.getRowIdentifier(dr.row) === rowId);
|
|
8263
|
+
computedRows.push({
|
|
8264
|
+
id: rowId,
|
|
8265
|
+
data: updated ? updated.current : row,
|
|
8266
|
+
flag: deleted ? 'deleted' : updated ? 'modified' : 'unchanged',
|
|
8267
|
+
valid: this.validateRow(deleted ? deleted.row : updated ? updated.current : row),
|
|
8268
|
+
});
|
|
8378
8269
|
}
|
|
8379
|
-
|
|
8270
|
+
for (const addedEntry of this.addedRows()) {
|
|
8271
|
+
const rowId = table.getRowIdentifier(addedEntry.row);
|
|
8272
|
+
computedRows.push({
|
|
8273
|
+
id: rowId,
|
|
8274
|
+
data: addedEntry.row,
|
|
8275
|
+
flag: 'added',
|
|
8276
|
+
valid: this.validateRow(addedEntry.row),
|
|
8277
|
+
});
|
|
8278
|
+
}
|
|
8279
|
+
return computedRows;
|
|
8380
8280
|
}, /* @ts-ignore */
|
|
8381
|
-
...(ngDevMode ? [{ debugName: "
|
|
8382
|
-
this.
|
|
8383
|
-
|
|
8384
|
-
|
|
8385
|
-
|
|
8386
|
-
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
|
|
8390
|
-
|
|
8391
|
-
|
|
8281
|
+
...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
8282
|
+
this.totalItems = computed(() => {
|
|
8283
|
+
return 'total' in (this.table() || {})
|
|
8284
|
+
? this.table()?.total || -1
|
|
8285
|
+
: this.table()?.count || -1;
|
|
8286
|
+
}, /* @ts-ignore */
|
|
8287
|
+
...(ngDevMode ? [{ debugName: "totalItems" }] : /* istanbul ignore next */ []));
|
|
8288
|
+
this.currentItems = computed(() => {
|
|
8289
|
+
return 'total' in (this.table() || {})
|
|
8290
|
+
? this.table()?.total || 0
|
|
8291
|
+
: this.table()?.count || 0;
|
|
8292
|
+
}, /* @ts-ignore */
|
|
8293
|
+
...(ngDevMode ? [{ debugName: "currentItems" }] : /* istanbul ignore next */ []));
|
|
8294
|
+
// Properties to allow the datagrid to work in standalone without weird hacks.
|
|
8295
|
+
this.data = input(null, /* @ts-ignore */
|
|
8296
|
+
...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
8297
|
+
this.name = input(null, /* @ts-ignore */
|
|
8298
|
+
...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
8299
|
+
this.primaryKey = input(null, /* @ts-ignore */
|
|
8300
|
+
...(ngDevMode ? [{ debugName: "primaryKey" }] : /* istanbul ignore next */ []));
|
|
8301
|
+
this.metadata = input(/* @ts-ignore */
|
|
8302
|
+
...(ngDevMode ? [undefined, { debugName: "metadata" }] : /* istanbul ignore next */ []));
|
|
8303
|
+
this.autoDataSource = null;
|
|
8304
|
+
this.onFilterValue = (columnName, value) => {
|
|
8305
|
+
if (this.allowFetchDistinctValues()) {
|
|
8306
|
+
this.onFilterValueChange.emit({
|
|
8307
|
+
column: columnName,
|
|
8308
|
+
value: value,
|
|
8309
|
+
});
|
|
8392
8310
|
}
|
|
8393
|
-
|
|
8394
|
-
|
|
8395
|
-
|
|
8396
|
-
|
|
8397
|
-
|
|
8398
|
-
|
|
8399
|
-
|
|
8400
|
-
|
|
8401
|
-
|
|
8402
|
-
|
|
8403
|
-
|
|
8404
|
-
|
|
8311
|
+
};
|
|
8312
|
+
this.onGroupByIncludedChange = (columnName, included) => {
|
|
8313
|
+
this.groupBy.update((currentGroup) => {
|
|
8314
|
+
if (currentGroup === null)
|
|
8315
|
+
return currentGroup;
|
|
8316
|
+
if (included) {
|
|
8317
|
+
currentGroup?.included.push(columnName);
|
|
8318
|
+
}
|
|
8319
|
+
else {
|
|
8320
|
+
currentGroup.included = currentGroup.included.filter((c) => c !== columnName);
|
|
8321
|
+
}
|
|
8322
|
+
return { ...currentGroup };
|
|
8405
8323
|
});
|
|
8406
|
-
|
|
8407
|
-
|
|
8408
|
-
|
|
8409
|
-
|
|
8410
|
-
|
|
8411
|
-
|
|
8412
|
-
|
|
8413
|
-
|
|
8414
|
-
|
|
8415
|
-
|
|
8416
|
-
|
|
8417
|
-
|
|
8418
|
-
|
|
8419
|
-
|
|
8420
|
-
|
|
8421
|
-
|
|
8422
|
-
|
|
8423
|
-
|
|
8424
|
-
|
|
8425
|
-
|
|
8426
|
-
|
|
8427
|
-
|
|
8428
|
-
|
|
8429
|
-
|
|
8430
|
-
|
|
8431
|
-
|
|
8432
|
-
|
|
8433
|
-
|
|
8434
|
-
|
|
8435
|
-
|
|
8436
|
-
|
|
8437
|
-
|
|
8438
|
-
|
|
8439
|
-
|
|
8440
|
-
|
|
8441
|
-
|
|
8442
|
-
|
|
8443
|
-
const componentSize = this.overlayRef?.overlayElement.getBoundingClientRect();
|
|
8444
|
-
switch (this.chrHoverPosition()) {
|
|
8445
|
-
case 'above':
|
|
8446
|
-
positionOffset.top -= (componentSize?.height || 0) + 20;
|
|
8447
|
-
positionOffset.left -= (componentSize?.width || 0) / 2;
|
|
8448
|
-
break;
|
|
8449
|
-
case 'below':
|
|
8450
|
-
positionOffset.top += 20;
|
|
8451
|
-
positionOffset.left -= (componentSize?.width || 0) / 2;
|
|
8452
|
-
break;
|
|
8453
|
-
case 'left':
|
|
8454
|
-
positionOffset.left -= (componentSize?.width || 0) + 20;
|
|
8455
|
-
positionOffset.top -= (componentSize?.height || 0) / 2;
|
|
8324
|
+
};
|
|
8325
|
+
this.onCellChange = (index, row, column, value) => {
|
|
8326
|
+
const initial = { ...row.data };
|
|
8327
|
+
row.data[column.columnName] = value;
|
|
8328
|
+
// If the row is created, we don't track it as modified
|
|
8329
|
+
switch (row.flag) {
|
|
8330
|
+
case 'added':
|
|
8331
|
+
this.addedRows.update((rows) => rows.map((r) => {
|
|
8332
|
+
if (this.table()?.getRowIdentifier(r.row) ===
|
|
8333
|
+
this.table()?.getRowIdentifier(row.data)) {
|
|
8334
|
+
r.row[column.columnName] = value;
|
|
8335
|
+
}
|
|
8336
|
+
return r;
|
|
8337
|
+
}));
|
|
8338
|
+
// this.addedRows.update((rows) => {
|
|
8339
|
+
// rows.find(
|
|
8340
|
+
// (r) =>
|
|
8341
|
+
// this.table()?.getRowIdentifier(r.row) ===
|
|
8342
|
+
// this.table()?.getRowIdentifier(row.data)
|
|
8343
|
+
// )!.row[column.columnName] = value;
|
|
8344
|
+
// return [...rows];
|
|
8345
|
+
// });
|
|
8346
|
+
return;
|
|
8347
|
+
case 'modified':
|
|
8348
|
+
this.modifiedRows.update((rows) => rows.map((r) => {
|
|
8349
|
+
if (r.index === index) {
|
|
8350
|
+
r.current = row.data;
|
|
8351
|
+
}
|
|
8352
|
+
return r;
|
|
8353
|
+
}));
|
|
8354
|
+
// this.modifiedRows.update((rows) => {
|
|
8355
|
+
// const changed = this.modifiedRows().find(
|
|
8356
|
+
// (modifiedRow) => modifiedRow.index === index
|
|
8357
|
+
// );
|
|
8358
|
+
// changed!.current = row.data;
|
|
8359
|
+
// return [...rows];
|
|
8360
|
+
// });
|
|
8456
8361
|
break;
|
|
8457
|
-
case '
|
|
8458
|
-
|
|
8459
|
-
|
|
8362
|
+
case 'unchanged':
|
|
8363
|
+
this.modifiedRows.set([
|
|
8364
|
+
...this.modifiedRows(),
|
|
8365
|
+
{ index: index, original: initial, current: row.data },
|
|
8366
|
+
]);
|
|
8460
8367
|
break;
|
|
8461
8368
|
}
|
|
8462
|
-
const positionStrategy = this.overlay
|
|
8463
|
-
.position()
|
|
8464
|
-
.global()
|
|
8465
|
-
.left(`${positionOffset.left}px`)
|
|
8466
|
-
.top(`${positionOffset.top}px`);
|
|
8467
|
-
return positionStrategy;
|
|
8468
8369
|
};
|
|
8469
|
-
this.
|
|
8470
|
-
|
|
8471
|
-
.
|
|
8472
|
-
.
|
|
8473
|
-
|
|
8474
|
-
|
|
8475
|
-
|
|
8476
|
-
|
|
8477
|
-
|
|
8478
|
-
|
|
8479
|
-
|
|
8480
|
-
|
|
8481
|
-
|
|
8482
|
-
|
|
8483
|
-
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
|
|
8492
|
-
|
|
8493
|
-
|
|
8494
|
-
|
|
8495
|
-
|
|
8496
|
-
|
|
8497
|
-
|
|
8498
|
-
|
|
8499
|
-
|
|
8500
|
-
|
|
8501
|
-
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
-
|
|
8370
|
+
this.addRow = () => {
|
|
8371
|
+
this.addedRows.set([
|
|
8372
|
+
...this.addedRows(),
|
|
8373
|
+
{ index: this.addedRows().length, row: {} },
|
|
8374
|
+
]);
|
|
8375
|
+
this.onAddRow.emit();
|
|
8376
|
+
};
|
|
8377
|
+
this.getRowTrackBy = (row, index) => {
|
|
8378
|
+
const table = this.table();
|
|
8379
|
+
// return table ? table.getRowIdentifier(row) : `row-${index}`;
|
|
8380
|
+
return table?.getRowNumber(row) ? table.getRowNumber(row) : index;
|
|
8381
|
+
};
|
|
8382
|
+
this.hasInvalidRows = () => {
|
|
8383
|
+
const allRows = [
|
|
8384
|
+
...this.addedRows().map((r) => r.row),
|
|
8385
|
+
...this.modifiedRows().map((r) => r.current),
|
|
8386
|
+
];
|
|
8387
|
+
return allRows.some((row) => !this.validateRow(row));
|
|
8388
|
+
};
|
|
8389
|
+
this.validateRow = (row) => {
|
|
8390
|
+
if (this.groupBy() !== null)
|
|
8391
|
+
return true;
|
|
8392
|
+
return this.formatterService.validateRow(row, this.columns());
|
|
8393
|
+
};
|
|
8394
|
+
this.canEdit = (column) => {
|
|
8395
|
+
const formatter = this.formatterService.getFormatter(null, column);
|
|
8396
|
+
if (!formatter)
|
|
8397
|
+
return false && this.allowUpdate();
|
|
8398
|
+
return this.allowUpdate() && formatter.canEdit(null, column);
|
|
8399
|
+
};
|
|
8400
|
+
this.isPrimaryKeyColumn = (column) => {
|
|
8401
|
+
const table = this.table();
|
|
8402
|
+
if (!table)
|
|
8403
|
+
return false;
|
|
8404
|
+
return table
|
|
8405
|
+
.primaryKeyColumns()
|
|
8406
|
+
.some((pk) => pk.columnName === column.columnName);
|
|
8407
|
+
};
|
|
8408
|
+
this.isUniqueKeyColumn = (column) => {
|
|
8409
|
+
const table = this.table();
|
|
8410
|
+
if (!table)
|
|
8411
|
+
return false;
|
|
8412
|
+
const uniqueConstraints = table.tableConstraints.filter((tc) => tc.constraintType === 'UNIQUE');
|
|
8413
|
+
for (const uc of uniqueConstraints) {
|
|
8414
|
+
if (uc.columns.some((col) => col.columnName === column.columnName)) {
|
|
8415
|
+
return true;
|
|
8416
|
+
}
|
|
8417
|
+
}
|
|
8418
|
+
return false;
|
|
8419
|
+
};
|
|
8420
|
+
this.isEditSafe = (column) => {
|
|
8421
|
+
if (this.groupBy() !== null)
|
|
8422
|
+
return false;
|
|
8423
|
+
if (this.trackByMode() === 'index')
|
|
8424
|
+
return true;
|
|
8425
|
+
if (this.crossRequestTrackingPersistence() === false)
|
|
8426
|
+
return true;
|
|
8427
|
+
return (this.trackByMode() === 'primaryKey' &&
|
|
8428
|
+
this.table()
|
|
8429
|
+
?.primaryKeyColumns()
|
|
8430
|
+
.some((pk) => pk.columnName === column.columnName) == false);
|
|
8431
|
+
};
|
|
8432
|
+
this.isForeignKeyColumn = (column) => {
|
|
8433
|
+
const table = this.table();
|
|
8434
|
+
if (!table)
|
|
8435
|
+
return false;
|
|
8436
|
+
const fkConstraints = table.tableConstraints.filter((tc) => tc.constraintType === 'FOREIGN KEY');
|
|
8437
|
+
for (const fk of fkConstraints) {
|
|
8438
|
+
if (fk.columns.some((col) => col.columnName === column.columnName)) {
|
|
8439
|
+
return true;
|
|
8440
|
+
}
|
|
8441
|
+
}
|
|
8442
|
+
return false;
|
|
8443
|
+
};
|
|
8444
|
+
this.datagridContextMenuActions = (column, filterElement, groupElement) => {
|
|
8445
|
+
const actions = [
|
|
8446
|
+
{
|
|
8447
|
+
label: 'Trier par ordre croissant',
|
|
8448
|
+
icon: 'arrow_upward',
|
|
8449
|
+
action: () => this.setSort(column, true),
|
|
8450
|
+
},
|
|
8451
|
+
{
|
|
8452
|
+
label: 'Trier par ordre décroissant',
|
|
8453
|
+
icon: 'arrow_downward',
|
|
8454
|
+
action: () => this.setSort(column, false),
|
|
8455
|
+
},
|
|
8456
|
+
{
|
|
8457
|
+
label: 'Effacer le tri',
|
|
8458
|
+
icon: 'clear',
|
|
8459
|
+
action: () => this.sort.set(null),
|
|
8460
|
+
},
|
|
8461
|
+
];
|
|
8462
|
+
if (filterElement && this.allowFiltering()) {
|
|
8463
|
+
actions.push({
|
|
8464
|
+
label: 'Filtrer sur cette colonne...',
|
|
8465
|
+
icon: 'filter_list',
|
|
8466
|
+
action: () => filterElement.toggle(),
|
|
8467
|
+
});
|
|
8468
|
+
}
|
|
8469
|
+
if (groupElement && this.allowGrouping()) {
|
|
8470
|
+
actions.push({
|
|
8471
|
+
label: 'Grouper par cette colonne',
|
|
8472
|
+
icon: 'group',
|
|
8473
|
+
action: () => groupElement.isOpen.set(true),
|
|
8474
|
+
});
|
|
8475
|
+
}
|
|
8476
|
+
return actions;
|
|
8477
|
+
};
|
|
8478
|
+
this.datarowContextMenuActions = (row, rowIndex) => {
|
|
8479
|
+
const items = [];
|
|
8480
|
+
for (const action of this.actions()) {
|
|
8481
|
+
items.push({
|
|
8482
|
+
label: action.display,
|
|
8483
|
+
action: action.callback.bind(null, row.data),
|
|
8484
|
+
color: action.color,
|
|
8485
|
+
icon: action.icon,
|
|
8486
|
+
});
|
|
8487
|
+
}
|
|
8488
|
+
switch (row.flag) {
|
|
8489
|
+
case 'deleted':
|
|
8490
|
+
items.push({
|
|
8491
|
+
label: 'Annuler la suppression',
|
|
8492
|
+
action: () => this.deletedRows.set(this.deletedRows().filter((r) => r.index !== rowIndex)),
|
|
8493
|
+
icon: 'undo',
|
|
8494
|
+
color: 'primary',
|
|
8495
|
+
});
|
|
8505
8496
|
break;
|
|
8506
|
-
case '
|
|
8507
|
-
|
|
8508
|
-
|
|
8509
|
-
|
|
8510
|
-
|
|
8511
|
-
|
|
8512
|
-
overlayY: 'center',
|
|
8513
|
-
},
|
|
8514
|
-
{
|
|
8515
|
-
originX: 'end',
|
|
8516
|
-
originY: 'center',
|
|
8517
|
-
overlayX: 'start',
|
|
8518
|
-
overlayY: 'center',
|
|
8497
|
+
case 'added':
|
|
8498
|
+
items.push({
|
|
8499
|
+
label: 'Supprimer la ligne ajoutée',
|
|
8500
|
+
action: () => {
|
|
8501
|
+
this.addedRows.update((rows) => rows.filter((r) => this.table().getRowIdentifier(r.row) !== row.id));
|
|
8502
|
+
this.table()?.removeRow(row);
|
|
8519
8503
|
},
|
|
8520
|
-
|
|
8504
|
+
icon: 'delete',
|
|
8505
|
+
color: 'error',
|
|
8506
|
+
});
|
|
8521
8507
|
break;
|
|
8522
|
-
|
|
8523
|
-
|
|
8524
|
-
{
|
|
8525
|
-
|
|
8526
|
-
|
|
8527
|
-
|
|
8528
|
-
|
|
8529
|
-
|
|
8530
|
-
|
|
8531
|
-
|
|
8532
|
-
|
|
8533
|
-
|
|
8534
|
-
|
|
8535
|
-
|
|
8536
|
-
|
|
8508
|
+
default:
|
|
8509
|
+
if (this.allowInsert() && this.allowDuplicate()) {
|
|
8510
|
+
items.push({
|
|
8511
|
+
label: 'Dupliquer la ligne',
|
|
8512
|
+
action: () => {
|
|
8513
|
+
const newRow = {
|
|
8514
|
+
[`${this.table()?.getRowIdentifier(row.data)}`]: this.addedRows().length + 1,
|
|
8515
|
+
...row.data,
|
|
8516
|
+
};
|
|
8517
|
+
this.addedRows.set([
|
|
8518
|
+
...this.addedRows(),
|
|
8519
|
+
{ index: this.addedRows().length, row: newRow },
|
|
8520
|
+
]);
|
|
8521
|
+
},
|
|
8522
|
+
icon: 'file_copy',
|
|
8523
|
+
color: 'primary',
|
|
8524
|
+
});
|
|
8525
|
+
}
|
|
8526
|
+
if (this.allowDelete()) {
|
|
8527
|
+
items.push({
|
|
8528
|
+
label: 'Supprimer la ligne',
|
|
8529
|
+
action: () => this.deleteRow(rowIndex, row.data),
|
|
8530
|
+
icon: 'delete',
|
|
8531
|
+
color: 'error',
|
|
8532
|
+
});
|
|
8533
|
+
}
|
|
8537
8534
|
break;
|
|
8538
8535
|
}
|
|
8539
|
-
return
|
|
8536
|
+
return items;
|
|
8540
8537
|
};
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
|
|
8544
|
-
|
|
8545
|
-
|
|
8546
|
-
|
|
8538
|
+
this.onAdd = () => {
|
|
8539
|
+
this.onAddRow.emit();
|
|
8540
|
+
setTimeout(() => {
|
|
8541
|
+
this.viewport()?.scrollTo({ bottom: 0 });
|
|
8542
|
+
}, 250);
|
|
8543
|
+
};
|
|
8544
|
+
this.log = (event) => {
|
|
8545
|
+
console.log(`[DataGrid-${this.id()}]`, event);
|
|
8546
|
+
};
|
|
8547
|
+
this.autoDataSource = new AutoDataSource({
|
|
8548
|
+
enableClientSideFiltering: true,
|
|
8549
|
+
enableClientSidePagination: true,
|
|
8550
|
+
enableClientSideSorting: true,
|
|
8551
|
+
pageSize: this.pageSize(),
|
|
8552
|
+
});
|
|
8553
|
+
effect(() => {
|
|
8554
|
+
if (this.table() && !this.crossRequestTrackingPersistence()) {
|
|
8555
|
+
this.resetChanges();
|
|
8556
|
+
}
|
|
8557
|
+
});
|
|
8558
|
+
effect(() => {
|
|
8559
|
+
const mode = this.table()?.hasPrimaryKey ? 'primaryKey' : 'index';
|
|
8560
|
+
this.trackByMode.set(mode);
|
|
8561
|
+
});
|
|
8562
|
+
effect(() => {
|
|
8563
|
+
const data = this.data();
|
|
8564
|
+
if (!data)
|
|
8565
|
+
return;
|
|
8566
|
+
if (this.table() === undefined || this.table() === null) {
|
|
8567
|
+
if (this.autoDataSource != null)
|
|
8568
|
+
this.autoDataSource.setRows(data);
|
|
8569
|
+
}
|
|
8547
8570
|
});
|
|
8548
8571
|
}
|
|
8549
8572
|
ngOnInit() {
|
|
8550
|
-
this.
|
|
8551
|
-
this.
|
|
8552
|
-
this.
|
|
8553
|
-
|
|
8554
|
-
|
|
8555
|
-
|
|
8556
|
-
this.startCloseTimeout();
|
|
8557
|
-
}));
|
|
8558
|
-
this.eventListeners.push(this.renderer.listen(this.el.nativeElement, 'mousemove', (event) => {
|
|
8559
|
-
if (!this.chrHoverSnap()) {
|
|
8560
|
-
const positionStrategy = this.mousePositionStrategy(event);
|
|
8561
|
-
this.overlayRef.updatePositionStrategy(positionStrategy);
|
|
8573
|
+
this.onInit.emit();
|
|
8574
|
+
if (this.table() === undefined || this.table() === null) {
|
|
8575
|
+
if (this.autoDataSource) {
|
|
8576
|
+
this.autoDataSource.setData(new AutoDataTable(this.name() ?? '', this.primaryKey(), this.metadata()));
|
|
8577
|
+
this.autoDataSource.registerDataGrid(this);
|
|
8578
|
+
this.autoDataSource.setRows(this.data() ?? []);
|
|
8562
8579
|
}
|
|
8563
|
-
}
|
|
8580
|
+
}
|
|
8564
8581
|
}
|
|
8565
|
-
ngOnDestroy() {
|
|
8566
|
-
|
|
8567
|
-
|
|
8568
|
-
this.overlayRef.dispose();
|
|
8569
|
-
this.removeEventListeners();
|
|
8582
|
+
ngOnDestroy() { }
|
|
8583
|
+
getColumnTooltip(column) {
|
|
8584
|
+
return column.tooltip;
|
|
8570
8585
|
}
|
|
8571
|
-
|
|
8572
|
-
this.
|
|
8573
|
-
|
|
8586
|
+
toggleSort(columnName) {
|
|
8587
|
+
const currentSort = this.sort();
|
|
8588
|
+
let isAsc = true;
|
|
8589
|
+
if (currentSort?.column === columnName)
|
|
8590
|
+
isAsc = !currentSort.isAsc;
|
|
8591
|
+
this.sort.set({ column: columnName, isAsc: isAsc });
|
|
8574
8592
|
}
|
|
8575
|
-
|
|
8576
|
-
this.
|
|
8577
|
-
this.closeTimeout = window.setTimeout(() => this.close(), this.chrHoverCloseDelay());
|
|
8593
|
+
setSort(columnName, isAsc) {
|
|
8594
|
+
this.sort.set({ column: columnName, isAsc: isAsc });
|
|
8578
8595
|
}
|
|
8579
|
-
|
|
8580
|
-
|
|
8581
|
-
|
|
8582
|
-
|
|
8596
|
+
onFilterBy(columnName, filter) {
|
|
8597
|
+
const currentFilters = { ...this.filter() };
|
|
8598
|
+
if (filter.value) {
|
|
8599
|
+
currentFilters[columnName] = {
|
|
8600
|
+
column: filter.column,
|
|
8601
|
+
mode: filter.mode,
|
|
8602
|
+
value: filter.value,
|
|
8603
|
+
};
|
|
8604
|
+
}
|
|
8605
|
+
else {
|
|
8606
|
+
delete currentFilters[columnName];
|
|
8607
|
+
}
|
|
8608
|
+
this.filter.set(currentFilters);
|
|
8609
|
+
}
|
|
8610
|
+
onGroupBy(group) {
|
|
8611
|
+
if (group.mode === null)
|
|
8612
|
+
this.groupBy.set(null);
|
|
8613
|
+
else {
|
|
8614
|
+
// group.included =
|
|
8615
|
+
// this.table()?.columnMetadatas.map((c) => c.columnName) || [];
|
|
8616
|
+
group.included = [group.column];
|
|
8617
|
+
this.groupBy.set(group);
|
|
8583
8618
|
}
|
|
8584
8619
|
}
|
|
8585
|
-
|
|
8586
|
-
|
|
8587
|
-
this.
|
|
8620
|
+
// Event handlers for pagination
|
|
8621
|
+
onPageChange(page) {
|
|
8622
|
+
this.currentPage.set(page);
|
|
8623
|
+
}
|
|
8624
|
+
onPageSizeChange(pageSize) {
|
|
8625
|
+
this.pageSize.set(pageSize);
|
|
8626
|
+
}
|
|
8627
|
+
refresh() {
|
|
8628
|
+
this.onRefresh.emit();
|
|
8629
|
+
// this.sort.set(null);
|
|
8630
|
+
// this.filter.set({});
|
|
8631
|
+
}
|
|
8632
|
+
getCellValue(row, columnName) {
|
|
8633
|
+
return row && row[columnName] !== undefined ? row[columnName] : '';
|
|
8634
|
+
}
|
|
8635
|
+
isRowAdded(row, index) {
|
|
8636
|
+
return this.addedRows().some((addedRow) => addedRow.index === index);
|
|
8588
8637
|
}
|
|
8589
|
-
|
|
8590
|
-
|
|
8591
|
-
if (!this.portal) {
|
|
8592
|
-
this.portal = new TemplatePortal(this.template, this.vcr, this.chrHoverContext());
|
|
8593
|
-
}
|
|
8594
|
-
const ref = this.overlayRef.attach(this.portal);
|
|
8595
|
-
// keep overlay open when overlay itself is hovered
|
|
8596
|
-
const overlayEl = this.overlayRef.overlayElement;
|
|
8597
|
-
this.clearOverlayListeners();
|
|
8598
|
-
this.overlayEventListeners.push(this.renderer.listen(overlayEl, 'mouseenter', () => {
|
|
8599
|
-
this.clearCloseTimeout();
|
|
8600
|
-
}));
|
|
8601
|
-
this.overlayEventListeners.push(this.renderer.listen(overlayEl, 'mouseleave', () => {
|
|
8602
|
-
this.startCloseTimeout();
|
|
8603
|
-
}));
|
|
8604
|
-
}
|
|
8638
|
+
isRowChanged(row, index) {
|
|
8639
|
+
return this.modifiedRows().some((modifiedRow) => modifiedRow.index === index);
|
|
8605
8640
|
}
|
|
8606
|
-
|
|
8607
|
-
this.
|
|
8608
|
-
this.clearOverlayListeners();
|
|
8609
|
-
this.overlayRef.detach();
|
|
8641
|
+
isCellChanged(rowIndex, columnName) {
|
|
8642
|
+
return this.modifiedCells().some((cell) => cell.rowIndex === rowIndex && cell.columnName === columnName);
|
|
8610
8643
|
}
|
|
8611
|
-
|
|
8612
|
-
|
|
8613
|
-
{
|
|
8614
|
-
provide: CDK_CONNECTED_OVERLAY_DEFAULT_CONFIG,
|
|
8615
|
-
useFactory: () => {
|
|
8616
|
-
disableClose: true;
|
|
8617
|
-
},
|
|
8618
|
-
},
|
|
8619
|
-
], ngImport: i0 }); }
|
|
8620
|
-
}
|
|
8621
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ChrHoverDirective, decorators: [{
|
|
8622
|
-
type: Directive,
|
|
8623
|
-
args: [{
|
|
8624
|
-
selector: '[chrHover]',
|
|
8625
|
-
providers: [
|
|
8626
|
-
{
|
|
8627
|
-
provide: CDK_CONNECTED_OVERLAY_DEFAULT_CONFIG,
|
|
8628
|
-
useFactory: () => {
|
|
8629
|
-
disableClose: true;
|
|
8630
|
-
},
|
|
8631
|
-
},
|
|
8632
|
-
],
|
|
8633
|
-
}]
|
|
8634
|
-
}], ctorParameters: () => [], propDecorators: { template: [{
|
|
8635
|
-
type: Input,
|
|
8636
|
-
args: ['chrHover']
|
|
8637
|
-
}], chrHoverContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "chrHoverContext", required: false }] }], chrHoverSnap: [{ type: i0.Input, args: [{ isSignal: true, alias: "chrHoverSnap", required: false }] }], chrHoverPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "chrHoverPosition", required: false }] }], chrHoverCloseDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "chrHoverCloseDelay", required: false }] }] } });
|
|
8638
|
-
|
|
8639
|
-
class CsvExporter {
|
|
8640
|
-
export(data, columns) {
|
|
8641
|
-
const csvRows = [];
|
|
8642
|
-
csvRows.push(columns.join(','));
|
|
8643
|
-
data.forEach((row) => {
|
|
8644
|
-
const values = columns.map((col) => {
|
|
8645
|
-
const cell = row[col];
|
|
8646
|
-
return typeof cell === 'string' ? cell.replace(/;/g, ',') : cell;
|
|
8647
|
-
});
|
|
8648
|
-
csvRows.push(values.join(','));
|
|
8649
|
-
});
|
|
8650
|
-
const csvContent = csvRows.join('\n');
|
|
8651
|
-
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
|
|
8652
|
-
return URL.createObjectURL(blob);
|
|
8644
|
+
isRowDeleted(row, index) {
|
|
8645
|
+
return this.deletedRows().some((deletedRow) => deletedRow.index === index);
|
|
8653
8646
|
}
|
|
8654
|
-
|
|
8655
|
-
|
|
8656
|
-
|
|
8647
|
+
deleteRow(index, row) {
|
|
8648
|
+
// If the row was modified, we need to get the original value and remove it from modifiedRows
|
|
8649
|
+
if (this.isRowChanged(row, index)) {
|
|
8650
|
+
const original = this.modifiedRows().find((modifiedRow) => modifiedRow.index === index)
|
|
8651
|
+
?.original || row;
|
|
8652
|
+
this.deletedRows.set([...this.deletedRows(), { index, row: original }]);
|
|
8653
|
+
this.modifiedRows.set(this.modifiedRows().filter((modifiedRow) => modifiedRow.index !== index));
|
|
8654
|
+
return;
|
|
8655
|
+
}
|
|
8656
|
+
// If the row was added, we just remove it from addedRows
|
|
8657
|
+
if (this.isRowAdded(row, index)) {
|
|
8658
|
+
this.addedRows.set(this.addedRows().filter((addedRow) => addedRow.index !== index));
|
|
8659
|
+
}
|
|
8660
|
+
if (!this.isRowDeleted(row, index)) {
|
|
8661
|
+
this.deletedRows.set([...this.deletedRows(), { index, row }]);
|
|
8662
|
+
}
|
|
8663
|
+
this.onDeleteRow.emit({ index, row });
|
|
8657
8664
|
}
|
|
8658
|
-
|
|
8659
|
-
|
|
8660
|
-
|
|
8661
|
-
|
|
8662
|
-
|
|
8663
|
-
|
|
8664
|
-
|
|
8665
|
-
|
|
8665
|
+
navigateToForeignTable(column) {
|
|
8666
|
+
if (!this.allowNavigation())
|
|
8667
|
+
return;
|
|
8668
|
+
if (column instanceof ColumnMetadata) {
|
|
8669
|
+
this.table()
|
|
8670
|
+
?.getConstraintsByType('FOREIGN KEY')
|
|
8671
|
+
.forEach((constraint) => {
|
|
8672
|
+
const cstCol = constraint.columns.find((c) => c.columnName === column.columnName);
|
|
8673
|
+
if (cstCol && cstCol instanceof TableConstraintColumn) {
|
|
8674
|
+
const reference = cstCol
|
|
8675
|
+
.reference;
|
|
8676
|
+
if (reference) {
|
|
8677
|
+
return this.onForeignTableNavigate.emit({
|
|
8678
|
+
targetTable: cstCol.reference.otherKey.tableName,
|
|
8679
|
+
targetSchema: cstCol.reference.otherKey.tableSchema,
|
|
8680
|
+
});
|
|
8681
|
+
}
|
|
8682
|
+
}
|
|
8666
8683
|
});
|
|
8667
|
-
|
|
8668
|
-
|
|
8669
|
-
|
|
8670
|
-
|
|
8671
|
-
});
|
|
8672
|
-
return URL.createObjectURL(blob);
|
|
8684
|
+
}
|
|
8685
|
+
else {
|
|
8686
|
+
this.onNavigate.emit({ targetColumnMetadata: column });
|
|
8687
|
+
}
|
|
8673
8688
|
}
|
|
8674
|
-
|
|
8675
|
-
|
|
8676
|
-
|
|
8689
|
+
resetChanges() {
|
|
8690
|
+
this.modifiedRows.set([]);
|
|
8691
|
+
this.addedRows.set([]);
|
|
8692
|
+
this.deletedRows.set([]);
|
|
8677
8693
|
}
|
|
8678
|
-
|
|
8679
|
-
|
|
8680
|
-
|
|
8681
|
-
|
|
8682
|
-
|
|
8694
|
+
getChangeSummary() {
|
|
8695
|
+
const modified = this.modifiedRows();
|
|
8696
|
+
const added = this.addedRows();
|
|
8697
|
+
const deleted = this.deletedRows();
|
|
8698
|
+
return {
|
|
8699
|
+
modified,
|
|
8700
|
+
added,
|
|
8701
|
+
deleted,
|
|
8702
|
+
hasChanges: modified.length > 0 || added.length > 0 || deleted.length > 0,
|
|
8703
|
+
};
|
|
8683
8704
|
}
|
|
8684
|
-
|
|
8685
|
-
|
|
8705
|
+
getCellTemplate(columnName, dataType) {
|
|
8706
|
+
const colMatch = this.templatesByColumn().get(columnName.toLowerCase());
|
|
8707
|
+
if (colMatch)
|
|
8708
|
+
return colMatch.template;
|
|
8709
|
+
const typeMatch = this.templatesByType().get(dataType.toLowerCase());
|
|
8710
|
+
if (typeMatch)
|
|
8711
|
+
return typeMatch.template;
|
|
8712
|
+
return null;
|
|
8686
8713
|
}
|
|
8687
|
-
|
|
8688
|
-
this.
|
|
8714
|
+
toggleCrossRequestTrackingPersistence() {
|
|
8715
|
+
this.crossRequestTrackingPersistence.set(!this.crossRequestTrackingPersistence());
|
|
8689
8716
|
}
|
|
8690
|
-
|
|
8691
|
-
|
|
8692
|
-
|
|
8693
|
-
|
|
8694
|
-
|
|
8695
|
-
|
|
8696
|
-
|
|
8697
|
-
|
|
8698
|
-
document.body.appendChild(link);
|
|
8699
|
-
link.click();
|
|
8700
|
-
document.body.removeChild(link);
|
|
8701
|
-
}
|
|
8702
|
-
return url;
|
|
8717
|
+
toggleAllowFetchDistinctValues() {
|
|
8718
|
+
this.allowFetchDistinctValues.set(!this.allowFetchDistinctValues());
|
|
8719
|
+
}
|
|
8720
|
+
onViewportScroll(event) {
|
|
8721
|
+
const viewport = event.target;
|
|
8722
|
+
const headerScrollElement = this.headerScroll()?.nativeElement;
|
|
8723
|
+
if (headerScrollElement) {
|
|
8724
|
+
headerScrollElement.scrollLeft = viewport.scrollLeft;
|
|
8703
8725
|
}
|
|
8704
|
-
return null;
|
|
8705
8726
|
}
|
|
8706
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type:
|
|
8707
|
-
static { this.ɵ
|
|
8727
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: DataGrid, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8728
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: DataGrid, isStandalone: true, selector: "chr-data-grid", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, table: { classPropertyName: "table", publicName: "table", isSignal: true, isRequired: false, transformFunction: null }, currentPage: { classPropertyName: "currentPage", publicName: "currentPage", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, sort: { classPropertyName: "sort", publicName: "sort", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, groupBy: { classPropertyName: "groupBy", publicName: "groupBy", isSignal: true, isRequired: false, transformFunction: null }, enableVirtualization: { classPropertyName: "enableVirtualization", publicName: "enableVirtualization", isSignal: true, isRequired: false, transformFunction: null }, allowFiltering: { classPropertyName: "allowFiltering", publicName: "allowFiltering", isSignal: true, isRequired: false, transformFunction: null }, allowGrouping: { classPropertyName: "allowGrouping", publicName: "allowGrouping", isSignal: true, isRequired: false, transformFunction: null }, allowInsert: { classPropertyName: "allowInsert", publicName: "allowInsert", isSignal: true, isRequired: false, transformFunction: null }, allowUpdate: { classPropertyName: "allowUpdate", publicName: "allowUpdate", isSignal: true, isRequired: false, transformFunction: null }, allowDelete: { classPropertyName: "allowDelete", publicName: "allowDelete", isSignal: true, isRequired: false, transformFunction: null }, allowDuplicate: { classPropertyName: "allowDuplicate", publicName: "allowDuplicate", isSignal: true, isRequired: false, transformFunction: null }, allowSync: { classPropertyName: "allowSync", publicName: "allowSync", isSignal: true, isRequired: false, transformFunction: null }, allowRefresh: { classPropertyName: "allowRefresh", publicName: "allowRefresh", isSignal: true, isRequired: false, transformFunction: null }, allowNavigation: { classPropertyName: "allowNavigation", publicName: "allowNavigation", isSignal: true, isRequired: false, transformFunction: null }, allowExport: { classPropertyName: "allowExport", publicName: "allowExport", isSignal: true, isRequired: false, transformFunction: null }, allowManageTrackingPersistence: { classPropertyName: "allowManageTrackingPersistence", publicName: "allowManageTrackingPersistence", isSignal: true, isRequired: false, transformFunction: null }, allowManageDistincValueFetching: { classPropertyName: "allowManageDistincValueFetching", publicName: "allowManageDistincValueFetching", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, allowFetchDistinctValues: { classPropertyName: "allowFetchDistinctValues", publicName: "allowFetchDistinctValues", isSignal: true, isRequired: false, transformFunction: null }, crossRequestTrackingPersistence: { classPropertyName: "crossRequestTrackingPersistence", publicName: "crossRequestTrackingPersistence", isSignal: true, isRequired: false, transformFunction: null }, modifiedCells: { classPropertyName: "modifiedCells", publicName: "modifiedCells", isSignal: true, isRequired: false, transformFunction: null }, modifiedRows: { classPropertyName: "modifiedRows", publicName: "modifiedRows", isSignal: true, isRequired: false, transformFunction: null }, addedRows: { classPropertyName: "addedRows", publicName: "addedRows", isSignal: true, isRequired: false, transformFunction: null }, deletedRows: { classPropertyName: "deletedRows", publicName: "deletedRows", isSignal: true, isRequired: false, transformFunction: null }, distinctValues: { classPropertyName: "distinctValues", publicName: "distinctValues", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, trackByMode: { classPropertyName: "trackByMode", publicName: "trackByMode", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, primaryKey: { classPropertyName: "primaryKey", publicName: "primaryKey", isSignal: true, isRequired: false, transformFunction: null }, metadata: { classPropertyName: "metadata", publicName: "metadata", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { table: "tableChange", currentPage: "currentPageChange", pageSize: "pageSizeChange", onInit: "onInit", sort: "sortChange", filter: "filterChange", groupBy: "groupByChange", cellChange: "cellChange", rowClick: "rowClick", onExport: "onExport", onSync: "onSync", onRefresh: "onRefresh", onAddRow: "onAddRow", onDeleteRow: "onDeleteRow", onForeignTableNavigate: "onForeignTableNavigate", onNavigate: "onNavigate", onFilterValueChange: "onFilterValueChange", allowFetchDistinctValues: "allowFetchDistinctValuesChange", crossRequestTrackingPersistence: "crossRequestTrackingPersistenceChange", modifiedCells: "modifiedCellsChange", modifiedRows: "modifiedRowsChange", addedRows: "addedRowsChange", deletedRows: "deletedRowsChange", trackByMode: "trackByModeChange" }, providers: [
|
|
8729
|
+
PaginationService,
|
|
8730
|
+
{
|
|
8731
|
+
provide: CHR_DEBOUNCE_DEFAULTS,
|
|
8732
|
+
useValue: new DebounceDefaults({ hoverTitle: 0 }),
|
|
8733
|
+
},
|
|
8734
|
+
// {
|
|
8735
|
+
// provide: VIRTUAL_SCROLL_STRATEGY,
|
|
8736
|
+
// useClass: DynamicSizeScrollStrategy,
|
|
8737
|
+
// },
|
|
8738
|
+
], queries: [{ propertyName: "cellTemplates", predicate: ChrCellDefDirective, isSignal: true }], viewQueries: [{ propertyName: "viewport", first: true, predicate: ["viewport"], descendants: true, isSignal: true }, { propertyName: "headerScroll", first: true, predicate: ["headerScroll"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (table()) {\r\n<div class=\"data-grid-container\">\r\n <div class=\"data-grid-header\">\r\n <h3>{{ title() ? title() : `${table()?.schema ? `${table()?.schema}.` : ''}${table()?.name}` }}</h3>\r\n @if(table()?.description){\r\n <span class=\"table-description\">{{ table()?.description }}</span>\r\n }\r\n <div class=\"data-grid-info\">\r\n <!-- {{allowSync()}} {{hasChanges()}} {{!hasInvalidRows()}} -->\r\n @if(allowManageDistincValueFetching()){\r\n <div>\r\n <span class=\"mat-icon icon-button tracking-persistence-button\"\r\n [attr.data-enabled]=\"allowFetchDistinctValues()\" (click)=\"toggleAllowFetchDistinctValues()\"\r\n title=\"R\u00E9cup\u00E9ration des valeurs distinctes d'une colonne lors du filtrage\">filter_list</span>\r\n </div>\r\n }\r\n @if (allowSync() && allowManageTrackingPersistence()) {\r\n <div>\r\n <span class=\"mat-icon icon-button tracking-persistence-button\"\r\n [attr.data-enabled]=\"crossRequestTrackingPersistence()\"\r\n (click)=\"toggleCrossRequestTrackingPersistence()\"\r\n title=\"Persistance du suivi des modifications entre les requ\u00EAtes\">track_changes</span>\r\n </div>\r\n }\r\n @if(allowSync() && hasChanges() && !hasInvalidRows()){\r\n <span class=\"mat-icon icon-button sync-button\" (click)=\"onSync.emit()\"\r\n title=\"Synchroniser les changements\">file_upload</span>\r\n }\r\n @if(allowRefresh()){\r\n <span class=\"mat-icon icon-button\" (click)=\"refresh()\" title=\"Recharger les donn\u00E9es\">refresh</span>\r\n }\r\n @if(allowInsert()){\r\n <span class=\"mat-icon icon-button\" (click)=\"onAdd()\" title=\"Ajouter une ligne\">add</span>\r\n }\r\n @if(allowExport()){\r\n <span class=\"mat-icon icon-button\" (click)=\"onExport.emit()\"\r\n title=\"T\u00E9l\u00E9charger les donn\u00E9es\">file_download</span>\r\n }\r\n @if(totalItems() !== -1){\r\n <span>Total: {{ totalItems() }} enregistrements</span>\r\n }\r\n </div>\r\n </div>\r\n <div class=\"grid-container data-grid-wrapper\"\r\n [style.grid-template-columns]=\"'repeat(' + columns().length + ', minmax(15rem, auto))'\"\r\n [style.max-height]=\"maxHeight()\" [style.overflow-y]=\"enableVirtualization() ? 'clip': 'auto'\">\r\n <div class=\"grid-header\" [style.column-span]=\"'all'\">\r\n @for (column of columns(); track column.columnName) {\r\n @let isForeignKey = isForeignKeyColumn(column);\r\n @let isPrimaryKey = isPrimaryKeyColumn(column);\r\n @let isComputedColumn = column.isGenerated;\r\n @let isUniqueColumn = isUniqueKeyColumn(column);\r\n <ng-container [ngTemplateOutlet]=\"headerTemplate\"\r\n [ngTemplateOutletContext]=\"{column: column, isForeignKey: isForeignKey, isPrimaryKey: isPrimaryKey, isComputedColumn: isComputedColumn, isUniqueColumn: isUniqueColumn}\"></ng-container>\r\n }\r\n </div>\r\n <div class=\"grid-body\">\r\n @if(enableVirtualization()){\r\n <cdk-virtual-scroll-viewport #viewport [itemSize]=\"41\" [style.height]=\"maxHeight()\" class=\"viewport\">\r\n <ng-container *cdkVirtualFor=\"let row of rows() | paginate: {itemsPerPage: pageSize(), currentPage: currentPage(), id:\r\n this.id(),\r\n totalItems: totalItems()}; let $index = index\" [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: row, index: getRowTrackBy(row.data, $index)}\">\r\n </ng-container>\r\n </cdk-virtual-scroll-viewport>\r\n } @else {\r\n @for (row of rows() | paginate: {itemsPerPage: pageSize(), currentPage: currentPage(), id:\r\n this.id(),\r\n totalItems: currentItems()};\r\n track getRowTrackBy(row.data, $index)) {\r\n <ng-container [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: row, index: getRowTrackBy(row.data, $index)}\">\r\n </ng-container>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n <ng-template #headerTemplate let-column=\"column\" let-isForeignKey=\"isForeignKey\" let-isPrimaryKey=\"isPrimaryKey\"\r\n let-isComputedColumn=\"isComputedColumn\" let-isUniqueColumn=\"isUniqueColumn\">\r\n <div class=\"grid-header-cell\" [attr.data-selected]=\"selectedColumn() === column.columnName\"\r\n [contextMenu]=\"datagridContextMenuActions(column.columnName, filterElement, groupElement)\"\r\n [title]=\"getColumnTooltip(column)\">\r\n @if(allowNavigation() && isForeignKey){\r\n <span ControlClick class=\"sort-receiver\" (click)=\"toggleSort(column.columnName)\"\r\n (ctrlClick)=\"navigateToForeignTable(column)\">{{ column.displayName || column.columnName\r\n }}</span>\r\n } @else {\r\n <span class=\"sort-receiver\" (click)=\"toggleSort(column.columnName)\">{{ column.displayName ||\r\n column.columnName\r\n }}</span>\r\n }\r\n <small class=\"sort-receiver column-type\" (click)=\"toggleSort(column.columnName)\">{{\r\n column.dataType }}\r\n {{column.length ?\r\n `(${column.length}${column.scale ? `, ${column.scale}` : ''})`: ''}}</small>\r\n <div class=\"column-icons\">\r\n @if(isUniqueColumn){\r\n <span class=\"mat-icon unique-key-icon\" title=\"Colonne avec contrainte d'unicit\u00E9\">looks_one</span>\r\n }\r\n @if(isPrimaryKey || isForeignKey){\r\n <span class=\"mat-icon\" [class.primary-key-icon]=\"isPrimaryKey\" [title]=\"'Colonne de la clef ' + (isPrimaryKey ?\r\n 'primaire' : '\u00E9trang\u00E8re')\" [class.key-icon]=\"isForeignKey\">key</span>\r\n }\r\n @if(allowSync() && (!canEdit(column) || !isEditSafe(column))){\r\n <span class=\"lock-icon mat-icon\" title=\"Colonne verrouill\u00E9e\">lock</span>\r\n }\r\n </div>\r\n @if (sort()?.column === column.columnName) {\r\n @if (sort()?.isAsc) {\r\n <span class=\"sort-icon mat-icon\" (click)=\"toggleSort(column.columnName)\">arrow_upward</span>\r\n } @else {\r\n <span class=\"sort-icon mat-icon\" (click)=\"toggleSort(column.columnName)\">arrow_downward</span>\r\n }\r\n }\r\n <div class=\"filter-group-controls\" #controls>\r\n <chr-column-filter #filterElement [class.hidden]=\"!allowFiltering()\" [by]=\"column.columnName\"\r\n [mode]=\"filter()[column.columnName]?.mode ?? null\" [attr.data-applied]=\"\"\r\n [value]=\"filter()[column.columnName]?.value ?? ''\" [columnMetadata]=\"column\"\r\n [suggestions]=\"columnSuggestions()[column.columnName]\"\r\n (valueChange)=\"onFilterValue(column.columnName, $event)\"\r\n (filterChange)=\"onFilterBy(column.columnName, $event)\" title=\"Double-clic pour d\u00E9finir un filtre\"\r\n class=\"filter\"></chr-column-filter>\r\n @let isGroupBySource = groupBy() == null || groupBy()?.column === column.columnName;\r\n <chr-column-group #groupElement [class.hidden]=\"!allowGrouping()\"\r\n [style.display]=\"!isGroupBySource ? 'none' : ''\" [by]=\"column.columnName\"\r\n [mode]=\"groupBy()?.mode ?? null\" (groupChange)=\"onGroupBy($event)\" class=\"group\"\r\n title=\"Double-clic pour d\u00E9finir un groupement\"></chr-column-group>\r\n @if(isComputedColumn){\r\n <span class=\"filter-icon mat-icon\" title=\"Colonne calcul\u00E9e\">functions</span>\r\n }@else if(!isGroupBySource && groupBy() !== null){\r\n <div class=\"group-by-include\" title=\"Inclure cette colonne dans le r\u00E9sultat group\u00E9\">\r\n <span class=\"mat-icon filter-icon disabled\">stack</span>\r\n <span class=\"toggle faded\">Inclure</span>\r\n <input #checkbox [checked]=\"groupByMap()[column.columnName]\"\r\n (change)=\"onGroupByIncludedChange(column.columnName, checkbox.checked)\"\r\n [name]=\"column.columnName+'-include'\" type=\"checkbox\" />\r\n </div>\r\n }\r\n\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #rowTemplate let-row let-index=\"index\">\r\n @let contextMenuItems = datarowContextMenuActions(row, index);\r\n <div #rowElement class=\"grid-row\"\r\n [style.grid-template-columns]=\"'repeat(' + columns().length + ', minmax(15rem, auto))'\"\r\n [attr.data-is-added]=\"row.flag === 'added'\" [scrollIntoView]=\"!row.valid\" [attr.data-is-valid]=\"row.valid\"\r\n (click)=\"rowClick.emit({ rowIndex: index, row: row.data, event: $event })\" [contextMenu]=\"contextMenuItems\"\r\n [attr.data-has-changed]=\"row.flag === 'modified'\" [attr.data-is-deleted]=\"row.flag === 'deleted'\">\r\n @for (column of columns(); track column.columnName) {\r\n <div class=\"grid-cell\" [attr.data-selected]=\"selectedColumn() === column.columnName\">\r\n <chr-editable-cell class=\"cell\" [value]=\"row.data[column.columnName]\" [row]=\"row.data\"\r\n [customTemplate]=\"getCellTemplate(column.columnName, column.dataType ?? 'varchar')\"\r\n (isEditingChange)=\"$event ? selectedColumn.set(column.columnName) : selectedColumn.set(null)\"\r\n (valueChange)=\"onCellChange(index, row, column, $event)\"\r\n [allowUpdate]=\"allowUpdate() && (isEditSafe(column)||row.flag === 'added') && row.flag !== 'deleted' && canEdit(column)\"\r\n [columnMetadata]=\"column\"></chr-editable-cell>\r\n @if($last){\r\n @if(actions().length > 0){\r\n <div class=\"actions-menu\">\r\n <span class=\"actions-menu-trigger mat-icon icon-button\" [style.cursor]=\"'pointer'\"\r\n [openOnClick]=\"true\" [contextMenu]=\"contextMenuItems\">more_vert</span>\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n <chr-paginator [id]=\"id()\" [page]=\"currentPage()\" [pageSize]=\"pageSize()\" (pageChange)=\"onPageChange($event)\"\r\n (pageSizeChange)=\"onPageSizeChange($event)\"></chr-paginator>\r\n</div>\r\n} @else {\r\n<div class=\"empty-state\">\r\n <p>Aucune donn\u00E9e</p>\r\n</div>\r\n}", styles: ["@import\"https://fonts.googleapis.com/css2?family=Material+Symbols:opsz,wght,FILL,GRAD@24,400,0,0\";@import\"https://fonts.googleapis.com/css2?family=Material+Icons\";.mat-icon:not(mat-icon),.material-symbols{font-family:Material Symbols;font-size:1.5rem;display:flex;align-items:center;justify-content:center}.mat-icon:not(mat-icon).small,.material-symbols.small{font-size:1rem}.mat-icon:not(mat-icon).large,.material-symbols.large{font-size:2rem}.hidden{display:none}.data-grid-wrapper{position:relative;display:grid!important;overflow:auto}.data-grid-container{background:inherit;border-radius:8px;box-shadow:0 2px 4px #0000001a;margin:1rem 0;--faded-text-color: color-mix( in srgb, var(--text-color) 40%, var(--background-color) 50% )}.data-grid-container .data-grid-header{border-top-left-radius:inherit;border-top-right-radius:inherit;background:var(--primary-color);padding:1rem 1.5rem;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:1rem}.data-grid-container .data-grid-header h3{margin:0;color:var(--primary-contrast-color);font-size:1.25rem;font-weight:600}.data-grid-container .data-grid-header .table-description{color:var(--primary-contrast-color);font-size:.875rem;font-style:italic}.data-grid-container .data-grid-header .data-grid-info{display:flex;align-items:center;gap:1rem;color:var(--text-color);font-size:.875rem}.data-grid-container .data-grid-header .data-grid-info span{background:var(--background-color);padding:.25rem .75rem;border-radius:1.25rem}.data-grid-container .data-grid-header .data-grid-info .sync-button{border:2px solid var(--warn-color);box-shadow:0 0 .5rem .15rem var(--warn-color)}.data-grid-container .data-grid-header .data-grid-info .sync-button:hover{background-color:var(--warn-color);color:var(--warn-contrast-color)}.data-grid-container .data-grid-header .data-grid-info .tracking-persistence-button{color:var(--success-contrast-color);background-color:var(--error-color)}.data-grid-container .data-grid-header .data-grid-info .tracking-persistence-button[data-enabled=true]{background-color:var(--success-color)}.data-grid-container .data-grid-header .data-grid-info .icon-button{cursor:pointer;padding:.1rem .25rem;font-size:1rem;transition:background-color .2s ease-in-out,color .2s ease-in-out}.data-grid-container .data-grid-header .data-grid-info .icon-button:hover{background-color:color-mix(in srgb,var(--background-color) 80%,var(--secondary-color) 80%);color:var(--secondary-contrast-color)}.data-grid-container .viewport{font-size:.875rem;scrollbar-width:none;grid-column:1/-1}.data-grid-container .viewport ::-webkit-scrollbar{display:none}.data-grid-container .viewport{-ms-overflow-style:none}.data-grid-container .grid-header,.data-grid-container .grid-body{display:grid;grid-template-columns:subgrid;grid-column:1/-1;font-size:.875rem}.data-grid-container .grid-row{display:grid!important;grid-column:1/-1}.data-grid-container .grid-header{position:sticky!important;top:0;z-index:10;background:color-mix(in srgb,var(--background-color) 80%,transparent 40%);-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);border-bottom:2px solid color-mix(in srgb,var(--text-color) 20%,var(--background-color) 90%)}.data-grid-container .grid-header-cell{position:relative;padding:.75rem 1rem;text-align:left;font-weight:600;color:color-mix(in srgb,var(--text-color) 90%,var(--background-color) 30%);-webkit-user-select:none;user-select:none}.data-grid-container .grid-header-cell .sort-receiver{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}.data-grid-container .grid-header-cell .sort-icon{position:absolute;right:.75rem;top:calc(50% - .75rem);font-size:1rem;color:var(--tertiary-color)}.data-grid-container .grid-header-cell .column-icons{position:absolute;right:.75rem;top:.5rem;display:flex;gap:.25rem;align-items:center}.data-grid-container .grid-header-cell .column-icons span,.data-grid-container .grid-header-cell .column-icons .mat-icon{font-size:1rem}.data-grid-container .grid-header-cell .primary-key-icon{color:var(--primary-color)}.data-grid-container .grid-header-cell .key-icon{color:var(--tertiary-color)}.data-grid-container .grid-header-cell .lock-icon{color:var(--warn-color)}.data-grid-container .grid-header-cell .column-type{font-weight:400;color:var(--faded-text-color);font-size:.75rem;text-transform:uppercase}.data-grid-container .grid-header-cell .filter-group-controls{display:flex;flex-direction:column;justify-content:center;gap:.25rem;width:calc(100% - .875rem)}.data-grid-container .grid-header-cell .group-by-include{display:flex;align-items:center;gap:.25rem;margin-top:.25rem;accent-color:var(--primary-color)}.data-grid-container .grid-header-cell .filter-icon{font-size:1rem}.data-grid-container .grid-row{border-bottom:1px solid color-mix(in srgb,var(--text-color) 20%,var(--background-color) 90%);transition:background-color .2s ease;position:relative}.data-grid-container .grid-row:nth-child(2n){background-color:color-mix(in srgb,var(--background-color) 90%,var(--neutral-color) 20%)}.data-grid-container .grid-row:after{content:\"\";position:absolute;left:0;top:0;bottom:0;width:.25rem;background-color:transparent}.data-grid-container .grid-row[data-is-deleted=true]{background-color:color-mix(in srgb,var(--background-color) 90%,var(--error-color) 20%)}.data-grid-container .grid-row[data-is-deleted=true]:after{background-color:var(--error-color)}.data-grid-container .grid-row[data-has-changed=true]{background-color:color-mix(in srgb,var(--background-color) 90%,var(--warn-color) 20%)}.data-grid-container .grid-row[data-has-changed=true]:after{background-color:var(--warn-color)}.data-grid-container .grid-row[data-is-added=true]{background-color:color-mix(in srgb,var(--background-color) 90%,var(--primary-color) 20%)}.data-grid-container .grid-row[data-is-added=true]:after{background-color:var(--primary-color)}.data-grid-container .grid-row[data-is-valid=false]{box-shadow:inset 0 0 .25rem var(--error-color)}.data-grid-container .grid-row:hover{background-color:var(--neutral-color)}.data-grid-container .grid-cell{position:relative;padding:.75rem 1rem;border-right:1px solid color-mix(in srgb,var(--background-color) 90%,var(--neutral-color) 20%)}.data-grid-container .grid-cell .cell{display:inline-block;min-width:100%;max-width:12rem}.data-grid-container .grid-cell .cell[data-changed=true]{font-weight:600;color:var(--warn-color)}.data-grid-container .grid-cell:last-child{border-right:none}.data-grid-container .grid-cell .actions-menu{position:absolute;right:0rem;top:50%;transform:translateY(-50%)}.data-grid-container .no-data-row{padding:2rem;text-align:center}.data-grid-container .no-data-row .no-data{color:var(--faded-text-color);font-style:italic}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ChrPaginatorComponent, selector: "app-chr-paginator,chr-paginator, chr-paginator", inputs: ["page", "pageSize", "id", "allowSizeChange", "allowPageEdit", "isPageEditing"], outputs: ["pageChange", "pageSizeChange", "isPageEditingChange"] }, { kind: "ngmodule", type: NgxPaginationModule }, { kind: "component", type: EditableCell, selector: "chr-editable-cell", inputs: ["allowUpdate", "customTemplate", "row", "value", "columnMetadata"], outputs: ["valueChange", "isEditingChange"] }, { kind: "directive", type: ContextMenuDirective, selector: "[contextMenu], [chrContextMenu], [chr-right-click]", inputs: ["contextMenu", "openOnClick"] }, { kind: "directive", type: ScrollIntoViewDirective, selector: "[scrollIntoView]", inputs: ["scrollIntoView"] }, { kind: "directive", type: ControlClickDirective, selector: "[CtrlClick], [ControlClick]", inputs: ["callback"], outputs: ["ctrlClick"] }, { kind: "component", type: ColumnFilter, selector: "chr-column-filter", inputs: ["isOpen", "by", "suggestions", "mode", "columnMetadata", "value"], outputs: ["isOpenChange", "modeChange", "valueChange", "filterChange"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1$1.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1$1.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1$1.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: ColumnGroup, selector: "chr-column-group", inputs: ["isOpen", "by", "mode"], outputs: ["isOpenChange", "modeChange", "groupChange"] }, { kind: "directive", type: ChrHoverTitleDirective, selector: "[chrTitle], [title]", inputs: ["chrTitle", "chrTitlePosition", "chrTitleSnap", "chrTitleDebounce"], outputs: ["chrTitleChange"] }, { kind: "pipe", type: i2.PaginatePipe, name: "paginate" }] }); }
|
|
8708
8739
|
}
|
|
8709
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type:
|
|
8710
|
-
type:
|
|
8711
|
-
args: [{
|
|
8712
|
-
|
|
8713
|
-
|
|
8714
|
-
|
|
8740
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: DataGrid, decorators: [{
|
|
8741
|
+
type: Component,
|
|
8742
|
+
args: [{ selector: 'chr-data-grid', imports: [
|
|
8743
|
+
CommonModule,
|
|
8744
|
+
ChrPaginatorComponent,
|
|
8745
|
+
NgxPaginationModule,
|
|
8746
|
+
EditableCell,
|
|
8747
|
+
ContextMenuDirective,
|
|
8748
|
+
ScrollIntoViewDirective,
|
|
8749
|
+
ControlClickDirective,
|
|
8750
|
+
ColumnFilter,
|
|
8751
|
+
ScrollingModule,
|
|
8752
|
+
ColumnGroup,
|
|
8753
|
+
ChrHoverTitleDirective,
|
|
8754
|
+
], providers: [
|
|
8755
|
+
PaginationService,
|
|
8756
|
+
{
|
|
8757
|
+
provide: CHR_DEBOUNCE_DEFAULTS,
|
|
8758
|
+
useValue: new DebounceDefaults({ hoverTitle: 0 }),
|
|
8759
|
+
},
|
|
8760
|
+
// {
|
|
8761
|
+
// provide: VIRTUAL_SCROLL_STRATEGY,
|
|
8762
|
+
// useClass: DynamicSizeScrollStrategy,
|
|
8763
|
+
// },
|
|
8764
|
+
], template: "@if (table()) {\r\n<div class=\"data-grid-container\">\r\n <div class=\"data-grid-header\">\r\n <h3>{{ title() ? title() : `${table()?.schema ? `${table()?.schema}.` : ''}${table()?.name}` }}</h3>\r\n @if(table()?.description){\r\n <span class=\"table-description\">{{ table()?.description }}</span>\r\n }\r\n <div class=\"data-grid-info\">\r\n <!-- {{allowSync()}} {{hasChanges()}} {{!hasInvalidRows()}} -->\r\n @if(allowManageDistincValueFetching()){\r\n <div>\r\n <span class=\"mat-icon icon-button tracking-persistence-button\"\r\n [attr.data-enabled]=\"allowFetchDistinctValues()\" (click)=\"toggleAllowFetchDistinctValues()\"\r\n title=\"R\u00E9cup\u00E9ration des valeurs distinctes d'une colonne lors du filtrage\">filter_list</span>\r\n </div>\r\n }\r\n @if (allowSync() && allowManageTrackingPersistence()) {\r\n <div>\r\n <span class=\"mat-icon icon-button tracking-persistence-button\"\r\n [attr.data-enabled]=\"crossRequestTrackingPersistence()\"\r\n (click)=\"toggleCrossRequestTrackingPersistence()\"\r\n title=\"Persistance du suivi des modifications entre les requ\u00EAtes\">track_changes</span>\r\n </div>\r\n }\r\n @if(allowSync() && hasChanges() && !hasInvalidRows()){\r\n <span class=\"mat-icon icon-button sync-button\" (click)=\"onSync.emit()\"\r\n title=\"Synchroniser les changements\">file_upload</span>\r\n }\r\n @if(allowRefresh()){\r\n <span class=\"mat-icon icon-button\" (click)=\"refresh()\" title=\"Recharger les donn\u00E9es\">refresh</span>\r\n }\r\n @if(allowInsert()){\r\n <span class=\"mat-icon icon-button\" (click)=\"onAdd()\" title=\"Ajouter une ligne\">add</span>\r\n }\r\n @if(allowExport()){\r\n <span class=\"mat-icon icon-button\" (click)=\"onExport.emit()\"\r\n title=\"T\u00E9l\u00E9charger les donn\u00E9es\">file_download</span>\r\n }\r\n @if(totalItems() !== -1){\r\n <span>Total: {{ totalItems() }} enregistrements</span>\r\n }\r\n </div>\r\n </div>\r\n <div class=\"grid-container data-grid-wrapper\"\r\n [style.grid-template-columns]=\"'repeat(' + columns().length + ', minmax(15rem, auto))'\"\r\n [style.max-height]=\"maxHeight()\" [style.overflow-y]=\"enableVirtualization() ? 'clip': 'auto'\">\r\n <div class=\"grid-header\" [style.column-span]=\"'all'\">\r\n @for (column of columns(); track column.columnName) {\r\n @let isForeignKey = isForeignKeyColumn(column);\r\n @let isPrimaryKey = isPrimaryKeyColumn(column);\r\n @let isComputedColumn = column.isGenerated;\r\n @let isUniqueColumn = isUniqueKeyColumn(column);\r\n <ng-container [ngTemplateOutlet]=\"headerTemplate\"\r\n [ngTemplateOutletContext]=\"{column: column, isForeignKey: isForeignKey, isPrimaryKey: isPrimaryKey, isComputedColumn: isComputedColumn, isUniqueColumn: isUniqueColumn}\"></ng-container>\r\n }\r\n </div>\r\n <div class=\"grid-body\">\r\n @if(enableVirtualization()){\r\n <cdk-virtual-scroll-viewport #viewport [itemSize]=\"41\" [style.height]=\"maxHeight()\" class=\"viewport\">\r\n <ng-container *cdkVirtualFor=\"let row of rows() | paginate: {itemsPerPage: pageSize(), currentPage: currentPage(), id:\r\n this.id(),\r\n totalItems: totalItems()}; let $index = index\" [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: row, index: getRowTrackBy(row.data, $index)}\">\r\n </ng-container>\r\n </cdk-virtual-scroll-viewport>\r\n } @else {\r\n @for (row of rows() | paginate: {itemsPerPage: pageSize(), currentPage: currentPage(), id:\r\n this.id(),\r\n totalItems: currentItems()};\r\n track getRowTrackBy(row.data, $index)) {\r\n <ng-container [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{$implicit: row, index: getRowTrackBy(row.data, $index)}\">\r\n </ng-container>\r\n }\r\n }\r\n </div>\r\n </div>\r\n\r\n <ng-template #headerTemplate let-column=\"column\" let-isForeignKey=\"isForeignKey\" let-isPrimaryKey=\"isPrimaryKey\"\r\n let-isComputedColumn=\"isComputedColumn\" let-isUniqueColumn=\"isUniqueColumn\">\r\n <div class=\"grid-header-cell\" [attr.data-selected]=\"selectedColumn() === column.columnName\"\r\n [contextMenu]=\"datagridContextMenuActions(column.columnName, filterElement, groupElement)\"\r\n [title]=\"getColumnTooltip(column)\">\r\n @if(allowNavigation() && isForeignKey){\r\n <span ControlClick class=\"sort-receiver\" (click)=\"toggleSort(column.columnName)\"\r\n (ctrlClick)=\"navigateToForeignTable(column)\">{{ column.displayName || column.columnName\r\n }}</span>\r\n } @else {\r\n <span class=\"sort-receiver\" (click)=\"toggleSort(column.columnName)\">{{ column.displayName ||\r\n column.columnName\r\n }}</span>\r\n }\r\n <small class=\"sort-receiver column-type\" (click)=\"toggleSort(column.columnName)\">{{\r\n column.dataType }}\r\n {{column.length ?\r\n `(${column.length}${column.scale ? `, ${column.scale}` : ''})`: ''}}</small>\r\n <div class=\"column-icons\">\r\n @if(isUniqueColumn){\r\n <span class=\"mat-icon unique-key-icon\" title=\"Colonne avec contrainte d'unicit\u00E9\">looks_one</span>\r\n }\r\n @if(isPrimaryKey || isForeignKey){\r\n <span class=\"mat-icon\" [class.primary-key-icon]=\"isPrimaryKey\" [title]=\"'Colonne de la clef ' + (isPrimaryKey ?\r\n 'primaire' : '\u00E9trang\u00E8re')\" [class.key-icon]=\"isForeignKey\">key</span>\r\n }\r\n @if(allowSync() && (!canEdit(column) || !isEditSafe(column))){\r\n <span class=\"lock-icon mat-icon\" title=\"Colonne verrouill\u00E9e\">lock</span>\r\n }\r\n </div>\r\n @if (sort()?.column === column.columnName) {\r\n @if (sort()?.isAsc) {\r\n <span class=\"sort-icon mat-icon\" (click)=\"toggleSort(column.columnName)\">arrow_upward</span>\r\n } @else {\r\n <span class=\"sort-icon mat-icon\" (click)=\"toggleSort(column.columnName)\">arrow_downward</span>\r\n }\r\n }\r\n <div class=\"filter-group-controls\" #controls>\r\n <chr-column-filter #filterElement [class.hidden]=\"!allowFiltering()\" [by]=\"column.columnName\"\r\n [mode]=\"filter()[column.columnName]?.mode ?? null\" [attr.data-applied]=\"\"\r\n [value]=\"filter()[column.columnName]?.value ?? ''\" [columnMetadata]=\"column\"\r\n [suggestions]=\"columnSuggestions()[column.columnName]\"\r\n (valueChange)=\"onFilterValue(column.columnName, $event)\"\r\n (filterChange)=\"onFilterBy(column.columnName, $event)\" title=\"Double-clic pour d\u00E9finir un filtre\"\r\n class=\"filter\"></chr-column-filter>\r\n @let isGroupBySource = groupBy() == null || groupBy()?.column === column.columnName;\r\n <chr-column-group #groupElement [class.hidden]=\"!allowGrouping()\"\r\n [style.display]=\"!isGroupBySource ? 'none' : ''\" [by]=\"column.columnName\"\r\n [mode]=\"groupBy()?.mode ?? null\" (groupChange)=\"onGroupBy($event)\" class=\"group\"\r\n title=\"Double-clic pour d\u00E9finir un groupement\"></chr-column-group>\r\n @if(isComputedColumn){\r\n <span class=\"filter-icon mat-icon\" title=\"Colonne calcul\u00E9e\">functions</span>\r\n }@else if(!isGroupBySource && groupBy() !== null){\r\n <div class=\"group-by-include\" title=\"Inclure cette colonne dans le r\u00E9sultat group\u00E9\">\r\n <span class=\"mat-icon filter-icon disabled\">stack</span>\r\n <span class=\"toggle faded\">Inclure</span>\r\n <input #checkbox [checked]=\"groupByMap()[column.columnName]\"\r\n (change)=\"onGroupByIncludedChange(column.columnName, checkbox.checked)\"\r\n [name]=\"column.columnName+'-include'\" type=\"checkbox\" />\r\n </div>\r\n }\r\n\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #rowTemplate let-row let-index=\"index\">\r\n @let contextMenuItems = datarowContextMenuActions(row, index);\r\n <div #rowElement class=\"grid-row\"\r\n [style.grid-template-columns]=\"'repeat(' + columns().length + ', minmax(15rem, auto))'\"\r\n [attr.data-is-added]=\"row.flag === 'added'\" [scrollIntoView]=\"!row.valid\" [attr.data-is-valid]=\"row.valid\"\r\n (click)=\"rowClick.emit({ rowIndex: index, row: row.data, event: $event })\" [contextMenu]=\"contextMenuItems\"\r\n [attr.data-has-changed]=\"row.flag === 'modified'\" [attr.data-is-deleted]=\"row.flag === 'deleted'\">\r\n @for (column of columns(); track column.columnName) {\r\n <div class=\"grid-cell\" [attr.data-selected]=\"selectedColumn() === column.columnName\">\r\n <chr-editable-cell class=\"cell\" [value]=\"row.data[column.columnName]\" [row]=\"row.data\"\r\n [customTemplate]=\"getCellTemplate(column.columnName, column.dataType ?? 'varchar')\"\r\n (isEditingChange)=\"$event ? selectedColumn.set(column.columnName) : selectedColumn.set(null)\"\r\n (valueChange)=\"onCellChange(index, row, column, $event)\"\r\n [allowUpdate]=\"allowUpdate() && (isEditSafe(column)||row.flag === 'added') && row.flag !== 'deleted' && canEdit(column)\"\r\n [columnMetadata]=\"column\"></chr-editable-cell>\r\n @if($last){\r\n @if(actions().length > 0){\r\n <div class=\"actions-menu\">\r\n <span class=\"actions-menu-trigger mat-icon icon-button\" [style.cursor]=\"'pointer'\"\r\n [openOnClick]=\"true\" [contextMenu]=\"contextMenuItems\">more_vert</span>\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n <chr-paginator [id]=\"id()\" [page]=\"currentPage()\" [pageSize]=\"pageSize()\" (pageChange)=\"onPageChange($event)\"\r\n (pageSizeChange)=\"onPageSizeChange($event)\"></chr-paginator>\r\n</div>\r\n} @else {\r\n<div class=\"empty-state\">\r\n <p>Aucune donn\u00E9e</p>\r\n</div>\r\n}", styles: ["@import\"https://fonts.googleapis.com/css2?family=Material+Symbols:opsz,wght,FILL,GRAD@24,400,0,0\";@import\"https://fonts.googleapis.com/css2?family=Material+Icons\";.mat-icon:not(mat-icon),.material-symbols{font-family:Material Symbols;font-size:1.5rem;display:flex;align-items:center;justify-content:center}.mat-icon:not(mat-icon).small,.material-symbols.small{font-size:1rem}.mat-icon:not(mat-icon).large,.material-symbols.large{font-size:2rem}.hidden{display:none}.data-grid-wrapper{position:relative;display:grid!important;overflow:auto}.data-grid-container{background:inherit;border-radius:8px;box-shadow:0 2px 4px #0000001a;margin:1rem 0;--faded-text-color: color-mix( in srgb, var(--text-color) 40%, var(--background-color) 50% )}.data-grid-container .data-grid-header{border-top-left-radius:inherit;border-top-right-radius:inherit;background:var(--primary-color);padding:1rem 1.5rem;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:1rem}.data-grid-container .data-grid-header h3{margin:0;color:var(--primary-contrast-color);font-size:1.25rem;font-weight:600}.data-grid-container .data-grid-header .table-description{color:var(--primary-contrast-color);font-size:.875rem;font-style:italic}.data-grid-container .data-grid-header .data-grid-info{display:flex;align-items:center;gap:1rem;color:var(--text-color);font-size:.875rem}.data-grid-container .data-grid-header .data-grid-info span{background:var(--background-color);padding:.25rem .75rem;border-radius:1.25rem}.data-grid-container .data-grid-header .data-grid-info .sync-button{border:2px solid var(--warn-color);box-shadow:0 0 .5rem .15rem var(--warn-color)}.data-grid-container .data-grid-header .data-grid-info .sync-button:hover{background-color:var(--warn-color);color:var(--warn-contrast-color)}.data-grid-container .data-grid-header .data-grid-info .tracking-persistence-button{color:var(--success-contrast-color);background-color:var(--error-color)}.data-grid-container .data-grid-header .data-grid-info .tracking-persistence-button[data-enabled=true]{background-color:var(--success-color)}.data-grid-container .data-grid-header .data-grid-info .icon-button{cursor:pointer;padding:.1rem .25rem;font-size:1rem;transition:background-color .2s ease-in-out,color .2s ease-in-out}.data-grid-container .data-grid-header .data-grid-info .icon-button:hover{background-color:color-mix(in srgb,var(--background-color) 80%,var(--secondary-color) 80%);color:var(--secondary-contrast-color)}.data-grid-container .viewport{font-size:.875rem;scrollbar-width:none;grid-column:1/-1}.data-grid-container .viewport ::-webkit-scrollbar{display:none}.data-grid-container .viewport{-ms-overflow-style:none}.data-grid-container .grid-header,.data-grid-container .grid-body{display:grid;grid-template-columns:subgrid;grid-column:1/-1;font-size:.875rem}.data-grid-container .grid-row{display:grid!important;grid-column:1/-1}.data-grid-container .grid-header{position:sticky!important;top:0;z-index:10;background:color-mix(in srgb,var(--background-color) 80%,transparent 40%);-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);border-bottom:2px solid color-mix(in srgb,var(--text-color) 20%,var(--background-color) 90%)}.data-grid-container .grid-header-cell{position:relative;padding:.75rem 1rem;text-align:left;font-weight:600;color:color-mix(in srgb,var(--text-color) 90%,var(--background-color) 30%);-webkit-user-select:none;user-select:none}.data-grid-container .grid-header-cell .sort-receiver{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}.data-grid-container .grid-header-cell .sort-icon{position:absolute;right:.75rem;top:calc(50% - .75rem);font-size:1rem;color:var(--tertiary-color)}.data-grid-container .grid-header-cell .column-icons{position:absolute;right:.75rem;top:.5rem;display:flex;gap:.25rem;align-items:center}.data-grid-container .grid-header-cell .column-icons span,.data-grid-container .grid-header-cell .column-icons .mat-icon{font-size:1rem}.data-grid-container .grid-header-cell .primary-key-icon{color:var(--primary-color)}.data-grid-container .grid-header-cell .key-icon{color:var(--tertiary-color)}.data-grid-container .grid-header-cell .lock-icon{color:var(--warn-color)}.data-grid-container .grid-header-cell .column-type{font-weight:400;color:var(--faded-text-color);font-size:.75rem;text-transform:uppercase}.data-grid-container .grid-header-cell .filter-group-controls{display:flex;flex-direction:column;justify-content:center;gap:.25rem;width:calc(100% - .875rem)}.data-grid-container .grid-header-cell .group-by-include{display:flex;align-items:center;gap:.25rem;margin-top:.25rem;accent-color:var(--primary-color)}.data-grid-container .grid-header-cell .filter-icon{font-size:1rem}.data-grid-container .grid-row{border-bottom:1px solid color-mix(in srgb,var(--text-color) 20%,var(--background-color) 90%);transition:background-color .2s ease;position:relative}.data-grid-container .grid-row:nth-child(2n){background-color:color-mix(in srgb,var(--background-color) 90%,var(--neutral-color) 20%)}.data-grid-container .grid-row:after{content:\"\";position:absolute;left:0;top:0;bottom:0;width:.25rem;background-color:transparent}.data-grid-container .grid-row[data-is-deleted=true]{background-color:color-mix(in srgb,var(--background-color) 90%,var(--error-color) 20%)}.data-grid-container .grid-row[data-is-deleted=true]:after{background-color:var(--error-color)}.data-grid-container .grid-row[data-has-changed=true]{background-color:color-mix(in srgb,var(--background-color) 90%,var(--warn-color) 20%)}.data-grid-container .grid-row[data-has-changed=true]:after{background-color:var(--warn-color)}.data-grid-container .grid-row[data-is-added=true]{background-color:color-mix(in srgb,var(--background-color) 90%,var(--primary-color) 20%)}.data-grid-container .grid-row[data-is-added=true]:after{background-color:var(--primary-color)}.data-grid-container .grid-row[data-is-valid=false]{box-shadow:inset 0 0 .25rem var(--error-color)}.data-grid-container .grid-row:hover{background-color:var(--neutral-color)}.data-grid-container .grid-cell{position:relative;padding:.75rem 1rem;border-right:1px solid color-mix(in srgb,var(--background-color) 90%,var(--neutral-color) 20%)}.data-grid-container .grid-cell .cell{display:inline-block;min-width:100%;max-width:12rem}.data-grid-container .grid-cell .cell[data-changed=true]{font-weight:600;color:var(--warn-color)}.data-grid-container .grid-cell:last-child{border-right:none}.data-grid-container .grid-cell .actions-menu{position:absolute;right:0rem;top:50%;transform:translateY(-50%)}.data-grid-container .no-data-row{padding:2rem;text-align:center}.data-grid-container .no-data-row .no-data{color:var(--faded-text-color);font-style:italic}\n"] }]
|
|
8765
|
+
}], ctorParameters: () => [], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], table: [{ type: i0.Input, args: [{ isSignal: true, alias: "table", required: false }] }, { type: i0.Output, args: ["tableChange"] }], viewport: [{ type: i0.ViewChild, args: ['viewport', { isSignal: true }] }], headerScroll: [{ type: i0.ViewChild, args: ['headerScroll', { isSignal: true }] }], currentPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentPage", required: false }] }, { type: i0.Output, args: ["currentPageChange"] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }, { type: i0.Output, args: ["pageSizeChange"] }], onInit: [{ type: i0.Output, args: ["onInit"] }], sort: [{ type: i0.Input, args: [{ isSignal: true, alias: "sort", required: false }] }, { type: i0.Output, args: ["sortChange"] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }, { type: i0.Output, args: ["filterChange"] }], groupBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupBy", required: false }] }, { type: i0.Output, args: ["groupByChange"] }], cellChange: [{ type: i0.Output, args: ["cellChange"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], enableVirtualization: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableVirtualization", required: false }] }], allowFiltering: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowFiltering", required: false }] }], allowGrouping: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowGrouping", required: false }] }], allowInsert: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowInsert", required: false }] }], allowUpdate: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowUpdate", required: false }] }], allowDelete: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowDelete", required: false }] }], allowDuplicate: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowDuplicate", required: false }] }], allowSync: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowSync", required: false }] }], allowRefresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowRefresh", required: false }] }], allowNavigation: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowNavigation", required: false }] }], allowExport: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowExport", required: false }] }], allowManageTrackingPersistence: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowManageTrackingPersistence", required: false }] }], allowManageDistincValueFetching: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowManageDistincValueFetching", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], onExport: [{ type: i0.Output, args: ["onExport"] }], onSync: [{ type: i0.Output, args: ["onSync"] }], onRefresh: [{ type: i0.Output, args: ["onRefresh"] }], onAddRow: [{ type: i0.Output, args: ["onAddRow"] }], onDeleteRow: [{ type: i0.Output, args: ["onDeleteRow"] }], onForeignTableNavigate: [{ type: i0.Output, args: ["onForeignTableNavigate"] }], onNavigate: [{ type: i0.Output, args: ["onNavigate"] }], onFilterValueChange: [{ type: i0.Output, args: ["onFilterValueChange"] }], allowFetchDistinctValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowFetchDistinctValues", required: false }] }, { type: i0.Output, args: ["allowFetchDistinctValuesChange"] }], crossRequestTrackingPersistence: [{ type: i0.Input, args: [{ isSignal: true, alias: "crossRequestTrackingPersistence", required: false }] }, { type: i0.Output, args: ["crossRequestTrackingPersistenceChange"] }], modifiedCells: [{ type: i0.Input, args: [{ isSignal: true, alias: "modifiedCells", required: false }] }, { type: i0.Output, args: ["modifiedCellsChange"] }], modifiedRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "modifiedRows", required: false }] }, { type: i0.Output, args: ["modifiedRowsChange"] }], addedRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "addedRows", required: false }] }, { type: i0.Output, args: ["addedRowsChange"] }], deletedRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "deletedRows", required: false }] }, { type: i0.Output, args: ["deletedRowsChange"] }], distinctValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "distinctValues", required: false }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], cellTemplates: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => ChrCellDefDirective), { isSignal: true }] }], trackByMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackByMode", required: false }] }, { type: i0.Output, args: ["trackByModeChange"] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], primaryKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryKey", required: false }] }], metadata: [{ type: i0.Input, args: [{ isSignal: true, alias: "metadata", required: false }] }] } });
|
|
8715
8766
|
|
|
8716
|
-
class
|
|
8717
|
-
constructor(
|
|
8718
|
-
this.
|
|
8719
|
-
|
|
8767
|
+
class MessageBanner {
|
|
8768
|
+
constructor() {
|
|
8769
|
+
this.isVisible = signal(true, /* @ts-ignore */
|
|
8770
|
+
...(ngDevMode ? [{ debugName: "isVisible" }] : /* istanbul ignore next */ []));
|
|
8771
|
+
this.closable = input(false, /* @ts-ignore */
|
|
8772
|
+
...(ngDevMode ? [{ debugName: "closable" }] : /* istanbul ignore next */ []));
|
|
8773
|
+
this.title = input(null, /* @ts-ignore */
|
|
8774
|
+
...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
8775
|
+
this.icon = input(null, /* @ts-ignore */
|
|
8776
|
+
...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
8777
|
+
this.message = input(/* @ts-ignore */
|
|
8778
|
+
...(ngDevMode ? [undefined, { debugName: "message" }] : /* istanbul ignore next */ []));
|
|
8779
|
+
this.type = input('none', /* @ts-ignore */
|
|
8780
|
+
...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
8781
|
+
this.close = () => {
|
|
8782
|
+
this.isVisible.set(false);
|
|
8783
|
+
};
|
|
8720
8784
|
}
|
|
8785
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MessageBanner, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8786
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: MessageBanner, isStandalone: true, selector: "chr-message-banner", inputs: { closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if(isVisible()){\r\n<div class=\"message-banner\" [attr.data-type]=\"type()\">\r\n <div class=\"banner-header\">\r\n @if(icon()){\r\n <span class=\"mat-icon material-symbols banner-icon\" [attr.data-icon]=\"icon()\">{{ icon() }}</span>\r\n\r\n }\r\n @if(title()){\r\n <strong class=\"banner-title\">{{title()}}</strong>\r\n }\r\n </div>\r\n <div class=\"message-content\">\r\n {{message()}}\r\n <ng-content></ng-content>\r\n </div>\r\n @if(closable()){\r\n <span class=\"mat-icon material-symbols close-icon\" (click)=\"close()\">close</span>\r\n }\r\n</div>\r\n}", styles: ["@import\"https://fonts.googleapis.com/css2?family=Material+Symbols:opsz,wght,FILL,GRAD@24,400,0,0\";@import\"https://fonts.googleapis.com/css2?family=Material+Icons\";.mat-icon:not(mat-icon),.material-symbols{font-family:Material Symbols;font-size:1.5rem;display:flex;align-items:center;justify-content:center}.mat-icon:not(mat-icon).small,.material-symbols.small{font-size:1rem}.mat-icon:not(mat-icon).large,.material-symbols.large{font-size:2rem}.message-banner[data-type=none]{--banner-color: var(--neutral-color);--banner-bg-color: color-mix( in srgb, var(--background-color) 90%, var(--neutral-color) 10% );--banner-icon-color: var(--text-color)}.message-banner[data-type=info]{--banner-color: var(--primary-color);--banner-bg-color: color-mix( in srgb, var(--background-color) 90%, var(--primary-color) 10% );--banner-icon-color: var(--primary-color)}.message-banner[data-type=warning]{--banner-color: var(--warn-color);--banner-bg-color: color-mix( in srgb, var(--background-color) 90%, var(--warn-color) 10% );--banner-icon-color: var(--warn-color)}.message-banner[data-type=error]{--banner-color: var(--error-color);--banner-bg-color: color-mix( in srgb, var(--background-color) 90%, var(--error-color) 10% );--banner-icon-color: var(--error-color)}.message-banner{flex:1 1 auto;border:1px solid var(--banner-color);background-color:var(--banner-bg-color);color:var(--text-color);padding:.65rem 1rem;margin:.5rem 0;border-radius:.25rem;display:flex;align-items:center;gap:.5rem;position:relative;font-size:.875rem}.message-banner .banner-header{position:absolute;display:flex;align-items:center;gap:.5rem;top:-.75rem;left:.5rem;-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);border-radius:.25rem;padding:0 .5rem;font-size:.75rem}.message-banner .banner-header .banner-icon{color:var(--banner-icon-color);fill:var(--banner-icon-color)}.message-banner ::ng-deep .message-content{display:flex;flex-direction:column;justify-items:center;width:100%}.message-banner ::ng-deep .message-content *{display:flex;align-items:center}\n"] }); }
|
|
8721
8787
|
}
|
|
8722
|
-
|
|
8723
|
-
|
|
8724
|
-
});
|
|
8788
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MessageBanner, decorators: [{
|
|
8789
|
+
type: Component,
|
|
8790
|
+
args: [{ selector: 'chr-message-banner', imports: [], template: "@if(isVisible()){\r\n<div class=\"message-banner\" [attr.data-type]=\"type()\">\r\n <div class=\"banner-header\">\r\n @if(icon()){\r\n <span class=\"mat-icon material-symbols banner-icon\" [attr.data-icon]=\"icon()\">{{ icon() }}</span>\r\n\r\n }\r\n @if(title()){\r\n <strong class=\"banner-title\">{{title()}}</strong>\r\n }\r\n </div>\r\n <div class=\"message-content\">\r\n {{message()}}\r\n <ng-content></ng-content>\r\n </div>\r\n @if(closable()){\r\n <span class=\"mat-icon material-symbols close-icon\" (click)=\"close()\">close</span>\r\n }\r\n</div>\r\n}", styles: ["@import\"https://fonts.googleapis.com/css2?family=Material+Symbols:opsz,wght,FILL,GRAD@24,400,0,0\";@import\"https://fonts.googleapis.com/css2?family=Material+Icons\";.mat-icon:not(mat-icon),.material-symbols{font-family:Material Symbols;font-size:1.5rem;display:flex;align-items:center;justify-content:center}.mat-icon:not(mat-icon).small,.material-symbols.small{font-size:1rem}.mat-icon:not(mat-icon).large,.material-symbols.large{font-size:2rem}.message-banner[data-type=none]{--banner-color: var(--neutral-color);--banner-bg-color: color-mix( in srgb, var(--background-color) 90%, var(--neutral-color) 10% );--banner-icon-color: var(--text-color)}.message-banner[data-type=info]{--banner-color: var(--primary-color);--banner-bg-color: color-mix( in srgb, var(--background-color) 90%, var(--primary-color) 10% );--banner-icon-color: var(--primary-color)}.message-banner[data-type=warning]{--banner-color: var(--warn-color);--banner-bg-color: color-mix( in srgb, var(--background-color) 90%, var(--warn-color) 10% );--banner-icon-color: var(--warn-color)}.message-banner[data-type=error]{--banner-color: var(--error-color);--banner-bg-color: color-mix( in srgb, var(--background-color) 90%, var(--error-color) 10% );--banner-icon-color: var(--error-color)}.message-banner{flex:1 1 auto;border:1px solid var(--banner-color);background-color:var(--banner-bg-color);color:var(--text-color);padding:.65rem 1rem;margin:.5rem 0;border-radius:.25rem;display:flex;align-items:center;gap:.5rem;position:relative;font-size:.875rem}.message-banner .banner-header{position:absolute;display:flex;align-items:center;gap:.5rem;top:-.75rem;left:.5rem;-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);border-radius:.25rem;padding:0 .5rem;font-size:.75rem}.message-banner .banner-header .banner-icon{color:var(--banner-icon-color);fill:var(--banner-icon-color)}.message-banner ::ng-deep .message-content{display:flex;flex-direction:column;justify-items:center;width:100%}.message-banner ::ng-deep .message-content *{display:flex;align-items:center}\n"] }]
|
|
8791
|
+
}], propDecorators: { closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }] } });
|
|
8725
8792
|
|
|
8726
|
-
|
|
8727
|
-
* Token de contexte HTTP mettre cache la réponse d'une requête via l'intercepteur CachingInterceptor.
|
|
8728
|
-
* La ressource doit être spécifiée pour identifier l'entrée de cache.
|
|
8729
|
-
* Vous êtes responsable de l'invalidation du cache via le token INVALIDATE_CACHE.
|
|
8730
|
-
*/
|
|
8731
|
-
const ENABLE_CACHE = new HttpContextToken(() => null);
|
|
8732
|
-
/**
|
|
8733
|
-
* Token de contexte HTTP pour invalider une entrée de cache spécifique.
|
|
8734
|
-
* La ressource doit être spécifiée pour identifier l'entrée de cache à invalider.
|
|
8735
|
-
*/
|
|
8736
|
-
const INVALIDATE_CACHE = new HttpContextToken(() => null);
|
|
8737
|
-
class CacheService {
|
|
8793
|
+
class Spinner {
|
|
8738
8794
|
constructor() {
|
|
8739
|
-
this.
|
|
8740
|
-
this.
|
|
8741
|
-
|
|
8742
|
-
|
|
8743
|
-
|
|
8744
|
-
|
|
8745
|
-
*/
|
|
8746
|
-
this.get = (key) => {
|
|
8747
|
-
const entry = this._cache[key];
|
|
8748
|
-
if (entry) {
|
|
8749
|
-
// Vérifie si l'entrée est expirée
|
|
8750
|
-
if (entry.status != 'expired' && Date.now() < entry.expiry) {
|
|
8751
|
-
return entry.value;
|
|
8752
|
-
}
|
|
8753
|
-
else {
|
|
8754
|
-
// Marque l'entrée comme expirée
|
|
8755
|
-
entry.status = 'expired';
|
|
8756
|
-
return null;
|
|
8757
|
-
}
|
|
8758
|
-
}
|
|
8759
|
-
return null;
|
|
8760
|
-
};
|
|
8761
|
-
/**
|
|
8762
|
-
* Met en cache une valeur avec une clé spécifique
|
|
8763
|
-
* @param key La clé sous laquelle stocker la valeur
|
|
8764
|
-
* @param value La valeur à mettre en cache
|
|
8765
|
-
*/
|
|
8766
|
-
this.set = (key, value) => {
|
|
8767
|
-
this._cache[key] = {
|
|
8768
|
-
value: value,
|
|
8769
|
-
expiry: Date.now() + this._cacheValidityDuration,
|
|
8770
|
-
status: 'valid',
|
|
8771
|
-
};
|
|
8772
|
-
};
|
|
8773
|
-
/**
|
|
8774
|
-
* Invalide une entrée de cache spécifique
|
|
8775
|
-
* @param key La clé de l'entrée à invalider
|
|
8776
|
-
*/
|
|
8777
|
-
this.invalidate = (key) => {
|
|
8778
|
-
if (this._cache[key]) {
|
|
8779
|
-
this._cache[key].status = 'expired';
|
|
8780
|
-
}
|
|
8781
|
-
};
|
|
8782
|
-
/**
|
|
8783
|
-
* Mets à jour la durée de validité du cache
|
|
8784
|
-
* @param duration Durée en millisecondes
|
|
8785
|
-
*/
|
|
8786
|
-
this.setCacheValidityDuration = (duration) => {
|
|
8787
|
-
this._cacheValidityDuration = duration;
|
|
8788
|
-
};
|
|
8789
|
-
this._cacheValidityDuration = this._default.duration;
|
|
8795
|
+
this.spinnerService = inject(SpinnerService);
|
|
8796
|
+
this.shown = input(false, /* @ts-ignore */
|
|
8797
|
+
...(ngDevMode ? [{ debugName: "shown" }] : /* istanbul ignore next */ []));
|
|
8798
|
+
this.isLoading = this.spinnerService.isLoading;
|
|
8799
|
+
this.shouldShow = computed(() => this.isLoading() || this.shown(), /* @ts-ignore */
|
|
8800
|
+
...(ngDevMode ? [{ debugName: "shouldShow" }] : /* istanbul ignore next */ []));
|
|
8790
8801
|
}
|
|
8791
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type:
|
|
8792
|
-
static { this.ɵ
|
|
8802
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: Spinner, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8803
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: Spinner, isStandalone: true, selector: "chr-spinner", inputs: { shown: { classPropertyName: "shown", publicName: "shown", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (shouldShow()) {\r\n<div class=\"spinner-backdrop\">\r\n <div class=\"spinner-container\">\r\n <div class=\"pulse-rings\">\r\n <div class=\"pulse-ring pulse-ring-1\"></div>\r\n <div class=\"pulse-ring pulse-ring-2\"></div>\r\n <div class=\"pulse-ring pulse-ring-3\"></div>\r\n <div class=\"pulse-ring pulse-ring-4\"></div>\r\n </div>\r\n\r\n <div class=\"loading-text\">\r\n <p>Chargement...</p>\r\n </div>\r\n </div>\r\n</div>\r\n}", styles: ["@charset \"UTF-8\";.spinner-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background-color:color-mix(in srgb,black 40%,transparent);display:flex;justify-content:center;align-items:center;z-index:9997;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);animation:fadeIn .3s ease-in-out}.spinner-container{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2rem;padding:3rem;border-radius:1.5rem;min-width:250px;animation:slideUp .4s ease-out}.pulse-rings{position:relative;width:120px;height:120px;display:flex;align-items:center;justify-content:center}.pulse-ring{position:absolute;border:3px solid transparent;border-radius:50%;animation:pulse-ring 2.5s cubic-bezier(.25,.46,.45,.94) infinite}.pulse-ring-1{width:40px;height:40px;border-color:var(--primary-color);animation-delay:0s;box-shadow:0 0 20px color-mix(in srgb,var(--primary-color) 30%,transparent)}.pulse-ring-2{width:60px;height:60px;border-color:var(--tertiary-color);animation-delay:.6s;box-shadow:0 0 25px color-mix(in srgb,var(--tertiary-color) 25%,transparent)}.pulse-ring-3{width:80px;height:80px;border-color:var(--secondary-color);animation-delay:1.2s;box-shadow:0 0 30px color-mix(in srgb,var(--secondary-color) 20%,transparent)}.pulse-ring-4{width:100px;height:100px;border-color:var(--primary-color);animation-delay:1.8s;opacity:.7;box-shadow:0 0 35px color-mix(in srgb,var(--primary-color) 15%,transparent)}.loading-text{text-align:center;color:var(--text-color);font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif}.loading-text p{margin:0;font-size:1.2rem;font-weight:500;color:var(--primary-color);letter-spacing:.5px;animation:text-pulse 2s ease-in-out infinite}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(30px) scale(.9)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes pulse-ring{0%{transform:scale(.6);opacity:1;border-width:4px}50%{opacity:.8;border-width:2px}to{transform:scale(1.3);opacity:0;border-width:1px}}@keyframes text-pulse{0%,to{opacity:.8}50%{opacity:1;text-shadow:0 0 10px color-mix(in srgb,var(--primary-color) 30%,transparent)}}@media(max-width:768px){.spinner-container{min-width:200px;padding:2rem;gap:1.5rem}.pulse-rings{width:100px;height:100px}.pulse-ring-1{width:35px;height:35px}.pulse-ring-2{width:50px;height:50px}.pulse-ring-3{width:65px;height:65px}.pulse-ring-4{width:80px;height:80px}.loading-text p{font-size:1rem}}.dark-theme .spinner-container{box-shadow:0 20px 40px color-mix(in srgb,black 40%,transparent);border-color:var(--neutral-color)}.dark-theme .pulse-ring-1{box-shadow:0 0 20px color-mix(in srgb,var(--primary-color) 50%,transparent)}.dark-theme .pulse-ring-2{box-shadow:0 0 25px color-mix(in srgb,var(--tertiary-color) 40%,transparent)}.as400-theme .pulse-ring{filter:drop-shadow(0 0 8px var(--primary-color))}.as400-theme .loading-text p{text-shadow:0 0 10px var(--primary-color)}\n"] }); }
|
|
8793
8804
|
}
|
|
8794
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type:
|
|
8795
|
-
type:
|
|
8796
|
-
args: [{
|
|
8797
|
-
|
|
8798
|
-
}]
|
|
8799
|
-
}], ctorParameters: () => [] });
|
|
8805
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: Spinner, decorators: [{
|
|
8806
|
+
type: Component,
|
|
8807
|
+
args: [{ selector: 'chr-spinner', imports: [], template: "@if (shouldShow()) {\r\n<div class=\"spinner-backdrop\">\r\n <div class=\"spinner-container\">\r\n <div class=\"pulse-rings\">\r\n <div class=\"pulse-ring pulse-ring-1\"></div>\r\n <div class=\"pulse-ring pulse-ring-2\"></div>\r\n <div class=\"pulse-ring pulse-ring-3\"></div>\r\n <div class=\"pulse-ring pulse-ring-4\"></div>\r\n </div>\r\n\r\n <div class=\"loading-text\">\r\n <p>Chargement...</p>\r\n </div>\r\n </div>\r\n</div>\r\n}", styles: ["@charset \"UTF-8\";.spinner-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background-color:color-mix(in srgb,black 40%,transparent);display:flex;justify-content:center;align-items:center;z-index:9997;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);animation:fadeIn .3s ease-in-out}.spinner-container{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2rem;padding:3rem;border-radius:1.5rem;min-width:250px;animation:slideUp .4s ease-out}.pulse-rings{position:relative;width:120px;height:120px;display:flex;align-items:center;justify-content:center}.pulse-ring{position:absolute;border:3px solid transparent;border-radius:50%;animation:pulse-ring 2.5s cubic-bezier(.25,.46,.45,.94) infinite}.pulse-ring-1{width:40px;height:40px;border-color:var(--primary-color);animation-delay:0s;box-shadow:0 0 20px color-mix(in srgb,var(--primary-color) 30%,transparent)}.pulse-ring-2{width:60px;height:60px;border-color:var(--tertiary-color);animation-delay:.6s;box-shadow:0 0 25px color-mix(in srgb,var(--tertiary-color) 25%,transparent)}.pulse-ring-3{width:80px;height:80px;border-color:var(--secondary-color);animation-delay:1.2s;box-shadow:0 0 30px color-mix(in srgb,var(--secondary-color) 20%,transparent)}.pulse-ring-4{width:100px;height:100px;border-color:var(--primary-color);animation-delay:1.8s;opacity:.7;box-shadow:0 0 35px color-mix(in srgb,var(--primary-color) 15%,transparent)}.loading-text{text-align:center;color:var(--text-color);font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif}.loading-text p{margin:0;font-size:1.2rem;font-weight:500;color:var(--primary-color);letter-spacing:.5px;animation:text-pulse 2s ease-in-out infinite}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(30px) scale(.9)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes pulse-ring{0%{transform:scale(.6);opacity:1;border-width:4px}50%{opacity:.8;border-width:2px}to{transform:scale(1.3);opacity:0;border-width:1px}}@keyframes text-pulse{0%,to{opacity:.8}50%{opacity:1;text-shadow:0 0 10px color-mix(in srgb,var(--primary-color) 30%,transparent)}}@media(max-width:768px){.spinner-container{min-width:200px;padding:2rem;gap:1.5rem}.pulse-rings{width:100px;height:100px}.pulse-ring-1{width:35px;height:35px}.pulse-ring-2{width:50px;height:50px}.pulse-ring-3{width:65px;height:65px}.pulse-ring-4{width:80px;height:80px}.loading-text p{font-size:1rem}}.dark-theme .spinner-container{box-shadow:0 20px 40px color-mix(in srgb,black 40%,transparent);border-color:var(--neutral-color)}.dark-theme .pulse-ring-1{box-shadow:0 0 20px color-mix(in srgb,var(--primary-color) 50%,transparent)}.dark-theme .pulse-ring-2{box-shadow:0 0 25px color-mix(in srgb,var(--tertiary-color) 40%,transparent)}.as400-theme .pulse-ring{filter:drop-shadow(0 0 8px var(--primary-color))}.as400-theme .loading-text p{text-shadow:0 0 10px var(--primary-color)}\n"] }]
|
|
8808
|
+
}], propDecorators: { shown: [{ type: i0.Input, args: [{ isSignal: true, alias: "shown", required: false }] }] } });
|
|
8800
8809
|
|
|
8801
|
-
|
|
8802
|
-
class ProgressService {
|
|
8810
|
+
class ChrSimpleTableComponent {
|
|
8803
8811
|
constructor() {
|
|
8804
|
-
this.
|
|
8805
|
-
|
|
8806
|
-
|
|
8807
|
-
|
|
8808
|
-
|
|
8809
|
-
|
|
8810
|
-
this.
|
|
8811
|
-
|
|
8812
|
-
|
|
8813
|
-
|
|
8814
|
-
return this._progressStates[key].asObservable();
|
|
8815
|
-
};
|
|
8816
|
-
/**
|
|
8817
|
-
* Met à jour l'état de progression pour une clé spécifique
|
|
8818
|
-
* @param key La clé de l'état de progression à mettre à jour
|
|
8819
|
-
* @param state Le nouvel état de progression
|
|
8820
|
-
*/
|
|
8821
|
-
this.set = (key, state) => {
|
|
8822
|
-
if (this._progressStates[key]) {
|
|
8823
|
-
this._progressStates[key].next(state);
|
|
8824
|
-
}
|
|
8825
|
-
else {
|
|
8826
|
-
this._progressStates[key] = new BehaviorSubject(state);
|
|
8827
|
-
}
|
|
8828
|
-
};
|
|
8812
|
+
this.id = input(crypto.randomUUID(), /* @ts-ignore */
|
|
8813
|
+
...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
8814
|
+
this.data = input.required(/* @ts-ignore */
|
|
8815
|
+
...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
8816
|
+
this.layout = input('auto', /* @ts-ignore */
|
|
8817
|
+
...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
|
|
8818
|
+
this.page = model(1, /* @ts-ignore */
|
|
8819
|
+
...(ngDevMode ? [{ debugName: "page" }] : /* istanbul ignore next */ []));
|
|
8820
|
+
this.pageSize = model(10, /* @ts-ignore */
|
|
8821
|
+
...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
|
|
8829
8822
|
}
|
|
8830
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type:
|
|
8831
|
-
static { this.ɵ
|
|
8823
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ChrSimpleTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8824
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: ChrSimpleTableComponent, isStandalone: true, selector: "chr-table", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { page: "pageChange", pageSize: "pageSizeChange" }, queries: [{ propertyName: "captionTemplate", first: true, predicate: ["caption"], descendants: true, read: TemplateRef }, { propertyName: "headerTemplate", first: true, predicate: ["header"], descendants: true, read: TemplateRef }, { propertyName: "rowTemplate", first: true, predicate: ["row"], descendants: true, read: TemplateRef }], ngImport: i0, template: "<table class=\"chr-table\" [attr.data-layout]=\"layout()\">\n @if (captionTemplate) {\n <caption>\n <ng-container [ngTemplateOutlet]=\"captionTemplate\"></ng-container>\n </caption>\n }\n @if (headerTemplate) {\n <thead>\n <ng-container [ngTemplateOutlet]=\"headerTemplate\"></ng-container>\n </thead>\n }\n @if (rowTemplate) {\n <tbody>\n @for (entry of data() | paginate: { id: id(), itemsPerPage: pageSize(), currentPage: page() }; track $index) {\n <ng-container [ngTemplateOutlet]=\"rowTemplate\" [ngTemplateOutletContext]=\"{ $implicit: entry }\">\n </ng-container>\n } @empty {\n <tr>\n <td>Aucune donn\u00E9e disponible</td>\n </tr>\n }\n </tbody>\n }\n</table>\n<chr-paginator [id]=\"id()\" [(page)]=\"page\" [(pageSize)]=\"pageSize\"></chr-paginator>", styles: [":host{display:block}.chr-table{table-layout:auto;width:100%;border-collapse:collapse;border-radius:.5rem;overflow:hidden;box-shadow:0 .125rem .5rem #00000012}.chr-table[data-layout=fixed]{table-layout:fixed}.chr-table thead th{text-align:left}.chr-table thead th:last-child:not(:first-child){text-align:right}.chr-table tbody th{text-align:center}.chr-table tbody td{text-align:left}.chr-table tbody td:last-child:not(:first-child){text-align:right}.chr-table th,.chr-table td{padding:.75rem;text-align:left}.chr-table td{padding:.25rem .75rem}.chr-table caption{padding:.75rem;text-align:left;width:100%}.chr-table th,.chr-table caption{background-color:var(--primary-color);color:var(--primary-contrast-color);font-weight:600}.chr-table tr:nth-child(2n){background-color:var(--neutral-color)}.chr-table tr:hover{box-shadow:inset 0 0 0 .125rem color-mix(in srgb,var(--primary-color) 30%,transparent)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: NgxPaginationModule }, { kind: "component", type: ChrPaginatorComponent, selector: "app-chr-paginator,chr-paginator, chr-paginator", inputs: ["page", "pageSize", "id", "allowSizeChange", "allowPageEdit", "isPageEditing"], outputs: ["pageChange", "pageSizeChange", "isPageEditingChange"] }, { kind: "pipe", type: i2.PaginatePipe, name: "paginate" }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
8832
8825
|
}
|
|
8833
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type:
|
|
8834
|
-
type:
|
|
8835
|
-
args: [{
|
|
8836
|
-
|
|
8837
|
-
|
|
8838
|
-
|
|
8826
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ChrSimpleTableComponent, decorators: [{
|
|
8827
|
+
type: Component,
|
|
8828
|
+
args: [{ selector: 'chr-table', imports: [CommonModule, NgxPaginationModule, ChrPaginatorComponent], encapsulation: ViewEncapsulation.None, template: "<table class=\"chr-table\" [attr.data-layout]=\"layout()\">\n @if (captionTemplate) {\n <caption>\n <ng-container [ngTemplateOutlet]=\"captionTemplate\"></ng-container>\n </caption>\n }\n @if (headerTemplate) {\n <thead>\n <ng-container [ngTemplateOutlet]=\"headerTemplate\"></ng-container>\n </thead>\n }\n @if (rowTemplate) {\n <tbody>\n @for (entry of data() | paginate: { id: id(), itemsPerPage: pageSize(), currentPage: page() }; track $index) {\n <ng-container [ngTemplateOutlet]=\"rowTemplate\" [ngTemplateOutletContext]=\"{ $implicit: entry }\">\n </ng-container>\n } @empty {\n <tr>\n <td>Aucune donn\u00E9e disponible</td>\n </tr>\n }\n </tbody>\n }\n</table>\n<chr-paginator [id]=\"id()\" [(page)]=\"page\" [(pageSize)]=\"pageSize\"></chr-paginator>", styles: [":host{display:block}.chr-table{table-layout:auto;width:100%;border-collapse:collapse;border-radius:.5rem;overflow:hidden;box-shadow:0 .125rem .5rem #00000012}.chr-table[data-layout=fixed]{table-layout:fixed}.chr-table thead th{text-align:left}.chr-table thead th:last-child:not(:first-child){text-align:right}.chr-table tbody th{text-align:center}.chr-table tbody td{text-align:left}.chr-table tbody td:last-child:not(:first-child){text-align:right}.chr-table th,.chr-table td{padding:.75rem;text-align:left}.chr-table td{padding:.25rem .75rem}.chr-table caption{padding:.75rem;text-align:left;width:100%}.chr-table th,.chr-table caption{background-color:var(--primary-color);color:var(--primary-contrast-color);font-weight:600}.chr-table tr:nth-child(2n){background-color:var(--neutral-color)}.chr-table tr:hover{box-shadow:inset 0 0 0 .125rem color-mix(in srgb,var(--primary-color) 30%,transparent)}\n"] }]
|
|
8829
|
+
}], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], page: [{ type: i0.Input, args: [{ isSignal: true, alias: "page", required: false }] }, { type: i0.Output, args: ["pageChange"] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }, { type: i0.Output, args: ["pageSizeChange"] }], captionTemplate: [{
|
|
8830
|
+
type: ContentChild,
|
|
8831
|
+
args: ['caption', { read: TemplateRef }]
|
|
8832
|
+
}], headerTemplate: [{
|
|
8833
|
+
type: ContentChild,
|
|
8834
|
+
args: ['header', { read: TemplateRef }]
|
|
8835
|
+
}], rowTemplate: [{
|
|
8836
|
+
type: ContentChild,
|
|
8837
|
+
args: ['row', { read: TemplateRef }]
|
|
8838
|
+
}] } });
|
|
8839
8839
|
|
|
8840
|
-
class
|
|
8841
|
-
constructor() {
|
|
8842
|
-
|
|
8843
|
-
* delete cookie
|
|
8844
|
-
* @param name
|
|
8845
|
-
*/
|
|
8846
|
-
deleteCookie(name) {
|
|
8847
|
-
this.setCookie(name, "", -1);
|
|
8840
|
+
class TabToEnterHandlerDirective {
|
|
8841
|
+
constructor() {
|
|
8842
|
+
this.el = inject(ElementRef);
|
|
8848
8843
|
}
|
|
8849
|
-
|
|
8850
|
-
|
|
8851
|
-
|
|
8852
|
-
|
|
8853
|
-
|
|
8854
|
-
|
|
8855
|
-
|
|
8856
|
-
|
|
8857
|
-
|
|
8858
|
-
|
|
8859
|
-
for (let i = 0; i < caLen; i += 1) {
|
|
8860
|
-
c = ca[i].replace(/^\s+/g, "");
|
|
8861
|
-
if (c.indexOf(cookieName) === 0) {
|
|
8862
|
-
return c.substring(cookieName.length, c.length);
|
|
8863
|
-
}
|
|
8844
|
+
handleTab(event) {
|
|
8845
|
+
if (event.key === 'Tab') {
|
|
8846
|
+
const enter = new KeyboardEvent('keyup', {
|
|
8847
|
+
...event,
|
|
8848
|
+
key: 'Enter',
|
|
8849
|
+
code: 'Enter',
|
|
8850
|
+
bubbles: true,
|
|
8851
|
+
keyCode: 13,
|
|
8852
|
+
});
|
|
8853
|
+
event.target?.dispatchEvent(enter);
|
|
8864
8854
|
}
|
|
8865
|
-
return "";
|
|
8866
|
-
}
|
|
8867
|
-
/**
|
|
8868
|
-
* set cookie
|
|
8869
|
-
* @param {string} name
|
|
8870
|
-
* @param {string} value
|
|
8871
|
-
* @param {number} expireDays
|
|
8872
|
-
* @param {string} path
|
|
8873
|
-
*/
|
|
8874
|
-
setCookie(name, value, expireDays, path = "") {
|
|
8875
|
-
const d = new Date();
|
|
8876
|
-
d.setTime(d.getTime() + expireDays * 24 * 60 * 60 * 1000);
|
|
8877
|
-
const expires = `expires=${d.toUTCString()}`;
|
|
8878
|
-
const cpath = path ? `; path=${path}` : "";
|
|
8879
|
-
document.cookie = `${name}=${value}; ${expires}${cpath}; SameSite=Lax`;
|
|
8880
8855
|
}
|
|
8881
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type:
|
|
8882
|
-
static { this.ɵ
|
|
8856
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: TabToEnterHandlerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
8857
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: TabToEnterHandlerDirective, isStandalone: true, selector: "[tab-enter]", host: { listeners: { "keydown": "handleTab($event)" } }, ngImport: i0 }); }
|
|
8883
8858
|
}
|
|
8884
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type:
|
|
8885
|
-
type:
|
|
8859
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: TabToEnterHandlerDirective, decorators: [{
|
|
8860
|
+
type: Directive,
|
|
8886
8861
|
args: [{
|
|
8887
|
-
|
|
8862
|
+
selector: '[tab-enter]',
|
|
8863
|
+
standalone: true,
|
|
8888
8864
|
}]
|
|
8889
|
-
}],
|
|
8890
|
-
|
|
8891
|
-
|
|
8865
|
+
}], propDecorators: { handleTab: [{
|
|
8866
|
+
type: HostListener,
|
|
8867
|
+
args: ['keydown', ['$event']]
|
|
8868
|
+
}] } });
|
|
8892
8869
|
|
|
8893
|
-
class
|
|
8894
|
-
constructor(
|
|
8895
|
-
this.
|
|
8896
|
-
this.
|
|
8897
|
-
|
|
8898
|
-
this.constraintName = data.constraintName || '';
|
|
8899
|
-
this.constraintType = data.constraintType || '';
|
|
8900
|
-
this.tableCatalog = data.tableCatalog || '';
|
|
8901
|
-
this.tableName = data.tableName || '';
|
|
8902
|
-
this.tableSchema = data.tableSchema || '';
|
|
8903
|
-
this.columns = data.columns
|
|
8904
|
-
? data.columns.map((d) => new TableConstraintColumn(d))
|
|
8905
|
-
: [];
|
|
8906
|
-
}
|
|
8907
|
-
fullTableName() {
|
|
8908
|
-
return `${this.tableSchema}.${this.tableName}`;
|
|
8909
|
-
}
|
|
8910
|
-
fullConstraintName() {
|
|
8911
|
-
return `${this.constraintSchema}.${this.constraintName}`;
|
|
8912
|
-
}
|
|
8913
|
-
isPrimaryKey() {
|
|
8914
|
-
return this.constraintType === 'PRIMARY KEY';
|
|
8915
|
-
}
|
|
8916
|
-
isForeignKey() {
|
|
8917
|
-
return this.constraintType === 'FOREIGN KEY';
|
|
8918
|
-
}
|
|
8919
|
-
isUnique() {
|
|
8920
|
-
return this.constraintType === 'UNIQUE';
|
|
8921
|
-
}
|
|
8922
|
-
isCheck() {
|
|
8923
|
-
return this.constraintType === 'CHECK';
|
|
8870
|
+
class ChrPreventReloadDirective {
|
|
8871
|
+
constructor() {
|
|
8872
|
+
this.host = inject(ElementRef);
|
|
8873
|
+
this.chrPreventReload = input(false, /* @ts-ignore */
|
|
8874
|
+
...(ngDevMode ? [{ debugName: "chrPreventReload" }] : /* istanbul ignore next */ []));
|
|
8924
8875
|
}
|
|
8876
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ChrPreventReloadDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
8877
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: ChrPreventReloadDirective, isStandalone: true, selector: "[chrPreventReload]", inputs: { chrPreventReload: { classPropertyName: "chrPreventReload", publicName: "chrPreventReload", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "window:beforeunload": "chrPreventReload() ? $event.preventDefault() : null" } }, ngImport: i0 }); }
|
|
8925
8878
|
}
|
|
8879
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ChrPreventReloadDirective, decorators: [{
|
|
8880
|
+
type: Directive,
|
|
8881
|
+
args: [{
|
|
8882
|
+
selector: '[chrPreventReload]',
|
|
8883
|
+
host: {
|
|
8884
|
+
'(window:beforeunload)': 'chrPreventReload() ? $event.preventDefault() : null',
|
|
8885
|
+
},
|
|
8886
|
+
}]
|
|
8887
|
+
}], propDecorators: { chrPreventReload: [{ type: i0.Input, args: [{ isSignal: true, alias: "chrPreventReload", required: false }] }] } });
|
|
8926
8888
|
|
|
8927
|
-
class
|
|
8928
|
-
|
|
8929
|
-
this.
|
|
8930
|
-
this.
|
|
8931
|
-
|
|
8932
|
-
|
|
8933
|
-
|
|
8934
|
-
|
|
8935
|
-
|
|
8936
|
-
|
|
8937
|
-
|
|
8938
|
-
|
|
8939
|
-
|
|
8889
|
+
class ChrDebounceDirective {
|
|
8890
|
+
constructor() {
|
|
8891
|
+
this.host = inject(ElementRef);
|
|
8892
|
+
this.defaults = inject(CHR_DEBOUNCE_DEFAULTS);
|
|
8893
|
+
this.renderer = inject(Renderer2);
|
|
8894
|
+
this.subject = new Subject();
|
|
8895
|
+
this.chrDebounceTime = input(null, /* @ts-ignore */
|
|
8896
|
+
...(ngDevMode ? [{ debugName: "chrDebounceTime" }] : /* istanbul ignore next */ []));
|
|
8897
|
+
this.debounceTimeValue = computed(() => {
|
|
8898
|
+
const time = this.chrDebounceTime();
|
|
8899
|
+
if (time !== null && !isNaN(Number(time))) {
|
|
8900
|
+
return Number(time);
|
|
8901
|
+
}
|
|
8902
|
+
return this.defaults.baseInputs;
|
|
8903
|
+
}, /* @ts-ignore */
|
|
8904
|
+
...(ngDevMode ? [{ debugName: "debounceTimeValue" }] : /* istanbul ignore next */ []));
|
|
8905
|
+
this.subscription = of();
|
|
8906
|
+
this.isDispatching = false;
|
|
8940
8907
|
}
|
|
8941
|
-
|
|
8942
|
-
const
|
|
8943
|
-
|
|
8944
|
-
|
|
8945
|
-
|
|
8946
|
-
|
|
8947
|
-
|
|
8948
|
-
|
|
8908
|
+
ngOnInit() {
|
|
8909
|
+
const element = this.host.nativeElement;
|
|
8910
|
+
this.subscription = this.subject.pipe(debounceTime$1(this.debounceTimeValue()));
|
|
8911
|
+
// Listener en phase CAPTURE pour intercepter AVANT tous les listeners Angular
|
|
8912
|
+
this.captureListener = this.renderer.listen(element, 'input', (event) => {
|
|
8913
|
+
if (this.isDispatching) {
|
|
8914
|
+
return;
|
|
8915
|
+
}
|
|
8916
|
+
event.preventDefault();
|
|
8917
|
+
event.stopImmediatePropagation();
|
|
8918
|
+
event.stopPropagation();
|
|
8919
|
+
this.subject.next(event);
|
|
8920
|
+
}, { capture: true });
|
|
8921
|
+
this.subscription.subscribe((event) => {
|
|
8922
|
+
this.isDispatching = true;
|
|
8923
|
+
const newEvent = new InputEvent('input', {
|
|
8924
|
+
bubbles: true,
|
|
8925
|
+
cancelable: true,
|
|
8926
|
+
data: event.data,
|
|
8927
|
+
inputType: event.inputType,
|
|
8928
|
+
});
|
|
8929
|
+
element.dispatchEvent(newEvent);
|
|
8930
|
+
setTimeout(() => (this.isDispatching = false), 0);
|
|
8931
|
+
});
|
|
8949
8932
|
}
|
|
8950
|
-
|
|
8951
|
-
|
|
8933
|
+
ngOnDestroy() {
|
|
8934
|
+
this.captureListener?.();
|
|
8935
|
+
this.subject.complete();
|
|
8952
8936
|
}
|
|
8953
|
-
|
|
8954
|
-
|
|
8937
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ChrDebounceDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
8938
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: ChrDebounceDirective, isStandalone: true, selector: "[chrDebounce]", inputs: { chrDebounceTime: { classPropertyName: "chrDebounceTime", publicName: "chrDebounceTime", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
8939
|
+
}
|
|
8940
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ChrDebounceDirective, decorators: [{
|
|
8941
|
+
type: Directive,
|
|
8942
|
+
args: [{
|
|
8943
|
+
selector: '[chrDebounce]',
|
|
8944
|
+
}]
|
|
8945
|
+
}], propDecorators: { chrDebounceTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "chrDebounceTime", required: false }] }] } });
|
|
8946
|
+
|
|
8947
|
+
class ChrHoverDirective {
|
|
8948
|
+
constructor() {
|
|
8949
|
+
this.el = inject((ElementRef));
|
|
8950
|
+
this.overlay = inject(Overlay);
|
|
8951
|
+
this.vcr = inject(ViewContainerRef);
|
|
8952
|
+
this.renderer = inject(Renderer2);
|
|
8953
|
+
this.eventListeners = [];
|
|
8954
|
+
this.chrHoverContext = input({}, /* @ts-ignore */
|
|
8955
|
+
...(ngDevMode ? [{ debugName: "chrHoverContext" }] : /* istanbul ignore next */ []));
|
|
8956
|
+
this.chrHoverSnap = input(false, /* @ts-ignore */
|
|
8957
|
+
...(ngDevMode ? [{ debugName: "chrHoverSnap" }] : /* istanbul ignore next */ []));
|
|
8958
|
+
this.chrHoverPosition = input('right', /* @ts-ignore */
|
|
8959
|
+
...(ngDevMode ? [{ debugName: "chrHoverPosition" }] : /* istanbul ignore next */ []));
|
|
8960
|
+
this.chrHoverCloseDelay = input(10, /* @ts-ignore */
|
|
8961
|
+
...(ngDevMode ? [{ debugName: "chrHoverCloseDelay" }] : /* istanbul ignore next */ []));
|
|
8962
|
+
this.closeTimeout = null;
|
|
8963
|
+
this.overlayEventListeners = [];
|
|
8964
|
+
this.mousePositionStrategy = (mousemove) => {
|
|
8965
|
+
const positionOffset = { left: mousemove.clientX, top: mousemove.clientY };
|
|
8966
|
+
const componentSize = this.overlayRef?.overlayElement.getBoundingClientRect();
|
|
8967
|
+
switch (this.chrHoverPosition()) {
|
|
8968
|
+
case 'above':
|
|
8969
|
+
positionOffset.top -= (componentSize?.height || 0) + 20;
|
|
8970
|
+
positionOffset.left -= (componentSize?.width || 0) / 2;
|
|
8971
|
+
break;
|
|
8972
|
+
case 'below':
|
|
8973
|
+
positionOffset.top += 20;
|
|
8974
|
+
positionOffset.left -= (componentSize?.width || 0) / 2;
|
|
8975
|
+
break;
|
|
8976
|
+
case 'left':
|
|
8977
|
+
positionOffset.left -= (componentSize?.width || 0) + 20;
|
|
8978
|
+
positionOffset.top -= (componentSize?.height || 0) / 2;
|
|
8979
|
+
break;
|
|
8980
|
+
case 'right':
|
|
8981
|
+
positionOffset.left += 20;
|
|
8982
|
+
positionOffset.top -= (componentSize?.height || 0) / 2;
|
|
8983
|
+
break;
|
|
8984
|
+
}
|
|
8985
|
+
const positionStrategy = this.overlay
|
|
8986
|
+
.position()
|
|
8987
|
+
.global()
|
|
8988
|
+
.left(`${positionOffset.left}px`)
|
|
8989
|
+
.top(`${positionOffset.top}px`);
|
|
8990
|
+
return positionStrategy;
|
|
8991
|
+
};
|
|
8992
|
+
this.snappedStrategy = () => {
|
|
8993
|
+
const positionStrategy = this.overlay
|
|
8994
|
+
.position()
|
|
8995
|
+
.flexibleConnectedTo(this.el);
|
|
8996
|
+
switch (this.chrHoverPosition()) {
|
|
8997
|
+
case 'above':
|
|
8998
|
+
positionStrategy.withPositions([
|
|
8999
|
+
{
|
|
9000
|
+
originX: 'center',
|
|
9001
|
+
originY: 'top',
|
|
9002
|
+
overlayX: 'center',
|
|
9003
|
+
overlayY: 'bottom',
|
|
9004
|
+
},
|
|
9005
|
+
{
|
|
9006
|
+
originX: 'center',
|
|
9007
|
+
originY: 'bottom',
|
|
9008
|
+
overlayX: 'center',
|
|
9009
|
+
overlayY: 'top',
|
|
9010
|
+
},
|
|
9011
|
+
]);
|
|
9012
|
+
break;
|
|
9013
|
+
case 'below':
|
|
9014
|
+
positionStrategy.withPositions([
|
|
9015
|
+
{
|
|
9016
|
+
originX: 'center',
|
|
9017
|
+
originY: 'bottom',
|
|
9018
|
+
overlayX: 'center',
|
|
9019
|
+
overlayY: 'top',
|
|
9020
|
+
},
|
|
9021
|
+
{
|
|
9022
|
+
originX: 'center',
|
|
9023
|
+
originY: 'top',
|
|
9024
|
+
overlayX: 'center',
|
|
9025
|
+
overlayY: 'bottom',
|
|
9026
|
+
},
|
|
9027
|
+
]);
|
|
9028
|
+
break;
|
|
9029
|
+
case 'left':
|
|
9030
|
+
positionStrategy.withPositions([
|
|
9031
|
+
{
|
|
9032
|
+
originX: 'start',
|
|
9033
|
+
originY: 'center',
|
|
9034
|
+
overlayX: 'end',
|
|
9035
|
+
overlayY: 'center',
|
|
9036
|
+
},
|
|
9037
|
+
{
|
|
9038
|
+
originX: 'end',
|
|
9039
|
+
originY: 'center',
|
|
9040
|
+
overlayX: 'start',
|
|
9041
|
+
overlayY: 'center',
|
|
9042
|
+
},
|
|
9043
|
+
]);
|
|
9044
|
+
break;
|
|
9045
|
+
case 'right':
|
|
9046
|
+
positionStrategy.withPositions([
|
|
9047
|
+
{
|
|
9048
|
+
originX: 'end',
|
|
9049
|
+
originY: 'center',
|
|
9050
|
+
overlayX: 'start',
|
|
9051
|
+
overlayY: 'center',
|
|
9052
|
+
},
|
|
9053
|
+
{
|
|
9054
|
+
originX: 'start',
|
|
9055
|
+
originY: 'center',
|
|
9056
|
+
overlayX: 'end',
|
|
9057
|
+
overlayY: 'center',
|
|
9058
|
+
},
|
|
9059
|
+
]);
|
|
9060
|
+
break;
|
|
9061
|
+
}
|
|
9062
|
+
return positionStrategy;
|
|
9063
|
+
};
|
|
9064
|
+
const positionStrategy = this.snappedStrategy();
|
|
9065
|
+
this.overlayRef = this.overlay.create({
|
|
9066
|
+
positionStrategy,
|
|
9067
|
+
hasBackdrop: false,
|
|
9068
|
+
disposeOnNavigation: true,
|
|
9069
|
+
disableClose: true,
|
|
9070
|
+
});
|
|
8955
9071
|
}
|
|
8956
|
-
|
|
8957
|
-
|
|
9072
|
+
ngOnInit() {
|
|
9073
|
+
this.overlayRef.updatePositionStrategy(this.snappedStrategy());
|
|
9074
|
+
this.eventListeners.push(this.renderer.listen(this.el.nativeElement, 'mouseenter', () => {
|
|
9075
|
+
this.clearCloseTimeout();
|
|
9076
|
+
this.open();
|
|
9077
|
+
}));
|
|
9078
|
+
this.eventListeners.push(this.renderer.listen(this.el.nativeElement, 'mouseleave', () => {
|
|
9079
|
+
this.startCloseTimeout();
|
|
9080
|
+
}));
|
|
9081
|
+
this.eventListeners.push(this.renderer.listen(this.el.nativeElement, 'mousemove', (event) => {
|
|
9082
|
+
if (!this.chrHoverSnap()) {
|
|
9083
|
+
const positionStrategy = this.mousePositionStrategy(event);
|
|
9084
|
+
this.overlayRef.updatePositionStrategy(positionStrategy);
|
|
9085
|
+
}
|
|
9086
|
+
}));
|
|
8958
9087
|
}
|
|
8959
|
-
|
|
8960
|
-
|
|
8961
|
-
|
|
8962
|
-
|
|
8963
|
-
this.
|
|
8964
|
-
this.schema = data.schema;
|
|
8965
|
-
this.name = data.name;
|
|
8966
|
-
this.description = data.description;
|
|
8967
|
-
this.isReadOnly = data.isReadOnly;
|
|
8968
|
-
this.rowNumberIdentity = data.rowNumberIdentity;
|
|
8969
|
-
this.columnMetadatas = data.columnMetadatas
|
|
8970
|
-
? data.columnMetadatas
|
|
8971
|
-
.map((d) => new ColumnMetadata(d))
|
|
8972
|
-
.sort((a, b) => a.ordinalPosition - b.ordinalPosition)
|
|
8973
|
-
: [];
|
|
8974
|
-
this.tableConstraints = data.tableConstraints
|
|
8975
|
-
? data.tableConstraints.map((d) => new TableConstraint(d))
|
|
8976
|
-
: [];
|
|
8977
|
-
this.hasPrimaryKey =
|
|
8978
|
-
data.hasPrimaryKey === undefined ? false : Boolean(data.hasPrimaryKey);
|
|
8979
|
-
this.rows = data.rows || [];
|
|
8980
|
-
this.count = data.count || 0;
|
|
8981
|
-
this.total = data.total || 0;
|
|
9088
|
+
ngOnDestroy() {
|
|
9089
|
+
this.clearCloseTimeout();
|
|
9090
|
+
this.clearOverlayListeners();
|
|
9091
|
+
this.overlayRef.dispose();
|
|
9092
|
+
this.removeEventListeners();
|
|
8982
9093
|
}
|
|
8983
|
-
|
|
8984
|
-
|
|
9094
|
+
removeEventListeners() {
|
|
9095
|
+
this.eventListeners.forEach((unlisten) => unlisten());
|
|
9096
|
+
this.eventListeners = [];
|
|
8985
9097
|
}
|
|
8986
|
-
|
|
8987
|
-
|
|
8988
|
-
|
|
8989
|
-
const rn = this.columnMetadatas.find((cmd) => cmd.columnName === 'ROW_NUMBER');
|
|
8990
|
-
return rn ? [rn] : [];
|
|
8991
|
-
}
|
|
8992
|
-
return this.columnMetadatas.filter((cmd) => pkColumns?.some((pc) => pc.columnName === cmd.columnName));
|
|
9098
|
+
startCloseTimeout() {
|
|
9099
|
+
this.clearCloseTimeout();
|
|
9100
|
+
this.closeTimeout = window.setTimeout(() => this.close(), this.chrHoverCloseDelay());
|
|
8993
9101
|
}
|
|
8994
|
-
|
|
8995
|
-
if (
|
|
8996
|
-
|
|
8997
|
-
|
|
8998
|
-
}
|
|
8999
|
-
}
|
|
9000
|
-
const pkColumns = this.primaryKeyColumns();
|
|
9001
|
-
if (this.hasPrimaryKey && pkColumns.length > 0) {
|
|
9002
|
-
let key = '';
|
|
9003
|
-
let index = 0;
|
|
9004
|
-
for (const pc of pkColumns) {
|
|
9005
|
-
if (row[pc.columnName] === undefined || row[pc.columnName] === null) {
|
|
9006
|
-
if (row[this.rowNumberIdentity] !== undefined)
|
|
9007
|
-
return `${row[this.rowNumberIdentity]}`;
|
|
9008
|
-
else
|
|
9009
|
-
break;
|
|
9010
|
-
}
|
|
9011
|
-
if (index == pkColumns.length - 1) {
|
|
9012
|
-
key += `${pc.columnName}:${row[pc.columnName]}`;
|
|
9013
|
-
}
|
|
9014
|
-
else
|
|
9015
|
-
key += `${pc.columnName}:${row[pc.columnName]}|`;
|
|
9016
|
-
index++;
|
|
9017
|
-
}
|
|
9018
|
-
return key;
|
|
9102
|
+
clearCloseTimeout() {
|
|
9103
|
+
if (this.closeTimeout != null) {
|
|
9104
|
+
clearTimeout(this.closeTimeout);
|
|
9105
|
+
this.closeTimeout = null;
|
|
9019
9106
|
}
|
|
9020
|
-
return JSON.stringify(row);
|
|
9021
9107
|
}
|
|
9022
|
-
|
|
9023
|
-
|
|
9108
|
+
clearOverlayListeners() {
|
|
9109
|
+
this.overlayEventListeners.forEach((u) => u());
|
|
9110
|
+
this.overlayEventListeners = [];
|
|
9024
9111
|
}
|
|
9025
|
-
|
|
9026
|
-
if (!this.
|
|
9027
|
-
if (
|
|
9028
|
-
|
|
9029
|
-
return row1[this.rowNumberIdentity] === row2[this.rowNumberIdentity];
|
|
9112
|
+
open() {
|
|
9113
|
+
if (!this.overlayRef.hasAttached()) {
|
|
9114
|
+
if (!this.portal) {
|
|
9115
|
+
this.portal = new TemplatePortal(this.template, this.vcr, this.chrHoverContext());
|
|
9030
9116
|
}
|
|
9117
|
+
const ref = this.overlayRef.attach(this.portal);
|
|
9118
|
+
// keep overlay open when overlay itself is hovered
|
|
9119
|
+
const overlayEl = this.overlayRef.overlayElement;
|
|
9120
|
+
this.clearOverlayListeners();
|
|
9121
|
+
this.overlayEventListeners.push(this.renderer.listen(overlayEl, 'mouseenter', () => {
|
|
9122
|
+
this.clearCloseTimeout();
|
|
9123
|
+
}));
|
|
9124
|
+
this.overlayEventListeners.push(this.renderer.listen(overlayEl, 'mouseleave', () => {
|
|
9125
|
+
this.startCloseTimeout();
|
|
9126
|
+
}));
|
|
9031
9127
|
}
|
|
9032
|
-
const pkColumns = this.primaryKeyColumns();
|
|
9033
|
-
if (this.hasPrimaryKey && pkColumns.length > 0) {
|
|
9034
|
-
return pkColumns.every((pc) => row1[pc.columnName] === row2[pc.columnName]);
|
|
9035
|
-
}
|
|
9036
|
-
return super.compareRows(row1, row2);
|
|
9037
|
-
}
|
|
9038
|
-
addRow(row) {
|
|
9039
|
-
row[this.rowNumberIdentity] = this.generateTempRowIdentifier();
|
|
9040
|
-
return super.addRow(row);
|
|
9041
|
-
}
|
|
9042
|
-
generateTempRowIdentifier() {
|
|
9043
|
-
return crypto.randomUUID();
|
|
9044
|
-
}
|
|
9045
|
-
}
|
|
9046
|
-
|
|
9047
|
-
class MinFileNameLengthValidator {
|
|
9048
|
-
constructor() {
|
|
9049
|
-
this.max = input(0, /* @ts-ignore */
|
|
9050
|
-
...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
|
|
9051
9128
|
}
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
|
|
9129
|
+
close() {
|
|
9130
|
+
this.clearCloseTimeout();
|
|
9131
|
+
this.clearOverlayListeners();
|
|
9132
|
+
this.overlayRef.detach();
|
|
9055
9133
|
}
|
|
9056
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type:
|
|
9057
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type:
|
|
9134
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ChrHoverDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
9135
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: ChrHoverDirective, isStandalone: true, selector: "[chrHover]", inputs: { template: { classPropertyName: "template", publicName: "chrHover", isSignal: false, isRequired: false, transformFunction: null }, chrHoverContext: { classPropertyName: "chrHoverContext", publicName: "chrHoverContext", isSignal: true, isRequired: false, transformFunction: null }, chrHoverSnap: { classPropertyName: "chrHoverSnap", publicName: "chrHoverSnap", isSignal: true, isRequired: false, transformFunction: null }, chrHoverPosition: { classPropertyName: "chrHoverPosition", publicName: "chrHoverPosition", isSignal: true, isRequired: false, transformFunction: null }, chrHoverCloseDelay: { classPropertyName: "chrHoverCloseDelay", publicName: "chrHoverCloseDelay", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
9058
9136
|
{
|
|
9059
|
-
provide:
|
|
9060
|
-
|
|
9061
|
-
|
|
9137
|
+
provide: CDK_CONNECTED_OVERLAY_DEFAULT_CONFIG,
|
|
9138
|
+
useFactory: () => {
|
|
9139
|
+
disableClose: true;
|
|
9140
|
+
},
|
|
9062
9141
|
},
|
|
9063
9142
|
], ngImport: i0 }); }
|
|
9064
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MinFileNameLengthValidator, providedIn: 'root' }); }
|
|
9065
9143
|
}
|
|
9066
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type:
|
|
9067
|
-
type: Injectable,
|
|
9068
|
-
args: [{ providedIn: 'root' }]
|
|
9069
|
-
}, {
|
|
9144
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ChrHoverDirective, decorators: [{
|
|
9070
9145
|
type: Directive,
|
|
9071
9146
|
args: [{
|
|
9072
|
-
selector: '[
|
|
9147
|
+
selector: '[chrHover]',
|
|
9073
9148
|
providers: [
|
|
9074
9149
|
{
|
|
9075
|
-
provide:
|
|
9076
|
-
|
|
9077
|
-
|
|
9150
|
+
provide: CDK_CONNECTED_OVERLAY_DEFAULT_CONFIG,
|
|
9151
|
+
useFactory: () => {
|
|
9152
|
+
disableClose: true;
|
|
9153
|
+
},
|
|
9078
9154
|
},
|
|
9079
9155
|
],
|
|
9080
|
-
standalone: true,
|
|
9081
9156
|
}]
|
|
9082
|
-
}],
|
|
9083
|
-
|
|
9084
|
-
|
|
9085
|
-
|
|
9086
|
-
const files = Array.isArray(value) ? value : [value];
|
|
9087
|
-
if (!value)
|
|
9088
|
-
return null;
|
|
9089
|
-
const errors = {};
|
|
9090
|
-
for (let i = 0; i < files.length; i++) {
|
|
9091
|
-
const fileNameLength = files[i].name?.length;
|
|
9092
|
-
if (fileNameLength === undefined)
|
|
9093
|
-
continue;
|
|
9094
|
-
if (fileNameLength < minLength)
|
|
9095
|
-
errors[i] = fileNameLength;
|
|
9096
|
-
}
|
|
9097
|
-
if (Object.keys(errors).length <= 0)
|
|
9098
|
-
return null;
|
|
9099
|
-
return {
|
|
9100
|
-
minFileNameLength: {
|
|
9101
|
-
minFileNameLength: minLength,
|
|
9102
|
-
indexes: errors,
|
|
9103
|
-
},
|
|
9104
|
-
indexes: errors,
|
|
9105
|
-
};
|
|
9106
|
-
};
|
|
9107
|
-
}
|
|
9157
|
+
}], ctorParameters: () => [], propDecorators: { template: [{
|
|
9158
|
+
type: Input,
|
|
9159
|
+
args: ['chrHover']
|
|
9160
|
+
}], chrHoverContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "chrHoverContext", required: false }] }], chrHoverSnap: [{ type: i0.Input, args: [{ isSignal: true, alias: "chrHoverSnap", required: false }] }], chrHoverPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "chrHoverPosition", required: false }] }], chrHoverCloseDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "chrHoverCloseDelay", required: false }] }] } });
|
|
9108
9161
|
|
|
9109
|
-
class
|
|
9110
|
-
|
|
9111
|
-
|
|
9112
|
-
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
|
|
9117
|
-
|
|
9118
|
-
|
|
9119
|
-
set rows(value) {
|
|
9120
|
-
this.count = value.length;
|
|
9121
|
-
this._rows = value.map((row, index) => {
|
|
9122
|
-
if (!this.hasPrimaryKey && !row.hasOwnProperty(this.rowNumberIdentity)) {
|
|
9123
|
-
return { [this.rowNumberIdentity]: index + 1, ...row };
|
|
9124
|
-
}
|
|
9125
|
-
return row;
|
|
9162
|
+
class CsvExporter {
|
|
9163
|
+
export(data, columns) {
|
|
9164
|
+
const csvRows = [];
|
|
9165
|
+
csvRows.push(columns.join(','));
|
|
9166
|
+
data.forEach((row) => {
|
|
9167
|
+
const values = columns.map((col) => {
|
|
9168
|
+
const cell = row[col];
|
|
9169
|
+
return typeof cell === 'string' ? cell.replace(/;/g, ',') : cell;
|
|
9170
|
+
});
|
|
9171
|
+
csvRows.push(values.join(','));
|
|
9126
9172
|
});
|
|
9127
|
-
|
|
9173
|
+
const csvContent = csvRows.join('\n');
|
|
9174
|
+
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
|
|
9175
|
+
return URL.createObjectURL(blob);
|
|
9128
9176
|
}
|
|
9129
|
-
|
|
9130
|
-
|
|
9131
|
-
|
|
9132
|
-
|
|
9133
|
-
|
|
9134
|
-
|
|
9135
|
-
|
|
9136
|
-
|
|
9137
|
-
|
|
9138
|
-
|
|
9139
|
-
|
|
9140
|
-
|
|
9141
|
-
|
|
9142
|
-
|
|
9143
|
-
|
|
9144
|
-
|
|
9145
|
-
|
|
9146
|
-
|
|
9147
|
-
|
|
9148
|
-
|
|
9149
|
-
|
|
9150
|
-
|
|
9151
|
-
|
|
9152
|
-
|
|
9153
|
-
|
|
9154
|
-
|
|
9155
|
-
|
|
9156
|
-
|
|
9157
|
-
|
|
9158
|
-
|
|
9159
|
-
|
|
9160
|
-
|
|
9161
|
-
|
|
9162
|
-
|
|
9163
|
-
|
|
9164
|
-
|
|
9165
|
-
|
|
9166
|
-
|
|
9167
|
-
|
|
9168
|
-
|
|
9169
|
-
|
|
9170
|
-
|
|
9171
|
-
|
|
9172
|
-
|
|
9173
|
-
|
|
9174
|
-
|
|
9175
|
-
|
|
9176
|
-
isUpdatable: false,
|
|
9177
|
-
tooltip: `${inferredType} ${length ? `(${inferredType})` : ''}`,
|
|
9178
|
-
columnName: key,
|
|
9179
|
-
dataType: inferredType,
|
|
9180
|
-
isNullable: false,
|
|
9181
|
-
};
|
|
9182
|
-
this.columnMetadatas.push(md);
|
|
9183
|
-
}
|
|
9177
|
+
canExport(filetype) {
|
|
9178
|
+
const supportedTypes = ['.csv', 'text/csv', 'csv'];
|
|
9179
|
+
return supportedTypes.includes(filetype);
|
|
9180
|
+
}
|
|
9181
|
+
}
|
|
9182
|
+
|
|
9183
|
+
class JsonExporter {
|
|
9184
|
+
export(data, columns) {
|
|
9185
|
+
const jsonData = data.map((row) => {
|
|
9186
|
+
const obj = {};
|
|
9187
|
+
columns.forEach((col) => {
|
|
9188
|
+
obj[col] = row[col];
|
|
9189
|
+
});
|
|
9190
|
+
return obj;
|
|
9191
|
+
});
|
|
9192
|
+
const blob = new Blob([JSON.stringify(jsonData, null, 2)], {
|
|
9193
|
+
type: 'application/json;charset=utf-8;',
|
|
9194
|
+
});
|
|
9195
|
+
return URL.createObjectURL(blob);
|
|
9196
|
+
}
|
|
9197
|
+
canExport(filetype) {
|
|
9198
|
+
const supportedTypes = ['.json', 'application/json', 'json'];
|
|
9199
|
+
return supportedTypes.includes(filetype);
|
|
9200
|
+
}
|
|
9201
|
+
}
|
|
9202
|
+
|
|
9203
|
+
class DataExporterService {
|
|
9204
|
+
constructor() {
|
|
9205
|
+
this.exporter = [new CsvExporter(), new JsonExporter()];
|
|
9206
|
+
}
|
|
9207
|
+
setExporters(exporters) {
|
|
9208
|
+
this.exporter = exporters;
|
|
9209
|
+
}
|
|
9210
|
+
registerExporter(exporter) {
|
|
9211
|
+
this.exporter.push(exporter);
|
|
9212
|
+
}
|
|
9213
|
+
export(data, columns, filetype, filename = 'export', autodownload = false) {
|
|
9214
|
+
const exporter = this.exporter.find((exp) => exp.canExport(filetype));
|
|
9215
|
+
if (exporter) {
|
|
9216
|
+
const url = exporter.export(data, columns);
|
|
9217
|
+
if (autodownload) {
|
|
9218
|
+
const link = document.createElement('a');
|
|
9219
|
+
link.href = url;
|
|
9220
|
+
link.download = `${filename}.${filetype.split('.').pop()}`;
|
|
9221
|
+
document.body.appendChild(link);
|
|
9222
|
+
link.click();
|
|
9223
|
+
document.body.removeChild(link);
|
|
9184
9224
|
}
|
|
9185
|
-
|
|
9225
|
+
return url;
|
|
9226
|
+
}
|
|
9227
|
+
return null;
|
|
9228
|
+
}
|
|
9229
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: DataExporterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
9230
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: DataExporterService, providedIn: 'root' }); }
|
|
9231
|
+
}
|
|
9232
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: DataExporterService, decorators: [{
|
|
9233
|
+
type: Injectable,
|
|
9234
|
+
args: [{
|
|
9235
|
+
providedIn: 'root',
|
|
9236
|
+
}]
|
|
9237
|
+
}], ctorParameters: () => [] });
|
|
9238
|
+
|
|
9239
|
+
class CachingDefaults {
|
|
9240
|
+
constructor(init) {
|
|
9241
|
+
this.duration = 1000 * 60 * 5; // 5 minutes par défaut;
|
|
9242
|
+
Object.assign(this, init);
|
|
9243
|
+
}
|
|
9244
|
+
}
|
|
9245
|
+
const CHR_CACHING_DEFAULTS = new InjectionToken('CHR_CACHING_DEFAULTS', {
|
|
9246
|
+
factory: () => new CachingDefaults(),
|
|
9247
|
+
});
|
|
9248
|
+
|
|
9249
|
+
/**
|
|
9250
|
+
* Token de contexte HTTP mettre cache la réponse d'une requête via l'intercepteur CachingInterceptor.
|
|
9251
|
+
* La ressource doit être spécifiée pour identifier l'entrée de cache.
|
|
9252
|
+
* Vous êtes responsable de l'invalidation du cache via le token INVALIDATE_CACHE.
|
|
9253
|
+
*/
|
|
9254
|
+
const ENABLE_CACHE = new HttpContextToken(() => null);
|
|
9255
|
+
/**
|
|
9256
|
+
* Token de contexte HTTP pour invalider une entrée de cache spécifique.
|
|
9257
|
+
* La ressource doit être spécifiée pour identifier l'entrée de cache à invalider.
|
|
9258
|
+
*/
|
|
9259
|
+
const INVALIDATE_CACHE = new HttpContextToken(() => null);
|
|
9260
|
+
class CacheService {
|
|
9261
|
+
constructor() {
|
|
9262
|
+
this._default = inject(CHR_CACHING_DEFAULTS);
|
|
9263
|
+
this._cache = {};
|
|
9186
9264
|
/**
|
|
9187
|
-
*
|
|
9265
|
+
* Récupère une valeur mise en cache par sa clé
|
|
9266
|
+
* @param key La clé de la valeur à récupérer
|
|
9267
|
+
* @returns La valeur mise en cache ou undefined si elle n'existe pas
|
|
9188
9268
|
*/
|
|
9189
|
-
this.
|
|
9190
|
-
const
|
|
9191
|
-
|
|
9192
|
-
|
|
9193
|
-
|
|
9269
|
+
this.get = (key) => {
|
|
9270
|
+
const entry = this._cache[key];
|
|
9271
|
+
if (entry) {
|
|
9272
|
+
// Vérifie si l'entrée est expirée
|
|
9273
|
+
if (entry.status != 'expired' && Date.now() < entry.expiry) {
|
|
9274
|
+
return entry.value;
|
|
9194
9275
|
}
|
|
9195
9276
|
else {
|
|
9196
|
-
|
|
9277
|
+
// Marque l'entrée comme expirée
|
|
9278
|
+
entry.status = 'expired';
|
|
9279
|
+
return null;
|
|
9197
9280
|
}
|
|
9198
9281
|
}
|
|
9199
|
-
return
|
|
9282
|
+
return null;
|
|
9200
9283
|
};
|
|
9201
|
-
|
|
9202
|
-
|
|
9203
|
-
|
|
9204
|
-
|
|
9205
|
-
|
|
9206
|
-
|
|
9207
|
-
|
|
9208
|
-
|
|
9209
|
-
|
|
9210
|
-
|
|
9211
|
-
|
|
9212
|
-
isGenerated: false,
|
|
9213
|
-
isUpdatable: false,
|
|
9214
|
-
tooltip: `${md.dataType?.toUpperCase()} ${md.length ? `(${md.length})` : ''}`,
|
|
9215
|
-
...md,
|
|
9216
|
-
}));
|
|
9217
|
-
}
|
|
9218
|
-
}
|
|
9219
|
-
|
|
9220
|
-
class AutoDataSource {
|
|
9221
|
-
constructor(config) {
|
|
9222
|
-
this._subscriptions = [];
|
|
9223
|
-
// Signaux internes
|
|
9224
|
-
this._datagrid = signal(null, /* @ts-ignore */
|
|
9225
|
-
...(ngDevMode ? [{ debugName: "_datagrid" }] : /* istanbul ignore next */ []));
|
|
9226
|
-
this._datagridElement = signal(null, /* @ts-ignore */
|
|
9227
|
-
...(ngDevMode ? [{ debugName: "_datagridElement" }] : /* istanbul ignore next */ []));
|
|
9228
|
-
this._data = signal(undefined, /* @ts-ignore */
|
|
9229
|
-
...(ngDevMode ? [{ debugName: "_data" }] : /* istanbul ignore next */ []));
|
|
9230
|
-
// protected _currentPage = signal(1);
|
|
9231
|
-
// protected _pageSize = signal(10);
|
|
9232
|
-
this._sort = signal(null, /* @ts-ignore */
|
|
9233
|
-
...(ngDevMode ? [{ debugName: "_sort" }] : /* istanbul ignore next */ []));
|
|
9234
|
-
this._filter = signal({}, /* @ts-ignore */
|
|
9235
|
-
...(ngDevMode ? [{ debugName: "_filter" }] : /* istanbul ignore next */ []));
|
|
9236
|
-
this._groupBy = signal(null, /* @ts-ignore */
|
|
9237
|
-
...(ngDevMode ? [{ debugName: "_groupBy" }] : /* istanbul ignore next */ []));
|
|
9238
|
-
this._loading = signal(false, /* @ts-ignore */
|
|
9239
|
-
...(ngDevMode ? [{ debugName: "_loading" }] : /* istanbul ignore next */ []));
|
|
9240
|
-
this._error = signal(null, /* @ts-ignore */
|
|
9241
|
-
...(ngDevMode ? [{ debugName: "_error" }] : /* istanbul ignore next */ []));
|
|
9242
|
-
// Données exposées (read-only)
|
|
9243
|
-
this.data = this._data.asReadonly();
|
|
9244
|
-
// public readonly currentPage: Signal<number> = this._currentPage.asReadonly();
|
|
9245
|
-
// public readonly pageSize: Signal<number> = this._pageSize.asReadonly();
|
|
9246
|
-
this.sort = this._sort.asReadonly();
|
|
9247
|
-
this.filter = this._filter.asReadonly();
|
|
9248
|
-
this.groupBy = this._groupBy.asReadonly();
|
|
9249
|
-
this.loading = this._loading.asReadonly();
|
|
9250
|
-
this.error = this._error.asReadonly();
|
|
9251
|
-
// Données traitées
|
|
9252
|
-
this.processedData = computed(() => {
|
|
9253
|
-
let result = this._data();
|
|
9254
|
-
if (!result)
|
|
9255
|
-
return undefined;
|
|
9256
|
-
result.total = result.rows.length ?? -1;
|
|
9257
|
-
// Filtrage côté client
|
|
9258
|
-
if (this.config.enableClientSideFiltering) {
|
|
9259
|
-
result = this.applyFilters(result, this.filter());
|
|
9260
|
-
}
|
|
9261
|
-
// Tri côté client
|
|
9262
|
-
if (this.config.enableClientSideSorting) {
|
|
9263
|
-
result = this.applySort(result, this._sort());
|
|
9264
|
-
}
|
|
9265
|
-
// Pagination côté client
|
|
9266
|
-
if (this.config.enableClientSidePagination) {
|
|
9267
|
-
// Do nothing, it is handled by the data grid directly
|
|
9268
|
-
}
|
|
9269
|
-
result.count = result.rows.length;
|
|
9270
|
-
return result;
|
|
9271
|
-
}, /* @ts-ignore */
|
|
9272
|
-
...(ngDevMode ? [{ debugName: "processedData" }] : /* istanbul ignore next */ []));
|
|
9273
|
-
this.config = {
|
|
9274
|
-
initialData: config?.initialData,
|
|
9275
|
-
pageSize: config?.pageSize ?? 10,
|
|
9276
|
-
enableClientSidePagination: config?.enableClientSidePagination ?? true,
|
|
9277
|
-
enableClientSideFiltering: config?.enableClientSideFiltering ?? true,
|
|
9278
|
-
enableClientSideSorting: config?.enableClientSideSorting ?? true,
|
|
9284
|
+
/**
|
|
9285
|
+
* Met en cache une valeur avec une clé spécifique
|
|
9286
|
+
* @param key La clé sous laquelle stocker la valeur
|
|
9287
|
+
* @param value La valeur à mettre en cache
|
|
9288
|
+
*/
|
|
9289
|
+
this.set = (key, value) => {
|
|
9290
|
+
this._cache[key] = {
|
|
9291
|
+
value: value,
|
|
9292
|
+
expiry: Date.now() + this._cacheValidityDuration,
|
|
9293
|
+
status: 'valid',
|
|
9294
|
+
};
|
|
9279
9295
|
};
|
|
9280
|
-
|
|
9281
|
-
|
|
9282
|
-
|
|
9283
|
-
|
|
9284
|
-
|
|
9285
|
-
if (this.
|
|
9286
|
-
this.
|
|
9287
|
-
|
|
9288
|
-
|
|
9289
|
-
|
|
9290
|
-
|
|
9291
|
-
|
|
9292
|
-
|
|
9293
|
-
|
|
9294
|
-
|
|
9295
|
-
}
|
|
9296
|
-
|
|
9297
|
-
// Méthode pour enregistrer la datagrid et écouter les événements de base
|
|
9298
|
-
registerDataGrid(element) {
|
|
9299
|
-
if (!element)
|
|
9300
|
-
return;
|
|
9301
|
-
this._datagridElement.set(element instanceof ElementRef ? element : null);
|
|
9302
|
-
const datagrid = (element instanceof ElementRef ? element.nativeElement : element);
|
|
9303
|
-
this._datagrid.set(datagrid);
|
|
9304
|
-
this._subscriptions.push(
|
|
9305
|
-
// datagrid.pageChange.subscribe((page: number) => {
|
|
9306
|
-
// console.log(
|
|
9307
|
-
// 'Page change event received:',
|
|
9308
|
-
// page,
|
|
9309
|
-
// this._datagridElement(),
|
|
9310
|
-
// element,
|
|
9311
|
-
// );
|
|
9312
|
-
// // this._subscriptions.push(this.handlePageChange(page).subscribe());
|
|
9313
|
-
// }),
|
|
9314
|
-
// datagrid.pageSizeChange.subscribe((pageSize: number) => {
|
|
9315
|
-
// // this._subscriptions
|
|
9316
|
-
// // .push(
|
|
9317
|
-
// // this.handlePageSizeChange(pageSize).subscribe(),
|
|
9318
|
-
// // );
|
|
9319
|
-
// }),
|
|
9320
|
-
datagrid.sort.subscribe((sort) => {
|
|
9321
|
-
this._subscriptions.push(this.handleSortChange(sort).subscribe());
|
|
9322
|
-
}), datagrid.filter.subscribe((filter) => {
|
|
9323
|
-
this._subscriptions.push(this.handleFilterChange(filter).subscribe());
|
|
9324
|
-
}), datagrid.groupBy.subscribe((group) => {
|
|
9325
|
-
this._subscriptions.push(this.handleGroupChange(group).subscribe());
|
|
9326
|
-
}));
|
|
9327
|
-
}
|
|
9328
|
-
// Méthodes publiques pour gérer les événements de la datagrid
|
|
9329
|
-
// public handlePageChange(page: number): Observable<void> {
|
|
9330
|
-
// this._currentPage.set(page);
|
|
9331
|
-
// return this.onPageChange(page);
|
|
9332
|
-
// }
|
|
9333
|
-
// public handlePageSizeChange(pageSize: number): Observable<void> {
|
|
9334
|
-
// this._pageSize.set(pageSize);
|
|
9335
|
-
// this._currentPage.set(1); // Reset à la première page
|
|
9336
|
-
// return this.onPageSizeChange(pageSize);
|
|
9337
|
-
// }
|
|
9338
|
-
handleSortChange(sort) {
|
|
9339
|
-
this._sort.set(sort);
|
|
9340
|
-
return this.onSortChange(sort);
|
|
9341
|
-
}
|
|
9342
|
-
handleFilterChange(filter) {
|
|
9343
|
-
this._filter.set(filter);
|
|
9344
|
-
this._datagrid()?.currentPage.set(1); // Reset à la première page
|
|
9345
|
-
return this.onFilterChange(filter);
|
|
9296
|
+
/**
|
|
9297
|
+
* Invalide une entrée de cache spécifique
|
|
9298
|
+
* @param key La clé de l'entrée à invalider
|
|
9299
|
+
*/
|
|
9300
|
+
this.invalidate = (key) => {
|
|
9301
|
+
if (this._cache[key]) {
|
|
9302
|
+
this._cache[key].status = 'expired';
|
|
9303
|
+
}
|
|
9304
|
+
};
|
|
9305
|
+
/**
|
|
9306
|
+
* Mets à jour la durée de validité du cache
|
|
9307
|
+
* @param duration Durée en millisecondes
|
|
9308
|
+
*/
|
|
9309
|
+
this.setCacheValidityDuration = (duration) => {
|
|
9310
|
+
this._cacheValidityDuration = duration;
|
|
9311
|
+
};
|
|
9312
|
+
this._cacheValidityDuration = this._default.duration;
|
|
9346
9313
|
}
|
|
9347
|
-
|
|
9348
|
-
|
|
9349
|
-
|
|
9350
|
-
|
|
9314
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CacheService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
9315
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CacheService, providedIn: 'root' }); }
|
|
9316
|
+
}
|
|
9317
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CacheService, decorators: [{
|
|
9318
|
+
type: Injectable,
|
|
9319
|
+
args: [{
|
|
9320
|
+
providedIn: 'root',
|
|
9321
|
+
}]
|
|
9322
|
+
}], ctorParameters: () => [] });
|
|
9323
|
+
|
|
9324
|
+
const ENABLE_PROGRESS = new HttpContextToken(() => null);
|
|
9325
|
+
class ProgressService {
|
|
9326
|
+
constructor() {
|
|
9327
|
+
this._progressStates = {};
|
|
9328
|
+
/**
|
|
9329
|
+
* Récupère l'état de progression pour une clé spécifique
|
|
9330
|
+
* @param key La clé de l'état de progression à récupérer
|
|
9331
|
+
* @returns L'état de progression ou null si inexistant
|
|
9332
|
+
*/
|
|
9333
|
+
this.get = (key) => {
|
|
9334
|
+
const obs = this._progressStates[key];
|
|
9335
|
+
if (!obs)
|
|
9336
|
+
return null;
|
|
9337
|
+
return this._progressStates[key].asObservable();
|
|
9338
|
+
};
|
|
9339
|
+
/**
|
|
9340
|
+
* Met à jour l'état de progression pour une clé spécifique
|
|
9341
|
+
* @param key La clé de l'état de progression à mettre à jour
|
|
9342
|
+
* @param state Le nouvel état de progression
|
|
9343
|
+
*/
|
|
9344
|
+
this.set = (key, state) => {
|
|
9345
|
+
if (this._progressStates[key]) {
|
|
9346
|
+
this._progressStates[key].next(state);
|
|
9347
|
+
}
|
|
9348
|
+
else {
|
|
9349
|
+
this._progressStates[key] = new BehaviorSubject(state);
|
|
9350
|
+
}
|
|
9351
|
+
};
|
|
9351
9352
|
}
|
|
9352
|
-
|
|
9353
|
-
|
|
9353
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ProgressService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
9354
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ProgressService, providedIn: 'root' }); }
|
|
9355
|
+
}
|
|
9356
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ProgressService, decorators: [{
|
|
9357
|
+
type: Injectable,
|
|
9358
|
+
args: [{
|
|
9359
|
+
providedIn: 'root',
|
|
9360
|
+
}]
|
|
9361
|
+
}] });
|
|
9362
|
+
|
|
9363
|
+
class CookiesService {
|
|
9364
|
+
constructor() { }
|
|
9365
|
+
/**
|
|
9366
|
+
* delete cookie
|
|
9367
|
+
* @param name
|
|
9368
|
+
*/
|
|
9369
|
+
deleteCookie(name) {
|
|
9370
|
+
this.setCookie(name, "", -1);
|
|
9354
9371
|
}
|
|
9355
|
-
|
|
9356
|
-
|
|
9357
|
-
|
|
9372
|
+
/**
|
|
9373
|
+
* get cookie
|
|
9374
|
+
* @param {string} name
|
|
9375
|
+
* @returns {string}
|
|
9376
|
+
*/
|
|
9377
|
+
getCookie(name) {
|
|
9378
|
+
const ca = decodeURIComponent(document.cookie).split(";");
|
|
9379
|
+
const caLen = ca.length;
|
|
9380
|
+
const cookieName = `${name}=`;
|
|
9381
|
+
let c;
|
|
9382
|
+
for (let i = 0; i < caLen; i += 1) {
|
|
9383
|
+
c = ca[i].replace(/^\s+/g, "");
|
|
9384
|
+
if (c.indexOf(cookieName) === 0) {
|
|
9385
|
+
return c.substring(cookieName.length, c.length);
|
|
9386
|
+
}
|
|
9358
9387
|
}
|
|
9359
|
-
|
|
9360
|
-
updated.rows = rows;
|
|
9361
|
-
updated.total = rows.length;
|
|
9362
|
-
this._data.set(updated);
|
|
9363
|
-
}
|
|
9364
|
-
setData(data) {
|
|
9365
|
-
this._data.set(data);
|
|
9366
|
-
}
|
|
9367
|
-
// Méthodes virtuelles à surcharger pour créer une data source serveur-side
|
|
9368
|
-
onPageChange(page) {
|
|
9369
|
-
// Comportement par défaut : rien (pagination côté client)
|
|
9370
|
-
return of(void 0);
|
|
9371
|
-
}
|
|
9372
|
-
onPageSizeChange(pageSize) {
|
|
9373
|
-
// Comportement par défaut : rien (pagination côté client)
|
|
9374
|
-
return of(void 0);
|
|
9375
|
-
}
|
|
9376
|
-
onSortChange(sort) {
|
|
9377
|
-
// Comportement par défaut : rien (tri côté client)
|
|
9378
|
-
return of(void 0);
|
|
9379
|
-
}
|
|
9380
|
-
onFilterChange(filter) {
|
|
9381
|
-
// Comportement par défaut : rien (filtrage côté client)
|
|
9382
|
-
return of(void 0);
|
|
9383
|
-
}
|
|
9384
|
-
onGroupChange(group) {
|
|
9385
|
-
// Comportement par défaut : rien
|
|
9386
|
-
return of(void 0);
|
|
9388
|
+
return "";
|
|
9387
9389
|
}
|
|
9388
|
-
|
|
9389
|
-
|
|
9390
|
-
|
|
9390
|
+
/**
|
|
9391
|
+
* set cookie
|
|
9392
|
+
* @param {string} name
|
|
9393
|
+
* @param {string} value
|
|
9394
|
+
* @param {number} expireDays
|
|
9395
|
+
* @param {string} path
|
|
9396
|
+
*/
|
|
9397
|
+
setCookie(name, value, expireDays, path = "") {
|
|
9398
|
+
const d = new Date();
|
|
9399
|
+
d.setTime(d.getTime() + expireDays * 24 * 60 * 60 * 1000);
|
|
9400
|
+
const expires = `expires=${d.toUTCString()}`;
|
|
9401
|
+
const cpath = path ? `; path=${path}` : "";
|
|
9402
|
+
document.cookie = `${name}=${value}; ${expires}${cpath}; SameSite=Lax`;
|
|
9391
9403
|
}
|
|
9392
|
-
|
|
9393
|
-
|
|
9394
|
-
|
|
9395
|
-
|
|
9396
|
-
|
|
9397
|
-
|
|
9398
|
-
|
|
9399
|
-
|
|
9400
|
-
|
|
9401
|
-
|
|
9402
|
-
|
|
9403
|
-
|
|
9404
|
-
|
|
9405
|
-
|
|
9406
|
-
|
|
9407
|
-
|
|
9408
|
-
case DGFilterMode.EQUALS:
|
|
9409
|
-
return stringValue === filterValue;
|
|
9410
|
-
case DGFilterMode.NOT_EQUALS:
|
|
9411
|
-
return stringValue !== filterValue;
|
|
9412
|
-
case DGFilterMode.GREATER_OR_EQUAL:
|
|
9413
|
-
return Number(value) >= Number(filter.value);
|
|
9414
|
-
case DGFilterMode.LOWER_OR_EQUAL:
|
|
9415
|
-
return Number(value) <= Number(filter.value);
|
|
9416
|
-
default:
|
|
9417
|
-
return true;
|
|
9418
|
-
}
|
|
9419
|
-
});
|
|
9420
|
-
});
|
|
9421
|
-
const cloned = data.clone();
|
|
9422
|
-
cloned.rows = filteredRows;
|
|
9423
|
-
return cloned;
|
|
9404
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CookiesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
9405
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CookiesService, providedIn: "root" }); }
|
|
9406
|
+
}
|
|
9407
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CookiesService, decorators: [{
|
|
9408
|
+
type: Injectable,
|
|
9409
|
+
args: [{
|
|
9410
|
+
providedIn: "root",
|
|
9411
|
+
}]
|
|
9412
|
+
}], ctorParameters: () => [] });
|
|
9413
|
+
|
|
9414
|
+
const SHOW_SPINNER = new HttpContextToken(() => true);
|
|
9415
|
+
|
|
9416
|
+
class MinFileNameLengthValidator {
|
|
9417
|
+
constructor() {
|
|
9418
|
+
this.max = input(0, /* @ts-ignore */
|
|
9419
|
+
...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
|
|
9424
9420
|
}
|
|
9425
|
-
|
|
9426
|
-
|
|
9427
|
-
|
|
9428
|
-
const sortedRows = [...data.rows].sort((a, b) => {
|
|
9429
|
-
const aValue = a[sort.column];
|
|
9430
|
-
const bValue = b[sort.column];
|
|
9431
|
-
if (aValue === bValue)
|
|
9432
|
-
return 0;
|
|
9433
|
-
if (aValue === null || aValue === undefined)
|
|
9434
|
-
return 1;
|
|
9435
|
-
if (bValue === null || bValue === undefined)
|
|
9436
|
-
return -1;
|
|
9437
|
-
const comparison = aValue > bValue ? 1 : -1;
|
|
9438
|
-
return sort.isAsc ? comparison : -comparison;
|
|
9439
|
-
});
|
|
9440
|
-
const cloned = data.clone();
|
|
9441
|
-
cloned.rows = sortedRows;
|
|
9442
|
-
return cloned;
|
|
9421
|
+
validate(control) {
|
|
9422
|
+
const max = this.max();
|
|
9423
|
+
return max ? minFileNameLength(max)(control) : null;
|
|
9443
9424
|
}
|
|
9425
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MinFileNameLengthValidator, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
9426
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: MinFileNameLengthValidator, isStandalone: true, selector: "[app-min-file-name-length]", inputs: { max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
9427
|
+
{
|
|
9428
|
+
provide: NG_VALIDATORS,
|
|
9429
|
+
useExisting: MinFileNameLengthValidator,
|
|
9430
|
+
multi: true,
|
|
9431
|
+
},
|
|
9432
|
+
], ngImport: i0 }); }
|
|
9433
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MinFileNameLengthValidator, providedIn: 'root' }); }
|
|
9434
|
+
}
|
|
9435
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MinFileNameLengthValidator, decorators: [{
|
|
9436
|
+
type: Injectable,
|
|
9437
|
+
args: [{ providedIn: 'root' }]
|
|
9438
|
+
}, {
|
|
9439
|
+
type: Directive,
|
|
9440
|
+
args: [{
|
|
9441
|
+
selector: '[app-min-file-name-length]',
|
|
9442
|
+
providers: [
|
|
9443
|
+
{
|
|
9444
|
+
provide: NG_VALIDATORS,
|
|
9445
|
+
useExisting: MinFileNameLengthValidator,
|
|
9446
|
+
multi: true,
|
|
9447
|
+
},
|
|
9448
|
+
],
|
|
9449
|
+
standalone: true,
|
|
9450
|
+
}]
|
|
9451
|
+
}], propDecorators: { max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }] } });
|
|
9452
|
+
function minFileNameLength(minLength) {
|
|
9453
|
+
return (control) => {
|
|
9454
|
+
const value = control.value;
|
|
9455
|
+
const files = Array.isArray(value) ? value : [value];
|
|
9456
|
+
if (!value)
|
|
9457
|
+
return null;
|
|
9458
|
+
const errors = {};
|
|
9459
|
+
for (let i = 0; i < files.length; i++) {
|
|
9460
|
+
const fileNameLength = files[i].name?.length;
|
|
9461
|
+
if (fileNameLength === undefined)
|
|
9462
|
+
continue;
|
|
9463
|
+
if (fileNameLength < minLength)
|
|
9464
|
+
errors[i] = fileNameLength;
|
|
9465
|
+
}
|
|
9466
|
+
if (Object.keys(errors).length <= 0)
|
|
9467
|
+
return null;
|
|
9468
|
+
return {
|
|
9469
|
+
minFileNameLength: {
|
|
9470
|
+
minFileNameLength: minLength,
|
|
9471
|
+
indexes: errors,
|
|
9472
|
+
},
|
|
9473
|
+
indexes: errors,
|
|
9474
|
+
};
|
|
9475
|
+
};
|
|
9444
9476
|
}
|
|
9445
9477
|
|
|
9446
9478
|
const OldSpinnerInterceptor = (req, next) => {
|