Добавление страницы information (#41)
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
import {makeApi} from '_utils/makeApi';
|
||||
import {http} from '../infrastructure/Http';
|
||||
import {makeApi} from '../utils/makeApi';
|
||||
|
||||
type User = {
|
||||
id: number;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {PageType} from '../enums/common';
|
||||
import {PageType} from '_enums/common';
|
||||
|
||||
export const ROUTES = {
|
||||
MAIN: '/',
|
||||
|
||||
@ -19,3 +19,9 @@ export enum PageType {
|
||||
Settings = 'settings',
|
||||
SigIn = 'sign-in',
|
||||
}
|
||||
|
||||
export enum Icon {
|
||||
AcUnit = 'acUnit',
|
||||
Apple = 'apple',
|
||||
Apartment = 'apartment',
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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<T extends Record<string, unknown>>(paramParsers: QueryParsers<T>) {
|
||||
const params = useReactParams<Record<keyof T, string>>();
|
||||
|
||||
@ -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<T extends Record<string, unknown>>(queryParsers: QueryParsers<T>): T {
|
||||
const {search} = useLocation();
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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;
|
||||
/**
|
||||
* Контекст выполнения, теги
|
||||
*/
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {PageType} from '../../enums/common';
|
||||
import {PageType} from '_enums/common';
|
||||
import {buildPath, BuildPathOptions} from '../buildPath';
|
||||
|
||||
describe('buildPath', () => {
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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';
|
||||
|
||||
|
||||
49
src/core/utils/__test__/makeTreeList.test.ts
Normal file
49
src/core/utils/__test__/makeTreeList.test.ts
Normal file
@ -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},
|
||||
]);
|
||||
});
|
||||
});
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
78
src/core/utils/makeTreeList.ts
Normal file
78
src/core/utils/makeTreeList.ts
Normal file
@ -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<FolderItem | TaskItem>;
|
||||
|
||||
export type FolderTaskMap = Record<string, Array<(Folder | Task)> | 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<FolderTaskMap>((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));
|
||||
};
|
||||
@ -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<T, K extends keyof T>(items: T[], searchText: string, searchProperties: K[]) {
|
||||
if (isEmpty(items) || isEmpty(searchText)) {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {isNotEmpty} from '../referers/common';
|
||||
import {isNotEmpty} from '_referers/common';
|
||||
|
||||
export function toRequestParamValue<T>(val: T): T;
|
||||
export function toRequestParamValue<T>(val?: T): Undefinable<T>;
|
||||
|
||||
Reference in New Issue
Block a user