mirror of
https://github.com/bakhirev/assayo.git
synced 2024-11-16 16:21:41 +00:00
update
This commit is contained in:
parent
2e29d4ede2
commit
5d890b4848
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||||
|
|
||||||
import Banner from 'ts/components/Banner';
|
import Banner from 'ts/components/Banner';
|
||||||
|
|
||||||
import style from './index.module.scss';
|
import style from '../index.module.scss';
|
||||||
|
|
||||||
interface ICardWithBannerProps {
|
interface ICardWithBannerProps {
|
||||||
long?: boolean;
|
long?: boolean;
|
36
src/ts/components/CardWithIcon/components/Scoring.tsx
Normal file
36
src/ts/components/CardWithIcon/components/Scoring.tsx
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import style from '../index.module.scss';
|
||||||
|
|
||||||
|
export interface IScoringProps {
|
||||||
|
title?: string;
|
||||||
|
value?: number;
|
||||||
|
total?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Scoring({
|
||||||
|
title,
|
||||||
|
value,
|
||||||
|
total,
|
||||||
|
}: IScoringProps): React.ReactElement | null {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
if (!value) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
title={t(title || 'page.person.scoring.toolbar')}
|
||||||
|
className={style.card_with_icon_scoring}
|
||||||
|
>
|
||||||
|
{`${value} / ${total || value}`}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Scoring.defaultProps = {
|
||||||
|
title: undefined,
|
||||||
|
value: undefined,
|
||||||
|
total: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Scoring;
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
.card_with_icon,
|
.card_with_icon,
|
||||||
.card_with_icon_long {
|
.card_with_icon_long {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: calc(50% - 12px);
|
width: calc(50% - 12px);
|
||||||
min-height: 270px;
|
min-height: 270px;
|
||||||
|
@ -11,8 +13,9 @@
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
border-radius: 8px;
|
border-radius: var(--border-radius-m);
|
||||||
border: 1px solid var(--color-border);
|
border: 1px solid var(--color-border);
|
||||||
background-color: var(--color-white);
|
background-color: var(--color-white);
|
||||||
|
|
||||||
|
@ -40,7 +43,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&_title,
|
&_title,
|
||||||
&_description {
|
&_description,
|
||||||
|
&_scoring {
|
||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
@ -57,7 +61,8 @@
|
||||||
margin: 0 0 4px 0;
|
margin: 0 0 4px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&_description {
|
&_description,
|
||||||
|
&_scoring {
|
||||||
font-size: var(--font-xs);
|
font-size: var(--font-xs);
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
color: var(--color-grey);
|
color: var(--color-grey);
|
||||||
|
@ -68,6 +73,22 @@
|
||||||
padding: 0;
|
padding: 0;
|
||||||
line-height: 270px;
|
line-height: 270px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&_scoring {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -11px;
|
||||||
|
left: 30%;
|
||||||
|
right: 30%;
|
||||||
|
|
||||||
|
display: inline-block;
|
||||||
|
padding: var(--space-xxxs) var(--space-xs);
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
border-radius: var(--border-radius-s);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
background-color: var(--color-white);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.card_with_icon_long {
|
.card_with_icon_long {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import type { IScoringProps } from './components/Scoring';
|
||||||
|
import Scoring from './components/Scoring';
|
||||||
import style from './index.module.scss';
|
import style from './index.module.scss';
|
||||||
|
|
||||||
interface ICardWithIconProps {
|
interface ICardWithIconProps {
|
||||||
|
@ -11,6 +13,7 @@ interface ICardWithIconProps {
|
||||||
color?: string;
|
color?: string;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
long?: boolean;
|
long?: boolean;
|
||||||
|
scoring?: IScoringProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
function CardWithIcon({
|
function CardWithIcon({
|
||||||
|
@ -21,8 +24,10 @@ function CardWithIcon({
|
||||||
color,
|
color,
|
||||||
icon,
|
icon,
|
||||||
long = false,
|
long = false,
|
||||||
|
scoring,
|
||||||
}: ICardWithIconProps): React.ReactElement | null {
|
}: ICardWithIconProps): React.ReactElement | null {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
if (!value && value !== 0) return null;
|
if (!value && value !== 0) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -48,6 +53,11 @@ function CardWithIcon({
|
||||||
<figcaption className={style.card_with_icon_description}>
|
<figcaption className={style.card_with_icon_description}>
|
||||||
{t(description || '')}
|
{t(description || '')}
|
||||||
</figcaption>
|
</figcaption>
|
||||||
|
<Scoring
|
||||||
|
title={scoring?.title}
|
||||||
|
value={scoring?.value}
|
||||||
|
total={scoring?.total}
|
||||||
|
/>
|
||||||
</figure>
|
</figure>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -58,6 +68,7 @@ CardWithIcon.defaultProps = {
|
||||||
color: undefined,
|
color: undefined,
|
||||||
icon: undefined,
|
icon: undefined,
|
||||||
long: false,
|
long: false,
|
||||||
|
scoring: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CardWithIcon;
|
export default CardWithIcon;
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import UiKitSelectOption from './Option';
|
import UiKitSelectOption from './Option';
|
||||||
|
import IOption from '../interfaces/Option';
|
||||||
|
|
||||||
import style from '../styles/index.module.scss';
|
import style from '../styles/index.module.scss';
|
||||||
|
|
||||||
interface UiKitSelectListProps {
|
interface UiKitSelectListProps {
|
||||||
value: any;
|
value: any;
|
||||||
options: any;
|
options: IOption[];
|
||||||
search?: string;
|
search?: string;
|
||||||
keyCode?: string;
|
keyCode?: string;
|
||||||
setKeyCode: Function;
|
setKeyCode: Function;
|
||||||
|
@ -26,8 +27,10 @@ function UiKitSelectList({
|
||||||
const [selectedIndex, setSelectedIndex] = useState<number>(-1);
|
const [selectedIndex, setSelectedIndex] = useState<number>(-1);
|
||||||
|
|
||||||
console.log(value);
|
console.log(value);
|
||||||
const searchResult = options
|
const searchText = search ? search.toLowerCase() : '';
|
||||||
?.filter((option: any) => option.title.indexOf(search) !== -1);
|
const searchResult = searchText
|
||||||
|
? options?.filter((option: any) => option?._textForSearch?.indexOf(searchText) !== -1)
|
||||||
|
: options;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!keyCode) return;
|
if (!keyCode) return;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import IOption from '../interfaces/Option';
|
||||||
import style from '../styles/index.module.scss';
|
import style from '../styles/index.module.scss';
|
||||||
|
|
||||||
interface UiKitSelectValueProps {
|
interface UiKitSelectValueProps {
|
||||||
value: any;
|
value: any;
|
||||||
options: any;
|
options: IOption[];
|
||||||
className?: string;
|
className?: string;
|
||||||
onClick: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
onClick: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import IOption from '../interfaces/Option';
|
||||||
|
|
||||||
function getStringFromObject(value: any) {
|
function getStringFromObject(value: any) {
|
||||||
return value?.title
|
return value?.title
|
||||||
|| value?.name
|
|| value?.name
|
||||||
|
@ -23,8 +25,9 @@ function getValue(
|
||||||
formatter: (a: any, i?: number) => string,
|
formatter: (a: any, i?: number) => string,
|
||||||
) {
|
) {
|
||||||
const type = typeof value;
|
const type = typeof value;
|
||||||
if (type === 'boolean') return value ? 'yes' : 'no';
|
if (type === 'boolean') return value ? 'true' : 'false';
|
||||||
if (type === 'number' || type === 'string') return value;
|
if (type === 'number') return `${value}`;
|
||||||
|
if (type === 'string') return value;
|
||||||
if (!value) return '';
|
if (!value) return '';
|
||||||
|
|
||||||
return Array.isArray(value)
|
return Array.isArray(value)
|
||||||
|
@ -40,10 +43,12 @@ export function getId(value: any, index: number) {
|
||||||
return getValue(value, (v: any) => getIdFromObject(v, index));
|
return getValue(value, (v: any) => getIdFromObject(v, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getOption(value: any, index: number) {
|
export function getOption(value: any, index: number): IOption {
|
||||||
|
const title = getTitle(value);
|
||||||
return {
|
return {
|
||||||
id: getId(value, index),
|
id: getId(value, index),
|
||||||
title: getTitle(value),
|
title,
|
||||||
|
_textForSearch: title.toLowerCase(),
|
||||||
source: value,
|
source: value,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React, { useMemo, useState } from 'react';
|
import React, { useMemo, useState } from 'react';
|
||||||
|
|
||||||
|
import IOption from './interfaces/Option';
|
||||||
import UiKitSelectValue from './components/Value';
|
import UiKitSelectValue from './components/Value';
|
||||||
import UiKitSelectSearch from './components/Search';
|
import UiKitSelectSearch from './components/Search';
|
||||||
import UiKitSelectList from './components/List';
|
import UiKitSelectList from './components/List';
|
||||||
|
@ -25,7 +26,7 @@ function UiKitSelect({
|
||||||
const [search, setSearch] = useState<string>('');
|
const [search, setSearch] = useState<string>('');
|
||||||
const [keyCode, setKeyCode] = useState<string>('');
|
const [keyCode, setKeyCode] = useState<string>('');
|
||||||
|
|
||||||
const formattedOptions = useMemo(() => options?.map(getOption) || [], [options]);
|
const formattedOptions: IOption[] = useMemo(() => options?.map(getOption) || [], [options]);
|
||||||
const formattedValue = useMemo(() => {
|
const formattedValue = useMemo(() => {
|
||||||
const selectedOption = options.find((option: any) => option.id === value);
|
const selectedOption = options.find((option: any) => option.id === value);
|
||||||
return getTitle(selectedOption) || getTitle(value);
|
return getTitle(selectedOption) || getTitle(value);
|
||||||
|
|
6
src/ts/components/CustomSelect/interfaces/Option.ts
Normal file
6
src/ts/components/CustomSelect/interfaces/Option.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
export default interface IOption {
|
||||||
|
id: string | number | boolean;
|
||||||
|
title: string;
|
||||||
|
_textForSearch: string;
|
||||||
|
source: any;
|
||||||
|
}
|
61
src/ts/helpers/DataGrip/components/scoring.ts
Normal file
61
src/ts/helpers/DataGrip/components/scoring.ts
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
import IHashMap from 'ts/interfaces/HashMap';
|
||||||
|
|
||||||
|
const PROPERTIES = [
|
||||||
|
{ property: 'daysWorked', sort: 1 },
|
||||||
|
{ property: 'daysLosses', sort: -1 },
|
||||||
|
{ property: 'commits', sort: 1 },
|
||||||
|
{ property: 'daysForTask', sort: -1 },
|
||||||
|
{ property: 'tasks', sort: 1 },
|
||||||
|
{ property: 'moneyAll', sort: 1 },
|
||||||
|
{ property: 'moneyWorked', sort: 1 },
|
||||||
|
{ property: 'moneyLosses', sort: -1 },
|
||||||
|
{ property: 'weekendPayment', sort: -1 },
|
||||||
|
];
|
||||||
|
|
||||||
|
export default class DataGripByScoring {
|
||||||
|
total: IHashMap<number> = {};
|
||||||
|
|
||||||
|
statisticByName: IHashMap<any> = {};
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.total = {};
|
||||||
|
this.statisticByName = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTotalInfo(dataGripByAuthor: any) {
|
||||||
|
const list = [...dataGripByAuthor.statistic];
|
||||||
|
|
||||||
|
list.forEach((user: any) => {
|
||||||
|
this.statisticByName[user.author] = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
PROPERTIES.forEach((config: any) => {
|
||||||
|
const values = list.map((user: any) => {
|
||||||
|
const value = user[config.property] || 0;
|
||||||
|
return Array.isArray(value)
|
||||||
|
? value?.length
|
||||||
|
: value;
|
||||||
|
});
|
||||||
|
|
||||||
|
const uniqValues = Array.from(new Set(values));
|
||||||
|
const places = uniqValues
|
||||||
|
.sort((a:number, b:number) => (b - a) * config.sort)
|
||||||
|
.map((v, i) => [v, i + 1]);
|
||||||
|
const refValuePlace = Object.fromEntries(places);
|
||||||
|
|
||||||
|
list.forEach((user: any) => {
|
||||||
|
const userValue = user[config.property];
|
||||||
|
const userFormattedValue = Array.isArray(userValue)
|
||||||
|
? userValue?.length
|
||||||
|
: userValue;
|
||||||
|
this.statisticByName[user.author][config.property] = refValuePlace[userFormattedValue];
|
||||||
|
});
|
||||||
|
|
||||||
|
this.total[config.property] = uniqValues.length;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import DataGripByGet from './components/get';
|
||||||
import DataGripByPR from './components/pr';
|
import DataGripByPR from './components/pr';
|
||||||
import DataGripByTasks from './components/tasks';
|
import DataGripByTasks from './components/tasks';
|
||||||
import DataGripByRelease from './components/release';
|
import DataGripByRelease from './components/release';
|
||||||
|
import DataGripByScoring from './components/scoring';
|
||||||
|
|
||||||
class DataGrip {
|
class DataGrip {
|
||||||
firstLastCommit: any = new MinMaxCounter();
|
firstLastCommit: any = new MinMaxCounter();
|
||||||
|
@ -39,6 +40,8 @@ class DataGrip {
|
||||||
|
|
||||||
release: any = new DataGripByRelease();
|
release: any = new DataGripByRelease();
|
||||||
|
|
||||||
|
scoring: any = new DataGripByScoring();
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
this.firstLastCommit.clear();
|
this.firstLastCommit.clear();
|
||||||
this.author.clear();
|
this.author.clear();
|
||||||
|
@ -52,6 +55,7 @@ class DataGrip {
|
||||||
this.pr.clear();
|
this.pr.clear();
|
||||||
this.tasks.clear();
|
this.tasks.clear();
|
||||||
this.release.clear();
|
this.release.clear();
|
||||||
|
this.scoring.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
addCommit(commit: ICommit | ISystemCommit) {
|
addCommit(commit: ICommit | ISystemCommit) {
|
||||||
|
@ -81,6 +85,7 @@ class DataGrip {
|
||||||
this.pr.updateTotalInfo(this.author);
|
this.pr.updateTotalInfo(this.author);
|
||||||
this.tasks.updateTotalInfo(this.pr);
|
this.tasks.updateTotalInfo(this.pr);
|
||||||
this.release.updateTotalInfo();
|
this.release.updateTotalInfo();
|
||||||
|
this.scoring.updateTotalInfo(this.author);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@ import IPersonCommonProps from '../interfaces/CommonProps';
|
||||||
|
|
||||||
const Money = observer(({ user }: IPersonCommonProps): React.ReactElement => {
|
const Money = observer(({ user }: IPersonCommonProps): React.ReactElement => {
|
||||||
const statistic = user;
|
const statistic = user;
|
||||||
|
const scoringTotal = dataGripStore.dataGrip.scoring.total;
|
||||||
|
const scoring = dataGripStore.dataGrip.scoring.statisticByName[user.author];
|
||||||
const byTimestamp = dataGripStore.dataGrip.timestamp.statisticByAuthor[statistic.author];
|
const byTimestamp = dataGripStore.dataGrip.timestamp.statisticByAuthor[statistic.author];
|
||||||
const taskNumber = statistic.tasks.length;
|
const taskNumber = statistic.tasks.length;
|
||||||
|
|
||||||
|
@ -36,24 +38,40 @@ const Money = observer(({ user }: IPersonCommonProps): React.ReactElement => {
|
||||||
icon="./assets/cards/money_total.png"
|
icon="./assets/cards/money_total.png"
|
||||||
title="page.person.money.moneyAll.title"
|
title="page.person.money.moneyAll.title"
|
||||||
description="page.person.money.moneyAll.description"
|
description="page.person.money.moneyAll.description"
|
||||||
|
scoring={{
|
||||||
|
value: scoring.moneyAll,
|
||||||
|
total: scoringTotal.moneyAll,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<CardWithIcon
|
<CardWithIcon
|
||||||
value={getShortMoney(statistic.moneyWorked)}
|
value={getShortMoney(statistic.moneyWorked)}
|
||||||
icon="./assets/cards/money_work.png"
|
icon="./assets/cards/money_work.png"
|
||||||
title="page.person.money.moneyWorked.title"
|
title="page.person.money.moneyWorked.title"
|
||||||
description="page.person.money.moneyWorked.description"
|
description="page.person.money.moneyWorked.description"
|
||||||
|
scoring={{
|
||||||
|
value: scoring.moneyWorked,
|
||||||
|
total: scoringTotal.moneyWorked,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<CardWithIcon
|
<CardWithIcon
|
||||||
value={getShortMoney(statistic.moneyLosses)}
|
value={getShortMoney(statistic.moneyLosses)}
|
||||||
icon="./assets/cards/money_lazy.png"
|
icon="./assets/cards/money_lazy.png"
|
||||||
title="page.person.money.moneyLosses.title"
|
title="page.person.money.moneyLosses.title"
|
||||||
description="page.person.money.moneyLosses.description"
|
description="page.person.money.moneyLosses.description"
|
||||||
|
scoring={{
|
||||||
|
value: scoring.moneyLosses,
|
||||||
|
total: scoringTotal.moneyLosses,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<CardWithIcon
|
<CardWithIcon
|
||||||
value={getShortMoney(byTimestamp.weekendPayment)}
|
value={getShortMoney(byTimestamp.weekendPayment)}
|
||||||
icon="./assets/cards/money_holidays.png"
|
icon="./assets/cards/money_holidays.png"
|
||||||
title="page.team.total.weekendPayment.title"
|
title="page.team.total.weekendPayment.title"
|
||||||
description="page.team.total.weekendPayment.description"
|
description="page.team.total.weekendPayment.description"
|
||||||
|
scoring={{
|
||||||
|
value: scoring.weekendPayment,
|
||||||
|
total: scoringTotal.weekendPayment,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</PageColumn>
|
</PageColumn>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { observer } from 'mobx-react-lite';
|
||||||
import { getShortNumber } from 'ts/helpers/formatter';
|
import { getShortNumber } from 'ts/helpers/formatter';
|
||||||
|
|
||||||
import CardWithIcon from 'ts/components/CardWithIcon';
|
import CardWithIcon from 'ts/components/CardWithIcon';
|
||||||
import CardWithBanner from 'ts/components/CardWithIcon/Banner';
|
import CardWithBanner from 'ts/components/CardWithIcon/components/Banner';
|
||||||
import NothingFound from 'ts/components/NothingFound';
|
import NothingFound from 'ts/components/NothingFound';
|
||||||
import IsStaff from 'ts/components/NothingFound/components/IsStaff';
|
import IsStaff from 'ts/components/NothingFound/components/IsStaff';
|
||||||
import PageWrapper from 'ts/components/Page/wrapper';
|
import PageWrapper from 'ts/components/Page/wrapper';
|
||||||
|
|
|
@ -6,7 +6,7 @@ import achievementByAuthor from 'ts/helpers/achievement/byCompetition';
|
||||||
import ACHIEVEMENT_TYPE from 'ts/helpers/achievement/constants/type';
|
import ACHIEVEMENT_TYPE from 'ts/helpers/achievement/constants/type';
|
||||||
|
|
||||||
import CardWithIcon from 'ts/components/CardWithIcon';
|
import CardWithIcon from 'ts/components/CardWithIcon';
|
||||||
import CardWithBanner from 'ts/components/CardWithIcon/Banner';
|
import CardWithBanner from 'ts/components/CardWithIcon/components/Banner';
|
||||||
import Achievements from 'ts/components/Achievement';
|
import Achievements from 'ts/components/Achievement';
|
||||||
import Description from 'ts/components/Description';
|
import Description from 'ts/components/Description';
|
||||||
import PageWrapper from 'ts/components/Page/wrapper';
|
import PageWrapper from 'ts/components/Page/wrapper';
|
||||||
|
@ -37,6 +37,8 @@ function AchievementBlock({ title, achievements }: IAchievementBlockProps) {
|
||||||
const Total = observer(({ user }: IPersonCommonProps): React.ReactElement => {
|
const Total = observer(({ user }: IPersonCommonProps): React.ReactElement => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const statistic = user;
|
const statistic = user;
|
||||||
|
const scoringTotal = dataGripStore.dataGrip.scoring.total;
|
||||||
|
const scoring = dataGripStore.dataGrip.scoring.statisticByName[user.author];
|
||||||
const commitsWithGet = dataGripStore.dataGrip.get.getsByAuthor[user.author];
|
const commitsWithGet = dataGripStore.dataGrip.get.getsByAuthor[user.author];
|
||||||
const taskNumber = statistic.tasks.length;
|
const taskNumber = statistic.tasks.length;
|
||||||
const achievements = achievementByAuthor.authors[statistic.author];
|
const achievements = achievementByAuthor.authors[statistic.author];
|
||||||
|
@ -51,24 +53,40 @@ const Total = observer(({ user }: IPersonCommonProps): React.ReactElement => {
|
||||||
icon="./assets/cards/work_days.png"
|
icon="./assets/cards/work_days.png"
|
||||||
title="page.person.total.daysWorked.title"
|
title="page.person.total.daysWorked.title"
|
||||||
description="page.person.total.daysWorked.description"
|
description="page.person.total.daysWorked.description"
|
||||||
|
scoring={{
|
||||||
|
value: scoring.daysWorked,
|
||||||
|
total: scoringTotal.daysWorked,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<CardWithIcon
|
<CardWithIcon
|
||||||
value={taskNumber ? taskNumber : null}
|
value={taskNumber ? taskNumber : null}
|
||||||
icon="./assets/cards/tasks.png"
|
icon="./assets/cards/tasks.png"
|
||||||
title="page.person.total.tasks.title"
|
title="page.person.total.tasks.title"
|
||||||
description="page.person.total.tasks.description"
|
description="page.person.total.tasks.description"
|
||||||
|
scoring={{
|
||||||
|
value: scoring.tasks,
|
||||||
|
total: scoringTotal.tasks,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<CardWithIcon
|
<CardWithIcon
|
||||||
value={statistic.daysLosses}
|
value={statistic.daysLosses}
|
||||||
icon="./assets/cards/lazy.png"
|
icon="./assets/cards/lazy.png"
|
||||||
title="page.team.total.daysLosses.title"
|
title="page.team.total.daysLosses.title"
|
||||||
description="page.team.total.daysLosses.description"
|
description="page.team.total.daysLosses.description"
|
||||||
|
scoring={{
|
||||||
|
value: scoring.daysLosses,
|
||||||
|
total: scoringTotal.daysLosses,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<CardWithIcon
|
<CardWithIcon
|
||||||
value={statistic.commits}
|
value={statistic.commits}
|
||||||
icon="./assets/cards/commits.png"
|
icon="./assets/cards/commits.png"
|
||||||
title="page.team.total.commits.title"
|
title="page.team.total.commits.title"
|
||||||
description="page.team.total.commits.description"
|
description="page.team.total.commits.description"
|
||||||
|
scoring={{
|
||||||
|
value: scoring.commits,
|
||||||
|
total: scoringTotal.commits,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<CardWithBanner long />
|
<CardWithBanner long />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -181,6 +181,7 @@ export default `
|
||||||
§ page.person.total.daysWorked.description: Учтены только дни, в которые делались коммиты
|
§ page.person.total.daysWorked.description: Учтены только дни, в которые делались коммиты
|
||||||
§ page.person.total.tasks.title: задач
|
§ page.person.total.tasks.title: задач
|
||||||
§ page.person.total.tasks.description: Если коммиты правильно подписаны
|
§ page.person.total.tasks.description: Если коммиты правильно подписаны
|
||||||
|
§ page.person.scoring.toolbar: Позиция по этой метрике, относительно других сотрудников
|
||||||
§ page.person.character.title: Персонаж
|
§ page.person.character.title: Персонаж
|
||||||
§ page.person.achievement.title: Достижения
|
§ page.person.achievement.title: Достижения
|
||||||
§ page.person.achievement.positive: Позитивные
|
§ page.person.achievement.positive: Позитивные
|
||||||
|
|
Loading…
Reference in a new issue