From 534fa35485687e3a0eaeea1ee0f141c60df074cc Mon Sep 17 00:00:00 2001 From: Nikolay <46225163+vigdorov@users.noreply.github.com> Date: Tue, 29 Dec 2020 15:02:18 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B8=D1=86?= =?UTF-8?q?=D1=8B=20information=20(#41)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.json | 2 +- jest.config.js | 2 +- src/app/components/both-menu/BothMenu.tsx | 90 ++++++++++--------- src/app/components/page/Page.tsx | 48 ++++++---- src/app/components/top-menu/TopMenu.tsx | 16 ++-- src/app/index.tsx | 14 +-- src/core/api/usersTestApi.ts | 2 +- src/core/consts/common.ts | 2 +- src/core/enums/common.ts | 6 ++ src/core/hooks/usePageType.ts | 2 +- src/core/hooks/useParams.ts | 4 +- src/core/hooks/useQuery.ts | 2 +- src/core/services/TasksService.ts | 6 +- src/core/types/common.ts | 3 +- src/core/utils/__test__/buildPath.test.ts | 2 +- .../utils/__test__/getParamFromUrl.test.ts | 2 +- .../__test__/getQueryParamFromUrl.test.ts | 2 +- src/core/utils/__test__/makeTreeList.test.ts | 49 ++++++++++ src/core/utils/buildPath.ts | 2 +- src/core/utils/common.ts | 4 +- src/core/utils/makeTreeList.ts | 78 ++++++++++++++++ src/core/utils/performTextSearch.ts | 2 +- src/core/utils/toRequestParamValue.ts | 2 +- .../components/info-list/FolderListItem.tsx | 53 +++++++++++ .../components/info-list/InfoList.tsx | 60 +++++++++++++ .../components/info-list/TaskListItem.tsx | 22 +++++ .../information/components/info-list/index.ts | 1 + .../information/components/page/Page.tsx | 14 ++- src/pages/information/consts.ts | 32 +++++++ tsconfig.json | 2 +- webpack.config.js | 2 +- 31 files changed, 434 insertions(+), 94 deletions(-) create mode 100644 src/core/utils/__test__/makeTreeList.test.ts create mode 100644 src/core/utils/makeTreeList.ts create mode 100644 src/pages/information/components/info-list/FolderListItem.tsx create mode 100644 src/pages/information/components/info-list/InfoList.tsx create mode 100644 src/pages/information/components/info-list/TaskListItem.tsx create mode 100644 src/pages/information/components/info-list/index.ts create mode 100644 src/pages/information/consts.ts diff --git a/.eslintrc.json b/.eslintrc.json index 5c94273..1244799 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -95,7 +95,7 @@ "@typescript-eslint/no-shadow": "warn", "@typescript-eslint/no-namespace": "off", "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": ["error"], + "@typescript-eslint/no-unused-vars": "warn", "@typescript-eslint/no-explicit-any": "off", "array-bracket-spacing": ["warn", "never"], "block-spacing": ["warn", "never"], diff --git a/jest.config.js b/jest.config.js index 27e1d52..358e9f8 100644 --- a/jest.config.js +++ b/jest.config.js @@ -89,8 +89,8 @@ module.exports = { '^_types(.*)$': '/src/core/types$1', '^_utils(.*)$': '/src/core/utils$1', '^_enums(.*)$': '/src/core/enums$1', + '^_referers(.*)$': '/src/core/referers$1', '^_pages(.*)$': '/src/pages$1', - '^_referers(.*)$': '/src/referers$1', }, // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader diff --git a/src/app/components/both-menu/BothMenu.tsx b/src/app/components/both-menu/BothMenu.tsx index a032ce4..e199b59 100644 --- a/src/app/components/both-menu/BothMenu.tsx +++ b/src/app/components/both-menu/BothMenu.tsx @@ -1,11 +1,16 @@ import {AppBar, createStyles, Fab, IconButton, makeStyles, Theme, Toolbar} from '@material-ui/core'; import React, {memo} from 'react'; +import Slide from '@material-ui/core/Slide'; import MoreIcon from '@material-ui/icons/MoreVert'; import AddIcon from '@material-ui/icons/Add'; import MoveToInboxIcon from '@material-ui/icons/MoveToInbox'; import CalendarTodayIcon from '@material-ui/icons/CalendarToday'; import ListAltIcon from '@material-ui/icons/ListAlt'; +type Props = { + trigger: boolean; +} + const useStyles = makeStyles((theme: Theme) => createStyles({ iconRight: { @@ -29,51 +34,52 @@ const useStyles = makeStyles((theme: Theme) => }), ); -const BothMenu: React.FC = () => { +const BothMenu: React.FC = ({trigger}) => { const classes = useStyles(); return ( - - - - - - - - - - - -
- - - - - - - - + + + + + + + + + + + + +
+ + + + + + + + + ); }; diff --git a/src/app/components/page/Page.tsx b/src/app/components/page/Page.tsx index 4e9868e..9ba5dfd 100644 --- a/src/app/components/page/Page.tsx +++ b/src/app/components/page/Page.tsx @@ -1,5 +1,7 @@ import React, {Fragment, memo} from 'react'; import {Route, Switch} from 'react-router-dom'; +import {Container, createStyles, makeStyles, useScrollTrigger} from '@material-ui/core'; + import mainPageRouter from '_pages/main/routing'; import chaosBoxPageRouter from '_pages/chaos-box/routing'; import calendarPageRouter from '_pages/calendar/routing'; @@ -13,26 +15,40 @@ import TopMenu from '../top-menu'; import './Page.scss'; import BothMenu from '../both-menu'; +const useStyles = makeStyles(() => + createStyles({ + container: { + height: '100hv', + display: 'flex', + flexDirection: 'column', + }, + }), +); + const Page: React.FC = () => { + const classes = useStyles(); + const trigger = useScrollTrigger(); return ( - -
- - {mainPageRouter} - {chaosBoxPageRouter} - {calendarPageRouter} - {informationPageRouter} - {projectsPageRouter} - {settingsPageRouter} - {signInPageRouter} - {tagsPageRouter} - - - - +
+ + + + {mainPageRouter} + {chaosBoxPageRouter} + {calendarPageRouter} + {informationPageRouter} + {projectsPageRouter} + {settingsPageRouter} + {signInPageRouter} + {tagsPageRouter} + + + + + +
- ); }; diff --git a/src/app/components/top-menu/TopMenu.tsx b/src/app/components/top-menu/TopMenu.tsx index 5e59187..10eb75f 100644 --- a/src/app/components/top-menu/TopMenu.tsx +++ b/src/app/components/top-menu/TopMenu.tsx @@ -3,6 +3,7 @@ import {useHistory} from 'react-router-dom'; import {createStyles, makeStyles} from '@material-ui/core/styles'; import AppBar from '@material-ui/core/AppBar'; import Toolbar from '@material-ui/core/Toolbar'; +import Slide from '@material-ui/core/Slide'; import Typography from '@material-ui/core/Typography'; import IconButton from '@material-ui/core/IconButton'; import ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos'; @@ -13,13 +14,14 @@ import {PAGE_TITLE} from '_consts/common'; import {usePageType} from '_hooks/usePageType'; import {buildPath} from '_utils/buildPath'; +type Props = { + trigger: boolean; +} + const NO_NAME_AVATAR = 'https://d.newsweek.com/en/full/425257/02-10-putin-economy.jpg'; const useStyles = makeStyles(() => createStyles({ - root: { - flexGrow: 1, - }, title: { flexGrow: 1, display: 'flex', @@ -28,7 +30,7 @@ const useStyles = makeStyles(() => }), ); -const TopMenu: React.FC = () => { +const TopMenu: React.FC = ({trigger}) => { const classes = useStyles(); const pageType = usePageType(); const history = useHistory(); @@ -39,8 +41,8 @@ const TopMenu: React.FC = () => { const title = PAGE_TITLE[pageType]; return ( -
- + + {pageType === PageType.Main && ( { -
+ ); }; diff --git a/src/app/index.tsx b/src/app/index.tsx index f236334..d1b9d54 100644 --- a/src/app/index.tsx +++ b/src/app/index.tsx @@ -4,10 +4,14 @@ import {HashRouter} from 'react-router-dom'; import App from './components/page'; ReactDOM.render( - - - - - , + /* + * Выключаем стрикт мод, пока не починят + * https://github.com/mui-org/material-ui/issues/13394 + */ + // + + + , + // document.getElementById('root') ); diff --git a/src/core/api/usersTestApi.ts b/src/core/api/usersTestApi.ts index 74c7aec..0700e9d 100644 --- a/src/core/api/usersTestApi.ts +++ b/src/core/api/usersTestApi.ts @@ -1,5 +1,5 @@ +import {makeApi} from '_utils/makeApi'; import {http} from '../infrastructure/Http'; -import {makeApi} from '../utils/makeApi'; type User = { id: number; diff --git a/src/core/consts/common.ts b/src/core/consts/common.ts index d69fbec..24049e3 100644 --- a/src/core/consts/common.ts +++ b/src/core/consts/common.ts @@ -1,4 +1,4 @@ -import {PageType} from '../enums/common'; +import {PageType} from '_enums/common'; export const ROUTES = { MAIN: '/', diff --git a/src/core/enums/common.ts b/src/core/enums/common.ts index 4589c3e..2611e03 100644 --- a/src/core/enums/common.ts +++ b/src/core/enums/common.ts @@ -19,3 +19,9 @@ export enum PageType { Settings = 'settings', SigIn = 'sign-in', } + +export enum Icon { + AcUnit = 'acUnit', + Apple = 'apple', + Apartment = 'apartment', +} diff --git a/src/core/hooks/usePageType.ts b/src/core/hooks/usePageType.ts index 33bb0d5..ef045e9 100644 --- a/src/core/hooks/usePageType.ts +++ b/src/core/hooks/usePageType.ts @@ -1,6 +1,6 @@ import {useMemo} from 'react'; import {useLocation} from 'react-router-dom'; -import {getPageType} from '../utils/common'; +import {getPageType} from '_utils/common'; export const usePageType = () => { const location = useLocation(); diff --git a/src/core/hooks/useParams.ts b/src/core/hooks/useParams.ts index 056f821..e2f7edc 100644 --- a/src/core/hooks/useParams.ts +++ b/src/core/hooks/useParams.ts @@ -1,7 +1,7 @@ import {useMemo} from 'react'; import {useParams as useReactParams} from 'react-router-dom'; -import {getParamsFromUrl} from '../utils/getParamFromUrl'; -import {QueryParsers} from '../utils/getQueryFromUrl'; +import {getParamsFromUrl} from '_utils/getParamFromUrl'; +import {QueryParsers} from '_utils/getQueryFromUrl'; export function useParams>(paramParsers: QueryParsers) { const params = useReactParams>(); diff --git a/src/core/hooks/useQuery.ts b/src/core/hooks/useQuery.ts index 64071df..7f59727 100644 --- a/src/core/hooks/useQuery.ts +++ b/src/core/hooks/useQuery.ts @@ -1,6 +1,6 @@ import {useMemo} from 'react'; import {useLocation} from 'react-router-dom'; -import {getQueryFromUrl, QueryParsers} from '../utils/getQueryFromUrl'; +import {getQueryFromUrl, QueryParsers} from '_utils/getQueryFromUrl'; export function useQuery>(queryParsers: QueryParsers): T { const {search} = useLocation(); diff --git a/src/core/services/TasksService.ts b/src/core/services/TasksService.ts index f9d94a2..20b3e82 100644 --- a/src/core/services/TasksService.ts +++ b/src/core/services/TasksService.ts @@ -1,7 +1,7 @@ import {v4} from 'uuid'; -import {TaskStatus} from '../enums/common'; -import {Task} from '../types/common'; -import {createService} from '../utils/createService'; +import {TaskStatus} from '_enums/common'; +import {Task} from '_types/common'; +import {createService} from '_utils/createService'; import {makeLocalStorageService} from './LocalStorageService'; const TASK_STORAGE_NAME = 'FYB_TASK_STORAGE'; diff --git a/src/core/types/common.ts b/src/core/types/common.ts index 105d324..2761d6e 100644 --- a/src/core/types/common.ts +++ b/src/core/types/common.ts @@ -1,4 +1,4 @@ -import {FolderType, TaskStatus} from '../enums/common'; +import {FolderType, Icon, TaskStatus} from '_enums/common'; export type Task = { /** @@ -10,6 +10,7 @@ export type Task = { created_at: string; start_at?: string; end_at?: string; + icon?: Icon; /** * Контекст выполнения, теги */ diff --git a/src/core/utils/__test__/buildPath.test.ts b/src/core/utils/__test__/buildPath.test.ts index 0aae8db..d9092be 100644 --- a/src/core/utils/__test__/buildPath.test.ts +++ b/src/core/utils/__test__/buildPath.test.ts @@ -1,4 +1,4 @@ -import {PageType} from '../../enums/common'; +import {PageType} from '_enums/common'; import {buildPath, BuildPathOptions} from '../buildPath'; describe('buildPath', () => { diff --git a/src/core/utils/__test__/getParamFromUrl.test.ts b/src/core/utils/__test__/getParamFromUrl.test.ts index ab700b8..ad39b27 100644 --- a/src/core/utils/__test__/getParamFromUrl.test.ts +++ b/src/core/utils/__test__/getParamFromUrl.test.ts @@ -1,4 +1,4 @@ -import {PageType} from '../../enums/common'; +import {PageType} from '_enums/common'; import {getParamsFromUrl} from '../getParamFromUrl'; import {QueryParsers} from '../getQueryFromUrl'; import {booleanParser, numberParser, stringParser} from '../queryParsers'; diff --git a/src/core/utils/__test__/getQueryParamFromUrl.test.ts b/src/core/utils/__test__/getQueryParamFromUrl.test.ts index ce29aeb..568b61f 100644 --- a/src/core/utils/__test__/getQueryParamFromUrl.test.ts +++ b/src/core/utils/__test__/getQueryParamFromUrl.test.ts @@ -1,4 +1,4 @@ -import {PageType} from '../../enums/common'; +import {PageType} from '_enums/common'; import {getQueryFromUrl, QueryParsers} from '../getQueryFromUrl'; import {arrayParser, booleanParser, numberParser, stringParser} from '../queryParsers'; diff --git a/src/core/utils/__test__/makeTreeList.test.ts b/src/core/utils/__test__/makeTreeList.test.ts new file mode 100644 index 0000000..5be2477 --- /dev/null +++ b/src/core/utils/__test__/makeTreeList.test.ts @@ -0,0 +1,49 @@ +import {Folder, Task} from '_types/common'; +import {FolderType, TaskStatus} from '_enums/common'; +import {makeMap, makeTreeList, ROOT_TREE} from '../makeTreeList'; + +const Folder_1 = {id: '1', name: '1', type: FolderType.Information}; +const Folder_2 = {id: '2', name: '2', type: FolderType.Information, folder: '999'}; +const Folder_3 = {id: '3', name: '3', type: FolderType.Information}; +const Folder_4 = {id: '4', name: '4', type: FolderType.Information, folder: '1'}; + +const Task_1 = {id: '11', created_at: '', status: TaskStatus.Progress}; +const Task_2 = {id: '22', created_at: '', status: TaskStatus.Progress, folder: '1'}; +const Task_3 = {id: '33', created_at: '', status: TaskStatus.Progress, folder: '4'}; +const Task_4 = {id: '44', created_at: '', status: TaskStatus.Progress, folder: '999'}; + +const folders: Folder[] = [Folder_1, Folder_2, Folder_3, Folder_4]; +const tasks: Task[] = [Task_1, Task_2, Task_3, Task_4]; + +describe('makeTreeList', () => { + it('Создает хеш-таблицу', () => { + expect(makeMap(folders, tasks)).toEqual({ + [ROOT_TREE]: [Folder_1, Folder_2, Folder_3, Task_1, Task_4], + '1': [Folder_4, Task_2], + '2': [], + '3': [], + '4': [Task_3], + }); + }); + + it('Создает дерево', () => { + expect(makeTreeList(folders, tasks)).toEqual([ + { + data: Folder_1, + children: [ + { + data: Folder_4, + children: [ + {data: Task_3}, + ], + }, + {data: Task_2}, + ], + }, + {data: Folder_2}, + {data: Folder_3}, + {data: Task_1}, + {data: Task_4}, + ]); + }); +}); diff --git a/src/core/utils/buildPath.ts b/src/core/utils/buildPath.ts index 6ff2b57..bf7c334 100644 --- a/src/core/utils/buildPath.ts +++ b/src/core/utils/buildPath.ts @@ -1,5 +1,5 @@ import {decode, ParsedUrlQueryInput, stringify} from 'querystring'; -import {PageType} from '../enums/common'; +import {PageType} from '_enums/common'; export type BuildPathOptions = { pageType: PageType; diff --git a/src/core/utils/common.ts b/src/core/utils/common.ts index adbac1f..5679d15 100644 --- a/src/core/utils/common.ts +++ b/src/core/utils/common.ts @@ -1,5 +1,5 @@ -import {PageType} from '../enums/common'; -import {isPageType} from '../referers/common'; +import {PageType} from '_enums/common'; +import {isPageType} from '_referers/common'; export const numberToString = (num: number): string => num.toString(); diff --git a/src/core/utils/makeTreeList.ts b/src/core/utils/makeTreeList.ts new file mode 100644 index 0000000..3fd2a6d --- /dev/null +++ b/src/core/utils/makeTreeList.ts @@ -0,0 +1,78 @@ +import {sortBy} from 'lodash'; +import {isNotEmpty} from '_referers/common'; +import {Folder, Task} from '_types/common'; + +export type FolderItem = { + data: Folder; + children?: TreeList; +}; + +export type TaskItem = { + data: Task; +}; + +export type TreeList = Array; + +export type FolderTaskMap = Record | undefined>; + +export const isFolderItem = (item: FolderItem | TaskItem): item is FolderItem => ( + 'type' in item.data +); +export const isTaskItem = (item: FolderItem | TaskItem): item is TaskItem => ( + 'status' in item.data +); + +export const ROOT_TREE = '__root__'; + +export const makeMap = (folders: Folder[], tasks: Task[]) => { + const INIT_MAP: FolderTaskMap = { + [ROOT_TREE]: [], + }; + + /** + * Собираем хеш-таблицу существующих папок с предзаполненным root элементом + */ + const map = folders.reduce((acc, folder) => ({ + ...acc, + [folder.id]: [], + }), INIT_MAP); + + /** + * Наполняем хеш-таблицу мутабельно для скорости. Если у папки или таски folder.id, + * которого уже не существует, то кладем их в root + */ + folders.forEach(folder => { + const parent = folder.folder ?? ROOT_TREE; + (map[parent] ?? map[ROOT_TREE])?.push(folder); + }); + + tasks.forEach(task => { + const parent = task.folder ?? ROOT_TREE; + (map[parent] ?? map[ROOT_TREE])?.push(task); + }); + + return map; +}; + +const makeTree = (parentId: string, map: FolderTaskMap): TreeList | undefined => { + const list = map[parentId]; + + if (isNotEmpty(list)) { + return sortBy(list, ['type']).map(item => { + if ('type' in item) { + const children = makeTree(item.id, map); + return { + ...(children ? {children} : {}), + data: item, + }; + } + return { + data: item, + }; + }); + } +}; + +export const makeTreeList = (folders: Folder[], tasks: Task[]) => { + return makeTree(ROOT_TREE, makeMap(folders, tasks)); +}; diff --git a/src/core/utils/performTextSearch.ts b/src/core/utils/performTextSearch.ts index 58652d6..8ff28d5 100644 --- a/src/core/utils/performTextSearch.ts +++ b/src/core/utils/performTextSearch.ts @@ -1,5 +1,5 @@ import ru from 'convert-layout/ru'; -import {isEmpty, isNotEmpty} from '../referers/common'; +import {isEmpty, isNotEmpty} from '_referers/common'; export function performTextSearch(items: T[], searchText: string, searchProperties: K[]) { if (isEmpty(items) || isEmpty(searchText)) { diff --git a/src/core/utils/toRequestParamValue.ts b/src/core/utils/toRequestParamValue.ts index f140aad..bb39ea5 100644 --- a/src/core/utils/toRequestParamValue.ts +++ b/src/core/utils/toRequestParamValue.ts @@ -1,4 +1,4 @@ -import {isNotEmpty} from '../referers/common'; +import {isNotEmpty} from '_referers/common'; export function toRequestParamValue(val: T): T; export function toRequestParamValue(val?: T): Undefinable; diff --git a/src/pages/information/components/info-list/FolderListItem.tsx b/src/pages/information/components/info-list/FolderListItem.tsx new file mode 100644 index 0000000..fcbafa9 --- /dev/null +++ b/src/pages/information/components/info-list/FolderListItem.tsx @@ -0,0 +1,53 @@ +import {Collapse, ListItemIcon, ListItem, ListItemText} from '@material-ui/core'; +import ExpandLess from '@material-ui/icons/ExpandLess'; +import ExpandMore from '@material-ui/icons/ExpandMore'; +import FolderIcon from '@material-ui/icons/Folder'; +import React, {FC, Fragment, memo, useCallback, useMemo} from 'react'; +import {isNotEmpty} from '_referers/common'; +import {FolderItem} from '_utils/makeTreeList'; +import InfoList from './InfoList'; + +type Props = { + item: FolderItem; + className: string; + space: number; + openFolderIds: string[]; + onFolderClick: (folderId: string) => void; +}; + +const FolderListItem: FC = ({item, className, space, openFolderIds, onFolderClick}) => { + const isOpen = useMemo(() => { + return openFolderIds.some(id => id === item.data.id); + }, [openFolderIds, item.data.id]); + + const isNotEmptyChildren = useMemo(() => isNotEmpty(item.children), [item.children]); + + const handleItemClick = useCallback(() => { + onFolderClick(item.data.id); + }, [onFolderClick, item.data.id]); + + return ( + + + + + + + {isNotEmptyChildren && ( + isOpen ? : + )} + + {isNotEmptyChildren && ( + + + + )} + + ); +}; + +export default memo(FolderListItem); diff --git a/src/pages/information/components/info-list/InfoList.tsx b/src/pages/information/components/info-list/InfoList.tsx new file mode 100644 index 0000000..fbcc465 --- /dev/null +++ b/src/pages/information/components/info-list/InfoList.tsx @@ -0,0 +1,60 @@ +import {createStyles, makeStyles, Theme, List} from '@material-ui/core'; +import {xor} from 'lodash'; +import React, {Fragment, memo, useCallback, useState} from 'react'; +import {isFolderItem, isTaskItem, TreeList} from '_utils/makeTreeList'; +import FolderListItem from './FolderListItem'; +import TaskListItem from './TaskListItem'; + +type Props = { + list: Undefinable; + space: number; +}; + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + root: { + width: '100%', + maxWidth: 360, + backgroundColor: theme.palette.background.paper, + }, + nested: ({space}) => ({ + paddingLeft: theme.spacing(4 * space), + }), + }), +); + +const InfoList: React.FC = ({list, space}) => { + const [openFolderIds, setOpenFolder] = useState([]); + + const handleSetOpenFolder = useCallback((id: string) => { + setOpenFolder(xor(openFolderIds, [id])); + }, [setOpenFolder, openFolderIds]); + + const classes = useStyles({space}); + + return ( + + {list?.map(item => ( + + {isFolderItem(item) && ( + + )} + {isTaskItem(item) && ( + + )} + + ))} + + ); +}; + +export default memo(InfoList); diff --git a/src/pages/information/components/info-list/TaskListItem.tsx b/src/pages/information/components/info-list/TaskListItem.tsx new file mode 100644 index 0000000..440b26e --- /dev/null +++ b/src/pages/information/components/info-list/TaskListItem.tsx @@ -0,0 +1,22 @@ +import {ListItemIcon, ListItem, ListItemText} from '@material-ui/core'; +import AssignmentLateIcon from '@material-ui/icons/AssignmentLate'; +import React, {FC, memo} from 'react'; +import {TaskItem} from '_utils/makeTreeList'; + +type Props = { + item: TaskItem; + className: string; +}; + +const TaskListItem: FC = ({item, className}) => { + return ( + + + + + + + ); +}; + +export default memo(TaskListItem); diff --git a/src/pages/information/components/info-list/index.ts b/src/pages/information/components/info-list/index.ts new file mode 100644 index 0000000..fef36db --- /dev/null +++ b/src/pages/information/components/info-list/index.ts @@ -0,0 +1 @@ +export {default} from './InfoList'; diff --git a/src/pages/information/components/page/Page.tsx b/src/pages/information/components/page/Page.tsx index a8fea49..5f780ae 100644 --- a/src/pages/information/components/page/Page.tsx +++ b/src/pages/information/components/page/Page.tsx @@ -1,8 +1,18 @@ -import React, {memo} from 'react'; +import React, {Fragment, memo} from 'react'; +import {isNotEmpty} from '_referers/common'; +import {makeTreeList} from '_utils/makeTreeList'; +import {FolderList, TaskList} from '../../consts'; +import InfoList from '../info-list'; + +const tree = makeTreeList(FolderList, TaskList); const Page: React.FC = () => { return ( -
information
+ + {isNotEmpty(tree) && ( + + )} + ); }; diff --git a/src/pages/information/consts.ts b/src/pages/information/consts.ts new file mode 100644 index 0000000..2e233c2 --- /dev/null +++ b/src/pages/information/consts.ts @@ -0,0 +1,32 @@ +import {v4} from 'uuid'; +import {FolderType, Icon, TaskStatus} from '_enums/common'; +import {Folder, Tag, Task} from '_types/common'; + +// Псевдоданные +export const TagList: Tag[] = [ + {id: '33', name: 'Tag', color: '#2fc036'}, + {id: '66', name: 'Tag', color: '#2fc036'}, + {id: '77', name: 'Tag', color: '#2fc036'}, + {id: '22', name: 'Tag', color: '#2fc036'}, +]; + +export const FolderList: Folder[] = [ + {id: '4', name: 'Folder 1', type: FolderType.Information}, + {id: '6', name: 'Folder 34', type: FolderType.Information}, + {id: '7', name: 'Folder ffd', type: FolderType.Information}, + {id: '73', name: 'Folder ffd', type: FolderType.Information, folder: '7'}, +]; + +export const TaskList: Task[] = [ + {id: v4(), title: 'Title number 1', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress, folder: '4'}, + {id: v4(), title: 'Title number 2', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress, folder: '4'}, + {id: v4(), title: 'Title number 3', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress, folder: '6'}, + {id: v4(), title: 'Title number 4', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress, tags: ['33', '77']}, + {id: v4(), title: 'Title number 5', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress}, + {id: v4(), title: 'Title number 6', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress}, + {id: v4(), title: 'Title number 7', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress, folder: '4'}, + {id: v4(), title: 'Title number 8', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress, folder: '4'}, + {id: v4(), title: 'Title number 9', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress, folder: '7'}, + {id: v4(), title: 'Title number 10', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress, folder: '7'}, + {id: v4(), title: 'Title number 11', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress, folder: '73'}, +]; diff --git a/tsconfig.json b/tsconfig.json index cf587db..b01425c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -29,8 +29,8 @@ "_types/*": ["./src/core/types/*"], "_utils/*": ["./src/core/utils/*"], "_enums/*": ["./src/core/enums/*"], + "_referers/*": ["./src/core/referers/*"], "_pages/*": ["./src/pages/*"], - "_referers/*": ["./src/referers/*"], } }, "include": [ diff --git a/webpack.config.js b/webpack.config.js index 1aa9ba8..66d2e06 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -38,8 +38,8 @@ module.exports = { _services: path.resolve(__dirname, 'src/core/services/'), _utils: path.resolve(__dirname, 'src/core/utils/'), _enums: path.resolve(__dirname, 'src/core/enums/'), + _referers: path.resolve(__dirname, 'src/core/referers/'), _pages: path.resolve(__dirname, 'src/pages/'), - _referers: path.resolve(__dirname, 'src/referers/'), } }, optimization: {