This commit is contained in:
bakhirev 2024-10-01 10:15:15 +03:00
parent de843015b9
commit b5c0fd7167
17 changed files with 142 additions and 29 deletions

View file

@ -8,7 +8,7 @@
<meta name="HandheldFriendly" content="True"> <meta name="HandheldFriendly" content="True">
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">
<meta name="format-detection" content="address=no"> <meta name="format-detection" content="address=no">
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default"> <meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="theme-color" content="white"/> <meta name="theme-color" content="white"/>
@ -25,7 +25,6 @@
</script> </script>
<link rel="icon" href="%PUBLIC_URL%/favicon.svg" /> <link rel="icon" href="%PUBLIC_URL%/favicon.svg" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>Git Statistics</title> <title>Git Statistics</title>
<meta name="description" content="Simple and fast report on git commit history."> <meta name="description" content="Simple and fast report on git commit history.">

View file

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { render } from 'react-dom'; import { createRoot } from 'react-dom/client';
import { HashRouter } from 'react-router-dom'; import { HashRouter } from 'react-router-dom';
import localization from 'ts/helpers/Localization'; import localization from 'ts/helpers/Localization';
@ -45,14 +45,16 @@ function renderReactApplication() {
printStore.endPrint(); printStore.endPrint();
}; };
render( const container = document.getElementById('root');
if (!container) return;
createRoot(container).render(
<React.StrictMode> <React.StrictMode>
<HashRouter> <HashRouter>
<Main /> <Main />
<Notifications/> <Notifications/>
</HashRouter> </HashRouter>
</React.StrictMode>, </React.StrictMode>,
document.getElementById('root'),
); );
} }

View file

@ -86,6 +86,7 @@ export class DataLoaderStore implements IDataLoaderStore {
loadMore: action, loadMore: action,
showAll: action, showAll: action,
updateSort: action, updateSort: action,
updateWatchedValue: action,
canSendRequest: computed, canSendRequest: computed,
}); });
} }

View file

@ -0,0 +1,29 @@
function polarToCartesian(x: number, y: number, r: number, degrees: number) {
const radians = degrees * Math.PI / 180;
return [
x + (r * Math.cos(radians)),
y + (r * Math.sin(radians)),
];
}
export function getSegmentPath(
x: number,
y: number,
r0: number,
r1: number,
d0: number,
d1: number,
) {
const arc = Math.abs(d0 - d1) > 180 ? 1 : 0;
const point = (radius: number, degree: number) =>
polarToCartesian(x, y, radius, degree)
.map(n => n.toPrecision(5))
.join(',');
return [
`M${point(r0, d0)}`,
`A${r0},${r0},0,${arc},1,${point(r0, d1)}`,
`L${point(r1, d1)}`,
`A${r1},${r1},0,${arc},0,${point(r1, d0)}`,
'Z',
].join('');
}

View file

@ -0,0 +1,12 @@
@import 'src/styles/variables';
.pie_svg {
display: inline-block;
height: 100%;
&_sector {
fill: transparent;
stroke: var(--color-black);
stroke-width: 2px;
}
}

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path d="M 0 100 L 20 80 L 40 80 L 40 100 Z" fill="transparent" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 192 B

View file

@ -0,0 +1,56 @@
import React from 'react';
import { IOptions, ISubLine } from 'ts/components/LineChart/interfaces';
import { getSegmentPath } from './helpers';
import style from './index.module.scss';
interface ILineSVGProps {
options: IOptions;
parts: ISubLine[];
center?: number;
}
const ROTATE = -90;
function LineSVG({
options,
parts,
center,
}: ILineSVGProps): React.ReactElement | null {
const centerRadius = 49 * ((center || 72) / 100);
let prev = 0;
const paths = parts.map((item: ISubLine) => {
const stroke = options.color.get(item.title).first;
const angle = 360 * item.width / 100;
const next = Math.min(prev + angle, 360);
const d = getSegmentPath(50, 50, centerRadius, 50, prev + ROTATE, next + ROTATE);
prev += angle;
return (
<path
key={item.title}
style={{ stroke }}
d={d}
className={style.pie_svg_sector}
/>
);
});
return (
<svg
viewBox="0 0 100 100"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
className={style.pie_svg}
>
{paths}
</svg>
);
}
LineSVG.defaultProps = {
className: '',
};
export default LineSVG;

View file

@ -12,7 +12,12 @@ import style from './styles/index.module.scss';
function addBannerInRandomIndex(list: any[]) { function addBannerInRandomIndex(list: any[]) {
const className = `${styleCard.recommendations_card} ${styleCard.recommendations_card_banner}`; const className = `${styleCard.recommendations_card} ${styleCard.recommendations_card_banner}`;
const item = (<Banner className={className} />); const item = (
<Banner
key="banner"
className={className}
/>
);
const index = Math.floor(Math.random() * list.length); const index = Math.floor(Math.random() * list.length);
const last = list.splice(index); const last = list.splice(index);
@ -32,12 +37,12 @@ function Recommendations({
.filter(item => item) .filter(item => item)
.map((recommendation) => (mode === 'print' ? ( .map((recommendation) => (mode === 'print' ? (
<CardForPrint <CardForPrint
key={recommendation[1]} key={recommendation.description}
recommendation={recommendation} recommendation={recommendation}
/> />
) : ( ) : (
<Card <Card
key={recommendation[1]} key={recommendation.description}
recommendation={recommendation} recommendation={recommendation}
onClick={() => { onClick={() => {
recommendationStore.open(recommendation); recommendationStore.open(recommendation);

View file

@ -21,22 +21,20 @@ function UiKitSelect({
options, options,
onChange, onChange,
}: IUiKitSelectProps) { }: IUiKitSelectProps) {
const items = (options || []) const formattedOptions = (options || []).map((option: any) => (
.map((option: any, index: number) => { typeof option !== 'object'
const formattedOption = typeof option !== 'object' ? ({ id: option, title: option })
? ({ id: option, title: option }) : option
: option; ));
return ( const items = formattedOptions.map((option: any, index: number) => (
<option <option
key={`${formattedOption?.id}_${index}`} key={`${option?.id}_${index}`}
value={formattedOption?.id ?? null} value={option?.id ?? null}
selected={value === formattedOption?.id} >
> {option?.title ?? option?.id ?? ''}
{formattedOption?.title ?? formattedOption?.id ?? ''} </option>
</option> ));
);
});
return ( return (
<Wrapper <Wrapper
@ -47,6 +45,7 @@ function UiKitSelect({
className={className} className={className}
> >
<select <select
value={value}
className={`${style.ui_kit_common} ${styleSelect.ui_kit_select} ${className || ''}`} className={`${style.ui_kit_common} ${styleSelect.ui_kit_select} ${className || ''}`}
onChange={(event: ChangeEvent<HTMLSelectElement>) => { onChange={(event: ChangeEvent<HTMLSelectElement>) => {
const selectedValue = event.target.value; const selectedValue = event.target.value;

View file

@ -26,7 +26,7 @@ export default class DataGripByAuthor {
} }
addCommit(commit: ICommit) { addCommit(commit: ICommit) {
if (this.commits[commit.author]) { if (this.commits.hasOwnProperty(commit.author)) {
this.#updateCommitByAuthor(commit); this.#updateCommitByAuthor(commit);
} else { } else {
this.#addCommitByAuthor(commit); this.#addCommitByAuthor(commit);

View file

@ -32,7 +32,7 @@ export default class DataGripByScope {
} }
addCommit(commit: ICommit) { addCommit(commit: ICommit) {
if (this.commits[commit.scope]) { if (this.commits.hasOwnProperty(commit.scope)) {
this.#updateCommitByScope(commit); this.#updateCommitByScope(commit);
} else { } else {
this.#addCommitByScope(commit); this.#addCommitByScope(commit);

View file

@ -18,7 +18,7 @@ export default class DataGripByTasks {
} }
addCommit(commit: ICommit) { addCommit(commit: ICommit) {
if (this.commits[commit.task]) { if (this.commits.hasOwnProperty(commit.task)) {
this.#updateCommitByTask(commit); this.#updateCommitByTask(commit);
} else { } else {
this.#addCommitByTask(commit); this.#addCommitByTask(commit);

View file

@ -17,7 +17,7 @@ export default class DataGripByType {
} }
addCommit(commit: ICommit) { addCommit(commit: ICommit) {
if (this.commits[commit.type]) { if (this.commits.hasOwnProperty(commit.type)) {
this.#updateCommitByType(commit); this.#updateCommitByType(commit);
} else { } else {
this.#addCommitByType(commit); this.#addCommitByType(commit);

View file

@ -17,7 +17,7 @@ export default class DataGripByWeek {
} }
addCommit(commit: ICommit) { addCommit(commit: ICommit) {
if (this.commits[commit.week]) { if (this.commits.hasOwnProperty(commit.week)) {
this.#updateCommitByWeek(commit); this.#updateCommitByWeek(commit);
} else { } else {
this.#addCommitByWeek(commit); this.#addCommitByWeek(commit);

View file

@ -25,6 +25,7 @@ export default class FileBuilderCommon {
} }
static updateTotal(file: IDirtyFile) { static updateTotal(file: IDirtyFile) {
if (Array.isArray(file?.path)) return;
// @ts-ignore // @ts-ignore
const { name, type, extension } = getNameTypeExtension(file?.path); const { name, type, extension } = getNameTypeExtension(file?.path);
file.name = name; file.name = name;

View file

@ -33,6 +33,8 @@ function getTopUser(listOfChanges: any) {
} }
export default function getAchievementByFile(fileGrip: any, byAuthor: any) { export default function getAchievementByFile(fileGrip: any, byAuthor: any) {
if (!fileGrip.files.list.length) return;
const moreLintHint: any = []; const moreLintHint: any = [];
const moreReadMe: any = []; const moreReadMe: any = [];
const moreStyle: any = []; const moreStyle: any = [];

View file

@ -89,13 +89,16 @@ function ViewWithWelcome() {
); );
} }
let bugInReactWithDoubleInit = 1;
const Main = observer(() => { const Main = observer(() => {
const view = viewNameStore.view; const view = viewNameStore.view;
useEffect(() => { useEffect(() => {
console.log('main');
// @ts-ignore // @ts-ignore
const list = window?.report || []; const list = window?.report || [];
if (list?.length) { if (list?.length && bugInReactWithDoubleInit !== list?.length) {
bugInReactWithDoubleInit = list?.length;
dataGripStore.asyncSetCommits(list); dataGripStore.asyncSetCommits(list);
} else { } else {
viewNameStore.toggle(ViewNameEnum.WELCOME); viewNameStore.toggle(ViewNameEnum.WELCOME);