mirror of
https://github.com/bakhirev/assayo.git
synced 2024-11-16 08:11:40 +00:00
JIRA-1234 feat(lang): test test test
This commit is contained in:
parent
3d4cb821ac
commit
9f77159b31
|
@ -1,5 +1,6 @@
|
|||
import React, { ReactNode } from 'react';
|
||||
|
||||
import localization from 'ts/helpers/Localization';
|
||||
import style from '../styles/index.module.scss';
|
||||
|
||||
export interface IUiKitWrapperProps {
|
||||
|
@ -25,22 +26,22 @@ function UiKitWrapper({
|
|||
return (
|
||||
<div
|
||||
className={`${style.wrapper} ${className || ''}`}
|
||||
title={help}
|
||||
title={localization.get(help)}
|
||||
>
|
||||
{title && (
|
||||
<h6 className={style.title}>
|
||||
{title}
|
||||
{localization.get(title)}
|
||||
</h6>
|
||||
)}
|
||||
{description && (
|
||||
<p className={style.description}>
|
||||
{description}
|
||||
{localization.get(description)}
|
||||
</p>
|
||||
)}
|
||||
{children}
|
||||
{help && (
|
||||
<p className={style.help}>
|
||||
{example}
|
||||
{localization.get(example)}
|
||||
</p>
|
||||
)}
|
||||
{error && (
|
||||
|
|
|
@ -28,6 +28,16 @@ localization.parse('ru', `
|
|||
§ sidebar.person.changes: Все изменения
|
||||
§ sidebar.person.words: Популярные слова
|
||||
§ sidebar.person.settings: Настройки
|
||||
§ page.welcome.step1: Выполните команду в корне вашего проекта
|
||||
§ page.welcome.step2: Перетащите файл log.txt на эту страницу
|
||||
§ page.welcome.description1: Git создаст файл log.txt. Он содержит данные для построения отчёта. Или git shortlog -s -n -e если отчёт вам не нужен. Создайте файл
|
||||
§ page.welcome.description2: в корне проекта, чтобы обьединить статистику по сотрудникам.
|
||||
§ page.welcome.description: Git создаст файл log.txt. Он содержит данные для построения отчёта. Или git shortlog -s -n -e если отчёт вам не нужен. Создайте файл [.mailmap|https://git-scm.com/docs/gitmailmap] в корне проекта, чтобы обьединить статистику по сотрудникам.
|
||||
§ page.welcome.warning1: Сервис *НЕ ХРАНИТ* и *НЕ ПЕРЕДАЁТ* ваши данные. Все расчёты выполняются локально в вашем браузере прямо на вашей машине.
|
||||
§ page.welcome.warning2: Сервис *НЕ СОБИРАЕТ СТАТИСТИКУ* по проектам. Вы можете отключить интернет, проверить трафик и даже собрать локальный билд из [исходников|https://github.com/bakhirev/assayo].
|
||||
§ page.team.author.title: Статистика по сотрудникам
|
||||
§ page.team.author.description1: *Часть статитики* (скорость работы, затраченные деньги и т.п.) *по сотрудникам с типом «Помошник» не считается*, т.к. это эпизодическая роль в проекте. Предпологаем, что они не влияют на проект, а их правками можно пренебречь на фоне общего объема работы.
|
||||
§ page.team.author.description2: *Сортировка по умолчанию* — это сортировка по количеству задач и группам (текущие, уволенные, помогающие сотрудники).
|
||||
§ page.team.author.types: Тип работ
|
||||
§ page.team.author.commits: Коммитов
|
||||
§ page.team.author.commitsSmall: коммитов
|
||||
|
@ -41,6 +51,9 @@ localization.parse('ru', `
|
|||
§ page.team.author.moneyAll: Получил
|
||||
§ page.team.author.moneyWorked: Отработал
|
||||
§ page.team.author.moneyLosses: Переплата
|
||||
§ page.team.hours.title: Распределение коммитов в течении каждого дня недели
|
||||
§ page.team.month.title: Календарь работы по проекту
|
||||
§ page.team.scope.title: Статистика по фичам
|
||||
§ page.team.scope.scope: Фича
|
||||
§ page.team.scope.days: Раб. дней
|
||||
§ page.team.scope.authorsDays: Человеко-дней
|
||||
|
@ -50,13 +63,18 @@ localization.parse('ru', `
|
|||
§ page.team.scope.types: Тип работ
|
||||
§ page.team.scope.authors: Персональный вклад
|
||||
§ page.team.scope.cost: Стоимость
|
||||
§ page.team.type.title: Статистика по типам задач
|
||||
§ page.team.type.description: *Персональный вклад* считается по количеству коммитов, а не объему измененных строк или файлов. Поэтому следует так же смотреть раздел «Анализ файлов», чтобы оценить масштаб изменений.
|
||||
§ page.team.type.type: Тип работы
|
||||
§ page.team.type.tasks: Задач
|
||||
§ page.team.type.tasksSmall: задач
|
||||
§ page.team.type.days: Дней
|
||||
§ page.team.type.daysSmall: дней
|
||||
§ page.team.type.authorsDays: Человеко-дней
|
||||
§ page.team.type.commits: Коммитов
|
||||
§ page.team.type.commitsSmall: коммитов
|
||||
§ page.team.type.authors: Персональный вклад
|
||||
§ page.team.total.titleA: Объём работ
|
||||
§ page.team.total.titleB: Стоимость
|
||||
§ page.team.total.daysWorked.title: человеко-дней
|
||||
§ page.team.total.daysWorked.description: Учтены только дни, в которые делались коммиты
|
||||
§ page.team.total.commits.title: коммитов
|
||||
|
@ -77,12 +95,16 @@ localization.parse('ru', `
|
|||
§ page.team.total.workSpeed.description: Средняя скорость работы команды при текущем составе сотрудников
|
||||
§ page.team.total.moneySpeed.title: в месяц
|
||||
§ page.team.total.moneySpeed.description: Прогнозируемая сумма выплаты на зп при текущем составе сотрудников без учета налогов и сопутствующих затрат
|
||||
§ page.team.total.titleA: Объём работ
|
||||
§ page.team.total.titleB: Стоимость
|
||||
§ page.team.tree.filters1: Пользователь
|
||||
§ page.team.tree.filters2: и более
|
||||
§ page.team.tree.filters3: коммитов в файле или папке
|
||||
§ page.team.tree.percent: Процент перезаписи
|
||||
§ page.team.total.description1: *Человеко-дни* — это работа одного сотрудника в течение одного рабочего дня. Например, за один календарный день, команда из трех сотрудников выдает объем работы в три человеко-дня.
|
||||
§ page.team.total.description2: *Днями прогулов* считаются только рабочие дни, когда коммиты могли бы быть сделаны. Выходные, государственные праздники и отпуска в расчёте не участвуют.
|
||||
§ page.team.total.description3: Карточка *работает и уволилось* показывает фактический состав сотрудников, которые постоянно участвуют в работе. Кроме этого, есть «помощники» — это сотрудники, как правило другой специализации, которые могут иногда делать коммиты в проект.
|
||||
§ page.team.total.description4: *Переплатой* считаются только рабочие дни, когда коммиты могли бы быть сделаны. Выходные, государственные праздники и отпуска в расчёте не участвуют. Именно поэтому переплата + фактическая стоимость != общей. В общей стоимости заложена оплата выходных, государственных праздников и отпусков.
|
||||
§ page.team.total.description5: *Работой на выходных* считается по коэфициенту х2 от оплаты обычного дня. Выше отображена именно переплата (х1), т.к. сам факт переработки в данном контексте не интересен. Мы не смотрим скорость сжигания бюджета. Мы смотрим переплату при увеличении скорости работы.
|
||||
§ page.team.tree.title: Дерево проекта с учётом выбранных фильтров
|
||||
§ page.team.tree.filters.author: Сотрудник
|
||||
§ page.team.tree.filters.commits: Количество коммитов
|
||||
§ page.team.tree.filters.help: Минимальное количество коммитов, которое сделал сотрудник в файле
|
||||
§ page.team.tree.filters.all: Все сотрудники
|
||||
§ page.team.tree.add: Кто добавлял
|
||||
§ page.team.tree.change: Кто менял
|
||||
§ page.team.tree.remove: Кто удалял
|
||||
|
|
|
@ -8,7 +8,6 @@ import SplashScreen from 'ts/components/SplashScreen';
|
|||
import Confirm from 'ts/components/ModalWindow/Confirm';
|
||||
|
||||
import PageWrapper from '../../PageWrapper';
|
||||
// import Main from '../../Main/index';
|
||||
import Team from '../../Team/index';
|
||||
import Person from '../../Person/index';
|
||||
import Welcome from '../../Welcome/index';
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
import React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import UiKitButton from 'ts/components/UiKit/components/Button';
|
||||
import localization from 'ts/helpers/Localization';
|
||||
|
||||
import style from '../styles/card.module.scss';
|
||||
|
||||
interface ICardProps {
|
||||
icon: string;
|
||||
title: string;
|
||||
description: string;
|
||||
link: string;
|
||||
}
|
||||
|
||||
function Card({
|
||||
icon,
|
||||
title,
|
||||
description,
|
||||
link,
|
||||
}: ICardProps): React.ReactElement | null {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<figure className={style.card}>
|
||||
<h4 className={style.card_title}>
|
||||
{localization.get(title)}
|
||||
</h4>
|
||||
<img
|
||||
className={style.card_icon}
|
||||
src={icon}
|
||||
/>
|
||||
<figcaption className={style.card_description}>
|
||||
{localization.get(description)}
|
||||
</figcaption>
|
||||
<UiKitButton
|
||||
className={style.card_button}
|
||||
onClick={() => {
|
||||
navigate(link);
|
||||
}}
|
||||
>
|
||||
Перейти в отчёт
|
||||
</UiKitButton>
|
||||
</figure>
|
||||
);
|
||||
}
|
||||
|
||||
export default Card;
|
|
@ -1,31 +0,0 @@
|
|||
import React from 'react';
|
||||
|
||||
import Card from './components/Card';
|
||||
|
||||
import style from './styles/index.module.scss';
|
||||
|
||||
function Main() {
|
||||
return (
|
||||
<section className={style.main}>
|
||||
<h2 className={style.main_title}>
|
||||
Выберите раздел аналити
|
||||
</h2>
|
||||
<div className={style.main_cards}>
|
||||
<Card
|
||||
icon="./assets/cards/money_lazy.png"
|
||||
title="Команда"
|
||||
description="Собраны метрики работы команды в целом, сумарные финансовые показатели, рекомендации для менеджера проекта."
|
||||
link="/team/total"
|
||||
/>
|
||||
<Card
|
||||
icon="./assets/cards/money_lazy.png"
|
||||
title="Сотрудник"
|
||||
description="Данные по каждому сотруднику отдельно. Личные достижения, характеристики, показатели работоспособности."
|
||||
link="/person/total/0"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export default Main;
|
|
@ -1,86 +0,0 @@
|
|||
@import '../../../../styles/variables';
|
||||
|
||||
.card {
|
||||
display: inline-block;
|
||||
width: 300px;
|
||||
min-height: 270px;
|
||||
margin: 0 24px 24px 0;
|
||||
padding: 16px;
|
||||
vertical-align: top;
|
||||
box-sizing: border-box;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--color-border);
|
||||
background-color: #FFFFFF;
|
||||
|
||||
&_icon {
|
||||
display: block;
|
||||
width: auto;
|
||||
height: 90px;
|
||||
margin: 16px auto;
|
||||
box-sizing: border-box;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
&_title,
|
||||
&_description {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
line-height: 1.3;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: var(--color-black);
|
||||
}
|
||||
|
||||
&_title {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
color: var(--color-11);
|
||||
}
|
||||
|
||||
&_description {
|
||||
font-size: var(--font-xs);
|
||||
font-weight: 100;
|
||||
line-height: 16px;
|
||||
color: var(--color-grey);
|
||||
}
|
||||
|
||||
&_button {
|
||||
padding: 0 16px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.card {
|
||||
min-height: 220px;
|
||||
padding: 16px 0;
|
||||
|
||||
&_title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&_description {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 650px) {
|
||||
.card {
|
||||
min-height: auto;
|
||||
padding: 32px 0;
|
||||
|
||||
&_value {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
&_title {
|
||||
font-size: var(--font-s);
|
||||
}
|
||||
|
||||
&_icon {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
@import '../../../../styles/variables';
|
||||
|
||||
.main {
|
||||
display: grid;
|
||||
grid-template-areas: 'header' 'main';
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 66px 1fr;
|
||||
min-height: 100vh;
|
||||
background-color: #F5F7F9;
|
||||
|
||||
&_title {
|
||||
grid-area: header;
|
||||
font-size: var(--font-l);
|
||||
line-height: var(--font-l);
|
||||
|
||||
font-weight: 100;
|
||||
display: block;
|
||||
padding: 24px;
|
||||
margin: 0;
|
||||
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
color: #84858D;
|
||||
background-color: #252735;
|
||||
}
|
||||
|
||||
&_cards {
|
||||
grid-area: main;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
min-height: calc(100vh - 60px);
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
}
|
|
@ -162,7 +162,7 @@ const Author = observer(({
|
|||
{mode !== 'print' && (
|
||||
<RecommendationsWrapper recommendations={recommendations} />
|
||||
)}
|
||||
<Title title="Статистика по сотрудникам"/>
|
||||
<Title title="page.team.author.title"/>
|
||||
<PageWrapper template="table">
|
||||
<DataLoader
|
||||
to="response"
|
||||
|
@ -177,12 +177,12 @@ const Author = observer(({
|
|||
<PageWrapper>
|
||||
<PageColumn>
|
||||
<Description
|
||||
text="*Часть статитики* (скорость работы, затраченные деньги и т.п.) *по сотрудникам с типом «Помошник» не считается*, т.к. это эпизодическая роль в проекте. Предпологаем, что они не влияют на проект, а их правками можно пренебречь на фоне общего объема работы."
|
||||
text={localization.get('page.team.author.description1')}
|
||||
/>
|
||||
</PageColumn>
|
||||
<PageColumn>
|
||||
<Description
|
||||
text="*Сортировка по умолчанию* — это сортировка по количеству задач и группам (текущие, уволенные, помогающие сотрудники)."
|
||||
text={localization.get('page.team.author.description2')}
|
||||
/>
|
||||
</PageColumn>
|
||||
</PageWrapper>
|
||||
|
|
|
@ -16,7 +16,7 @@ const Hours = observer((): React.ReactElement => {
|
|||
return (
|
||||
<>
|
||||
<RecommendationsWrapper recommendations={recommendations} />
|
||||
<Title title="Распределение коммитов в течении каждого дня недели"/>
|
||||
<Title title="page.team.hours.title"/>
|
||||
<PageWrapper template="table">
|
||||
<HoursChart statistic={statistic} />
|
||||
</PageWrapper>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React from 'react';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
import localization from 'ts/helpers/Localization';
|
||||
import dataGripStore from 'ts/store/DataGrip';
|
||||
|
||||
import RecommendationsWrapper from 'ts/components/Recommendations/wrapper';
|
||||
|
@ -24,7 +23,7 @@ const Month = observer(({
|
|||
{mode !== 'print' && (
|
||||
<RecommendationsWrapper recommendations={recommendations}/>
|
||||
)}
|
||||
<Title title={localization.get('Календарь работы по проекту')}/>
|
||||
<Title title="page.team.month.title"/>
|
||||
<PageWrapper template="table">
|
||||
<YearChart
|
||||
maxCommits={max}
|
||||
|
|
|
@ -116,7 +116,7 @@ const Scope = observer(({
|
|||
{mode !== 'print' && (
|
||||
<RecommendationsWrapper recommendations={recommendations} />
|
||||
)}
|
||||
<Title title="Статистика по фичам"/>
|
||||
<Title title="page.team.scope.title"/>
|
||||
<PageWrapper template="table">
|
||||
<DataLoader
|
||||
to="response"
|
||||
|
|
|
@ -4,7 +4,6 @@ import { observer } from 'mobx-react-lite';
|
|||
import { IPagination } from 'ts/interfaces/Pagination';
|
||||
import dataGripStore from 'ts/store/DataGrip';
|
||||
import { getShortDateRange } from 'ts/helpers/formatter';
|
||||
import localization from 'ts/helpers/Localization';
|
||||
|
||||
import UiKitButton from 'ts/components/UiKit/components/Button';
|
||||
import UiKitSelect from 'ts/components/UiKit/components/Select';
|
||||
|
@ -60,7 +59,7 @@ const Tempo = observer((): React.ReactElement => {
|
|||
if (!partOfData?.length) return (<NothingFound />);
|
||||
return (
|
||||
<>
|
||||
<Title title={localization.get('common.filters')} />
|
||||
<Title title="common.filters" />
|
||||
<PageWrapper>
|
||||
<div className={style.tempo_page_filters}>
|
||||
<UiKitButton
|
||||
|
|
|
@ -26,7 +26,7 @@ const Total = observer((): React.ReactElement => {
|
|||
return (
|
||||
<PageWrapper>
|
||||
<PageColumn>
|
||||
<Title title={localization.get('page.team.total.titleA')}/>
|
||||
<Title title="page.team.total.titleA"/>
|
||||
<div>
|
||||
<CardWithIcon
|
||||
value={statistic.daysWorked}
|
||||
|
@ -61,17 +61,17 @@ const Total = observer((): React.ReactElement => {
|
|||
/>
|
||||
</div>
|
||||
<Description
|
||||
text="*Человеко-дни* — это работа одного сотрудника в течение одного рабочего дня. Например, за один календарный день, команда из трех сотрудников выдает объем работы в три человеко-дня."
|
||||
text={localization.get('page.team.total.description1')}
|
||||
/>
|
||||
<Description
|
||||
text="*Днями прогулов* считаются только рабочие дни, когда коммиты могли бы быть сделаны. Выходные, государственные праздники и отпуска в расчёте не участвуют."
|
||||
text={localization.get('page.team.total.description2')}
|
||||
/>
|
||||
<Description
|
||||
text="Карточка *работает и уволилось* показывает фактический состав сотрудников, которые постоянно участвуют в работе. Кроме этого, есть «помощники» — это сотрудники, как правило другой специализации, которые могут иногда делать коммиты в проект."
|
||||
text={localization.get('page.team.total.description3')}
|
||||
/>
|
||||
</PageColumn>
|
||||
<PageColumn>
|
||||
<Title title={localization.get('page.team.total.titleB')}/>
|
||||
<Title title="page.team.total.titleB"/>
|
||||
<div>
|
||||
<CardWithIcon
|
||||
value={getShortMoney(statistic.moneyAll)}
|
||||
|
@ -106,10 +106,10 @@ const Total = observer((): React.ReactElement => {
|
|||
/>
|
||||
</div>
|
||||
<Description
|
||||
text="*Переплатой* считаются только рабочие дни, когда коммиты могли бы быть сделаны. Выходные, государственные праздники и отпуска в расчёте не участвуют. Именно поэтому переплата + фактическая стоимость != общей. В общей стоимости заложена оплата выходных, государственных праздников и отпусков."
|
||||
text={localization.get('page.team.total.description4')}
|
||||
/>
|
||||
<Description
|
||||
text="*Работой на выходных* считается по коэфициенту х2 от оплаты обычного дня. Выше отображена именно переплата (х1), т.к. сам факт переработки в данном контексте не интересен. Мы не смотрим скорость сжигания бюджета. Мы смотрим переплату при увеличении скорости работы."
|
||||
text={localization.get('page.team.total.description5')}
|
||||
/>
|
||||
</PageColumn>
|
||||
</PageWrapper>
|
||||
|
|
|
@ -37,7 +37,10 @@ function TreeView({ response }: ITreeViewProps) {
|
|||
};
|
||||
|
||||
const fileChart = getOptions({ order: dataGripStore.dataGrip.author.list, suffix: 'строк' });
|
||||
const rewriteChart = getOptions({ order: ['добавили', 'изменили'], suffix: 'строк' });
|
||||
const rewriteChart = getOptions({ order: [
|
||||
'page.team.tree.lineAdd',
|
||||
'page.team.tree.lineRemove',
|
||||
], suffix: 'page.team.tree.line' });
|
||||
|
||||
return (
|
||||
<Table
|
||||
|
@ -69,14 +72,14 @@ function TreeView({ response }: ITreeViewProps) {
|
|||
value={file ? 100 : 0}
|
||||
options={rewriteChart}
|
||||
details={{
|
||||
'добавили': file?.lines || 0,
|
||||
'изменили': (file?.total?.changes || 0) + (file?.total?.removed || 0),
|
||||
'page.team.tree.lineAdd': file?.lines || 0,
|
||||
'page.team.tree.lineRemove': (file?.total?.changes || 0) + (file?.total?.removed || 0),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Column
|
||||
title="Кто добавлял"
|
||||
title="page.team.tree.add"
|
||||
properties="file"
|
||||
minWidth={200}
|
||||
template={(file: any) => (
|
||||
|
@ -88,7 +91,7 @@ function TreeView({ response }: ITreeViewProps) {
|
|||
)}
|
||||
/>
|
||||
<Column
|
||||
title="Кто менял"
|
||||
title="page.team.tree.change"
|
||||
properties="file"
|
||||
minWidth={200}
|
||||
template={(file: any) => (
|
||||
|
@ -100,7 +103,7 @@ function TreeView({ response }: ITreeViewProps) {
|
|||
)}
|
||||
/>
|
||||
<Column
|
||||
title="Кто удалял"
|
||||
title="page.team.tree.remove"
|
||||
properties="file"
|
||||
minWidth={200}
|
||||
template={(file: any) => (
|
||||
|
@ -128,7 +131,7 @@ const Tree = observer((): React.ReactElement => {
|
|||
<>
|
||||
<Title title={localization.get('common.filters')} />
|
||||
<TreeFilters/>
|
||||
<Title title="Дерево проекта с учётом выбранных фильтров"/>
|
||||
<Title title="page.team.tree.title"/>
|
||||
<PageWrapper template="table">
|
||||
<DataLoader
|
||||
to="response"
|
||||
|
|
|
@ -4,6 +4,7 @@ import { observer } from 'mobx-react-lite';
|
|||
import dataGripStore from 'ts/store/DataGrip';
|
||||
import UiKitSelect from 'ts/components/UiKit/components/SelectWithButtons';
|
||||
import UiKitInputNumber from 'ts/components/UiKit/components/InputNumber';
|
||||
import localization from 'ts/helpers/Localization';
|
||||
|
||||
import treeStore from '../store/Tree';
|
||||
import style from '../styles/filters.module.scss';
|
||||
|
@ -11,12 +12,12 @@ import style from '../styles/filters.module.scss';
|
|||
const TreeFilters = observer((): React.ReactElement => {
|
||||
const authors = dataGripStore.dataGrip.author.list;
|
||||
const options = authors.map((title: string, id: number) => ({ id: id + 1, title }));
|
||||
options.unshift({ id: 0, title: 'Все сотрудники' });
|
||||
options.unshift({ id: 0, title: localization.get('page.team.tree.filters.all') });
|
||||
|
||||
return (
|
||||
<>
|
||||
<UiKitSelect
|
||||
title="Сотрудник"
|
||||
title="page.team.tree.filters.author"
|
||||
value={treeStore.authorId}
|
||||
options={options}
|
||||
className={style.filter}
|
||||
|
@ -25,8 +26,8 @@ const TreeFilters = observer((): React.ReactElement => {
|
|||
}}
|
||||
/>
|
||||
<UiKitInputNumber
|
||||
title="Количество коммитов"
|
||||
help="Минимальное количество коммитов, которое сделал сотрудник в файле"
|
||||
title="page.team.tree.filters.commits"
|
||||
help="page.team.tree.filters.help"
|
||||
value={treeStore.minCommits}
|
||||
className={style.filter}
|
||||
onChange={(minCommits: number) => {
|
||||
|
|
|
@ -22,6 +22,7 @@ import RecommendationsWrapper from 'ts/components/Recommendations/wrapper';
|
|||
import Description from 'ts/components/Description';
|
||||
|
||||
import { getMax } from 'ts/pages/Common/helpers/getMax';
|
||||
import localization from 'ts/helpers/Localization';
|
||||
|
||||
interface ITypeViewProps {
|
||||
response?: IPagination<any>;
|
||||
|
@ -31,8 +32,8 @@ interface ITypeViewProps {
|
|||
function TypeView({ response, updateSort }: ITypeViewProps) {
|
||||
if (!response) return null;
|
||||
|
||||
const taskChart = getOptions({ max: getMax(response, 'tasks'), suffix: 'задач' });
|
||||
const daysByAuthorsChart = getOptions({ max: getMax(response, 'daysByAuthorsTotal'), suffix: 'дней' });
|
||||
const taskChart = getOptions({ max: getMax(response, 'tasks'), suffix: 'page.team.type.tasksSmall' });
|
||||
const daysByAuthorsChart = getOptions({ max: getMax(response, 'daysByAuthorsTotal'), suffix: 'page.team.type.daysSmall' });
|
||||
const authorChart = getOptions({ order: dataGripStore.dataGrip.author.list });
|
||||
|
||||
return (
|
||||
|
@ -121,7 +122,7 @@ const Type = observer(({
|
|||
{mode !== 'print' && (
|
||||
<RecommendationsWrapper recommendations={recommendations} />
|
||||
)}
|
||||
<Title title="Статистика по типам задач"/>
|
||||
<Title title="page.team.type.title"/>
|
||||
<PageWrapper template="table">
|
||||
<DataLoader
|
||||
to="response"
|
||||
|
@ -135,7 +136,7 @@ const Type = observer(({
|
|||
</PageWrapper>
|
||||
<PageWrapper>
|
||||
<Description
|
||||
text="*Персональный вклад* считается по количеству коммитов, а не объему измененных строк или файлов. Поэтому следует так же смотреть раздел «Анализ файлов», чтобы оценить масштаб изменений."
|
||||
text={localization.get('page.team.type.description')}
|
||||
/>
|
||||
</PageWrapper>
|
||||
</>
|
||||
|
|
|
@ -2,6 +2,8 @@ import React from 'react';
|
|||
import { Link } from 'react-router-dom';
|
||||
|
||||
import Console from 'ts/components/Console';
|
||||
import localization from 'ts/helpers/Localization';
|
||||
|
||||
import style from './styles/index.module.scss';
|
||||
|
||||
function WarningInfo() {
|
||||
|
@ -33,34 +35,32 @@ function WarningInfo() {
|
|||
}
|
||||
|
||||
function Welcome() {
|
||||
const canShowWarning = true;
|
||||
const command = 'git --no-pager log --numstat --oneline --all --reverse --date=iso-strict --pretty=format:"%ad>%cN>%cE>%s" > log.txt\n';
|
||||
return (
|
||||
<>
|
||||
{true && (<WarningInfo />)}
|
||||
{canShowWarning && (<WarningInfo />)}
|
||||
<section className={style.welcome}>
|
||||
<div className={style.welcome_row}>
|
||||
<h2 className={style.welcome_first_title}>
|
||||
Выполните команду в корне вашего проекта
|
||||
{localization.get('page.welcome.step1')}
|
||||
</h2>
|
||||
<Console
|
||||
className={style.welcome_console}
|
||||
textForCopy={command}
|
||||
/>
|
||||
<p className={style.welcome_description}>
|
||||
Git создаст файл log.txt.
|
||||
Он содержит данные для построения отчёта.
|
||||
Или git shortlog -s -n -e если отчёт вам не нужен.
|
||||
Создайте файл
|
||||
{localization.get('page.welcome.description1')}
|
||||
<Link
|
||||
className={`${style.welcome_link}`}
|
||||
target="_blank"
|
||||
to="https://git-scm.com/docs/gitmailmap">
|
||||
.mailmap
|
||||
</Link>
|
||||
{' в корне проекта, чтобы обьединить статистику по сотрудникам.'}
|
||||
{localization.get('page.welcome.description2')}
|
||||
</p>
|
||||
<h2 className={style.welcome_last_title}>
|
||||
Перетащите файл log.txt на эту страницу
|
||||
{localization.get('page.welcome.step2')}
|
||||
</h2>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
|
||||
&_link {
|
||||
display: inline;
|
||||
margin: 16px 0 0 4px;
|
||||
margin: 16px 4px 0 4px;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue