From 0d46bcdd44a9e020ace15285e0c7890ba856f925 Mon Sep 17 00:00:00 2001 From: Geoffrey Kwan Date: Wed, 27 Jan 2021 15:06:26 -0500 Subject: [PATCH 1/3] Upgraded Table authoring to Angular. #2902 --- .../src/app/teacher-hybrid-angular.module.ts | 2 + src/main/webapp/site/src/messages.xlf | 123 +++++ .../wise5/components/table/authoring.html | 381 ---------------- .../table-authoring.component.html | 177 ++++++++ .../table-authoring.component.scss | 62 +++ .../table-authoring.component.ts | 364 +++++++++++++++ .../wise5/components/table/tableAuthoring.ts | 428 ------------------ .../table/tableAuthoringComponentModule.ts | 9 +- 8 files changed, 734 insertions(+), 812 deletions(-) delete mode 100644 src/main/webapp/wise5/components/table/authoring.html create mode 100644 src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.html create mode 100644 src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.scss create mode 100644 src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.ts delete mode 100644 src/main/webapp/wise5/components/table/tableAuthoring.ts diff --git a/src/main/webapp/site/src/app/teacher-hybrid-angular.module.ts b/src/main/webapp/site/src/app/teacher-hybrid-angular.module.ts index 6a5134318d..a7e51fad62 100644 --- a/src/main/webapp/site/src/app/teacher-hybrid-angular.module.ts +++ b/src/main/webapp/site/src/app/teacher-hybrid-angular.module.ts @@ -52,6 +52,7 @@ import { ConceptMapAuthoring } from '../../../wise5/components/conceptMap/concep import { DrawAuthoring } from '../../../wise5/components/draw/draw-authoring/draw-authoring.component'; import { MatchAuthoring } from '../../../wise5/components/match/match-authoring/match-authoring.component'; import { LabelAuthoring } from '../../../wise5/components/label/label-authoring/label-authoring.component'; +import { TableAuthoring } from '../../../wise5/components/table/table-authoring/table-authoring.component'; @NgModule({ declarations: [ @@ -87,6 +88,7 @@ import { LabelAuthoring } from '../../../wise5/components/label/label-authoring/ RubricAuthoringComponent, StatusIconComponent, StepInfoComponent, + TableAuthoring, WorkgroupInfoComponent, WorkgroupNodeScoreComponent, WorkgroupSelectAutocompleteComponent, diff --git a/src/main/webapp/site/src/messages.xlf b/src/main/webapp/site/src/messages.xlf index c7e6ac4b89..f268ec041c 100644 --- a/src/main/webapp/site/src/messages.xlf +++ b/src/main/webapp/site/src/messages.xlf @@ -6040,6 +6040,10 @@ ../../wise5/components/openResponse/open-response-authoring/open-response-authoring.component.html 11 + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 2 + Enter Prompt Here @@ -6067,6 +6071,10 @@ ../../wise5/components/openResponse/open-response-authoring/open-response-authoring.component.html 15 + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 6 + Background Image (Optional) @@ -6356,6 +6364,14 @@ ../../wise5/components/multipleChoice/multiple-choice-authoring/multiple-choice-authoring.component.html 124 + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 58 + + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 99 + Show Node Labels @@ -7289,6 +7305,113 @@ 6 + + Columns + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 13 + + + + Rows + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 20 + + + + Global Cell Size + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 27 + + + + Insert Column Before + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 44 + + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 47 + + + + Delete Column + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 55 + + + + Insert Column After + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 67 + + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 70 + + + + Insert Row Before + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 85 + + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 88 + + + + Delete Row + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 96 + + + + Insert Row After + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 108 + + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 111 + + + + Editable + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 130 + + + + Column Cell Size + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 152 + + + + Make All Cells Editable + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 167 + + + + Make All Cells Uneditable + + ../../wise5/components/table/table-authoring/table-authoring.component.html + 174 + + (Team ) diff --git a/src/main/webapp/wise5/components/table/authoring.html b/src/main/webapp/wise5/components/table/authoring.html deleted file mode 100644 index 08bbdb80d3..0000000000 --- a/src/main/webapp/wise5/components/table/authoring.html +++ /dev/null @@ -1,381 +0,0 @@ -
- -
-
-
-
- - {{ ::'SHOW_SAVE_BUTTON' | translate }} - -
-
- - {{ ::'SHOW_SUBMIT_BUTTON' | translate }} - -
-
- - {{ ::'SHOW_ADD_TO_NOTEBOOK_BUTTON' | translate }} - -
-
- - - - -
-
-

{{ ::'table.dataExplorer' | translate }}

-
- - {{ ::'table.enableDataExplorer' | translate }} - -
-
-
-

{{ ::'table.allowedGraphTypes' | translate }}

- - {{ ::'table.scatterPlot' | translate }} - - - {{ ::'table.lineGraph' | translate }} - - - {{ ::'table.barGraph' | translate }} - -
-
- - {{ ::'table.showScatterPlotRegressionLine' | translate }} - -
-
- - - - -
-
- - - - -
-
-
- - - - - - {{ ::'table.yAxis' | translate }} {{ $index + 1 }} - - - - -
-
-
- - {{ ::'table.canStudentEditAxisLabels' | translate }} - -
-
-
-
- - - - -
-
-
- - - add - - {{ ::'ADD_CONNECTED_COMPONENT' | translate }} - - -
-
-
- - - - - {{tableController.getNodePositionAndTitleByNodeId(item.$key)}} - - - - - - - - {{ componentIndex + 1 }}. {{component.type}} - - ({{ ::'thisComponent' | translate }}) - - - - - - - - - {{ ::'importWork' | translate }} - - - {{ ::'showWork' | translate }} - - - - - - - - {{ ::'merge' | translate }} - - - {{ ::'append' | translate }} - - - - - - - delete - - {{ ::'DELETE' | translate }} - - - - - - {{ ::'table.onlyShowDataAtMouseXPosition' | translate }} - - -
-
-
- -
-
-
- - - - -
-
- - - - - - - - - - - - -
-
- - - - - - - - - - - - - - - - - -
- - loupe - - {{ ::'table.insertColumnBefore' | translate }} - - - - delete - - {{ ::'table.deleteColumn' | translate }} - - - - loupe - - {{ ::'table.insertColumnAfter' | translate }} - - -
- - loupe - - {{ ::'table.insertRowBefore' | translate }} - - -
- - delete - - {{ ::'table.deleteRow' | translate }} - - -
- - loupe - - {{ ::'table.insertRowAfter' | translate }} - - -
- - - -
- - {{ ::'table.editableByStudent' | translate }} - -
-   -
- - - - - - -
-
-
- - {{ ::'table.makeAllCellsEditable' | translate }} - - - {{ ::'table.makeAllCellsUneditable' | translate }} - -
-
-
-
diff --git a/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.html b/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.html new file mode 100644 index 0000000000..5995f387dd --- /dev/null +++ b/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.html @@ -0,0 +1,177 @@ + + Prompt + + +
+ + Columns + + + + Rows + + + + Global Cell Size + + +
+ + + + + + + + + + + + + + + + + +
+
+ + + +
+
+
+
+ + + + +
+ + + + + Editable + +
+
+
+
+ Optional +
+
+
+ + Column Cell Size + + +
+
+
+ + +
\ No newline at end of file diff --git a/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.scss b/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.scss new file mode 100644 index 0000000000..cdd97d67ff --- /dev/null +++ b/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.scss @@ -0,0 +1,62 @@ +.prompt { + width: 100%; +} + +.size-input { + width: 120px; + margin-right: 20px; +} + +.table { + width: 100%; +} + +.rotate90 { + -webkit-transform: rotate(90deg); + transform: rotate(90deg); +} + +.rotate270 { + -webkit-transform: rotate(270deg); + transform: rotate(270deg); +} + +.column-buttons { + margin: 5px; +} + +.row-buttons { + margin-top: 5px; + margin-bottom: 5px; +} + +.spacer { + width: 56px; +} + +.outer-cell-container { + border: 1px solid black; + padding: 5px; + width: auto; +} + +.inner-cell-container { + border: 1px solid black; + padding: 10px; +} + +.cell-text { + width: 100%; +} + +.blank-row-cell { + height: 20px; +} + +::ng-deep .mat-form-field-infix { + width: auto !important; +} + +.make-all-cells-editable-buttons { + margin: 10px; +} \ No newline at end of file diff --git a/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.ts b/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.ts new file mode 100644 index 0000000000..46e7b3c3c6 --- /dev/null +++ b/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.ts @@ -0,0 +1,364 @@ +'use strict'; + +import { Component } from '@angular/core'; +import { Subject, Subscription } from 'rxjs'; +import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; +import { ProjectAssetService } from '../../../../site/src/app/services/projectAssetService'; +import { ComponentAuthoring } from '../../../authoringTool/components/component-authoring.component'; +import { ConfigService } from '../../../services/configService'; +import { NodeService } from '../../../services/nodeService'; +import { TeacherProjectService } from '../../../services/teacherProjectService'; + +@Component({ + selector: 'table-authoring', + templateUrl: 'table-authoring.component.html', + styleUrls: ['table-authoring.component.scss'] +}) +export class TableAuthoring extends ComponentAuthoring { + columnCellSizes: any; + + numColumnsChange: Subject = new Subject(); + numRowsChange: Subject = new Subject(); + globalCellSizeChange: Subject = new Subject(); + inputChange: Subject = new Subject(); + + numColumnsChangeSubscription: Subscription; + numRowsChangeSubscription: Subscription; + globalCellSizeChangeSubscription: Subscription; + inputChangeSubscription: Subscription; + + constructor( + protected ConfigService: ConfigService, + protected NodeService: NodeService, + protected ProjectAssetService: ProjectAssetService, + protected ProjectService: TeacherProjectService + ) { + super(ConfigService, NodeService, ProjectAssetService, ProjectService); + this.numColumnsChangeSubscription = this.numColumnsChange + .pipe(debounceTime(1000), distinctUntilChanged()) + .subscribe(() => { + this.tableNumColumnsChanged(); + }); + this.numRowsChangeSubscription = this.numRowsChange + .pipe(debounceTime(1000), distinctUntilChanged()) + .subscribe(() => { + this.tableNumRowsChanged(); + }); + this.globalCellSizeChangeSubscription = this.globalCellSizeChange + .pipe(debounceTime(1000), distinctUntilChanged()) + .subscribe(() => { + this.componentChanged(); + }); + this.inputChangeSubscription = this.inputChange + .pipe(debounceTime(1000), distinctUntilChanged()) + .subscribe(() => { + this.componentChanged(); + }); + } + + ngOnInit() { + super.ngOnInit(); + this.columnCellSizes = this.parseColumnCellSizes(this.componentContent); + } + + ngOnDestroy() { + super.ngOnDestroy(); + this.unsubscribeAll(); + } + + unsubscribeAll() { + this.numColumnsChangeSubscription.unsubscribe(); + this.numRowsChangeSubscription.unsubscribe(); + this.globalCellSizeChangeSubscription.unsubscribe(); + this.inputChangeSubscription.unsubscribe(); + } + + tableNumRowsChanged(): void { + const oldValue = this.getNumRowsInTableData(); + const newValue = this.authoringComponentContent.numRows; + if (newValue < oldValue) { + if (this.areRowsAfterEmpty(newValue)) { + this.tableSizeChanged(); + } else { + if (confirm($localize`Are you sure you want to decrease the number of rows?`)) { + this.tableSizeChanged(); + } else { + this.authoringComponentContent.numRows = oldValue; + } + } + } else { + this.tableSizeChanged(); + } + } + + areRowsAfterEmpty(rowIndex: number): boolean { + const oldNumRows = this.getNumRowsInTableData(); + for (let r = rowIndex; r < oldNumRows; r++) { + if (!this.isRowEmpty(r)) { + return false; + } + } + return true; + } + + isRowEmpty(rowIndex: number): boolean { + const tableData = this.authoringComponentContent.tableData; + for (const cell of tableData[rowIndex]) { + if (cell.text != null && cell.text != '') { + return false; + } + } + return true; + } + + tableNumColumnsChanged(): void { + const oldValue = this.getNumColumnsInTableData(); + const newValue = this.authoringComponentContent.numColumns; + if (newValue < oldValue) { + if (this.areColumnsAfterEmpty(newValue)) { + this.tableSizeChanged(); + } else { + if (confirm($localize`Are you sure you want to decrease the number of columns?`)) { + this.tableSizeChanged(); + } else { + this.authoringComponentContent.numColumns = oldValue; + } + } + } else { + this.tableSizeChanged(); + } + } + + areColumnsAfterEmpty(columnIndex: number): boolean { + const oldNumColumns = this.getNumColumnsInTableData(); + for (let c = columnIndex; c < oldNumColumns; c++) { + if (!this.isColumnEmpty(c)) { + return false; + } + } + return true; + } + + isColumnEmpty(columnIndex: number): boolean { + for (const row of this.authoringComponentContent.tableData) { + const cell = row[columnIndex]; + if (cell.text != null && cell.text != '') { + return false; + } + } + return true; + } + + tableSizeChanged(): void { + this.authoringComponentContent.tableData = this.getUpdatedTable( + this.authoringComponentContent.numRows, + this.authoringComponentContent.numColumns + ); + this.componentChanged(); + } + + /** + * Create a table with the given dimensions. Populate the cells with the cells from the old table. + * @param newNumRows the number of rows in the new table + * @param newNumColumns the number of columns in the new table + * @returns a new table + */ + getUpdatedTable(newNumRows: number, newNumColumns: number): any { + const newTable = []; + for (let r = 0; r < newNumRows; r++) { + const newRow = []; + for (let c = 0; c < newNumColumns; c++) { + let cell = this.getCellObjectFromTableData(c, r); + if (cell == null) { + cell = this.createEmptyCell(); + } + newRow.push(cell); + } + newTable.push(newRow); + } + return newTable; + } + + /** + * Get the cell object at the given x, y location + * @param x the column number (zero indexed) + * @param y the row number (zero indexed) + * @returns the cell at the given x, y location or null if there is none + */ + getCellObjectFromTableData(x: number, y: number): any { + let cellObject = null; + const tableData = this.authoringComponentContent.tableData; + if (tableData != null) { + const row = tableData[y]; + if (row != null) { + cellObject = row[x]; + } + } + return cellObject; + } + + createEmptyCell(): any { + return { + text: '', + editable: true, + size: null + }; + } + + insertRow(y: number): void { + const tableData = this.authoringComponentContent.tableData; + const newRow = []; + const numColumns = this.authoringComponentContent.numColumns; + for (let c = 0; c < numColumns; c++) { + const newCell = this.createEmptyCell(); + const cellSize = this.columnCellSizes[c]; + if (cellSize != null) { + newCell.size = cellSize; + } + newRow.push(newCell); + } + tableData.splice(y, 0, newRow); + this.authoringComponentContent.numRows++; + this.componentChanged(); + } + + deleteRow(y: number): void { + if (confirm($localize`Are you sure you want to delete this row?`)) { + const tableData = this.authoringComponentContent.tableData; + if (tableData != null) { + tableData.splice(y, 1); + this.authoringComponentContent.numRows--; + } + this.componentChanged(); + } + } + + insertColumn(x: number): void { + const tableData = this.authoringComponentContent.tableData; + const numRows = this.authoringComponentContent.numRows; + for (let r = 0; r < numRows; r++) { + const tempRow = tableData[r]; + if (tempRow != null) { + const newCell = this.createEmptyCell(); + tempRow.splice(x, 0, newCell); + } + } + this.authoringComponentContent.numColumns++; + this.parseColumnCellSizes(this.authoringComponentContent); + this.componentChanged(); + } + + deleteColumn(x: number): void { + if (confirm($localize`Are you sure you want to delete this column?`)) { + const tableData = this.authoringComponentContent.tableData; + const numRows = this.authoringComponentContent.numRows; + for (let r = 0; r < numRows; r++) { + const tempRow = tableData[r]; + if (tempRow != null) { + tempRow.splice(x, 1); + } + } + this.authoringComponentContent.numColumns--; + this.parseColumnCellSizes(this.authoringComponentContent); + this.componentChanged(); + } + } + + /** + * Get the number of rows in the table data. This is slightly different from just getting the + * numRows field in the component content. Usually the number of rows will be the same. In some + * cases it can be different such as during authoring immediately after the author changes the + * number of rows using the number of rows input. + * @return {number} The number of rows in the table data. + */ + getNumRowsInTableData(): number { + return this.authoringComponentContent.tableData.length; + } + + /** + * Get the number of columns in the table data. This is slightly different from just getting the + * numColumns field in the component content. Usually the number of columns will be the same. In + * some cases it can be different such as during authoring immediately after the author changes + * the number of columns using the number of columns input. + * @return {number} The number of columns in the table data. + */ + getNumColumnsInTableData(): number { + const tableData = this.authoringComponentContent.tableData; + if (tableData.length > 0) { + return tableData[0].length; + } + return 0; + } + + setAllCellsUneditable(): void { + this.setAllCellsIsEditable(false); + this.componentChanged(); + } + + setAllCellsEditable(): void { + this.setAllCellsIsEditable(true); + this.componentChanged(); + } + + setAllCellsIsEditable(isEditable: boolean): void { + const tableData = this.authoringComponentContent.tableData; + for (let r = 0; r < tableData.length; r++) { + const row = tableData[r]; + for (let c = 0; c < row.length; c++) { + const cell = row[c]; + cell.editable = isEditable; + } + } + } + + /** + * Parse the column cell sizes. We will get the column cell sizes by looking at the size value of + * each cell in the first row. + * @param componentContent the component content + */ + parseColumnCellSizes(componentContent: any): any { + const columnCellSizes = {}; + const tableData = componentContent.tableData; + const firstRow = tableData[0]; + if (firstRow != null) { + for (let x = 0; x < firstRow.length; x++) { + const cell = firstRow[x]; + columnCellSizes[x] = cell.size; + } + } + return columnCellSizes; + } + + columnSizeChanged(index: number): void { + let cellSize = this.columnCellSizes[index]; + if (cellSize == '') { + cellSize = null; + } + this.setColumnCellSizes(index, cellSize); + } + + setColumnCellSizes(column: number, size: number): void { + const tableData = this.authoringComponentContent.tableData; + for (let r = 0; r < tableData.length; r++) { + const row = tableData[r]; + const cell = row[column]; + if (cell != null) { + cell.size = size; + } + } + this.componentChanged(); + } + + automaticallySetConnectedComponentFieldsIfPossible(connectedComponent) { + if (connectedComponent.type === 'importWork' && connectedComponent.action == null) { + connectedComponent.action = 'merge'; + } else if (connectedComponent.type === 'showWork') { + connectedComponent.action = null; + } + } + + connectedComponentTypeChanged(connectedComponent) { + this.automaticallySetConnectedComponentFieldsIfPossible(connectedComponent); + this.componentChanged(); + } +} diff --git a/src/main/webapp/wise5/components/table/tableAuthoring.ts b/src/main/webapp/wise5/components/table/tableAuthoring.ts deleted file mode 100644 index beef4e7fef..0000000000 --- a/src/main/webapp/wise5/components/table/tableAuthoring.ts +++ /dev/null @@ -1,428 +0,0 @@ -'use strict'; - -import { Directive } from '@angular/core'; -import { EditComponentController } from '../../authoringTool/components/editComponentController'; - -@Directive() -class TableAuthoringController extends EditComponentController { - columnCellSizes: any; - - static $inject = [ - '$filter', - 'ConfigService', - 'NodeService', - 'NotificationService', - 'ProjectAssetService', - 'ProjectService', - 'UtilService' - ]; - - constructor( - $filter, - ConfigService, - NodeService, - NotificationService, - ProjectAssetService, - ProjectService, - UtilService - ) { - super( - $filter, - ConfigService, - NodeService, - NotificationService, - ProjectAssetService, - ProjectService, - UtilService - ); - } - - $onInit() { - super.$onInit(); - this.columnCellSizes = this.parseColumnCellSizes(this.componentContent); - } - - tableNumRowsChanged(oldValue: number): void { - if (this.authoringComponentContent.numRows < oldValue) { - if (this.areRowsAfterEmpty(this.authoringComponentContent.numRows)) { - this.tableSizeChanged(); - } else { - if (confirm(this.$translate('table.areYouSureYouWantToDecreaseTheNumberOfRows'))) { - this.tableSizeChanged(); - } else { - this.authoringComponentContent.numRows = oldValue; - } - } - } else { - this.tableSizeChanged(); - } - } - - /** - * Determine if the rows after the given index are empty. - * @param rowIndex The index of the row to start checking at. This value is zero indexed. - * @return {boolean} True if the row at the given index and all the rows after are empty. - * False if the row at the given index or any row after the row index is not empty. - */ - areRowsAfterEmpty(rowIndex: number): boolean { - const oldNumRows = this.getNumRowsInTableData(); - for (let r = rowIndex; r < oldNumRows; r++) { - if (!this.isRowEmpty(r)) { - return false; - } - } - return true; - } - - /** - * Determine if a row has cells that are all empty string. - * @param rowIndex The row index. This value is zero indexed. - * @returns {boolean} True if the text in all the cells in the row are empty string. - * False if the text in any cell in the row is not empty string. - */ - isRowEmpty(rowIndex: number): boolean { - const tableData = this.authoringComponentContent.tableData; - for (const cell of tableData[rowIndex]) { - if (cell.text != null && cell.text != '') { - return false; - } - } - return true; - } - - /** - * The author has changed the number of columns. - * @param oldValue The previous number of columns. - */ - tableNumColumnsChanged(oldValue: number): void { - if (this.authoringComponentContent.numColumns < oldValue) { - // the author is reducing the number of columns - if (this.areColumnsAfterEmpty(this.authoringComponentContent.numColumns)) { - // the columns that we will delete are empty so we will remove the columns - this.tableSizeChanged(); - } else { - if (confirm(this.$translate('table.areYouSureYouWantToDecreaseTheNumberOfColumns'))) { - this.tableSizeChanged(); - } else { - this.authoringComponentContent.numColumns = oldValue; - } - } - } else { - // the author is increasing the number of columns - this.tableSizeChanged(); - } - } - - /** - * Determine if the columns after the given index are empty. - * @param columnIndex The index of the column to start checking at. This value is zero indexed. - * @return {boolean} True if the column at the given index and all the columns after are empty. - * False if the column at the given index or any column after the column index is not empty. - */ - areColumnsAfterEmpty(columnIndex: number): boolean { - const oldNumColumns = this.getNumColumnsInTableData(); - for (let c = columnIndex; c < oldNumColumns; c++) { - if (!this.isColumnEmpty(c)) { - return false; - } - } - return true; - } - - /** - * Determine if a column has cells that are all empty string. - * @param columnIndex The column index. This value is zero indexed. - * @returns {boolean} True if the text in all the cells in the column are empty string. - * False if the text in any cell in the column is not empty string. - */ - isColumnEmpty(columnIndex: number): boolean { - for (const row of this.authoringComponentContent.tableData) { - const cell = row[columnIndex]; - if (cell.text != null && cell.text != '') { - return false; - } - } - return true; - } - - /** - * The table size has changed in the authoring view so we will update it - */ - tableSizeChanged(): void { - this.authoringComponentContent.tableData = this.getUpdatedTableSize( - this.authoringComponentContent.numRows, - this.authoringComponentContent.numColumns - ); - this.componentChanged(); - } - - /** - * Create a table with the given dimensions. Populate the cells with - * the cells from the old table. - * @param newNumRows the number of rows in the new table - * @param newNumColumns the number of columns in the new table - * @returns a new table - */ - getUpdatedTableSize(newNumRows: number, newNumColumns: number): any { - const newTable = []; - for (let r = 0; r < newNumRows; r++) { - const newRow = []; - for (let c = 0; c < newNumColumns; c++) { - let cell = this.getCellObjectFromComponentContent(c, r); - if (cell == null) { - cell = this.createEmptyCell(); - } - newRow.push(cell); - } - newTable.push(newRow); - } - return newTable; - } - - /** - * Get the cell object at the given x, y location - * @param x the column number (zero indexed) - * @param y the row number (zero indexed) - * @returns the cell at the given x, y location or null if there is none - */ - getCellObjectFromComponentContent(x: number, y: number): any { - let cellObject = null; - const tableData = this.authoringComponentContent.tableData; - if (tableData != null) { - const row = tableData[y]; - if (row != null) { - cellObject = row[x]; - } - } - return cellObject; - } - - createEmptyCell(): any { - return { - text: '', - editable: true, - size: null - }; - } - - /** - * Insert a row into the table from the authoring view - * @param y the row number to insert at - */ - insertRow(y: number): void { - const tableData = this.authoringComponentContent.tableData; - if (tableData != null) { - const newRow = []; - const numColumns = this.authoringComponentContent.numColumns; - for (let c = 0; c < numColumns; c++) { - const newCell = this.createEmptyCell(); - const cellSize = this.columnCellSizes[c]; - if (cellSize != null) { - newCell.size = cellSize; - } - newRow.push(newCell); - } - tableData.splice(y, 0, newRow); - this.authoringComponentContent.numRows++; - } - this.componentChanged(); - } - - /** - * Delete a row in the table from the authoring view - * @param y the row number to delete - */ - deleteRow(y: number): void { - if (confirm(this.$translate('table.areYouSureYouWantToDeleteThisRow'))) { - const tableData = this.authoringComponentContent.tableData; - if (tableData != null) { - tableData.splice(y, 1); - this.authoringComponentContent.numRows--; - } - this.componentChanged(); - } - } - - /** - * Insert a column into the table from the authoring view - * @param x the column number to insert at - */ - insertColumn(x: number): void { - const tableData = this.authoringComponentContent.tableData; - if (tableData != null) { - const numRows = this.authoringComponentContent.numRows; - for (let r = 0; r < numRows; r++) { - const tempRow = tableData[r]; - if (tempRow != null) { - const newCell = this.createEmptyCell(); - tempRow.splice(x, 0, newCell); - } - } - this.authoringComponentContent.numColumns++; - this.parseColumnCellSizes(this.authoringComponentContent); - } - this.componentChanged(); - } - - /** - * Delete a column in the table from the authoring view - * @param x the column number to delete - */ - deleteColumn(x: number): void { - if (confirm(this.$translate('table.areYouSureYouWantToDeleteThisColumn'))) { - const tableData = this.authoringComponentContent.tableData; - if (tableData != null) { - const numRows = this.authoringComponentContent.numRows; - for (let r = 0; r < numRows; r++) { - const tempRow = tableData[r]; - if (tempRow != null) { - tempRow.splice(x, 1); - } - } - this.authoringComponentContent.numColumns--; - this.parseColumnCellSizes(this.authoringComponentContent); - } - this.componentChanged(); - } - } - - /** - * Get the number of rows in the table data. This is slightly different from - * just getting the numRows field in the component content. Usually the - * number of rows will be the same. In some cases it can be different - * such as during authoring immediately after the author changes the number - * of rows using the number of rows input. - * @return {number} The number of rows in the table data. - */ - getNumRowsInTableData(): number { - return this.authoringComponentContent.tableData.length; - } - - /** - * Get the number of columns in the table data. This is slightly different from - * just getting the numColumns field in the component content. Usually the - * number of columns will be the same. In some cases it can be different - * such as during authoring immediately after the author changes the number - * of columns using the number of columns input. - * @return {number} The number of columns in the table data. - */ - getNumColumnsInTableData(): number { - const tableData = this.authoringComponentContent.tableData; - if (tableData.length > 0) { - return tableData[0].length; - } - return 0; - } - - makeAllCellsUneditable(): void { - const tableData = this.authoringComponentContent.tableData; - if (tableData != null) { - for (let r = 0; r < tableData.length; r++) { - const row = tableData[r]; - if (row != null) { - for (let c = 0; c < row.length; c++) { - const cell = row[c]; - if (cell != null) { - cell.editable = false; - } - } - } - } - } - this.componentChanged(); - } - - makeAllCellsEditable(): void { - const tableData = this.authoringComponentContent.tableData; - if (tableData != null) { - for (let r = 0; r < tableData.length; r++) { - const row = tableData[r]; - if (row != null) { - for (let c = 0; c < row.length; c++) { - const cell = row[c]; - if (cell != null) { - cell.editable = true; - } - } - } - } - } - this.componentChanged(); - } - - /** - * Parse the column cell sizes. We will get the column cell sizes by looking - * at size value of each column in the first row. - * @param componentContent the component content - */ - parseColumnCellSizes(componentContent: any): any { - const columnCellSizes = {}; - const tableData = componentContent.tableData; - if (tableData != null) { - const firstRow = tableData[0]; - if (firstRow != null) { - for (let x = 0; x < firstRow.length; x++) { - const cell = firstRow[x]; - columnCellSizes[x] = cell.size; - } - } - } - return columnCellSizes; - } - - columnSizeChanged(index: number): void { - if (index != null) { - let cellSize = this.columnCellSizes[index]; - if (cellSize == '') { - cellSize = null; - } - this.setColumnCellSizes(index, cellSize); - } - } - - /** - * Set the cell sizes for all the cells in a column - * @param column the column number - * @param size the cell size - */ - setColumnCellSizes(column: number, size: number): void { - const tableData = this.authoringComponentContent.tableData; - if (tableData != null) { - for (let r = 0; r < tableData.length; r++) { - const row = tableData[r]; - if (row != null) { - const cell = row[column]; - if (cell != null) { - cell.size = size; - } - } - } - } - this.componentChanged(); - } - - automaticallySetConnectedComponentFieldsIfPossible(connectedComponent) { - if (connectedComponent.type === 'importWork' && connectedComponent.action == null) { - connectedComponent.action = 'merge'; - } else if (connectedComponent.type === 'showWork') { - connectedComponent.action = null; - } - } - - connectedComponentTypeChanged(connectedComponent) { - this.automaticallySetConnectedComponentFieldsIfPossible(connectedComponent); - this.componentChanged(); - } -} - -const TableAuthoring = { - bindings: { - nodeId: '@', - componentId: '@' - }, - controller: TableAuthoringController, - controllerAs: 'tableController', - templateUrl: 'wise5/components/table/authoring.html' -}; - -export default TableAuthoring; diff --git a/src/main/webapp/wise5/components/table/tableAuthoringComponentModule.ts b/src/main/webapp/wise5/components/table/tableAuthoringComponentModule.ts index 60f9c96360..c202b806cd 100644 --- a/src/main/webapp/wise5/components/table/tableAuthoringComponentModule.ts +++ b/src/main/webapp/wise5/components/table/tableAuthoringComponentModule.ts @@ -2,14 +2,17 @@ import * as angular from 'angular'; import { TableService } from './tableService'; -import { downgradeInjectable } from '@angular/upgrade/static'; -import TableAuthoring from './tableAuthoring'; +import { downgradeComponent, downgradeInjectable } from '@angular/upgrade/static'; import { EditTableAdvancedComponent } from './edit-table-advanced/edit-table-advanced.component'; +import { TableAuthoring } from './table-authoring/table-authoring.component'; const tableAuthoringComponentModule = angular .module('tableAuthoringComponentModule', ['pascalprecht.translate']) .service('TableService', downgradeInjectable(TableService)) - .component('tableAuthoring', TableAuthoring) + .directive( + 'tableAuthoring', + downgradeComponent({ component: TableAuthoring }) as angular.IDirectiveFactory + ) .component('editTableAdvanced', EditTableAdvancedComponent) .config([ '$translatePartialLoaderProvider', From 6e50560b5e4fc2bf7ca2314be4c9182b346e7156 Mon Sep 17 00:00:00 2001 From: Hiroki Terashima Date: Thu, 28 Jan 2021 10:36:32 -0800 Subject: [PATCH 2/3] Cleaned up table authoring code. #2902 --- .../table-authoring/table-authoring.component.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.ts b/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.ts index 46e7b3c3c6..a1e97f3052 100644 --- a/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.ts +++ b/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.ts @@ -104,7 +104,7 @@ export class TableAuthoring extends ComponentAuthoring { isRowEmpty(rowIndex: number): boolean { const tableData = this.authoringComponentContent.tableData; for (const cell of tableData[rowIndex]) { - if (cell.text != null && cell.text != '') { + if (!this.isEmpty(cell.text)) { return false; } } @@ -142,13 +142,17 @@ export class TableAuthoring extends ComponentAuthoring { isColumnEmpty(columnIndex: number): boolean { for (const row of this.authoringComponentContent.tableData) { const cell = row[columnIndex]; - if (cell.text != null && cell.text != '') { + if (!this.isEmpty(cell.text)) { return false; } } return true; } + isEmpty(txt: string): boolean { + return txt == null || txt == ''; + } + tableSizeChanged(): void { this.authoringComponentContent.tableData = this.getUpdatedTable( this.authoringComponentContent.numRows, @@ -301,11 +305,8 @@ export class TableAuthoring extends ComponentAuthoring { } setAllCellsIsEditable(isEditable: boolean): void { - const tableData = this.authoringComponentContent.tableData; - for (let r = 0; r < tableData.length; r++) { - const row = tableData[r]; - for (let c = 0; c < row.length; c++) { - const cell = row[c]; + for (const row of this.authoringComponentContent.tableData) { + for (const cell of row) { cell.editable = isEditable; } } From d125cbf84db1029e89aac7aa9b55da050d79a68b Mon Sep 17 00:00:00 2001 From: Geoffrey Kwan Date: Fri, 29 Jan 2021 15:03:15 -0500 Subject: [PATCH 3/3] Cleaned up some Table authoring code. #2902 --- .../table-authoring.component.html | 4 +++ .../table-authoring.component.ts | 26 ++++++++----------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.html b/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.html index 5995f387dd..9fcbfba3af 100644 --- a/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.html +++ b/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.html @@ -13,6 +13,7 @@ Columns @@ -20,6 +21,7 @@ Rows @@ -27,6 +29,7 @@ Global Cell Size @@ -152,6 +155,7 @@ Column Cell Size diff --git a/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.ts b/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.ts index a1e97f3052..0d4cfa8f31 100644 --- a/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.ts +++ b/src/main/webapp/wise5/components/table/table-authoring/table-authoring.component.ts @@ -209,7 +209,7 @@ export class TableAuthoring extends ComponentAuthoring { }; } - insertRow(y: number): void { + insertRow(rowIndex: number): void { const tableData = this.authoringComponentContent.tableData; const newRow = []; const numColumns = this.authoringComponentContent.numColumns; @@ -221,46 +221,42 @@ export class TableAuthoring extends ComponentAuthoring { } newRow.push(newCell); } - tableData.splice(y, 0, newRow); + tableData.splice(rowIndex, 0, newRow); this.authoringComponentContent.numRows++; this.componentChanged(); } - deleteRow(y: number): void { + deleteRow(rowIndex: number): void { if (confirm($localize`Are you sure you want to delete this row?`)) { const tableData = this.authoringComponentContent.tableData; if (tableData != null) { - tableData.splice(y, 1); + tableData.splice(rowIndex, 1); this.authoringComponentContent.numRows--; } this.componentChanged(); } } - insertColumn(x: number): void { + insertColumn(columnIndex: number): void { const tableData = this.authoringComponentContent.tableData; const numRows = this.authoringComponentContent.numRows; for (let r = 0; r < numRows; r++) { - const tempRow = tableData[r]; - if (tempRow != null) { - const newCell = this.createEmptyCell(); - tempRow.splice(x, 0, newCell); - } + const row = tableData[r]; + const newCell = this.createEmptyCell(); + row.splice(columnIndex, 0, newCell); } this.authoringComponentContent.numColumns++; this.parseColumnCellSizes(this.authoringComponentContent); this.componentChanged(); } - deleteColumn(x: number): void { + deleteColumn(columnIndex: number): void { if (confirm($localize`Are you sure you want to delete this column?`)) { const tableData = this.authoringComponentContent.tableData; const numRows = this.authoringComponentContent.numRows; for (let r = 0; r < numRows; r++) { - const tempRow = tableData[r]; - if (tempRow != null) { - tempRow.splice(x, 1); - } + const row = tableData[r]; + row.splice(columnIndex, 1); } this.authoringComponentContent.numColumns--; this.parseColumnCellSizes(this.authoringComponentContent);