Skip to content

Commit

Permalink
update to v2.1.5-beta-3
Browse files Browse the repository at this point in the history
  • Loading branch information
relaxdd committed May 31, 2023
1 parent 5ab783a commit 1cb0bc7
Show file tree
Hide file tree
Showing 14 changed files with 304 additions and 169 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "working-hours",
"homepage": "/working-hours/",
"version": "2.1.5-beta-1",
"version": "2.1.5-beta-3",
"private": true,
"dependencies": {
"bootstrap": "^5.2.3",
Expand Down
4 changes: 2 additions & 2 deletions src/defines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
// prev = 214023

export const appVersion = {
name: '2.1.5-beta-1',
code: 215021,
name: '2.1.5-beta-3',
code: 215023,
}
4 changes: 2 additions & 2 deletions src/hooks/useLog.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect } from "react"
import { useEffect } from 'react'

function useLog(data: any, deps: any[] = []) {
deps = deps.length ? deps : [data]
deps = deps.length ? [data, ...deps] : [data]

useEffect(() => {
console.log(data)
Expand Down
122 changes: 122 additions & 0 deletions src/service/ImportService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { ITableOptionsEntity, IWorkTableRow } from '@/types'

type EventHandlers = {
update: null | ((list: ITableOptionsEntity[]) => void),
success: null | ((table: IWorkTableRow[]) => void)
}

class ImportService {
private reader: FileReader
private handlers: EventHandlers

public constructor(
file: File | Blob,
private entities: ITableOptionsEntity[],
private active: string,
) {
this.reader = new FileReader()
this.reader.readAsText(file)

this.reader.onload = this.onload.bind(this)

this.reader.onerror = () => {
this.onerror(this.reader.error)
}

this.handlers = {
update: null,
success: null,
}
}

/* ========================================== */

public onUpdateEntity(fn: (data: ITableOptionsEntity[]) => void) {
this.handlers.update = fn
}

public onSuccess(fn: (table: IWorkTableRow[]) => void) {
this.handlers.success = fn
}

/* ========================================== */

private insertEntities(entity: string[], prevTech: string[]) {
if (!this.handlers.update) return

const list = entity.filter(key => !prevTech.includes(key)).map((it, i) => ({
key: it, text: `Текст - ${i + 1}`, rate: 100,
}))

this.handlers.update(list)
}

private onload() {
if (!this.reader.result) return
if (!this.handlers.success) return

try {
const any = JSON.parse(this.reader.result as string)
const data = this.validate(any)
if (!data.length) return

const entity = data.reduce<string[]>((list, it) => {
if (!list.includes(it.entity)) list.push(it.entity)
return list
}, [])

const prevTech = this.entities.map(({ key }) => key)
const extra = [...entity, ...prevTech]

if (extra.length !== prevTech.length)
this.insertEntities(entity, prevTech)

this.handlers.success(data)
} catch (err) {
this.onerror(err)
}
}

private onerror(err: any) {
console.error(err)
alert('Не удалось импортировать файл!')
}

private validate(data: any): IWorkTableRow[] {
if (!Array.isArray(data)) {
alert('Ошибка импорта, не валидный формат данных!')
return []
}

const schema: { key: string, type: string, empty?: boolean }[] = [
{ key: 'id', type: 'string', empty: false },
{ key: 'start', type: 'string', empty: false },
{ key: 'finish', type: 'string', empty: false },
{ key: 'entity', type: 'string', empty: false },
{ key: 'isPaid', type: 'boolean' },
{ key: 'description', type: 'string', empty: true },
]

const list = []

for (const it of data) {
if (!(typeof it === 'object' && !Array.isArray(it)))
return []

const check = schema.every(({ key, type, empty }) => {
return key in it && typeof it[key] === type &&
(type === 'string' && !empty ? it[key].trim() !== '' : true)
})

if (!check) continue
else {
it['tableId'] = this.active
list.push(it)
}
}

return list
}
}

export default ImportService
4 changes: 2 additions & 2 deletions src/service/TableService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ class TableService {

public static deleteWorkTable(id: string): IWorkTable[] | false {
localStorage.removeItem(getLsTableKey(id))
localStorage.removeItem(getLsOptionsKey(id))

const list = this.listOfTablesInfo
const index = list.findIndex(it => it.id === id)

if (index === -1)
return false
if (index === -1) return false

list.splice(index, 1)
this.listOfTablesInfo = list
Expand Down
59 changes: 36 additions & 23 deletions src/temps/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@ import {
wrapPayload,
} from 'context/TableContext'
import { useEffect, useReducer, useState } from 'react'
import TableButtons from './table/TableButtons'
import Bottom from './Bottom'
import Filter from './filter/Filter'
import { getAllIds, getTypedKeys } from '@/utils'
import { getAllIds, getTypedKeys, localStorageKeys } from '@/utils'
import Left from './left/Left'
import DescrModal from './modals/DescrModal'
import TableService from '@/service/TableService'
import useDidUpdateEffect from '@/hooks/useDidUpdateEffect'
import Empty from './empty/Empty'
import SettingModal from './setting/SettingModal'
import CompareData from '@/utils/class/CompareData'
import { appVersion } from '@/defines'
import { getAppSettings } from '@/utils/login'
import HelpModal from '@/temps/modals/HelpModal'
import AddingModal from '@/temps/modals/AddingModal'
import { getLsOptionsKey } from '@/data'

type BoundPartsOfStore = Pick<ITableStore, 'initialTable' | 'modifiedTable' | 'selectedRows'>

Expand All @@ -46,27 +46,40 @@ function getBoundPartsOfStore(table: IWorkTableRow[]): BoundPartsOfStore {
}
}

function getActiveOptions(id: string | null, def = defOptions) {
if (appVersion.code < 213023) {
console.warn('Need reformat legacy options!')
return def
}
function qtyObjKeys(obj: Object): number {
return Object.keys(obj).length
}

function validateOptions(opt: ITableOptions, def: ITableOptions) {
const verify = ['hiddenCols', 'usingKeys']

return getTypedKeys(def).reduce<Record<string, any>>((list, key) => {
if (!(key in opt))
list[key] = def[key]
else if (verify.includes(key))
list[key] = qtyObjKeys(opt[key]) === qtyObjKeys(def[key])
? opt[key] : def[key]
else if (key === 'listOfTech')
list[key] = opt[key].length ? opt[key] : def[key]
else
list[key] = opt[key]

let check = false
return list
}, {}) as ITableOptions
}

function getActiveOptions(id: string | null, def = defOptions) {
let validate = false

const options = id ? (() => {
check = true
validate = true
return TableService.getActiveOptions(id)
})() ?? def : def

if (check) {
return getTypedKeys(def).reduce<Record<string, any>>((list, key) => {
list[key] = key in options ? options[key] : def[key]
return list
}, {}) as ITableOptions
}

return options
if (validate)
return validateOptions(options, def)
else
return options
}

function getInitStore(): ITableStore {
Expand Down Expand Up @@ -131,14 +144,14 @@ function App() {
}, [store.activeTable])

return width >= 768 ? (
<Container>
<TableContext.Provider value={[store, dispatch, wrapPayload]}>
<TableContext.Provider value={[store, dispatch, wrapPayload]}>
<Container>
{store.activeTable === null
? <Empty/>
: (<>
<Filter/>
<Table/>
<TableButtons/>
<Bottom/>
<DescrModal/>
<HelpModal/>
<SettingModal/>
Expand All @@ -149,8 +162,8 @@ function App() {
</>)}

<Left/>
</TableContext.Provider>
</Container>
</Container>
</TableContext.Provider>
) : (
<div className="container">
<div style={{ height: '100vh', width: '100%', display: 'flex', alignItems: 'center' }}>
Expand Down
Loading

0 comments on commit 1cb0bc7

Please sign in to comment.