@ai-table/grid 0.1.28 → 0.1.29

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.
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../packages/grid/src/core/utils/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAoB,MAAM,eAAe,CAAC;AACzE,OAAO,EAAgB,aAAa,EAAiB,cAAc,EAAE,YAAY,EAAY,MAAM,iBAAiB,CAAC;AAErH,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,wBAAgB,aAAa,CACzB,OAAO,EAAE,cAAc,CAAC,cAAc,CAAC,EACvC,MAAM,EAAE,cAAc,CAAC,aAAa,CAAC,EACrC,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,GAC/B,OAAO,CAwCT;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAahF"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../packages/grid/src/core/utils/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAoB,MAAM,eAAe,CAAC;AACzE,OAAO,EAAgB,aAAa,EAAiB,cAAc,EAAE,YAAY,EAAY,MAAM,iBAAiB,CAAC;AAErH,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,wBAAgB,aAAa,CACzB,OAAO,EAAE,cAAc,CAAC,cAAc,CAAC,EACvC,MAAM,EAAE,cAAc,CAAC,aAAa,CAAC,EACrC,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,GAC/B,OAAO,CAyCT;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAahF"}
@@ -29,7 +29,7 @@ import { AITableFieldGroup, AITableFieldType, AITableRowColumnType, DragType, is
29
29
  import ObjectID from 'bson-objectid';
30
30
  import { customAlphabet } from 'nanoid';
31
31
  import * as _ from 'lodash';
32
- import ___default, { isNumber, includes, values, isString, isObject } from 'lodash';
32
+ import ___default, { isNumber, includes, values, isString, isNil, isObject } from 'lodash';
33
33
  import * as i1 from '@angular/forms';
34
34
  import { FormsModule } from '@angular/forms';
35
35
  import { ThyDatePicker, ThyDatePickerFormatPipe } from 'ngx-tethys/date-picker';
@@ -1354,6 +1354,7 @@ function createAITable(records, fields, gridData) {
1354
1354
  selectedCells: new Set(),
1355
1355
  activeCell: null,
1356
1356
  expandCell: null,
1357
+ editingCell: null,
1357
1358
  selectAllState: AITableSelectAllState.none
1358
1359
  }),
1359
1360
  keywordsMatchedCells: signal(new Set()),
@@ -8789,11 +8790,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
8789
8790
  class AITableFillHandle {
8790
8791
  constructor() {
8791
8792
  this.config = input.required();
8792
- this.hasSelectedCells = computed(() => {
8793
- return this.config().aiTable.selection().selectedCells.size > 0;
8794
- });
8795
- this.readonly = computed(() => {
8796
- return this.config().readonly;
8793
+ this.showFillHandle = computed(() => {
8794
+ const { aiTable, readonly } = this.config();
8795
+ const selection = aiTable.selection();
8796
+ const hasSelectedCells = selection.selectedCells.size > 0;
8797
+ const isExpandCell = selection.expandCell;
8798
+ const isEditingCell = selection.editingCell;
8799
+ return hasSelectedCells && !readonly && !isEditingCell && !isExpandCell;
8797
8800
  });
8798
8801
  this.handleConfig = computed(() => {
8799
8802
  const { aiTable, coordinate } = this.config();
@@ -8826,7 +8829,7 @@ class AITableFillHandle {
8826
8829
  }
8827
8830
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableFillHandle, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8828
8831
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableFillHandle, isStandalone: true, selector: "ai-table-fill-handle", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
8829
- @if (hasSelectedCells() && !readonly()) {
8832
+ @if (showFillHandle()) {
8830
8833
  <ko-rect [config]="handleConfig()"></ko-rect>
8831
8834
  }
8832
8835
  `, isInline: true, dependencies: [{ kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }] }); }
@@ -8836,7 +8839,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
8836
8839
  args: [{
8837
8840
  selector: 'ai-table-fill-handle',
8838
8841
  template: `
8839
- @if (hasSelectedCells() && !readonly()) {
8842
+ @if (showFillHandle()) {
8840
8843
  <ko-rect [config]="handleConfig()"></ko-rect>
8841
8844
  }
8842
8845
  `,
@@ -9022,20 +9025,6 @@ class AITableFieldStat {
9022
9025
  const { width } = this.config();
9023
9026
  return width - AI_TABLE_ACTION_COMMON_SIZE - AI_TABLE_CELL_PADDING;
9024
9027
  });
9025
- this.textData = computed(() => {
9026
- const textString = this.renderText() || '';
9027
- const availableTextWidth = this.availableTextWidth();
9028
- const { text, textWidth } = drawer.textEllipsis({
9029
- text: textString,
9030
- maxWidth: availableTextWidth,
9031
- fontSize: DEFAULT_FONT_SIZE,
9032
- fontWeight: DEFAULT_FONT_WEIGHT
9033
- });
9034
- return {
9035
- width: textWidth,
9036
- text
9037
- };
9038
- });
9039
9028
  this.groupConfig = computed(() => {
9040
9029
  return {
9041
9030
  x: this.config().x,
@@ -9061,7 +9050,7 @@ class AITableFieldStat {
9061
9050
  opacity: 1,
9062
9051
  listening: !readonly
9063
9052
  };
9064
- if (this.renderText()) {
9053
+ if (this.renderTexts()) {
9065
9054
  config.borders = [false, true, false, true];
9066
9055
  config.stroke = Colors.gray200;
9067
9056
  config.strokeWidth = AI_TABLE_CELL_LINE_BORDER;
@@ -9098,53 +9087,119 @@ class AITableFieldStat {
9098
9087
  const aiTable = this.aiTable();
9099
9088
  return {
9100
9089
  field: this.field(),
9101
- aiTable
9090
+ aiTable,
9091
+ getFieldValue: (record, options) => {
9092
+ const { aiTable, field } = options;
9093
+ const cellValue = AITableQueries.getFieldValue(aiTable, [record._id, field._id]);
9094
+ return transformToCellText(cellValue, options);
9095
+ }
9102
9096
  };
9103
9097
  });
9104
9098
  this.isActiveOrHover = computed(() => {
9105
9099
  return this.isActive() || this.isHover();
9106
9100
  });
9107
- this.renderText = computed(() => {
9101
+ this.renderTexts = computed(() => {
9102
+ const { height, width } = this.containerBox();
9108
9103
  const field = this.field();
9109
9104
  const records = this.records();
9110
9105
  const fieldModel = FieldModelMap[field.type];
9111
9106
  const selectedInfo = this.selectedInfo();
9107
+ let resultString = null;
9108
+ let formatString = null;
9109
+ let statValue = '';
9112
9110
  if (this.isFirstColumn() && selectedInfo.isSelected) {
9113
9111
  if (selectedInfo.selectedType === 'records') {
9114
- const result = getI18nTextByKey(this.aiTable(), AITableGridI18nKey.selectedRecordsCount);
9115
- return result.replace('{count}', selectedInfo.selectedCount.toString());
9112
+ formatString = getI18nTextByKey(this.aiTable(), AITableGridI18nKey.selectedRecordsCount);
9116
9113
  }
9117
9114
  else {
9118
- const result = getI18nTextByKey(this.aiTable(), AITableGridI18nKey.selectedCellsCount);
9119
- return result.replace('{count}', selectedInfo.selectedCount.toString());
9115
+ formatString = getI18nTextByKey(this.aiTable(), AITableGridI18nKey.selectedCellsCount);
9120
9116
  }
9117
+ resultString = formatString.replace('{count}', `${selectedInfo.selectedCount.toString()}`);
9118
+ statValue = selectedInfo.selectedCount.toString();
9121
9119
  }
9122
9120
  else {
9123
- let result = fieldModel.getStatFormatValue(records, this.options());
9124
- if (!result && this.isActiveOrHover()) {
9125
- result = getI18nTextByKey(this.aiTable(), AITableGridI18nKey.stat);
9121
+ statValue = fieldModel.stat(records, this.options());
9122
+ if (!isNil(statValue)) {
9123
+ formatString = fieldModel.getFormat(this.field(), this.aiTable());
9124
+ if (formatString) {
9125
+ resultString = formatString.replace('{{statValue}}', `${statValue.toString()}`);
9126
+ statValue = statValue.toString();
9127
+ }
9128
+ }
9129
+ else if (this.isActiveOrHover()) {
9130
+ formatString = getI18nTextByKey(this.aiTable(), AITableGridI18nKey.stat);
9131
+ resultString = getI18nTextByKey(this.aiTable(), AITableGridI18nKey.stat);
9126
9132
  }
9127
- return result;
9128
9133
  }
9134
+ if (!resultString) {
9135
+ return null;
9136
+ }
9137
+ const { text, textWidth } = drawer.textEllipsis({
9138
+ text: resultString,
9139
+ maxWidth: width - AI_TABLE_ACTION_COMMON_SIZE - AI_TABLE_CELL_PADDING,
9140
+ fontSize: DEFAULT_FONT_SIZE,
9141
+ fontWeight: DEFAULT_FONT_WEIGHT
9142
+ });
9143
+ return {
9144
+ texts: text.split(' '),
9145
+ totalWidth: textWidth,
9146
+ statValue: statValue || ''
9147
+ };
9129
9148
  });
9130
9149
  this.containerBox = computed(() => {
9131
9150
  const { height, width } = this.config();
9132
9151
  return { height, width };
9133
9152
  });
9134
- this.textConfig = computed(() => {
9153
+ this.textsConfig = computed(() => {
9135
9154
  const { height, width } = this.containerBox();
9136
- const text = this.renderText();
9137
- if (text) {
9138
- const renderWidth = this.textData().width;
9139
- return {
9140
- x: width - AI_TABLE_ACTION_COMMON_SIZE - renderWidth,
9141
- y: 0,
9142
- width: renderWidth,
9143
- height: height,
9144
- text: this.textData().text,
9145
- lineHeight: AI_TABLE_TEXT_LINE_HEIGHT,
9146
- listening: false
9147
- };
9155
+ const renderTexts = this.renderTexts();
9156
+ const result = [];
9157
+ let previousColor = Colors.gray700;
9158
+ if (renderTexts) {
9159
+ const { texts, totalWidth, statValue } = renderTexts;
9160
+ let remainingWidth = width - AI_TABLE_ACTION_COMMON_SIZE;
9161
+ for (const [index, text] of texts.entries()) {
9162
+ if (remainingWidth <= 0) {
9163
+ break;
9164
+ }
9165
+ let isLast = index === texts.length - 1;
9166
+ let isStatValue = statValue.includes(text.replace('%', '').replace('…', ''));
9167
+ let isEllipsis = text === '…';
9168
+ const { text: renderText, textWidth } = drawer.textEllipsis({
9169
+ text: isLast ? text : `${text} `,
9170
+ maxWidth: remainingWidth,
9171
+ fontSize: DEFAULT_FONT_SIZE,
9172
+ fontWeight: DEFAULT_FONT_WEIGHT
9173
+ });
9174
+ remainingWidth -= textWidth;
9175
+ let fill;
9176
+ if (isStatValue) {
9177
+ fill = Colors.gray700;
9178
+ }
9179
+ else if (isEllipsis) {
9180
+ fill = previousColor;
9181
+ }
9182
+ else {
9183
+ fill = Colors.gray600;
9184
+ }
9185
+ result.push({
9186
+ x: 0,
9187
+ y: 0,
9188
+ width: textWidth,
9189
+ height: height,
9190
+ fill,
9191
+ text: renderText,
9192
+ lineHeight: AI_TABLE_TEXT_LINE_HEIGHT,
9193
+ listening: false
9194
+ });
9195
+ previousColor = fill;
9196
+ }
9197
+ let startX = width - AI_TABLE_ACTION_COMMON_SIZE - totalWidth;
9198
+ result.forEach((item) => {
9199
+ item.x = startX;
9200
+ startX += item.width;
9201
+ });
9202
+ return result;
9148
9203
  }
9149
9204
  return null;
9150
9205
  });
@@ -9249,8 +9304,10 @@ class AITableFieldStat {
9249
9304
  ></ai-table-background>
9250
9305
 
9251
9306
  <ko-group>
9252
- @if (textConfig()) {
9253
- <ai-table-text [config]="textConfig()!"></ai-table-text>
9307
+ @if (textsConfig()) {
9308
+ @for (textConfig of textsConfig(); track $index) {
9309
+ <ai-table-text [config]="textConfig"></ai-table-text>
9310
+ }
9254
9311
  <ai-table-icon [config]="iconConfig()"></ai-table-icon>
9255
9312
  }
9256
9313
  </ko-group>
@@ -9271,8 +9328,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
9271
9328
  ></ai-table-background>
9272
9329
 
9273
9330
  <ko-group>
9274
- @if (textConfig()) {
9275
- <ai-table-text [config]="textConfig()!"></ai-table-text>
9331
+ @if (textsConfig()) {
9332
+ @for (textConfig of textsConfig(); track $index) {
9333
+ <ai-table-text [config]="textConfig"></ai-table-text>
9334
+ }
9276
9335
  <ai-table-icon [config]="iconConfig()"></ai-table-icon>
9277
9336
  }
9278
9337
  </ko-group>
@@ -10304,7 +10363,11 @@ function performFill(aiTable, sourceCells, mouseUpRecordId, actions) {
10304
10363
  const startFieldIndex = visibleColumnsIndexMap.get(sourceStartCell[1]);
10305
10364
  const endFieldIndex = visibleColumnsIndexMap.get(sourceEndCell[1]);
10306
10365
  for (let index = startFieldIndex; index <= endFieldIndex; index++) {
10307
- const fieldId = fields[index]._id;
10366
+ const field = fields[index];
10367
+ const fieldId = field._id;
10368
+ if (isSystemField(field)) {
10369
+ continue;
10370
+ }
10308
10371
  for (let rowIndex = targetStartRowIndex; rowIndex <= targetEndRowIndex; rowIndex++) {
10309
10372
  const targetRecordId = linearRows[rowIndex]._id;
10310
10373
  const relativeRowIndex = direction === 'downward' ? rowIndex - targetStartRowIndex : targetEndRowIndex - rowIndex;
@@ -10498,6 +10561,7 @@ class AITableGridSelectionService {
10498
10561
  selectedCells: new Set(),
10499
10562
  activeCell: null,
10500
10563
  expandCell: null,
10564
+ editingCell: null,
10501
10565
  selectAllState: AITableSelectAllState.none
10502
10566
  });
10503
10567
  }
@@ -10510,6 +10574,12 @@ class AITableGridSelectionService {
10510
10574
  expandCell: expandCell
10511
10575
  });
10512
10576
  }
10577
+ setEditingCell(editingCell) {
10578
+ this.aiTable.selection.set({
10579
+ ...this.aiTable.selection(),
10580
+ editingCell: editingCell
10581
+ });
10582
+ }
10513
10583
  selectField(fieldId) {
10514
10584
  if (this.aiTable.selection().selectedFields.has(fieldId)) {
10515
10585
  return;
@@ -10537,6 +10607,7 @@ class AITableGridSelectionService {
10537
10607
  selectedCells: new Set(),
10538
10608
  activeCell: null,
10539
10609
  expandCell: null,
10610
+ editingCell: null,
10540
10611
  selectAllState: this.selectAllState()
10541
10612
  });
10542
10613
  }
@@ -10680,6 +10751,7 @@ class AITableGridEventService {
10680
10751
  this.globalMousedownEvent$ = new Subject();
10681
10752
  this.destroyRef = inject(DestroyRef);
10682
10753
  this.thyPopover = inject(ThyPopover);
10754
+ this.selectionService = inject(AITableGridSelectionService);
10683
10755
  }
10684
10756
  initialize(aiTable, aiFieldRenderers) {
10685
10757
  this.aiTable = aiTable;
@@ -10798,6 +10870,7 @@ class AITableGridEventService {
10798
10870
  const fieldType = this.aiTable.fieldsMap()[fieldId].type;
10799
10871
  const { component, isInternalComponent } = this.getEditorComponent(fieldType);
10800
10872
  const offsetOriginPosition = this.getOriginPosition(aiTable, options);
10873
+ this.selectionService.setEditingCell([recordId, fieldId]);
10801
10874
  this.cellEditorPopoverRef = this.thyPopover.open(component, {
10802
10875
  viewContainerRef: isInternalComponent ? undefined : options?.viewContainerRef,
10803
10876
  origin: container,
@@ -10845,6 +10918,7 @@ class AITableGridEventService {
10845
10918
  this.cellEditorPopoverRef.afterClosed().subscribe(() => {
10846
10919
  wheelEvent.unsubscribe();
10847
10920
  this.cellEditorPopoverRef = null;
10921
+ this.selectionService.setEditingCell(null);
10848
10922
  });
10849
10923
  this.cellEditorPopoverRef.componentInstance.updateFieldValues.subscribe((value) => {
10850
10924
  options.updateFieldValues(value);
@@ -10856,6 +10930,7 @@ class AITableGridEventService {
10856
10930
  if (this.cellEditorPopoverRef) {
10857
10931
  this.cellEditorPopoverRef.close();
10858
10932
  this.cellEditorPopoverRef = null;
10933
+ this.selectionService.setEditingCell(null);
10859
10934
  }
10860
10935
  }
10861
10936
  getCurrentEditCell() {