mirror of
https://github.com/bakhirev/assayo.git
synced 2024-11-16 08:11:40 +00:00
update
This commit is contained in:
parent
6362f71a80
commit
57008ac20e
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
|
||||
import { getClassNameForTimeZone } from '../helpers';
|
||||
import { getPositionForTimeZone, getColorForTimeZone } from '../helpers';
|
||||
|
||||
import style from '../styles/index.module.scss';
|
||||
|
||||
|
@ -13,11 +13,12 @@ function Point({
|
|||
timezone,
|
||||
authors,
|
||||
}: PointProps): React.ReactElement | null {
|
||||
const className = getClassNameForTimeZone(timezone);
|
||||
const position = getPositionForTimeZone(timezone);
|
||||
const color = getColorForTimeZone(authors);
|
||||
return (
|
||||
<div
|
||||
title={authors.join(', ')}
|
||||
className={`${style.time_zone_map_point} ${className}`}
|
||||
className={`${style.time_zone_map_point} ${position} ${color}`}
|
||||
>
|
||||
{authors.length}
|
||||
</div>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import dataGripStore from 'ts/store/DataGrip';
|
||||
|
||||
import style from '../styles/index.module.scss';
|
||||
|
||||
const REF_TIMEZONE_CLASS = {
|
||||
|
@ -46,10 +48,23 @@ export function getGroupsByTimeZone(authors: any[]) {
|
|||
}, {});
|
||||
}
|
||||
|
||||
export function getClassNameForTimeZone(timezone?: string) {
|
||||
export function getPositionForTimeZone(timezone?: string) {
|
||||
const suffix = (timezone || '')
|
||||
.replace('+', 'p')
|
||||
.replace('-', 'm')
|
||||
.replace(':', '');
|
||||
return REF_TIMEZONE_CLASS[suffix] || style.time_zone_map_point_hide;
|
||||
}
|
||||
|
||||
export function getColorForTimeZone(authors: string[]) {
|
||||
let isDismissed = false;
|
||||
for (let i = 0, l = authors.length; i < l; i++) {
|
||||
const item = dataGripStore.dataGrip.author.statisticByName[authors[i]];
|
||||
if (item?.isStaff) continue;
|
||||
if (!item?.isDismissed) return style.time_zone_map_point_active;
|
||||
if (item?.isDismissed) isDismissed = true;
|
||||
}
|
||||
return isDismissed
|
||||
? style.time_zone_map_point_dismissed
|
||||
: '';
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
color: var(--color-white);
|
||||
border-radius: var(--border-radius-l);
|
||||
background-color: var(--color-second);
|
||||
background-color: var(--color-black);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,4 +82,6 @@
|
|||
&_m1100 { top: 67%; left: 0; }
|
||||
&_m1200 { top: 62%; left: 97%; }
|
||||
&_hide { display: none }
|
||||
&_active { background-color: var(--color-first) }
|
||||
&_dismissed { background-color: var(--color-second) }
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import ICommit from 'ts/interfaces/Commit';
|
|||
import IHashMap, { HashMap } from 'ts/interfaces/HashMap';
|
||||
|
||||
import { ONE_DAY } from 'ts/helpers/formatter';
|
||||
import { createHashMap, createIncrement, increment } from 'ts/helpers/Math';
|
||||
import { createIncrement, increment } from 'ts/helpers/Math';
|
||||
|
||||
import userSettings from 'ts/store/UserSettings';
|
||||
|
||||
|
@ -24,21 +24,21 @@ export default class DataGripByAuthor {
|
|||
this.statisticByName = {};
|
||||
}
|
||||
|
||||
addCommit(commit: ICommit) {
|
||||
addCommit(commit: ICommit, totalCommits: number) {
|
||||
const statistic = this.commits.get(commit.author);
|
||||
if (statistic) {
|
||||
this.#updateCommitByAuthor(statistic, commit);
|
||||
this.#updateCommitByAuthor(statistic, commit, totalCommits);
|
||||
} else {
|
||||
this.#addCommitByAuthor(commit);
|
||||
}
|
||||
this.#setMoneyByMonth(commit);
|
||||
}
|
||||
|
||||
#updateCommitByAuthor(statistic: any, commit: ICommit) {
|
||||
#updateCommitByAuthor(statistic: any, commit: ICommit, totalCommits: number) {
|
||||
statistic.commits += 1;
|
||||
statistic.lastCommit = commit;
|
||||
statistic.device = statistic.device || commit.device;
|
||||
statistic.days[commit.timestamp] = true;
|
||||
statistic.days.set(commit.timestamp, true);
|
||||
statistic.tasks[commit.task] = commit.added + commit.changes + commit.removed
|
||||
+ (statistic.tasks[commit.task] ? statistic.tasks[commit.task] : 0);
|
||||
increment(statistic.types, commit.type);
|
||||
|
@ -55,7 +55,9 @@ export default class DataGripByAuthor {
|
|||
debugger;
|
||||
}
|
||||
statistic.commitsByHour[commit.hours] += 1;
|
||||
if (totalCommits < 50000) {
|
||||
statistic.wordStatistics = DataGripByAuthor.#updateWordStatistics(commit, statistic.wordStatistics);
|
||||
}
|
||||
|
||||
if (commit.company && statistic.lastCompany !== commit.company) {
|
||||
statistic.lastCompany = commit.company;
|
||||
|
@ -80,7 +82,7 @@ export default class DataGripByAuthor {
|
|||
commits: 1,
|
||||
firstCommit: commit,
|
||||
lastCommit: commit,
|
||||
days: createHashMap(commit.timestamp),
|
||||
days: new Map([[commit.timestamp, true]]),
|
||||
tasks: { [commit.task]: commit.added + commit.changes + commit.removed },
|
||||
types: createIncrement(commit.type),
|
||||
scopes: createIncrement(commit.scope),
|
||||
|
@ -171,7 +173,7 @@ export default class DataGripByAuthor {
|
|||
const from = dot.firstCommit.milliseconds;
|
||||
const to = dot.lastCommit.milliseconds;
|
||||
|
||||
const workDays = Object.keys(dot.days).length;
|
||||
const workDays = dot.days.size;
|
||||
const allDaysInProject = Math.ceil((to - from) / ONE_DAY);
|
||||
const lazyDays = Math.floor((allDaysInProject * WORK_AND_HOLIDAYS) - workDays) + 1;
|
||||
|
||||
|
@ -242,8 +244,16 @@ export default class DataGripByAuthor {
|
|||
...this.employment.staff,
|
||||
];
|
||||
|
||||
this.updateSort();
|
||||
}
|
||||
|
||||
updateSort() {
|
||||
const position = new Map();
|
||||
this.list.forEach((name: string, index: number) => {
|
||||
position.set(name, index);
|
||||
});
|
||||
this.statistic.sort((a: any, b: any) => (
|
||||
this.list.indexOf(a.author) - this.list.indexOf(b.author)
|
||||
position.get(a.author) - position.get(b.author)
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
import ICommit from 'ts/interfaces/Commit';
|
||||
import IHashMap from 'ts/interfaces/HashMap';
|
||||
import IHashMap, { HashMap } from 'ts/interfaces/HashMap';
|
||||
import userSettings from 'ts/store/UserSettings';
|
||||
import { createHashMap, createIncrement, increment } from 'ts/helpers/Math';
|
||||
import { createIncrement, increment } from 'ts/helpers/Math';
|
||||
|
||||
interface IStatByAuthor {
|
||||
commits: number; // number of commits by author in this scope
|
||||
days: IHashMap<boolean>; // commit timestamp
|
||||
days: HashMap<boolean>; // commit timestamp
|
||||
types: IHashMap<number>; // commit type by author in this scope (fix, feat)
|
||||
}
|
||||
|
||||
interface IStatByScope {
|
||||
scope: string; // scope name
|
||||
commits: number; // number of commits in this scope
|
||||
days: IHashMap<boolean>; // commit timestamp
|
||||
tasks: IHashMap<boolean>; // task name in this scope (JIRA-123)
|
||||
days: HashMap<boolean>; // commit timestamp
|
||||
tasks: HashMap<boolean>; // task name in this scope (JIRA-123)
|
||||
types: IHashMap<number>; // commit type in this scope (fix, feat)
|
||||
authors: IHashMap<IStatByAuthor>; // stat by author for this scope
|
||||
}
|
||||
|
@ -42,14 +42,14 @@ export default class DataGripByScope {
|
|||
#updateCommitByScope(commit: ICommit) {
|
||||
const statistic = this.commits[commit.scope] as IStatByScope;
|
||||
statistic.commits += 1;
|
||||
statistic.days[commit.timestamp] = true;
|
||||
statistic.tasks[commit.task] = true;
|
||||
statistic.days.set(commit.timestamp, true);
|
||||
statistic.tasks.set(commit.task, true);
|
||||
increment(statistic.types, commit.type);
|
||||
|
||||
const author = statistic.authors[commit.author];
|
||||
if (author) {
|
||||
author.commits += 1;
|
||||
author.days[commit.timestamp] = true;
|
||||
author.days.set(commit.timestamp, true);
|
||||
increment(author.types, commit.type);
|
||||
} else {
|
||||
statistic.authors[commit.author] = this.#getDefaultAuthorForScope(commit);
|
||||
|
@ -60,8 +60,8 @@ export default class DataGripByScope {
|
|||
this.commits[commit.scope] = {
|
||||
scope: commit.scope,
|
||||
commits: 1,
|
||||
days: createHashMap(commit.timestamp),
|
||||
tasks: createHashMap(commit.task),
|
||||
days: new Map([[commit.timestamp, true]]),
|
||||
tasks: new Map([[commit.task, true]]),
|
||||
types: createIncrement(commit.type),
|
||||
authors: createIncrement(commit.author, this.#getDefaultAuthorForScope(commit)),
|
||||
};
|
||||
|
@ -70,7 +70,7 @@ export default class DataGripByScope {
|
|||
#getDefaultAuthorForScope(commit: ICommit): IStatByAuthor {
|
||||
return {
|
||||
commits: 1,
|
||||
days: { [commit.timestamp]: true },
|
||||
days: new Map([[commit.timestamp, true]]),
|
||||
types: { [commit.type]: 1 },
|
||||
};
|
||||
}
|
||||
|
@ -84,18 +84,20 @@ export default class DataGripByScope {
|
|||
let cost = 0;
|
||||
for (let name in dot.authors) {
|
||||
const user = dot.authors[name];
|
||||
const days: number = Object.keys(user.days).length;
|
||||
const days: number = user.days.size;
|
||||
// TODO: need middle salary in month;
|
||||
salaryCache[name] = salaryCache[name] || userSettings.getCurrentSalaryInDay(name);
|
||||
cost += days * salaryCache[name];
|
||||
dot.authors[name] = { ...user, days };
|
||||
}
|
||||
|
||||
dot.tasks.delete('');
|
||||
|
||||
return {
|
||||
...dot,
|
||||
days: Object.keys(dot.days).length,
|
||||
days: dot.days.size,
|
||||
cost,
|
||||
tasks: Object.keys(dot.tasks).filter(t => t),
|
||||
tasks: dot.tasks.size,
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
@ -27,8 +27,8 @@ export default class DataGripByType {
|
|||
#updateCommitByType(commit: ICommit) {
|
||||
const statistic = this.commits[commit.type];
|
||||
statistic.commits += 1;
|
||||
statistic.days[commit.timestamp] = true;
|
||||
statistic.tasks[commit.task] = true;
|
||||
statistic.days.set(commit.timestamp, true);
|
||||
statistic.tasks.set(commit.task, true);
|
||||
|
||||
increment(statistic.commitsByAuthors, commit.author);
|
||||
if (!statistic.daysByAuthors[commit.author]) statistic.daysByAuthors[commit.author] = {};
|
||||
|
@ -39,8 +39,8 @@ export default class DataGripByType {
|
|||
this.commits[commit.type] = {
|
||||
type: commit.type,
|
||||
commits: 1,
|
||||
days: createIncrement(commit.timestamp, true),
|
||||
tasks: createIncrement(commit.task, true),
|
||||
days: new Map([[commit.timestamp, true]]),
|
||||
tasks: new Map([[commit.task, true]]),
|
||||
commitsByAuthors: createIncrement(commit.author, true),
|
||||
daysByAuthors: {
|
||||
[commit.author]: createIncrement(commit.timestamp, true),
|
||||
|
@ -56,8 +56,8 @@ export default class DataGripByType {
|
|||
.filter((dot: any) => dot.commits > 5 || isCorrectType[dot?.type || ''])
|
||||
.map((dot: any) => ({
|
||||
...dot,
|
||||
tasks: Object.keys(dot.tasks).length,
|
||||
days: Object.keys(dot.days).length,
|
||||
tasks: dot.tasks.size,
|
||||
days: dot.days.size,
|
||||
daysByAuthorsTotal: Object.values(dot.daysByAuthors)
|
||||
.reduce((t: number, v: any) => (t + Object.keys(v).length), 0),
|
||||
}))
|
||||
|
|
|
@ -66,13 +66,13 @@ class DataGrip {
|
|||
this.scoring.clear();
|
||||
}
|
||||
|
||||
addCommit(commit: ICommit | ISystemCommit) {
|
||||
addCommit(commit: ICommit | ISystemCommit, totalCommits: number) {
|
||||
if (commit.author === 'GitHub') return;
|
||||
this.pr.addCommit(commit); // @ts-ignore
|
||||
this.release.addCommit(commit); // @ts-ignore
|
||||
if (!commit.commitType) {
|
||||
this.firstLastCommit.update(commit.milliseconds, commit);
|
||||
this.author.addCommit(commit);
|
||||
this.author.addCommit(commit, totalCommits);
|
||||
this.scope.addCommit(commit);
|
||||
this.type.addCommit(commit);
|
||||
this.timestamp.addCommit(commit);
|
||||
|
|
|
@ -28,7 +28,9 @@ export default class RecommendationsTeamByType {
|
|||
|
||||
getBusFactor(dataGrip: any) {
|
||||
if (dataGrip.author.list.length < 2) return null;
|
||||
if (dataGrip.type.statistic.length > 200) return null; // for performance
|
||||
|
||||
// TODO: bad performance
|
||||
const oneMaintainer = dataGrip.type.statistic.filter((statistic: any) => {
|
||||
const limit = statistic.commits * 0.8;
|
||||
return dataGrip.author.list.some((name: string) => statistic.commitsByAuthors[name] >= limit);
|
||||
|
|
|
@ -29,9 +29,17 @@ const TIMESTAMP = [
|
|||
ONE_DAY * 3,
|
||||
];
|
||||
|
||||
export function getDayName(index:number, weekday: 'long' | 'short') {
|
||||
// for performance
|
||||
const dayNameCache = new Map();
|
||||
export function getDayName(index:number, weekday: 'long' | 'short') { // @ts-ignore
|
||||
const code = window?.localization?.language || 'ru';
|
||||
const response = dayNameCache.get(`${code}${index}${weekday}`);
|
||||
if (response) return response;
|
||||
|
||||
const date = new Date(TIMESTAMP[index]);
|
||||
return date.toLocaleString(getLangPrefix(), { weekday: weekday || 'long' });
|
||||
const dayName = date.toLocaleString(getLangPrefix(), { weekday: weekday || 'long' });
|
||||
dayNameCache.set(`${code}${index}${weekday}`, dayName);
|
||||
return dayName;
|
||||
}
|
||||
|
||||
export function getDateByTimestamp(timestamp: string) {
|
||||
|
|
77
src/ts/pages/Team/components/Country/components/Map.tsx
Normal file
77
src/ts/pages/Team/components/Country/components/Map.tsx
Normal file
|
@ -0,0 +1,77 @@
|
|||
import React, { useMemo, useState } from 'react';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
import dataGripStore from 'ts/store/DataGrip';
|
||||
|
||||
import SelectWithButtons from 'ts/components/UiKit/components/SelectWithButtons';
|
||||
import UiKitCheckbox from 'ts/components/UiKit/components/Checkbox';
|
||||
import TimeZoneMap from 'ts/components/TimeZoneMap';
|
||||
import PageWrapper from 'ts/components/Page/Box';
|
||||
import Title from 'ts/components/Title';
|
||||
import { t } from 'ts/helpers/Localization';
|
||||
|
||||
import style from '../../../styles/country.module.scss';
|
||||
|
||||
function getOptions(companies: any[]) {
|
||||
const options = companies.map((item: any) => ({ id: item.company, title: item.company }));
|
||||
return [
|
||||
{ id: '', title: t('page.common.filter.allUsers') },
|
||||
{ id: Math.random(), title: 'Unknown' },
|
||||
...options,
|
||||
];
|
||||
}
|
||||
|
||||
const CustomMap = observer(() => {
|
||||
const companies = dataGripStore.dataGrip.company.statistic;
|
||||
const companyOptions = useMemo(() => getOptions(companies), companies);
|
||||
|
||||
const [company, setCompany] = useState<string>('');
|
||||
const [isStaff, setIsStaff] = useState<boolean>(true);
|
||||
const [isActive, setIsActive] = useState<boolean>(true);
|
||||
const [isDismissed, setIsDismissed] = useState<boolean>(true);
|
||||
|
||||
const authors = dataGripStore.dataGrip.author.statistic
|
||||
.filter((author: any) => {
|
||||
if (company && author.lastCompany !== company) return false;
|
||||
if (!isStaff && author.isStaff) return false;
|
||||
if (!isActive && !author.isDismissed && !author.isStaff) return false;
|
||||
if (!isDismissed && author.isDismissed && !author.isStaff) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
return (
|
||||
<PageWrapper>
|
||||
<Title title="page.team.country.byTimezone"/>
|
||||
<TimeZoneMap authors={authors}/>
|
||||
<div className={style.team_country_filter}>
|
||||
<UiKitCheckbox
|
||||
title="page.team.country.filters.active"
|
||||
className={style.team_country_filter_checkbox}
|
||||
value={isActive}
|
||||
onChange={() => setIsActive(!isActive)}
|
||||
/>
|
||||
<UiKitCheckbox
|
||||
title="page.team.country.filters.dismissed"
|
||||
className={style.team_country_filter_checkbox}
|
||||
value={isDismissed}
|
||||
onChange={() => setIsDismissed(!isDismissed)}
|
||||
/>
|
||||
<UiKitCheckbox
|
||||
title="page.team.country.filters.staff"
|
||||
className={style.team_country_filter_checkbox}
|
||||
value={isStaff}
|
||||
onChange={() => setIsStaff(!isStaff)}
|
||||
/>
|
||||
<SelectWithButtons
|
||||
title="page.team.tree.filters.author"
|
||||
className={style.team_country_filter_select}
|
||||
value={company}
|
||||
options={companyOptions}
|
||||
onChange={(id: string) => setCompany(id)}
|
||||
/>
|
||||
</div>
|
||||
</PageWrapper>
|
||||
);
|
||||
});
|
||||
|
||||
export default CustomMap;
|
|
@ -13,10 +13,9 @@ import NothingFound from 'ts/components/NothingFound';
|
|||
import Title from 'ts/components/Title';
|
||||
import Countries from './components/Countries';
|
||||
import CountryCharts from './components/Charts';
|
||||
import TimeZoneMap from 'ts/components/TimeZoneMap';
|
||||
import PageWrapper from 'ts/components/Page/Box';
|
||||
import fullScreen from 'ts/store/FullScreen';
|
||||
|
||||
import CustomMap from './components/Map';
|
||||
import Travel from './components/Travel';
|
||||
|
||||
const Country = observer(({
|
||||
|
@ -36,15 +35,8 @@ const Country = observer(({
|
|||
|
||||
return (
|
||||
<>
|
||||
{!fullScreen.isOpen && (
|
||||
<>
|
||||
<PageWrapper>
|
||||
<Title title="page.team.country.byTimezone"/>
|
||||
<TimeZoneMap authors={authors}/>
|
||||
</PageWrapper>
|
||||
<CountryCharts/>
|
||||
</>
|
||||
)}
|
||||
{!fullScreen.isOpen && <CustomMap />}
|
||||
{!fullScreen.isOpen && <CountryCharts />}
|
||||
|
||||
{canShowByCountries ? (
|
||||
<>
|
||||
|
|
16
src/ts/pages/Team/styles/country.module.scss
Normal file
16
src/ts/pages/Team/styles/country.module.scss
Normal file
|
@ -0,0 +1,16 @@
|
|||
@import 'src/styles/variables';
|
||||
|
||||
.team_country_filter {
|
||||
margin-top: var(--space-m);
|
||||
|
||||
&_checkbox,
|
||||
&_select {
|
||||
display: inline-block;
|
||||
margin-right: var(--space-xxl);
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
&_select {
|
||||
min-width: 350px;
|
||||
}
|
||||
}
|
|
@ -65,8 +65,10 @@ class DataGripStore {
|
|||
|
||||
processingCommitGrouping(commits: (ICommit | ISystemCommit)[]) {
|
||||
commits.sort((a, b) => a.milliseconds - b.milliseconds);
|
||||
|
||||
const totalCommits = commits.length;
|
||||
commits.forEach((commit: ICommit | ISystemCommit) => {
|
||||
dataGrip.addCommit(commit);
|
||||
dataGrip.addCommit(commit, totalCommits);
|
||||
});
|
||||
|
||||
setTimeout(() => this.processingFileGrouping(commits), PROCESSING_DELAY);
|
||||
|
@ -128,7 +130,7 @@ class DataGripStore {
|
|||
? depersonalized.getCommit(commit)
|
||||
: commit;
|
||||
|
||||
dataGrip.addCommit(localCommit);
|
||||
dataGrip.addCommit(localCommit, 0);
|
||||
fileGrip.addCommit(localCommit);
|
||||
});
|
||||
|
||||
|
|
|
@ -130,6 +130,9 @@ export default `
|
|||
§ page.team.company.active.yes: active
|
||||
§ page.team.company.active.no: contract has expired
|
||||
§ page.team.country.byTimezone: By the time of the last commit
|
||||
§ page.team.country.filters.active: Works
|
||||
§ page.team.country.filters.dismissed: Dismissed
|
||||
§ page.team.country.filters.staff: Staff
|
||||
§ page.team.country.pieByDomain.title: By email, timezone and language
|
||||
§ page.team.country.pieByTimezone.title: By timezone
|
||||
§ page.team.country.chart.item: employments
|
||||
|
|
|
@ -130,6 +130,9 @@ export default `
|
|||
§ page.team.company.active.yes: active
|
||||
§ page.team.company.active.no: contract has expired
|
||||
§ page.team.country.byTimezone: By the time of the last commit
|
||||
§ page.team.country.filters.active: Works
|
||||
§ page.team.country.filters.dismissed: Dismissed
|
||||
§ page.team.country.filters.staff: Staff
|
||||
§ page.team.country.pieByDomain.title: By email, timezone and language
|
||||
§ page.team.country.pieByTimezone.title: By timezone
|
||||
§ page.team.country.chart.item: employments
|
||||
|
|
|
@ -130,6 +130,9 @@ export default `
|
|||
§ page.team.company.active.yes: active
|
||||
§ page.team.company.active.no: contract has expired
|
||||
§ page.team.country.byTimezone: By the time of the last commit
|
||||
§ page.team.country.filters.active: Works
|
||||
§ page.team.country.filters.dismissed: Dismissed
|
||||
§ page.team.country.filters.staff: Staff
|
||||
§ page.team.country.pieByDomain.title: By email, timezone and language
|
||||
§ page.team.country.pieByTimezone.title: By timezone
|
||||
§ page.team.country.chart.item: employments
|
||||
|
|
|
@ -130,6 +130,9 @@ export default `
|
|||
§ page.team.company.active.yes: active
|
||||
§ page.team.company.active.no: contract has expired
|
||||
§ page.team.country.byTimezone: By the time of the last commit
|
||||
§ page.team.country.filters.active: Works
|
||||
§ page.team.country.filters.dismissed: Dismissed
|
||||
§ page.team.country.filters.staff: Staff
|
||||
§ page.team.country.pieByDomain.title: By email, timezone and language
|
||||
§ page.team.country.pieByTimezone.title: By timezone
|
||||
§ page.team.country.chart.item: employments
|
||||
|
|
|
@ -130,6 +130,9 @@ export default `
|
|||
§ page.team.company.active.yes: active
|
||||
§ page.team.company.active.no: contract has expired
|
||||
§ page.team.country.byTimezone: By the time of the last commit
|
||||
§ page.team.country.filters.active: Works
|
||||
§ page.team.country.filters.dismissed: Dismissed
|
||||
§ page.team.country.filters.staff: Staff
|
||||
§ page.team.country.pieByDomain.title: By email, timezone and language
|
||||
§ page.team.country.pieByTimezone.title: By timezone
|
||||
§ page.team.country.chart.item: employments
|
||||
|
|
|
@ -130,6 +130,9 @@ export default `
|
|||
§ page.team.company.active.yes: active
|
||||
§ page.team.company.active.no: contract has expired
|
||||
§ page.team.country.byTimezone: By the time of the last commit
|
||||
§ page.team.country.filters.active: Works
|
||||
§ page.team.country.filters.dismissed: Dismissed
|
||||
§ page.team.country.filters.staff: Staff
|
||||
§ page.team.country.pieByDomain.title: By email, timezone and language
|
||||
§ page.team.country.pieByTimezone.title: By timezone
|
||||
§ page.team.country.chart.item: employments
|
||||
|
|
|
@ -130,6 +130,9 @@ export default `
|
|||
§ page.team.company.active.yes: активна
|
||||
§ page.team.company.active.no: контракт истёк
|
||||
§ page.team.country.byTimezone: По времени последнего коммита
|
||||
§ page.team.country.filters.active: Работают
|
||||
§ page.team.country.filters.dismissed: Уволенные
|
||||
§ page.team.country.filters.staff: Помощники
|
||||
§ page.team.country.pieByDomain.title: По почте, времени и языку
|
||||
§ page.team.country.pieByTimezone.title: По времени
|
||||
§ page.team.country.chart.item: сотрудников
|
||||
|
|
|
@ -125,6 +125,9 @@ export default `
|
|||
§ page.team.company.active.yes: active
|
||||
§ page.team.company.active.no: contract has expired
|
||||
§ page.team.country.byTimezone: By the time of the last commit
|
||||
§ page.team.country.filters.active: Works
|
||||
§ page.team.country.filters.dismissed: Dismissed
|
||||
§ page.team.country.filters.staff: Staff
|
||||
§ page.team.country.pieByDomain.title: By email, timezone and language
|
||||
§ page.team.country.pieByTimezone.title: By timezone
|
||||
§ page.team.country.chart.item: employments
|
||||
|
|
Loading…
Reference in a new issue