mirror of
https://github.com/bakhirev/assayo.git
synced 2025-02-22 13:02:18 +00:00
update
This commit is contained in:
parent
88452159ae
commit
118c337585
File diff suppressed because one or more lines are too long
|
@ -13,7 +13,7 @@ interface IGetItemProps {
|
|||
}
|
||||
|
||||
function GetItem({ commit, mode }: IGetItemProps) {
|
||||
const size = commit.taskNumber?.length || 1;
|
||||
const size = `${commit.taskNumber}`.length || 1;
|
||||
const className = size > 5
|
||||
? style.get_list_big_number
|
||||
: '';
|
||||
|
|
|
@ -52,5 +52,5 @@ export default function getSubLines(
|
|||
if (other.length === 0) return normal;
|
||||
if (other.length === 1) return allItems;
|
||||
return [...normal, getFormattedOther(other, normalWidth, options)]
|
||||
.filter((item: any) => item.width > 1);
|
||||
.filter((item: any) => item.width >= 1);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ function LineChart({
|
|||
details,
|
||||
className,
|
||||
}: ILineChartProps): React.ReactElement | null {
|
||||
if (value === 0) return null;
|
||||
if (value === 0 || (!value && !details)) return null;
|
||||
|
||||
let width = Math.round((value || 100) * (100 / options.max));
|
||||
if (width < 1) return null;
|
||||
|
|
|
@ -36,7 +36,7 @@ function DefaultCell({
|
|||
: value;
|
||||
|
||||
const content: any = typeof column.template === 'function'
|
||||
? column.template(formattedValue, row)
|
||||
? column.template(formattedValue, row, rowIndex)
|
||||
: `${column.prefixes ?? ''}${formattedValue ?? ''}${column.suffixes ?? ''}`;
|
||||
|
||||
const cellTitle = typeof content === 'string' && content.length > 20
|
||||
|
|
|
@ -37,8 +37,9 @@ export default class DataGripByPR {
|
|||
message: commit.message,
|
||||
dateCreate: commit.milliseconds, // last commit date before PR
|
||||
dateMerge: commit.milliseconds,
|
||||
daysReview: 1,
|
||||
daysBacklog: 1,
|
||||
daysInWork: 1,
|
||||
daysReview: 1,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -68,6 +69,7 @@ export default class DataGripByPR {
|
|||
// TODO он не мог быть пустым. Надо расследовать TASK-110 в тестовой выборке.
|
||||
pr.dateCreate = lastCommitDateBeforePR || pr.dateCreate;
|
||||
pr.daysReview = ((pr.dateMerge - pr.dateCreate) || ONE_DAY) / ONE_DAY;
|
||||
pr.daysBacklog = ((pr.dateCreate - task.createdBefore) || ONE_DAY) / ONE_DAY;
|
||||
|
||||
const list = byAuthor.get(pr.author);
|
||||
if (list) list.push(pr);
|
||||
|
@ -132,6 +134,9 @@ export default class DataGripByPR {
|
|||
const daysReview = DataGripByPR.getPRByGroups(prs, 'daysReview');
|
||||
const daysReviewWeightedAverage = parseInt(daysReview.weightedAverage.toFixed(1), 10);
|
||||
|
||||
const daysBacklog = DataGripByPR.getPRByGroups(prs, 'daysBacklog');
|
||||
const daysBacklogWeightedAverage = parseInt(daysBacklog.weightedAverage.toFixed(1), 10);
|
||||
|
||||
const daysInWork = DataGripByPR.getPRByGroups(prs, 'daysInWork');
|
||||
const daysInWorkWeightedAverage = parseInt(daysInWork.weightedAverage.toFixed(1), 10);
|
||||
|
||||
|
@ -142,10 +147,12 @@ export default class DataGripByPR {
|
|||
|
||||
workDays: daysInWork.details,
|
||||
delayDays: daysReview.details,
|
||||
weightedAverage: daysInWorkWeightedAverage + daysReviewWeightedAverage,
|
||||
daysBacklog: daysBacklog.details,
|
||||
weightedAverage: daysInWorkWeightedAverage + daysReviewWeightedAverage + daysBacklogWeightedAverage,
|
||||
weightedAverageDetails: {
|
||||
workDays: daysInWorkWeightedAverage,
|
||||
delayDays: daysReviewWeightedAverage,
|
||||
daysBacklog: daysBacklogWeightedAverage,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
|
126
src/ts/helpers/DataGrip/components/taskNumbers.ts
Normal file
126
src/ts/helpers/DataGrip/components/taskNumbers.ts
Normal file
|
@ -0,0 +1,126 @@
|
|||
import ICommit from 'ts/interfaces/Commit';
|
||||
import { HashMap } from 'ts/interfaces/HashMap';
|
||||
import { WeightedAverage } from 'ts/helpers/Math';
|
||||
|
||||
export default class DataGripByTaskNumbers {
|
||||
commits: HashMap<any> = new Map();
|
||||
|
||||
statistic: any = [];
|
||||
|
||||
clear() {
|
||||
this.commits.clear();
|
||||
this.statistic = [];
|
||||
}
|
||||
|
||||
addCommit(commit: ICommit) {
|
||||
if (!commit.taskCode || !commit.week) return;
|
||||
const statistic = this.commits.get(commit.taskCode);
|
||||
if (statistic) {
|
||||
this.#updateCommitByTaskCode(statistic, commit);
|
||||
} else {
|
||||
this.#addCommitByTaskCode(commit);
|
||||
}
|
||||
}
|
||||
|
||||
#updateCommitByTaskCode(statistic: any, commit: ICommit) {
|
||||
const data = statistic.weekTaskNumber.get(commit.week);
|
||||
if (data) {
|
||||
if (data.max < commit.taskNumber) data.max = commit.taskNumber;
|
||||
data.all.add(commit.taskNumber);
|
||||
data.authors.add(commit.author);
|
||||
} else {
|
||||
this.#addWeekInfo(statistic.weekTaskNumber, commit);
|
||||
}
|
||||
}
|
||||
|
||||
#addWeekInfo(data: any, commit: ICommit) {
|
||||
data.set(commit.week, {
|
||||
week: commit.week * (-1),
|
||||
date: commit.timestamp,
|
||||
month: commit.month,
|
||||
year: commit.year,
|
||||
max: commit.taskNumber,
|
||||
all: new Set([commit.taskNumber]),
|
||||
authors: new Set([commit.author]),
|
||||
});
|
||||
}
|
||||
|
||||
#addCommitByTaskCode(commit: ICommit) {
|
||||
const weekTaskNumber = new Map();
|
||||
this.commits.set(commit.taskCode, {
|
||||
taskCode: commit.taskCode,
|
||||
weekTaskNumber,
|
||||
});
|
||||
this.#addWeekInfo(weekTaskNumber, commit);
|
||||
}
|
||||
|
||||
updateTotalInfo() {
|
||||
this.statistic = {};
|
||||
|
||||
Array.from(this.commits.values()).forEach((dot: any) => {
|
||||
const weeks = Array.from(dot.weekTaskNumber.values())
|
||||
.sort((a: any, b: any) => a.week - b.week) as any;
|
||||
|
||||
const weightedAverage = new WeightedAverage();
|
||||
const months: any = [];
|
||||
let tasks = 0;
|
||||
let fixed = 0;
|
||||
let authors = 0;
|
||||
let monthIndex = weeks[0].month;
|
||||
let prev = 0;
|
||||
|
||||
weeks.forEach((week: any) => {
|
||||
let newTasks = week.max - prev;
|
||||
newTasks = newTasks > 0 ? newTasks : 0;
|
||||
prev = week.max > prev ? week.max : prev;
|
||||
|
||||
if (monthIndex === week.month) {
|
||||
tasks += newTasks;
|
||||
fixed += week.all.size;
|
||||
authors += week.authors.size;
|
||||
return;
|
||||
}
|
||||
|
||||
monthIndex = week.month;
|
||||
|
||||
const allAuthors = tasks > 0 && authors > 1
|
||||
? Math.floor(tasks / (fixed / authors))
|
||||
: 0;
|
||||
|
||||
const weeksInMonth = 4;
|
||||
const allAuthors1 = Math.floor(allAuthors / weeksInMonth);
|
||||
months.push({
|
||||
date: week.date,
|
||||
year: week.year,
|
||||
tasks,
|
||||
tasksInWeek: Math.floor(tasks / weeksInMonth),
|
||||
fixed: Math.floor(fixed / weeksInMonth),
|
||||
authors: Math.floor(authors / weeksInMonth) || 1,
|
||||
allAuthors: allAuthors1 || 1,
|
||||
});
|
||||
|
||||
if (allAuthors1 > 1) weightedAverage.update(allAuthors1);
|
||||
|
||||
tasks = newTasks;
|
||||
fixed = week.all.size;
|
||||
authors = week.authors.size;
|
||||
});
|
||||
|
||||
const limit = weightedAverage.get() * 2;
|
||||
const formattedList = months
|
||||
.filter((item: any) => (
|
||||
item.authors > 1
|
||||
&& item.tasks > 0
|
||||
&& item.allAuthors > 1
|
||||
&& item.allAuthors < limit
|
||||
))
|
||||
.reverse();
|
||||
|
||||
if (formattedList.length) {
|
||||
this.statistic[dot.taskCode] = formattedList;
|
||||
}
|
||||
});
|
||||
|
||||
this.commits.clear();
|
||||
}
|
||||
}
|
64
src/ts/helpers/DataGrip/components/taskNumbersDate.ts
Normal file
64
src/ts/helpers/DataGrip/components/taskNumbersDate.ts
Normal file
|
@ -0,0 +1,64 @@
|
|||
import ICommit from 'ts/interfaces/Commit';
|
||||
import { HashMap } from 'ts/interfaces/HashMap';
|
||||
import { ONE_DAY } from 'ts/helpers/formatter';
|
||||
|
||||
export default class DataGripByTaskNumbersDate {
|
||||
commits: HashMap<any> = new Map();
|
||||
|
||||
clear() {
|
||||
this.commits.clear();
|
||||
}
|
||||
|
||||
addCommit(commit: ICommit) {
|
||||
if (!commit.taskCode || !commit.week) return;
|
||||
const statistic = this.commits.get(commit.taskCode);
|
||||
if (statistic) {
|
||||
this.#updateCommitByTaskCode(statistic, commit);
|
||||
} else {
|
||||
this.#addCommitByTaskCode(commit);
|
||||
}
|
||||
}
|
||||
|
||||
#updateCommitByTaskCode(statistic: any, commit: ICommit) {
|
||||
const milliseconds = statistic.taskNumbers.get(commit.taskNumber);
|
||||
if (!milliseconds || commit.milliseconds < milliseconds) {
|
||||
statistic.taskNumbers.set(commit.taskNumber, {
|
||||
task: commit.task,
|
||||
milliseconds: commit.milliseconds,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#addCommitByTaskCode(commit: ICommit) {
|
||||
const taskNumbers = new Map();
|
||||
taskNumbers.set(commit.taskNumber, {
|
||||
task: commit.task,
|
||||
milliseconds: commit.milliseconds,
|
||||
});
|
||||
this.commits.set(commit.taskCode, {
|
||||
taskCode: commit.taskCode,
|
||||
taskNumbers,
|
||||
});
|
||||
}
|
||||
|
||||
updateTotalInfo(dataGripByTasks: any) {
|
||||
Array.from(this.commits.values()).forEach((dot: any) => {
|
||||
const taskNumbers = Array.from(dot.taskNumbers.entries())
|
||||
.sort((a: any, b: any) => a[0] - b[0])
|
||||
.reverse();
|
||||
|
||||
taskNumbers.forEach((item: any, index: number) => {
|
||||
const next = taskNumbers[index + 1];
|
||||
if (!next) return;
|
||||
if (item[1].milliseconds <= next[1].milliseconds) return;
|
||||
item[1].milliseconds = next[1].milliseconds;
|
||||
|
||||
const task = dataGripByTasks.statisticByName.get(item[1].task);
|
||||
task.createdBefore = next[1].milliseconds;
|
||||
task.daysInJira = (task.from - task.createdBefore) / ONE_DAY;
|
||||
});
|
||||
});
|
||||
|
||||
this.commits.clear();
|
||||
}
|
||||
}
|
|
@ -79,6 +79,8 @@ export default class DataGripByTasks {
|
|||
commits: commits.length,
|
||||
timestamps: Array.from(timestamps),
|
||||
daysInWork,
|
||||
daysInJira: 1, // заполняются в taskNumbersDate
|
||||
createdBefore: from,
|
||||
comments,
|
||||
authors,
|
||||
types,
|
||||
|
|
|
@ -15,6 +15,8 @@ import DataGripByTasks from './components/tasks';
|
|||
import DataGripByRelease from './components/release';
|
||||
import DataGripByScoring from './components/scoring';
|
||||
import DataGripByTaskCodes from './components/taskCodes';
|
||||
import DataGripByTaskNumbers from './components/taskNumbers';
|
||||
import DataGripByTaskNumbersDate from './components/taskNumbersDate';
|
||||
import DataGripByCompany from './components/company';
|
||||
import DataGripByCountry from './components/country';
|
||||
|
||||
|
@ -51,6 +53,10 @@ class DataGrip {
|
|||
|
||||
taskCodes: any = new DataGripByTaskCodes();
|
||||
|
||||
taskNumbers: any = new DataGripByTaskNumbers();
|
||||
|
||||
taskNumbersDate: any = new DataGripByTaskNumbersDate();
|
||||
|
||||
clear() {
|
||||
this.firstLastCommit.clear();
|
||||
this.author.clear();
|
||||
|
@ -68,6 +74,8 @@ class DataGrip {
|
|||
this.release.clear();
|
||||
this.scoring.clear();
|
||||
this.taskCodes.clear();
|
||||
this.taskNumbers.clear();
|
||||
this.taskNumbersDate.clear();
|
||||
}
|
||||
|
||||
addCommit(commit: ICommit | ISystemCommit, totalCommits: number) {
|
||||
|
@ -84,6 +92,8 @@ class DataGrip {
|
|||
this.week.addCommit(commit);
|
||||
this.tasks.addCommit(commit);
|
||||
this.taskCodes.addCommit(commit);
|
||||
this.taskNumbers.addCommit(commit);
|
||||
this.taskNumbersDate.addCommit(commit);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,12 +106,14 @@ class DataGrip {
|
|||
this.week.updateTotalInfo(this.author);
|
||||
this.recommendations.updateTotalInfo(this);
|
||||
this.tasks.updateTotalInfo();
|
||||
this.taskNumbersDate.updateTotalInfo(this.tasks);
|
||||
this.pr.updateTotalInfo(this.tasks, this.author);
|
||||
this.release.updateTotalInfo(this.tasks, this.pr);
|
||||
this.scoring.updateTotalInfo(this.author, this.timestamp);
|
||||
this.company.updateTotalInfo(this.author);
|
||||
this.country.updateTotalInfo(this.author);
|
||||
this.taskCodes.updateTotalInfo(this.firstLastCommit.maxData, this.author);
|
||||
this.taskNumbers.updateTotalInfo();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,3 @@ export function increment(object: Object, path: string) {
|
|||
export function createIncrement(key?: string, firstValue?: any) {
|
||||
return key ? { [key]: firstValue || 1 } : {};
|
||||
}
|
||||
|
||||
export function createHashMap(key?: string) {
|
||||
return createIncrement(key, true);
|
||||
}
|
||||
|
|
|
@ -74,9 +74,24 @@ export function getTask(message: string) {
|
|||
return ((message || '').match(/(([A-Z]+[-_])|(#)|(gh-)|(GH-))([0-9]+)/gm) || [])[0] || '';
|
||||
}
|
||||
|
||||
// ABC-123 => '123';
|
||||
// ABC-123 => 123;
|
||||
const stringToNumber = new Map();
|
||||
(new Array(100000)).fill(1).map((k, i) => {
|
||||
stringToNumber.set(`${i}`, i);
|
||||
});
|
||||
export function getTaskNumber(task?: string) {
|
||||
return (task || '').replace(/[^0-9]+/gim, '');
|
||||
const onlyNumbers = (task || '').replace(/[^0-9]+/gim, '');
|
||||
if (onlyNumbers === '0') {
|
||||
return 0;
|
||||
}
|
||||
if (stringToNumber[onlyNumbers]) {
|
||||
return stringToNumber[onlyNumbers];
|
||||
}
|
||||
const value = parseInt(onlyNumbers, 10);
|
||||
if (value || value === 0) {
|
||||
return value;
|
||||
}
|
||||
return onlyNumbers;
|
||||
}
|
||||
|
||||
// ABC-123 => 'ABC';
|
||||
|
|
|
@ -56,10 +56,22 @@ export function get2Number(time: number) {
|
|||
return time < 10 ? `0${time}` : time;
|
||||
}
|
||||
|
||||
export function getDate(timestamp: string) {
|
||||
export function getCustomDate(timestamp: string, options?: any) {
|
||||
if (!timestamp) return '';
|
||||
const date = new Date(timestamp);
|
||||
return date.toLocaleString(getLangPrefix(), { day: 'numeric', month: 'long', year: 'numeric' });
|
||||
return date.toLocaleString(getLangPrefix(), options || { day: 'numeric', month: 'long', year: 'numeric' });
|
||||
}
|
||||
|
||||
export function getDate(timestamp: string) {
|
||||
return getCustomDate(timestamp, { day: 'numeric', month: 'long', year: 'numeric' });
|
||||
}
|
||||
|
||||
export function getShortDate(timestamp: string) {
|
||||
return getCustomDate(timestamp, { day: 'numeric', month: 'long' });
|
||||
}
|
||||
|
||||
export function getShortTime(timestamp: string) {
|
||||
return getCustomDate(timestamp, { hour: 'numeric', minute: 'numeric' });
|
||||
}
|
||||
|
||||
export function getDateForExcel(timestamp: string) {
|
||||
|
@ -68,19 +80,6 @@ export function getDateForExcel(timestamp: string) {
|
|||
return date.toISOString().substring(0, 10).split('-').reverse().join('.');
|
||||
}
|
||||
|
||||
export function getShortDate(timestamp: string) {
|
||||
if (!timestamp) return '';
|
||||
const date = new Date(timestamp);
|
||||
return date.toLocaleString(getLangPrefix(), { day: 'numeric', month: 'long' });
|
||||
}
|
||||
|
||||
export function getShortTime(timestamp: string) {
|
||||
if (!timestamp) return '';
|
||||
const date = new Date(timestamp);
|
||||
return date.toLocaleString(getLangPrefix(), { hour: 'numeric', minute: 'numeric' });
|
||||
}
|
||||
|
||||
|
||||
function getCurrencyFromUSD(money: number, currency: string) {
|
||||
if (currency === 'USD' || !money) return money;
|
||||
const k = {
|
||||
|
|
|
@ -37,7 +37,7 @@ export interface ILog {
|
|||
message: string; // "JIRA-0000 fix(profile): add new avatar",
|
||||
text: string; // "add new avatar"
|
||||
task: string; // "JIRA-0000",
|
||||
taskNumber: string; // "0000",
|
||||
taskNumber: number; // "0000",
|
||||
taskCode: string; // "JIRA",
|
||||
type: string; // feat|fix|docs|style|refactor|test|chore
|
||||
scope: string; // table, sale, profile and etc.
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
import React from 'react';
|
||||
|
||||
import { IPagination } from 'ts/interfaces/Pagination';
|
||||
import { getCustomDate } from 'ts/helpers/formatter';
|
||||
|
||||
import DataView from 'ts/components/DataView';
|
||||
import Column from 'ts/components/Table/components/Column';
|
||||
import { ColumnTypesEnum } from 'ts/components/Table/interfaces/Column';
|
||||
import LineChart from 'ts/components/LineChart';
|
||||
import getOptions from 'ts/components/LineChart/helpers/getOptions';
|
||||
import { getMax } from 'ts/pages/Common/helpers/getMax';
|
||||
|
||||
interface MonthsProps {
|
||||
response?: IPagination<any>;
|
||||
updateSort?: Function;
|
||||
rowsForExcel?: any[];
|
||||
mode?: string;
|
||||
}
|
||||
|
||||
export function Months({ response, updateSort, rowsForExcel, mode }: MonthsProps) {
|
||||
if (!response) return null;
|
||||
|
||||
const allAuthorsChart = getOptions({
|
||||
max: getMax(response, 'allAuthors'),
|
||||
suffix: 'page.team.department.months.allAuthors',
|
||||
});
|
||||
|
||||
return (
|
||||
<DataView
|
||||
rowsForExcel={rowsForExcel}
|
||||
rows={response.content}
|
||||
sort={response.sort}
|
||||
updateSort={updateSort}
|
||||
type={mode === 'print' ? 'cards' : undefined}
|
||||
columnCount={mode === 'print' ? 3 : undefined}
|
||||
>
|
||||
<Column
|
||||
isFixed
|
||||
title="page.team.department.months.date"
|
||||
template={(row: any, b: any, index: number) => {
|
||||
const next = response.content[index + 1];
|
||||
const value = getCustomDate(row.date, { month: 'long', year: 'numeric' });
|
||||
return next?.year !== row.year
|
||||
? (<b>{value}</b>)
|
||||
: value;
|
||||
}}
|
||||
width={150}
|
||||
/>
|
||||
<Column
|
||||
template={ColumnTypesEnum.NUMBER}
|
||||
properties="tasks"
|
||||
title="page.team.department.months.tasks"
|
||||
width={100}
|
||||
/>
|
||||
<Column
|
||||
template={ColumnTypesEnum.SHORT_NUMBER}
|
||||
properties="tasksInWeek"
|
||||
title="page.team.department.months.tasksInWeek"
|
||||
width={100}
|
||||
/>
|
||||
<Column
|
||||
template={ColumnTypesEnum.SHORT_NUMBER}
|
||||
properties="fixed"
|
||||
title="page.team.department.months.fixed"
|
||||
width={100}
|
||||
/>
|
||||
<Column
|
||||
template={ColumnTypesEnum.SHORT_NUMBER}
|
||||
properties="authors"
|
||||
title="page.team.department.months.authors"
|
||||
width={150}
|
||||
/>
|
||||
<Column
|
||||
template={ColumnTypesEnum.SHORT_NUMBER}
|
||||
properties="allAuthors"
|
||||
width={70}
|
||||
/>
|
||||
<Column
|
||||
isSortable
|
||||
width={200}
|
||||
properties="allAuthors"
|
||||
title="page.team.department.months.allAuthors"
|
||||
template={(value: number) => (
|
||||
<LineChart
|
||||
options={allAuthorsChart}
|
||||
value={value}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</DataView>
|
||||
);
|
||||
}
|
||||
|
||||
Months.defaultProps = {
|
||||
response: undefined,
|
||||
};
|
||||
|
||||
export default Months;
|
|
@ -1,27 +1,40 @@
|
|||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { IPaginationRequest } from 'ts/interfaces/Pagination';
|
||||
import ISort from 'ts/interfaces/Sort';
|
||||
import dataGripStore from 'ts/store/DataGrip';
|
||||
import fullScreen from 'ts/store/FullScreen';
|
||||
|
||||
import Title from 'ts/components/Title';
|
||||
import Description from 'ts/components/Description';
|
||||
import DataLoader from 'ts/components/DataLoader';
|
||||
import Pagination from 'ts/components/DataLoader/components/Pagination';
|
||||
import getFakeLoader from 'ts/components/DataLoader/helpers/formatter';
|
||||
import SelectWithButtons from 'ts/components/UiKit/components/SelectWithButtons';
|
||||
import NothingFound from 'ts/components/NothingFound';
|
||||
import Title from 'ts/components/Title';
|
||||
|
||||
import ICommonPageProps from 'ts/components/Page/interfaces/CommonPageProps';
|
||||
import PageWrapper from 'ts/components/Page/wrapper';
|
||||
|
||||
import Departments from './components/Departments';
|
||||
import DepartmentCharts from './components/Charts';
|
||||
import Months from './components/Months';
|
||||
|
||||
import style from '../../styles/filters.module.scss';
|
||||
|
||||
const Department = observer(({
|
||||
mode,
|
||||
}: ICommonPageProps): React.ReactElement | null => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const byMonths = dataGripStore.dataGrip.taskNumbers.statistic;
|
||||
const content = dataGripStore.dataGrip.taskCodes.statistic
|
||||
.filter((item: any) => item.totalDaysWorked > 10);
|
||||
const options = Object.keys(byMonths).map((id: string) => ({ id }));
|
||||
|
||||
const [taskCode, setTaskCode] = useState(options[0].id);
|
||||
|
||||
if (!content?.length) {
|
||||
return <NothingFound />;
|
||||
|
@ -42,6 +55,33 @@ const Department = observer(({
|
|||
<Departments />
|
||||
<Pagination />
|
||||
</DataLoader>
|
||||
|
||||
<Title title="page.team.department.months.title"/>
|
||||
<PageWrapper>
|
||||
<div className={style.table_filters}>
|
||||
<SelectWithButtons
|
||||
title="page.team.tree.filters.author"
|
||||
value={taskCode}
|
||||
className={style.table_filters_item}
|
||||
options={options}
|
||||
onChange={(value: string) => {
|
||||
console.log(value);
|
||||
setTaskCode(value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</PageWrapper>
|
||||
<DataLoader
|
||||
to="response"
|
||||
loader={(pagination?: IPaginationRequest, sort?: ISort[]) => getFakeLoader({
|
||||
content: byMonths[taskCode], pagination, sort, mode,
|
||||
})}
|
||||
watch={taskCode}
|
||||
>
|
||||
<Months/>
|
||||
<Pagination />
|
||||
</DataLoader>
|
||||
<Description text={t('page.team.department.months.description')} />
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -21,19 +21,38 @@ function Total() {
|
|||
const delayChart = DataGripByPR.getPRByGroups(allPR, 'daysReview');
|
||||
const delayChartOptions = getOptions({ order: delayChart.order, limit: 3, suffix: 'PR' });
|
||||
|
||||
const backlogChart = DataGripByPR.getPRByGroups(allPR, 'daysBacklog');
|
||||
const backlogChartOptions = getOptions({ order: backlogChart.order, limit: 3, suffix: 'PR' });
|
||||
|
||||
const workDaysWeightedAverage = Math.round(workChart.weightedAverage);
|
||||
const delayDaysWeightedAverage = Math.round(delayChart.weightedAverage);
|
||||
const weightedAverage = workDaysWeightedAverage + delayDaysWeightedAverage;
|
||||
|
||||
const weightedAverageChart = getOptions({ // @ts-ignore
|
||||
order: ['page.team.pr.word', 'page.team.pr.delay'],
|
||||
order: [
|
||||
'page.team.pr.word',
|
||||
'page.team.pr.delay',
|
||||
],
|
||||
suffix: 'page.team.pr.days',
|
||||
});
|
||||
|
||||
console.log(weightedAverage.toFixed(1));
|
||||
|
||||
return (
|
||||
<PageWrapper>
|
||||
<PageColumn>
|
||||
<PieChart
|
||||
title="page.team.pr.backlogDays"
|
||||
options={backlogChartOptions}
|
||||
details={backlogChart.details}
|
||||
/>
|
||||
<PieChart
|
||||
title="page.team.pr.delayDays"
|
||||
options={delayChartOptions}
|
||||
details={delayChart.details}
|
||||
/>
|
||||
<Description text={t('page.team.pr.description3')}/>
|
||||
<Description text={t('page.team.pr.description2')}/>
|
||||
<br/>
|
||||
<br/>
|
||||
</PageColumn>
|
||||
<PageColumn>
|
||||
<PieChart
|
||||
title="page.team.pr.workDays"
|
||||
|
@ -48,16 +67,7 @@ function Total() {
|
|||
'page.team.pr.delay': delayDaysWeightedAverage,
|
||||
}}
|
||||
/>
|
||||
</PageColumn>
|
||||
<PageColumn>
|
||||
<PieChart
|
||||
title="page.team.pr.delayDays"
|
||||
options={delayChartOptions}
|
||||
details={delayChart.details}
|
||||
/>
|
||||
<Description text={t('page.team.pr.description1')}/>
|
||||
<Description text={t('page.team.pr.description2')} />
|
||||
<Description text={t('page.team.pr.description3')} />
|
||||
</PageColumn>
|
||||
</PageWrapper>
|
||||
);
|
||||
|
|
73
src/ts/pages/Team/components/Tasks/BacklogCharts.tsx
Normal file
73
src/ts/pages/Team/components/Tasks/BacklogCharts.tsx
Normal file
|
@ -0,0 +1,73 @@
|
|||
import React from 'react';
|
||||
|
||||
import IHashMap from 'ts/interfaces/HashMap';
|
||||
import PieChart from 'ts/components/PieChart';
|
||||
import getOptions from 'ts/components/LineChart/helpers/getOptions';
|
||||
import PageWrapper from 'ts/components/Page/wrapper';
|
||||
import PageColumn from 'ts/components/Page/column';
|
||||
|
||||
import dataGripStore from 'ts/store/DataGrip';
|
||||
import { increment } from 'ts/helpers/Math';
|
||||
|
||||
interface BacklogChartsProps {
|
||||
content: any[],
|
||||
allTaskNumber: number,
|
||||
backlogTaskNumber: number,
|
||||
}
|
||||
|
||||
function getGroupsByAuthors(list: any[], propertyName: string) {
|
||||
return list.reduce((acc: IHashMap<number>, item: any) => {
|
||||
increment(acc, item[propertyName]);
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
function BacklogCharts({
|
||||
content,
|
||||
allTaskNumber,
|
||||
backlogTaskNumber,
|
||||
}: BacklogChartsProps) {
|
||||
if (!content?.length) return null;
|
||||
|
||||
const authors = dataGripStore.dataGrip.author.list;
|
||||
|
||||
const authorDetails = getGroupsByAuthors(content, 'author');
|
||||
const authorChartOptions = getOptions({
|
||||
order: authors,
|
||||
limit: 3,
|
||||
suffix: 'tasks',
|
||||
other: 'page.team.tasks.charts.authors.other',
|
||||
});
|
||||
|
||||
const weightedAverageChart = getOptions({ // @ts-ignore
|
||||
order: [
|
||||
'page.team.tasks.charts.relative.backlog',
|
||||
'page.team.tasks.charts.relative.all',
|
||||
],
|
||||
suffix: 'page.team.pr.days',
|
||||
});
|
||||
|
||||
return (
|
||||
<PageWrapper>
|
||||
<PageColumn>
|
||||
<PieChart
|
||||
title="page.team.tasks.charts.authors.title"
|
||||
options={authorChartOptions}
|
||||
details={authorDetails}
|
||||
/>
|
||||
</PageColumn>
|
||||
<PageColumn>
|
||||
<PieChart
|
||||
title="page.team.tasks.charts.relative.title"
|
||||
options={weightedAverageChart}
|
||||
details={{
|
||||
'page.team.tasks.charts.relative.all': allTaskNumber - backlogTaskNumber,
|
||||
'page.team.tasks.charts.relative.backlog': backlogTaskNumber,
|
||||
}}
|
||||
/>
|
||||
</PageColumn>
|
||||
</PageWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
export default BacklogCharts;
|
|
@ -8,6 +8,9 @@ import Column from 'ts/components/Table/components/Column';
|
|||
import { ColumnTypesEnum } from 'ts/components/Table/interfaces/Column';
|
||||
import UiKitTags from 'ts/components/UiKit/components/Tags';
|
||||
import { PRLink, TaskLink } from 'ts/components/ExternalLink';
|
||||
import LineChart from 'ts/components/LineChart';
|
||||
import getOptions from 'ts/components/LineChart/helpers/getOptions';
|
||||
import { getMax } from 'ts/pages/Common/helpers/getMax';
|
||||
|
||||
import { getDate } from 'ts/helpers/formatter';
|
||||
|
||||
|
@ -23,6 +26,8 @@ interface ViewProps {
|
|||
export function View({ response, updateSort, rowsForExcel, mode }: ViewProps) {
|
||||
if (!response) return null;
|
||||
|
||||
const backlogChart = getOptions({ max: getMax(response, 'daysInJira') });
|
||||
|
||||
return (
|
||||
<DataView
|
||||
rowsForExcel={rowsForExcel}
|
||||
|
@ -101,6 +106,30 @@ export function View({ response, updateSort, rowsForExcel, mode }: ViewProps) {
|
|||
properties="author"
|
||||
width={170}
|
||||
/>
|
||||
<Column
|
||||
template={ColumnTypesEnum.STRING}
|
||||
title="page.team.tasks.createdBefore"
|
||||
properties="createdBefore"
|
||||
width={150}
|
||||
formatter={getDate}
|
||||
/>
|
||||
<Column
|
||||
template={ColumnTypesEnum.SHORT_NUMBER}
|
||||
properties="daysInJira"
|
||||
width={50}
|
||||
/>
|
||||
<Column
|
||||
isSortable
|
||||
title="page.team.tasks.backlog"
|
||||
properties="daysInJira"
|
||||
minWidth={150}
|
||||
template={(value: any) => (
|
||||
<LineChart
|
||||
options={backlogChart}
|
||||
value={value}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Column
|
||||
template={ColumnTypesEnum.STRING}
|
||||
title="page.team.tasks.from"
|
||||
|
|
|
@ -13,6 +13,7 @@ import NothingFound from 'ts/components/NothingFound';
|
|||
import Title from 'ts/components/Title';
|
||||
import PageWrapper from 'ts/components/Page/wrapper';
|
||||
|
||||
import BacklogCharts from './BacklogCharts';
|
||||
import Filters from './Filters';
|
||||
import View from './View';
|
||||
|
||||
|
@ -46,14 +47,19 @@ const Tasks = observer(({
|
|||
mode,
|
||||
}: ICommonPageProps): React.ReactElement | null => {
|
||||
const rows = dataGripStore.dataGrip.tasks.statistic;
|
||||
const backlogRows = rows
|
||||
.filter((task: any) => task.daysInJira > 90);
|
||||
|
||||
const [filters, setFilters] = useState<any>({ user: 0, company: 0 });
|
||||
const content = getContentByFilters(rows, filters);
|
||||
const backlogContent = getContentByFilters(backlogRows, filters);
|
||||
const hash = [
|
||||
mode,
|
||||
dataGripStore.hash,
|
||||
filters.user,
|
||||
filters.company,
|
||||
content.length,
|
||||
backlogContent.length,
|
||||
].join('.');
|
||||
|
||||
if (!rows?.length) return mode !== 'print' ? (<NothingFound />) : null;
|
||||
|
@ -80,6 +86,29 @@ const Tasks = observer(({
|
|||
/>
|
||||
<Pagination/>
|
||||
</DataLoader>
|
||||
|
||||
<Title title="page.team.tasks.backlogTitle"/>
|
||||
<BacklogCharts
|
||||
content={backlogContent}
|
||||
allTaskNumber={content.length}
|
||||
backlogTaskNumber={backlogContent.length}
|
||||
/>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<DataLoader
|
||||
to="response"
|
||||
loader={(pagination?: IPaginationRequest, sort?: ISort[]) => getFakeLoader({
|
||||
content: backlogContent, pagination, sort, mode,
|
||||
})}
|
||||
watch={hash}
|
||||
>
|
||||
<View
|
||||
mode={mode}
|
||||
rowsForExcel={backlogContent}
|
||||
/>
|
||||
<Pagination/>
|
||||
</DataLoader>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -176,6 +176,7 @@ export default `
|
|||
§ page.team.pr.lastCommitTime: Last
|
||||
§ page.team.pr.workDays: Development days
|
||||
§ page.team.pr.delayDays: Days waiting for merge
|
||||
§ page.team.pr.backlogDays: The delay of the task in the backlog before the start of development
|
||||
§ page.team.pr.middleTimeRelease: Average delivery time (days)
|
||||
§ page.team.pr.chart.1day: day
|
||||
§ page.team.pr.chart.3day: three days
|
||||
|
@ -192,17 +193,25 @@ export default `
|
|||
§ page.team.pr.oneTaskDays: Time spent on one task
|
||||
§ page.team.pr.description1: *Development time* is the time difference from the first to the last commit on a task. It does not matter if there were breaks of several days between commits or not. Any commit increases the time.
|
||||
§ page.team.pr.description2: *Waiting time* is the time between the last commit and the code merge. It shows the actual downtime while waiting for something.
|
||||
§ page.team.pr.description3: *Why display development time* without splitting into coding and code review? To show the business the actual delivery time of the code. Waiting for testing, review comments, DevOps problems, and other process imperfections are already included in this term.
|
||||
§ page.team.pr.description3: *Task creation date* in the task tracker is calculated by its sequential number and the minimum date of any next Issue in the code. The method has a margin of error and, as a rule, the tasks turn out to be older. Frequent releases, fast bugfixes, and a large number of employees working on the code reduce this margin of error.
|
||||
§ page.team.pr.statByAuthors: Statistics by employees
|
||||
§ page.team.pr.longDelay: Prolonged Waiting for merge
|
||||
§ page.team.pr.anonymous: PR without task number
|
||||
§ page.team.pr.branch: Branch
|
||||
§ page.team.tasks.task: Task
|
||||
§ page.team.tasks.author: First commit author
|
||||
§ page.team.tasks.createdBefore: Created before
|
||||
§ page.team.tasks.backlog: Development waiting
|
||||
§ page.team.tasks.from: First commit
|
||||
§ page.team.tasks.to: Last commit
|
||||
§ page.team.tasks.daysInWork: Days in work
|
||||
§ page.team.tasks.comments: Comments
|
||||
§ page.team.tasks.backlogTitle: Tasks undeveloped for over four months after being added to the task-tracker
|
||||
§ page.team.tasks.charts.authors.title: Who is doing these tasks?
|
||||
§ page.team.tasks.charts.authors.other: and etc.
|
||||
§ page.team.tasks.charts.relative.title: Count relative to other tasks
|
||||
§ page.team.tasks.charts.relative.backlog: backlog
|
||||
§ page.team.tasks.charts.relative.all: other tasks
|
||||
§ page.team.extension.extension: File extensions
|
||||
§ page.team.extension.type: File sub types
|
||||
§ page.team.extension.name: Type
|
||||
|
@ -237,6 +246,14 @@ export default `
|
|||
§ page.team.department.tasks: tasks
|
||||
§ page.team.department.totalDays: Working days
|
||||
§ page.team.department.totalAuthors: Number of employees
|
||||
§ page.team.department.months.title: Possible number of employees in the department
|
||||
§ page.team.department.months.description: It is assumed that the task tracker issues the serial numbers of the tasks. Knowing the maximum task number at the beginning and end of the month, we can find out the number of completed tasks. Knowing how many tasks the authors we know have closed this month, we can interpolate their work speed to all new tasks and assume the total number of employees whose work was not reflected in the git log.
|
||||
§ page.team.department.months.date: Date
|
||||
§ page.team.department.months.tasks: New tasks
|
||||
§ page.team.department.months.tasksInWeek: in week
|
||||
§ page.team.department.months.fixed: was fixed
|
||||
§ page.team.department.months.authors: Worked
|
||||
§ page.team.department.months.allAuthors: total number of employees in the department
|
||||
§ page.team.building.races.title: The speed of closing tasks
|
||||
§ page.team.building.races.go: Let's go!
|
||||
§ page.team.building.swimmingPool.title: Maximum commit message length
|
||||
|
|
|
@ -176,6 +176,7 @@ export default `
|
|||
§ page.team.pr.lastCommitTime: Last
|
||||
§ page.team.pr.workDays: Average time spent working on a task
|
||||
§ page.team.pr.delayDays: Average time of the PR review
|
||||
§ page.team.pr.backlogDays: The delay of the task in the backlog before the start of development
|
||||
§ page.team.pr.all.workDays: Time spent working on a task
|
||||
§ page.team.pr.all.delayDays: Time of the PR review
|
||||
§ page.team.pr.middleTimeRelease: The ratio of development time to review time
|
||||
|
@ -194,17 +195,25 @@ export default `
|
|||
§ page.team.pr.oneTaskDays: Time spent on one task
|
||||
§ page.team.pr.description1: *Development time* is the time difference from the first to the last commit on a task. It does not matter if there were breaks of several days between commits or not. Any commit increases the time.
|
||||
§ page.team.pr.description2: *Waiting time* is the time between the last commit and the code merge. It shows the actual downtime while waiting for something.
|
||||
§ page.team.pr.description3: *Why display development time* without splitting into coding and code review? To show the business the actual delivery time of the code. Waiting for testing, review comments, DevOps problems, and other process imperfections are already included in this term.
|
||||
§ page.team.pr.description3: *Task creation date* in the task tracker is calculated by its sequential number and the minimum date of any next Issue in the code. The method has a margin of error and, as a rule, the tasks turn out to be older. Frequent releases, fast bugfixes, and a large number of employees working on the code reduce this margin of error.
|
||||
§ page.team.pr.statByAuthors: Statistics by employees
|
||||
§ page.team.pr.longDelay: Prolonged Waiting for merge
|
||||
§ page.team.pr.anonymous: PR without task number
|
||||
§ page.team.pr.branch: Branch
|
||||
§ page.team.tasks.task: Task
|
||||
§ page.team.tasks.author: First commit author
|
||||
§ page.team.tasks.createdBefore: Created before
|
||||
§ page.team.tasks.backlog: Development waiting
|
||||
§ page.team.tasks.from: First commit
|
||||
§ page.team.tasks.to: Last commit
|
||||
§ page.team.tasks.daysInWork: Days in work
|
||||
§ page.team.tasks.comments: Comments
|
||||
§ page.team.tasks.backlogTitle: Tasks undeveloped for over four months after being added to the task-tracker
|
||||
§ page.team.tasks.charts.authors.title: Who is doing these tasks?
|
||||
§ page.team.tasks.charts.authors.other: and etc.
|
||||
§ page.team.tasks.charts.relative.title: Count relative to other tasks
|
||||
§ page.team.tasks.charts.relative.backlog: backlog
|
||||
§ page.team.tasks.charts.relative.all: other tasks
|
||||
§ page.team.extension.extension: File extensions
|
||||
§ page.team.extension.type: File sub types
|
||||
§ page.team.extension.name: Type
|
||||
|
@ -239,6 +248,14 @@ export default `
|
|||
§ page.team.department.tasks: tasks
|
||||
§ page.team.department.totalDays: Working days
|
||||
§ page.team.department.totalAuthors: Number of employees
|
||||
§ page.team.department.months.title: Possible number of employees in the department
|
||||
§ page.team.department.months.description: It is assumed that the task tracker issues the serial numbers of the tasks. Knowing the maximum task number at the beginning and end of the month, we can find out the number of completed tasks. Knowing how many tasks the authors we know have closed this month, we can interpolate their work speed to all new tasks and assume the total number of employees whose work was not reflected in the git log.
|
||||
§ page.team.department.months.date: Date
|
||||
§ page.team.department.months.tasks: New tasks
|
||||
§ page.team.department.months.tasksInWeek: in week
|
||||
§ page.team.department.months.fixed: was fixed
|
||||
§ page.team.department.months.authors: Worked
|
||||
§ page.team.department.months.allAuthors: total number of employees in the department
|
||||
§ page.team.building.races.title: The speed of closing tasks
|
||||
§ page.team.building.races.go: Let's go!
|
||||
§ page.team.building.swimmingPool.title: Maximum commit message length
|
||||
|
|
|
@ -176,6 +176,7 @@ export default `
|
|||
§ page.team.pr.lastCommitTime: Last
|
||||
§ page.team.pr.workDays: Average time spent working on a task
|
||||
§ page.team.pr.delayDays: Average time of the PR review
|
||||
§ page.team.pr.backlogDays: The delay of the task in the backlog before the start of development
|
||||
§ page.team.pr.all.workDays: Time spent working on a task
|
||||
§ page.team.pr.all.delayDays: Time of the PR review
|
||||
§ page.team.pr.middleTimeRelease: The ratio of development time to review time
|
||||
|
@ -194,17 +195,25 @@ export default `
|
|||
§ page.team.pr.oneTaskDays: Time spent on one task
|
||||
§ page.team.pr.description1: *Development time* this is the time difference from the first to the last commits for the task. It doesn't matter if there were breaks of several days between commits or not. The very fact of any commits increases the time.
|
||||
§ page.team.pr.description2: *Waiting time* this is the time between the last commit and the code injection. It shows the actual idle waiting for something.
|
||||
§ page.team.pr.description3: *Why display the development time* without a breakdown into coding and code review? Then, to show the business the actual delivery time of the code. The expectation of testing, comments on the review, DevOps problems and other imperfections of the process are already laid down in this period.
|
||||
§ page.team.pr.description3: *Task creation date* in the task tracker is calculated by its sequential number and the minimum date of any next Issue in the code. The method has a margin of error and, as a rule, the tasks turn out to be older. Frequent releases, fast bugfixes, and a large number of employees working on the code reduce this margin of error.
|
||||
§ page.team.pr.statByAuthors: Employee statistics
|
||||
§ page.team.pr.longDelay: Long wait for infusion
|
||||
§ page.team.pr.anonymous: PR without task number
|
||||
§ page.team.pr.branch: Branch
|
||||
§ page.team.tasks.task: Task
|
||||
§ page.team.tasks.author: The author of the first commits
|
||||
§ page.team.tasks.createdBefore: Created before
|
||||
§ page.team.tasks.backlog: Development waiting
|
||||
§ page.team.tasks.from: The first commits
|
||||
§ page.team.tasks.to: Last commits
|
||||
§ page.team.tasks.daysInWork: Days in the work
|
||||
§ page.team.tasks.comments: Comments
|
||||
§ page.team.tasks.backlogTitle: Tasks undeveloped for over four months after being added to the task-tracker
|
||||
§ page.team.tasks.charts.authors.title: Who is doing these tasks?
|
||||
§ page.team.tasks.charts.authors.other: and etc.
|
||||
§ page.team.tasks.charts.relative.title: Count relative to other tasks
|
||||
§ page.team.tasks.charts.relative.backlog: backlog
|
||||
§ page.team.tasks.charts.relative.all: other tasks
|
||||
§ page.team.extension.extension: File extensions
|
||||
§ page.team.extension.type: File sub types
|
||||
§ page.team.extension.name: Type
|
||||
|
@ -239,6 +248,14 @@ export default `
|
|||
§ page.team.department.tasks: tasks
|
||||
§ page.team.department.totalDays: Working days
|
||||
§ page.team.department.totalAuthors: Number of employees
|
||||
§ page.team.department.months.title: Possible number of employees in the department
|
||||
§ page.team.department.months.description: It is assumed that the task tracker issues the serial numbers of the tasks. Knowing the maximum task number at the beginning and end of the month, we can find out the number of completed tasks. Knowing how many tasks the authors we know have closed this month, we can interpolate their work speed to all new tasks and assume the total number of employees whose work was not reflected in the git log.
|
||||
§ page.team.department.months.date: Date
|
||||
§ page.team.department.months.tasks: New tasks
|
||||
§ page.team.department.months.tasksInWeek: in week
|
||||
§ page.team.department.months.fixed: was fixed
|
||||
§ page.team.department.months.authors: Worked
|
||||
§ page.team.department.months.allAuthors: total number of employees in the department
|
||||
§ page.team.building.races.title: The speed of closing tasks
|
||||
§ page.team.building.races.go: Let's go!
|
||||
§ page.team.building.swimmingPool.title: Maximum commit message length
|
||||
|
|
|
@ -176,6 +176,7 @@ export default `
|
|||
§ page.team.pr.lastCommitTime: Dernier
|
||||
§ page.team.pr.workDays: Average time spent working on a task
|
||||
§ page.team.pr.delayDays: Average time of the PR review
|
||||
§ page.team.pr.backlogDays: The delay of the task in the backlog before the start of development
|
||||
§ page.team.pr.all.workDays: Time spent working on a task
|
||||
§ page.team.pr.all.delayDays: Time of the PR review
|
||||
§ page.team.pr.middleTimeRelease: The ratio of development time to review time
|
||||
|
@ -194,17 +195,25 @@ export default `
|
|||
§ page.team.pr.oneTaskDays: Temps passé sur une tâche
|
||||
§ page.team.pr.description1: *Temps de développement* c’est la différence de temps entre le premier et le dernier commit pour un problème donné. Il n’importe pas si il y avait des pauses pendant plusieurs jours entre les commits, ou non. Le fait même d’avoir fait un quelconque commit augmente le temps.
|
||||
§ page.team.pr.description2: *Délai d'attente* c'est le temps entre le dernier commit et l'injection de code. Il montre le réel simple en attendant quoi que ce soit.
|
||||
§ page.team.pr.description3: *Pourquoi afficher le temps de développement* sans se diviser en Coding et revue de code? Ensuite, pour montrer à l'entreprise le délai de Livraison réel du code. L'attente des tests, les commentaires sur la revue, les problèmes de DevOps et d'autres imperfections du processus sont déjà posés dans cette période.
|
||||
§ page.team.pr.description3: *Task creation date* in the task tracker is calculated by its sequential number and the minimum date of any next Issue in the code. The method has a margin of error and, as a rule, the tasks turn out to be older. Frequent releases, fast bugfixes, and a large number of employees working on the code reduce this margin of error.
|
||||
§ page.team.pr.statByAuthors: Statistiques du personnel
|
||||
§ page.team.pr.longDelay: Longue attente pour l'injection
|
||||
§ page.team.pr.anonymous: PR without task number
|
||||
§ page.team.pr.branch: Branch
|
||||
§ page.team.tasks.task: Tâche
|
||||
§ page.team.tasks.author: Auteur du premier commit
|
||||
§ page.team.tasks.createdBefore: Created before
|
||||
§ page.team.tasks.backlog: Development waiting
|
||||
§ page.team.tasks.from: Premier commit
|
||||
§ page.team.tasks.to: Dernier commit
|
||||
§ page.team.tasks.daysInWork: Jours de travail
|
||||
§ page.team.tasks.comments: Commentaires
|
||||
§ page.team.tasks.backlogTitle: Tasks undeveloped for over four months after being added to the task-tracker
|
||||
§ page.team.tasks.charts.authors.title: Who is doing these tasks?
|
||||
§ page.team.tasks.charts.authors.other: and etc.
|
||||
§ page.team.tasks.charts.relative.title: Count relative to other tasks
|
||||
§ page.team.tasks.charts.relative.backlog: backlog
|
||||
§ page.team.tasks.charts.relative.all: other tasks
|
||||
§ page.team.extension.extension: File extensions
|
||||
§ page.team.extension.type: File sub types
|
||||
§ page.team.extension.name: Type
|
||||
|
@ -239,6 +248,14 @@ export default `
|
|||
§ page.team.department.tasks: tasks
|
||||
§ page.team.department.totalDays: Working days
|
||||
§ page.team.department.totalAuthors: Number of employees
|
||||
§ page.team.department.months.title: Possible number of employees in the department
|
||||
§ page.team.department.months.description: It is assumed that the task tracker issues the serial numbers of the tasks. Knowing the maximum task number at the beginning and end of the month, we can find out the number of completed tasks. Knowing how many tasks the authors we know have closed this month, we can interpolate their work speed to all new tasks and assume the total number of employees whose work was not reflected in the git log.
|
||||
§ page.team.department.months.date: Date
|
||||
§ page.team.department.months.tasks: New tasks
|
||||
§ page.team.department.months.tasksInWeek: in week
|
||||
§ page.team.department.months.fixed: was fixed
|
||||
§ page.team.department.months.authors: Worked
|
||||
§ page.team.department.months.allAuthors: total number of employees in the department
|
||||
§ page.team.building.races.title: The speed of closing tasks
|
||||
§ page.team.building.races.go: Let's go!
|
||||
§ page.team.building.swimmingPool.title: Maximum commit message length
|
||||
|
|
|
@ -176,6 +176,7 @@ export default `
|
|||
§ page.team.pr.lastCommitTime: Last
|
||||
§ page.team.pr.workDays: Average time spent working on a task
|
||||
§ page.team.pr.delayDays: Average time of the PR review
|
||||
§ page.team.pr.backlogDays: The delay of the task in the backlog before the start of development
|
||||
§ page.team.pr.all.workDays: Time spent working on a task
|
||||
§ page.team.pr.all.delayDays: Time of the PR review
|
||||
§ page.team.pr.middleTimeRelease: The ratio of development time to review time
|
||||
|
@ -194,17 +195,25 @@ export default `
|
|||
§ page.team.pr.oneTaskDays: Time spent on one task
|
||||
§ page.team.pr.description1: *Development time* is the time difference from the first to the last commit on a task. It does not matter if there were breaks of several days between commits or not. Any commit increases the time.
|
||||
§ page.team.pr.description2: *Waiting time* is the time between the last commit and the code merge. It shows the actual downtime while waiting for something.
|
||||
§ page.team.pr.description3: *Why display development time* without splitting into coding and code review? To show the business the actual delivery time of the code. Waiting for testing, review comments, DevOps problems, and other process imperfections are already included in this term.
|
||||
§ page.team.pr.description3: *Task creation date* in the task tracker is calculated by its sequential number and the minimum date of any next Issue in the code. The method has a margin of error and, as a rule, the tasks turn out to be older. Frequent releases, fast bugfixes, and a large number of employees working on the code reduce this margin of error.
|
||||
§ page.team.pr.statByAuthors: Statistics by employees
|
||||
§ page.team.pr.longDelay: Prolonged Waiting for merge
|
||||
§ page.team.pr.anonymous: PR without task number
|
||||
§ page.team.pr.branch: Branch
|
||||
§ page.team.tasks.task: Task
|
||||
§ page.team.tasks.author: First commit author
|
||||
§ page.team.tasks.createdBefore: Created before
|
||||
§ page.team.tasks.backlog: Development waiting
|
||||
§ page.team.tasks.from: First commit
|
||||
§ page.team.tasks.to: Last commit
|
||||
§ page.team.tasks.daysInWork: Days in work
|
||||
§ page.team.tasks.comments: Comments
|
||||
§ page.team.tasks.backlogTitle: Tasks undeveloped for over four months after being added to the task-tracker
|
||||
§ page.team.tasks.charts.authors.title: Who is doing these tasks?
|
||||
§ page.team.tasks.charts.authors.other: and etc.
|
||||
§ page.team.tasks.charts.relative.title: Count relative to other tasks
|
||||
§ page.team.tasks.charts.relative.backlog: backlog
|
||||
§ page.team.tasks.charts.relative.all: other tasks
|
||||
§ page.team.extension.extension: File extensions
|
||||
§ page.team.extension.type: File sub types
|
||||
§ page.team.extension.name: Type
|
||||
|
@ -239,6 +248,14 @@ export default `
|
|||
§ page.team.department.tasks: tasks
|
||||
§ page.team.department.totalDays: Working days
|
||||
§ page.team.department.totalAuthors: Number of employees
|
||||
§ page.team.department.months.title: Possible number of employees in the department
|
||||
§ page.team.department.months.description: It is assumed that the task tracker issues the serial numbers of the tasks. Knowing the maximum task number at the beginning and end of the month, we can find out the number of completed tasks. Knowing how many tasks the authors we know have closed this month, we can interpolate their work speed to all new tasks and assume the total number of employees whose work was not reflected in the git log.
|
||||
§ page.team.department.months.date: Date
|
||||
§ page.team.department.months.tasks: New tasks
|
||||
§ page.team.department.months.tasksInWeek: in week
|
||||
§ page.team.department.months.fixed: was fixed
|
||||
§ page.team.department.months.authors: Worked
|
||||
§ page.team.department.months.allAuthors: total number of employees in the department
|
||||
§ page.team.building.races.title: The speed of closing tasks
|
||||
§ page.team.building.races.go: Let's go!
|
||||
§ page.team.building.swimmingPool.title: Maximum commit message length
|
||||
|
|
|
@ -176,6 +176,7 @@ export default `
|
|||
§ page.team.pr.lastCommitTime: 마지막
|
||||
§ page.team.pr.workDays: 작업 작업에 소요된 평균 시간
|
||||
§ page.team.pr.delayDays: 평균 홍보 검토 시간
|
||||
§ page.team.pr.backlogDays: The delay of the task in the backlog before the start of development
|
||||
§ page.team.pr.all.workDays: 작업 작업에 소요된 시간
|
||||
§ page.team.pr.all.delayDays: 홍보 검토 시간
|
||||
§ page.team.pr.middleTimeRelease: 검토 할 개발 시간의 비율
|
||||
|
@ -194,17 +195,25 @@ export default `
|
|||
§ page.team.pr.oneTaskDays: 한 작업에 소요 된 시간
|
||||
§ page.team.pr.description1: *개발 시간*이 작업은 작업의 첫 번째 커밋에서 마지막 커밋까지의 시간 차이입니다. 커밋 사이에 며칠의 휴식 시간이 있었는지 여부는 중요하지 않습니다. 모든 커밋의 바로 그 사실은 시간을 증가시킵니다.
|
||||
§ page.team.pr.description2: *대기 시간*마지막 커밋과 코드 주입 사이의 시간입니다. 그것은 무언가를 기다리는 실제 유휴 상태를 보여줍니다.
|
||||
§ page.team.pr.description3: *개발 시간을 표시하는 이유*코딩 및 코드 검토로 분해하지 않고? 그런 다음,비즈니스 코드의 실제 배달 시간을 표시합니다. 테스트의 기대,검토에 대한 의견,개발 운영 문제 및 프로세스의 다른 결함은 이미이 기간에 규정되어있다.
|
||||
§ page.team.pr.description3: *Task creation date* in the task tracker is calculated by its sequential number and the minimum date of any next Issue in the code. The method has a margin of error and, as a rule, the tasks turn out to be older. Frequent releases, fast bugfixes, and a large number of employees working on the code reduce this margin of error.
|
||||
§ page.team.pr.statByAuthors: 직원 통계
|
||||
§ page.team.pr.longDelay: 주입에 대한 긴 대기
|
||||
§ page.team.pr.anonymous: 문제 번호가없는 홍보
|
||||
§ page.team.pr.branch: 지점
|
||||
§ page.team.tasks.task: 작업
|
||||
§ page.team.tasks.author: 첫 번째 커밋의 저자
|
||||
§ page.team.tasks.createdBefore: Created before
|
||||
§ page.team.tasks.backlog: Development waiting
|
||||
§ page.team.tasks.from: 첫 번째 커밋
|
||||
§ page.team.tasks.to: 마지막 커밋
|
||||
§ page.team.tasks.daysInWork: 일 의 날
|
||||
§ page.team.tasks.comments: 댓글
|
||||
§ page.team.tasks.backlogTitle: Tasks undeveloped for over four months after being added to the task-tracker
|
||||
§ page.team.tasks.charts.authors.title: Who is doing these tasks?
|
||||
§ page.team.tasks.charts.authors.other: and etc.
|
||||
§ page.team.tasks.charts.relative.title: Count relative to other tasks
|
||||
§ page.team.tasks.charts.relative.backlog: backlog
|
||||
§ page.team.tasks.charts.relative.all: other tasks
|
||||
§ page.team.extension.extension: 파일 확장자
|
||||
§ page.team.extension.type: 파일 하위 유형
|
||||
§ page.team.extension.name: 유형
|
||||
|
@ -239,6 +248,14 @@ export default `
|
|||
§ page.team.department.tasks: tasks
|
||||
§ page.team.department.totalDays: Working days
|
||||
§ page.team.department.totalAuthors: Number of employees
|
||||
§ page.team.department.months.title: Possible number of employees in the department
|
||||
§ page.team.department.months.description: It is assumed that the task tracker issues the serial numbers of the tasks. Knowing the maximum task number at the beginning and end of the month, we can find out the number of completed tasks. Knowing how many tasks the authors we know have closed this month, we can interpolate their work speed to all new tasks and assume the total number of employees whose work was not reflected in the git log.
|
||||
§ page.team.department.months.date: Date
|
||||
§ page.team.department.months.tasks: New tasks
|
||||
§ page.team.department.months.tasksInWeek: in week
|
||||
§ page.team.department.months.fixed: was fixed
|
||||
§ page.team.department.months.authors: Worked
|
||||
§ page.team.department.months.allAuthors: total number of employees in the department
|
||||
§ page.team.building.races.title: The speed of closing tasks
|
||||
§ page.team.building.races.go: Let's go!
|
||||
§ page.team.building.swimmingPool.title: Maximum commit message length
|
||||
|
|
|
@ -176,6 +176,7 @@ export default `
|
|||
§ page.team.pr.lastCommitTime: Last
|
||||
§ page.team.pr.workDays: Average time spent working on a task
|
||||
§ page.team.pr.delayDays: Average time of the PR review
|
||||
§ page.team.pr.backlogDays: The delay of the task in the backlog before the start of development
|
||||
§ page.team.pr.all.workDays: Time spent working on a task
|
||||
§ page.team.pr.all.delayDays: Time of the PR review
|
||||
§ page.team.pr.middleTimeRelease: The ratio of development time to review time
|
||||
|
@ -194,17 +195,25 @@ export default `
|
|||
§ page.team.pr.oneTaskDays: Time spent on one task
|
||||
§ page.team.pr.description1: *Development time* is the time difference from the first to the last commit on a task. It does not matter if there were breaks of several days between commits or not. Any commit increases the time.
|
||||
§ page.team.pr.description2: *Waiting time* is the time between the last commit and the code merge. It shows the actual downtime while waiting for something.
|
||||
§ page.team.pr.description3: *Why display development time* without splitting into coding and code review? To show the business the actual delivery time of the code. Waiting for testing, review comments, DevOps problems, and other process imperfections are already included in this term.
|
||||
§ page.team.pr.description3: *Task creation date* in the task tracker is calculated by its sequential number and the minimum date of any next Issue in the code. The method has a margin of error and, as a rule, the tasks turn out to be older. Frequent releases, fast bugfixes, and a large number of employees working on the code reduce this margin of error.
|
||||
§ page.team.pr.statByAuthors: Statistics by employees
|
||||
§ page.team.pr.longDelay: Prolonged Waiting for merge
|
||||
§ page.team.pr.anonymous: PR without task number
|
||||
§ page.team.pr.branch: Branch
|
||||
§ page.team.tasks.task: Task
|
||||
§ page.team.tasks.author: First commit author
|
||||
§ page.team.tasks.createdBefore: Created before
|
||||
§ page.team.tasks.backlog: Development waiting
|
||||
§ page.team.tasks.from: First commit
|
||||
§ page.team.tasks.to: Last commit
|
||||
§ page.team.tasks.daysInWork: Days in work
|
||||
§ page.team.tasks.comments: Comments
|
||||
§ page.team.tasks.backlogTitle: Tasks undeveloped for over four months after being added to the task-tracker
|
||||
§ page.team.tasks.charts.authors.title: Who is doing these tasks?
|
||||
§ page.team.tasks.charts.authors.other: and etc.
|
||||
§ page.team.tasks.charts.relative.title: Count relative to other tasks
|
||||
§ page.team.tasks.charts.relative.backlog: backlog
|
||||
§ page.team.tasks.charts.relative.all: other tasks
|
||||
§ page.team.extension.extension: File extensions
|
||||
§ page.team.extension.type: File sub types
|
||||
§ page.team.extension.name: Type
|
||||
|
@ -239,6 +248,14 @@ export default `
|
|||
§ page.team.department.tasks: tasks
|
||||
§ page.team.department.totalDays: Working days
|
||||
§ page.team.department.totalAuthors: Number of employees
|
||||
§ page.team.department.months.title: Possible number of employees in the department
|
||||
§ page.team.department.months.description: It is assumed that the task tracker issues the serial numbers of the tasks. Knowing the maximum task number at the beginning and end of the month, we can find out the number of completed tasks. Knowing how many tasks the authors we know have closed this month, we can interpolate their work speed to all new tasks and assume the total number of employees whose work was not reflected in the git log.
|
||||
§ page.team.department.months.date: Date
|
||||
§ page.team.department.months.tasks: New tasks
|
||||
§ page.team.department.months.tasksInWeek: in week
|
||||
§ page.team.department.months.fixed: was fixed
|
||||
§ page.team.department.months.authors: Worked
|
||||
§ page.team.department.months.allAuthors: total number of employees in the department
|
||||
§ page.team.building.races.title: The speed of closing tasks
|
||||
§ page.team.building.races.go: Let's go!
|
||||
§ page.team.building.swimmingPool.title: Maximum commit message length
|
||||
|
|
|
@ -176,6 +176,7 @@ export default `
|
|||
§ page.team.pr.lastCommitTime: Последний
|
||||
§ page.team.pr.workDays: Среднее время работы над задачей
|
||||
§ page.team.pr.delayDays: Среднее время ревью PR
|
||||
§ page.team.pr.backlogDays: Время задачи в бэклоге до начала разработки
|
||||
§ page.team.pr.all.workDays: Время работы над задачей
|
||||
§ page.team.pr.all.delayDays: Время ревью PR
|
||||
§ page.team.pr.middleTimeRelease: Отношение времени разработки к времени ревью
|
||||
|
@ -192,19 +193,27 @@ export default `
|
|||
§ page.team.pr.delay: ожидание
|
||||
§ page.team.pr.days: дней
|
||||
§ page.team.pr.oneTaskDays: Время потраченное на одну задачу
|
||||
§ page.team.pr.description1: *Время разработки* это разница времени от первого до последнего коммита по задаче. Не важно были перерывы в несколько дней между коммитами или нет. Сам факт какого-либо коммита увеличивает время.
|
||||
§ page.team.pr.description2: *Время ожидания* это время между последним коммитом и влитием кода. Оно показывает фактический простой в ожидании чего-либо.
|
||||
§ page.team.pr.description3: *Зачем отображать время разработки* без разбивки на кодинг и код-ревью? Затем, чтобы показать бизнесу фактическое время поставки кода. Ожидание тестирования, замечания на ревью, проблемы DevOps и прочие несовершенства процесса, как раз уже заложены в этот срок.
|
||||
§ page.team.pr.description1: *Время работы над задачей* это разница времени от первого до последнего коммита по задаче. Не важно были перерывы в несколько дней между коммитами или нет. Сам факт какого-либо коммита увеличивает время.
|
||||
§ page.team.pr.description2: *Время ревью PR* это время между последним коммитом и влитием кода. Оно показывает фактический простой в ожидании чего-либо.
|
||||
§ page.team.pr.description3: *Дата создания задачи* в таск-трекере вычисляется по её порядковому номеру и минимальной дате любой следующей задачи в коде. Метод имеет погрешность и, как правило, задачи оказываются старше. Частые релизы, быстрые баг-фиксы и большое количество сотрудников, работающих над кодом, уменьшают эту погрешность.
|
||||
§ page.team.pr.statByAuthors: Статистика по сотрудникам
|
||||
§ page.team.pr.longDelay: Длительное ожидание влития
|
||||
§ page.team.pr.anonymous: PR без номера задачи
|
||||
§ page.team.pr.branch: Ветка
|
||||
§ page.team.tasks.task: Задача
|
||||
§ page.team.tasks.author: Автор первого коммита
|
||||
§ page.team.tasks.createdBefore: Создана до
|
||||
§ page.team.tasks.from: Первый коммит
|
||||
§ page.team.tasks.to: Последний коммит
|
||||
§ page.team.tasks.backlog: Ожидание разработки
|
||||
§ page.team.tasks.daysInWork: Дней в работе
|
||||
§ page.team.tasks.comments: Комментарии
|
||||
§ page.team.tasks.backlogTitle: Список задач, которые завели в таск-трекер и не брали в разработку больше четырех месяцев
|
||||
§ page.team.tasks.charts.authors.title: Кто его разбирает
|
||||
§ page.team.tasks.charts.authors.other: и другие
|
||||
§ page.team.tasks.charts.relative.title: Объем относительно других задач
|
||||
§ page.team.tasks.charts.relative.backlog: тех. долг
|
||||
§ page.team.tasks.charts.relative.all: другие задачи
|
||||
§ page.team.extension.extension: Расширения файлов
|
||||
§ page.team.extension.type: Подтип файлов
|
||||
§ page.team.extension.name: Тип
|
||||
|
@ -239,6 +248,14 @@ export default `
|
|||
§ page.team.department.tasks: задач
|
||||
§ page.team.department.totalDays: Дней работы
|
||||
§ page.team.department.totalAuthors: Количество сотрудников
|
||||
§ page.team.department.months.title: Возможное количество сотрудников в отделе
|
||||
§ page.team.department.months.description: Предполагается, что таск-трекер выдает серийные номера задач. Зная максимальный номер задачи в начале и конце месяца, мы можем узнать количество заведенных задач. Зная сколько задач за этот месяц закрыли известные нам авторы, мы можем интерполировать их скорость работы на все новые задачи и предположить общую численность сотрудников, работа которых не была отраженна в логе.
|
||||
§ page.team.department.months.date: Дата
|
||||
§ page.team.department.months.tasks: Новых задач
|
||||
§ page.team.department.months.tasksInWeek: в неделю
|
||||
§ page.team.department.months.fixed: исправленно
|
||||
§ page.team.department.months.authors: Работало
|
||||
§ page.team.department.months.allAuthors: а всего сотрудников в отделе
|
||||
§ page.team.building.races.title: Скорость закрытия задач
|
||||
§ page.team.building.races.go: Поехали!
|
||||
§ page.team.building.swimmingPool.title: Максимальная длина подписи коммита
|
||||
|
|
|
@ -171,6 +171,7 @@ export default `
|
|||
§ page.team.pr.lastCommitTime: 最后一次
|
||||
§ page.team.pr.workDays: 完成任务的平均时间
|
||||
§ page.team.pr.delayDays: PR审查的平均时间
|
||||
§ page.team.pr.backlogDays: The delay of the task in the backlog before the start of development
|
||||
§ page.team.pr.all.workDays: 任务完成时间
|
||||
§ page.team.pr.all.delayDays: PR请求的审议时间
|
||||
§ page.team.pr.middleTimeRelease: 开发时间与审查时间的比率
|
||||
|
@ -189,17 +190,25 @@ export default `
|
|||
§ page.team.pr.oneTaskDays: 花在一项任务上的时间
|
||||
§ page.team.pr.description1: *花在一项任务上的时间* 这是从第一个到最后一个的时间差 Commits 按任务划分. 如果之间有几天的休息时间也没关系 Commits 还是不是. 任何一个事实 Commits 增加时间.
|
||||
§ page.team.pr.description2: *轮候时间* 这是最后一次之间的时间 Commits 通过输入代码. 它显示了实际的空闲等待的东西.
|
||||
§ page.team.pr.description3: *为什么显示开发时间* 无需拆分为编码和代码审查? 然后,向业务显示代码的实际交付时间。 测试的期望,对审查的评论,DevOps问题和流程的其他不完善之处已经在这一时期制定.
|
||||
§ page.team.pr.description3: *Task creation date* in the task tracker is calculated by its sequential number and the minimum date of any next Issue in the code. The method has a margin of error and, as a rule, the tasks turn out to be older. Frequent releases, fast bugfixes, and a large number of employees working on the code reduce this margin of error.
|
||||
§ page.team.pr.statByAuthors: 雇员统计数字
|
||||
§ page.team.pr.longDelay: 长时间等待输液
|
||||
§ page.team.pr.anonymous: PR without task number
|
||||
§ page.team.pr.branch: Branch
|
||||
§ page.team.tasks.task: 任务
|
||||
§ page.team.tasks.author: 第一篇的作者 Commits
|
||||
§ page.team.tasks.createdBefore: Created before
|
||||
§ page.team.tasks.backlog: Development waiting
|
||||
§ page.team.tasks.from: 第一个 Commits
|
||||
§ page.team.tasks.to: 最后一次 Commits
|
||||
§ page.team.tasks.daysInWork: 工作中的日子
|
||||
§ page.team.tasks.comments: 评论
|
||||
§ page.team.tasks.backlogTitle: Tasks undeveloped for over four months after being added to the task-tracker
|
||||
§ page.team.tasks.charts.authors.title: Who is doing these tasks?
|
||||
§ page.team.tasks.charts.authors.other: and etc.
|
||||
§ page.team.tasks.charts.relative.title: Count relative to other tasks
|
||||
§ page.team.tasks.charts.relative.backlog: backlog
|
||||
§ page.team.tasks.charts.relative.all: other tasks
|
||||
§ page.team.extension.extension: File extensions
|
||||
§ page.team.extension.type: File sub types
|
||||
§ page.team.extension.name: Type
|
||||
|
@ -234,6 +243,14 @@ export default `
|
|||
§ page.team.department.tasks: tasks
|
||||
§ page.team.department.totalDays: Working days
|
||||
§ page.team.department.totalAuthors: Number of employees
|
||||
§ page.team.department.months.title: Possible number of employees in the department
|
||||
§ page.team.department.months.description: It is assumed that the task tracker issues the serial numbers of the tasks. Knowing the maximum task number at the beginning and end of the month, we can find out the number of completed tasks. Knowing how many tasks the authors we know have closed this month, we can interpolate their work speed to all new tasks and assume the total number of employees whose work was not reflected in the git log.
|
||||
§ page.team.department.months.date: Date
|
||||
§ page.team.department.months.tasks: New tasks
|
||||
§ page.team.department.months.tasksInWeek: in week
|
||||
§ page.team.department.months.fixed: was fixed
|
||||
§ page.team.department.months.authors: Worked
|
||||
§ page.team.department.months.allAuthors: total number of employees in the department
|
||||
§ page.team.building.races.title: The speed of closing tasks
|
||||
§ page.team.building.races.go: Let's go!
|
||||
§ page.team.building.swimmingPool.title: Maximum commit message length
|
||||
|
|
Loading…
Reference in a new issue