mirror of
https://github.com/bakhirev/assayo.git
synced 2025-09-01 10:09:39 +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 {
|
||||
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…
Add table
Reference in a new issue