mirror of
https://github.com/bakhirev/assayo.git
synced 2024-11-16 08:11:40 +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 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 property="og:title" content="Git Statistics">
|
||||
<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}`}
|
||||
onClick={() => {
|
||||
copyInBuffer(textForCopy);
|
||||
notificationsStore.show('Текст скопирован');
|
||||
notificationsStore.show(localization.get('uiKit.console.notification'));
|
||||
}}
|
||||
>
|
||||
{localization.get('uiKit.console')}
|
||||
{localization.get('uiKit.console.button')}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -5,6 +5,7 @@ import ISort from 'ts/interfaces/Sort';
|
|||
import Table from 'ts/components/Table';
|
||||
import Cards from 'ts/components/Cards';
|
||||
import { downloadCsv } from 'ts/helpers/File';
|
||||
import viewSettings from 'ts/store/ViewSettings';
|
||||
|
||||
import style from './index.module.scss';
|
||||
import PageWrapper from '../Page/wrapper';
|
||||
|
@ -32,7 +33,10 @@ function DataView({
|
|||
children,
|
||||
}: IDataViewProps): React.ReactElement | null {
|
||||
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;
|
||||
|
||||
|
@ -64,7 +68,9 @@ function DataView({
|
|||
src={icon}
|
||||
className={style.data_view_icon}
|
||||
onClick={() => {
|
||||
setType(localType === 'table' ? 'cards' : 'table');
|
||||
const newType = localType === 'table' ? 'cards' : 'table';
|
||||
setType(newType);
|
||||
viewSettings.setItem(urlParams, newType, 'table');
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
@ -99,7 +105,7 @@ function DataView({
|
|||
DataView.defaultProps = {
|
||||
rows: [],
|
||||
sort: [],
|
||||
type: 'table',
|
||||
type: undefined,
|
||||
columnCount: undefined,
|
||||
updateSort: () => {
|
||||
},
|
||||
|
|
|
@ -31,6 +31,19 @@
|
|||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
&_link {
|
||||
text-decoration: underline;
|
||||
color: var(--color-button);
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:visited {
|
||||
color: var(--color-button);
|
||||
}
|
||||
}
|
||||
|
||||
&_list {
|
||||
position: relative;
|
||||
padding: 0 0 0 22px;
|
||||
|
|
|
@ -6,9 +6,10 @@ import cssStyle from './index.module.scss';
|
|||
interface ICommonProps {
|
||||
text: string;
|
||||
style: any;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
function getTextWithLink(text: string) {
|
||||
function getTextWithLink(text: string, className?: string) {
|
||||
const parts = (text || '')
|
||||
.split(/(\[[^\]]+\])/gim)
|
||||
.map((value: string) => {
|
||||
|
@ -18,7 +19,10 @@ function getTextWithLink(text: string) {
|
|||
<Link
|
||||
key={value}
|
||||
target="_blank"
|
||||
to={link}>
|
||||
rel="noreferrer"
|
||||
className={className || ''}
|
||||
to={link}
|
||||
>
|
||||
{title}
|
||||
</Link>
|
||||
);
|
||||
|
@ -26,43 +30,43 @@ function getTextWithLink(text: string) {
|
|||
return (<>{parts}</>) ;
|
||||
}
|
||||
|
||||
function getTextWithStyle(text: string) {
|
||||
function getTextWithStyle(text: string, className?: string) {
|
||||
const parts = (text || '')
|
||||
.split('*')
|
||||
.map((value: string, index: number) => (index % 2
|
||||
? (<b key={value}>{getTextWithLink(value)}</b>)
|
||||
: (<span key={value}>{getTextWithLink(value)}</span>)
|
||||
? (<b key={value}>{getTextWithLink(value, className)}</b>)
|
||||
: (<span key={value}>{getTextWithLink(value, className)}</span>)
|
||||
));
|
||||
return (<>{parts}</>) ;
|
||||
}
|
||||
|
||||
function List({ text, style }: ICommonProps) {
|
||||
function List({ text, style, className }: ICommonProps) {
|
||||
return (
|
||||
<p
|
||||
className={cssStyle.description_list}
|
||||
style={style || {}}
|
||||
className={`${cssStyle.description_list} ${className || ''}`}
|
||||
>
|
||||
{getTextWithStyle(text)}
|
||||
{getTextWithStyle(text, className)}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
function Title({ text, style }: ICommonProps) {
|
||||
function Title({ text, style, className }: ICommonProps) {
|
||||
return (
|
||||
<h6
|
||||
className={cssStyle.description_title}
|
||||
style={style || {}}
|
||||
className={`${cssStyle.description_title} ${className || ''}`}
|
||||
>
|
||||
{getTextWithStyle(text)}
|
||||
{getTextWithStyle(text, className)}
|
||||
</h6>
|
||||
);
|
||||
}
|
||||
|
||||
function SimpleText({ text, style }: ICommonProps) {
|
||||
function SimpleText({ text, style, className }: ICommonProps) {
|
||||
return (
|
||||
<p
|
||||
className={cssStyle.description_text}
|
||||
style={style || {}}
|
||||
className={`${cssStyle.description_text} ${className || ''}`}
|
||||
>
|
||||
{getTextWithStyle(text)}
|
||||
</p>
|
||||
|
@ -72,9 +76,10 @@ function SimpleText({ text, style }: ICommonProps) {
|
|||
interface IDescriptionProps {
|
||||
text?: string | string[];
|
||||
style?: any;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
function Description({ text, style }: IDescriptionProps) {
|
||||
function Description({ text, style, className }: IDescriptionProps) {
|
||||
const paragraphs = !Array.isArray(text)
|
||||
? (text || '').trim().split(/\n+/gm)
|
||||
: text;
|
||||
|
@ -82,29 +87,35 @@ function Description({ text, style }: IDescriptionProps) {
|
|||
const items = paragraphs.map((paragraph) => {
|
||||
const prefix = paragraph.substring(0, 2);
|
||||
const mainText = paragraph.substring(2);
|
||||
|
||||
if (prefix === '- ') {
|
||||
return (
|
||||
<List
|
||||
key={mainText}
|
||||
text={mainText}
|
||||
style={style}
|
||||
className={className}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (prefix === '# ') {
|
||||
return (
|
||||
<Title
|
||||
key={mainText}
|
||||
text={mainText}
|
||||
style={style}
|
||||
className={className}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SimpleText
|
||||
key={mainText}
|
||||
text={paragraph}
|
||||
style={style}
|
||||
className={className}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import localization from './Localization';
|
||||
|
||||
function getFormattedType(dataGrip: any): string {
|
||||
const popularType = dataGrip.extension.statistic?.[0] || {};
|
||||
const extension = popularType?.extension || '';
|
||||
|
@ -45,7 +47,7 @@ function getFormattedType(dataGrip: any): string {
|
|||
|
||||
export default function getTitle(dataGrip: any, commits: any) {
|
||||
if (!commits.length) {
|
||||
return 'Git Statistics';
|
||||
return localization.get('common.title');
|
||||
}
|
||||
|
||||
const type = getFormattedType(dataGrip) || '';
|
||||
|
|
|
@ -19,10 +19,10 @@ const Common = observer((): React.ReactElement | null => {
|
|||
<InputString
|
||||
title="page.settings.document.name"
|
||||
value={title}
|
||||
placeholder="Git Statistics"
|
||||
placeholder={localization.get('common.title')}
|
||||
onChange={(value: string) => {
|
||||
setTitle(value);
|
||||
document.title = value || 'Git Statistics';
|
||||
document.title = value || localization.get('common.title');
|
||||
applicationHasCustom.title = true;
|
||||
}}
|
||||
/>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import Console from 'ts/components/Console';
|
||||
import Description from 'ts/components/Description';
|
||||
import {
|
||||
getStringFromFileList,
|
||||
getStringsForParser,
|
||||
|
@ -14,27 +14,14 @@ import style from './styles/index.module.scss';
|
|||
function WarningInfo() {
|
||||
return (
|
||||
<h4 className={style.welcome_warning}>
|
||||
<p>
|
||||
{'Сервис '}
|
||||
<span className={style.welcome_warning_bold}>НЕ ХРАНИТ</span>
|
||||
{' и '}
|
||||
<span className={style.welcome_warning_bold}>НЕ ПЕРЕДАЁТ</span>
|
||||
{' ваши данные. Все расчёты выполняются локально в вашем браузере прямо на вашей машине.'}
|
||||
</p>
|
||||
<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>
|
||||
<Description
|
||||
text={localization.get('page.welcome.warning1')}
|
||||
className={style.welcome_warning_text}
|
||||
/>
|
||||
<Description
|
||||
text={localization.get('page.welcome.warning2')}
|
||||
className={style.welcome_warning_text}
|
||||
/>
|
||||
</h4>
|
||||
);
|
||||
}
|
||||
|
@ -54,16 +41,10 @@ function Welcome() {
|
|||
className={style.welcome_console}
|
||||
textForCopy={command}
|
||||
/>
|
||||
<p className={style.welcome_description}>
|
||||
{localization.get('page.welcome.description1')}
|
||||
<Link
|
||||
className={`${style.welcome_link}`}
|
||||
target="_blank"
|
||||
to="https://git-scm.com/docs/gitmailmap">
|
||||
.mailmap
|
||||
</Link>
|
||||
{localization.get('page.welcome.description2')}
|
||||
</p>
|
||||
<Description
|
||||
text={localization.get('page.welcome.description')}
|
||||
className={`${style.welcome_description}`}
|
||||
/>
|
||||
<h2 className={style.welcome_last_title}>
|
||||
{localization.get('page.welcome.step2') === 'page.welcome.step2'
|
||||
? ''
|
||||
|
|
|
@ -23,34 +23,23 @@
|
|||
}
|
||||
|
||||
&_warning {
|
||||
font-weight: 100;
|
||||
font-size: var(--font-s);
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
padding: 6px;
|
||||
box-sizing: border-box;
|
||||
|
||||
line-height: 1.5;
|
||||
text-align: center;
|
||||
border-bottom: 3px solid red;
|
||||
background-color: #FCDADA;
|
||||
|
||||
&_bold {
|
||||
font-weight: bold;
|
||||
color: red;
|
||||
&_text {
|
||||
text-align: center;
|
||||
color: #B50404;
|
||||
}
|
||||
|
||||
&_link {
|
||||
text-decoration: underline;
|
||||
color: var(--color-button);
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&_link,
|
||||
&_description {
|
||||
font-size: var(--font-xs);
|
||||
|
||||
|
@ -66,12 +55,6 @@
|
|||
color: #878FA1;
|
||||
}
|
||||
|
||||
&_link {
|
||||
display: inline;
|
||||
margin: 16px 4px 0 4px;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&_first_title,
|
||||
&_last_title {
|
||||
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 `
|
||||
§ uiKit.console: Copy
|
||||
§ uiKit.console.button: Copy
|
||||
§ uiKit.console.notification: Text was copied
|
||||
§ uiKit.dataLoader.page: Page
|
||||
§ uiKit.dataLoader.size: Displayed
|
||||
§ 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.
|
||||
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.notifications.save: The changes have been saved
|
||||
§ common.notifications.setting: The settings have been saved
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
export default `
|
||||
§ 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.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.description2: [Create a .mailmap file|https://git-scm.com/docs/gitmailmap] in the root of the project to consolidate employee statistics.
|
||||
§ 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.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.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.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.description: the most popular word. Occurs $1 times.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export default `
|
||||
§ uiKit.console: Копировать
|
||||
§ uiKit.console.button: Копировать
|
||||
§ uiKit.console.notification: Текст скопирован
|
||||
§ uiKit.dataLoader.page: Страница
|
||||
§ uiKit.dataLoader.size: Отображается по
|
||||
§ uiKit.dataLoader.from: из
|
||||
|
@ -22,6 +23,7 @@ export default `
|
|||
Поэтому система не рассчитывает для него ряд показателей.
|
||||
Если это ошибка и данного сотрудника нужно рассчитать как обычного, перейдите в раздел «Настройки» и измените его тип.
|
||||
|
||||
§ common.title: Git статистика
|
||||
§ common.filters: Фильтры
|
||||
§ common.notifications.save: Изменения сохранены
|
||||
§ common.notifications.setting: Настройки сохранены
|
||||
|
|
|
@ -2,8 +2,6 @@ export default `
|
|||
§ page.welcome.step1: Выполните команду в корне вашего проекта
|
||||
§ page.welcome.step3: Перетащите
|
||||
§ 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.warning1: Сервис *НЕ ХРАНИТ* и *НЕ ПЕРЕДАЁТ* ваши данные. Все расчёты выполняются локально в вашем браузере прямо на вашей машине.
|
||||
§ page.welcome.warning2: Сервис *НЕ СОБИРАЕТ СТАТИСТИКУ* по проектам. Вы можете отключить интернет, проверить трафик и даже собрать локальный билд из [исходников|https://github.com/bakhirev/assayo].
|
||||
|
|
Loading…
Reference in a new issue