add remove row function
This commit is contained in:
parent
2f78b7ec22
commit
497a275537
@ -3,10 +3,10 @@ import * as actions from 'redux/action-creators';
|
|||||||
import { $, Dom } from 'core/Dom';
|
import { $, Dom } from 'core/Dom';
|
||||||
import { ComponentOptionsType, ExcelComponent } from 'core/ExcelComponent';
|
import { ComponentOptionsType, ExcelComponent } from 'core/ExcelComponent';
|
||||||
import { TableSelection } from 'components/table/TableSelection';
|
import { TableSelection } from 'components/table/TableSelection';
|
||||||
import { changeCurrentStyles, changeCurrentText, changeTableSize } from 'redux/action-creators';
|
import { changeCurrentStyles, changeCurrentText, changeTableSize, removeRowFromTable } from 'redux/action-creators';
|
||||||
import { createTable, getNewRowHTML } from 'components/table/table.template';
|
import { createTable, getNewRowHTML } from 'components/table/table.template';
|
||||||
import { initialState, initialStyleState } from 'src/constants';
|
import { initialState, initialStyleState } from 'src/constants';
|
||||||
import { parse } from 'core/utils';
|
import { getCellId, parse } from 'core/utils';
|
||||||
import { resizeHandler } from 'components/table/handlers/table.resize';
|
import { resizeHandler } from 'components/table/handlers/table.resize';
|
||||||
import { selectHandler } from 'components/table/handlers/table.select.handler';
|
import { selectHandler } from 'components/table/handlers/table.select.handler';
|
||||||
|
|
||||||
@ -45,8 +45,8 @@ export class Table extends ExcelComponent {
|
|||||||
const maxColFromState = Math.max(...Object.keys(colState).map(el => +el));
|
const maxColFromState = Math.max(...Object.keys(colState).map(el => +el));
|
||||||
|
|
||||||
const normalTableSize = {
|
const normalTableSize = {
|
||||||
col: Math.max(maxRowFromState, row),
|
row: Math.max(maxRowFromState, row),
|
||||||
row: Math.max(maxColFromState, col),
|
col: Math.max(maxColFromState, col),
|
||||||
};
|
};
|
||||||
|
|
||||||
if ((maxColFromState !== this.tableSize.col) || (maxRowFromState !== this.tableSize.row)) {
|
if ((maxColFromState !== this.tableSize.col) || (maxRowFromState !== this.tableSize.row)) {
|
||||||
@ -65,6 +65,7 @@ export class Table extends ExcelComponent {
|
|||||||
this.$onEventFromObserver('formula:enter-press', () => this.selection.$currentCell.focus());
|
this.$onEventFromObserver('formula:enter-press', () => this.selection.$currentCell.focus());
|
||||||
this.$onEventFromObserver('toolbar:applyStyle', this.updateCurrentStyles);
|
this.$onEventFromObserver('toolbar:applyStyle', this.updateCurrentStyles);
|
||||||
this.$onEventFromObserver('toolbar:add-row', this.addNewRowHandler);
|
this.$onEventFromObserver('toolbar:add-row', this.addNewRowHandler);
|
||||||
|
this.$onEventFromObserver('toolbar:remove-row', this.removeRowHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
initTable() {
|
initTable() {
|
||||||
@ -156,7 +157,7 @@ export class Table extends ExcelComponent {
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
updateCurrentStyles = (style: CSSStyleDeclaration) => {
|
updateCurrentStyles = (style: Partial<CSSStyleDeclaration>) => {
|
||||||
this.selection.applyStyle(style);
|
this.selection.applyStyle(style);
|
||||||
this.dispatchToStore(actions.applyStyle({
|
this.dispatchToStore(actions.applyStyle({
|
||||||
value: style,
|
value: style,
|
||||||
@ -194,4 +195,17 @@ export class Table extends ExcelComponent {
|
|||||||
onMouseup() {
|
onMouseup() {
|
||||||
this.isMouseDowned = false;
|
this.isMouseDowned = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeRowHandler = () => {
|
||||||
|
const cell = this.selection.$focusedCell;
|
||||||
|
const cellId = getCellId(cell);
|
||||||
|
if (!cellId) return;
|
||||||
|
|
||||||
|
const { row } = cellId;
|
||||||
|
const nodeToRemove = this.$root.find(`[data-row='${row}']`);
|
||||||
|
this.$root.removeChild(nodeToRemove);
|
||||||
|
this.selection.clearSelection();
|
||||||
|
|
||||||
|
this.dispatchToStore(removeRowFromTable(+row));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { Table } from 'components/table/Table';
|
import { Table } from 'components/table/Table';
|
||||||
import { $, Dom } from 'core/Dom';
|
import { $, Dom } from 'core/Dom';
|
||||||
import { getParamsFromCellId, startCellId } from 'components/table/table.functions';
|
import { getParamsFromCellId, startCellId } from 'components/table/table.functions';
|
||||||
|
import { initialStyleState } from 'src/constants';
|
||||||
|
|
||||||
export class TableSelection {
|
export class TableSelection {
|
||||||
static selectedClassName = 'selected';
|
static selectedClassName = 'selected';
|
||||||
@ -60,6 +61,7 @@ export class TableSelection {
|
|||||||
this.$currentCell?.removeClass(TableSelection.selectedClassName);
|
this.$currentCell?.removeClass(TableSelection.selectedClassName);
|
||||||
this.clearHeaderSelection();
|
this.clearHeaderSelection();
|
||||||
this.selectedCellsGroup = [];
|
this.selectedCellsGroup = [];
|
||||||
|
this.rootTable.updateCurrentStyles(initialStyleState);
|
||||||
}
|
}
|
||||||
|
|
||||||
selectFromTo($from: Dom, $cell: Dom) {
|
selectFromTo($from: Dom, $cell: Dom) {
|
||||||
@ -110,7 +112,7 @@ export class TableSelection {
|
|||||||
this.$currentCell = $cell;
|
this.$currentCell = $cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyStyle(style: CSSStyleDeclaration) {
|
applyStyle(style: Partial<CSSStyleDeclaration>) {
|
||||||
this.selectedCellsGroup.forEach(el => el.css(style));
|
this.selectedCellsGroup.forEach(el => el.css(style));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -71,6 +71,7 @@ export function selectHandler(event: MouseEvent | KeyboardEvent, selection: Tabl
|
|||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'ArrowDown': {
|
case 'ArrowDown': {
|
||||||
|
if (selection.rootTable.tableSize.row === row + 1) return;
|
||||||
row++;
|
row++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -79,6 +80,7 @@ export function selectHandler(event: MouseEvent | KeyboardEvent, selection: Tabl
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'ArrowRight': {
|
case 'ArrowRight': {
|
||||||
|
if (selection.rootTable.tableSize.col === col + 1) return;
|
||||||
col++;
|
col++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,11 +49,16 @@ export class Toolbar extends ExcelComponentState {
|
|||||||
// TODO refactor, make style handler
|
// TODO refactor, make style handler
|
||||||
const target = $(event.target);
|
const target = $(event.target);
|
||||||
|
|
||||||
if (target.closest('[data-addbtn]').isExist) {
|
if (target.closest('[data-add-row-btn]').isExist) {
|
||||||
this.$emitEventToObserver('toolbar:add-row');
|
this.$emitEventToObserver('toolbar:add-row');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (target.closest('[data-remove-row-btn]').isExist) {
|
||||||
|
this.$emitEventToObserver('toolbar:remove-row');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let stringValue;
|
let stringValue;
|
||||||
let value;
|
let value;
|
||||||
let key;
|
let key;
|
||||||
|
|||||||
@ -88,7 +88,8 @@ export function createToolbar(state: ToolbarStateType): string {
|
|||||||
|
|
||||||
buttons.push(increaseDecreaseFontSize);
|
buttons.push(increaseDecreaseFontSize);
|
||||||
buttons.push(selectGroup);
|
buttons.push(selectGroup);
|
||||||
buttons.push(createAddRowTable());
|
buttons.push(createAddRowButton());
|
||||||
|
buttons.push(createRemoveRowButton());
|
||||||
|
|
||||||
return buttons.join('');
|
return buttons.join('');
|
||||||
}
|
}
|
||||||
@ -170,10 +171,18 @@ function createButtonFromConfig(btnConfig: ButtonConfigType) {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createAddRowTable() {
|
function createAddRowButton() {
|
||||||
return `
|
return `
|
||||||
<div class="button" data-addbtn>
|
<div class="button" data-add-row-btn>
|
||||||
<i class="material-icons" data-addbtn>add_circle</i>
|
<i class="material-icons" data-add-row-btn>add_circle</i>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createRemoveRowButton() {
|
||||||
|
return `
|
||||||
|
<div class="button" data-remove-row-btn>
|
||||||
|
<i class="material-icons" data-remove-row-btn>remove_circle</i>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -134,6 +134,10 @@ export class Dom implements DomClass {
|
|||||||
return this.$el.getAttribute(name);
|
return this.$el.getAttribute(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeChild($child: Dom) {
|
||||||
|
this.$el.removeChild($child.$el);
|
||||||
|
}
|
||||||
|
|
||||||
get isExist(): boolean {
|
get isExist(): boolean {
|
||||||
return !!this.$el;
|
return !!this.$el;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { Dom } from 'core/Dom';
|
||||||
import { CallbackType, StateType } from 'redux/types';
|
import { CallbackType, StateType } from 'redux/types';
|
||||||
import { fontSizes } from 'src/constants';
|
import { fontSizes } from 'src/constants';
|
||||||
|
|
||||||
@ -66,3 +67,11 @@ export function isSmallestFontSize(fontSize?: string): number | boolean {
|
|||||||
export function getMethodNameByEventName(eventName: string): string {
|
export function getMethodNameByEventName(eventName: string): string {
|
||||||
return `on${capitalize(eventName)}`;
|
return `on${capitalize(eventName)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getCellId($cell: Dom): { row: string, col:string } | false {
|
||||||
|
if (!$cell.isExist) return false;
|
||||||
|
const id = $cell.data.id?.split(':');
|
||||||
|
if (!Array.isArray(id)) return false;
|
||||||
|
const [row, col] = id;
|
||||||
|
return { row, col };
|
||||||
|
}
|
||||||
|
|||||||
@ -7,3 +7,4 @@ export const TABLE_RESIZE = 'TABLE_RESIZE';
|
|||||||
export const UPDATE_DATE = 'UPDATE_DATE';
|
export const UPDATE_DATE = 'UPDATE_DATE';
|
||||||
export const CHANGE_CURRENT_TEXT = 'CHANGE_CURRENT_TEXT';
|
export const CHANGE_CURRENT_TEXT = 'CHANGE_CURRENT_TEXT';
|
||||||
export const CHANGE_TABLE_SIZE = 'CHANGE_TABLE_SIZE';
|
export const CHANGE_TABLE_SIZE = 'CHANGE_TABLE_SIZE';
|
||||||
|
export const REMOVE_ROW_FROM_TABLE = 'REMOVE_ROW_FROM_TABLE';
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import {
|
|||||||
APPLY_STYLES,
|
APPLY_STYLES,
|
||||||
CHANGE_TITLE,
|
CHANGE_TITLE,
|
||||||
DELETE_TABLE,
|
DELETE_TABLE,
|
||||||
UPDATE_DATE, CHANGE_CURRENT_TEXT, CHANGE_TABLE_SIZE,
|
UPDATE_DATE, CHANGE_CURRENT_TEXT, CHANGE_TABLE_SIZE, REMOVE_ROW_FROM_TABLE,
|
||||||
} from 'redux/action-constants';
|
} from 'redux/action-constants';
|
||||||
|
|
||||||
export function tableResize(resizeData: ResizeReturnDataType): ActionType {
|
export function tableResize(resizeData: ResizeReturnDataType): ActionType {
|
||||||
@ -31,7 +31,7 @@ export function changeCurrentStyles(data: Partial<CSSStyleDeclaration>): ActionT
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function applyStyle(data: { ids: (string | undefined)[], value: CSSStyleDeclaration }): ActionType {
|
export function applyStyle(data: { ids: (string | undefined)[], value: Partial<CSSStyleDeclaration> }): ActionType {
|
||||||
return {
|
return {
|
||||||
type: APPLY_STYLES,
|
type: APPLY_STYLES,
|
||||||
data,
|
data,
|
||||||
@ -72,3 +72,10 @@ export function changeTableSize(data: { col: number, row: number }): ActionType
|
|||||||
data,
|
data,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function removeRowFromTable(removedRowNumber: number) {
|
||||||
|
return {
|
||||||
|
type: REMOVE_ROW_FROM_TABLE,
|
||||||
|
data: removedRowNumber,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { ToolbarStateType } from 'components/toolbar/toolbar-types';
|
||||||
import { ActionType, StateType } from 'redux/types';
|
import { ActionType, StateType } from 'redux/types';
|
||||||
import { ActiveRoute } from 'core/routes/ActiveRoute';
|
import { ActiveRoute } from 'core/routes/ActiveRoute';
|
||||||
import { storageName } from 'pages/ExcelPage';
|
import { storageName } from 'pages/ExcelPage';
|
||||||
@ -8,7 +9,7 @@ import {
|
|||||||
APPLY_STYLES,
|
APPLY_STYLES,
|
||||||
CHANGE_TITLE,
|
CHANGE_TITLE,
|
||||||
DELETE_TABLE,
|
DELETE_TABLE,
|
||||||
UPDATE_DATE, CHANGE_CURRENT_TEXT, CHANGE_TABLE_SIZE,
|
UPDATE_DATE, CHANGE_CURRENT_TEXT, CHANGE_TABLE_SIZE, REMOVE_ROW_FROM_TABLE,
|
||||||
} from 'redux/action-constants';
|
} from 'redux/action-constants';
|
||||||
|
|
||||||
export function rootReducer(state: StateType, action: ActionType): StateType {
|
export function rootReducer(state: StateType, action: ActionType): StateType {
|
||||||
@ -74,6 +75,70 @@ export function rootReducer(state: StateType, action: ActionType): StateType {
|
|||||||
return { ...state, tableSize: action.data };
|
return { ...state, tableSize: action.data };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case REMOVE_ROW_FROM_TABLE: {
|
||||||
|
// needs to be redefined next params:
|
||||||
|
// rowState: { [k: number]: number };
|
||||||
|
// dataState: { [k: string]: string };
|
||||||
|
// stylesState: { [k: string]: ToolbarStateType };
|
||||||
|
// tableSize: { col: number, row: number }
|
||||||
|
|
||||||
|
const newRowStateEntries: [number, number][] = [];
|
||||||
|
const newDataStateEntries: [string, string][] = [];
|
||||||
|
const newStylesStateEntries: [string, ToolbarStateType][] = [];
|
||||||
|
// rowState change
|
||||||
|
Object.entries(state.rowState).forEach(([key, value]) => {
|
||||||
|
switch (true) {
|
||||||
|
case key < action.data:
|
||||||
|
newRowStateEntries.push([+key, value]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case key > action.data:
|
||||||
|
newRowStateEntries.push([+key - 1, value]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const newRowState = Object.fromEntries(newRowStateEntries);
|
||||||
|
// dataState change
|
||||||
|
Object.entries(state.dataState).forEach(([key, value]) => {
|
||||||
|
const [row, col] = key.split(':');
|
||||||
|
switch (true) {
|
||||||
|
case row < action.data:
|
||||||
|
newDataStateEntries.push([key, value.toString()]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case row > action.data:
|
||||||
|
newDataStateEntries.push([`${+row - 1}:${col}`, value.toString()]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const newDataState = Object.fromEntries(newDataStateEntries);
|
||||||
|
// stylesState change
|
||||||
|
Object.entries(state.stylesState).forEach(([key, value]) => {
|
||||||
|
const [row, col] = key.split(':');
|
||||||
|
switch (true) {
|
||||||
|
case row < action.data:
|
||||||
|
newStylesStateEntries.push([key, value]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case row > action.data:
|
||||||
|
newStylesStateEntries.push([`${+row - 1}:${col}`, value]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const newStylesState = Object.fromEntries(newStylesStateEntries);
|
||||||
|
// tableSize
|
||||||
|
const newTableSize = { col: state.tableSize.col, row: state.tableSize.row - 1 };
|
||||||
|
|
||||||
|
// const newRowState = Object.keys(state.rowState).filter(rowIndex => rowIndex.toString() !== action.data.toString()).
|
||||||
|
return { ...state, rowState: newRowState, dataState: newDataState, stylesState: newStylesState, tableSize: newTableSize };
|
||||||
|
}
|
||||||
|
|
||||||
default: return state;
|
default: return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
max-height: calc(100vh - ($header-height + $toolbar-height + $formula-height));
|
||||||
top: $header-height + $toolbar-height + $formula-height;
|
top: $header-height + $toolbar-height + $formula-height;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
font-size: $default-cell-font-size;
|
font-size: $default-cell-font-size;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user