add routing, dashboard page, excel table pages
This commit is contained in:
parent
1456c256e3
commit
6f1b9803bd
@ -26,6 +26,7 @@ module.exports = {
|
|||||||
"@typescript-eslint/no-use-before-define": "off",
|
"@typescript-eslint/no-use-before-define": "off",
|
||||||
"@typescript-eslint/restrict-template-expressions": "off",
|
"@typescript-eslint/restrict-template-expressions": "off",
|
||||||
"@typescript-eslint/unbound-method": "off",
|
"@typescript-eslint/unbound-method": "off",
|
||||||
|
"@typescript-eslint/quotes": "warn",
|
||||||
"arrow-parens": "off",
|
"arrow-parens": "off",
|
||||||
"class-methods-use-this": "off",
|
"class-methods-use-this": "off",
|
||||||
"func-names": "off",
|
"func-names": "off",
|
||||||
@ -34,6 +35,7 @@ module.exports = {
|
|||||||
"max-len": "off",
|
"max-len": "off",
|
||||||
"no-console": "off",
|
"no-console": "off",
|
||||||
"no-new": "off",
|
"no-new": "off",
|
||||||
|
"no-continue": "off",
|
||||||
"no-plusplus": "off",
|
"no-plusplus": "off",
|
||||||
"object-curly-newline": "off",
|
"object-curly-newline": "off",
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { Store } from '../../core/createStore';
|
import { Store } from 'core/createStore';
|
||||||
import { $, Dom } from '../../core/dom';
|
import { $, Dom } from 'core/dom';
|
||||||
import { Emitter } from '../../core/Emitter';
|
import { Emitter } from 'core/Emitter';
|
||||||
import { ExcelComponent } from '../../core/ExcelComponent';
|
import { ExcelComponent } from 'core/ExcelComponent';
|
||||||
import { StoreSubscriber } from '../../core/StoreSubscriber';
|
import { StoreSubscriber } from 'core/StoreSubscriber';
|
||||||
|
|
||||||
interface ExcelOptionsType {
|
interface ExcelOptionsType {
|
||||||
components: any[],
|
components: any[],
|
||||||
@ -16,14 +16,11 @@ export class Excel {
|
|||||||
store: Store;
|
store: Store;
|
||||||
subscriber: StoreSubscriber;
|
subscriber: StoreSubscriber;
|
||||||
|
|
||||||
constructor(selector: string, options: ExcelOptionsType) {
|
constructor(options: ExcelOptionsType) {
|
||||||
this.$el = $(selector);
|
|
||||||
this.components = options.components;
|
this.components = options.components;
|
||||||
this.emitter = new Emitter();
|
this.emitter = new Emitter();
|
||||||
this.store = options.store;
|
this.store = options.store;
|
||||||
this.subscriber = new StoreSubscriber(this.store);
|
this.subscriber = new StoreSubscriber(this.store);
|
||||||
|
|
||||||
console.log(`Created new Excel class in ${selector} with options: ${options}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getRoot() {
|
getRoot() {
|
||||||
@ -44,12 +41,10 @@ export class Excel {
|
|||||||
return component;
|
return component;
|
||||||
});
|
});
|
||||||
|
|
||||||
return $root.$el;
|
return $root;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
init() {
|
||||||
this.$el.append(this.getRoot());
|
|
||||||
|
|
||||||
this.subscriber.subscribeComponents(this.components);
|
this.subscriber.subscribeComponents(this.components);
|
||||||
this.components.forEach(component => component.init());
|
this.components.forEach(component => component.init());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Dom } from '../../core/dom';
|
import { Dom } from 'core/dom';
|
||||||
import { ExcelComponent } from '../../core/ExcelComponent';
|
import { ExcelComponent } from 'core/ExcelComponent';
|
||||||
|
|
||||||
export class Formula extends ExcelComponent {
|
export class Formula extends ExcelComponent {
|
||||||
static className = 'excel__formula';
|
static className = 'excel__formula';
|
||||||
|
|||||||
@ -1,14 +1,16 @@
|
|||||||
import { $, Dom } from '../../core/dom';
|
import { $, Dom } from 'core/dom';
|
||||||
import { ExcelComponent } from '../../core/ExcelComponent';
|
import { ExcelStateComponent } from 'core/ExcelStateComponent';
|
||||||
import * as actions from '../../redux/actions';
|
import { deleteTable } from 'redux/actions';
|
||||||
|
import * as actions from 'redux/actions';
|
||||||
|
|
||||||
export class Header extends ExcelComponent {
|
export class Header extends ExcelStateComponent {
|
||||||
static className = 'excel__header';
|
static className = 'excel__header';
|
||||||
|
|
||||||
constructor($root: Dom, options: any) {
|
constructor($root: Dom, options: any) {
|
||||||
super($root, {
|
super($root, {
|
||||||
name: 'Header',
|
name: 'Header',
|
||||||
listeners: ['input'],
|
listeners: ['input', 'click'],
|
||||||
|
subscribe: ['title'],
|
||||||
...options,
|
...options,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -20,10 +22,10 @@ export class Header extends ExcelComponent {
|
|||||||
<input type="text" class="input" value="${title}">
|
<input type="text" class="input" value="${title}">
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="button">
|
<div class="button" data-button="delete-table">
|
||||||
<i class="material-icons">delete</i>
|
<i class="material-icons">delete</i>
|
||||||
</div>
|
</div>
|
||||||
<div class="button">
|
<div class="button" data-button="exit">
|
||||||
<i class="material-icons">exit_to_app</i>
|
<i class="material-icons">exit_to_app</i>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@ -34,4 +36,31 @@ export class Header extends ExcelComponent {
|
|||||||
|
|
||||||
this.$dispatch(actions.changeTitle($target.text));
|
this.$dispatch(actions.changeTitle($target.text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onClick(event: MouseEvent) {
|
||||||
|
const target = event.target as HTMLElement;
|
||||||
|
if (!target) return;
|
||||||
|
|
||||||
|
const $btn = $(target).closest('[data-button]');
|
||||||
|
if (!$btn.$el) return;
|
||||||
|
|
||||||
|
const btnEvent = $btn?.data?.button;
|
||||||
|
|
||||||
|
switch (btnEvent) {
|
||||||
|
case 'exit': {
|
||||||
|
window.location.hash = '';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'delete-table': {
|
||||||
|
this.$dispatch(deleteTable(this.store.getState().id));
|
||||||
|
console.log('THIS', this);
|
||||||
|
this.destroy();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
|
import { $, Dom } from 'core/dom';
|
||||||
|
import { ExcelComponent } from 'core/ExcelComponent';
|
||||||
|
import { parse } from 'core/parse';
|
||||||
|
import { changeCurrentStyles } from 'redux/actions';
|
||||||
|
import * as actions from 'redux/actions';
|
||||||
import { initialStyleState } from '../../constants';
|
import { initialStyleState } from '../../constants';
|
||||||
import { $, Dom } from '../../core/dom';
|
|
||||||
import { ExcelComponent } from '../../core/ExcelComponent';
|
|
||||||
import { parse } from '../../core/parse';
|
|
||||||
import { changeCurrentStyles } from '../../redux/actions';
|
|
||||||
import * as actions from '../../redux/actions';
|
|
||||||
import { resizeHandler } from './handlers/table.resize';
|
import { resizeHandler } from './handlers/table.resize';
|
||||||
import { selectHandler } from './handlers/table.select.handler';
|
import { selectHandler } from './handlers/table.select.handler';
|
||||||
import { createTable } from './table.template';
|
import { createTable } from './table.template';
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { $, Dom } from '../../core/dom';
|
import { $, Dom } from 'core/dom';
|
||||||
import { getParamsFromCellId } from './table.functions';
|
import { getParamsFromCellId } from './table.functions';
|
||||||
|
|
||||||
export class TableSelection {
|
export class TableSelection {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { $, Dom } from '../../../core/dom';
|
import { $, Dom } from 'core/dom';
|
||||||
|
|
||||||
type CustomElementType = Element & { css: any };
|
type CustomElementType = Element & { css: any };
|
||||||
type ResizeReturnDataType = { value: number, id: string, type: string };
|
type ResizeReturnDataType = { value: number, id: string, type: string };
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { $ } from '../../../core/dom';
|
import { $ } from 'core/dom';
|
||||||
import { getParamsFromCellId, isCell } from '../table.functions';
|
import { getParamsFromCellId, isCell } from '../table.functions';
|
||||||
import { TableSelection } from '../TableSelection';
|
import { TableSelection } from '../TableSelection';
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { $ } from '../../core/dom';
|
import { $ } from 'core/dom';
|
||||||
|
|
||||||
export function isCell(event: Event): boolean {
|
export function isCell(event: Event): boolean {
|
||||||
return $(event.target as HTMLElement).data.type === 'cell';
|
return $(event.target as HTMLElement).data.type === 'cell';
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { initialStyleState } from '../../constants';
|
import { $, Dom } from 'core/dom';
|
||||||
import { $, Dom } from '../../core/dom';
|
import { ExcelStateComponent } from 'core/ExcelStateComponent';
|
||||||
import { OptionsType } from '../../core/ExcelComponent';
|
import { OptionsType } from 'core/ExcelComponent';
|
||||||
import { ExcelStateComponent } from '../../core/ExcelStateComponent';
|
|
||||||
import { createToolbar } from './toolbar.template';
|
import { createToolbar } from './toolbar.template';
|
||||||
|
import { initialStyleState } from '../../constants';
|
||||||
|
|
||||||
export class Toolbar extends ExcelStateComponent {
|
export class Toolbar extends ExcelStateComponent {
|
||||||
static className = 'excel__toolbar';
|
static className = 'excel__toolbar';
|
||||||
@ -18,7 +18,6 @@ export class Toolbar extends ExcelStateComponent {
|
|||||||
|
|
||||||
prepare() {
|
prepare() {
|
||||||
const currentToolbarState = this.toolbarState;
|
const currentToolbarState = this.toolbarState;
|
||||||
console.log('Current state', currentToolbarState);
|
|
||||||
|
|
||||||
this.initState(currentToolbarState);
|
this.initState(currentToolbarState);
|
||||||
}
|
}
|
||||||
@ -44,7 +43,10 @@ export class Toolbar extends ExcelStateComponent {
|
|||||||
|
|
||||||
onClick(event: MouseEvent) {
|
onClick(event: MouseEvent) {
|
||||||
const target = $(event.target as HTMLElement);
|
const target = $(event.target as HTMLElement);
|
||||||
const value = JSON.parse(target.data.value);
|
const stringValue = target?.data?.value;
|
||||||
|
if (!stringValue) return;
|
||||||
|
|
||||||
|
const value = JSON.parse(stringValue);
|
||||||
const key = Object.keys(value)[0];
|
const key = Object.keys(value)[0];
|
||||||
|
|
||||||
this.$emit('toolbar:applyStyle', value);
|
this.$emit('toolbar:applyStyle', value);
|
||||||
|
|||||||
@ -8,13 +8,16 @@ export const initialStyleState: Partial<CSSStyleDeclaration> = {
|
|||||||
fontStyle: 'normal',
|
fontStyle: 'normal',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const initialState: StateType = {
|
export function getNormalizeInitialState(params: string): StateType {
|
||||||
colState: {},
|
return {
|
||||||
rowState: {},
|
colState: {},
|
||||||
dataState: {},
|
rowState: {},
|
||||||
currentText: '',
|
dataState: {},
|
||||||
stylesState: {},
|
currentText: '',
|
||||||
title: 'New excel table',
|
stylesState: {},
|
||||||
...storage('excel-state'),
|
title: 'New excel table',
|
||||||
currentStyles: { ...storage('excel-state')?.stylesState?.['0:0'] },
|
...storage(`excel:${params}`),
|
||||||
};
|
currentStyles: { ...storage(`excel:${params}`)?.stylesState?.['0:0'] },
|
||||||
|
id: params,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { ActionType, SubscribeType } from '../redux/types';
|
import { ActionType, SubscribeType } from 'redux/types';
|
||||||
import { Store } from './createStore';
|
import { Store } from './createStore';
|
||||||
import { Dom } from './dom';
|
import { Dom } from './dom';
|
||||||
import { DomListener } from './DomListener';
|
import { DomListener } from './DomListener';
|
||||||
@ -73,6 +73,5 @@ export abstract class ExcelComponent extends DomListener implements ExcelCompone
|
|||||||
destroy() {
|
destroy() {
|
||||||
this.removeDOMListeners();
|
this.removeDOMListeners();
|
||||||
this.unsubscribers.forEach(unsub => unsub());
|
this.unsubscribers.forEach(unsub => unsub());
|
||||||
this.storeSub.unsubscribe();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
src/core/Page.ts
Normal file
19
src/core/Page.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
export abstract class Page {
|
||||||
|
params: any;
|
||||||
|
|
||||||
|
constructor(params: any) {
|
||||||
|
this.params = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
getRoot() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
afterRender() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { StateType } from '../redux/types';
|
import { StateType } from 'redux/types';
|
||||||
import { Store } from './createStore';
|
import { Store } from './createStore';
|
||||||
import { isEqual } from './utils';
|
import { isEqual } from './utils';
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import { initialState } from '../constants';
|
|
||||||
import { ActionType, ReducerType, StateType, SubscribeType } from '../redux/types';
|
import { ActionType, ReducerType, StateType, SubscribeType } from '../redux/types';
|
||||||
|
|
||||||
export class Store {
|
export class Store {
|
||||||
state: StateType;
|
state: StateType;
|
||||||
listeners: ((args?: any) => void)[];
|
listeners: ((args?: any) => void)[];
|
||||||
|
|
||||||
constructor(private reducer: ReducerType) {
|
constructor(private reducer: ReducerType, initialState: StateType) {
|
||||||
this.state = reducer({ ...initialState }, { type: '__INIT__' });
|
this.state = reducer({ ...initialState }, { type: '__INIT__' });
|
||||||
this.listeners = [];
|
this.listeners = [];
|
||||||
}
|
}
|
||||||
@ -13,7 +12,7 @@ export class Store {
|
|||||||
subscribe(fn: (state?: StateType) => void): SubscribeType {
|
subscribe(fn: (state?: StateType) => void): SubscribeType {
|
||||||
this.listeners.push(fn);
|
this.listeners.push(fn);
|
||||||
return {
|
return {
|
||||||
unsubscribe() {
|
unsubscribe: () => {
|
||||||
this.listeners = this.listeners.filter((l: any) => l !== fn);
|
this.listeners = this.listeners.filter((l: any) => l !== fn);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
9
src/core/routes/ActiveRoute.ts
Normal file
9
src/core/routes/ActiveRoute.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export class ActiveRoute {
|
||||||
|
static get path() {
|
||||||
|
return window.location.hash.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static get param() {
|
||||||
|
return window.location.hash.split('/');
|
||||||
|
}
|
||||||
|
}
|
||||||
57
src/core/routes/router.ts
Normal file
57
src/core/routes/router.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { DashboardPage } from 'pages/DashboardPage';
|
||||||
|
import { ExcelPage } from 'pages/ExcelPage';
|
||||||
|
import { $, Dom } from 'core/dom';
|
||||||
|
import { ActiveRoute } from './ActiveRoute';
|
||||||
|
|
||||||
|
export class Router {
|
||||||
|
private $placeholder: Dom;
|
||||||
|
private routes: {
|
||||||
|
dashboard: DashboardPage
|
||||||
|
excel: ExcelPage
|
||||||
|
};
|
||||||
|
private page: DashboardPage | ExcelPage;
|
||||||
|
|
||||||
|
constructor(selector: string, routes: any) {
|
||||||
|
if (!selector) throw new Error('Selector not provided');
|
||||||
|
|
||||||
|
this.$placeholder = $(selector);
|
||||||
|
this.routes = routes;
|
||||||
|
this.page = null;
|
||||||
|
|
||||||
|
this.changePageHandler = this.changePageHandler.bind(this);
|
||||||
|
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
window.addEventListener('hashchange', this.changePageHandler);
|
||||||
|
this.changePageHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
changePageHandler() {
|
||||||
|
this.$placeholder.clear();
|
||||||
|
this.page?.destroy();
|
||||||
|
|
||||||
|
let Page;
|
||||||
|
|
||||||
|
switch (true) {
|
||||||
|
case ActiveRoute.path.includes('excel'):
|
||||||
|
Page = this.routes.excel;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ActiveRoute.path.includes('dashboard'):
|
||||||
|
default:
|
||||||
|
Page = this.routes.dashboard;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
this.page = new Page(ActiveRoute.param);
|
||||||
|
|
||||||
|
this.$placeholder.append(this.page.getRoot());
|
||||||
|
this.page.afterRender();
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
window.removeEventListener('hashchange', this.changePageHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,9 +5,13 @@ export function capitalize(string: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function storage(key: string, data: any = null): any {
|
export function storage(key: string, data: any = null): any {
|
||||||
if (!data) return JSON.parse(localStorage.getItem(key));
|
if (!data) {
|
||||||
|
console.log('RETURN KEY', key, data);
|
||||||
|
return JSON.parse(localStorage.getItem(key));
|
||||||
|
}
|
||||||
|
|
||||||
localStorage.setItem(key, JSON.stringify(data));
|
localStorage.setItem(key, JSON.stringify(data));
|
||||||
|
console.log('SET ITEM', key, data);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
28
src/index.ts
28
src/index.ts
@ -1,25 +1,9 @@
|
|||||||
import { Excel } from './components/excel/Excel';
|
|
||||||
import { Formula } from './components/formula/Formula';
|
|
||||||
import { Header } from './components/header/Header';
|
|
||||||
import { Table } from './components/table/Table';
|
|
||||||
import { Toolbar } from './components/toolbar/Toolbar';
|
|
||||||
import './styles/index.scss';
|
import './styles/index.scss';
|
||||||
import { Store } from './core/createStore';
|
import { Router } from 'core/routes/router';
|
||||||
import { debounce, storage } from './core/utils';
|
import { DashboardPage } from 'pages/DashboardPage';
|
||||||
import { rootReducer } from './redux/rootReducer';
|
import { ExcelPage } from 'pages/ExcelPage';
|
||||||
import { StateType } from './redux/types';
|
|
||||||
|
|
||||||
const store = new Store(rootReducer);
|
new Router('#app', {
|
||||||
|
dashboard: DashboardPage,
|
||||||
const stateListener = debounce((state: StateType) => {
|
excel: ExcelPage,
|
||||||
storage('excel-state', state);
|
|
||||||
}, 300);
|
|
||||||
|
|
||||||
store.subscribe(stateListener);
|
|
||||||
|
|
||||||
const excel = new Excel('#app', {
|
|
||||||
components: [Header, Toolbar, Formula, Table],
|
|
||||||
store,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
excel.render();
|
|
||||||
|
|||||||
25
src/pages/DashboardPage.ts
Normal file
25
src/pages/DashboardPage.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { Page } from 'core/Page';
|
||||||
|
import { $ } from 'core/dom';
|
||||||
|
import { createRecordsTable } from 'pages/dashboard.functions';
|
||||||
|
|
||||||
|
export class DashboardPage extends Page {
|
||||||
|
getRoot() {
|
||||||
|
const id = Date.now().toString();
|
||||||
|
|
||||||
|
return $.create('div', 'db').html(
|
||||||
|
`
|
||||||
|
<div class="db__header">
|
||||||
|
<h1>Excel Панель управыления</h1>
|
||||||
|
</div>
|
||||||
|
<div class="db__new">
|
||||||
|
<div class="db__view">
|
||||||
|
<a href="#excel/${id}" class="db__create">Новая таблица</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="db__table db__view">
|
||||||
|
${createRecordsTable()}
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
46
src/pages/ExcelPage.ts
Normal file
46
src/pages/ExcelPage.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { Excel } from 'components/excel/Excel';
|
||||||
|
import { Formula } from 'components/formula/Formula';
|
||||||
|
import { Header } from 'components/header/Header';
|
||||||
|
import { Table } from 'components/table/Table';
|
||||||
|
import { Toolbar } from 'components/toolbar/Toolbar';
|
||||||
|
import { Store } from 'core/createStore';
|
||||||
|
import { Page } from 'core/Page';
|
||||||
|
import { debounce, storage } from 'core/utils';
|
||||||
|
import { rootReducer } from 'redux/rootReducer';
|
||||||
|
import { StateType } from 'redux/types';
|
||||||
|
import { getNormalizeInitialState } from '../constants';
|
||||||
|
|
||||||
|
export function storageName(param: string) {
|
||||||
|
return `excel:${param}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ExcelPage extends Page {
|
||||||
|
private excel: Excel;
|
||||||
|
|
||||||
|
getRoot() {
|
||||||
|
const params = this.params[1] ? this.params[1] : Date.now().toString();
|
||||||
|
const normalizeState = storage(storageName(params)) || getNormalizeInitialState(params);
|
||||||
|
const store = new Store(rootReducer, normalizeState);
|
||||||
|
|
||||||
|
const stateListener = debounce((state: StateType) => {
|
||||||
|
storage(storageName(params), state);
|
||||||
|
}, 300);
|
||||||
|
|
||||||
|
store.subscribe(stateListener);
|
||||||
|
|
||||||
|
this.excel = new Excel({
|
||||||
|
components: [Header, Toolbar, Formula, Table],
|
||||||
|
store,
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.excel.getRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
afterRender() {
|
||||||
|
this.excel.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.excel.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
46
src/pages/dashboard.functions.ts
Normal file
46
src/pages/dashboard.functions.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { storage } from 'core/utils';
|
||||||
|
|
||||||
|
function toHtml(key: string) {
|
||||||
|
const date = +key.split(':')[1];
|
||||||
|
const params = storage(key);
|
||||||
|
const link = `#excel/${date}`;
|
||||||
|
return `
|
||||||
|
<li class="db__record">
|
||||||
|
<a href=${link}>${params.title}</a>
|
||||||
|
<strong>${new Date(date).toLocaleDateString()}</strong>
|
||||||
|
</li>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAllRecords() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createRecordsTable() {
|
||||||
|
const keys = getAllKeys();
|
||||||
|
if (!keys.length) return '<p>Пока не создали ни одной таблицы</p>';
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div class="db__list-header">
|
||||||
|
<span>Название</span>
|
||||||
|
<span>Дата открытия</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="db__list">
|
||||||
|
${keys.map((key) => toHtml(key)).join('')}
|
||||||
|
</ul>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAllKeys() {
|
||||||
|
const keys = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < localStorage.length; i++) {
|
||||||
|
const key = localStorage.key(i);
|
||||||
|
if (!key.includes('excel')) continue;
|
||||||
|
|
||||||
|
keys.push(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { CHANGE_TEXT, CHANGE_STYLES, TABLE_RESIZE, APPLY_STYLES, CHANGE_TITLE } from './constants';
|
import { CHANGE_TEXT, CHANGE_STYLES, TABLE_RESIZE, APPLY_STYLES, CHANGE_TITLE, DELETE_TABLE } from './constants';
|
||||||
|
|
||||||
export function tableResize(resizeData: any) {
|
export function tableResize(resizeData: any) {
|
||||||
return {
|
return {
|
||||||
@ -34,3 +34,10 @@ export function changeTitle(data: string) {
|
|||||||
data,
|
data,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function deleteTable(data: string) {
|
||||||
|
return {
|
||||||
|
type: DELETE_TABLE,
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@ -3,3 +3,4 @@ export const CHANGE_TEXT = 'CHANGE_TEXT';
|
|||||||
export const APPLY_STYLES = 'APPLY_STYLES';
|
export const APPLY_STYLES = 'APPLY_STYLES';
|
||||||
export const CHANGE_STYLES = 'CURRENT_STYLES';
|
export const CHANGE_STYLES = 'CURRENT_STYLES';
|
||||||
export const CHANGE_TITLE = 'CHANGE_TITLE';
|
export const CHANGE_TITLE = 'CHANGE_TITLE';
|
||||||
|
export const DELETE_TABLE = 'DELETE_TABLE';
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { CHANGE_TEXT, CHANGE_STYLES, TABLE_RESIZE, APPLY_STYLES, CHANGE_TITLE } from './constants';
|
import { storageName } from 'pages/ExcelPage';
|
||||||
|
import { CHANGE_TEXT, CHANGE_STYLES, TABLE_RESIZE, APPLY_STYLES, CHANGE_TITLE, DELETE_TABLE } from './constants';
|
||||||
import { ActionType, StateType } from './types';
|
import { ActionType, StateType } from './types';
|
||||||
|
|
||||||
export function rootReducer(state: StateType, action: ActionType) {
|
export function rootReducer(state: StateType, action: ActionType) {
|
||||||
@ -44,6 +45,15 @@ export function rootReducer(state: StateType, action: ActionType) {
|
|||||||
return { ...state, title: action.data };
|
return { ...state, title: action.data };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case DELETE_TABLE: {
|
||||||
|
const name = storageName(action.data);
|
||||||
|
console.log('delete table item', name);
|
||||||
|
localStorage.removeItem(name);
|
||||||
|
window.location.hash = '';
|
||||||
|
|
||||||
|
return { ...state };
|
||||||
|
}
|
||||||
|
|
||||||
default: return state;
|
default: return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user