mirror of
https://github.com/bakhirev/assayo.git
synced 2025-02-22 04:52:21 +00:00
update
This commit is contained in:
parent
9bd2675129
commit
88452159ae
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 {
|
||||
max-height: calc(60vh - 200px);
|
||||
max-height: calc(100vh - 200px);
|
||||
padding: 0 24px;
|
||||
overflow: auto;
|
||||
line-height: 1.5;
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next';
|
|||
import Description from 'ts/components/Description';
|
||||
import UiKitButton from 'ts/components/UiKit/components/Button';
|
||||
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 { getFormattedTitle, getDescriptionText } from '../helpers';
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
|
||||
import Description from 'ts/components/Description';
|
||||
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 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 { Modal, Header, Body, Footer } from 'ts/components/ModalWindow';
|
||||
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 { getFormattedTitle, getDescriptionText } from '../helpers';
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
import { getDateByTimestamp } from 'ts/helpers/formatter';
|
||||
import RECOMMENDATION_TYPES from '../contstants';
|
||||
import { getBuilder } from '../helpers';
|
||||
|
||||
const {
|
||||
getArgTitle,
|
||||
getTitleArgDescription,
|
||||
} = getBuilder('timestamp');
|
||||
|
||||
export default class RecommendationsPersonByTimestamp {
|
||||
getTotalInfo(dataGrip: any) {
|
||||
|
@ -10,35 +15,14 @@ export default class RecommendationsPersonByTimestamp {
|
|||
acc[name] = [];
|
||||
|
||||
if (workInWeek) {
|
||||
acc[name].push({
|
||||
title: 'recommendations.timestamp.common.title',
|
||||
description: 'recommendations.timestamp.weekendDays.description',
|
||||
type: RECOMMENDATION_TYPES.ALERT,
|
||||
arguments: {
|
||||
title: [workInWeek],
|
||||
},
|
||||
});
|
||||
acc[name].push(getArgTitle('weekendDays', [workInWeek]));
|
||||
}
|
||||
|
||||
if (byAuthor.daysLosses) {
|
||||
acc[name].push({
|
||||
title: 'recommendations.timestamp.common.title',
|
||||
description: 'recommendations.timestamp.lossesDays.description',
|
||||
type: RECOMMENDATION_TYPES.WARNING,
|
||||
arguments: {
|
||||
title: [byAuthor.daysLosses],
|
||||
},
|
||||
});
|
||||
acc[name].push(getArgTitle('lossesDays', [byAuthor.daysLosses]));
|
||||
}
|
||||
|
||||
acc[name].push({
|
||||
title: 'recommendations.timestamp.common.title',
|
||||
description: 'recommendations.timestamp.allDays.description',
|
||||
type: RECOMMENDATION_TYPES.FACT,
|
||||
arguments: {
|
||||
title: [byAuthor.daysAll],
|
||||
},
|
||||
});
|
||||
acc[name].push(getArgTitle('allDays', [byAuthor.daysAll]));
|
||||
|
||||
acc[name].push(this.getFirstDay(byTimestamp));
|
||||
|
||||
|
@ -51,28 +35,12 @@ export default class RecommendationsPersonByTimestamp {
|
|||
getFirstDay(byTimestamp: any) {
|
||||
const commit = byTimestamp.allCommitsByTimestamp[0];
|
||||
const [date, day] = getDateByTimestamp(commit.timestamp);
|
||||
return {
|
||||
title: date,
|
||||
description: 'recommendations.timestamp.firstCommit.description',
|
||||
type: RECOMMENDATION_TYPES.FACT,
|
||||
arguments: {
|
||||
description: [day],
|
||||
},
|
||||
};
|
||||
return getTitleArgDescription('firstCommit', date, [day]);
|
||||
}
|
||||
|
||||
getLastDay(byTimestamp: any) {
|
||||
const commit = byTimestamp.allCommitsByTimestamp[(byTimestamp.allCommitsByTimestamp.length - 1)];
|
||||
const [date, day] = getDateByTimestamp(commit.timestamp);
|
||||
return {
|
||||
title: date,
|
||||
description: 'recommendations.timestamp.lastCommit.description',
|
||||
type: RECOMMENDATION_TYPES.FACT,
|
||||
arguments: {
|
||||
description: [day],
|
||||
},
|
||||
};
|
||||
return getTitleArgDescription('lastCommit', date, [day]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import RECOMMENDATION_TYPES from '../contstants';
|
||||
import { getBuilder } from '../helpers';
|
||||
|
||||
const { getItem } = getBuilder('week');
|
||||
|
||||
export default class RecommendationsPersonByWeek {
|
||||
getTotalInfo(dataGrip: any) {
|
||||
|
@ -16,63 +18,39 @@ export default class RecommendationsPersonByWeek {
|
|||
|
||||
getLazyDays(lastWeeks: any[], name: string) {
|
||||
const lazyDays = lastWeeks.map(statistic => statistic.lazyDays[name]);
|
||||
|
||||
if (lazyDays[0] < lazyDays[1] && lazyDays[1] < lazyDays[2]) return {
|
||||
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]) return {
|
||||
title: 'recommendations.week.lazyDays.up.title',
|
||||
description: 'recommendations.week.lazyDays.up.description',
|
||||
type: RECOMMENDATION_TYPES.ALERT,
|
||||
};
|
||||
|
||||
if (lazyDays[0] < lazyDays[1] && lazyDays[1] < lazyDays[2]) {
|
||||
return getItem('lazyDaysDown');
|
||||
}
|
||||
if (lazyDays[0] > lazyDays[1] && lazyDays[1] > lazyDays[2]) {
|
||||
return getItem('lazyDaysUp');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
getNotWork(lastWeeks: any[], name: string) {
|
||||
const lazyDays = lastWeeks.map(statistic => statistic.lazyDays[name]);
|
||||
|
||||
if (lazyDays[0] && lazyDays[1] && lazyDays[2]) return {
|
||||
title: 'recommendations.week.notWork.title',
|
||||
description: 'recommendations.week.notWork.description',
|
||||
type: RECOMMENDATION_TYPES.ALERT,
|
||||
};
|
||||
|
||||
if (lazyDays[0] && lazyDays[1] && lazyDays[2]) {
|
||||
return getItem('notWork');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
getUpWork(lastWeeks: any[], name: string) {
|
||||
const weekDays = lastWeeks.map(statistic => statistic.weekDays[name]);
|
||||
|
||||
if (weekDays[0] && weekDays[1] && weekDays[2]) return {
|
||||
title: 'recommendations.week.upWork.title',
|
||||
description: 'recommendations.week.upWork.description',
|
||||
type: RECOMMENDATION_TYPES.ALERT,
|
||||
};
|
||||
|
||||
if (weekDays[0] && weekDays[1] && weekDays[2]) {
|
||||
return getItem('upWork');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
getTasks(lastWeeks: any[], name: string) { // TODO: спорно, это видно по количеству изменений
|
||||
const lazyDays = lastWeeks.map(statistic => statistic.taskInDay[name]);
|
||||
|
||||
if (lazyDays[0] < lazyDays[1] && lazyDays[1] < lazyDays[2]) return {
|
||||
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]) return {
|
||||
title: 'recommendations.week.task.down.title',
|
||||
description: 'recommendations.week.task.down.description',
|
||||
type: RECOMMENDATION_TYPES.ALERT,
|
||||
};
|
||||
|
||||
if (lazyDays[0] < lazyDays[1] && lazyDays[1] < lazyDays[2]) {
|
||||
return getItem('taskUp');
|
||||
}
|
||||
if (lazyDays[0] > lazyDays[1] && lazyDays[1] > lazyDays[2]) {
|
||||
return getItem('taskDown');
|
||||
}
|
||||
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 {
|
||||
getTotalInfo(dataGrip: any) {
|
||||
|
@ -41,106 +47,27 @@ export default class RecommendationsTeamByAuthor {
|
|||
return [
|
||||
projectType,
|
||||
|
||||
(lotOfLazy.length ? {
|
||||
title: 'recommendations.author.lotOfLazy.title',
|
||||
description: 'recommendations.author.lotOfLazy.description',
|
||||
type: RECOMMENDATION_TYPES.ALERT,
|
||||
arguments: {
|
||||
title: lotOfLazy.length,
|
||||
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),
|
||||
(lotOfLazy.length ? getArgTitleDescription('lotOfLazy', lotOfLazy.length, lotOfLazy.join(';\n- ')) : null),
|
||||
(manyLazy.length ? getArgTitleDescription('manyLazy', manyLazy.length, manyLazy.join(';\n- ')) : null),
|
||||
(oneTypeMans.length ? getTitle('oneTypeMans', oneTypeMans) : null),
|
||||
(worker.length ? getArgTitleDescription('workToday', worker.length, worker.join(';\n- ')) : null),
|
||||
(dismissed.length ? getArgTitleDescription('dismissed', dismissed.length, dismissed.join(';\n- ')) : null),
|
||||
(staff.length ? getArgTitleDescription('staff', staff.length, staff.join(';\n- ')) : null),
|
||||
|
||||
// ['Планирование', 'Задачи распределены довольно равномерно', 'info'],
|
||||
{
|
||||
title: 'recommendations.author.manager.title',
|
||||
description: 'recommendations.author.manager.description',
|
||||
type: RECOMMENDATION_TYPES.INFO,
|
||||
},
|
||||
{
|
||||
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,
|
||||
},
|
||||
getItem('manager'),
|
||||
getItem('shorTalk'),
|
||||
getItem('ipr'),
|
||||
getItem('oneToOne'),
|
||||
getItem('club'),
|
||||
].filter(item => item);
|
||||
}
|
||||
|
||||
getProjectType(workLazyTotal: number) {
|
||||
if (workLazyTotal < 1) return {
|
||||
title: 'recommendations.author.projectType.openSource.title',
|
||||
description: 'recommendations.author.projectType.openSource.description',
|
||||
type: RECOMMENDATION_TYPES.FACT,
|
||||
};
|
||||
if (workLazyTotal < 1) return getItem('projectTypeOpenSource');
|
||||
|
||||
if (workLazyTotal < 5) return {
|
||||
title: 'recommendations.author.projectType.easy.title',
|
||||
description: 'recommendations.author.projectType.easy.description',
|
||||
type: RECOMMENDATION_TYPES.ALERT,
|
||||
};
|
||||
if (workLazyTotal < 5) return getItem('projectTypeEasy');
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import RECOMMENDATION_TYPES from '../contstants';
|
||||
import { getBuilder } from '../helpers';
|
||||
|
||||
const { getItem } = getBuilder('hour');
|
||||
|
||||
export default class RecommendationsTeamByHour {
|
||||
getTotalInfo(dataGrip: any) {
|
||||
|
@ -16,23 +18,9 @@ export default class RecommendationsTeamByHour {
|
|||
const weekends = Math.max(...statistic.commitsByDayAndHourTotal.slice(5, 7));
|
||||
const workAndWeekends = weekends / weekday;
|
||||
|
||||
if (workAndWeekends > 0.45) return {
|
||||
title: 'recommendations.hour.onlyWork.title',
|
||||
description: 'recommendations.hour.onlyWork.description',
|
||||
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,
|
||||
};
|
||||
if (workAndWeekends > 0.45) return getItem('onlyWork');
|
||||
if (workAndWeekends > 0.2) return getItem('weekends');
|
||||
if (workAndWeekends > 0) return getItem('easy');
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { getMoney } from 'ts/helpers/formatter';
|
||||
import RECOMMENDATION_TYPES from '../contstants';
|
||||
import { getBuilder } from '../helpers';
|
||||
|
||||
const { getItem, getTitle } = getBuilder('scope');
|
||||
|
||||
export default class RecommendationsTeamByScope {
|
||||
getTotalInfo(dataGrip: any) {
|
||||
|
@ -8,21 +10,9 @@ export default class RecommendationsTeamByScope {
|
|||
this.getBusFactor(dataGrip),
|
||||
this.getManyTypes(dataGrip),
|
||||
this.getParallelism(dataGrip),
|
||||
{
|
||||
title: money,
|
||||
description: 'recommendations.scope.money',
|
||||
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,
|
||||
},
|
||||
getTitle('money', money),
|
||||
getItem('plan'),
|
||||
getItem('cost'),
|
||||
].filter(item => item);
|
||||
}
|
||||
|
||||
|
@ -42,23 +32,10 @@ export default class RecommendationsTeamByScope {
|
|||
const total = data.reduce((sum, value) => sum + value, 0);
|
||||
const parallelism = total / data.length;
|
||||
|
||||
if (parallelism < 1.3) return {
|
||||
title: 'recommendations.scope.parallelism.not.title',
|
||||
description: 'recommendations.scope.parallelism.not.description',
|
||||
type: RECOMMENDATION_TYPES.FACT,
|
||||
};
|
||||
if (parallelism < 1.3) return getItem('parallelismNot');
|
||||
if (parallelism < 2) return getItem('parallelismHas');
|
||||
|
||||
if (parallelism < 2) return {
|
||||
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,
|
||||
};
|
||||
return getItem('parallelismEvery');
|
||||
}
|
||||
|
||||
getBusFactor(dataGrip: any) {
|
||||
|
@ -73,17 +50,9 @@ export default class RecommendationsTeamByScope {
|
|||
if (!oneMaintainer.length) return null;
|
||||
const everyHasOne = oneMaintainer.length > dataGrip.scope.statistic.length * 0.6;
|
||||
|
||||
if (everyHasOne) return {
|
||||
title: 'recommendations.scope.bus.everyHasOne.title',
|
||||
description: 'recommendations.scope.bus.everyHasOne.description',
|
||||
type: RECOMMENDATION_TYPES.WARNING,
|
||||
};
|
||||
|
||||
return {
|
||||
title: oneMaintainer,
|
||||
description: 'recommendations.scope.bus.oneMaintainer',
|
||||
type: RECOMMENDATION_TYPES.ALERT,
|
||||
};
|
||||
return everyHasOne
|
||||
? getItem('busEveryHasOne')
|
||||
: getTitle('busOneMaintainer', oneMaintainer);
|
||||
}
|
||||
|
||||
getManyTypes(dataGrip: any) {
|
||||
|
@ -96,22 +65,8 @@ export default class RecommendationsTeamByScope {
|
|||
|
||||
const everyHasOne = oneType.length > dataGrip.scope.statistic.length * 0.6;
|
||||
|
||||
if (everyHasOne) return {
|
||||
title: 'recommendations.scope.types.process.title',
|
||||
description: [
|
||||
'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,
|
||||
};
|
||||
return everyHasOne
|
||||
? getItem('typesProcess')
|
||||
: getTitle('typesOne', oneType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
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 {
|
||||
getTotalInfo(dataGrip: any) {
|
||||
|
@ -11,26 +17,9 @@ export default class RecommendationsTeamByTimestamp {
|
|||
// TODO: all days не верный, я вывожу рабочие дни, а не выходные.
|
||||
|
||||
return [
|
||||
(workInWeek ? {
|
||||
title: 'recommendations.timestamp.common.title',
|
||||
description: 'recommendations.timestamp.weekendDays.description',
|
||||
type: RECOMMENDATION_TYPES.ALERT,
|
||||
arguments: {
|
||||
title: [workInWeek],
|
||||
},
|
||||
} : null),
|
||||
|
||||
(workInWeek ? getArgTitle('weekendDays', [workInWeek]) : null),
|
||||
this.getWorkOnWeek(byTimestamp.allCommitsByTimestamp.length, workInWeek),
|
||||
|
||||
{
|
||||
title: 'recommendations.timestamp.common.title',
|
||||
description: 'recommendations.timestamp.allDays.description',
|
||||
type: RECOMMENDATION_TYPES.FACT,
|
||||
arguments: {
|
||||
title: [totalDays],
|
||||
},
|
||||
},
|
||||
|
||||
getArgTitle('allDays', [totalDays]),
|
||||
this.getFirstDay(byTimestamp),
|
||||
this.getLastDay(byTimestamp),
|
||||
].filter(item => item);
|
||||
|
@ -38,61 +27,21 @@ export default class RecommendationsTeamByTimestamp {
|
|||
|
||||
getWorkOnWeek(allWorkDays: number, workOnWeek: number) {
|
||||
const percent = (workOnWeek * 100) / allWorkDays;
|
||||
|
||||
if (percent > 13) {
|
||||
return {
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
if (percent > 13) return getItem('regularWeekendWord');
|
||||
if (percent > 7) return getItem('sometimeWeekendWord');
|
||||
if (percent > 2) return getItem('neverWeekendWord');
|
||||
return null;
|
||||
}
|
||||
|
||||
getFirstDay(byTimestamp: any) {
|
||||
const commit = byTimestamp.allCommitsByTimestamp[0];
|
||||
const [ date, day ] = getDateByTimestamp(commit.timestamp);
|
||||
|
||||
return {
|
||||
title: date,
|
||||
description: 'recommendations.timestamp.firstCommit.description',
|
||||
type: RECOMMENDATION_TYPES.FACT,
|
||||
arguments: {
|
||||
description: [day],
|
||||
},
|
||||
};
|
||||
return getTitleArgDescription('firstCommit', date, [day]);
|
||||
}
|
||||
|
||||
getLastDay(byTimestamp: any) {
|
||||
const commit = byTimestamp.allCommitsByTimestamp[(byTimestamp.allCommitsByTimestamp.length - 1)];
|
||||
const [ date, day ] = getDateByTimestamp(commit.timestamp);
|
||||
|
||||
return {
|
||||
title: date,
|
||||
description: 'recommendations.timestamp.lastCommit.description',
|
||||
type: RECOMMENDATION_TYPES.FACT,
|
||||
arguments: {
|
||||
description: [day],
|
||||
},
|
||||
};
|
||||
return getTitleArgDescription('lastCommit', date, [day]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import RECOMMENDATION_TYPES from '../contstants';
|
||||
import { getBuilder } from '../helpers';
|
||||
|
||||
const { getItem, getArgDescription } = getBuilder('type');
|
||||
|
||||
export default class RecommendationsTeamByType {
|
||||
getTotalInfo(dataGrip: any) {
|
||||
|
@ -8,21 +10,9 @@ export default class RecommendationsTeamByType {
|
|||
|
||||
return [
|
||||
this.getBusFactor(dataGrip),
|
||||
(fewTypes ? {
|
||||
title: 'recommendations.type.fewTypes.title',
|
||||
description: 'recommendations.type.fewTypes.description',
|
||||
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,
|
||||
},
|
||||
(fewTypes ? getItem('fewTypes') : null),
|
||||
getItem('diff'),
|
||||
getItem('buddy'),
|
||||
].filter(item => item);
|
||||
}
|
||||
|
||||
|
@ -39,27 +29,8 @@ export default class RecommendationsTeamByType {
|
|||
if (!oneMaintainer.length) return null;
|
||||
const everyHasOne = oneMaintainer.length > dataGrip.type.statistic.length * 0.6;
|
||||
|
||||
if (everyHasOne) return {
|
||||
title: 'recommendations.type.everyHasOne.title',
|
||||
description: [
|
||||
'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- ')}`],
|
||||
},
|
||||
};
|
||||
return everyHasOne
|
||||
? getItem('everyHasOne')
|
||||
: getArgDescription('oneMaintainer', [`- ${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 {
|
||||
getTotalInfo(dataGrip: any) {
|
||||
|
@ -14,45 +16,23 @@ export default class RecommendationsTeamByWeek {
|
|||
|
||||
getLazyDays(dataGrip: any, lastWeek: any) {
|
||||
const lazyDays = lastWeek.map((statistic: any) => statistic.lazyDaysTotal / statistic.authorsLength);
|
||||
|
||||
if (lazyDays[0] < lazyDays[1] && lazyDays[1] < lazyDays[2]) {
|
||||
return {
|
||||
title: 'recommendations.week.lazyDays.down.title',
|
||||
description: 'recommendations.week.lazyDays.down.description',
|
||||
type: RECOMMENDATION_TYPES.FACT,
|
||||
};
|
||||
return getItem('lazyDaysDown');
|
||||
}
|
||||
|
||||
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 getItem('lazyDaysUp');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
getTasks(dataGrip: any, lastWeek: any) { // TODO: спорно, это видно по количеству изменений
|
||||
const lazyDays = lastWeek.map((statistic: any) => statistic.tasks / statistic.authorsLength);
|
||||
|
||||
if (lazyDays[0] < lazyDays[1] && lazyDays[1] < lazyDays[2]) {
|
||||
return {
|
||||
title: 'recommendations.week.task.up.title',
|
||||
description: 'recommendations.week.task.up.description',
|
||||
type: RECOMMENDATION_TYPES.FACT,
|
||||
};
|
||||
return getItem('taskUp');
|
||||
}
|
||||
|
||||
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 getItem('taskDown');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -64,15 +44,9 @@ export default class RecommendationsTeamByWeek {
|
|||
// TODO: неверный расчет
|
||||
// нужен человек, который встречается в трех массивах лидеров прогула
|
||||
if (lazyMaintainer[0] === lazyMaintainer[1] === lazyMaintainer[2]) {
|
||||
return {
|
||||
title: lazyMaintainer[0],
|
||||
description: 'recommendations.week.task.lazyMaintainer.description',
|
||||
type: RECOMMENDATION_TYPES.ALERT,
|
||||
};
|
||||
return getTitle('taskLazyMaintainer', lazyMaintainer[0]);
|
||||
}
|
||||
|
||||
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 { 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 NothingFound from 'ts/components/NothingFound';
|
||||
|
|
|
@ -9,7 +9,7 @@ import PageWrapper from 'ts/components/Page/wrapper';
|
|||
import BarChart from 'ts/components/BarChart';
|
||||
import DayInfo from 'ts/components/DayInfo';
|
||||
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';
|
||||
|
||||
interface ICommitsProps {
|
||||
|
|
|
@ -5,7 +5,7 @@ import NothingFound from 'ts/components/NothingFound';
|
|||
import PageWrapper from 'ts/components/Page/wrapper';
|
||||
import CandyChart from 'ts/components/CandyChart';
|
||||
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 {
|
||||
statistic: any[];
|
||||
|
|
|
@ -142,6 +142,12 @@ export const TEAM = [
|
|||
title: 'sidebar.team.words',
|
||||
icon: './assets/menu/team_words.svg',
|
||||
},
|
||||
{
|
||||
id: 'recommendations',
|
||||
link: '/team/recommendations',
|
||||
title: 'sidebar.team.recommendations',
|
||||
icon: './assets/menu/building.svg',
|
||||
},
|
||||
{
|
||||
id: '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 Refactor from './components/Refactor';
|
||||
import Department from './components/Department';
|
||||
import RecommendationsPage from './components/Recommendations';
|
||||
|
||||
interface ViewProps {
|
||||
page?: string;
|
||||
|
@ -61,6 +62,7 @@ const View = observer(({ page }: ViewProps): React.ReactElement => {
|
|||
if (page === 'tasks') return <Tasks/>;
|
||||
if (page === 'refactor') return <Refactor/>;
|
||||
if (page === 'department') return <Department/>;
|
||||
if (page === 'recommendations') return <RecommendationsPage/>;
|
||||
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.country: Locations
|
||||
§ sidebar.team.settings: Die Einstellungen
|
||||
§ sidebar.team.recommendations: Recommendations and facts
|
||||
§ sidebar.team.building: Games
|
||||
§ sidebar.person.total: Allgemeine Informationen
|
||||
§ sidebar.person.money: Arbeitskosten
|
||||
§ 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.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.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.description: space for a photo
|
||||
§ page.person.total.title: Main characteristics
|
||||
|
|
|
@ -34,6 +34,8 @@ export default `
|
|||
§ sidebar.team.department: Departments
|
||||
§ sidebar.team.country: Locations
|
||||
§ sidebar.team.settings: Settings
|
||||
§ sidebar.team.recommendations: Recommendations and facts
|
||||
§ sidebar.team.building: Games
|
||||
§ sidebar.person.total: Common info
|
||||
§ sidebar.person.money: Work cost
|
||||
§ 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.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.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.description: space for a photo
|
||||
§ page.person.total.title: Main characteristics
|
||||
|
|
|
@ -36,6 +36,8 @@ export default `
|
|||
§ sidebar.team.department: Departments
|
||||
§ sidebar.team.country: Locations
|
||||
§ sidebar.team.settings: Ajustes
|
||||
§ sidebar.team.recommendations: Recommendations and facts
|
||||
§ sidebar.team.building: Games
|
||||
§ sidebar.person.total: Información general
|
||||
§ sidebar.person.money: Costo del trabajo
|
||||
§ 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.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.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.description: a place for a photo
|
||||
§ page.person.total.title: Main Features
|
||||
|
|
|
@ -34,6 +34,8 @@ export default `
|
|||
§ sidebar.team.department: Departments
|
||||
§ sidebar.team.country: Locations
|
||||
§ sidebar.team.settings: Réglages
|
||||
§ sidebar.team.recommendations: Recommendations and facts
|
||||
§ sidebar.team.building: Games
|
||||
§ sidebar.person.total: Informations générales
|
||||
§ sidebar.person.money: Coût des travaux
|
||||
§ 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.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.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.description: place à la photographie
|
||||
§ page.person.total.title: Caractéristiques de base
|
||||
|
|
|
@ -35,6 +35,8 @@ export default `
|
|||
§ sidebar.team.department: Departments
|
||||
§ sidebar.team.country: Locations
|
||||
§ sidebar.team.settings: 設定
|
||||
§ sidebar.team.recommendations: Recommendations and facts
|
||||
§ sidebar.team.building: Games
|
||||
§ sidebar.person.total: 一般的な情報
|
||||
§ sidebar.person.money: 仕事のコスト
|
||||
§ 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.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.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.description: space for a photo
|
||||
§ page.person.total.title: Main characteristics
|
||||
|
|
|
@ -34,6 +34,8 @@ export default `
|
|||
§ sidebar.team.department: Departments
|
||||
§ sidebar.team.country: 위치
|
||||
§ sidebar.team.settings: 설정
|
||||
§ sidebar.team.recommendations: 권장 사항 및 사실
|
||||
§ sidebar.team.building: Games
|
||||
§ sidebar.person.total: 일반 정보
|
||||
§ sidebar.person.money: 작업 비용
|
||||
§ 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.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.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.description: 사진 촬영 장소
|
||||
§ page.person.total.title: 주요 특징
|
||||
|
|
|
@ -35,6 +35,8 @@ export default `
|
|||
§ sidebar.team.department: Departments
|
||||
§ sidebar.team.country: Locations
|
||||
§ sidebar.team.settings: Sintonização
|
||||
§ sidebar.team.recommendations: Recommendations and facts
|
||||
§ sidebar.team.building: Games
|
||||
§ sidebar.person.total: Informação geral
|
||||
§ sidebar.person.money: Custo do trabalho
|
||||
§ 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.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.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.description: space for a photo
|
||||
§ page.person.total.title: Main characteristics
|
||||
|
|
|
@ -34,6 +34,7 @@ export default `
|
|||
§ sidebar.team.department: Отделы
|
||||
§ sidebar.team.country: Местоположение
|
||||
§ sidebar.team.settings: Настройки
|
||||
§ sidebar.team.recommendations: Рекомендации и факты
|
||||
§ sidebar.team.building: Мини игры
|
||||
§ sidebar.person.total: Общая информация
|
||||
§ sidebar.person.money: Стоимость работы
|
||||
|
|
|
@ -269,6 +269,10 @@ export default `
|
|||
§ page.team.building.quiz.result2.description: Правильных ответов от 40% до 70%. Вы имеете хорошее представление о вашей команде, но можете узнать её лучше. Ознакомьтесь с данными в соседних разделах и попробуйте снова!
|
||||
§ page.team.building.quiz.result3.title: Отлично
|
||||
§ 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.description: место для фотографии
|
||||
§ page.person.total.title: Основные характеристики
|
||||
|
|
|
@ -35,6 +35,8 @@ export default `
|
|||
§ sidebar.team.department: Departments
|
||||
§ sidebar.team.country: Locations
|
||||
§ sidebar.team.settings: 设置
|
||||
§ sidebar.team.recommendations: Recommendations and facts
|
||||
§ sidebar.team.building: Games
|
||||
§ sidebar.person.total: 般资料
|
||||
§ sidebar.person.money: 工作的成本
|
||||
§ 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.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.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.description: 拍照的地方
|
||||
§ page.person.total.title: 主要特点
|
||||
|
|
Loading…
Reference in a new issue