mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-24 20:36:40 +07:00
removed boris reducer
This commit is contained in:
parent
77af1ab05a
commit
120bf8954c
72 changed files with 225 additions and 298 deletions
16
src/api/boris/index.ts
Normal file
16
src/api/boris/index.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { API } from '~/constants/api';
|
||||
import { api, cleanResult } from '~/utils/api';
|
||||
import { IGetGithubIssuesResult, StatBackend } from '~/types/boris';
|
||||
import axios from 'axios';
|
||||
|
||||
export const getBorisBackendStats = () =>
|
||||
api.get<StatBackend>(API.BORIS.GET_BACKEND_STATS).then(cleanResult);
|
||||
|
||||
export const getGithubIssues = () => {
|
||||
return axios
|
||||
.get<IGetGithubIssuesResult>(API.BORIS.GITHUB_ISSUES, {
|
||||
params: { state: 'all', sort: 'created' },
|
||||
})
|
||||
.then(result => result.data)
|
||||
.catch(() => []);
|
||||
};
|
|
@ -1,7 +1,7 @@
|
|||
import { api, cleanResult } from '~/utils/api';
|
||||
import { IComment, INode } from '../types';
|
||||
import { IComment, INode } from '~/redux/types';
|
||||
import { API } from '~/constants/api';
|
||||
import { COMMENTS_DISPLAY } from './constants';
|
||||
import { COMMENTS_DISPLAY } from '~/constants/node';
|
||||
import {
|
||||
ApiDeleteNodeTagsRequest,
|
||||
ApiDeleteNodeTagsResult,
|
||||
|
@ -23,7 +23,7 @@ import {
|
|||
ApiPostNodeTagsResult,
|
||||
GetNodeDiffRequest,
|
||||
GetNodeDiffResult,
|
||||
} from '~/redux/node/types';
|
||||
} from '~/types/node';
|
||||
import axios, { AxiosRequestConfig } from 'axios';
|
||||
|
||||
export type ApiPostNodeRequest = { node: INode };
|
|
@ -5,16 +5,17 @@ import { BorisContacts } from '~/components/boris/BorisContacts';
|
|||
import { BorisStats } from '~/components/boris/BorisStats';
|
||||
import { Group } from '~/components/containers/Group';
|
||||
import { IUser } from '~/redux/auth/types';
|
||||
import { BorisUsageStats } from '~/redux/boris/reducer';
|
||||
import { BorisUsageStats } from '~/types/boris';
|
||||
|
||||
interface Props {
|
||||
user: IUser;
|
||||
isTester: boolean;
|
||||
stats: BorisUsageStats;
|
||||
setBetaTester: (val: boolean) => void;
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
const BorisSidebar: FC<Props> = ({ user, stats, isTester, setBetaTester }) => (
|
||||
const BorisSidebar: FC<Props> = ({ user, stats, isLoading, isTester, setBetaTester }) => (
|
||||
<Group className={styles.stats__container}>
|
||||
<div className={styles.super_powers}>
|
||||
{user.is_user && <BorisSuperpowers active={isTester} onChange={setBetaTester} />}
|
||||
|
@ -23,7 +24,7 @@ const BorisSidebar: FC<Props> = ({ user, stats, isTester, setBetaTester }) => (
|
|||
<BorisContacts />
|
||||
|
||||
<div className={styles.stats__wrap}>
|
||||
<BorisStats stats={stats} />
|
||||
<BorisStats stats={stats} isLoading={isLoading} />
|
||||
</div>
|
||||
</Group>
|
||||
);
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
import React, { FC } from 'react';
|
||||
import { BorisUsageStats } from '~/redux/boris/reducer';
|
||||
import { BorisUsageStats } from '~/types/boris';
|
||||
import { BorisStatsGit } from '../BorisStatsGit';
|
||||
import { BorisStatsBackend } from '../BorisStatsBackend';
|
||||
|
||||
interface IProps {
|
||||
stats: BorisUsageStats;
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
const BorisStats: FC<IProps> = ({ stats }) => {
|
||||
const BorisStats: FC<IProps> = ({ stats, isLoading }) => {
|
||||
return (
|
||||
<>
|
||||
<BorisStatsBackend stats={stats} />
|
||||
<BorisStatsGit stats={stats} />
|
||||
<BorisStatsBackend stats={stats.backend} isLoading={isLoading} />
|
||||
<BorisStatsGit issues={stats.issues} isLoading={isLoading} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,72 +1,73 @@
|
|||
import React, { FC } from 'react';
|
||||
import { IBorisState } from '~/redux/boris/reducer';
|
||||
import { StatBackend } from '~/types/boris';
|
||||
import styles from './styles.module.scss';
|
||||
import { sizeOf } from '~/utils/dom';
|
||||
import { StatsRow } from '~/components/common/StatsRow';
|
||||
import { SubTitle } from '~/components/common/SubTitle';
|
||||
|
||||
interface IProps {
|
||||
stats: IBorisState['stats'];
|
||||
stats: StatBackend;
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
const BorisStatsBackend: FC<IProps> = ({ stats: { is_loading, backend } }) => {
|
||||
if (!backend && !is_loading) {
|
||||
const BorisStatsBackend: FC<IProps> = ({ isLoading, stats }) => {
|
||||
if (!stats && !isLoading) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.wrap}>
|
||||
<SubTitle isLoading={is_loading} className={styles.title}>
|
||||
<SubTitle isLoading={isLoading} className={styles.title}>
|
||||
Юнитс
|
||||
</SubTitle>
|
||||
|
||||
<ul>
|
||||
<StatsRow isLoading={is_loading} label="В сознании">
|
||||
{backend.users.alive}
|
||||
<StatsRow isLoading={isLoading} label="В сознании">
|
||||
{stats.users.alive}
|
||||
</StatsRow>
|
||||
|
||||
<StatsRow isLoading={is_loading} label="Криокамера">
|
||||
{backend.users.total - backend.users.alive}
|
||||
<StatsRow isLoading={isLoading} label="Криокамера">
|
||||
{stats.users.total - stats.users.alive}
|
||||
</StatsRow>
|
||||
</ul>
|
||||
|
||||
<SubTitle isLoading={is_loading} className={styles.title}>
|
||||
<SubTitle isLoading={isLoading} className={styles.title}>
|
||||
Контент
|
||||
</SubTitle>
|
||||
|
||||
<ul>
|
||||
<StatsRow isLoading={is_loading} label="Фотографии">
|
||||
{backend.nodes.images}
|
||||
<StatsRow isLoading={isLoading} label="Фотографии">
|
||||
{stats.nodes.images}
|
||||
</StatsRow>
|
||||
|
||||
<StatsRow isLoading={is_loading} label="Письма">
|
||||
{backend.nodes.texts}
|
||||
<StatsRow isLoading={isLoading} label="Письма">
|
||||
{stats.nodes.texts}
|
||||
</StatsRow>
|
||||
|
||||
<StatsRow isLoading={is_loading} label="Видеозаписи">
|
||||
{backend.nodes.videos}
|
||||
<StatsRow isLoading={isLoading} label="Видеозаписи">
|
||||
{stats.nodes.videos}
|
||||
</StatsRow>
|
||||
|
||||
<StatsRow isLoading={is_loading} label="Аудиозаписи">
|
||||
{backend.nodes.audios}
|
||||
<StatsRow isLoading={isLoading} label="Аудиозаписи">
|
||||
{stats.nodes.audios}
|
||||
</StatsRow>
|
||||
|
||||
<StatsRow isLoading={is_loading} label="Комментарии">
|
||||
{backend.comments.total}
|
||||
<StatsRow isLoading={isLoading} label="Комментарии">
|
||||
{stats.comments.total}
|
||||
</StatsRow>
|
||||
</ul>
|
||||
|
||||
<SubTitle isLoading={is_loading} className={styles.title}>
|
||||
<SubTitle isLoading={isLoading} className={styles.title}>
|
||||
Сторедж
|
||||
</SubTitle>
|
||||
|
||||
<ul>
|
||||
<StatsRow isLoading={is_loading} label="Файлы">
|
||||
{backend.files.count}
|
||||
<StatsRow isLoading={isLoading} label="Файлы">
|
||||
{stats.files.count}
|
||||
</StatsRow>
|
||||
|
||||
<StatsRow isLoading={is_loading} label="На диске">
|
||||
{sizeOf(backend.files.size)}
|
||||
<StatsRow isLoading={isLoading} label="На диске">
|
||||
{sizeOf(stats.files.size)}
|
||||
</StatsRow>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -1,27 +1,28 @@
|
|||
import React, { FC, useMemo } from 'react';
|
||||
import { IBorisState } from '~/redux/boris/reducer';
|
||||
import { GithubIssue } from '~/types/boris';
|
||||
import styles from './styles.module.scss';
|
||||
import { Placeholder } from '~/components/placeholders/Placeholder';
|
||||
import { BorisStatsGitCard } from '../BorisStatsGitCard';
|
||||
|
||||
interface IProps {
|
||||
stats: IBorisState['stats'];
|
||||
issues: GithubIssue[];
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
const BorisStatsGit: FC<IProps> = ({ stats }) => {
|
||||
const BorisStatsGit: FC<IProps> = ({ issues, isLoading }) => {
|
||||
const open = useMemo(
|
||||
() => stats.issues.filter(el => !el.pull_request && el.state === 'open').slice(0, 5),
|
||||
[stats.issues]
|
||||
() => issues.filter(el => !el.pull_request && el.state === 'open').slice(0, 5),
|
||||
[issues]
|
||||
);
|
||||
|
||||
const closed = useMemo(
|
||||
() => stats.issues.filter(el => !el.pull_request && el.state === 'closed').slice(0, 5),
|
||||
[stats.issues]
|
||||
() => issues.filter(el => !el.pull_request && el.state === 'closed').slice(0, 5),
|
||||
[issues]
|
||||
);
|
||||
|
||||
if (!stats.issues.length) return null;
|
||||
if (!issues.length) return null;
|
||||
|
||||
if (stats.is_loading) {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<>
|
||||
<div className={styles.stats__title}>
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import React, { FC, useMemo } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
import { getPrettyDate } from '~/utils/dom';
|
||||
import { IGithubIssue } from '~/redux/boris/types';
|
||||
import { GithubIssue } from '~/types/boris';
|
||||
import classNames from 'classnames';
|
||||
|
||||
interface IProps {
|
||||
data: IGithubIssue;
|
||||
data: GithubIssue;
|
||||
}
|
||||
|
||||
const stateLabels: Record<IGithubIssue['state'], string> = {
|
||||
const stateLabels: Record<GithubIssue['state'], string> = {
|
||||
open: 'Ожидает',
|
||||
closed: 'Сделано',
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ import { CommentFormFormatButtons } from '~/components/comment/CommentFormFormat
|
|||
import { CommentFormAttaches } from '~/components/comment/CommentFormAttaches';
|
||||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
import { IComment, INode } from '~/redux/types';
|
||||
import { EMPTY_COMMENT } from '~/redux/node/constants';
|
||||
import { EMPTY_COMMENT } from '~/constants/node';
|
||||
import { UploadDropzone } from '~/components/upload/UploadDropzone';
|
||||
import styles from './styles.module.scss';
|
||||
import { ERROR_LITERAL } from '~/constants/errors';
|
||||
|
|
|
@ -3,7 +3,7 @@ import { UPLOAD_TYPES } from '~/redux/uploads/constants';
|
|||
import { ImageGrid } from '../ImageGrid';
|
||||
import { AudioGrid } from '../AudioGrid';
|
||||
import styles from './styles.module.scss';
|
||||
import { NodeEditorProps } from '~/redux/node/types';
|
||||
import { NodeEditorProps } from '~/types/node';
|
||||
import { useNodeImages } from '~/hooks/node/useNodeImages';
|
||||
import { useNodeAudios } from '~/hooks/node/useNodeAudios';
|
||||
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { createElement, FC } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
import { NODE_PANEL_COMPONENTS } from '~/redux/node/constants';
|
||||
import { NODE_PANEL_COMPONENTS } from '~/constants/node';
|
||||
import { has } from 'ramda';
|
||||
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { FC } from 'react';
|
||||
import { EditorUploadButton } from '~/components/editors/EditorUploadButton';
|
||||
import { UPLOAD_TYPES } from '~/redux/uploads/constants';
|
||||
import { IEditorComponentProps } from '~/redux/node/types';
|
||||
import { IEditorComponentProps } from '~/types/node';
|
||||
|
||||
type IProps = IEditorComponentProps & {};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { FC } from 'react';
|
||||
import { Filler } from '~/components/containers/Filler';
|
||||
import { IEditorComponentProps } from '~/redux/node/types';
|
||||
import { IEditorComponentProps } from '~/types/node';
|
||||
import styles from './styles.module.scss';
|
||||
|
||||
type IProps = IEditorComponentProps & {};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { FC } from 'react';
|
||||
import { EditorUploadButton } from '~/components/editors/EditorUploadButton';
|
||||
import { UPLOAD_TYPES } from '~/redux/uploads/constants';
|
||||
import { IEditorComponentProps } from '~/redux/node/types';
|
||||
import { IEditorComponentProps } from '~/types/node';
|
||||
|
||||
type IProps = IEditorComponentProps & {};
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { FC, useCallback } from 'react';
|
||||
import { IEditorComponentProps } from '~/redux/node/types';
|
||||
import { IEditorComponentProps } from '~/types/node';
|
||||
import { Button } from '~/components/input/Button';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import styles from './styles.module.scss';
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { ChangeEvent, FC, useCallback } from 'react';
|
|||
import styles from './styles.module.scss';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { UPLOAD_TYPES } from '~/redux/uploads/constants';
|
||||
import { IEditorComponentProps } from '~/redux/node/types';
|
||||
import { IEditorComponentProps } from '~/types/node';
|
||||
import { useFileUploaderContext } from '~/hooks/data/useFileUploader';
|
||||
import { getFileType } from '~/utils/uploader';
|
||||
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
|
||||
|
|
|
@ -5,7 +5,7 @@ import { path } from 'ramda';
|
|||
import { getURL } from '~/utils/dom';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { PRESETS } from '~/constants/urls';
|
||||
import { IEditorComponentProps } from '~/redux/node/types';
|
||||
import { IEditorComponentProps } from '~/types/node';
|
||||
import { useFileUploader } from '~/hooks/data/useFileUploader';
|
||||
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
|
||||
import { getFileType } from '~/utils/uploader';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { FC } from 'react';
|
||||
import { ImageGrid } from '~/components/editors/ImageGrid';
|
||||
import styles from './styles.module.scss';
|
||||
import { NodeEditorProps } from '~/redux/node/types';
|
||||
import { NodeEditorProps } from '~/types/node';
|
||||
import { useFileUploaderContext } from '~/hooks/data/useFileUploader';
|
||||
import { UploadDropzone } from '~/components/upload/UploadDropzone';
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { FC, useCallback } from 'react';
|
|||
import styles from './styles.module.scss';
|
||||
import { Textarea } from '~/components/input/Textarea';
|
||||
import { path } from 'ramda';
|
||||
import { NodeEditorProps } from '~/redux/node/types';
|
||||
import { NodeEditorProps } from '~/types/node';
|
||||
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
|
||||
|
||||
type IProps = NodeEditorProps & {};
|
||||
|
|
|
@ -4,7 +4,7 @@ import { path } from 'ramda';
|
|||
import { InputText } from '~/components/input/InputText';
|
||||
import classnames from 'classnames';
|
||||
import { getYoutubeThumb } from '~/utils/dom';
|
||||
import { NodeEditorProps } from '~/redux/node/types';
|
||||
import { NodeEditorProps } from '~/types/node';
|
||||
import { useNodeFormContext } from '~/hooks/node/useNodeFormFormik';
|
||||
|
||||
type IProps = NodeEditorProps & {};
|
||||
|
|
|
@ -7,7 +7,7 @@ import styles from './styles.module.scss';
|
|||
import markdown from '~/styles/common/markdown.module.scss';
|
||||
import { Icon } from '~/components/input/Icon';
|
||||
import { PRESETS } from '~/constants/urls';
|
||||
import { NODE_TYPES } from '~/redux/node/constants';
|
||||
import { NODE_TYPES } from '~/constants/node';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { CellShade } from '~/components/flow/CellShade';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { FC } from 'react';
|
||||
import { INodeComponentProps } from '~/redux/node/constants';
|
||||
import { INodeComponentProps } from '~/constants/node';
|
||||
import { Placeholder } from '~/components/placeholders/Placeholder';
|
||||
import { NodeAudioBlock } from '~/components/node/NodeAudioBlock';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { FC } from 'react';
|
||||
import { INodeComponentProps } from '~/redux/node/constants';
|
||||
import { INodeComponentProps } from '~/constants/node';
|
||||
import styles from './styles.module.scss';
|
||||
import { Markdown } from '~/components/containers/Markdown';
|
||||
import { formatText } from '~/utils/dom';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { FC } from 'react';
|
||||
import { INodeComponentProps } from '~/redux/node/constants';
|
||||
import { INodeComponentProps } from '~/constants/node';
|
||||
import SwiperCore, { A11y, Navigation, Pagination, SwiperOptions } from 'swiper';
|
||||
|
||||
import 'swiper/swiper.scss';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { FC } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
import { INodeComponentProps } from '~/redux/node/constants';
|
||||
import { INodeComponentProps } from '~/constants/node';
|
||||
import { useColorGradientFromString } from '~/hooks/color/useColorGradientFromString';
|
||||
|
||||
interface Props extends INodeComponentProps {}
|
||||
|
|
|
@ -4,7 +4,7 @@ import { Group } from '~/components/containers/Group';
|
|||
import { Icon } from '~/components/input/Icon';
|
||||
import Tippy from '@tippy.js/react';
|
||||
import { useGotoNode } from '~/hooks/node/useGotoNode';
|
||||
import { INodeComponentProps } from '~/redux/node/constants';
|
||||
import { INodeComponentProps } from '~/constants/node';
|
||||
import { Placeholder } from '~/components/placeholders/Placeholder';
|
||||
|
||||
const LabNodeTitle: FC<INodeComponentProps> = ({ node, isLoading }) => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { FC } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
import { INodeComponentProps } from '~/redux/node/constants';
|
||||
import { INodeComponentProps } from '~/constants/node';
|
||||
import { useGotoNode } from '~/hooks/node/useGotoNode';
|
||||
|
||||
const LabPad: FC<INodeComponentProps> = ({ node }) => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { FC, useMemo } from 'react';
|
||||
import { Markdown } from '~/components/containers/Markdown';
|
||||
import { INodeComponentProps } from '~/redux/node/constants';
|
||||
import { INodeComponentProps } from '~/constants/node';
|
||||
import { formatTextParagraphs } from '~/utils/dom';
|
||||
import { path } from 'ramda';
|
||||
import styles from './styles.module.scss';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { FC } from 'react';
|
||||
import { INodeComponentProps } from '~/redux/node/constants';
|
||||
import { INodeComponentProps } from '~/constants/node';
|
||||
import { NodeVideoBlock } from '~/components/node/NodeVideoBlock';
|
||||
import { Placeholder } from '~/components/placeholders/Placeholder';
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { FC } from 'react';
|
||||
import { AudioPlayer } from '~/components/media/AudioPlayer';
|
||||
import styles from './styles.module.scss';
|
||||
import { INodeComponentProps } from '~/redux/node/constants';
|
||||
import { INodeComponentProps } from '~/constants/node';
|
||||
import { useNodeAudios } from '~/hooks/node/useNodeAudios';
|
||||
|
||||
interface IProps extends INodeComponentProps {}
|
||||
|
|
|
@ -3,7 +3,7 @@ import styles from './styles.module.scss';
|
|||
import { path } from 'ramda';
|
||||
import { getURL } from '~/utils/dom';
|
||||
import { PRESETS } from '~/constants/urls';
|
||||
import { INodeComponentProps } from '~/redux/node/constants';
|
||||
import { INodeComponentProps } from '~/constants/node';
|
||||
import { useNodeImages } from '~/hooks/node/useNodeImages';
|
||||
|
||||
interface IProps extends INodeComponentProps {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { FC, useCallback, useState } from 'react';
|
||||
import { INodeComponentProps } from '~/redux/node/constants';
|
||||
import { INodeComponentProps } from '~/constants/node';
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
|
||||
import 'swiper/swiper.scss';
|
||||
|
|
|
@ -3,7 +3,7 @@ import { NodeRelatedPlaceholder } from '~/components/node/NodeRelated/placeholde
|
|||
import { NodeRelated } from '~/components/node/NodeRelated';
|
||||
import { URLS } from '~/constants/urls';
|
||||
import { INode } from '~/redux/types';
|
||||
import { INodeRelated } from '~/redux/node/types';
|
||||
import { INodeRelated } from '~/types/node';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
interface IProps {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { FC, useMemo } from 'react';
|
||||
import { path } from 'ramda';
|
||||
import { formatTextParagraphs } from '~/utils/dom';
|
||||
import { INodeComponentProps } from '~/redux/node/constants';
|
||||
import { INodeComponentProps } from '~/constants/node';
|
||||
import classNames from 'classnames';
|
||||
import styles from './styles.module.scss';
|
||||
import markdown from '~/styles/common/markdown.module.scss';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { FC, useMemo } from 'react';
|
||||
import styles from './styles.module.scss';
|
||||
import { path } from 'ramda';
|
||||
import { INodeComponentProps } from '~/redux/node/constants';
|
||||
import { INodeComponentProps } from '~/constants/node';
|
||||
|
||||
interface IProps extends INodeComponentProps {}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ export const API = {
|
|||
},
|
||||
BORIS: {
|
||||
GET_BACKEND_STATS: '/stats/',
|
||||
GITHUB_ISSUES: 'https://api.github.com/repos/muerwre/vault-frontend/issues',
|
||||
},
|
||||
TAG: {
|
||||
NODES: `/tag/nodes`,
|
||||
|
|
22
src/constants/boris/constants.ts
Normal file
22
src/constants/boris/constants.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
import { StatBackend } from '~/types/boris';
|
||||
|
||||
export const initialBackendStats: StatBackend = {
|
||||
users: {
|
||||
total: 0,
|
||||
alive: 0,
|
||||
},
|
||||
nodes: {
|
||||
images: 0,
|
||||
audios: 0,
|
||||
videos: 0,
|
||||
texts: 0,
|
||||
total: 0,
|
||||
},
|
||||
comments: {
|
||||
total: 0,
|
||||
},
|
||||
files: {
|
||||
count: 0,
|
||||
size: 0,
|
||||
},
|
||||
};
|
|
@ -1,4 +1,4 @@
|
|||
import { NODE_TYPES } from '~/redux/node/constants';
|
||||
import { NODE_TYPES } from '~/constants/node';
|
||||
import { LoginDialog } from '~/containers/dialogs/LoginDialog';
|
||||
import { LoadingDialog } from '~/containers/dialogs/LoadingDialog';
|
||||
import { TestDialog } from '~/containers/dialogs/TestDialog';
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
export const DEFAULT_DOMINANT_COLOR = '#000000';
|
|
@ -1,5 +1,5 @@
|
|||
import { FC } from 'react';
|
||||
import { IComment, INode, ValueOf } from '../types';
|
||||
import { IComment, INode, ValueOf } from 'src/redux/types';
|
||||
import { NodeTextBlock } from '~/components/node/NodeTextBlock';
|
||||
import { NodeAudioBlock } from '~/components/node/NodeAudioBlock';
|
||||
import { NodeVideoBlock } from '~/components/node/NodeVideoBlock';
|
||||
|
@ -11,7 +11,7 @@ import { AudioEditor } from '~/components/editors/AudioEditor';
|
|||
import { EditorImageUploadButton } from '~/components/editors/EditorImageUploadButton';
|
||||
import { EditorAudioUploadButton } from '~/components/editors/EditorAudioUploadButton';
|
||||
import { EditorUploadCoverButton } from '~/components/editors/EditorUploadCoverButton';
|
||||
import { IEditorComponentProps, NodeEditorProps } from '~/redux/node/types';
|
||||
import { IEditorComponentProps, NodeEditorProps } from '~/types/node';
|
||||
import { EditorFiller } from '~/components/editors/EditorFiller';
|
||||
import { EditorPublicSwitch } from '~/components/editors/EditorPublicSwitch';
|
||||
import { NodeImageSwiperBlock } from '~/components/node/NodeImageSwiperBlock';
|
||||
|
@ -127,4 +127,6 @@ export const NODE_SETTINGS = {
|
|||
MAX_IMAGE_ASPECT: 1.2,
|
||||
};
|
||||
|
||||
export const DEFAULT_DOMINANT_COLOR = '#000000';
|
||||
|
||||
export const COMMENTS_DISPLAY = 25;
|
|
@ -1,5 +1,5 @@
|
|||
import React, { FC, useCallback, useMemo, useRef } from 'react';
|
||||
import { EMPTY_NODE, NODE_TYPES } from '~/redux/node/constants';
|
||||
import { EMPTY_NODE, NODE_TYPES } from '~/constants/node';
|
||||
import { EditorDialog } from '~/containers/dialogs/EditorDialog';
|
||||
import { useHistory, useRouteMatch } from 'react-router';
|
||||
import { values } from 'ramda';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { createElement, FC, useCallback, useMemo, useState } from 'react';
|
||||
import { IDialogProps } from '~/redux/modal/constants';
|
||||
import styles from './styles.module.scss';
|
||||
import { NODE_EDITORS } from '~/redux/node/constants';
|
||||
import { NODE_EDITORS } from '~/constants/node';
|
||||
import { BetterScrollDialog } from '../BetterScrollDialog';
|
||||
import { CoverBackdrop } from '~/components/containers/CoverBackdrop';
|
||||
import { prop } from 'ramda';
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { FC, useMemo } from 'react';
|
|||
import Masonry from 'react-masonry-css';
|
||||
import styles from './styles.module.scss';
|
||||
import { LabNode } from '~/components/lab/LabNode';
|
||||
import { EMPTY_NODE, NODE_TYPES } from '~/redux/node/constants';
|
||||
import { EMPTY_NODE, NODE_TYPES } from '~/constants/node';
|
||||
import { values } from 'ramda';
|
||||
import { useLabPagination } from '~/hooks/lab/useLabPagination';
|
||||
import { useLabContext } from '~/utils/context/LabContextProvider';
|
||||
|
|
|
@ -2,13 +2,12 @@ import { useDispatch } from 'react-redux';
|
|||
import { useCallback, useEffect } from 'react';
|
||||
import isBefore from 'date-fns/isBefore';
|
||||
import { authSetState, authSetUser } from '~/redux/auth/actions';
|
||||
import { borisLoadStats } from '~/redux/boris/actions';
|
||||
import { useUser } from '~/hooks/user/userUser';
|
||||
import { IComment } from '~/redux/types';
|
||||
import { useShallowSelect } from '~/hooks/data/useShallowSelect';
|
||||
import { selectAuthIsTester } from '~/redux/auth/selectors';
|
||||
import { selectBorisStats } from '~/redux/boris/selectors';
|
||||
import { useRandomPhrase } from '~/constants/phrases';
|
||||
import { useBorisStats } from '~/hooks/boris/useBorisStats';
|
||||
|
||||
export const useBoris = (comments: IComment[]) => {
|
||||
const dispatch = useDispatch();
|
||||
|
@ -29,9 +28,7 @@ export const useBoris = (comments: IComment[]) => {
|
|||
dispatch(authSetUser({ last_seen_boris: last_comment.created_at }));
|
||||
}, [user.last_seen_boris, dispatch, comments]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(borisLoadStats());
|
||||
}, [dispatch]);
|
||||
const { stats, isLoading: isLoadingStats } = useBorisStats();
|
||||
|
||||
const setIsBetaTester = useCallback(
|
||||
(is_tester: boolean) => {
|
||||
|
@ -41,8 +38,7 @@ export const useBoris = (comments: IComment[]) => {
|
|||
);
|
||||
|
||||
const isTester = useShallowSelect(selectAuthIsTester);
|
||||
const stats = useShallowSelect(selectBorisStats);
|
||||
const title = useRandomPhrase('BORIS_TITLE');
|
||||
|
||||
return { setIsBetaTester, isTester, stats, title };
|
||||
return { setIsBetaTester, isTester, stats, title, isLoadingStats };
|
||||
};
|
||||
|
|
25
src/hooks/boris/useBorisStats.ts
Normal file
25
src/hooks/boris/useBorisStats.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import useSWR from 'swr';
|
||||
import { API } from '~/constants/api';
|
||||
import { getBorisBackendStats, getGithubIssues } from '~/api/boris';
|
||||
import { BorisUsageStats } from '~/types/boris';
|
||||
import { initialBackendStats } from '~/constants/boris/constants';
|
||||
|
||||
export const useBorisStats = () => {
|
||||
const { data: backend = initialBackendStats, isValidating: isValidatingBackend } = useSWR(
|
||||
API.BORIS.GET_BACKEND_STATS,
|
||||
() => getBorisBackendStats()
|
||||
);
|
||||
|
||||
const { data: issues = [], isValidating: isValidatingGit } = useSWR(API.BORIS.GITHUB_ISSUES, () =>
|
||||
getGithubIssues()
|
||||
);
|
||||
|
||||
const stats: BorisUsageStats = {
|
||||
backend,
|
||||
issues,
|
||||
};
|
||||
|
||||
const isLoading = !backend && isValidatingBackend;
|
||||
|
||||
return { stats, isLoading };
|
||||
};
|
|
@ -3,8 +3,8 @@ import { IComment } from '~/redux/types';
|
|||
import { API } from '~/constants/api';
|
||||
import { flatten, isNil } from 'ramda';
|
||||
import useSWRInfinite from 'swr/infinite';
|
||||
import { apiGetNodeComments } from '~/redux/node/api';
|
||||
import { COMMENTS_DISPLAY } from '~/redux/node/constants';
|
||||
import { apiGetNodeComments } from '~/api/node';
|
||||
import { COMMENTS_DISPLAY } from '~/constants/node';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
const getKey: (nodeId: number) => KeyLoader<IComment[]> = (nodeId: number) => (
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { useCallback } from 'react';
|
||||
import { IComment } from '~/redux/types';
|
||||
import { useGetComments } from '~/hooks/comments/useGetComments';
|
||||
import { apiLockComment, apiPostComment } from '~/redux/node/api';
|
||||
import { apiLockComment, apiPostComment } from '~/api/node';
|
||||
import { showErrorToast } from '~/utils/errors/showToast';
|
||||
|
||||
export const useNodeComments = (nodeId: number) => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useCallback } from 'react';
|
||||
import { INode } from '~/redux/types';
|
||||
import { apiPostNode } from '~/redux/node/api';
|
||||
import { apiPostNode } from '~/api/node';
|
||||
import { selectFlowNodes } from '~/redux/flow/selectors';
|
||||
import { flowSetNodes } from '~/redux/flow/actions';
|
||||
import { selectLabListNodes } from '~/redux/lab/selectors';
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { INode } from '~/redux/types';
|
||||
import useSWR from 'swr';
|
||||
import { ApiGetNodeRelatedResult } from '~/redux/node/types';
|
||||
import { ApiGetNodeRelatedResult } from '~/types/node';
|
||||
import { API } from '~/constants/api';
|
||||
import { useCallback } from 'react';
|
||||
import { apiGetNodeRelated } from '~/redux/node/api';
|
||||
import { apiGetNodeRelated } from '~/api/node';
|
||||
|
||||
export const useGetNodeRelated = (id?: INode['id']) => {
|
||||
const { data, isValidating, mutate } = useSWR<ApiGetNodeRelatedResult>(API.NODE.RELATED(id), () =>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import useSWR from 'swr';
|
||||
import { ApiGetNodeResponse } from '~/redux/node/types';
|
||||
import { ApiGetNodeResponse } from '~/types/node';
|
||||
import { API } from '~/constants/api';
|
||||
import { useOnNodeSeen } from '~/hooks/node/useOnNodeSeen';
|
||||
import { apiGetNode } from '~/redux/node/api';
|
||||
import { apiGetNode } from '~/api/node';
|
||||
import { useCallback } from 'react';
|
||||
import { INode } from '~/redux/types';
|
||||
import { EMPTY_NODE } from '~/redux/node/constants';
|
||||
import { EMPTY_NODE } from '~/constants/node';
|
||||
|
||||
export const useLoadNode = (id: number) => {
|
||||
const { data, isValidating, mutate } = useSWR<ApiGetNodeResponse>(API.NODE.GET_NODE(id), () =>
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useCallback } from 'react';
|
|||
import { useDispatch } from 'react-redux';
|
||||
import { modalShowDialog } from '~/redux/modal/actions';
|
||||
import { NODE_EDITOR_DIALOGS } from '~/constants/dialogs';
|
||||
import { apiLockNode, apiPostNodeHeroic, apiPostNodeLike } from '~/redux/node/api';
|
||||
import { apiLockNode, apiPostNodeHeroic, apiPostNodeLike } from '~/api/node';
|
||||
import { showErrorToast } from '~/utils/errors/showToast';
|
||||
|
||||
export const useNodeActions = (node: INode, update: (node: Partial<INode>) => Promise<unknown>) => {
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
import { INode } from '~/redux/types';
|
||||
import { createElement, FC, useCallback, useMemo } from 'react';
|
||||
import { isNil, prop } from 'ramda';
|
||||
import {
|
||||
INodeComponentProps,
|
||||
LAB_PREVIEW_LAYOUT,
|
||||
NODE_COMPONENTS,
|
||||
NODE_HEADS,
|
||||
NODE_INLINES,
|
||||
} from '~/redux/node/constants';
|
||||
import { INodeComponentProps, LAB_PREVIEW_LAYOUT, NODE_COMPONENTS, NODE_HEADS, NODE_INLINES, } from '~/constants/node';
|
||||
|
||||
// useNodeBlocks returns head, block and inline blocks of node
|
||||
export const useNodeBlocks = (node: INode, isLoading: boolean) => {
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useCallback } from 'react';
|
|||
import { ITag } from '~/redux/types';
|
||||
import { URLS } from '~/constants/urls';
|
||||
import { useLoadNode } from '~/hooks/node/useLoadNode';
|
||||
import { apiDeleteNodeTag, apiPostNodeTags } from '~/redux/node/api';
|
||||
import { apiDeleteNodeTag, apiPostNodeTags } from '~/api/node';
|
||||
|
||||
export const useNodeTags = (id: number) => {
|
||||
const { update } = useLoadNode(id);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { useLoadNode } from '~/hooks/node/useLoadNode';
|
||||
import { useCallback } from 'react';
|
||||
import { INode } from '~/redux/types';
|
||||
import { apiPostNode } from '~/redux/node/api';
|
||||
import { apiPostNode } from '~/api/node';
|
||||
import { selectFlowNodes } from '~/redux/flow/selectors';
|
||||
import { flowSetNodes } from '~/redux/flow/actions';
|
||||
import { selectLabListNodes } from '~/redux/lab/selectors';
|
||||
|
|
|
@ -9,7 +9,7 @@ import { Card } from '~/components/containers/Card';
|
|||
import { SidebarRouter } from '~/containers/main/SidebarRouter';
|
||||
import { BorisSidebar } from '~/components/boris/BorisSidebar';
|
||||
import { useUserContext } from '~/utils/context/UserContextProvider';
|
||||
import { BorisUsageStats } from '~/redux/boris/reducer';
|
||||
import { BorisUsageStats } from '~/types/boris';
|
||||
import { Tabs } from '~/components/dialogs/Tabs';
|
||||
import { Superpower } from '~/components/boris/Superpower';
|
||||
import { BorisUIDemo } from '~/components/boris/BorisUIDemo';
|
||||
|
@ -19,9 +19,10 @@ type IProps = {
|
|||
setIsBetaTester: (val: boolean) => void;
|
||||
isTester: boolean;
|
||||
stats: BorisUsageStats;
|
||||
isLoadingStats: boolean;
|
||||
};
|
||||
|
||||
const BorisLayout: FC<IProps> = ({ title, setIsBetaTester, isTester, stats }) => {
|
||||
const BorisLayout: FC<IProps> = ({ title, setIsBetaTester, isTester, stats, isLoadingStats }) => {
|
||||
const user = useUserContext();
|
||||
|
||||
return (
|
||||
|
@ -60,6 +61,7 @@ const BorisLayout: FC<IProps> = ({ title, setIsBetaTester, isTester, stats }) =>
|
|||
stats={stats}
|
||||
setBetaTester={setIsBetaTester}
|
||||
user={user}
|
||||
isLoading={isLoadingStats}
|
||||
/>
|
||||
</StickyBox>
|
||||
</Group>
|
||||
|
|
|
@ -19,7 +19,7 @@ const BorisPage: VFC = () => {
|
|||
hasMore,
|
||||
isLoading: isLoadingComments,
|
||||
} = useNodeComments(696);
|
||||
const { title, setIsBetaTester, isTester, stats } = useBoris(comments);
|
||||
const { title, setIsBetaTester, isTester, stats, isLoadingStats } = useBoris(comments);
|
||||
|
||||
return (
|
||||
<NodeContextProvider node={node} isLoading={isLoading} update={update}>
|
||||
|
@ -37,6 +37,7 @@ const BorisPage: VFC = () => {
|
|||
setIsBetaTester={setIsBetaTester}
|
||||
isTester={isTester}
|
||||
stats={stats}
|
||||
isLoadingStats={isLoadingStats}
|
||||
/>
|
||||
</CommentContextProvider>
|
||||
</NodeContextProvider>
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
import { IBorisState } from './reducer';
|
||||
import { BORIS_ACTIONS } from './constants';
|
||||
|
||||
export const borisSet = (state: Partial<IBorisState>) => ({
|
||||
type: BORIS_ACTIONS.SET_BORIS,
|
||||
state,
|
||||
});
|
||||
|
||||
export const borisSetStats = (stats: Partial<IBorisState['stats']>) => ({
|
||||
type: BORIS_ACTIONS.SET_STATS,
|
||||
stats,
|
||||
});
|
||||
|
||||
export const borisLoadStats = () => ({
|
||||
type: BORIS_ACTIONS.LOAD_STATS,
|
||||
});
|
|
@ -1,20 +0,0 @@
|
|||
import git from '~/stats/git.json';
|
||||
import { API } from '~/constants/api';
|
||||
import { api, cleanResult } from '~/utils/api';
|
||||
import { IBorisState, IStatBackend } from './reducer';
|
||||
import axios from 'axios';
|
||||
import { IGetGithubIssuesResult } from '~/redux/boris/types';
|
||||
|
||||
export const getBorisGitStats = () => Promise.resolve<IBorisState['stats']['git']>(git);
|
||||
|
||||
export const getBorisBackendStats = () =>
|
||||
api.get<IStatBackend>(API.BORIS.GET_BACKEND_STATS).then(cleanResult);
|
||||
|
||||
export const getGithubIssues = () => {
|
||||
return axios
|
||||
.get<IGetGithubIssuesResult>('https://api.github.com/repos/muerwre/vault-frontend/issues', {
|
||||
params: { state: 'all', sort: 'created' },
|
||||
})
|
||||
.then(result => result.data)
|
||||
.catch(() => []);
|
||||
};
|
|
@ -1,8 +0,0 @@
|
|||
const prefix = `BORIS.`;
|
||||
|
||||
export const BORIS_ACTIONS = {
|
||||
SET_BORIS: `${prefix}SET_BORIS`,
|
||||
SET_STATS: `${prefix}SET_STATS`,
|
||||
|
||||
LOAD_STATS: `${prefix}LOAD_STATS`,
|
||||
};
|
|
@ -1,20 +0,0 @@
|
|||
import { IBorisState } from './reducer';
|
||||
import { BORIS_ACTIONS } from './constants';
|
||||
|
||||
const borisSet = (current: IBorisState, { state }: ReturnType<typeof borisSet>) => ({
|
||||
...current,
|
||||
...state,
|
||||
});
|
||||
|
||||
const borisSetStats = (state: IBorisState, { stats }: ReturnType<typeof borisSetStats>) => ({
|
||||
...state,
|
||||
stats: {
|
||||
...state.stats,
|
||||
...stats,
|
||||
},
|
||||
});
|
||||
|
||||
export const BORIS_HANDLERS = {
|
||||
[BORIS_ACTIONS.SET_BORIS]: borisSet,
|
||||
[BORIS_ACTIONS.SET_STATS]: borisSetStats,
|
||||
};
|
|
@ -1,72 +0,0 @@
|
|||
import { createReducer } from '~/utils/reducer';
|
||||
import { BORIS_HANDLERS } from './handlers';
|
||||
import { IGithubIssue } from '~/redux/boris/types';
|
||||
|
||||
export type IStatGitRow = {
|
||||
commit: string;
|
||||
subject: string;
|
||||
timestamp: string;
|
||||
};
|
||||
|
||||
export type IStatBackend = {
|
||||
users: {
|
||||
total: number;
|
||||
alive: number;
|
||||
};
|
||||
nodes: {
|
||||
images: number;
|
||||
audios: number;
|
||||
videos: number;
|
||||
texts: number;
|
||||
total: number;
|
||||
};
|
||||
comments: {
|
||||
total: number;
|
||||
};
|
||||
files: {
|
||||
count: number;
|
||||
size: number;
|
||||
};
|
||||
};
|
||||
|
||||
export interface BorisUsageStats {
|
||||
git: Partial<IStatGitRow>[];
|
||||
issues: IGithubIssue[];
|
||||
backend: IStatBackend;
|
||||
is_loading: boolean;
|
||||
}
|
||||
export type IBorisState = Readonly<{
|
||||
stats: BorisUsageStats;
|
||||
}>;
|
||||
|
||||
const initialBackendStats: IStatBackend = {
|
||||
users: {
|
||||
total: 0,
|
||||
alive: 0,
|
||||
},
|
||||
nodes: {
|
||||
images: 0,
|
||||
audios: 0,
|
||||
videos: 0,
|
||||
texts: 0,
|
||||
total: 0,
|
||||
},
|
||||
comments: {
|
||||
total: 0,
|
||||
},
|
||||
files: {
|
||||
count: 0,
|
||||
size: 0,
|
||||
},
|
||||
};
|
||||
|
||||
const BORIS_INITIAL_STATE: IBorisState = {
|
||||
stats: {
|
||||
git: [],
|
||||
issues: [],
|
||||
backend: initialBackendStats,
|
||||
is_loading: false,
|
||||
},
|
||||
};
|
||||
|
||||
export default createReducer(BORIS_INITIAL_STATE, BORIS_HANDLERS);
|
|
@ -1,24 +0,0 @@
|
|||
import { call, put, takeLatest } from 'redux-saga/effects';
|
||||
import { BORIS_ACTIONS } from './constants';
|
||||
import { borisSetStats } from './actions';
|
||||
import { getBorisBackendStats, getGithubIssues } from './api';
|
||||
import { Unwrap } from '../types';
|
||||
|
||||
function* loadStats() {
|
||||
try {
|
||||
yield put(borisSetStats({ is_loading: true }));
|
||||
|
||||
const backend: Unwrap<typeof getBorisBackendStats> = yield call(getBorisBackendStats);
|
||||
const issues: Unwrap<typeof getGithubIssues> = yield call(getGithubIssues);
|
||||
|
||||
yield put(borisSetStats({ issues, backend }));
|
||||
} catch (e) {
|
||||
yield put(borisSetStats({ git: [], backend: undefined }));
|
||||
} finally {
|
||||
yield put(borisSetStats({ is_loading: false }));
|
||||
}
|
||||
}
|
||||
|
||||
export default function* borisSaga() {
|
||||
yield takeLatest(BORIS_ACTIONS.LOAD_STATS, loadStats);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { IState } from '../store';
|
||||
|
||||
export const selectBoris = (state: IState) => state.boris;
|
||||
export const selectBorisStats = (state: IState) => state.boris.stats;
|
|
@ -1,12 +0,0 @@
|
|||
export interface IGithubIssue {
|
||||
id: string;
|
||||
url: string;
|
||||
html_url: string;
|
||||
body: string;
|
||||
title: string;
|
||||
state: 'open' | 'closed';
|
||||
created_at: string;
|
||||
pull_request?: unknown;
|
||||
}
|
||||
|
||||
export type IGetGithubIssuesResult = IGithubIssue[];
|
|
@ -1,7 +1,7 @@
|
|||
import { api, cleanResult, configWithToken } from '~/utils/api';
|
||||
import { INode, IResultWithStatus } from '../types';
|
||||
import { API } from '~/constants/api';
|
||||
import { PostCellViewRequest, PostCellViewResult } from '~/redux/node/types';
|
||||
import { PostCellViewRequest, PostCellViewResult } from '~/types/node';
|
||||
import { GetSearchResultsRequest, GetSearchResultsResult } from '~/redux/flow/types';
|
||||
|
||||
export const postNode = ({
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { call, delay, put, race, select, take, takeLatest, takeLeading } from 'redux-saga/effects';
|
||||
import { REHYDRATE } from 'redux-persist';
|
||||
import { FLOW_ACTIONS } from './constants';
|
||||
import { getNodeDiff } from '../node/api';
|
||||
import { getNodeDiff } from '~/api/node';
|
||||
import {
|
||||
flowChangeSearch,
|
||||
flowSetCellView,
|
||||
|
|
|
@ -29,9 +29,6 @@ import { modalSaga } from './modal/sagas';
|
|||
|
||||
import { authLogout, authOpenProfile, gotAuthPostMessage } from './auth/actions';
|
||||
|
||||
import boris, { IBorisState } from './boris/reducer';
|
||||
import borisSaga from './boris/sagas';
|
||||
|
||||
import messages, { IMessagesState } from './messages';
|
||||
import messagesSaga from './messages/sagas';
|
||||
|
||||
|
@ -66,7 +63,6 @@ export interface IState {
|
|||
uploads: IUploadState;
|
||||
flow: IFlowState;
|
||||
player: IPlayerState;
|
||||
boris: IBorisState;
|
||||
messages: IMessagesState;
|
||||
tag: ITagState;
|
||||
lab: ILabState;
|
||||
|
@ -86,7 +82,6 @@ export const store = createStore(
|
|||
combineReducers<IState>({
|
||||
auth: persistReducer(authPersistConfig, auth),
|
||||
modal,
|
||||
boris,
|
||||
router: connectRouter(history),
|
||||
uploads,
|
||||
flow: persistReducer(flowPersistConfig, flow),
|
||||
|
@ -107,7 +102,6 @@ export function configureStore(): {
|
|||
sagaMiddleware.run(flowSaga);
|
||||
sagaMiddleware.run(playerSaga);
|
||||
sagaMiddleware.run(modalSaga);
|
||||
sagaMiddleware.run(borisSaga);
|
||||
sagaMiddleware.run(messagesSaga);
|
||||
sagaMiddleware.run(tagSaga);
|
||||
sagaMiddleware.run(labSaga);
|
||||
|
|
47
src/types/boris/index.ts
Normal file
47
src/types/boris/index.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
export interface GithubIssue {
|
||||
id: string;
|
||||
url: string;
|
||||
html_url: string;
|
||||
body: string;
|
||||
title: string;
|
||||
state: 'open' | 'closed';
|
||||
created_at: string;
|
||||
pull_request?: unknown;
|
||||
}
|
||||
|
||||
export type IGetGithubIssuesResult = GithubIssue[];
|
||||
|
||||
export type IStatGitRow = {
|
||||
commit: string;
|
||||
subject: string;
|
||||
timestamp: string;
|
||||
};
|
||||
|
||||
export type StatBackend = {
|
||||
users: {
|
||||
total: number;
|
||||
alive: number;
|
||||
};
|
||||
nodes: {
|
||||
images: number;
|
||||
audios: number;
|
||||
videos: number;
|
||||
texts: number;
|
||||
total: number;
|
||||
};
|
||||
comments: {
|
||||
total: number;
|
||||
};
|
||||
files: {
|
||||
count: number;
|
||||
size: number;
|
||||
};
|
||||
};
|
||||
|
||||
export interface BorisUsageStats {
|
||||
issues: GithubIssue[];
|
||||
backend: StatBackend;
|
||||
}
|
||||
export type IBorisState = Readonly<{
|
||||
stats: BorisUsageStats;
|
||||
}>;
|
|
@ -1,5 +1,5 @@
|
|||
import { INode } from '~/redux/types';
|
||||
import { EMPTY_NODE } from '~/redux/node/constants';
|
||||
import { EMPTY_NODE } from '~/constants/node';
|
||||
import React, { createContext, FC, useContext } from 'react';
|
||||
|
||||
export interface NodeContextProps {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { INodeRelated } from '~/redux/node/types';
|
||||
import { INodeRelated } from '~/types/node';
|
||||
import React, { createContext, FC, useContext } from 'react';
|
||||
|
||||
interface NodeRelatedProviderProps {
|
||||
|
|
|
@ -2,7 +2,7 @@ import { USER_ROLES } from '~/redux/auth/constants';
|
|||
import { ICommentGroup, INode } from '~/redux/types';
|
||||
import { IUser } from '~/redux/auth/types';
|
||||
import { path } from 'ramda';
|
||||
import { NODE_TYPES } from '~/redux/node/constants';
|
||||
import { NODE_TYPES } from '~/constants/node';
|
||||
|
||||
export const canEditNode = (node?: Partial<INode>, user?: Partial<IUser>): boolean =>
|
||||
path(['role'], user) === USER_ROLES.ADMIN ||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { FC, useEffect } from 'react';
|
||||
import { INode, ITag } from '~/redux/types';
|
||||
import { NodeRelatedContextProvider } from '~/utils/context/NodeRelatedContextProvider';
|
||||
import { INodeRelated } from '~/redux/node/types';
|
||||
import { INodeRelated } from '~/types/node';
|
||||
import { useGetNodeRelated } from '~/hooks/node/useGetNodeRelated';
|
||||
|
||||
interface NodeRelatedProviderProps {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue