mirror of
https://github.com/bakhirev/assayo.git
synced 2025-09-04 11:40:10 +00:00
update
This commit is contained in:
parent
9bd2675129
commit
88452159ae
42 changed files with 634 additions and 412 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -77,7 +77,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&_body {
|
&_body {
|
||||||
max-height: calc(60vh - 200px);
|
max-height: calc(100vh - 200px);
|
||||||
padding: 0 24px;
|
padding: 0 24px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next';
|
||||||
import Description from 'ts/components/Description';
|
import Description from 'ts/components/Description';
|
||||||
import UiKitButton from 'ts/components/UiKit/components/Button';
|
import UiKitButton from 'ts/components/UiKit/components/Button';
|
||||||
import localization from 'ts/helpers/Localization';
|
import localization from 'ts/helpers/Localization';
|
||||||
import RECOMMENDATION_TYPES from 'ts/helpers/Recommendations/contstants';
|
import { RECOMMENDATION_TYPES } from 'ts/helpers/Recommendations/helpers/contstants';
|
||||||
import isMobile from 'ts/helpers/isMobile';
|
import isMobile from 'ts/helpers/isMobile';
|
||||||
|
|
||||||
import { getFormattedTitle, getDescriptionText } from '../helpers';
|
import { getFormattedTitle, getDescriptionText } from '../helpers';
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||||
|
|
||||||
import Description from 'ts/components/Description';
|
import Description from 'ts/components/Description';
|
||||||
import localization from 'ts/helpers/Localization';
|
import localization from 'ts/helpers/Localization';
|
||||||
import RECOMMENDATION_TYPES from 'ts/helpers/Recommendations/contstants';
|
import { RECOMMENDATION_TYPES } from 'ts/helpers/Recommendations/helpers/contstants';
|
||||||
|
|
||||||
import { getFormattedTitle, getDescriptionText } from '../helpers';
|
import { getFormattedTitle, getDescriptionText } from '../helpers';
|
||||||
import style from '../styles/card.module.scss';
|
import style from '../styles/card.module.scss';
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { observer } from 'mobx-react-lite';
|
||||||
import UiKitButton from 'ts/components/UiKit/components/Button';
|
import UiKitButton from 'ts/components/UiKit/components/Button';
|
||||||
import { Modal, Header, Body, Footer } from 'ts/components/ModalWindow';
|
import { Modal, Header, Body, Footer } from 'ts/components/ModalWindow';
|
||||||
import Description from 'ts/components/Description';
|
import Description from 'ts/components/Description';
|
||||||
import RECOMMENDATION_TYPES from 'ts/helpers/Recommendations/contstants';
|
import { RECOMMENDATION_TYPES } from 'ts/helpers/Recommendations/helpers/contstants';
|
||||||
import localization from 'ts/helpers/Localization';
|
import localization from 'ts/helpers/Localization';
|
||||||
|
|
||||||
import { getFormattedTitle, getDescriptionText } from '../helpers';
|
import { getFormattedTitle, getDescriptionText } from '../helpers';
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
import { getDateByTimestamp } from 'ts/helpers/formatter';
|
import { getDateByTimestamp } from 'ts/helpers/formatter';
|
||||||
import RECOMMENDATION_TYPES from '../contstants';
|
import { getBuilder } from '../helpers';
|
||||||
|
|
||||||
|
const {
|
||||||
|
getArgTitle,
|
||||||
|
getTitleArgDescription,
|
||||||
|
} = getBuilder('timestamp');
|
||||||
|
|
||||||
export default class RecommendationsPersonByTimestamp {
|
export default class RecommendationsPersonByTimestamp {
|
||||||
getTotalInfo(dataGrip: any) {
|
getTotalInfo(dataGrip: any) {
|
||||||
|
@ -10,35 +15,14 @@ export default class RecommendationsPersonByTimestamp {
|
||||||
acc[name] = [];
|
acc[name] = [];
|
||||||
|
|
||||||
if (workInWeek) {
|
if (workInWeek) {
|
||||||
acc[name].push({
|
acc[name].push(getArgTitle('weekendDays', [workInWeek]));
|
||||||
title: 'recommendations.timestamp.common.title',
|
|
||||||
description: 'recommendations.timestamp.weekendDays.description',
|
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
|
||||||
arguments: {
|
|
||||||
title: [workInWeek],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (byAuthor.daysLosses) {
|
if (byAuthor.daysLosses) {
|
||||||
acc[name].push({
|
acc[name].push(getArgTitle('lossesDays', [byAuthor.daysLosses]));
|
||||||
title: 'recommendations.timestamp.common.title',
|
|
||||||
description: 'recommendations.timestamp.lossesDays.description',
|
|
||||||
type: RECOMMENDATION_TYPES.WARNING,
|
|
||||||
arguments: {
|
|
||||||
title: [byAuthor.daysLosses],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
acc[name].push({
|
acc[name].push(getArgTitle('allDays', [byAuthor.daysAll]));
|
||||||
title: 'recommendations.timestamp.common.title',
|
|
||||||
description: 'recommendations.timestamp.allDays.description',
|
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
arguments: {
|
|
||||||
title: [byAuthor.daysAll],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
acc[name].push(this.getFirstDay(byTimestamp));
|
acc[name].push(this.getFirstDay(byTimestamp));
|
||||||
|
|
||||||
|
@ -51,28 +35,12 @@ export default class RecommendationsPersonByTimestamp {
|
||||||
getFirstDay(byTimestamp: any) {
|
getFirstDay(byTimestamp: any) {
|
||||||
const commit = byTimestamp.allCommitsByTimestamp[0];
|
const commit = byTimestamp.allCommitsByTimestamp[0];
|
||||||
const [date, day] = getDateByTimestamp(commit.timestamp);
|
const [date, day] = getDateByTimestamp(commit.timestamp);
|
||||||
return {
|
return getTitleArgDescription('firstCommit', date, [day]);
|
||||||
title: date,
|
|
||||||
description: 'recommendations.timestamp.firstCommit.description',
|
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
arguments: {
|
|
||||||
description: [day],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getLastDay(byTimestamp: any) {
|
getLastDay(byTimestamp: any) {
|
||||||
const commit = byTimestamp.allCommitsByTimestamp[(byTimestamp.allCommitsByTimestamp.length - 1)];
|
const commit = byTimestamp.allCommitsByTimestamp[(byTimestamp.allCommitsByTimestamp.length - 1)];
|
||||||
const [date, day] = getDateByTimestamp(commit.timestamp);
|
const [date, day] = getDateByTimestamp(commit.timestamp);
|
||||||
return {
|
return getTitleArgDescription('lastCommit', date, [day]);
|
||||||
title: date,
|
|
||||||
description: 'recommendations.timestamp.lastCommit.description',
|
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
arguments: {
|
|
||||||
description: [day],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import RECOMMENDATION_TYPES from '../contstants';
|
import { getBuilder } from '../helpers';
|
||||||
|
|
||||||
|
const { getItem } = getBuilder('week');
|
||||||
|
|
||||||
export default class RecommendationsPersonByWeek {
|
export default class RecommendationsPersonByWeek {
|
||||||
getTotalInfo(dataGrip: any) {
|
getTotalInfo(dataGrip: any) {
|
||||||
|
@ -16,63 +18,39 @@ export default class RecommendationsPersonByWeek {
|
||||||
|
|
||||||
getLazyDays(lastWeeks: any[], name: string) {
|
getLazyDays(lastWeeks: any[], name: string) {
|
||||||
const lazyDays = lastWeeks.map(statistic => statistic.lazyDays[name]);
|
const lazyDays = lastWeeks.map(statistic => statistic.lazyDays[name]);
|
||||||
|
if (lazyDays[0] < lazyDays[1] && lazyDays[1] < lazyDays[2]) {
|
||||||
if (lazyDays[0] < lazyDays[1] && lazyDays[1] < lazyDays[2]) return {
|
return getItem('lazyDaysDown');
|
||||||
title: 'recommendations.week.lazyDays.down.title',
|
}
|
||||||
description: 'recommendations.week.lazyDays.down.description',
|
if (lazyDays[0] > lazyDays[1] && lazyDays[1] > lazyDays[2]) {
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
return getItem('lazyDaysUp');
|
||||||
};
|
}
|
||||||
|
|
||||||
if (lazyDays[0] > lazyDays[1] && lazyDays[1] > lazyDays[2]) return {
|
|
||||||
title: 'recommendations.week.lazyDays.up.title',
|
|
||||||
description: 'recommendations.week.lazyDays.up.description',
|
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
|
||||||
};
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getNotWork(lastWeeks: any[], name: string) {
|
getNotWork(lastWeeks: any[], name: string) {
|
||||||
const lazyDays = lastWeeks.map(statistic => statistic.lazyDays[name]);
|
const lazyDays = lastWeeks.map(statistic => statistic.lazyDays[name]);
|
||||||
|
if (lazyDays[0] && lazyDays[1] && lazyDays[2]) {
|
||||||
if (lazyDays[0] && lazyDays[1] && lazyDays[2]) return {
|
return getItem('notWork');
|
||||||
title: 'recommendations.week.notWork.title',
|
}
|
||||||
description: 'recommendations.week.notWork.description',
|
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
|
||||||
};
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getUpWork(lastWeeks: any[], name: string) {
|
getUpWork(lastWeeks: any[], name: string) {
|
||||||
const weekDays = lastWeeks.map(statistic => statistic.weekDays[name]);
|
const weekDays = lastWeeks.map(statistic => statistic.weekDays[name]);
|
||||||
|
if (weekDays[0] && weekDays[1] && weekDays[2]) {
|
||||||
if (weekDays[0] && weekDays[1] && weekDays[2]) return {
|
return getItem('upWork');
|
||||||
title: 'recommendations.week.upWork.title',
|
}
|
||||||
description: 'recommendations.week.upWork.description',
|
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
|
||||||
};
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTasks(lastWeeks: any[], name: string) { // TODO: спорно, это видно по количеству изменений
|
getTasks(lastWeeks: any[], name: string) { // TODO: спорно, это видно по количеству изменений
|
||||||
const lazyDays = lastWeeks.map(statistic => statistic.taskInDay[name]);
|
const lazyDays = lastWeeks.map(statistic => statistic.taskInDay[name]);
|
||||||
|
if (lazyDays[0] < lazyDays[1] && lazyDays[1] < lazyDays[2]) {
|
||||||
if (lazyDays[0] < lazyDays[1] && lazyDays[1] < lazyDays[2]) return {
|
return getItem('taskUp');
|
||||||
title: 'recommendations.week.task.up.title',
|
}
|
||||||
description: 'recommendations.week.task.up.description',
|
if (lazyDays[0] > lazyDays[1] && lazyDays[1] > lazyDays[2]) {
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
return getItem('taskDown');
|
||||||
};
|
}
|
||||||
|
|
||||||
if (lazyDays[0] > lazyDays[1] && lazyDays[1] > lazyDays[2]) return {
|
|
||||||
title: 'recommendations.week.task.down.title',
|
|
||||||
description: 'recommendations.week.task.down.description',
|
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
|
||||||
};
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
import RECOMMENDATION_TYPES from '../contstants';
|
import { getBuilder } from '../helpers';
|
||||||
|
|
||||||
|
const {
|
||||||
|
getItem,
|
||||||
|
getTitle,
|
||||||
|
getArgTitleDescription,
|
||||||
|
} = getBuilder('author');
|
||||||
|
|
||||||
export default class RecommendationsTeamByAuthor {
|
export default class RecommendationsTeamByAuthor {
|
||||||
getTotalInfo(dataGrip: any) {
|
getTotalInfo(dataGrip: any) {
|
||||||
|
@ -41,106 +47,27 @@ export default class RecommendationsTeamByAuthor {
|
||||||
return [
|
return [
|
||||||
projectType,
|
projectType,
|
||||||
|
|
||||||
(lotOfLazy.length ? {
|
(lotOfLazy.length ? getArgTitleDescription('lotOfLazy', lotOfLazy.length, lotOfLazy.join(';\n- ')) : null),
|
||||||
title: 'recommendations.author.lotOfLazy.title',
|
(manyLazy.length ? getArgTitleDescription('manyLazy', manyLazy.length, manyLazy.join(';\n- ')) : null),
|
||||||
description: 'recommendations.author.lotOfLazy.description',
|
(oneTypeMans.length ? getTitle('oneTypeMans', oneTypeMans) : null),
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
(worker.length ? getArgTitleDescription('workToday', worker.length, worker.join(';\n- ')) : null),
|
||||||
arguments: {
|
(dismissed.length ? getArgTitleDescription('dismissed', dismissed.length, dismissed.join(';\n- ')) : null),
|
||||||
title: lotOfLazy.length,
|
(staff.length ? getArgTitleDescription('staff', staff.length, staff.join(';\n- ')) : null),
|
||||||
description: lotOfLazy.join(';\n- '),
|
|
||||||
},
|
|
||||||
} : null),
|
|
||||||
|
|
||||||
(manyLazy.length ? {
|
|
||||||
title: 'recommendations.author.manyLazy.title',
|
|
||||||
description: 'recommendations.author.manyLazy.description',
|
|
||||||
type: RECOMMENDATION_TYPES.WARNING,
|
|
||||||
arguments: {
|
|
||||||
title: manyLazy.length,
|
|
||||||
description: manyLazy.join(';\n- '),
|
|
||||||
},
|
|
||||||
} : null),
|
|
||||||
|
|
||||||
(oneTypeMans.length ? {
|
|
||||||
title: oneTypeMans,
|
|
||||||
description: 'recommendations.author.oneTypeMans',
|
|
||||||
type: RECOMMENDATION_TYPES.WARNING,
|
|
||||||
} : null),
|
|
||||||
|
|
||||||
(worker.length ? {
|
|
||||||
title: 'recommendations.author.workToday.title',
|
|
||||||
description: 'recommendations.author.workToday.description',
|
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
arguments: {
|
|
||||||
title: worker.length,
|
|
||||||
description: worker.join(';\n- '),
|
|
||||||
},
|
|
||||||
} : null),
|
|
||||||
|
|
||||||
(dismissed.length ? {
|
|
||||||
title: 'recommendations.author.dismissed.title',
|
|
||||||
description: 'recommendations.author.dismissed.description',
|
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
arguments: {
|
|
||||||
title: dismissed.length,
|
|
||||||
description: dismissed.join(';\n- '),
|
|
||||||
},
|
|
||||||
} : null),
|
|
||||||
|
|
||||||
(staff.length ? {
|
|
||||||
title: 'recommendations.author.staff.title',
|
|
||||||
description: 'recommendations.author.staff.description',
|
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
arguments: {
|
|
||||||
title: staff.length,
|
|
||||||
description: staff.join(';\n- '),
|
|
||||||
},
|
|
||||||
} : null),
|
|
||||||
|
|
||||||
// ['Планирование', 'Задачи распределены довольно равномерно', 'info'],
|
// ['Планирование', 'Задачи распределены довольно равномерно', 'info'],
|
||||||
{
|
getItem('manager'),
|
||||||
title: 'recommendations.author.manager.title',
|
getItem('shorTalk'),
|
||||||
description: 'recommendations.author.manager.description',
|
getItem('ipr'),
|
||||||
type: RECOMMENDATION_TYPES.INFO,
|
getItem('oneToOne'),
|
||||||
},
|
getItem('club'),
|
||||||
{
|
|
||||||
title: 'recommendations.author.shorTalk.title',
|
|
||||||
description: 'recommendations.author.shorTalk.description',
|
|
||||||
type: RECOMMENDATION_TYPES.INFO,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'recommendations.author.ipr.title',
|
|
||||||
description: 'recommendations.author.ipr.description',
|
|
||||||
type: RECOMMENDATION_TYPES.INFO,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'recommendations.author.oneToOne.title',
|
|
||||||
description: 'recommendations.author.oneToOne.description',
|
|
||||||
type: RECOMMENDATION_TYPES.INFO,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'recommendations.author.club.title',
|
|
||||||
description: 'recommendations.author.club.description',
|
|
||||||
type: RECOMMENDATION_TYPES.INFO,
|
|
||||||
},
|
|
||||||
].filter(item => item);
|
].filter(item => item);
|
||||||
}
|
}
|
||||||
|
|
||||||
getProjectType(workLazyTotal: number) {
|
getProjectType(workLazyTotal: number) {
|
||||||
if (workLazyTotal < 1) return {
|
if (workLazyTotal < 1) return getItem('projectTypeOpenSource');
|
||||||
title: 'recommendations.author.projectType.openSource.title',
|
|
||||||
description: 'recommendations.author.projectType.openSource.description',
|
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (workLazyTotal < 5) return {
|
if (workLazyTotal < 5) return getItem('projectTypeEasy');
|
||||||
title: 'recommendations.author.projectType.easy.title',
|
|
||||||
description: 'recommendations.author.projectType.easy.description',
|
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
|
||||||
};
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import RECOMMENDATION_TYPES from '../contstants';
|
import { getBuilder } from '../helpers';
|
||||||
|
|
||||||
|
const { getItem } = getBuilder('hour');
|
||||||
|
|
||||||
export default class RecommendationsTeamByHour {
|
export default class RecommendationsTeamByHour {
|
||||||
getTotalInfo(dataGrip: any) {
|
getTotalInfo(dataGrip: any) {
|
||||||
|
@ -16,23 +18,9 @@ export default class RecommendationsTeamByHour {
|
||||||
const weekends = Math.max(...statistic.commitsByDayAndHourTotal.slice(5, 7));
|
const weekends = Math.max(...statistic.commitsByDayAndHourTotal.slice(5, 7));
|
||||||
const workAndWeekends = weekends / weekday;
|
const workAndWeekends = weekends / weekday;
|
||||||
|
|
||||||
if (workAndWeekends > 0.45) return {
|
if (workAndWeekends > 0.45) return getItem('onlyWork');
|
||||||
title: 'recommendations.hour.onlyWork.title',
|
if (workAndWeekends > 0.2) return getItem('weekends');
|
||||||
description: 'recommendations.hour.onlyWork.description',
|
if (workAndWeekends > 0) return getItem('easy');
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (workAndWeekends > 0.2) return {
|
|
||||||
title: 'recommendations.hour.weekends.title',
|
|
||||||
description: 'recommendations.hour.weekends.description',
|
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (workAndWeekends > 0) return {
|
|
||||||
title: 'recommendations.hour.easy.title',
|
|
||||||
description: 'recommendations.hour.easy.description',
|
|
||||||
type: RECOMMENDATION_TYPES.WARNING,
|
|
||||||
};
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { getMoney } from 'ts/helpers/formatter';
|
import { getMoney } from 'ts/helpers/formatter';
|
||||||
import RECOMMENDATION_TYPES from '../contstants';
|
import { getBuilder } from '../helpers';
|
||||||
|
|
||||||
|
const { getItem, getTitle } = getBuilder('scope');
|
||||||
|
|
||||||
export default class RecommendationsTeamByScope {
|
export default class RecommendationsTeamByScope {
|
||||||
getTotalInfo(dataGrip: any) {
|
getTotalInfo(dataGrip: any) {
|
||||||
|
@ -8,21 +10,9 @@ export default class RecommendationsTeamByScope {
|
||||||
this.getBusFactor(dataGrip),
|
this.getBusFactor(dataGrip),
|
||||||
this.getManyTypes(dataGrip),
|
this.getManyTypes(dataGrip),
|
||||||
this.getParallelism(dataGrip),
|
this.getParallelism(dataGrip),
|
||||||
{
|
getTitle('money', money),
|
||||||
title: money,
|
getItem('plan'),
|
||||||
description: 'recommendations.scope.money',
|
getItem('cost'),
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'recommendations.scope.plan.title',
|
|
||||||
description: 'recommendations.scope.plan.description',
|
|
||||||
type: RECOMMENDATION_TYPES.INFO,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'recommendations.scope.cost.title',
|
|
||||||
description: 'recommendations.scope.cost.description',
|
|
||||||
type: RECOMMENDATION_TYPES.INFO,
|
|
||||||
},
|
|
||||||
].filter(item => item);
|
].filter(item => item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,23 +32,10 @@ export default class RecommendationsTeamByScope {
|
||||||
const total = data.reduce((sum, value) => sum + value, 0);
|
const total = data.reduce((sum, value) => sum + value, 0);
|
||||||
const parallelism = total / data.length;
|
const parallelism = total / data.length;
|
||||||
|
|
||||||
if (parallelism < 1.3) return {
|
if (parallelism < 1.3) return getItem('parallelismNot');
|
||||||
title: 'recommendations.scope.parallelism.not.title',
|
if (parallelism < 2) return getItem('parallelismHas');
|
||||||
description: 'recommendations.scope.parallelism.not.description',
|
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (parallelism < 2) return {
|
return getItem('parallelismEvery');
|
||||||
title: 'recommendations.scope.parallelism.has.title',
|
|
||||||
description: 'recommendations.scope.parallelism.has.description',
|
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
title: 'recommendations.scope.parallelism.every.title',
|
|
||||||
description: 'recommendations.scope.parallelism.every.description',
|
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getBusFactor(dataGrip: any) {
|
getBusFactor(dataGrip: any) {
|
||||||
|
@ -73,17 +50,9 @@ export default class RecommendationsTeamByScope {
|
||||||
if (!oneMaintainer.length) return null;
|
if (!oneMaintainer.length) return null;
|
||||||
const everyHasOne = oneMaintainer.length > dataGrip.scope.statistic.length * 0.6;
|
const everyHasOne = oneMaintainer.length > dataGrip.scope.statistic.length * 0.6;
|
||||||
|
|
||||||
if (everyHasOne) return {
|
return everyHasOne
|
||||||
title: 'recommendations.scope.bus.everyHasOne.title',
|
? getItem('busEveryHasOne')
|
||||||
description: 'recommendations.scope.bus.everyHasOne.description',
|
: getTitle('busOneMaintainer', oneMaintainer);
|
||||||
type: RECOMMENDATION_TYPES.WARNING,
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
title: oneMaintainer,
|
|
||||||
description: 'recommendations.scope.bus.oneMaintainer',
|
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getManyTypes(dataGrip: any) {
|
getManyTypes(dataGrip: any) {
|
||||||
|
@ -96,22 +65,8 @@ export default class RecommendationsTeamByScope {
|
||||||
|
|
||||||
const everyHasOne = oneType.length > dataGrip.scope.statistic.length * 0.6;
|
const everyHasOne = oneType.length > dataGrip.scope.statistic.length * 0.6;
|
||||||
|
|
||||||
if (everyHasOne) return {
|
return everyHasOne
|
||||||
title: 'recommendations.scope.types.process.title',
|
? getItem('typesProcess')
|
||||||
description: [
|
: getTitle('typesOne', oneType);
|
||||||
'recommendations.scope.types.process.description',
|
|
||||||
'recommendations.scope.types.common',
|
|
||||||
],
|
|
||||||
type: RECOMMENDATION_TYPES.WARNING,
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
title: oneType,
|
|
||||||
description: [
|
|
||||||
'recommendations.scope.types.one',
|
|
||||||
'recommendations.scope.types.common',
|
|
||||||
],
|
|
||||||
type: RECOMMENDATION_TYPES.WARNING,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
import { getDateByTimestamp } from 'ts/helpers/formatter';
|
import { getDateByTimestamp } from 'ts/helpers/formatter';
|
||||||
import RECOMMENDATION_TYPES from '../contstants';
|
import { getBuilder } from '../helpers';
|
||||||
|
|
||||||
|
const {
|
||||||
|
getItem,
|
||||||
|
getArgTitle,
|
||||||
|
getTitleArgDescription,
|
||||||
|
} = getBuilder('timestamp');
|
||||||
|
|
||||||
export default class RecommendationsTeamByTimestamp {
|
export default class RecommendationsTeamByTimestamp {
|
||||||
getTotalInfo(dataGrip: any) {
|
getTotalInfo(dataGrip: any) {
|
||||||
|
@ -11,26 +17,9 @@ export default class RecommendationsTeamByTimestamp {
|
||||||
// TODO: all days не верный, я вывожу рабочие дни, а не выходные.
|
// TODO: all days не верный, я вывожу рабочие дни, а не выходные.
|
||||||
|
|
||||||
return [
|
return [
|
||||||
(workInWeek ? {
|
(workInWeek ? getArgTitle('weekendDays', [workInWeek]) : null),
|
||||||
title: 'recommendations.timestamp.common.title',
|
|
||||||
description: 'recommendations.timestamp.weekendDays.description',
|
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
|
||||||
arguments: {
|
|
||||||
title: [workInWeek],
|
|
||||||
},
|
|
||||||
} : null),
|
|
||||||
|
|
||||||
this.getWorkOnWeek(byTimestamp.allCommitsByTimestamp.length, workInWeek),
|
this.getWorkOnWeek(byTimestamp.allCommitsByTimestamp.length, workInWeek),
|
||||||
|
getArgTitle('allDays', [totalDays]),
|
||||||
{
|
|
||||||
title: 'recommendations.timestamp.common.title',
|
|
||||||
description: 'recommendations.timestamp.allDays.description',
|
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
arguments: {
|
|
||||||
title: [totalDays],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
this.getFirstDay(byTimestamp),
|
this.getFirstDay(byTimestamp),
|
||||||
this.getLastDay(byTimestamp),
|
this.getLastDay(byTimestamp),
|
||||||
].filter(item => item);
|
].filter(item => item);
|
||||||
|
@ -38,61 +27,21 @@ export default class RecommendationsTeamByTimestamp {
|
||||||
|
|
||||||
getWorkOnWeek(allWorkDays: number, workOnWeek: number) {
|
getWorkOnWeek(allWorkDays: number, workOnWeek: number) {
|
||||||
const percent = (workOnWeek * 100) / allWorkDays;
|
const percent = (workOnWeek * 100) / allWorkDays;
|
||||||
|
if (percent > 13) return getItem('regularWeekendWord');
|
||||||
if (percent > 13) {
|
if (percent > 7) return getItem('sometimeWeekendWord');
|
||||||
return {
|
if (percent > 2) return getItem('neverWeekendWord');
|
||||||
title: 'recommendations.timestamp.regularWeekendWord.title',
|
|
||||||
description: 'recommendations.timestamp.weekendWord.description',
|
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (percent > 7) {
|
|
||||||
return {
|
|
||||||
title: 'recommendations.timestamp.sometimeWeekendWord.title',
|
|
||||||
description: 'recommendations.timestamp.weekendWord.description',
|
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (percent > 2) {
|
|
||||||
return {
|
|
||||||
title: 'recommendations.timestamp.neverWeekendWord.title',
|
|
||||||
description: 'recommendations.timestamp.neverWeekendWord.description',
|
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getFirstDay(byTimestamp: any) {
|
getFirstDay(byTimestamp: any) {
|
||||||
const commit = byTimestamp.allCommitsByTimestamp[0];
|
const commit = byTimestamp.allCommitsByTimestamp[0];
|
||||||
const [ date, day ] = getDateByTimestamp(commit.timestamp);
|
const [ date, day ] = getDateByTimestamp(commit.timestamp);
|
||||||
|
return getTitleArgDescription('firstCommit', date, [day]);
|
||||||
return {
|
|
||||||
title: date,
|
|
||||||
description: 'recommendations.timestamp.firstCommit.description',
|
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
arguments: {
|
|
||||||
description: [day],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getLastDay(byTimestamp: any) {
|
getLastDay(byTimestamp: any) {
|
||||||
const commit = byTimestamp.allCommitsByTimestamp[(byTimestamp.allCommitsByTimestamp.length - 1)];
|
const commit = byTimestamp.allCommitsByTimestamp[(byTimestamp.allCommitsByTimestamp.length - 1)];
|
||||||
const [ date, day ] = getDateByTimestamp(commit.timestamp);
|
const [ date, day ] = getDateByTimestamp(commit.timestamp);
|
||||||
|
return getTitleArgDescription('lastCommit', date, [day]);
|
||||||
return {
|
|
||||||
title: date,
|
|
||||||
description: 'recommendations.timestamp.lastCommit.description',
|
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
arguments: {
|
|
||||||
description: [day],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import RECOMMENDATION_TYPES from '../contstants';
|
import { getBuilder } from '../helpers';
|
||||||
|
|
||||||
|
const { getItem, getArgDescription } = getBuilder('type');
|
||||||
|
|
||||||
export default class RecommendationsTeamByType {
|
export default class RecommendationsTeamByType {
|
||||||
getTotalInfo(dataGrip: any) {
|
getTotalInfo(dataGrip: any) {
|
||||||
|
@ -8,21 +10,9 @@ export default class RecommendationsTeamByType {
|
||||||
|
|
||||||
return [
|
return [
|
||||||
this.getBusFactor(dataGrip),
|
this.getBusFactor(dataGrip),
|
||||||
(fewTypes ? {
|
(fewTypes ? getItem('fewTypes') : null),
|
||||||
title: 'recommendations.type.fewTypes.title',
|
getItem('diff'),
|
||||||
description: 'recommendations.type.fewTypes.description',
|
getItem('buddy'),
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
} : null),
|
|
||||||
{
|
|
||||||
title: 'recommendations.type.diff.title',
|
|
||||||
description: 'recommendations.type.diff.description',
|
|
||||||
type: RECOMMENDATION_TYPES.INFO,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'recommendations.type.buddy.title',
|
|
||||||
description: 'recommendations.type.buddy.description',
|
|
||||||
type: RECOMMENDATION_TYPES.INFO,
|
|
||||||
},
|
|
||||||
].filter(item => item);
|
].filter(item => item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,27 +29,8 @@ export default class RecommendationsTeamByType {
|
||||||
if (!oneMaintainer.length) return null;
|
if (!oneMaintainer.length) return null;
|
||||||
const everyHasOne = oneMaintainer.length > dataGrip.type.statistic.length * 0.6;
|
const everyHasOne = oneMaintainer.length > dataGrip.type.statistic.length * 0.6;
|
||||||
|
|
||||||
if (everyHasOne) return {
|
return everyHasOne
|
||||||
title: 'recommendations.type.everyHasOne.title',
|
? getItem('everyHasOne')
|
||||||
description: [
|
: getArgDescription('oneMaintainer', [`- ${oneMaintainer.join(';\n- ')}`]);
|
||||||
'recommendations.type.everyHasOne.description',
|
|
||||||
'recommendations.type.common',
|
|
||||||
],
|
|
||||||
type: RECOMMENDATION_TYPES.WARNING,
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
title: 'recommendations.type.oneMaintainer.title',
|
|
||||||
description: [
|
|
||||||
'recommendations.type.oneMaintainer.description',
|
|
||||||
'recommendations.type.common',
|
|
||||||
],
|
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
|
||||||
arguments: {
|
|
||||||
description: [`- ${oneMaintainer.join(';\n- ')}`],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import RECOMMENDATION_TYPES from '../contstants';
|
import { getBuilder } from '../helpers';
|
||||||
|
|
||||||
|
const { getItem, getTitle } = getBuilder('week');
|
||||||
|
|
||||||
export default class RecommendationsTeamByWeek {
|
export default class RecommendationsTeamByWeek {
|
||||||
getTotalInfo(dataGrip: any) {
|
getTotalInfo(dataGrip: any) {
|
||||||
|
@ -14,45 +16,23 @@ export default class RecommendationsTeamByWeek {
|
||||||
|
|
||||||
getLazyDays(dataGrip: any, lastWeek: any) {
|
getLazyDays(dataGrip: any, lastWeek: any) {
|
||||||
const lazyDays = lastWeek.map((statistic: any) => statistic.lazyDaysTotal / statistic.authorsLength);
|
const lazyDays = lastWeek.map((statistic: any) => statistic.lazyDaysTotal / statistic.authorsLength);
|
||||||
|
|
||||||
if (lazyDays[0] < lazyDays[1] && lazyDays[1] < lazyDays[2]) {
|
if (lazyDays[0] < lazyDays[1] && lazyDays[1] < lazyDays[2]) {
|
||||||
return {
|
return getItem('lazyDaysDown');
|
||||||
title: 'recommendations.week.lazyDays.down.title',
|
|
||||||
description: 'recommendations.week.lazyDays.down.description',
|
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lazyDays[0] > lazyDays[1] && lazyDays[1] > lazyDays[2]) {
|
if (lazyDays[0] > lazyDays[1] && lazyDays[1] > lazyDays[2]) {
|
||||||
return {
|
return getItem('lazyDaysUp');
|
||||||
title: 'recommendations.week.lazyDays.up.title',
|
|
||||||
description: 'recommendations.week.lazyDays.up.description',
|
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTasks(dataGrip: any, lastWeek: any) { // TODO: спорно, это видно по количеству изменений
|
getTasks(dataGrip: any, lastWeek: any) { // TODO: спорно, это видно по количеству изменений
|
||||||
const lazyDays = lastWeek.map((statistic: any) => statistic.tasks / statistic.authorsLength);
|
const lazyDays = lastWeek.map((statistic: any) => statistic.tasks / statistic.authorsLength);
|
||||||
|
|
||||||
if (lazyDays[0] < lazyDays[1] && lazyDays[1] < lazyDays[2]) {
|
if (lazyDays[0] < lazyDays[1] && lazyDays[1] < lazyDays[2]) {
|
||||||
return {
|
return getItem('taskUp');
|
||||||
title: 'recommendations.week.task.up.title',
|
|
||||||
description: 'recommendations.week.task.up.description',
|
|
||||||
type: RECOMMENDATION_TYPES.FACT,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lazyDays[0] > lazyDays[1] && lazyDays[1] > lazyDays[2]) {
|
if (lazyDays[0] > lazyDays[1] && lazyDays[1] > lazyDays[2]) {
|
||||||
return {
|
return getItem('taskDown');
|
||||||
title: 'recommendations.week.task.down.title',
|
|
||||||
description: 'recommendations.week.task.down.description',
|
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,15 +44,9 @@ export default class RecommendationsTeamByWeek {
|
||||||
// TODO: неверный расчет
|
// TODO: неверный расчет
|
||||||
// нужен человек, который встречается в трех массивах лидеров прогула
|
// нужен человек, который встречается в трех массивах лидеров прогула
|
||||||
if (lazyMaintainer[0] === lazyMaintainer[1] === lazyMaintainer[2]) {
|
if (lazyMaintainer[0] === lazyMaintainer[1] === lazyMaintainer[2]) {
|
||||||
return {
|
return getTitle('taskLazyMaintainer', lazyMaintainer[0]);
|
||||||
title: lazyMaintainer[0],
|
|
||||||
description: 'recommendations.week.task.lazyMaintainer.description',
|
|
||||||
type: RECOMMENDATION_TYPES.ALERT,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
export default {
|
|
||||||
ALERT: 'error',
|
|
||||||
WARNING: 'warning',
|
|
||||||
FACT: 'fact',
|
|
||||||
INFO: 'info',
|
|
||||||
};
|
|
296
src/ts/helpers/Recommendations/helpers/contstants.ts
Normal file
296
src/ts/helpers/Recommendations/helpers/contstants.ts
Normal file
|
@ -0,0 +1,296 @@
|
||||||
|
export const RECOMMENDATION_TYPES = {
|
||||||
|
ALERT: 'error',
|
||||||
|
WARNING: 'warning',
|
||||||
|
FACT: 'fact',
|
||||||
|
INFO: 'info',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RECOMMENDATIONS_BY_VIEW = {
|
||||||
|
timestamp: {
|
||||||
|
weekendDays: {
|
||||||
|
title: 'recommendations.timestamp.common.title',
|
||||||
|
description: 'recommendations.timestamp.weekendDays.description',
|
||||||
|
type: RECOMMENDATION_TYPES.ALERT,
|
||||||
|
arguments: {
|
||||||
|
title: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
lossesDays: {
|
||||||
|
title: 'recommendations.timestamp.common.title',
|
||||||
|
description: 'recommendations.timestamp.lossesDays.description',
|
||||||
|
type: RECOMMENDATION_TYPES.WARNING,
|
||||||
|
arguments: {
|
||||||
|
title: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
allDays: {
|
||||||
|
title: 'recommendations.timestamp.common.title',
|
||||||
|
description: 'recommendations.timestamp.allDays.description',
|
||||||
|
type: RECOMMENDATION_TYPES.FACT,
|
||||||
|
arguments: {
|
||||||
|
title: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
firstCommit: {
|
||||||
|
title: '',
|
||||||
|
description: 'recommendations.timestamp.firstCommit.description',
|
||||||
|
type: RECOMMENDATION_TYPES.FACT,
|
||||||
|
arguments: {
|
||||||
|
description: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
lastCommit: {
|
||||||
|
title: '',
|
||||||
|
description: 'recommendations.timestamp.lastCommit.description',
|
||||||
|
type: RECOMMENDATION_TYPES.FACT,
|
||||||
|
arguments: {
|
||||||
|
description: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
regularWeekendWord: {
|
||||||
|
title: 'recommendations.timestamp.regularWeekendWord.title',
|
||||||
|
description: 'recommendations.timestamp.weekendWord.description',
|
||||||
|
type: RECOMMENDATION_TYPES.ALERT,
|
||||||
|
},
|
||||||
|
sometimeWeekendWord:{
|
||||||
|
title: 'recommendations.timestamp.sometimeWeekendWord.title',
|
||||||
|
description: 'recommendations.timestamp.weekendWord.description',
|
||||||
|
type: RECOMMENDATION_TYPES.ALERT,
|
||||||
|
},
|
||||||
|
neverWeekendWord: {
|
||||||
|
title: 'recommendations.timestamp.neverWeekendWord.title',
|
||||||
|
description: 'recommendations.timestamp.neverWeekendWord.description',
|
||||||
|
type: RECOMMENDATION_TYPES.FACT,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
lazyDaysDown: {
|
||||||
|
title: 'recommendations.week.lazyDays.down.title',
|
||||||
|
description: 'recommendations.week.lazyDays.down.description',
|
||||||
|
type: RECOMMENDATION_TYPES.FACT,
|
||||||
|
},
|
||||||
|
lazyDaysUp: {
|
||||||
|
title: 'recommendations.week.lazyDays.up.title',
|
||||||
|
description: 'recommendations.week.lazyDays.up.description',
|
||||||
|
type: RECOMMENDATION_TYPES.ALERT,
|
||||||
|
},
|
||||||
|
notWork: {
|
||||||
|
title: 'recommendations.week.notWork.title',
|
||||||
|
description: 'recommendations.week.notWork.description',
|
||||||
|
type: RECOMMENDATION_TYPES.ALERT,
|
||||||
|
},
|
||||||
|
upWork: {
|
||||||
|
title: 'recommendations.week.upWork.title',
|
||||||
|
description: 'recommendations.week.upWork.description',
|
||||||
|
type: RECOMMENDATION_TYPES.ALERT,
|
||||||
|
},
|
||||||
|
taskUp: {
|
||||||
|
title: 'recommendations.week.task.up.title',
|
||||||
|
description: 'recommendations.week.task.up.description',
|
||||||
|
type: RECOMMENDATION_TYPES.FACT,
|
||||||
|
},
|
||||||
|
taskDown: {
|
||||||
|
title: 'recommendations.week.task.down.title',
|
||||||
|
description: 'recommendations.week.task.down.description',
|
||||||
|
type: RECOMMENDATION_TYPES.ALERT,
|
||||||
|
},
|
||||||
|
taskLazyMaintainer: {
|
||||||
|
description: 'recommendations.week.task.lazyMaintainer.description',
|
||||||
|
type: RECOMMENDATION_TYPES.ALERT,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
fewTypes: {
|
||||||
|
title: 'recommendations.type.fewTypes.title',
|
||||||
|
description: 'recommendations.type.fewTypes.description',
|
||||||
|
type: RECOMMENDATION_TYPES.FACT,
|
||||||
|
},
|
||||||
|
diff: {
|
||||||
|
title: 'recommendations.type.diff.title',
|
||||||
|
description: 'recommendations.type.diff.description',
|
||||||
|
type: RECOMMENDATION_TYPES.INFO,
|
||||||
|
},
|
||||||
|
buddy: {
|
||||||
|
title: 'recommendations.type.buddy.title',
|
||||||
|
description: 'recommendations.type.buddy.description',
|
||||||
|
type: RECOMMENDATION_TYPES.INFO,
|
||||||
|
},
|
||||||
|
everyHasOne: {
|
||||||
|
title: 'recommendations.type.everyHasOne.title',
|
||||||
|
description: [
|
||||||
|
'recommendations.type.everyHasOne.description',
|
||||||
|
'recommendations.type.common',
|
||||||
|
],
|
||||||
|
type: RECOMMENDATION_TYPES.WARNING,
|
||||||
|
},
|
||||||
|
oneMaintainer: {
|
||||||
|
title: 'recommendations.type.oneMaintainer.title',
|
||||||
|
description: [
|
||||||
|
'recommendations.type.oneMaintainer.description',
|
||||||
|
'recommendations.type.common',
|
||||||
|
],
|
||||||
|
type: RECOMMENDATION_TYPES.ALERT,
|
||||||
|
arguments: {
|
||||||
|
description: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
scope: {
|
||||||
|
money: {
|
||||||
|
description: 'recommendations.scope.money',
|
||||||
|
type: RECOMMENDATION_TYPES.FACT,
|
||||||
|
},
|
||||||
|
plan: {
|
||||||
|
title: 'recommendations.scope.plan.title',
|
||||||
|
description: 'recommendations.scope.plan.description',
|
||||||
|
type: RECOMMENDATION_TYPES.INFO,
|
||||||
|
},
|
||||||
|
cost: {
|
||||||
|
title: 'recommendations.scope.cost.title',
|
||||||
|
description: 'recommendations.scope.cost.description',
|
||||||
|
type: RECOMMENDATION_TYPES.INFO,
|
||||||
|
},
|
||||||
|
parallelismNot: {
|
||||||
|
title: 'recommendations.scope.parallelism.not.title',
|
||||||
|
description: 'recommendations.scope.parallelism.not.description',
|
||||||
|
type: RECOMMENDATION_TYPES.FACT,
|
||||||
|
},
|
||||||
|
parallelismHas: {
|
||||||
|
title: 'recommendations.scope.parallelism.has.title',
|
||||||
|
description: 'recommendations.scope.parallelism.has.description',
|
||||||
|
type: RECOMMENDATION_TYPES.FACT,
|
||||||
|
},
|
||||||
|
parallelismEvery: {
|
||||||
|
title: 'recommendations.scope.parallelism.every.title',
|
||||||
|
description: 'recommendations.scope.parallelism.every.description',
|
||||||
|
type: RECOMMENDATION_TYPES.FACT,
|
||||||
|
},
|
||||||
|
busEveryHasOne: {
|
||||||
|
title: 'recommendations.scope.bus.everyHasOne.title',
|
||||||
|
description: 'recommendations.scope.bus.everyHasOne.description',
|
||||||
|
type: RECOMMENDATION_TYPES.WARNING,
|
||||||
|
},
|
||||||
|
busOneMaintainer: {
|
||||||
|
description: 'recommendations.scope.bus.oneMaintainer',
|
||||||
|
type: RECOMMENDATION_TYPES.ALERT,
|
||||||
|
},
|
||||||
|
typesProcess: {
|
||||||
|
title: 'recommendations.scope.types.process.title',
|
||||||
|
description: [
|
||||||
|
'recommendations.scope.types.process.description',
|
||||||
|
'recommendations.scope.types.common',
|
||||||
|
],
|
||||||
|
type: RECOMMENDATION_TYPES.WARNING,
|
||||||
|
},
|
||||||
|
typesOne: {
|
||||||
|
description: [
|
||||||
|
'recommendations.scope.types.one',
|
||||||
|
'recommendations.scope.types.common',
|
||||||
|
],
|
||||||
|
type: RECOMMENDATION_TYPES.WARNING,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
hour: {
|
||||||
|
onlyWork: {
|
||||||
|
title: 'recommendations.hour.onlyWork.title',
|
||||||
|
description: 'recommendations.hour.onlyWork.description',
|
||||||
|
type: RECOMMENDATION_TYPES.ALERT,
|
||||||
|
},
|
||||||
|
weekends: {
|
||||||
|
title: 'recommendations.hour.weekends.title',
|
||||||
|
description: 'recommendations.hour.weekends.description',
|
||||||
|
type: RECOMMENDATION_TYPES.ALERT,
|
||||||
|
},
|
||||||
|
easy: {
|
||||||
|
title: 'recommendations.hour.easy.title',
|
||||||
|
description: 'recommendations.hour.easy.description',
|
||||||
|
type: RECOMMENDATION_TYPES.WARNING,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
lotOfLazy: {
|
||||||
|
title: 'recommendations.author.lotOfLazy.title',
|
||||||
|
description: 'recommendations.author.lotOfLazy.description',
|
||||||
|
type: RECOMMENDATION_TYPES.ALERT,
|
||||||
|
arguments: {
|
||||||
|
title: '',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
manyLazy: {
|
||||||
|
title: 'recommendations.author.manyLazy.title',
|
||||||
|
description: 'recommendations.author.manyLazy.description',
|
||||||
|
type: RECOMMENDATION_TYPES.WARNING,
|
||||||
|
arguments: {
|
||||||
|
title: '',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
oneTypeMans: {
|
||||||
|
description: 'recommendations.author.oneTypeMans',
|
||||||
|
type: RECOMMENDATION_TYPES.WARNING,
|
||||||
|
},
|
||||||
|
workToday: {
|
||||||
|
title: 'recommendations.author.workToday.title',
|
||||||
|
description: 'recommendations.author.workToday.description',
|
||||||
|
type: RECOMMENDATION_TYPES.FACT,
|
||||||
|
arguments: {
|
||||||
|
title: '',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
dismissed: {
|
||||||
|
title: 'recommendations.author.dismissed.title',
|
||||||
|
description: 'recommendations.author.dismissed.description',
|
||||||
|
type: RECOMMENDATION_TYPES.FACT,
|
||||||
|
arguments: {
|
||||||
|
title: '',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
staff: {
|
||||||
|
title: 'recommendations.author.staff.title',
|
||||||
|
description: 'recommendations.author.staff.description',
|
||||||
|
type: RECOMMENDATION_TYPES.FACT,
|
||||||
|
arguments: {
|
||||||
|
title: '',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
manager: {
|
||||||
|
title: 'recommendations.author.manager.title',
|
||||||
|
description: 'recommendations.author.manager.description',
|
||||||
|
type: RECOMMENDATION_TYPES.INFO,
|
||||||
|
},
|
||||||
|
shorTalk: {
|
||||||
|
title: 'recommendations.author.shorTalk.title',
|
||||||
|
description: 'recommendations.author.shorTalk.description',
|
||||||
|
type: RECOMMENDATION_TYPES.INFO,
|
||||||
|
},
|
||||||
|
ipr: {
|
||||||
|
title: 'recommendations.author.ipr.title',
|
||||||
|
description: 'recommendations.author.ipr.description',
|
||||||
|
type: RECOMMENDATION_TYPES.INFO,
|
||||||
|
},
|
||||||
|
oneToOne: {
|
||||||
|
title: 'recommendations.author.oneToOne.title',
|
||||||
|
description: 'recommendations.author.oneToOne.description',
|
||||||
|
type: RECOMMENDATION_TYPES.INFO,
|
||||||
|
},
|
||||||
|
club: {
|
||||||
|
title: 'recommendations.author.club.title',
|
||||||
|
description: 'recommendations.author.club.description',
|
||||||
|
type: RECOMMENDATION_TYPES.INFO,
|
||||||
|
},
|
||||||
|
projectTypeOpenSource: {
|
||||||
|
title: 'recommendations.author.projectType.openSource.title',
|
||||||
|
description: 'recommendations.author.projectType.openSource.description',
|
||||||
|
type: RECOMMENDATION_TYPES.FACT,
|
||||||
|
},
|
||||||
|
projectTypeEasy: {
|
||||||
|
title: 'recommendations.author.projectType.easy.title',
|
||||||
|
description: 'recommendations.author.projectType.easy.description',
|
||||||
|
type: RECOMMENDATION_TYPES.ALERT,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
58
src/ts/helpers/Recommendations/helpers/index.ts
Normal file
58
src/ts/helpers/Recommendations/helpers/index.ts
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
import { RECOMMENDATIONS_BY_VIEW } from './contstants';
|
||||||
|
|
||||||
|
export function getBuilder(type: string) {
|
||||||
|
function getItem(id: string) {
|
||||||
|
return RECOMMENDATIONS_BY_VIEW[type][id];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTitle(id: string, title: any) {
|
||||||
|
return { ...getItem(id), title };
|
||||||
|
}
|
||||||
|
|
||||||
|
function getArgTitle(id: string, title?: any) {
|
||||||
|
return {
|
||||||
|
...getItem(id),
|
||||||
|
arguments: {
|
||||||
|
title,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getArgDescription(id: string, description?: any) {
|
||||||
|
return {
|
||||||
|
...getItem(id),
|
||||||
|
arguments: {
|
||||||
|
description,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTitleArgDescription(id: string, title: string, description?: any) {
|
||||||
|
return {
|
||||||
|
...getTitle(id, title),
|
||||||
|
arguments: {
|
||||||
|
description,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getArgTitleDescription(id: string, title: any, description?: any) {
|
||||||
|
return {
|
||||||
|
...getItem(id),
|
||||||
|
arguments: {
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
getItem,
|
||||||
|
getTitle,
|
||||||
|
getArgTitle,
|
||||||
|
getArgDescription,
|
||||||
|
getTitleArgDescription,
|
||||||
|
getArgTitleDescription,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React, { useState } from 'react';
|
||||||
|
|
||||||
import dataGripStore from 'ts/store/DataGrip';
|
import dataGripStore from 'ts/store/DataGrip';
|
||||||
import { getDate, getDateByTimestamp } from 'ts/helpers/formatter';
|
import { getDate, getDateByTimestamp } from 'ts/helpers/formatter';
|
||||||
import RECOMMENDATION_TYPES from 'ts/helpers/Recommendations/contstants';
|
import { RECOMMENDATION_TYPES } from 'ts/helpers/Recommendations/helpers/contstants';
|
||||||
|
|
||||||
import Recommendations from 'ts/components/Recommendations';
|
import Recommendations from 'ts/components/Recommendations';
|
||||||
import NothingFound from 'ts/components/NothingFound';
|
import NothingFound from 'ts/components/NothingFound';
|
||||||
|
|
|
@ -9,7 +9,7 @@ import PageWrapper from 'ts/components/Page/wrapper';
|
||||||
import BarChart from 'ts/components/BarChart';
|
import BarChart from 'ts/components/BarChart';
|
||||||
import DayInfo from 'ts/components/DayInfo';
|
import DayInfo from 'ts/components/DayInfo';
|
||||||
import Title from 'ts/components/Title';
|
import Title from 'ts/components/Title';
|
||||||
import RECOMMENDATION_TYPES from 'ts/helpers/Recommendations/contstants';
|
import { RECOMMENDATION_TYPES } from 'ts/helpers/Recommendations/helpers/contstants';
|
||||||
import localization from 'ts/helpers/Localization';
|
import localization from 'ts/helpers/Localization';
|
||||||
|
|
||||||
interface ICommitsProps {
|
interface ICommitsProps {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import NothingFound from 'ts/components/NothingFound';
|
||||||
import PageWrapper from 'ts/components/Page/wrapper';
|
import PageWrapper from 'ts/components/Page/wrapper';
|
||||||
import CandyChart from 'ts/components/CandyChart';
|
import CandyChart from 'ts/components/CandyChart';
|
||||||
import Title from 'ts/components/Title';
|
import Title from 'ts/components/Title';
|
||||||
import RECOMMENDATION_TYPES from 'ts/helpers/Recommendations/contstants';
|
import { RECOMMENDATION_TYPES } from 'ts/helpers/Recommendations/helpers/contstants';
|
||||||
|
|
||||||
interface IPopularWordsProps {
|
interface IPopularWordsProps {
|
||||||
statistic: any[];
|
statistic: any[];
|
||||||
|
|
|
@ -142,6 +142,12 @@ export const TEAM = [
|
||||||
title: 'sidebar.team.words',
|
title: 'sidebar.team.words',
|
||||||
icon: './assets/menu/team_words.svg',
|
icon: './assets/menu/team_words.svg',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'recommendations',
|
||||||
|
link: '/team/recommendations',
|
||||||
|
title: 'sidebar.team.recommendations',
|
||||||
|
icon: './assets/menu/building.svg',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'building',
|
id: 'building',
|
||||||
link: '/team/building',
|
link: '/team/building',
|
||||||
|
|
85
src/ts/pages/Team/components/Recommendations.tsx
Normal file
85
src/ts/pages/Team/components/Recommendations.tsx
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { observer } from 'mobx-react-lite';
|
||||||
|
|
||||||
|
import CardForPrint from 'ts/components/Recommendations/components/CardForPrint';
|
||||||
|
import NothingFound from 'ts/components/NothingFound';
|
||||||
|
import Title from 'ts/components/Title';
|
||||||
|
|
||||||
|
import IHashMap from 'ts/interfaces/HashMap';
|
||||||
|
import dataGripStore from 'ts/store/DataGrip';
|
||||||
|
import { RECOMMENDATION_TYPES } from 'ts/helpers/Recommendations/helpers/contstants';
|
||||||
|
import style from '../styles/recommendations.module.scss';
|
||||||
|
|
||||||
|
function getAll(recommendations: IHashMap<any>) {
|
||||||
|
return Object.values(recommendations)
|
||||||
|
.flat(1)
|
||||||
|
.filter((item: any) => item);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGroups(recommendations: any[]) {
|
||||||
|
return recommendations.reduce((acc: IHashMap<any>, item: any) => {
|
||||||
|
if (!acc[item.type]) {
|
||||||
|
acc[item.type] = [];
|
||||||
|
}
|
||||||
|
acc[item.type].push(item);
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BlockProps {
|
||||||
|
title: string;
|
||||||
|
recommendations: any[];
|
||||||
|
}
|
||||||
|
|
||||||
|
function Block({
|
||||||
|
title,
|
||||||
|
recommendations,
|
||||||
|
}: BlockProps): React.ReactElement | null {
|
||||||
|
const cards = recommendations.map((recommendation: any) => (
|
||||||
|
<CardForPrint
|
||||||
|
key={recommendation.description}
|
||||||
|
recommendation={recommendation}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
if (!cards.length) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Title title={title}/>
|
||||||
|
<div className={style.recommendations_page}>
|
||||||
|
{cards}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const RecommendationsPage = observer((): React.ReactElement => {
|
||||||
|
const all = getAll(dataGripStore.dataGrip.recommendations.team);
|
||||||
|
if (!all?.length) return (<NothingFound/>);
|
||||||
|
|
||||||
|
const groups = getGroups(all);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Block
|
||||||
|
title="page.team.recommendations.alert"
|
||||||
|
recommendations={groups[RECOMMENDATION_TYPES.ALERT]}
|
||||||
|
/>
|
||||||
|
<Block
|
||||||
|
title="page.team.recommendations.warning"
|
||||||
|
recommendations={groups[RECOMMENDATION_TYPES.WARNING]}
|
||||||
|
/>
|
||||||
|
<Block
|
||||||
|
title="page.team.recommendations.fact"
|
||||||
|
recommendations={groups[RECOMMENDATION_TYPES.FACT]}
|
||||||
|
/>
|
||||||
|
<Block
|
||||||
|
title="page.team.recommendations.info"
|
||||||
|
recommendations={groups[RECOMMENDATION_TYPES.INFO]}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default RecommendationsPage;
|
|
@ -28,6 +28,7 @@ import Print from './components/Print';
|
||||||
import Release from './components/Release';
|
import Release from './components/Release';
|
||||||
import Refactor from './components/Refactor';
|
import Refactor from './components/Refactor';
|
||||||
import Department from './components/Department';
|
import Department from './components/Department';
|
||||||
|
import RecommendationsPage from './components/Recommendations';
|
||||||
|
|
||||||
interface ViewProps {
|
interface ViewProps {
|
||||||
page?: string;
|
page?: string;
|
||||||
|
@ -61,6 +62,7 @@ const View = observer(({ page }: ViewProps): React.ReactElement => {
|
||||||
if (page === 'tasks') return <Tasks/>;
|
if (page === 'tasks') return <Tasks/>;
|
||||||
if (page === 'refactor') return <Refactor/>;
|
if (page === 'refactor') return <Refactor/>;
|
||||||
if (page === 'department') return <Department/>;
|
if (page === 'department') return <Department/>;
|
||||||
|
if (page === 'recommendations') return <RecommendationsPage/>;
|
||||||
return <Total/>;
|
return <Total/>;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
18
src/ts/pages/Team/styles/recommendations.module.scss
Normal file
18
src/ts/pages/Team/styles/recommendations.module.scss
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
@import 'src/styles/variables';
|
||||||
|
|
||||||
|
.recommendations_page {
|
||||||
|
column-count: 3;
|
||||||
|
margin: 0 0 var(--space-xxl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1500px) {
|
||||||
|
.recommendations_page {
|
||||||
|
column-count: 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 800px) {
|
||||||
|
.recommendations_page {
|
||||||
|
column-count: 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,6 +36,8 @@ export default `
|
||||||
§ sidebar.team.department: Departments
|
§ sidebar.team.department: Departments
|
||||||
§ sidebar.team.country: Locations
|
§ sidebar.team.country: Locations
|
||||||
§ sidebar.team.settings: Die Einstellungen
|
§ sidebar.team.settings: Die Einstellungen
|
||||||
|
§ sidebar.team.recommendations: Recommendations and facts
|
||||||
|
§ sidebar.team.building: Games
|
||||||
§ sidebar.person.total: Allgemeine Informationen
|
§ sidebar.person.total: Allgemeine Informationen
|
||||||
§ sidebar.person.money: Arbeitskosten
|
§ sidebar.person.money: Arbeitskosten
|
||||||
§ sidebar.person.speed: Geschwindigkeit
|
§ sidebar.person.speed: Geschwindigkeit
|
||||||
|
|
|
@ -267,6 +267,10 @@ export default `
|
||||||
§ page.team.building.quiz.result2.description: The correct answers range from 40% to 70%. You have a good idea of your team, but you can get to know it better. Check out the data in the adjacent sections and try again!
|
§ page.team.building.quiz.result2.description: The correct answers range from 40% to 70%. You have a good idea of your team, but you can get to know it better. Check out the data in the adjacent sections and try again!
|
||||||
§ page.team.building.quiz.result3.title: Great
|
§ page.team.building.quiz.result3.title: Great
|
||||||
§ page.team.building.quiz.result3.description: There are more than 70% correct answers. You know the statistics on your team perfectly well!
|
§ page.team.building.quiz.result3.description: There are more than 70% correct answers. You know the statistics on your team perfectly well!
|
||||||
|
§ page.team.recommendations.alert: Warning
|
||||||
|
§ page.team.recommendations.warning: Pay attention
|
||||||
|
§ page.team.recommendations.fact: Facts about the project
|
||||||
|
§ page.team.recommendations.info: General tips
|
||||||
§ page.person.print.photo.title: Photo
|
§ page.person.print.photo.title: Photo
|
||||||
§ page.person.print.photo.description: space for a photo
|
§ page.person.print.photo.description: space for a photo
|
||||||
§ page.person.total.title: Main characteristics
|
§ page.person.total.title: Main characteristics
|
||||||
|
|
|
@ -34,6 +34,8 @@ export default `
|
||||||
§ sidebar.team.department: Departments
|
§ sidebar.team.department: Departments
|
||||||
§ sidebar.team.country: Locations
|
§ sidebar.team.country: Locations
|
||||||
§ sidebar.team.settings: Settings
|
§ sidebar.team.settings: Settings
|
||||||
|
§ sidebar.team.recommendations: Recommendations and facts
|
||||||
|
§ sidebar.team.building: Games
|
||||||
§ sidebar.person.total: Common info
|
§ sidebar.person.total: Common info
|
||||||
§ sidebar.person.money: Work cost
|
§ sidebar.person.money: Work cost
|
||||||
§ sidebar.person.speed: Speed
|
§ sidebar.person.speed: Speed
|
||||||
|
|
|
@ -269,6 +269,10 @@ export default `
|
||||||
§ page.team.building.quiz.result2.description: The correct answers range from 40% to 70%. You have a good idea of your team, but you can get to know it better. Check out the data in the adjacent sections and try again!
|
§ page.team.building.quiz.result2.description: The correct answers range from 40% to 70%. You have a good idea of your team, but you can get to know it better. Check out the data in the adjacent sections and try again!
|
||||||
§ page.team.building.quiz.result3.title: Great
|
§ page.team.building.quiz.result3.title: Great
|
||||||
§ page.team.building.quiz.result3.description: There are more than 70% correct answers. You know the statistics on your team perfectly well!
|
§ page.team.building.quiz.result3.description: There are more than 70% correct answers. You know the statistics on your team perfectly well!
|
||||||
|
§ page.team.recommendations.alert: Warning
|
||||||
|
§ page.team.recommendations.warning: Pay attention
|
||||||
|
§ page.team.recommendations.fact: Facts about the project
|
||||||
|
§ page.team.recommendations.info: General tips
|
||||||
§ page.person.print.photo.title: Photo
|
§ page.person.print.photo.title: Photo
|
||||||
§ page.person.print.photo.description: space for a photo
|
§ page.person.print.photo.description: space for a photo
|
||||||
§ page.person.total.title: Main characteristics
|
§ page.person.total.title: Main characteristics
|
||||||
|
|
|
@ -36,6 +36,8 @@ export default `
|
||||||
§ sidebar.team.department: Departments
|
§ sidebar.team.department: Departments
|
||||||
§ sidebar.team.country: Locations
|
§ sidebar.team.country: Locations
|
||||||
§ sidebar.team.settings: Ajustes
|
§ sidebar.team.settings: Ajustes
|
||||||
|
§ sidebar.team.recommendations: Recommendations and facts
|
||||||
|
§ sidebar.team.building: Games
|
||||||
§ sidebar.person.total: Información general
|
§ sidebar.person.total: Información general
|
||||||
§ sidebar.person.money: Costo del trabajo
|
§ sidebar.person.money: Costo del trabajo
|
||||||
§ sidebar.person.speed: Velocidad
|
§ sidebar.person.speed: Velocidad
|
||||||
|
|
|
@ -269,6 +269,10 @@ export default `
|
||||||
§ page.team.building.quiz.result2.description: The correct answers range from 40% to 70%. You have a good idea of your team, but you can get to know it better. Check out the data in the adjacent sections and try again!
|
§ page.team.building.quiz.result2.description: The correct answers range from 40% to 70%. You have a good idea of your team, but you can get to know it better. Check out the data in the adjacent sections and try again!
|
||||||
§ page.team.building.quiz.result3.title: Great
|
§ page.team.building.quiz.result3.title: Great
|
||||||
§ page.team.building.quiz.result3.description: There are more than 70% correct answers. You know the statistics on your team perfectly well!
|
§ page.team.building.quiz.result3.description: There are more than 70% correct answers. You know the statistics on your team perfectly well!
|
||||||
|
§ page.team.recommendations.alert: Warning
|
||||||
|
§ page.team.recommendations.warning: Pay attention
|
||||||
|
§ page.team.recommendations.fact: Facts about the project
|
||||||
|
§ page.team.recommendations.info: General tips
|
||||||
§ page.person.print.photo.title: Photo
|
§ page.person.print.photo.title: Photo
|
||||||
§ page.person.print.photo.description: a place for a photo
|
§ page.person.print.photo.description: a place for a photo
|
||||||
§ page.person.total.title: Main Features
|
§ page.person.total.title: Main Features
|
||||||
|
|
|
@ -34,6 +34,8 @@ export default `
|
||||||
§ sidebar.team.department: Departments
|
§ sidebar.team.department: Departments
|
||||||
§ sidebar.team.country: Locations
|
§ sidebar.team.country: Locations
|
||||||
§ sidebar.team.settings: Réglages
|
§ sidebar.team.settings: Réglages
|
||||||
|
§ sidebar.team.recommendations: Recommendations and facts
|
||||||
|
§ sidebar.team.building: Games
|
||||||
§ sidebar.person.total: Informations générales
|
§ sidebar.person.total: Informations générales
|
||||||
§ sidebar.person.money: Coût des travaux
|
§ sidebar.person.money: Coût des travaux
|
||||||
§ sidebar.person.speed: Vitesse
|
§ sidebar.person.speed: Vitesse
|
||||||
|
|
|
@ -269,6 +269,10 @@ export default `
|
||||||
§ page.team.building.quiz.result2.description: The correct answers range from 40% to 70%. You have a good idea of your team, but you can get to know it better. Check out the data in the adjacent sections and try again!
|
§ page.team.building.quiz.result2.description: The correct answers range from 40% to 70%. You have a good idea of your team, but you can get to know it better. Check out the data in the adjacent sections and try again!
|
||||||
§ page.team.building.quiz.result3.title: Great
|
§ page.team.building.quiz.result3.title: Great
|
||||||
§ page.team.building.quiz.result3.description: There are more than 70% correct answers. You know the statistics on your team perfectly well!
|
§ page.team.building.quiz.result3.description: There are more than 70% correct answers. You know the statistics on your team perfectly well!
|
||||||
|
§ page.team.recommendations.alert: Warning
|
||||||
|
§ page.team.recommendations.warning: Pay attention
|
||||||
|
§ page.team.recommendations.fact: Facts about the project
|
||||||
|
§ page.team.recommendations.info: General tips
|
||||||
§ page.person.print.photo.title: Photo
|
§ page.person.print.photo.title: Photo
|
||||||
§ page.person.print.photo.description: place à la photographie
|
§ page.person.print.photo.description: place à la photographie
|
||||||
§ page.person.total.title: Caractéristiques de base
|
§ page.person.total.title: Caractéristiques de base
|
||||||
|
|
|
@ -35,6 +35,8 @@ export default `
|
||||||
§ sidebar.team.department: Departments
|
§ sidebar.team.department: Departments
|
||||||
§ sidebar.team.country: Locations
|
§ sidebar.team.country: Locations
|
||||||
§ sidebar.team.settings: 設定
|
§ sidebar.team.settings: 設定
|
||||||
|
§ sidebar.team.recommendations: Recommendations and facts
|
||||||
|
§ sidebar.team.building: Games
|
||||||
§ sidebar.person.total: 一般的な情報
|
§ sidebar.person.total: 一般的な情報
|
||||||
§ sidebar.person.money: 仕事のコスト
|
§ sidebar.person.money: 仕事のコスト
|
||||||
§ sidebar.person.speed: スピード
|
§ sidebar.person.speed: スピード
|
||||||
|
|
|
@ -269,6 +269,10 @@ export default `
|
||||||
§ page.team.building.quiz.result2.description: The correct answers range from 40% to 70%. You have a good idea of your team, but you can get to know it better. Check out the data in the adjacent sections and try again!
|
§ page.team.building.quiz.result2.description: The correct answers range from 40% to 70%. You have a good idea of your team, but you can get to know it better. Check out the data in the adjacent sections and try again!
|
||||||
§ page.team.building.quiz.result3.title: Great
|
§ page.team.building.quiz.result3.title: Great
|
||||||
§ page.team.building.quiz.result3.description: There are more than 70% correct answers. You know the statistics on your team perfectly well!
|
§ page.team.building.quiz.result3.description: There are more than 70% correct answers. You know the statistics on your team perfectly well!
|
||||||
|
§ page.team.recommendations.alert: Warning
|
||||||
|
§ page.team.recommendations.warning: Pay attention
|
||||||
|
§ page.team.recommendations.fact: Facts about the project
|
||||||
|
§ page.team.recommendations.info: General tips
|
||||||
§ page.person.print.photo.title: Photo
|
§ page.person.print.photo.title: Photo
|
||||||
§ page.person.print.photo.description: space for a photo
|
§ page.person.print.photo.description: space for a photo
|
||||||
§ page.person.total.title: Main characteristics
|
§ page.person.total.title: Main characteristics
|
||||||
|
|
|
@ -34,6 +34,8 @@ export default `
|
||||||
§ sidebar.team.department: Departments
|
§ sidebar.team.department: Departments
|
||||||
§ sidebar.team.country: 위치
|
§ sidebar.team.country: 위치
|
||||||
§ sidebar.team.settings: 설정
|
§ sidebar.team.settings: 설정
|
||||||
|
§ sidebar.team.recommendations: 권장 사항 및 사실
|
||||||
|
§ sidebar.team.building: Games
|
||||||
§ sidebar.person.total: 일반 정보
|
§ sidebar.person.total: 일반 정보
|
||||||
§ sidebar.person.money: 작업 비용
|
§ sidebar.person.money: 작업 비용
|
||||||
§ sidebar.person.speed: 속도
|
§ sidebar.person.speed: 속도
|
||||||
|
|
|
@ -269,6 +269,10 @@ export default `
|
||||||
§ page.team.building.quiz.result2.description: The correct answers range from 40% to 70%. You have a good idea of your team, but you can get to know it better. Check out the data in the adjacent sections and try again!
|
§ page.team.building.quiz.result2.description: The correct answers range from 40% to 70%. You have a good idea of your team, but you can get to know it better. Check out the data in the adjacent sections and try again!
|
||||||
§ page.team.building.quiz.result3.title: Great
|
§ page.team.building.quiz.result3.title: Great
|
||||||
§ page.team.building.quiz.result3.description: There are more than 70% correct answers. You know the statistics on your team perfectly well!
|
§ page.team.building.quiz.result3.description: There are more than 70% correct answers. You know the statistics on your team perfectly well!
|
||||||
|
§ page.team.recommendations.alert: Warning
|
||||||
|
§ page.team.recommendations.warning: Pay attention
|
||||||
|
§ page.team.recommendations.fact: Facts about the project
|
||||||
|
§ page.team.recommendations.info: General tips
|
||||||
§ page.person.print.photo.title: 사진
|
§ page.person.print.photo.title: 사진
|
||||||
§ page.person.print.photo.description: 사진 촬영 장소
|
§ page.person.print.photo.description: 사진 촬영 장소
|
||||||
§ page.person.total.title: 주요 특징
|
§ page.person.total.title: 주요 특징
|
||||||
|
|
|
@ -35,6 +35,8 @@ export default `
|
||||||
§ sidebar.team.department: Departments
|
§ sidebar.team.department: Departments
|
||||||
§ sidebar.team.country: Locations
|
§ sidebar.team.country: Locations
|
||||||
§ sidebar.team.settings: Sintonização
|
§ sidebar.team.settings: Sintonização
|
||||||
|
§ sidebar.team.recommendations: Recommendations and facts
|
||||||
|
§ sidebar.team.building: Games
|
||||||
§ sidebar.person.total: Informação geral
|
§ sidebar.person.total: Informação geral
|
||||||
§ sidebar.person.money: Custo do trabalho
|
§ sidebar.person.money: Custo do trabalho
|
||||||
§ sidebar.person.speed: Velocidade
|
§ sidebar.person.speed: Velocidade
|
||||||
|
|
|
@ -269,6 +269,10 @@ export default `
|
||||||
§ page.team.building.quiz.result2.description: The correct answers range from 40% to 70%. You have a good idea of your team, but you can get to know it better. Check out the data in the adjacent sections and try again!
|
§ page.team.building.quiz.result2.description: The correct answers range from 40% to 70%. You have a good idea of your team, but you can get to know it better. Check out the data in the adjacent sections and try again!
|
||||||
§ page.team.building.quiz.result3.title: Great
|
§ page.team.building.quiz.result3.title: Great
|
||||||
§ page.team.building.quiz.result3.description: There are more than 70% correct answers. You know the statistics on your team perfectly well!
|
§ page.team.building.quiz.result3.description: There are more than 70% correct answers. You know the statistics on your team perfectly well!
|
||||||
|
§ page.team.recommendations.alert: Warning
|
||||||
|
§ page.team.recommendations.warning: Pay attention
|
||||||
|
§ page.team.recommendations.fact: Facts about the project
|
||||||
|
§ page.team.recommendations.info: General tips
|
||||||
§ page.person.print.photo.title: Photo
|
§ page.person.print.photo.title: Photo
|
||||||
§ page.person.print.photo.description: space for a photo
|
§ page.person.print.photo.description: space for a photo
|
||||||
§ page.person.total.title: Main characteristics
|
§ page.person.total.title: Main characteristics
|
||||||
|
|
|
@ -34,6 +34,7 @@ export default `
|
||||||
§ sidebar.team.department: Отделы
|
§ sidebar.team.department: Отделы
|
||||||
§ sidebar.team.country: Местоположение
|
§ sidebar.team.country: Местоположение
|
||||||
§ sidebar.team.settings: Настройки
|
§ sidebar.team.settings: Настройки
|
||||||
|
§ sidebar.team.recommendations: Рекомендации и факты
|
||||||
§ sidebar.team.building: Мини игры
|
§ sidebar.team.building: Мини игры
|
||||||
§ sidebar.person.total: Общая информация
|
§ sidebar.person.total: Общая информация
|
||||||
§ sidebar.person.money: Стоимость работы
|
§ sidebar.person.money: Стоимость работы
|
||||||
|
|
|
@ -269,6 +269,10 @@ export default `
|
||||||
§ page.team.building.quiz.result2.description: Правильных ответов от 40% до 70%. Вы имеете хорошее представление о вашей команде, но можете узнать её лучше. Ознакомьтесь с данными в соседних разделах и попробуйте снова!
|
§ page.team.building.quiz.result2.description: Правильных ответов от 40% до 70%. Вы имеете хорошее представление о вашей команде, но можете узнать её лучше. Ознакомьтесь с данными в соседних разделах и попробуйте снова!
|
||||||
§ page.team.building.quiz.result3.title: Отлично
|
§ page.team.building.quiz.result3.title: Отлично
|
||||||
§ page.team.building.quiz.result3.description: Правильных ответов больше 70%. Вы отлично знаете статистику по вашей команде!
|
§ page.team.building.quiz.result3.description: Правильных ответов больше 70%. Вы отлично знаете статистику по вашей команде!
|
||||||
|
§ page.team.recommendations.alert: Проблемы
|
||||||
|
§ page.team.recommendations.warning: Обратить внимание
|
||||||
|
§ page.team.recommendations.fact: Факты о проекте
|
||||||
|
§ page.team.recommendations.info: Общие советы
|
||||||
§ page.person.print.photo.title: Фотография
|
§ page.person.print.photo.title: Фотография
|
||||||
§ page.person.print.photo.description: место для фотографии
|
§ page.person.print.photo.description: место для фотографии
|
||||||
§ page.person.total.title: Основные характеристики
|
§ page.person.total.title: Основные характеристики
|
||||||
|
|
|
@ -35,6 +35,8 @@ export default `
|
||||||
§ sidebar.team.department: Departments
|
§ sidebar.team.department: Departments
|
||||||
§ sidebar.team.country: Locations
|
§ sidebar.team.country: Locations
|
||||||
§ sidebar.team.settings: 设置
|
§ sidebar.team.settings: 设置
|
||||||
|
§ sidebar.team.recommendations: Recommendations and facts
|
||||||
|
§ sidebar.team.building: Games
|
||||||
§ sidebar.person.total: 般资料
|
§ sidebar.person.total: 般资料
|
||||||
§ sidebar.person.money: 工作的成本
|
§ sidebar.person.money: 工作的成本
|
||||||
§ sidebar.person.speed: 速度
|
§ sidebar.person.speed: 速度
|
||||||
|
|
|
@ -264,6 +264,10 @@ export default `
|
||||||
§ page.team.building.quiz.result2.description: The correct answers range from 40% to 70%. You have a good idea of your team, but you can get to know it better. Check out the data in the adjacent sections and try again!
|
§ page.team.building.quiz.result2.description: The correct answers range from 40% to 70%. You have a good idea of your team, but you can get to know it better. Check out the data in the adjacent sections and try again!
|
||||||
§ page.team.building.quiz.result3.title: Great
|
§ page.team.building.quiz.result3.title: Great
|
||||||
§ page.team.building.quiz.result3.description: There are more than 70% correct answers. You know the statistics on your team perfectly well!
|
§ page.team.building.quiz.result3.description: There are more than 70% correct answers. You know the statistics on your team perfectly well!
|
||||||
|
§ page.team.recommendations.alert: Warning
|
||||||
|
§ page.team.recommendations.warning: Pay attention
|
||||||
|
§ page.team.recommendations.fact: Facts about the project
|
||||||
|
§ page.team.recommendations.info: General tips
|
||||||
§ page.person.print.photo.title: 照片
|
§ page.person.print.photo.title: 照片
|
||||||
§ page.person.print.photo.description: 拍照的地方
|
§ page.person.print.photo.description: 拍照的地方
|
||||||
§ page.person.total.title: 主要特点
|
§ page.person.total.title: 主要特点
|
||||||
|
|
Loading…
Add table
Reference in a new issue