From 62fbe6a91605e13c59e3641c23ca89fc738a7a90 Mon Sep 17 00:00:00 2001 From: Sergey Kazarinov Date: Tue, 18 Jun 2024 12:20:24 +0500 Subject: [PATCH 1/9] feat: add structure of the routes --- docs/developments.md | 4 ++++ src/components/formula/Formula.ts | 1 - src/core/dom/dom.ts | 4 +--- structures/routing.dio | 40 +++++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 structures/routing.dio diff --git a/docs/developments.md b/docs/developments.md index 7f20e19..41c79f4 100644 --- a/docs/developments.md +++ b/docs/developments.md @@ -49,3 +49,7 @@ - Реализовано добавление стилей для ячеек в соответствии с тулбаром - Реализовано изменение заголовка таблицы - Реализован [debounce](/src/helpers/debounce.ts) для оптимизации + +#### Routing + +- Реализован [роутинг](../structures/routing.dio) приложения. diff --git a/src/components/formula/Formula.ts b/src/components/formula/Formula.ts index 3b77e26..a3f9243 100644 --- a/src/components/formula/Formula.ts +++ b/src/components/formula/Formula.ts @@ -35,7 +35,6 @@ class Formula extends ExcelComponent implements IFormula { this.$subscribe('table:select', ($cell: Dom) => { const id = $cell.getId(); const dataValue = $cell.attr('data-value'); - console.log('dataValue', dataValue); if (id) { this.$dispatch(actions.changeTextActionCreator({ text: $cell.text(), id })); } diff --git a/src/core/dom/dom.ts b/src/core/dom/dom.ts index 66db3e8..c9e957e 100644 --- a/src/core/dom/dom.ts +++ b/src/core/dom/dom.ts @@ -239,9 +239,7 @@ export class Dom implements IDom { attr(name: string, value: string): this; attr(name: string): string | undefined | null; attr(name: string, value?: string): string | this | undefined | null { - console.log('value', value); - if (value) { - console.log('name', name); + if (typeof value === 'string') { this.$el?.setAttribute(name, value); return this; } diff --git a/structures/routing.dio b/structures/routing.dio new file mode 100644 index 0000000..7704a65 --- /dev/null +++ b/structures/routing.dio @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 089dd922f5a4453e8b8be9167c4f0794bf2555c8 Mon Sep 17 00:00:00 2001 From: Sergey Kazarinov Date: Tue, 18 Jun 2024 13:02:23 +0500 Subject: [PATCH 2/9] feat: add Router for routing --- src/core/routes/ActiveRoute.ts | 25 ++++++++++++++++ src/core/routes/Router.ts | 52 ++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 src/core/routes/ActiveRoute.ts create mode 100644 src/core/routes/Router.ts diff --git a/src/core/routes/ActiveRoute.ts b/src/core/routes/ActiveRoute.ts new file mode 100644 index 0000000..d470b1f --- /dev/null +++ b/src/core/routes/ActiveRoute.ts @@ -0,0 +1,25 @@ +class ActiveRoute { + /** + * Геттер получения текущего адреса + * + * @static + * @readonly + * @type {string} + */ + static get path() { + return window.location.hash.slice(1); + } + + /** + * Геттер получения параметра таблицы + * + * @static + * @readonly + * @type {string} + */ + static get param() { + return ActiveRoute.path.split('/')[1]; + } +} + +export default ActiveRoute; diff --git a/src/core/routes/Router.ts b/src/core/routes/Router.ts new file mode 100644 index 0000000..35ca7e3 --- /dev/null +++ b/src/core/routes/Router.ts @@ -0,0 +1,52 @@ +import $, { Dom } from '../dom/dom'; +import ActiveRoute from './ActiveRoute'; + +interface IRouter { + /** + * Инициализация роутинга + * Добавление слушателя события на изменения hash + */ + init(): void; + changePageHandler(): void; + /** + * Метод при размонтировании + * Удаляет слушатели событий + */ + destroy(): void; +} + +class Router implements IRouter { + private $placeholder: Dom; + + private routes: any; + + constructor(selector: string, routes: any) { + if (!selector) { + throw new Error('Selector is not provided in Router'); + } + + this.$placeholder = $(selector); + this.routes = routes; + + this.changePageHandler = this.changePageHandler.bind(this); + + this.init(); + } + + init() { + window.addEventListener('hashchange', this.changePageHandler); + this.changePageHandler(); + } + + changePageHandler() { + console.info(ActiveRoute.path); + + this.$placeholder.html(`

${ActiveRoute.path}

`); + } + + destroy() { + window.removeEventListener('hashchange', this.changePageHandler); + } +} + +export default Router; From cae5b6c83a02bdaa7e38b25dc03262f19166f38f Mon Sep 17 00:00:00 2001 From: Sergey Kazarinov Date: Tue, 18 Jun 2024 13:59:10 +0500 Subject: [PATCH 3/9] feat: add dashboardPage and ExcelPage --- src/components/excel/Excel.ts | 8 ++---- src/core/routes/Page.ts | 30 +++++++++++++++++++++ src/core/routes/Router.ts | 18 +++++++++---- src/index.ts | 32 +++++----------------- src/pages/DashboardPage.ts | 34 +++++++++++++++++++++++ src/pages/ExcelPage.ts | 51 +++++++++++++++++++++++++++++++++++ 6 files changed, 137 insertions(+), 36 deletions(-) create mode 100644 src/core/routes/Page.ts create mode 100644 src/pages/DashboardPage.ts create mode 100644 src/pages/ExcelPage.ts diff --git a/src/components/excel/Excel.ts b/src/components/excel/Excel.ts index c1ec99a..d6fec02 100644 --- a/src/components/excel/Excel.ts +++ b/src/components/excel/Excel.ts @@ -11,8 +11,6 @@ interface IExcelOptions { } class Excel { - public $el; - public components: (new (...arg: any[]) => T)[]; public objectComponents: T[]; @@ -23,8 +21,7 @@ class Excel { public subscriber: StoreSubscriber; - constructor(selector: string, options: IExcelOptions) { - this.$el = $(selector); + constructor(options: IExcelOptions) { this.components = options.components || []; this.objectComponents = []; this.observer = new Observer(); @@ -51,8 +48,7 @@ class Excel { return $root; } - render() { - this.$el?.append(this.getRoot()); + init() { this.subscriber.subscribeComponents(this.objectComponents); this.objectComponents.forEach((component) => { component.init(); diff --git a/src/core/routes/Page.ts b/src/core/routes/Page.ts new file mode 100644 index 0000000..480c879 --- /dev/null +++ b/src/core/routes/Page.ts @@ -0,0 +1,30 @@ +import { Dom } from '../dom/dom'; + +interface IPage { + getRoot(): Dom; + afterRender(): void; + destroy(): void; +} + +class Page implements IPage { + private params: any; + + constructor(params?: any) { + this.params = params; + } + + /** + * Метод выбрасывает ошибку, если не реализован в классах наследников + * + * @returns {Element} + */ + getRoot(): Dom { + throw new Error('error page'); + } + + afterRender(): void {} + + destroy(): void {} +} + +export default Page; diff --git a/src/core/routes/Router.ts b/src/core/routes/Router.ts index 35ca7e3..2f0150a 100644 --- a/src/core/routes/Router.ts +++ b/src/core/routes/Router.ts @@ -1,5 +1,11 @@ +import DashboardPage from '@src/pages/DashboardPage'; +import ExcelPage from '@src/pages/ExcelPage'; import $, { Dom } from '../dom/dom'; -import ActiveRoute from './ActiveRoute'; + +interface IRoutesParams { + dashboard: new (...arg: any[]) => DashboardPage; + excel: new (...arg: any[]) => ExcelPage; +} interface IRouter { /** @@ -18,9 +24,9 @@ interface IRouter { class Router implements IRouter { private $placeholder: Dom; - private routes: any; + private routes: IRoutesParams; - constructor(selector: string, routes: any) { + constructor(selector: string, routes: IRoutesParams) { if (!selector) { throw new Error('Selector is not provided in Router'); } @@ -39,9 +45,11 @@ class Router implements IRouter { } changePageHandler() { - console.info(ActiveRoute.path); + const Page = this.routes.excel; - this.$placeholder.html(`

${ActiveRoute.path}

`); + const page = new Page(); + this.$placeholder.append(page.getRoot()); + page.afterRender(); } destroy() { diff --git a/src/index.ts b/src/index.ts index 31da3ac..cfe95d7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,28 +1,10 @@ -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 { EXCEL_STATE } from './consts/localStorage'; -import debounce from './helpers/debounce'; -import localStorageFn from './helpers/localStorage'; +import Router from './core/routes/Router'; +import DashboardPage from './pages/DashboardPage'; +import ExcelPage from './pages/ExcelPage'; import './scss/index.scss'; -import createStore from './store/createStore'; -import { initialState } from './store/initialState'; -import rootReducer from './store/rootReducer'; -const store = createStore(rootReducer, initialState); - -const stateListener = debounce((state: S) => { - console.info(state); - localStorageFn(EXCEL_STATE, state); -}, 500); - -store.subscribe(stateListener); - -const excel = new Excel
('#app', { - components: [Header, Toolbar, Formula, Table], - store, +// eslint-disable-next-line +new Router('#app', { + dashboard: DashboardPage, + excel: ExcelPage, }); - -excel.render(); diff --git a/src/pages/DashboardPage.ts b/src/pages/DashboardPage.ts new file mode 100644 index 0000000..ede733c --- /dev/null +++ b/src/pages/DashboardPage.ts @@ -0,0 +1,34 @@ +import $, { Dom } from '@src/core/dom/dom'; +import Page from '@src/core/routes/Page'; + +class DashboardPage extends Page { + getRoot(): Dom { + const nodeElement = $.create('div', 'dashboard').html(/* html */ ` +
+

Excel Dashboard

+
+ + +
+
+ Название + Дата открытия +
+ + +
+ `); + return nodeElement as Dom; + } +} + +export default DashboardPage; diff --git a/src/pages/ExcelPage.ts b/src/pages/ExcelPage.ts new file mode 100644 index 0000000..4c3f601 --- /dev/null +++ b/src/pages/ExcelPage.ts @@ -0,0 +1,51 @@ +import Excel from '@src/components/excel/Excel'; +import Formula from '@src/components/formula/Formula'; +import Header from '@src/components/header/Header'; +import Table from '@src/components/table/Table'; +import Toolbar from '@src/components/toolbar/Toolbar'; +import { EXCEL_STATE } from '@src/consts/localStorage'; +import { Dom } from '@src/core/dom/dom'; +import Page from '@src/core/routes/Page'; +import debounce from '@src/helpers/debounce'; +import localStorageFn from '@src/helpers/localStorage'; +import createStore from '@src/store/createStore'; +import initialState from '@src/store/initialState'; +import rootReducer from '@src/store/rootReducer'; + +type TExcelGeneric = Header | Toolbar | Formula | Table; + +class ExcelPage extends Page { + private excel: Excel
| null; + + constructor() { + super(); + this.excel = null; + } + + getRoot(): Dom { + const store = createStore(rootReducer, initialState); + + const stateListener = debounce((state: S) => { + localStorageFn(EXCEL_STATE, state); + }, 500); + + store.subscribe(stateListener); + + this.excel = new Excel({ + components: [Header, Toolbar, Formula, Table], + store, + }); + + return this.excel.getRoot(); + } + + afterRender(): void { + this.excel?.init(); + } + + destroy(): void { + this.excel?.destroy(); + } +} + +export default ExcelPage; From 6fb978c96f979f031045166a9ba5f1ed4dc98032 Mon Sep 17 00:00:00 2001 From: Sergey Kazarinov Date: Tue, 18 Jun 2024 16:27:03 +0500 Subject: [PATCH 4/9] feat: add different routes for pages --- src/core/routes/Router.ts | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/core/routes/Router.ts b/src/core/routes/Router.ts index 2f0150a..f2b4e2e 100644 --- a/src/core/routes/Router.ts +++ b/src/core/routes/Router.ts @@ -1,6 +1,8 @@ import DashboardPage from '@src/pages/DashboardPage'; import ExcelPage from '@src/pages/ExcelPage'; import $, { Dom } from '../dom/dom'; +import ActiveRoute from './ActiveRoute'; +import Page from './Page'; interface IRoutesParams { dashboard: new (...arg: any[]) => DashboardPage; @@ -13,6 +15,10 @@ interface IRouter { * Добавление слушателя события на изменения hash */ init(): void; + + /** + * Метод рендеринга страницы (компонента) + */ changePageHandler(): void; /** * Метод при размонтировании @@ -26,6 +32,8 @@ class Router implements IRouter { private routes: IRoutesParams; + private page: null | Page; + constructor(selector: string, routes: IRoutesParams) { if (!selector) { throw new Error('Selector is not provided in Router'); @@ -33,6 +41,7 @@ class Router implements IRouter { this.$placeholder = $(selector); this.routes = routes; + this.page = null; this.changePageHandler = this.changePageHandler.bind(this); @@ -45,11 +54,15 @@ class Router implements IRouter { } changePageHandler() { - const Page = this.routes.excel; + this.$placeholder.clear(); + if (this.page) { + this.page.destroy(); + } + const PageClass = ActiveRoute.path.includes('excel') ? this.routes.excel : this.routes.dashboard; - const page = new Page(); - this.$placeholder.append(page.getRoot()); - page.afterRender(); + this.page = new PageClass(ActiveRoute.param); + this.$placeholder.append(this.page.getRoot()); + this.page.afterRender(); } destroy() { From e6f6a6d50d299ebbabc35474161ae379dcfb278f Mon Sep 17 00:00:00 2001 From: Sergey Kazarinov Date: Tue, 18 Jun 2024 17:57:59 +0500 Subject: [PATCH 5/9] refact: dashboardPage - add dashboard.functions --- .../dashboard/dashboard.functions.ts | 38 +++++++++++++++++++ src/pages/DashboardPage.ts | 16 ++------ 2 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 src/components/dashboard/dashboard.functions.ts diff --git a/src/components/dashboard/dashboard.functions.ts b/src/components/dashboard/dashboard.functions.ts new file mode 100644 index 0000000..43971ad --- /dev/null +++ b/src/components/dashboard/dashboard.functions.ts @@ -0,0 +1,38 @@ +export const toHTML = () => /* html */ ` +
  • + Таблица №1 + 12.06.2023 +
  • + `; + +export const getAllKeys = () => { + const keys = []; + for (let i = 0; i < localStorage.length; i++) { + const key = localStorage.key(i); + if (key?.includes('excel')) { + keys.push(key); + } + } + return keys; +}; + +export const createTable = () => { + const keys = getAllKeys(); + + if (!keys.length) { + return ` +

    Таблицы отсутствуют

    + `; + } + + return ` +
    + Название + Дата открытия +
    + +
      + ${keys.map(toHTML).join('')} +
    + `; +}; diff --git a/src/pages/DashboardPage.ts b/src/pages/DashboardPage.ts index ede733c..fb2af36 100644 --- a/src/pages/DashboardPage.ts +++ b/src/pages/DashboardPage.ts @@ -1,30 +1,22 @@ +import { createTable } from '@src/components/dashboard/dashboard.functions'; import $, { Dom } from '@src/core/dom/dom'; import Page from '@src/core/routes/Page'; class DashboardPage extends Page { getRoot(): Dom { + const newId = Date.now().toString(); const nodeElement = $.create('div', 'dashboard').html(/* html */ `

    Excel Dashboard

    -
    - Название - Дата открытия -
    - - + ${createTable()}
    `); return nodeElement as Dom; From 33dfe775359277cc6b9c4762a39cf6be11755d6d Mon Sep 17 00:00:00 2001 From: Sergey Kazarinov Date: Wed, 19 Jun 2024 19:40:19 +0500 Subject: [PATCH 6/9] feat: add diferent states for diferents params --- src/components/header/Header.ts | 4 ++-- src/consts/consts.ts | 2 +- src/core/routes/Page.ts | 4 ++-- src/core/routes/Router.ts | 1 - src/helpers/localStorage.ts | 2 +- src/pages/ExcelPage.ts | 16 ++++++++++------ src/store/initialState.ts | 14 ++++++++++---- 7 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/components/header/Header.ts b/src/components/header/Header.ts index a94231b..a24ed53 100644 --- a/src/components/header/Header.ts +++ b/src/components/header/Header.ts @@ -1,4 +1,4 @@ -import { defaultTitle } from '@src/consts/consts'; +import { DEFAULT_TITLE } from '@src/consts/consts'; import $, { Dom } from '@src/core/dom/dom'; import ExcelComponent from '@src/core/excelComponent/ExcelComponent'; import debounce from '@src/helpers/debounce'; @@ -24,7 +24,7 @@ class Header extends ExcelComponent implements IHeader { } toHTML(): string { - const { title = defaultTitle } = this.store.getState(); + const { title = DEFAULT_TITLE } = this.store.getState(); return `
    diff --git a/src/consts/consts.ts b/src/consts/consts.ts index 9900710..a5d07cf 100644 --- a/src/consts/consts.ts +++ b/src/consts/consts.ts @@ -7,4 +7,4 @@ export const initialToolbarState: IToolbarState = { fontStyle: 'normal', }; -export const defaultTitle = 'Новая таблица'; +export const DEFAULT_TITLE = 'Новая таблица'; diff --git a/src/core/routes/Page.ts b/src/core/routes/Page.ts index 480c879..16f73be 100644 --- a/src/core/routes/Page.ts +++ b/src/core/routes/Page.ts @@ -7,9 +7,9 @@ interface IPage { } class Page implements IPage { - private params: any; + protected params: string | undefined; - constructor(params?: any) { + constructor(params?: string) { this.params = params; } diff --git a/src/core/routes/Router.ts b/src/core/routes/Router.ts index f2b4e2e..39417aa 100644 --- a/src/core/routes/Router.ts +++ b/src/core/routes/Router.ts @@ -59,7 +59,6 @@ class Router implements IRouter { this.page.destroy(); } const PageClass = ActiveRoute.path.includes('excel') ? this.routes.excel : this.routes.dashboard; - this.page = new PageClass(ActiveRoute.param); this.$placeholder.append(this.page.getRoot()); this.page.afterRender(); diff --git a/src/helpers/localStorage.ts b/src/helpers/localStorage.ts index f2b20b2..934a60d 100644 --- a/src/helpers/localStorage.ts +++ b/src/helpers/localStorage.ts @@ -7,7 +7,7 @@ const localStorageFn = (key: string, data?: unknown) => { if (!data) { const localStorageData = localStorage.getItem(key); - return localStorageData && (JSON.parse(localStorageData) as R); + return localStorageData ? (JSON.parse(localStorageData) as R) : undefined; } localStorage.setItem(key, JSON.stringify(data)); diff --git a/src/pages/ExcelPage.ts b/src/pages/ExcelPage.ts index 4c3f601..b9d82ea 100644 --- a/src/pages/ExcelPage.ts +++ b/src/pages/ExcelPage.ts @@ -3,30 +3,34 @@ import Formula from '@src/components/formula/Formula'; import Header from '@src/components/header/Header'; import Table from '@src/components/table/Table'; import Toolbar from '@src/components/toolbar/Toolbar'; -import { EXCEL_STATE } from '@src/consts/localStorage'; import { Dom } from '@src/core/dom/dom'; import Page from '@src/core/routes/Page'; import debounce from '@src/helpers/debounce'; import localStorageFn from '@src/helpers/localStorage'; import createStore from '@src/store/createStore'; -import initialState from '@src/store/initialState'; +import { normalizeInitialState } from '@src/store/initialState'; import rootReducer from '@src/store/rootReducer'; +import { IRootState } from '@src/store/store.types'; type TExcelGeneric = Header | Toolbar | Formula | Table; +const storageName = (param: string | undefined) => `excel:${param}`; + class ExcelPage extends Page { private excel: Excel
    | null; - constructor() { - super(); + constructor(params: string) { + super(params); this.excel = null; } getRoot(): Dom { - const store = createStore(rootReducer, initialState); + const params = this.params ?? Date.now().toString(); + const localState = localStorageFn(storageName(params)); + const store = createStore(rootReducer, normalizeInitialState(localState)); const stateListener = debounce((state: S) => { - localStorageFn(EXCEL_STATE, state); + localStorageFn(storageName(params), state); }, 500); store.subscribe(stateListener); diff --git a/src/store/initialState.ts b/src/store/initialState.ts index f3e6a3f..b4094c2 100644 --- a/src/store/initialState.ts +++ b/src/store/initialState.ts @@ -1,4 +1,4 @@ -import { initialToolbarState } from '@src/consts/consts'; +import { DEFAULT_TITLE, initialToolbarState } from '@src/consts/consts'; import { EXCEL_STATE } from '@src/consts/localStorage'; import localStorageFn from '@src/helpers/localStorage'; import { IRootState } from './store.types'; @@ -10,11 +10,17 @@ export const defaultState: IRootState = { stylesState: {}, currentText: '', currentStyles: initialToolbarState, - title: 'Новая таблица', + title: DEFAULT_TITLE, }; const localStorageState = localStorageFn(EXCEL_STATE); -export const initialState = localStorageState || defaultState; +export const initialState = localStorageState || structuredClone(defaultState); -export default initialState; +const normalize = (state: S) => ({ + ...state, + currentStyle: initialToolbarState, + currentText: '', +}); + +export const normalizeInitialState = (state?: S) => (state ? normalize(state) : structuredClone(defaultState)); From df7712f4f4b20574fb3b1217dbb03901e9f40de6 Mon Sep 17 00:00:00 2001 From: Sergey Kazarinov Date: Wed, 19 Jun 2024 20:16:39 +0500 Subject: [PATCH 7/9] feat: add exit button model and delete button --- .../dashboard/dashboard.functions.ts | 16 ++++++++-- src/components/header/Header.ts | 31 +++++++++++++++---- src/core/routes/ActiveRoute.ts | 4 +++ src/types/general.ts | 6 +++- 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/components/dashboard/dashboard.functions.ts b/src/components/dashboard/dashboard.functions.ts index 43971ad..e794a2b 100644 --- a/src/components/dashboard/dashboard.functions.ts +++ b/src/components/dashboard/dashboard.functions.ts @@ -1,9 +1,21 @@ -export const toHTML = () => /* html */ ` +import localStorageFn from '@src/helpers/localStorage'; +import { IRootState } from '@src/store/store.types'; + +export const toHTML = (key: string) => { + const model = localStorageFn(key); + const id = key.split(':')[1]; + + if (!model) { + return ''; + } + + return /* html */ `
  • - Таблица №1 + ${model.title} 12.06.2023
  • `; +}; export const getAllKeys = () => { const keys = []; diff --git a/src/components/header/Header.ts b/src/components/header/Header.ts index a24ed53..d1baac2 100644 --- a/src/components/header/Header.ts +++ b/src/components/header/Header.ts @@ -1,10 +1,11 @@ import { DEFAULT_TITLE } from '@src/consts/consts'; import $, { Dom } from '@src/core/dom/dom'; import ExcelComponent from '@src/core/excelComponent/ExcelComponent'; +import ActiveRoute from '@src/core/routes/ActiveRoute'; import debounce from '@src/helpers/debounce'; import { changeTitle } from '@src/store/actions'; import { IComponentOptions } from '@src/types/components'; -import { IInputEvent } from '@src/types/general'; +import { IButtonEvent, IInputEvent } from '@src/types/general'; interface IHeader {} @@ -14,7 +15,7 @@ class Header extends ExcelComponent implements IHeader { constructor($root: Dom, options: IComponentOptions) { super($root, { name: 'Header', - listeners: ['input'], + listeners: ['input', 'click'], ...options, }); } @@ -30,11 +31,11 @@ class Header extends ExcelComponent implements IHeader {
    - -
    @@ -45,6 +46,24 @@ class Header extends ExcelComponent implements IHeader { const $target = $(event.target); this.$dispatch(changeTitle($target.text())); } + + onClick(event: IButtonEvent) { + const $target = $(event.target); + + if ($target.data?.button === 'remove') { + // eslint-disable-next-line + const decision = confirm('Вы действительно хотите удалить таблицу?'); + + if (decision) { + localStorage.removeItem(`excel:${ActiveRoute.param}`); + ActiveRoute.navigate(''); + } + } + + if ($target.data?.button === 'exit') { + ActiveRoute.navigate(''); + } + } } export default Header; diff --git a/src/core/routes/ActiveRoute.ts b/src/core/routes/ActiveRoute.ts index d470b1f..ef1953c 100644 --- a/src/core/routes/ActiveRoute.ts +++ b/src/core/routes/ActiveRoute.ts @@ -20,6 +20,10 @@ class ActiveRoute { static get param() { return ActiveRoute.path.split('/')[1]; } + + static navigate(path: string) { + window.location.hash = path; + } } export default ActiveRoute; diff --git a/src/types/general.ts b/src/types/general.ts index 2c02d17..8ae9619 100644 --- a/src/types/general.ts +++ b/src/types/general.ts @@ -4,6 +4,10 @@ export interface IDivClickEvent extends MouseEvent { target: HTMLDivElement; } -export interface IInputEvent extends InputEvent { +export interface IInputEvent extends MouseEvent { target: HTMLInputElement; } + +export interface IButtonEvent extends MouseEvent { + target: HTMLButtonElement; +} From 066fdcae93d32c5f540c38db102ae63d3a09891d Mon Sep 17 00:00:00 2001 From: Sergey Kazarinov Date: Wed, 19 Jun 2024 20:26:57 +0500 Subject: [PATCH 8/9] feat: add open date for table --- src/components/dashboard/dashboard.functions.ts | 4 +++- src/components/excel/Excel.ts | 2 ++ src/store/action.types.ts | 5 +++++ src/store/actions.ts | 5 +++++ src/store/initialState.ts | 1 + src/store/rootReducer.ts | 3 +++ src/store/store.types.ts | 1 + 7 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/components/dashboard/dashboard.functions.ts b/src/components/dashboard/dashboard.functions.ts index e794a2b..85f7a86 100644 --- a/src/components/dashboard/dashboard.functions.ts +++ b/src/components/dashboard/dashboard.functions.ts @@ -12,7 +12,9 @@ export const toHTML = (key: string) => { return /* html */ `
  • ${model.title} - 12.06.2023 + + ${new Date(model.dateTable).toLocaleDateString()} ${new Date(model.dateTable).toLocaleTimeString()} +
  • `; }; diff --git a/src/components/excel/Excel.ts b/src/components/excel/Excel.ts index d6fec02..478c54c 100644 --- a/src/components/excel/Excel.ts +++ b/src/components/excel/Excel.ts @@ -3,6 +3,7 @@ import { IExcelComponent } from '@src/core/excelComponent/ExcelComponent'; import Observer from '@src/core/observer/Observer'; import StoreSubscriber from '@src/core/storeSubscriber/StoreSubscriber'; import { TActions } from '@src/store/action.types'; +import { updateDate } from '@src/store/actions'; import { IReturnCreateStore, IRootState } from '@src/store/store.types'; interface IExcelOptions { @@ -49,6 +50,7 @@ class Excel { } init() { + this.store.dispatch(updateDate()); this.subscriber.subscribeComponents(this.objectComponents); this.objectComponents.forEach((component) => { component.init(); diff --git a/src/store/action.types.ts b/src/store/action.types.ts index 498b9fe..de1ed5d 100644 --- a/src/store/action.types.ts +++ b/src/store/action.types.ts @@ -23,12 +23,17 @@ export interface IChangeTitle { payload: string; } +export interface IUpdateDate { + readonly type: 'UPDATE_DATE'; +} + export type TTableActions = | ITableResizeActionCreator | IChangeTextActionCreator | IApplyStyle | ICurrentStyles | IChangeTitle + | IUpdateDate | { type: '__INIT__'; payload: any }; export type TActions = TTableActions; diff --git a/src/store/actions.ts b/src/store/actions.ts index c189861..5812fbc 100644 --- a/src/store/actions.ts +++ b/src/store/actions.ts @@ -6,6 +6,7 @@ import { IChangeTitle, ICurrentStyles, ITableResizeActionCreator, + IUpdateDate, } from './action.types'; export const tableResizeActionCreator = (data: ITableResize): ITableResizeActionCreator => ({ @@ -32,3 +33,7 @@ export const changeTitle = (data: string): IChangeTitle => ({ type: 'CHANGE_TITLE', payload: data, }); + +export const updateDate = (): IUpdateDate => ({ + type: 'UPDATE_DATE', +}); diff --git a/src/store/initialState.ts b/src/store/initialState.ts index b4094c2..cddf983 100644 --- a/src/store/initialState.ts +++ b/src/store/initialState.ts @@ -11,6 +11,7 @@ export const defaultState: IRootState = { currentText: '', currentStyles: initialToolbarState, title: DEFAULT_TITLE, + dateTable: new Date().toJSON(), }; const localStorageState = localStorageFn(EXCEL_STATE); diff --git a/src/store/rootReducer.ts b/src/store/rootReducer.ts index 21e5b0f..e15c8e8 100644 --- a/src/store/rootReducer.ts +++ b/src/store/rootReducer.ts @@ -47,6 +47,9 @@ const rootReducer = (state: IRootState, action: TActions): IRootState => { case 'CHANGE_TITLE': return { ...state, title: action.payload }; + case 'UPDATE_DATE': + return { ...state, dateTable: new Date().toJSON() }; + default: return state; } diff --git a/src/store/store.types.ts b/src/store/store.types.ts index 68367b3..04c2a2b 100644 --- a/src/store/store.types.ts +++ b/src/store/store.types.ts @@ -18,4 +18,5 @@ export interface IRootState { currentText: string; currentStyles: IToolbarState; title: string; + dateTable: string; } From 6b140e638e4c4a395a73d455516d132b9a134941 Mon Sep 17 00:00:00 2001 From: Sergey Kazarinov Date: Wed, 19 Jun 2024 20:35:17 +0500 Subject: [PATCH 9/9] feat: update Readme --- docs/developments.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/developments.md b/docs/developments.md index 41c79f4..5eea555 100644 --- a/docs/developments.md +++ b/docs/developments.md @@ -52,4 +52,8 @@ #### Routing -- Реализован [роутинг](../structures/routing.dio) приложения. +- Реализован [роутинг](../structures/routing.dio) приложения: + - Создание новых таблиц с добавлением query-params + - Переход на существующие таблицы + - Выход в главное меню + - Удаление таблицы