@contrail/document-table 1.0.5-alpha.1 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -3,5 +3,6 @@ export * from './table-constants';
3
3
  export * from './table-copy.service';
4
4
  export * from './table-merge.service';
5
5
  export * from './table-paste.service';
6
+ export * from './table-rotate.service';
6
7
  export * from './table.service';
7
8
  export * from './table-range';
package/lib/index.js CHANGED
@@ -19,5 +19,6 @@ __exportStar(require("./table-constants"), exports);
19
19
  __exportStar(require("./table-copy.service"), exports);
20
20
  __exportStar(require("./table-merge.service"), exports);
21
21
  __exportStar(require("./table-paste.service"), exports);
22
+ __exportStar(require("./table-rotate.service"), exports);
22
23
  __exportStar(require("./table.service"), exports);
23
24
  __exportStar(require("./table-range"), exports);
@@ -11,7 +11,7 @@ class TableCopyService {
11
11
  static copy(tableElement, childElements) {
12
12
  const copiedChildElementIds = new Map();
13
13
  const childElementsMap = new Map();
14
- childElements.forEach(element => {
14
+ childElements.forEach((element) => {
15
15
  childElementsMap.set(element.id, element);
16
16
  });
17
17
  const rowIds = [];
@@ -55,16 +55,16 @@ class TableCopyService {
55
55
  columnIds.push(newElement.id);
56
56
  newChildElements.push(newElement);
57
57
  }
58
- const cellElements = childElements.filter(e => e.type === 'cell');
58
+ const cellElements = childElements.filter((e) => e.type === 'cell');
59
59
  if (cellElements.length < tableElement.rowIds.length * tableElement.columnIds.length) {
60
60
  for (let i = 0; i < tableElement.rowIds.length; i++) {
61
61
  for (let j = 0; j < tableElement.columnIds.length; j++) {
62
62
  const rowId = tableElement.rowIds[i];
63
63
  const columnId = tableElement.columnIds[j];
64
- const cellElement = cellElements.find(e => e.type === 'cell' && e.rowId === rowId && e.columnId === columnId);
64
+ const cellElement = cellElements.find((e) => e.type === 'cell' && e.rowId === rowId && e.columnId === columnId);
65
65
  if (!cellElement) {
66
- const row = childElements.find(e => e.id === rowId);
67
- const column = childElements.find(e => e.id === columnId);
66
+ const row = childElements.find((e) => e.id === rowId);
67
+ const column = childElements.find((e) => e.id === columnId);
68
68
  cellElements.push((0, table_service_1.createCell)({
69
69
  rowId,
70
70
  columnId,
@@ -98,6 +98,7 @@ class TableCopyService {
98
98
  }
99
99
  newTableElement.rowIds = rowIds;
100
100
  newTableElement.columnIds = columnIds;
101
+ console.log(newChildElements);
101
102
  return [newTableElement, ...newChildElements];
102
103
  }
103
104
  static createTableFromCells(element, rows, columns, cells) {
@@ -110,7 +111,7 @@ class TableCopyService {
110
111
  const tableId = (0, nanoid_1.nanoid)(16);
111
112
  let width = 0, height = 0;
112
113
  let startRow, endRow, startColumn, endColumn;
113
- cells.forEach(cell => {
114
+ cells.forEach((cell) => {
114
115
  const rowIndex = element.rowIds.indexOf(cell.rowId);
115
116
  const columnIndex = element.columnIds.indexOf(cell.columnId);
116
117
  const isNotSet = startRow == undefined;
@@ -124,8 +125,8 @@ class TableCopyService {
124
125
  endColumn = columnIndex;
125
126
  existingCellsMap.set(`${rowIndex}_${columnIndex}`, cell);
126
127
  });
127
- const skipRows = Array.from({ length: endRow - startRow + 1 }, (value, index) => startRow + index).filter(i => !Array.from(existingCellsMap.keys()).find(v => v.startsWith(`${i}_`)));
128
- const skipColumns = Array.from({ length: endColumn - startColumn + 1 }, (value, index) => startColumn + index).filter(j => !Array.from(existingCellsMap.keys()).find(v => v.endsWith(`_${j}`)));
128
+ const skipRows = Array.from({ length: endRow - startRow + 1 }, (value, index) => startRow + index).filter((i) => !Array.from(existingCellsMap.keys()).find((v) => v.startsWith(`${i}_`)));
129
+ const skipColumns = Array.from({ length: endColumn - startColumn + 1 }, (value, index) => startColumn + index).filter((j) => !Array.from(existingCellsMap.keys()).find((v) => v.endsWith(`_${j}`)));
129
130
  for (let i = startRow; i <= endRow; i++) {
130
131
  if (skipRows.indexOf(i) !== -1)
131
132
  continue;
@@ -189,6 +190,7 @@ class TableCopyService {
189
190
  },
190
191
  style: util_1.ObjectUtil.cloneDeep(cell.style),
191
192
  position: { x: 0, y: 0 },
193
+ rotate: Object.assign({}, cell.rotate),
192
194
  });
193
195
  cellElements.push(element);
194
196
  }
@@ -275,8 +277,7 @@ class TableCopyService {
275
277
  var _a, _b, _c, _d, _e, _f;
276
278
  const fontFamily = `${(_c = (_b = (_a = cellElement.style) === null || _a === void 0 ? void 0 : _a.font) === null || _b === void 0 ? void 0 : _b.family) !== null && _c !== void 0 ? _c : table_constants_1.DEFAULT_TEXT_FONT_FAMILY}`;
277
279
  const fontSize = `${(_f = (_e = (_d = cellElement.style) === null || _d === void 0 ? void 0 : _d.font) === null || _e === void 0 ? void 0 : _e.size) !== null && _f !== void 0 ? _f : table_constants_1.DEFAULT_TEXT_FONT_SIZE}pt`;
278
- const size = table_service_1.TableService.getSize(cellElement.text, `width: ${cellElement.size.width -
279
- table_constants_1.TABLE_TEXT_PADDING * 2}px; height: auto; font-family: ${fontFamily}; font-size: ${fontSize};`);
280
+ const size = table_service_1.TableService.getSize(cellElement.text, `width: ${cellElement.size.width - table_constants_1.TABLE_TEXT_PADDING * 2}px; height: auto; font-family: ${fontFamily}; font-size: ${fontSize};`);
280
281
  const documentElement = {
281
282
  isTextTool: true,
282
283
  text: cellElement.text,
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TableMergeService = void 0;
4
+ const documents_1 = require("@contrail/documents");
4
5
  const util_1 = require("@contrail/util");
5
6
  const table_service_1 = require("./table.service");
6
7
  const table_range_1 = require("./table-range");
@@ -33,7 +34,7 @@ class TableMergeService {
33
34
  const rowId = tableElement.rowIds[i];
34
35
  for (let j = columnIndex; j < columnIndex + ((_b = cell.colspan) !== null && _b !== void 0 ? _b : 1); j++) {
35
36
  const columnId = tableElement.columnIds[j];
36
- const mergedCell = childElements.find(e => e.type === 'cell' && e.columnId === columnId && e.rowId === rowId);
37
+ const mergedCell = childElements.find((e) => e.type === 'cell' && e.columnId === columnId && e.rowId === rowId);
37
38
  if (mergedCell) {
38
39
  mergedCells.push(mergedCell);
39
40
  }
@@ -45,7 +46,7 @@ class TableMergeService {
45
46
  static isValidRangeToMerge(tableElement, childElements, tableRange) {
46
47
  if (tableRange.singular())
47
48
  return false;
48
- const mergedRanges = TableMergeService.getMergedRanges(tableElement, childElements).filter(range => range.intersects(tableRange) && !range.within(tableRange));
49
+ const mergedRanges = TableMergeService.getMergedRanges(tableElement, childElements).filter((range) => range.intersects(tableRange) && !range.within(tableRange));
49
50
  return mergedRanges.length === 0;
50
51
  }
51
52
  static merge(tableElement, childElements, tableRange) {
@@ -59,30 +60,49 @@ class TableMergeService {
59
60
  tableRange.each((rowIndex, columnIndex) => {
60
61
  const rowId = tableElement.rowIds[rowIndex];
61
62
  const columnId = tableElement.columnIds[columnIndex];
62
- const element = childElements.find(e => e.type === 'cell' && e.columnId === columnId && e.rowId === rowId);
63
+ const element = childElements.find((e) => e.type === 'cell' && e.columnId === columnId && e.rowId === rowId);
63
64
  if (element) {
64
65
  const elementUndo = util_1.ObjectUtil.cloneDeep(element);
65
66
  element.colspan = 1;
66
67
  element.rowspan = 1;
67
68
  if (tableRange.isStart(rowIndex, columnIndex)) {
68
69
  firstCell = element;
69
- let width = 0;
70
- tableRange.eachColumn(columnIndex => {
71
- const columnId = tableElement.columnIds[columnIndex];
72
- const column = childElements.find(e => e.type === 'column' && e.id === columnId);
73
- width = width + column.size.width;
74
- });
75
- if (colspan > 1) {
76
- element.colspan = colspan;
70
+ if (table_service_1.TableService.isVerticalCell(element)) {
71
+ let height = 0;
72
+ tableRange.eachRow((rowIndex) => {
73
+ const rowId = tableElement.rowIds[rowIndex];
74
+ const row = childElements.find((e) => e.type === 'row' && e.id === rowId);
75
+ height = height + row.size.height;
76
+ });
77
+ if (colspan > 1) {
78
+ element.colspan = colspan;
79
+ }
80
+ if (rowspan > 1) {
81
+ element.rowspan = rowspan;
82
+ }
83
+ element.size.height = height;
84
+ element.size.width = table_service_1.TableService.getCellSize(element).height;
77
85
  }
78
- if (rowspan > 1) {
79
- element.rowspan = rowspan;
86
+ else {
87
+ let width = 0;
88
+ tableRange.eachColumn((columnIndex) => {
89
+ const columnId = tableElement.columnIds[columnIndex];
90
+ const column = childElements.find((e) => e.type === 'column' && e.id === columnId);
91
+ width = width + column.size.width;
92
+ });
93
+ if (colspan > 1) {
94
+ element.colspan = colspan;
95
+ }
96
+ if (rowspan > 1) {
97
+ element.rowspan = rowspan;
98
+ }
99
+ element.size.width = width;
100
+ element.size.height = table_service_1.TableService.getCellSize(element).height;
80
101
  }
81
- element.size.width = width;
82
- element.size.height = table_service_1.TableService.getCellSize(element).height;
83
102
  }
84
103
  else {
85
104
  element.style = util_1.ObjectUtil.mergeDeep(util_1.ObjectUtil.cloneDeep(table_service_1.TableService.DEFAULT_CELL_STYLE), firstCell.style);
105
+ element.rotate = Object.assign({}, firstCell.rotate);
86
106
  table_service_1.TableService.clearCell(element);
87
107
  }
88
108
  elementsToUpdate.push({ change: element, undo: elementUndo });
@@ -96,27 +116,42 @@ class TableMergeService {
96
116
  }
97
117
  static unmerge(tableElement, childElements, tableRange) {
98
118
  const mergedRanges = TableMergeService.getMergedRanges(tableElement, childElements);
99
- if (!mergedRanges.find(range => range.equals(tableRange)))
119
+ if (!mergedRanges.find((range) => range.equals(tableRange)))
100
120
  throw new Error(table_service_1.TABLE_ERROR.INVALID_RANGE_TO_UNMERGE);
101
121
  const tableUndo = Object.assign(Object.assign({}, (0, table_service_1.tableData)(tableElement)), { size: Object.assign({}, tableElement.size) });
102
122
  const elementsToUpdate = [];
123
+ const columnWidthsToUpdate = new Map();
124
+ const rowHeightsToUpdate = new Map();
103
125
  let firstCell;
104
126
  tableRange.each((rowIndex, columnIndex) => {
105
127
  const rowId = tableElement.rowIds[rowIndex];
106
128
  const columnId = tableElement.columnIds[columnIndex];
107
- const element = childElements.find(e => e.type === 'cell' && e.columnId === columnId && e.rowId === rowId);
108
- const column = childElements.find(e => e.type === 'column' && e.id === columnId);
109
- const row = childElements.find(e => e.type === 'row' && e.id === rowId);
129
+ const element = childElements.find((e) => e.type === 'cell' && e.columnId === columnId && e.rowId === rowId);
130
+ const column = childElements.find((e) => e.type === 'column' && e.id === columnId);
131
+ const row = childElements.find((e) => e.type === 'row' && e.id === rowId);
110
132
  if (element && column && row) {
111
133
  const elementUndo = util_1.ObjectUtil.cloneDeep(element);
112
134
  element.colspan = 1;
113
135
  element.rowspan = 1;
114
136
  if (tableRange.isStart(rowIndex, columnIndex)) {
115
137
  firstCell = element;
116
- element.size.width = column.size.width;
117
- element.size.height = table_service_1.TableService.getCellSize(element).height;
118
- if (element.size.height > row.size.height) {
119
- elementsToUpdate.push(table_service_1.TableService.resizeRow(tableElement, childElements, rowId, element.size.height).elementsToUpdate[1]);
138
+ if (table_service_1.TableService.isVerticalCell(element)) {
139
+ element.size.height = row.size.height;
140
+ element.size.width = table_service_1.TableService.getCellSize(element).height;
141
+ if (element.size.width > column.size.width) {
142
+ if (!columnWidthsToUpdate.has(column.id) || columnWidthsToUpdate.get(column.id) < element.size.width) {
143
+ columnWidthsToUpdate.set(column.id, element.size.width);
144
+ }
145
+ }
146
+ }
147
+ else {
148
+ element.size.width = column.size.width;
149
+ element.size.height = table_service_1.TableService.getCellSize(element).height;
150
+ if (element.size.height > row.size.height) {
151
+ if (!rowHeightsToUpdate.has(row.id) || rowHeightsToUpdate.get(row.id) < element.size.height) {
152
+ rowHeightsToUpdate.set(row.id, element.size.height);
153
+ }
154
+ }
120
155
  }
121
156
  }
122
157
  else {
@@ -129,6 +164,17 @@ class TableMergeService {
129
164
  throw new Error();
130
165
  }
131
166
  });
167
+ for (const [columnId, width] of columnWidthsToUpdate) {
168
+ const updatedColumn = table_service_1.TableService.resizeColumn(tableElement, childElements, columnId, width).elementsToUpdate[1];
169
+ const updatedRowAndCells = table_service_1.TableService.autoFitRows(tableElement, childElements, columnId).elementsToUpdate;
170
+ const uniqueUpdatedRowAndCells = (0, documents_1.uniqueElementsToUpdate)(updatedRowAndCells, elementsToUpdate);
171
+ elementsToUpdate.push(updatedColumn);
172
+ elementsToUpdate.push(...uniqueUpdatedRowAndCells);
173
+ }
174
+ for (const [rowId, height] of rowHeightsToUpdate) {
175
+ const updatedRow = table_service_1.TableService.resizeRow(tableElement, childElements, rowId, height).elementsToUpdate[1];
176
+ elementsToUpdate.push(updatedRow);
177
+ }
132
178
  return {
133
179
  elementsToUpdate: [
134
180
  {
@@ -13,23 +13,23 @@ class TablePasteService {
13
13
  }
14
14
  static pasteRowsAndColumns(tableElement, childElements, elementsToPaste, targetRow, targetColumn) {
15
15
  var _a, _b, _c;
16
- const tableToPaste = elementsToPaste.find(e => e.type === 'table');
17
- const rowsToPaste = elementsToPaste.filter(e => e.type === 'row');
18
- const columnsToPaste = elementsToPaste.filter(e => e.type === 'column');
19
- const cellsToPaste = elementsToPaste.filter(e => e.type === 'cell');
16
+ const tableToPaste = elementsToPaste.find((e) => e.type === 'table');
17
+ const rowsToPaste = elementsToPaste.filter((e) => e.type === 'row');
18
+ const columnsToPaste = elementsToPaste.filter((e) => e.type === 'column');
19
+ const cellsToPaste = elementsToPaste.filter((e) => e.type === 'cell');
20
20
  const startRow = targetRow;
21
21
  const endRow = startRow + tableToPaste.rowIds.length - 1;
22
22
  const startColumn = targetColumn;
23
23
  const endColumn = startColumn + tableToPaste.columnIds.length - 1;
24
- const existingCells = childElements.filter(e => e.type === 'cell');
24
+ const existingCells = childElements.filter((e) => e.type === 'cell');
25
25
  const elementsToCreate = [];
26
26
  const elementsToUpdate = [];
27
27
  let existingMergedRanges = table_merge_service_1.TableMergeService.getMergedRanges(tableElement, childElements);
28
28
  for (let rowIndex = startRow; rowIndex <= endRow; rowIndex++) {
29
29
  const rowToPaste = rowsToPaste[rowIndex - targetRow];
30
30
  let existingRowId = tableElement.rowIds[rowIndex];
31
- let existingRow = childElements.find(e => e.type === 'row' && e.id === existingRowId) ||
32
- elementsToCreate.find(e => e.type === 'row' && e.id === existingRowId);
31
+ let existingRow = childElements.find((e) => e.type === 'row' && e.id === existingRowId) ||
32
+ elementsToCreate.find((e) => e.type === 'row' && e.id === existingRowId);
33
33
  this.log('current row', rowIndex, existingRowId, existingRow);
34
34
  if (!existingRowId) {
35
35
  const [newRow, ...newRowCells] = (_a = table_service_1.TableService.addRow(tableElement, [...existingCells, ...elementsToCreate], rowIndex, rowToPaste.size.height)) === null || _a === void 0 ? void 0 : _a.elementsToCreate;
@@ -46,8 +46,8 @@ class TablePasteService {
46
46
  for (let columnIndex = startColumn; columnIndex <= endColumn; columnIndex++) {
47
47
  const columnToPaste = columnsToPaste[columnIndex - targetColumn];
48
48
  let existingColumnId = tableElement.columnIds[columnIndex];
49
- let existingColumn = childElements.find(e => e.type === 'column' && e.id === existingColumnId) ||
50
- elementsToCreate.find(e => e.type === 'column' && e.id === existingColumnId);
49
+ let existingColumn = childElements.find((e) => e.type === 'column' && e.id === existingColumnId) ||
50
+ elementsToCreate.find((e) => e.type === 'column' && e.id === existingColumnId);
51
51
  this.log('current column', columnIndex, existingColumnId, existingColumn);
52
52
  if (!tableElement.columnIds[columnIndex]) {
53
53
  const [newColumn, ...newColumnCells] = (_b = table_service_1.TableService.addColumn(tableElement, [...existingCells, ...elementsToCreate], columnIndex, columnToPaste.size.width)) === null || _b === void 0 ? void 0 : _b.elementsToCreate;
@@ -58,22 +58,21 @@ class TablePasteService {
58
58
  }
59
59
  if (columnToPaste.size.width > existingColumn.size.width) {
60
60
  const updatedColumn = table_service_1.TableService.resizeColumn(tableElement, childElements, existingColumnId, columnToPaste.size.width).elementsToUpdate[1];
61
- const updatedRowAndCells = table_service_1.TableService.autoFitRows(tableElement, childElements, existingColumnId)
62
- .elementsToUpdate;
61
+ const updatedRowAndCells = table_service_1.TableService.autoFitRows(tableElement, childElements, existingColumnId).elementsToUpdate;
63
62
  const uniqueUpdatedRowAndCells = (0, documents_1.uniqueElementsToUpdate)(updatedRowAndCells, elementsToUpdate);
64
63
  elementsToUpdate.push(updatedColumn);
65
64
  elementsToUpdate.push(...uniqueUpdatedRowAndCells);
66
65
  this.log('resized column', columnIndex, existingColumnId, existingColumn);
67
66
  this.log('resized column cells and row', uniqueUpdatedRowAndCells, uniqueUpdatedRowAndCells);
68
67
  }
69
- const cellToPaste = cellsToPaste.find(e => e.rowId === rowToPaste.id && e.columnId === columnToPaste.id);
68
+ const cellToPaste = cellsToPaste.find((e) => e.rowId === rowToPaste.id && e.columnId === columnToPaste.id);
70
69
  if (!cellToPaste)
71
70
  continue;
72
71
  const cellRange = new table_range_1.TableRange(rowIndex, rowIndex, columnIndex, columnIndex);
73
- const mergedRange = existingMergedRanges.find(range => range.intersects(cellRange));
72
+ const mergedRange = existingMergedRanges.find((range) => range.intersects(cellRange));
74
73
  const mergedRangeOther = mergedRange && !cellRange.equals(mergedRange.start());
75
74
  if (mergedRange) {
76
- existingMergedRanges = existingMergedRanges.filter(r => !r.equals(mergedRange));
75
+ existingMergedRanges = existingMergedRanges.filter((r) => !r.equals(mergedRange));
77
76
  }
78
77
  if (mergedRangeOther) {
79
78
  const [updatedTable, ...unmergedCellAndRow] = (_c = table_merge_service_1.TableMergeService.unmerge(tableElement, childElements, mergedRange)) === null || _c === void 0 ? void 0 : _c.elementsToUpdate;
@@ -86,30 +85,33 @@ class TablePasteService {
86
85
  return { elementsToCreate, elementsToUpdate };
87
86
  }
88
87
  static pasteTableCells(tableElement, childElements, elementsToPaste, targetRow, targetColumn) {
89
- const tableToPaste = elementsToPaste.find(e => e.type === 'table');
90
- const rowsToPaste = elementsToPaste.filter(e => e.type === 'row');
91
- const columnsToPaste = elementsToPaste.filter(e => e.type === 'column');
92
- const cellsToPaste = elementsToPaste.filter(e => e.type === 'cell');
88
+ const tableToPaste = elementsToPaste.find((e) => e.type === 'table');
89
+ const rowsToPaste = elementsToPaste.filter((e) => e.type === 'row');
90
+ const columnsToPaste = elementsToPaste.filter((e) => e.type === 'column');
91
+ const cellsToPaste = elementsToPaste.filter((e) => e.type === 'cell');
92
+ this.log(elementsToPaste);
93
93
  const startRow = targetRow;
94
94
  const endRow = startRow + tableToPaste.rowIds.length - 1;
95
95
  const startColumn = targetColumn;
96
96
  const endColumn = startColumn + tableToPaste.columnIds.length - 1;
97
- const existingCells = childElements.filter(e => e.type === 'cell');
97
+ const existingCells = childElements.filter((e) => e.type === 'cell');
98
98
  const tableUndo = util_1.ObjectUtil.cloneDeep(tableElement);
99
99
  const { elementsToUpdate, elementsToCreate } = TablePasteService.pasteRowsAndColumns(tableElement, childElements, elementsToPaste, targetRow, targetColumn);
100
100
  for (let rowIndex = startRow; rowIndex <= endRow; rowIndex++) {
101
101
  const rowToPaste = rowsToPaste[rowIndex - targetRow];
102
102
  const existingRowId = tableElement.rowIds[rowIndex];
103
+ const existingRow = childElements.find((e) => e.type === 'row' && e.id === existingRowId) ||
104
+ elementsToCreate.find((e) => e.type === 'row' && e.id === existingRowId);
103
105
  for (let columnIndex = startColumn; columnIndex <= endColumn; columnIndex++) {
104
106
  const columnToPaste = columnsToPaste[columnIndex - targetColumn];
105
107
  const existingColumnId = tableElement.columnIds[columnIndex];
106
- const existingColumn = childElements.find(e => e.type === 'column' && e.id === existingColumnId) ||
107
- elementsToCreate.find(e => e.type === 'column' && e.id === existingColumnId);
108
- const cellToPaste = cellsToPaste.find(e => e.rowId === rowToPaste.id && e.columnId === columnToPaste.id);
108
+ const existingColumn = childElements.find((e) => e.type === 'column' && e.id === existingColumnId) ||
109
+ elementsToCreate.find((e) => e.type === 'column' && e.id === existingColumnId);
110
+ const cellToPaste = cellsToPaste.find((e) => e.rowId === rowToPaste.id && e.columnId === columnToPaste.id);
109
111
  if (!cellToPaste)
110
112
  continue;
111
- const createdCell = elementsToCreate.find(e => e.type === 'cell' && e.rowId === existingRowId && e.columnId === existingColumnId);
112
- const existingCell = existingCells.find(e => e.rowId === existingRowId && e.columnId === existingColumnId);
113
+ const createdCell = elementsToCreate.find((e) => e.type === 'cell' && e.rowId === existingRowId && e.columnId === existingColumnId);
114
+ const existingCell = existingCells.find((e) => e.rowId === existingRowId && e.columnId === existingColumnId);
113
115
  const cell = createdCell !== null && createdCell !== void 0 ? createdCell : existingCell;
114
116
  const cellUndo = util_1.ObjectUtil.cloneDeep(cell);
115
117
  this.log('cell to paste', cellToPaste);
@@ -118,11 +120,21 @@ class TablePasteService {
118
120
  cell.style = util_1.ObjectUtil.mergeDeep(util_1.ObjectUtil.cloneDeep(table_service_1.TableService.DEFAULT_CELL_STYLE), util_1.ObjectUtil.cloneDeep(cellToPaste.style));
119
121
  cell.colspan = cellToPaste.colspan > 1 ? cellToPaste.colspan : 1;
120
122
  cell.rowspan = cellToPaste.rowspan > 1 ? cellToPaste.rowspan : 1;
123
+ if (cellToPaste.rotate)
124
+ cell.rotate = Object.assign({}, cellToPaste.rotate);
121
125
  const cellMergedRanged = table_merge_service_1.TableMergeService.getMergedRange(tableElement, cell);
122
- cell.size.width = cellMergedRanged
123
- ? table_service_1.TableService.getColumnsWidth(tableElement, [...childElements, ...elementsToCreate], cellMergedRanged.startColumn, cellMergedRanged.endColumn)
124
- : existingColumn.size.width;
125
- cell.size.height = table_service_1.TableService.getCellSize(cell).height;
126
+ if (table_service_1.TableService.isVerticalCell(cell)) {
127
+ cell.size.height = cellMergedRanged
128
+ ? table_service_1.TableService.getRowsHeight(tableElement, [...childElements, ...elementsToCreate], cellMergedRanged.startRow, cellMergedRanged.endRow)
129
+ : existingRow.size.height;
130
+ cell.size.width = table_service_1.TableService.getCellSize(cell).height;
131
+ }
132
+ else {
133
+ cell.size.width = cellMergedRanged
134
+ ? table_service_1.TableService.getColumnsWidth(tableElement, [...childElements, ...elementsToCreate], cellMergedRanged.startColumn, cellMergedRanged.endColumn)
135
+ : existingColumn.size.width;
136
+ cell.size.height = table_service_1.TableService.getCellSize(cell).height;
137
+ }
126
138
  if (!createdCell && !elementsToUpdate.find(({ change }) => change.id === cell.id)) {
127
139
  cellUndo.colspan = cellUndo.colspan > 1 ? cellUndo.colspan : 1;
128
140
  cellUndo.rowspan = cellUndo.rowspan > 1 ? cellUndo.rowspan : 1;
@@ -0,0 +1,4 @@
1
+ import { DocumentElement, DocumentElementChanges } from '@contrail/documents';
2
+ export declare class TableRotateService {
3
+ static rotateCells(tableElement: DocumentElement, childElements: DocumentElement[], cells: DocumentElement[], angle: number): DocumentElementChanges;
4
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TableRotateService = void 0;
4
+ const documents_1 = require("@contrail/documents");
5
+ const table_service_1 = require("./table.service");
6
+ const util_1 = require("@contrail/util");
7
+ class TableRotateService {
8
+ static rotateCells(tableElement, childElements, cells, angle) {
9
+ const elementsToUpdate = [];
10
+ const columnWidthsToUpdate = new Map();
11
+ const rowHeightsToUpdate = new Map();
12
+ for (const cell of cells) {
13
+ const row = childElements.find((e) => e.type === 'row' && e.id === cell.rowId);
14
+ const column = childElements.find((e) => e.type === 'column' && e.id === cell.columnId);
15
+ if (!row || !column)
16
+ continue;
17
+ const cellUndo = util_1.ObjectUtil.cloneDeep(cell);
18
+ cell.rotate = { angle };
19
+ if (angle === 270) {
20
+ cell.size.height = row.size.height;
21
+ cell.size.width = table_service_1.TableService.getCellSize(cell).height;
22
+ if (cell.size.width > column.size.width) {
23
+ if (!columnWidthsToUpdate.has(column.id) || columnWidthsToUpdate.get(column.id) < cell.size.width) {
24
+ columnWidthsToUpdate.set(column.id, cell.size.width);
25
+ }
26
+ }
27
+ }
28
+ else {
29
+ cell.size.width = column.size.width;
30
+ cell.size.height = table_service_1.TableService.getCellSize(cell).height;
31
+ if (cell.size.height > row.size.height) {
32
+ if (!rowHeightsToUpdate.has(row.id) || rowHeightsToUpdate.get(row.id) < cell.size.height) {
33
+ rowHeightsToUpdate.set(row.id, cell.size.height);
34
+ }
35
+ }
36
+ }
37
+ elementsToUpdate.push({ change: cell, undo: cellUndo });
38
+ }
39
+ for (const [columnId, width] of columnWidthsToUpdate) {
40
+ const updatedColumn = table_service_1.TableService.resizeColumn(tableElement, childElements, columnId, width).elementsToUpdate[1];
41
+ const updatedRowAndCells = table_service_1.TableService.autoFitRows(tableElement, childElements, columnId).elementsToUpdate;
42
+ const uniqueUpdatedRowAndCells = (0, documents_1.uniqueElementsToUpdate)(updatedRowAndCells, elementsToUpdate);
43
+ elementsToUpdate.push(updatedColumn);
44
+ elementsToUpdate.push(...uniqueUpdatedRowAndCells);
45
+ }
46
+ for (const [rowId, height] of rowHeightsToUpdate) {
47
+ const updatedRow = table_service_1.TableService.resizeRow(tableElement, childElements, rowId, height).elementsToUpdate[1];
48
+ const updatedColumnAndCells = table_service_1.TableService.autoFitColumns(tableElement, childElements, rowId).elementsToUpdate;
49
+ const uniqueUpdatedColumnAndCells = (0, documents_1.uniqueElementsToUpdate)(updatedColumnAndCells, elementsToUpdate);
50
+ elementsToUpdate.push(updatedRow);
51
+ elementsToUpdate.push(...uniqueUpdatedColumnAndCells);
52
+ }
53
+ return { elementsToUpdate };
54
+ }
55
+ }
56
+ exports.TableRotateService = TableRotateService;
@@ -31,14 +31,17 @@ export declare class TableService {
31
31
  static resizeRow(tableElement: DocumentElement, childElements: DocumentElement[], rowId: string, height: number): DocumentElementChanges;
32
32
  static resizeColumn(tableElement: DocumentElement, childElements: DocumentElement[], columnId: string, width: number): DocumentElementChanges;
33
33
  private static getColumns;
34
- static getColumnsWidth(tableElement: DocumentElement, childElements: DocumentElement[], startIndex: number, endIndex: number): number;
34
+ static getColumnsWidth(tableElement: DocumentElement, childElements: DocumentElement[], startIndex: number, endIndex: number, skipIndex?: number): number;
35
35
  private static getRows;
36
- private static getRowsHeight;
36
+ static getRowsHeight(tableElement: DocumentElement, childElements: DocumentElement[], startIndex: number, endIndex: number, skipIndex?: number): number;
37
37
  private static getCellMinHeight;
38
+ private static getCellMinWidth;
38
39
  static autoFitRows(tableElement: DocumentElement, childElements: DocumentElement[], columnId: string): DocumentElementChanges;
40
+ static autoFitColumns(tableElement: DocumentElement, childElements: DocumentElement[], rowId: string): DocumentElementChanges;
39
41
  static clearCell(element: DocumentElement): void;
40
42
  static getCellSize(element: DocumentElement, text?: string): SizeDefinition;
41
43
  static getSize(text: string, style: string): SizeDefinition;
42
44
  static getTableChildElements(tableId: string, elements: DocumentElement[]): DocumentElement[];
43
45
  static updateCellText(tableElement: DocumentElement, childElements: DocumentElement[], rowIndex: number, columnIndex: number, text: string): DocumentElementChanges;
46
+ static isVerticalCell(element: DocumentElement): boolean;
44
47
  }
@@ -120,11 +120,11 @@ class TableService {
120
120
  static addColumn(tableElement, childElements, index, optionalWidth) {
121
121
  const prevColumnId = tableElement.columnIds[Math.max(0, index - 1)];
122
122
  const prevColumnCells = TableService.getCellsAtColumn(prevColumnId, tableElement, childElements);
123
- const width = optionalWidth != null ? optionalWidth : childElements.find(e => e.id === prevColumnId).size.width;
124
- const mergedRanges = table_merge_service_1.TableMergeService.getMergedRanges(tableElement, childElements).filter(range => range.startColumn < index && index <= range.endColumn);
123
+ const width = optionalWidth != null ? optionalWidth : childElements.find((e) => e.id === prevColumnId).size.width;
124
+ const mergedRanges = table_merge_service_1.TableMergeService.getMergedRanges(tableElement, childElements).filter((range) => range.startColumn < index && index <= range.endColumn);
125
125
  const cellsToUpdate = [];
126
126
  if (mergedRanges.length > 0) {
127
- const columnIndexes = [...new Set(mergedRanges.map(range => range.startColumn))];
127
+ const columnIndexes = [...new Set(mergedRanges.map((range) => range.startColumn))];
128
128
  for (const columnIndex of columnIndexes) {
129
129
  const targetColumnId = tableElement.columnIds[columnIndex];
130
130
  const targetCells = this.getCellsAtColumn(targetColumnId, tableElement, childElements);
@@ -208,19 +208,19 @@ class TableService {
208
208
  }
209
209
  static getCellsAtColumn(columnId, tableElement, childElements) {
210
210
  return childElements
211
- .filter(element => element.type === 'cell' && element.columnId === columnId)
211
+ .filter((element) => element.type === 'cell' && element.columnId === columnId)
212
212
  .sort((a, b) => tableElement.rowIds.indexOf(a.rowId) - tableElement.rowIds.indexOf(b.rowId));
213
213
  }
214
214
  static getCellsAtRow(rowId, tableElement, childElements) {
215
215
  return childElements
216
- .filter(element => element.type === 'cell' && element.rowId === rowId)
216
+ .filter((element) => element.type === 'cell' && element.rowId === rowId)
217
217
  .sort((a, b) => tableElement.columnIds.indexOf(a.columnId) - tableElement.columnIds.indexOf(b.columnId));
218
218
  }
219
219
  static addRow(tableElement, childElements, index, optionalHeight) {
220
- const mergedRanges = table_merge_service_1.TableMergeService.getMergedRanges(tableElement, childElements).filter(range => range.startRow < index && index <= range.endRow);
220
+ const mergedRanges = table_merge_service_1.TableMergeService.getMergedRanges(tableElement, childElements).filter((range) => range.startRow < index && index <= range.endRow);
221
221
  const cellsToUpdate = [];
222
222
  if (mergedRanges.length > 0) {
223
- const rowIndexes = [...new Set(mergedRanges.map(range => range.startRow))];
223
+ const rowIndexes = [...new Set(mergedRanges.map((range) => range.startRow))];
224
224
  for (const rowIndex of rowIndexes) {
225
225
  const targetRowId = tableElement.rowIds[rowIndex];
226
226
  const targetCells = this.getCellsAtRow(targetRowId, tableElement, childElements);
@@ -248,7 +248,7 @@ class TableService {
248
248
  }
249
249
  const prevRowId = tableElement.rowIds[Math.max(0, index - 1)];
250
250
  const prevRowCells = TableService.getCellsAtRow(prevRowId, tableElement, childElements);
251
- const height = optionalHeight != null ? optionalHeight : childElements.find(e => e.id === prevRowId).size.height;
251
+ const height = optionalHeight != null ? optionalHeight : childElements.find((e) => e.id === prevRowId).size.height;
252
252
  const rowId = (0, nanoid_1.nanoid)(16);
253
253
  const row = {
254
254
  id: rowId,
@@ -306,7 +306,7 @@ class TableService {
306
306
  const elementsMap = new Map();
307
307
  for (const range of ranges) {
308
308
  range.each((rowIndex, columnIndex) => {
309
- const cell = childElements.find(e => e.type === 'cell' &&
309
+ const cell = childElements.find((e) => e.type === 'cell' &&
310
310
  e.rowId === tableElement.rowIds[rowIndex] &&
311
311
  e.columnId === tableElement.columnIds[columnIndex]);
312
312
  if (cell && !elementsMap.get(cell.id)) {
@@ -325,13 +325,13 @@ class TableService {
325
325
  if (columnIdsToDelete.length === tableElement.columnIds.length) {
326
326
  return this.deleteTable(tableElement, childElements);
327
327
  }
328
- const mergedRanges = table_merge_service_1.TableMergeService.getMergedRanges(tableElement, childElements).filter(range => columnIndexes.filter(columnIndex => range.intersectsCol(columnIndex, columnIndex)).length > 0);
329
- const columnsToDelete = columnIdsToDelete.map(columnId => childElements.find(e => e.type === 'column' && e.id === columnId));
330
- const cellsToDelete = childElements.filter(e => e.type === 'cell' && columnIdsToDelete.indexOf(e.columnId) !== -1);
328
+ const mergedRanges = table_merge_service_1.TableMergeService.getMergedRanges(tableElement, childElements).filter((range) => columnIndexes.filter((columnIndex) => range.intersectsCol(columnIndex, columnIndex)).length > 0);
329
+ const columnsToDelete = columnIdsToDelete.map((columnId) => childElements.find((e) => e.type === 'column' && e.id === columnId));
330
+ const cellsToDelete = childElements.filter((e) => e.type === 'cell' && columnIdsToDelete.indexOf(e.columnId) !== -1);
331
331
  let deleteAllowed = true;
332
332
  if (mergedRanges.length > 0) {
333
333
  for (const cell of this.getCellsAtRanges(tableElement, childElements, mergedRanges)) {
334
- if (!cellsToDelete.find(e => e.id === cell.id)) {
334
+ if (!cellsToDelete.find((e) => e.id === cell.id)) {
335
335
  deleteAllowed = false;
336
336
  break;
337
337
  }
@@ -347,7 +347,7 @@ class TableService {
347
347
  size: Object.assign({}, tableElement.size),
348
348
  columnIds: [...tableElement.columnIds],
349
349
  };
350
- tableElement.columnIds = tableElement.columnIds.filter(id => columnIdsToDelete.indexOf(id) === -1);
350
+ tableElement.columnIds = tableElement.columnIds.filter((id) => columnIdsToDelete.indexOf(id) === -1);
351
351
  tableElement.size.width =
352
352
  tableElement.size.width - columnsToDelete.reduce((totalWidth, element) => totalWidth + element.size.width, 0);
353
353
  return {
@@ -371,13 +371,13 @@ class TableService {
371
371
  if (rowIdsToDelete.length === tableElement.rowIds.length) {
372
372
  return this.deleteTable(tableElement, childElements);
373
373
  }
374
- const mergedRanges = table_merge_service_1.TableMergeService.getMergedRanges(tableElement, childElements).filter(range => rowIndexes.filter(rowIndex => range.intersectsRow(rowIndex, rowIndex)).length > 0);
375
- const rowsToDelete = rowIdsToDelete.map(rowId => childElements.find(e => e.type === 'row' && e.id === rowId));
376
- const cellsToDelete = childElements.filter(e => e.type === 'cell' && rowIdsToDelete.indexOf(e.rowId) !== -1);
374
+ const mergedRanges = table_merge_service_1.TableMergeService.getMergedRanges(tableElement, childElements).filter((range) => rowIndexes.filter((rowIndex) => range.intersectsRow(rowIndex, rowIndex)).length > 0);
375
+ const rowsToDelete = rowIdsToDelete.map((rowId) => childElements.find((e) => e.type === 'row' && e.id === rowId));
376
+ const cellsToDelete = childElements.filter((e) => e.type === 'cell' && rowIdsToDelete.indexOf(e.rowId) !== -1);
377
377
  let deleteAllowed = true;
378
378
  if (mergedRanges.length > 0) {
379
379
  for (const cell of this.getCellsAtRanges(tableElement, childElements, mergedRanges)) {
380
- if (!cellsToDelete.find(e => e.id === cell.id)) {
380
+ if (!cellsToDelete.find((e) => e.id === cell.id)) {
381
381
  deleteAllowed = false;
382
382
  break;
383
383
  }
@@ -393,7 +393,7 @@ class TableService {
393
393
  size: Object.assign({}, tableElement.size),
394
394
  rowIds: [...tableElement.rowIds],
395
395
  };
396
- tableElement.rowIds = tableElement.rowIds.filter(id => rowIdsToDelete.indexOf(id) === -1);
396
+ tableElement.rowIds = tableElement.rowIds.filter((id) => rowIdsToDelete.indexOf(id) === -1);
397
397
  tableElement.size.height =
398
398
  tableElement.size.height - rowsToDelete.reduce((totalHeight, element) => totalHeight + element.size.height, 0);
399
399
  return {
@@ -415,9 +415,9 @@ class TableService {
415
415
  static move(key, tableElement, childElements, from, to) {
416
416
  const isColumn = key === 'columnIds';
417
417
  const mergedRanges = table_merge_service_1.TableMergeService.getMergedRanges(tableElement, childElements);
418
- const fromMergedRanges = mergedRanges.filter(range => isColumn ? range.cols > 0 && range.intersectsCol(from, from) : range.rows > 0 && range.intersectsRow(from, from));
418
+ const fromMergedRanges = mergedRanges.filter((range) => isColumn ? range.cols > 0 && range.intersectsCol(from, from) : range.rows > 0 && range.intersectsRow(from, from));
419
419
  const indexIncrement = from < to ? 1 : 0;
420
- const toMergedRanges = mergedRanges.filter(range => isColumn
420
+ const toMergedRanges = mergedRanges.filter((range) => isColumn
421
421
  ? range.startColumn - indexIncrement < to && to <= range.endColumn - indexIncrement
422
422
  : range.startRow - indexIncrement < to && to <= range.endRow - indexIncrement);
423
423
  if (fromMergedRanges.length > 0 || toMergedRanges.length > 0) {
@@ -435,12 +435,12 @@ class TableService {
435
435
  };
436
436
  }
437
437
  static resizeRow(tableElement, childElements, rowId, height) {
438
- const row = childElements.find(e => e.type === 'row' && e.id === rowId);
438
+ const row = childElements.find((e) => e.type === 'row' && e.id === rowId);
439
439
  const rowUndo = Object.assign(Object.assign({}, tableData(row)), { size: Object.assign({}, row.size) });
440
440
  const tableUndo = Object.assign(Object.assign({}, tableData(tableElement)), { size: Object.assign({}, tableElement.size) });
441
441
  row.size.height = height;
442
442
  tableElement.size.height = childElements
443
- .filter(e => e.type === 'row')
443
+ .filter((e) => e.type === 'row')
444
444
  .reduce((acc, row) => acc + row.size.height, 0);
445
445
  return {
446
446
  elementsToUpdate: [
@@ -456,12 +456,12 @@ class TableService {
456
456
  };
457
457
  }
458
458
  static resizeColumn(tableElement, childElements, columnId, width) {
459
- const column = childElements.find(e => e.type === 'column' && e.id === columnId);
459
+ const column = childElements.find((e) => e.type === 'column' && e.id === columnId);
460
460
  const columnUndo = Object.assign(Object.assign({}, tableData(column)), { size: Object.assign({}, column.size) });
461
461
  const tableUndo = Object.assign(Object.assign({}, tableData(tableElement)), { size: Object.assign({}, tableElement.size) });
462
462
  column.size.width = width;
463
463
  tableElement.size.width = childElements
464
- .filter(e => e.type === 'column')
464
+ .filter((e) => e.type === 'column')
465
465
  .reduce((acc, column) => acc + column.size.width, 0);
466
466
  return {
467
467
  elementsToUpdate: [
@@ -479,19 +479,19 @@ class TableService {
479
479
  static getColumns(tableElement, childElements) {
480
480
  const columns = [];
481
481
  for (const columnId of tableElement.columnIds) {
482
- const column = childElements.find(e => e.type === 'column' && e.id === columnId);
482
+ const column = childElements.find((e) => e.type === 'column' && e.id === columnId);
483
483
  if (!column)
484
484
  throw new Error(TABLE_ERROR.INVALID_TABLE);
485
485
  columns.push(column);
486
486
  }
487
487
  return columns;
488
488
  }
489
- static getColumnsWidth(tableElement, childElements, startIndex, endIndex) {
489
+ static getColumnsWidth(tableElement, childElements, startIndex, endIndex, skipIndex) {
490
490
  const columns = this.getColumns(tableElement, childElements);
491
491
  let width = 0;
492
492
  for (let i = startIndex; i <= endIndex; i++) {
493
493
  const column = columns[i];
494
- if (column) {
494
+ if (column && (skipIndex == null || skipIndex !== i)) {
495
495
  width = width + column.size.width;
496
496
  }
497
497
  }
@@ -500,7 +500,7 @@ class TableService {
500
500
  static getRows(tableElement, childElements) {
501
501
  const rows = [];
502
502
  for (const rowId of tableElement.rowIds) {
503
- const row = childElements.find(e => e.type === 'row' && e.id === rowId);
503
+ const row = childElements.find((e) => e.type === 'row' && e.id === rowId);
504
504
  if (!row)
505
505
  throw new Error(TABLE_ERROR.INVALID_TABLE);
506
506
  rows.push(row);
@@ -519,6 +519,8 @@ class TableService {
519
519
  return height;
520
520
  }
521
521
  static getCellMinHeight(cell, tableElement, childElements) {
522
+ if (TableService.isVerticalCell(cell))
523
+ return table_constants_1.TABLE_ROW_MIN_HEIGHT;
522
524
  let height = cell.size.height;
523
525
  const rowIndex = tableElement.rowIds.indexOf(cell.rowId);
524
526
  const columnIndex = tableElement.columnIds.indexOf(cell.columnId);
@@ -526,12 +528,12 @@ class TableService {
526
528
  throw new Error(TABLE_ERROR.INVALID_TABLE);
527
529
  const cellRange = new table_range_1.TableRange(rowIndex, rowIndex, columnIndex, columnIndex);
528
530
  const mergedRanges = table_merge_service_1.TableMergeService.getMergedRanges(tableElement, childElements);
529
- const mergedRange = mergedRanges.find(range => cellRange.within(range));
531
+ const mergedRange = mergedRanges.find((range) => cellRange.within(range));
530
532
  if (mergedRange) {
531
533
  const mergedRangeStart = mergedRange && cellRange.equals(mergedRange.start());
532
534
  const mergedCell = mergedRangeStart
533
535
  ? cell
534
- : childElements.find(e => e.type === 'cell' &&
536
+ : childElements.find((e) => e.type === 'cell' &&
535
537
  e.rowId === tableElement.rowIds[mergedRange.startRow] &&
536
538
  e.columnId === tableElement.columnIds[mergedRange.startColumn]);
537
539
  height =
@@ -540,24 +542,48 @@ class TableService {
540
542
  }
541
543
  return height;
542
544
  }
545
+ static getCellMinWidth(cell, tableElement, childElements) {
546
+ if (!TableService.isVerticalCell(cell))
547
+ return table_constants_1.TABLE_COLUMN_MIN_WIDTH;
548
+ let width = cell.size.width;
549
+ const rowIndex = tableElement.rowIds.indexOf(cell.rowId);
550
+ const columnIndex = tableElement.columnIds.indexOf(cell.columnId);
551
+ if (rowIndex < 0 || columnIndex < 0)
552
+ throw new Error(TABLE_ERROR.INVALID_TABLE);
553
+ const cellRange = new table_range_1.TableRange(rowIndex, rowIndex, columnIndex, columnIndex);
554
+ const mergedRanges = table_merge_service_1.TableMergeService.getMergedRanges(tableElement, childElements);
555
+ const mergedRange = mergedRanges.find((range) => cellRange.within(range));
556
+ if (mergedRange) {
557
+ const mergedRangeStart = mergedRange && cellRange.equals(mergedRange.start());
558
+ const mergedCell = mergedRangeStart
559
+ ? cell
560
+ : childElements.find((e) => e.type === 'cell' &&
561
+ e.rowId === tableElement.rowIds[mergedRange.startRow] &&
562
+ e.columnId === tableElement.columnIds[mergedRange.startColumn]);
563
+ width =
564
+ mergedCell.size.width -
565
+ TableService.getColumnsWidth(tableElement, childElements, mergedRange.startColumn, mergedRange.endColumn, columnIndex);
566
+ }
567
+ return width;
568
+ }
543
569
  static autoFitRows(tableElement, childElements, columnId) {
544
570
  var _a;
545
571
  const elementsToUpdate = [];
546
572
  const columnIndex = tableElement.columnIds.indexOf(columnId);
547
- const column = childElements.find(e => e.type === 'column' && e.id === columnId);
573
+ const column = childElements.find((e) => e.type === 'column' && e.id === columnId);
548
574
  const mergedRanges = table_merge_service_1.TableMergeService.getMergedRanges(tableElement, childElements);
549
575
  for (const [rowIndex, rowId] of tableElement.rowIds.entries()) {
550
- const row = childElements.find(e => e.type === 'row' && e.id === rowId);
551
- const cell = childElements.find(e => e.type === 'cell' && e.rowId === rowId && e.columnId === columnId);
552
- if (!row || !cell)
576
+ const row = childElements.find((e) => e.type === 'row' && e.id === rowId);
577
+ const cell = childElements.find((e) => e.type === 'cell' && e.rowId === rowId && e.columnId === columnId);
578
+ if (!row || !cell || TableService.isVerticalCell(cell))
553
579
  continue;
554
580
  const cellUndo = util_1.ObjectUtil.cloneDeep(cell);
555
581
  const cellRange = new table_range_1.TableRange(rowIndex, rowIndex, columnIndex, columnIndex);
556
- const mergedRange = mergedRanges.find(range => cellRange.within(range));
582
+ const mergedRange = mergedRanges.find((range) => cellRange.within(range));
557
583
  const mergedRangeStart = mergedRange && cellRange.equals(mergedRange.start());
558
584
  const mergedRangeOther = mergedRange && !cellRange.equals(mergedRange.start());
559
585
  if (mergedRangeOther) {
560
- const mergedCell = childElements.find(e => e.type === 'cell' &&
586
+ const mergedCell = childElements.find((e) => e.type === 'cell' &&
561
587
  e.rowId === tableElement.rowIds[mergedRange.startRow] &&
562
588
  e.columnId === tableElement.columnIds[mergedRange.startColumn]);
563
589
  if (rowIndex === mergedRange.endRow && columnIndex !== mergedRange.startColumn) {
@@ -589,15 +615,68 @@ class TableService {
589
615
  }
590
616
  return { elementsToUpdate };
591
617
  }
618
+ static autoFitColumns(tableElement, childElements, rowId) {
619
+ var _a;
620
+ const elementsToUpdate = [];
621
+ const rowIndex = tableElement.rowIds.indexOf(rowId);
622
+ const row = childElements.find((e) => e.type === 'row' && e.id === rowId);
623
+ const mergedRanges = table_merge_service_1.TableMergeService.getMergedRanges(tableElement, childElements);
624
+ for (const [columnIndex, columnId] of tableElement.columnIds.entries()) {
625
+ const column = childElements.find((e) => e.type === 'column' && e.id === columnId);
626
+ const cell = childElements.find((e) => e.type === 'cell' && e.rowId === rowId && e.columnId === columnId);
627
+ if (!column || !cell || !TableService.isVerticalCell(cell))
628
+ continue;
629
+ const cellUndo = util_1.ObjectUtil.cloneDeep(cell);
630
+ const cellRange = new table_range_1.TableRange(rowIndex, rowIndex, columnIndex, columnIndex);
631
+ const mergedRange = mergedRanges.find((range) => cellRange.within(range));
632
+ const mergedRangeStart = mergedRange && cellRange.equals(mergedRange.start());
633
+ const mergedRangeOther = mergedRange && !cellRange.equals(mergedRange.start());
634
+ if (mergedRangeOther) {
635
+ const mergedCell = childElements.find((e) => e.type === 'cell' &&
636
+ e.rowId === tableElement.rowIds[mergedRange.startRow] &&
637
+ e.columnId === tableElement.columnIds[mergedRange.startColumn]);
638
+ if (columnIndex === mergedRange.endColumn && rowIndex !== mergedRange.startRow) {
639
+ const mergedCellUndo = util_1.ObjectUtil.cloneDeep(mergedCell);
640
+ mergedCell.size.height = TableService.getRowsHeight(tableElement, childElements, mergedRange.startRow, mergedRange.endRow);
641
+ mergedCell.size.width = TableService.getCellSize(mergedCell).height;
642
+ elementsToUpdate.push({
643
+ change: mergedCell,
644
+ undo: mergedCellUndo,
645
+ });
646
+ }
647
+ }
648
+ cell.size.height = mergedRangeStart
649
+ ? TableService.getRowsHeight(tableElement, childElements, mergedRange.startRow, mergedRange.endRow)
650
+ : row.size.height;
651
+ cell.size.width = TableService.getCellSize(cell).height;
652
+ elementsToUpdate.push({
653
+ change: cell,
654
+ undo: cellUndo,
655
+ });
656
+ if (columnIndex === ((_a = mergedRange === null || mergedRange === void 0 ? void 0 : mergedRange.endColumn) !== null && _a !== void 0 ? _a : columnIndex)) {
657
+ const cellWidth = TableService.getCellMinWidth(cell, tableElement, childElements);
658
+ if (cellWidth > column.size.width) {
659
+ elementsToUpdate.push(TableService.resizeColumn(tableElement, childElements, columnId, cellWidth).elementsToUpdate[1]);
660
+ }
661
+ }
662
+ }
663
+ return { elementsToUpdate };
664
+ }
592
665
  static clearCell(element) {
593
666
  element.text = '';
594
- element.size.height = table_constants_1.TABLE_ROW_MIN_HEIGHT;
667
+ if (TableService.isVerticalCell(element)) {
668
+ element.size.width = table_constants_1.TABLE_COLUMN_MIN_WIDTH;
669
+ }
670
+ else {
671
+ element.size.height = table_constants_1.TABLE_ROW_MIN_HEIGHT;
672
+ }
595
673
  }
596
674
  static getCellSize(element, text) {
597
675
  var _a, _b, _c, _d, _e, _f;
598
676
  const fontFamily = `${(_c = (_b = (_a = element.style) === null || _a === void 0 ? void 0 : _a.font) === null || _b === void 0 ? void 0 : _b.family) !== null && _c !== void 0 ? _c : table_constants_1.DEFAULT_TEXT_FONT_FAMILY}`;
599
677
  const fontSize = `${(_f = (_e = (_d = element.style) === null || _d === void 0 ? void 0 : _d.font) === null || _e === void 0 ? void 0 : _e.size) !== null && _f !== void 0 ? _f : table_constants_1.DEFAULT_TEXT_FONT_SIZE}pt`;
600
- const fixedWidth = `${element.size.width - table_constants_1.TABLE_TEXT_PADDING * 2}px`;
678
+ const width = TableService.isVerticalCell(element) ? element.size.height : element.size.width;
679
+ const fixedWidth = `${width - table_constants_1.TABLE_TEXT_PADDING * 2}px`;
601
680
  const size = this.getSize(text !== null && text !== void 0 ? text : element.text, `width: ${fixedWidth}; height: auto; font-family: ${fontFamily}; font-size: ${fontSize};`);
602
681
  return { height: Math.max(size.height + table_constants_1.TABLE_TEXT_PADDING * 2, table_constants_1.TABLE_ROW_MIN_HEIGHT), width: size.width };
603
682
  }
@@ -616,20 +695,26 @@ class TableService {
616
695
  return { width, height };
617
696
  }
618
697
  static getTableChildElements(tableId, elements) {
619
- return elements.filter(e => e.tableId === tableId && ['cell', 'column', 'row'].indexOf(e.type) !== -1);
698
+ return elements.filter((e) => e.tableId === tableId && ['cell', 'column', 'row'].indexOf(e.type) !== -1);
620
699
  }
621
700
  static updateCellText(tableElement, childElements, rowIndex, columnIndex, text) {
622
701
  const rowId = tableElement.rowIds[rowIndex];
623
702
  const columnId = tableElement.columnIds[columnIndex];
624
- const cell = childElements.find(e => e.type === 'cell' && e.rowId === rowId && e.columnId === columnId);
625
- const row = childElements.find(e => e.type === 'row' && e.id === rowId);
703
+ const cell = childElements.find((e) => e.type === 'cell' && e.rowId === rowId && e.columnId === columnId);
704
+ const row = childElements.find((e) => e.type === 'row' && e.id === rowId);
705
+ const column = childElements.find((e) => e.type === 'column' && e.id === columnId);
626
706
  if (!rowId || !columnId || !cell || !row) {
627
707
  throw new Error(TABLE_ERROR.INVALID_TABLE);
628
708
  }
629
709
  const elementsToUpdate = [];
630
710
  const cellUndo = Object.assign(Object.assign({}, tableData(cell)), { text: cell.text, size: Object.assign({}, cell.size) });
631
711
  cell.text = text;
632
- cell.size.height = TableService.getCellSize(cell).height;
712
+ if (TableService.isVerticalCell(cell)) {
713
+ cell.size.width = TableService.getCellSize(cell).height;
714
+ }
715
+ else {
716
+ cell.size.height = TableService.getCellSize(cell).height;
717
+ }
633
718
  elementsToUpdate.push({
634
719
  change: Object.assign(Object.assign({}, tableData(cell)), { text: cell.text, size: cell.size }),
635
720
  undo: cellUndo,
@@ -637,10 +722,17 @@ class TableService {
637
722
  if (cell.size.height > row.size.height) {
638
723
  elementsToUpdate.push(...TableService.resizeRow(tableElement, childElements, rowId, cell.size.height).elementsToUpdate);
639
724
  }
725
+ if (cell.size.width > column.size.width) {
726
+ elementsToUpdate.push(...TableService.resizeColumn(tableElement, childElements, columnId, cell.size.width).elementsToUpdate);
727
+ }
640
728
  return {
641
729
  elementsToUpdate,
642
730
  };
643
731
  }
732
+ static isVerticalCell(element) {
733
+ var _a;
734
+ return element && element.type === 'cell' && ((_a = element.rotate) === null || _a === void 0 ? void 0 : _a.angle) === 270;
735
+ }
644
736
  }
645
737
  exports.TableService = TableService;
646
738
  TableService.DEFAULT_CELL_STYLE = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrail/document-table",
3
- "version": "1.0.5-alpha.1",
3
+ "version": "1.0.6",
4
4
  "description": "Library for document tables",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -38,10 +38,10 @@
38
38
  "testEnvironment": "node"
39
39
  },
40
40
  "dependencies": {
41
- "@contrail/actions": "^1.0.17-alpha.2",
42
- "@contrail/documents": "^1.2.9-alpha.0",
43
- "@contrail/types": "^3.1.2-alpha.1",
44
- "@contrail/util": "^1.1.17-alpha.2",
41
+ "@contrail/actions": "^1.0.17",
42
+ "@contrail/documents": "^1.3.2",
43
+ "@contrail/types": "^3.1.3",
44
+ "@contrail/util": "^1.1.18",
45
45
  "reflect-metadata": "^0.1.13"
46
46
  }
47
47
  }