mirror of
https://github.com/bakhirev/assayo.git
synced 2024-11-16 16:21:41 +00:00
MMM-2022 lol(kek): 4eburek
This commit is contained in:
parent
a22abc0dc5
commit
ffe71996f1
|
@ -42,7 +42,7 @@
|
||||||
<meta name="copyright" content="(c) Bakhirev Aleksei">
|
<meta name="copyright" content="(c) Bakhirev Aleksei">
|
||||||
<meta http-equiv="Reply-to" content="alexey-bakhirev@yandex.ru">
|
<meta http-equiv="Reply-to" content="alexey-bakhirev@yandex.ru">
|
||||||
|
|
||||||
<meta name="application-name" content="Git Statistics">
|
<meta name="application-name" content="Git statistics">
|
||||||
<meta name="msapplication-tooltip" content="Simple and fast report on Git commit history.">
|
<meta name="msapplication-tooltip" content="Simple and fast report on Git commit history.">
|
||||||
<meta property="og:title" content="Git Statistics">
|
<meta property="og:title" content="Git Statistics">
|
||||||
<meta property="og:description" content="Simple and fast report on Git commit history.">
|
<meta property="og:description" content="Simple and fast report on Git commit history.">
|
||||||
|
|
|
@ -41,10 +41,10 @@ function Console({ className, textForCopy, children }: IConsoleProps) {
|
||||||
className={`${style.console_copy}`}
|
className={`${style.console_copy}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
copyInBuffer(textForCopy);
|
copyInBuffer(textForCopy);
|
||||||
notificationsStore.show('Текст скопирован');
|
notificationsStore.show(localization.get('uiKit.console.notification'));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{localization.get('uiKit.console')}
|
{localization.get('uiKit.console.button')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,6 +5,7 @@ import ISort from 'ts/interfaces/Sort';
|
||||||
import Table from 'ts/components/Table';
|
import Table from 'ts/components/Table';
|
||||||
import Cards from 'ts/components/Cards';
|
import Cards from 'ts/components/Cards';
|
||||||
import { downloadCsv } from 'ts/helpers/File';
|
import { downloadCsv } from 'ts/helpers/File';
|
||||||
|
import viewSettings from 'ts/store/ViewSettings';
|
||||||
|
|
||||||
import style from './index.module.scss';
|
import style from './index.module.scss';
|
||||||
import PageWrapper from '../Page/wrapper';
|
import PageWrapper from '../Page/wrapper';
|
||||||
|
@ -32,7 +33,10 @@ function DataView({
|
||||||
children,
|
children,
|
||||||
}: IDataViewProps): React.ReactElement | null {
|
}: IDataViewProps): React.ReactElement | null {
|
||||||
const urlParams = useParams<any>();
|
const urlParams = useParams<any>();
|
||||||
const [localType, setType] = useState<string>(type || 'table');
|
const defaultType = viewSettings.getItem(urlParams, 'table');
|
||||||
|
console.log(defaultType);
|
||||||
|
const [localType, setType] = useState<string>(type || defaultType);
|
||||||
|
console.log(localType);
|
||||||
|
|
||||||
if (!rows || !rows.length) return null;
|
if (!rows || !rows.length) return null;
|
||||||
|
|
||||||
|
@ -64,7 +68,9 @@ function DataView({
|
||||||
src={icon}
|
src={icon}
|
||||||
className={style.data_view_icon}
|
className={style.data_view_icon}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setType(localType === 'table' ? 'cards' : 'table');
|
const newType = localType === 'table' ? 'cards' : 'table';
|
||||||
|
setType(newType);
|
||||||
|
viewSettings.setItem(urlParams, newType, 'table');
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -99,7 +105,7 @@ function DataView({
|
||||||
DataView.defaultProps = {
|
DataView.defaultProps = {
|
||||||
rows: [],
|
rows: [],
|
||||||
sort: [],
|
sort: [],
|
||||||
type: 'table',
|
type: undefined,
|
||||||
columnCount: undefined,
|
columnCount: undefined,
|
||||||
updateSort: () => {
|
updateSort: () => {
|
||||||
},
|
},
|
||||||
|
|
|
@ -31,6 +31,19 @@
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&_link {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: var(--color-button);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:visited {
|
||||||
|
color: var(--color-button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&_list {
|
&_list {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0 0 0 22px;
|
padding: 0 0 0 22px;
|
||||||
|
|
|
@ -6,9 +6,10 @@ import cssStyle from './index.module.scss';
|
||||||
interface ICommonProps {
|
interface ICommonProps {
|
||||||
text: string;
|
text: string;
|
||||||
style: any;
|
style: any;
|
||||||
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTextWithLink(text: string) {
|
function getTextWithLink(text: string, className?: string) {
|
||||||
const parts = (text || '')
|
const parts = (text || '')
|
||||||
.split(/(\[[^\]]+\])/gim)
|
.split(/(\[[^\]]+\])/gim)
|
||||||
.map((value: string) => {
|
.map((value: string) => {
|
||||||
|
@ -18,7 +19,10 @@ function getTextWithLink(text: string) {
|
||||||
<Link
|
<Link
|
||||||
key={value}
|
key={value}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
to={link}>
|
rel="noreferrer"
|
||||||
|
className={className || ''}
|
||||||
|
to={link}
|
||||||
|
>
|
||||||
{title}
|
{title}
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
|
@ -26,43 +30,43 @@ function getTextWithLink(text: string) {
|
||||||
return (<>{parts}</>) ;
|
return (<>{parts}</>) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTextWithStyle(text: string) {
|
function getTextWithStyle(text: string, className?: string) {
|
||||||
const parts = (text || '')
|
const parts = (text || '')
|
||||||
.split('*')
|
.split('*')
|
||||||
.map((value: string, index: number) => (index % 2
|
.map((value: string, index: number) => (index % 2
|
||||||
? (<b key={value}>{getTextWithLink(value)}</b>)
|
? (<b key={value}>{getTextWithLink(value, className)}</b>)
|
||||||
: (<span key={value}>{getTextWithLink(value)}</span>)
|
: (<span key={value}>{getTextWithLink(value, className)}</span>)
|
||||||
));
|
));
|
||||||
return (<>{parts}</>) ;
|
return (<>{parts}</>) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
function List({ text, style }: ICommonProps) {
|
function List({ text, style, className }: ICommonProps) {
|
||||||
return (
|
return (
|
||||||
<p
|
<p
|
||||||
className={cssStyle.description_list}
|
|
||||||
style={style || {}}
|
style={style || {}}
|
||||||
|
className={`${cssStyle.description_list} ${className || ''}`}
|
||||||
>
|
>
|
||||||
{getTextWithStyle(text)}
|
{getTextWithStyle(text, className)}
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Title({ text, style }: ICommonProps) {
|
function Title({ text, style, className }: ICommonProps) {
|
||||||
return (
|
return (
|
||||||
<h6
|
<h6
|
||||||
className={cssStyle.description_title}
|
|
||||||
style={style || {}}
|
style={style || {}}
|
||||||
|
className={`${cssStyle.description_title} ${className || ''}`}
|
||||||
>
|
>
|
||||||
{getTextWithStyle(text)}
|
{getTextWithStyle(text, className)}
|
||||||
</h6>
|
</h6>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function SimpleText({ text, style }: ICommonProps) {
|
function SimpleText({ text, style, className }: ICommonProps) {
|
||||||
return (
|
return (
|
||||||
<p
|
<p
|
||||||
className={cssStyle.description_text}
|
|
||||||
style={style || {}}
|
style={style || {}}
|
||||||
|
className={`${cssStyle.description_text} ${className || ''}`}
|
||||||
>
|
>
|
||||||
{getTextWithStyle(text)}
|
{getTextWithStyle(text)}
|
||||||
</p>
|
</p>
|
||||||
|
@ -72,9 +76,10 @@ function SimpleText({ text, style }: ICommonProps) {
|
||||||
interface IDescriptionProps {
|
interface IDescriptionProps {
|
||||||
text?: string | string[];
|
text?: string | string[];
|
||||||
style?: any;
|
style?: any;
|
||||||
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Description({ text, style }: IDescriptionProps) {
|
function Description({ text, style, className }: IDescriptionProps) {
|
||||||
const paragraphs = !Array.isArray(text)
|
const paragraphs = !Array.isArray(text)
|
||||||
? (text || '').trim().split(/\n+/gm)
|
? (text || '').trim().split(/\n+/gm)
|
||||||
: text;
|
: text;
|
||||||
|
@ -82,29 +87,35 @@ function Description({ text, style }: IDescriptionProps) {
|
||||||
const items = paragraphs.map((paragraph) => {
|
const items = paragraphs.map((paragraph) => {
|
||||||
const prefix = paragraph.substring(0, 2);
|
const prefix = paragraph.substring(0, 2);
|
||||||
const mainText = paragraph.substring(2);
|
const mainText = paragraph.substring(2);
|
||||||
|
|
||||||
if (prefix === '- ') {
|
if (prefix === '- ') {
|
||||||
return (
|
return (
|
||||||
<List
|
<List
|
||||||
key={mainText}
|
key={mainText}
|
||||||
text={mainText}
|
text={mainText}
|
||||||
style={style}
|
style={style}
|
||||||
|
className={className}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prefix === '# ') {
|
if (prefix === '# ') {
|
||||||
return (
|
return (
|
||||||
<Title
|
<Title
|
||||||
key={mainText}
|
key={mainText}
|
||||||
text={mainText}
|
text={mainText}
|
||||||
style={style}
|
style={style}
|
||||||
|
className={className}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SimpleText
|
<SimpleText
|
||||||
key={mainText}
|
key={mainText}
|
||||||
text={paragraph}
|
text={paragraph}
|
||||||
style={style}
|
style={style}
|
||||||
|
className={className}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import localization from './Localization';
|
||||||
|
|
||||||
function getFormattedType(dataGrip: any): string {
|
function getFormattedType(dataGrip: any): string {
|
||||||
const popularType = dataGrip.extension.statistic?.[0] || {};
|
const popularType = dataGrip.extension.statistic?.[0] || {};
|
||||||
const extension = popularType?.extension || '';
|
const extension = popularType?.extension || '';
|
||||||
|
@ -45,7 +47,7 @@ function getFormattedType(dataGrip: any): string {
|
||||||
|
|
||||||
export default function getTitle(dataGrip: any, commits: any) {
|
export default function getTitle(dataGrip: any, commits: any) {
|
||||||
if (!commits.length) {
|
if (!commits.length) {
|
||||||
return 'Git Statistics';
|
return localization.get('common.title');
|
||||||
}
|
}
|
||||||
|
|
||||||
const type = getFormattedType(dataGrip) || '';
|
const type = getFormattedType(dataGrip) || '';
|
||||||
|
|
|
@ -19,10 +19,10 @@ const Common = observer((): React.ReactElement | null => {
|
||||||
<InputString
|
<InputString
|
||||||
title="page.settings.document.name"
|
title="page.settings.document.name"
|
||||||
value={title}
|
value={title}
|
||||||
placeholder="Git Statistics"
|
placeholder={localization.get('common.title')}
|
||||||
onChange={(value: string) => {
|
onChange={(value: string) => {
|
||||||
setTitle(value);
|
setTitle(value);
|
||||||
document.title = value || 'Git Statistics';
|
document.title = value || localization.get('common.title');
|
||||||
applicationHasCustom.title = true;
|
applicationHasCustom.title = true;
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
import Console from 'ts/components/Console';
|
import Console from 'ts/components/Console';
|
||||||
|
import Description from 'ts/components/Description';
|
||||||
import {
|
import {
|
||||||
getStringFromFileList,
|
getStringFromFileList,
|
||||||
getStringsForParser,
|
getStringsForParser,
|
||||||
|
@ -14,27 +14,14 @@ import style from './styles/index.module.scss';
|
||||||
function WarningInfo() {
|
function WarningInfo() {
|
||||||
return (
|
return (
|
||||||
<h4 className={style.welcome_warning}>
|
<h4 className={style.welcome_warning}>
|
||||||
<p>
|
<Description
|
||||||
{'Сервис '}
|
text={localization.get('page.welcome.warning1')}
|
||||||
<span className={style.welcome_warning_bold}>НЕ ХРАНИТ</span>
|
className={style.welcome_warning_text}
|
||||||
{' и '}
|
/>
|
||||||
<span className={style.welcome_warning_bold}>НЕ ПЕРЕДАЁТ</span>
|
<Description
|
||||||
{' ваши данные. Все расчёты выполняются локально в вашем браузере прямо на вашей машине.'}
|
text={localization.get('page.welcome.warning2')}
|
||||||
</p>
|
className={style.welcome_warning_text}
|
||||||
<p>
|
/>
|
||||||
{'Сервис '}
|
|
||||||
<span className={style.welcome_warning_bold}>НЕ СОБИРАЕТ СТАТИСТИКУ</span>
|
|
||||||
{' по проектам. Вы можете отключить интернет, проверить трафик и даже собрать локальный билд из '}
|
|
||||||
<a
|
|
||||||
href='https://github.com/bakhirev/assayo'
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
className={style.welcome_warning_link}
|
|
||||||
>
|
|
||||||
исходников
|
|
||||||
</a>
|
|
||||||
{'.'}
|
|
||||||
</p>
|
|
||||||
</h4>
|
</h4>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -54,16 +41,10 @@ function Welcome() {
|
||||||
className={style.welcome_console}
|
className={style.welcome_console}
|
||||||
textForCopy={command}
|
textForCopy={command}
|
||||||
/>
|
/>
|
||||||
<p className={style.welcome_description}>
|
<Description
|
||||||
{localization.get('page.welcome.description1')}
|
text={localization.get('page.welcome.description')}
|
||||||
<Link
|
className={`${style.welcome_description}`}
|
||||||
className={`${style.welcome_link}`}
|
/>
|
||||||
target="_blank"
|
|
||||||
to="https://git-scm.com/docs/gitmailmap">
|
|
||||||
.mailmap
|
|
||||||
</Link>
|
|
||||||
{localization.get('page.welcome.description2')}
|
|
||||||
</p>
|
|
||||||
<h2 className={style.welcome_last_title}>
|
<h2 className={style.welcome_last_title}>
|
||||||
{localization.get('page.welcome.step2') === 'page.welcome.step2'
|
{localization.get('page.welcome.step2') === 'page.welcome.step2'
|
||||||
? ''
|
? ''
|
||||||
|
|
|
@ -23,34 +23,23 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&_warning {
|
&_warning {
|
||||||
font-weight: 100;
|
|
||||||
font-size: var(--font-s);
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
line-height: 1.5;
|
|
||||||
text-align: center;
|
|
||||||
border-bottom: 3px solid red;
|
border-bottom: 3px solid red;
|
||||||
background-color: #FCDADA;
|
background-color: #FCDADA;
|
||||||
|
|
||||||
&_bold {
|
&_text {
|
||||||
font-weight: bold;
|
text-align: center;
|
||||||
color: red;
|
color: #B50404;
|
||||||
}
|
}
|
||||||
|
|
||||||
&_link {
|
&_link {
|
||||||
text-decoration: underline;
|
|
||||||
color: var(--color-button);
|
color: var(--color-button);
|
||||||
|
|
||||||
&:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&_link,
|
|
||||||
&_description {
|
&_description {
|
||||||
font-size: var(--font-xs);
|
font-size: var(--font-xs);
|
||||||
|
|
||||||
|
@ -66,12 +55,6 @@
|
||||||
color: #878FA1;
|
color: #878FA1;
|
||||||
}
|
}
|
||||||
|
|
||||||
&_link {
|
|
||||||
display: inline;
|
|
||||||
margin: 16px 4px 0 4px;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
&_first_title,
|
&_first_title,
|
||||||
&_last_title {
|
&_last_title {
|
||||||
font-size: 42px;
|
font-size: 42px;
|
||||||
|
|
69
src/ts/store/ViewSettings.ts
Normal file
69
src/ts/store/ViewSettings.ts
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
import { observable, action, makeObservable } from 'mobx';
|
||||||
|
|
||||||
|
class ViewSettingsStore {
|
||||||
|
key: string = 'view_settings';
|
||||||
|
|
||||||
|
version: number = 1;
|
||||||
|
|
||||||
|
settings: any = {};
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.load();
|
||||||
|
makeObservable(this, {
|
||||||
|
settings: observable,
|
||||||
|
load: action,
|
||||||
|
setItem: action,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
load() {
|
||||||
|
const settings = JSON.parse(localStorage.getItem(this.key) || '{}') || {};
|
||||||
|
if (settings.version === this.version) {
|
||||||
|
this.settings = settings.settings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
save() {
|
||||||
|
if (Object.keys(this.settings).length === 0) {
|
||||||
|
localStorage.removeItem(this.key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem(this.key, JSON.stringify({
|
||||||
|
version: this.version,
|
||||||
|
settings: this.settings,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
#getPath(path: any): string {
|
||||||
|
if (!path) return '';
|
||||||
|
if (Array.isArray(path)) {
|
||||||
|
return path.join('.');
|
||||||
|
} else if (typeof path === 'object') {
|
||||||
|
return [path.type, path.page].join('.');
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
setItem(path: any, value: any, defaultValue?: any) {
|
||||||
|
const formattedPath = this.#getPath(path);
|
||||||
|
if (!formattedPath) return;
|
||||||
|
|
||||||
|
if (!value || value === defaultValue) {
|
||||||
|
delete this.settings[formattedPath];
|
||||||
|
} else {
|
||||||
|
this.settings[formattedPath] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
getItem(path: any, defaultValue?: any): any {
|
||||||
|
const formattedPath = this.#getPath(path);
|
||||||
|
return this.settings?.[formattedPath] || defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const viewSettings = new ViewSettingsStore();
|
||||||
|
|
||||||
|
export default viewSettings;
|
|
@ -1,5 +1,6 @@
|
||||||
export default `
|
export default `
|
||||||
§ uiKit.console: Copy
|
§ uiKit.console.button: Copy
|
||||||
|
§ uiKit.console.notification: Text was copied
|
||||||
§ uiKit.dataLoader.page: Page
|
§ uiKit.dataLoader.page: Page
|
||||||
§ uiKit.dataLoader.size: Displayed
|
§ uiKit.dataLoader.size: Displayed
|
||||||
§ uiKit.dataLoader.from: out of
|
§ uiKit.dataLoader.from: out of
|
||||||
|
@ -22,6 +23,7 @@ The work of employees with such status on this project can be neglected as their
|
||||||
Therefore, the system does not calculate a number of indicators for him.
|
Therefore, the system does not calculate a number of indicators for him.
|
||||||
If this is an error and this employee needs to be calculated as usual, go to the “Settings” section and change his type.
|
If this is an error and this employee needs to be calculated as usual, go to the “Settings” section and change his type.
|
||||||
|
|
||||||
|
§ common.title: Git statistics
|
||||||
§ common.filters: Filters
|
§ common.filters: Filters
|
||||||
§ common.notifications.save: The changes have been saved
|
§ common.notifications.save: The changes have been saved
|
||||||
§ common.notifications.setting: The settings have been saved
|
§ common.notifications.setting: The settings have been saved
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
export default `
|
export default `
|
||||||
§ page.welcome.step1: Execute the command in the root of your project.
|
§ page.welcome.step1: Execute the command in the root of your project.
|
||||||
§ page.welcome.step3: Drag and Drop.
|
§ page.welcome.step3: Drag and drop
|
||||||
§ page.welcome.step4: the log.txt file onto this page.
|
§ page.welcome.step4: the log.txt file onto this page.
|
||||||
§ page.welcome.description1: Git will create a log.txt file. It contains data for report generation. Or use git shortlog -s -n -e if you don't need a report. Create a file.
|
§ page.welcome.description: Git will create a log.txt file. It contains data for report generation. Or use git shortlog -s -n -e if you don't need a report. Create a [.mailmap|https://git-scm.com/docs/gitmailmap] file in the root of the project to consolidate employee statistics.
|
||||||
§ page.welcome.description2: [Create a .mailmap file|https://git-scm.com/docs/gitmailmap] in the root of the project to consolidate employee statistics.
|
§ page.welcome.warning1: The service *DOES NOT SAVE* and *DOES NOT TRANSFER* your data. All calculations are performed locally in your browser on your machine.
|
||||||
§ page.welcome.description: Git will create a log.txt file. It contains data for report generation. Or use git shortlog -s -n -e if you don't need a report. Create a [.mailmap file|https://git-scm.com/docs/gitmailmap] in the root of the project to consolidate employee statistics.
|
|
||||||
§ page.welcome.warning1: The service *DOES NOT STORE* and *DOES NOT TRANSFER* your data. All calculations are performed locally in your browser on your machine.
|
|
||||||
§ page.welcome.warning2: The service *DOES NOT COLLECT STATISTICS* on projects. You can disconnect the internet, check traffic, and even build a local version from the [source|https://github.com/bakhirev/assayo].
|
§ page.welcome.warning2: The service *DOES NOT COLLECT STATISTICS* on projects. You can disconnect the internet, check traffic, and even build a local version from the [source|https://github.com/bakhirev/assayo].
|
||||||
§ page.common.words.title: Word Statistics.
|
§ page.common.words.title: Word Statistics.
|
||||||
§ page.common.words.description: the most popular word. Occurs $1 times.
|
§ page.common.words.description: the most popular word. Occurs $1 times.
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
export default `
|
export default `
|
||||||
§ uiKit.console: Копировать
|
§ uiKit.console.button: Копировать
|
||||||
|
§ uiKit.console.notification: Текст скопирован
|
||||||
§ uiKit.dataLoader.page: Страница
|
§ uiKit.dataLoader.page: Страница
|
||||||
§ uiKit.dataLoader.size: Отображается по
|
§ uiKit.dataLoader.size: Отображается по
|
||||||
§ uiKit.dataLoader.from: из
|
§ uiKit.dataLoader.from: из
|
||||||
|
@ -22,6 +23,7 @@ export default `
|
||||||
Поэтому система не рассчитывает для него ряд показателей.
|
Поэтому система не рассчитывает для него ряд показателей.
|
||||||
Если это ошибка и данного сотрудника нужно рассчитать как обычного, перейдите в раздел «Настройки» и измените его тип.
|
Если это ошибка и данного сотрудника нужно рассчитать как обычного, перейдите в раздел «Настройки» и измените его тип.
|
||||||
|
|
||||||
|
§ common.title: Git статистика
|
||||||
§ common.filters: Фильтры
|
§ common.filters: Фильтры
|
||||||
§ common.notifications.save: Изменения сохранены
|
§ common.notifications.save: Изменения сохранены
|
||||||
§ common.notifications.setting: Настройки сохранены
|
§ common.notifications.setting: Настройки сохранены
|
||||||
|
|
|
@ -2,8 +2,6 @@ export default `
|
||||||
§ page.welcome.step1: Выполните команду в корне вашего проекта
|
§ page.welcome.step1: Выполните команду в корне вашего проекта
|
||||||
§ page.welcome.step3: Перетащите
|
§ page.welcome.step3: Перетащите
|
||||||
§ page.welcome.step4: файл log.txt на эту страницу
|
§ page.welcome.step4: файл log.txt на эту страницу
|
||||||
§ page.welcome.description1: Git создаст файл log.txt. Он содержит данные для построения отчёта. Или git shortlog -s -n -e если отчёт вам не нужен. Создайте файл
|
|
||||||
§ page.welcome.description2: [.mailmap|https://git-scm.com/docs/gitmailmap] в корне проекта, чтобы объединить статистику по сотрудникам.
|
|
||||||
§ page.welcome.description: Git создаст файл log.txt. Он содержит данные для построения отчёта. Или git shortlog -s -n -e если отчёт вам не нужен. Создайте файл [.mailmap|https://git-scm.com/docs/gitmailmap] в корне проекта, чтобы объединить статистику по сотрудникам.
|
§ page.welcome.description: Git создаст файл log.txt. Он содержит данные для построения отчёта. Или git shortlog -s -n -e если отчёт вам не нужен. Создайте файл [.mailmap|https://git-scm.com/docs/gitmailmap] в корне проекта, чтобы объединить статистику по сотрудникам.
|
||||||
§ page.welcome.warning1: Сервис *НЕ ХРАНИТ* и *НЕ ПЕРЕДАЁТ* ваши данные. Все расчёты выполняются локально в вашем браузере прямо на вашей машине.
|
§ page.welcome.warning1: Сервис *НЕ ХРАНИТ* и *НЕ ПЕРЕДАЁТ* ваши данные. Все расчёты выполняются локально в вашем браузере прямо на вашей машине.
|
||||||
§ page.welcome.warning2: Сервис *НЕ СОБИРАЕТ СТАТИСТИКУ* по проектам. Вы можете отключить интернет, проверить трафик и даже собрать локальный билд из [исходников|https://github.com/bakhirev/assayo].
|
§ page.welcome.warning2: Сервис *НЕ СОБИРАЕТ СТАТИСТИКУ* по проектам. Вы можете отключить интернет, проверить трафик и даже собрать локальный билд из [исходников|https://github.com/bakhirev/assayo].
|
||||||
|
|
Loading…
Reference in a new issue