This commit is contained in:
bakhirev 2024-08-10 01:08:00 +03:00
parent d0952ff866
commit 73b7b611a4
25 changed files with 80 additions and 296 deletions

View file

@ -5,11 +5,11 @@ import { useTranslation } from 'react-i18next';
import ISort from 'ts/interfaces/Sort'; 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 viewSettings from 'ts/store/ViewSettings';
import { downloadExcel } from 'ts/helpers/File'; import { downloadExcel } from 'ts/helpers/File';
import isMobile from 'ts/helpers/isMobile'; import isMobile from 'ts/helpers/isMobile';
import fullScreen from 'ts/store/FullScreen'; import fullScreen from 'ts/store/FullScreen';
import dataViewStore from './store';
import style from './index.module.scss'; import style from './index.module.scss';
import PageWrapper from '../Page/wrapper'; import PageWrapper from '../Page/wrapper';
@ -41,7 +41,7 @@ function DataView({
}: IDataViewProps): React.ReactElement | null { }: IDataViewProps): React.ReactElement | null {
const { t } = useTranslation(); const { t } = useTranslation();
const urlParams = useParams<any>(); const urlParams = useParams<any>();
const defaultType = viewSettings.getItem(urlParams, isMobile ? 'cards' : 'table'); const defaultType = dataViewStore.getItem(urlParams, isMobile ? 'cards' : 'table');
const [localType, setType] = useState<string>(type || defaultType); const [localType, setType] = useState<string>(type || defaultType);
if (!rows || !rows.length) return null; if (!rows || !rows.length) return null;
@ -89,7 +89,7 @@ function DataView({
onClick={() => { onClick={() => {
const newType = localType === 'table' ? 'cards' : 'table'; const newType = localType === 'table' ? 'cards' : 'table';
setType(newType); setType(newType);
viewSettings.setItem(urlParams, newType, 'table'); dataViewStore.setItem(urlParams, newType, 'table');
}} }}
/> />
)} )}

View file

@ -1,5 +1,8 @@
import React from 'react'; import React from 'react';
import CustomSelect from 'ts/components/CustomSelect';
import isMobile from 'ts/helpers/isMobile';
import { IUiKitWrapperProps } from './Wrapper'; import { IUiKitWrapperProps } from './Wrapper';
import UiKitButton from './Button'; import UiKitButton from './Button';
import UiKitSelect from './Select'; import UiKitSelect from './Select';
@ -41,11 +44,19 @@ function UiKitSelectWithButtons({
> >
« «
</UiKitButton> </UiKitButton>
<UiKitSelect {isMobile ? (
value={value} <UiKitSelect
options={options} value={value}
onChange={onChange} options={options}
/> onChange={onChange}
/>
) : (
<CustomSelect
value={value}
options={options}
onChange={onChange}
/>
)}
<UiKitButton <UiKitButton
mode="second" mode="second"
className={style.ui_kit_select_with_buttons_right} className={style.ui_kit_select_with_buttons_right}

View file

@ -1,6 +1,6 @@
import IHashMap from 'ts/interfaces/HashMap'; import IHashMap from 'ts/interfaces/HashMap';
import { get2Number } from 'ts/helpers/formatter'; import { get2Number } from 'ts/helpers/formatter';
import settingsStore from 'ts/store/Settings'; import userSettings from 'ts/store/UserSettings';
import IMonth from '../interfaces/Month'; import IMonth from '../interfaces/Month';
import IWorkDay from '../interfaces/WorkDay'; import IWorkDay from '../interfaces/WorkDay';
@ -66,7 +66,7 @@ function addCommitsInMonth(
const uniqueAuthors = Array.from(new Set(authors)); const uniqueAuthors = Array.from(new Set(authors));
// @ts-ignore // @ts-ignore
monthsByDate[key].money = uniqueAuthors.reduce((money: number, name: string) => { monthsByDate[key].money = uniqueAuthors.reduce((money: number, name: string) => {
return money + settingsStore.getMiddleSalaryInMonth(name); return money + userSettings.getCurrentSalaryInMonth(name); // TODO: need middle salary in month
}, 0); }, 0);
} }
} }
@ -95,4 +95,4 @@ export default function getCommitsByMonth(
addCommitsInMonth(prev, monthsByDate, commits); addCommitsInMonth(prev, monthsByDate, commits);
return months; return months;
} }

View file

@ -4,7 +4,6 @@ import IHashMap from 'ts/interfaces/HashMap';
import { ONE_DAY } from 'ts/helpers/formatter'; import { ONE_DAY } from 'ts/helpers/formatter';
import { increment } from 'ts/helpers/Math'; import { increment } from 'ts/helpers/Math';
import settingsStore from 'ts/store/Settings';
import userSettings from 'ts/store/UserSettings'; import userSettings from 'ts/store/UserSettings';
export default class DataGripByAuthor { export default class DataGripByAuthor {
@ -138,10 +137,9 @@ export default class DataGripByAuthor {
return total; return total;
} }
updateTotalInfo() { updateTotalInfo(lastCommit: ICommit) {
const HOLIDAYS = 118 + 22; // праздники + выходные + отпуск const HOLIDAYS = 118 + 22; // праздники + выходные + отпуск
const WORK_AND_HOLIDAYS = (HOLIDAYS / (365 - HOLIDAYS)); const WORK_AND_HOLIDAYS = (HOLIDAYS / (365 - HOLIDAYS));
const lastCommit = settingsStore.commits[settingsStore.commits.length - 1];
const dismissedLimit = lastCommit?.milliseconds - 32 * ONE_DAY; const dismissedLimit = lastCommit?.milliseconds - 32 * ONE_DAY;
this.employment = { this.employment = {

View file

@ -1,6 +1,6 @@
import ICommit from 'ts/interfaces/Commit'; import ICommit from 'ts/interfaces/Commit';
import IHashMap from 'ts/interfaces/HashMap'; import IHashMap from 'ts/interfaces/HashMap';
import settingsStore from 'ts/store/Settings'; import userSettings from 'ts/store/UserSettings';
import { increment } from 'ts/helpers/Math'; import { increment } from 'ts/helpers/Math';
interface IStatByAuthor { interface IStatByAuthor {
@ -85,7 +85,8 @@ export default class DataGripByScope {
for (let name in dot.authors) { for (let name in dot.authors) {
const user = dot.authors[name]; const user = dot.authors[name];
const days: number = Object.keys(user.days).length; const days: number = Object.keys(user.days).length;
salaryCache[name] = salaryCache[name] || settingsStore.getMiddleSalaryInDay(name); // TODO: need middle salary in month;
salaryCache[name] = salaryCache[name] || userSettings.getCurrentSalaryInMonth(name);
cost += days * salaryCache[name]; cost += days * salaryCache[name];
dot.authors[name] = { ...user, days }; dot.authors[name] = { ...user, days };
} }

View file

@ -1,6 +1,6 @@
import ICommit from 'ts/interfaces/Commit'; import ICommit from 'ts/interfaces/Commit';
import IHashMap from 'ts/interfaces/HashMap'; import IHashMap from 'ts/interfaces/HashMap';
import settingsStore from 'ts/store/Settings'; import userSettings from 'ts/store/UserSettings';
import { increment } from 'ts/helpers/Math'; import { increment } from 'ts/helpers/Math';
import MinMaxCounter from './counter'; import MinMaxCounter from './counter';
@ -119,7 +119,7 @@ export default class DataGripByTimestamp {
#getWeekendPaymentByAuthor(statistic: any, dataGripByAuthor: any) { #getWeekendPaymentByAuthor(statistic: any, dataGripByAuthor: any) {
if (dataGripByAuthor.isStaff) return 0; if (dataGripByAuthor.isStaff) return 0;
const salaryInDay = settingsStore.getMiddleSalaryInDay(dataGripByAuthor.author); const salaryInDay = userSettings.getCurrentSalaryInMonth(dataGripByAuthor.author); // TODO: need middle salary in month
const saturday = statistic.workByDay[5] * salaryInDay; const saturday = statistic.workByDay[5] * salaryInDay;
const sunday = statistic.workByDay[6] * salaryInDay; const sunday = statistic.workByDay[6] * salaryInDay;
return saturday + sunday; return saturday + sunday;

View file

@ -1,6 +1,5 @@
import ICommit from 'ts/interfaces/Commit'; import ICommit from 'ts/interfaces/Commit';
import IHashMap from 'ts/interfaces/HashMap'; import IHashMap from 'ts/interfaces/HashMap';
import settingsStore from 'ts/store/Settings';
import { increment } from 'ts/helpers/Math'; import { increment } from 'ts/helpers/Math';
export default class DataGripByWeek { export default class DataGripByWeek {
@ -79,8 +78,8 @@ export default class DataGripByWeek {
authorsLength += 1; authorsLength += 1;
workDays[name] = Object.keys(dot.workDays[name]).length; workDays[name] = Object.keys(dot.workDays[name]).length;
workDaysTotal += workDays[name]; workDaysTotal += workDays[name];
// userSettings.getCurrentWorkDaysInWeek(name); TODO: need middle salary in month
const limit = settingsStore.workDays[name] || settingsStore.defaultWorkDays; const limit = 5;
const lazyDaysValue = limit - workDays[name]; const lazyDaysValue = limit - workDays[name];
const weekDaysValue = workDays[name] - limit; const weekDaysValue = workDays[name] - limit;

View file

@ -1,6 +1,5 @@
import ICommit, { ISystemCommit } from 'ts/interfaces/Commit'; import ICommit, { ISystemCommit } from 'ts/interfaces/Commit';
import settingsStore from 'ts/store/Settings';
import Recommendations from 'ts/helpers/Recommendations'; import Recommendations from 'ts/helpers/Recommendations';
import DataGripByAuthor from './components/author'; import DataGripByAuthor from './components/author';
@ -40,10 +39,6 @@ class DataGrip {
release: any = new DataGripByRelease(); release: any = new DataGripByRelease();
initializationInfo: any = {};
hash: number = 0;
clear() { clear() {
this.firstLastCommit.clear(); this.firstLastCommit.clear();
this.author.clear(); this.author.clear();
@ -75,8 +70,8 @@ class DataGrip {
} }
} }
#updateTotalInfo() { updateTotalInfo() {
this.author.updateTotalInfo(); this.author.updateTotalInfo(this.firstLastCommit.maxData);
this.team.updateTotalInfo(this.author); this.team.updateTotalInfo(this.author);
this.scope.updateTotalInfo(); this.scope.updateTotalInfo();
this.type.updateTotalInfo(); this.type.updateTotalInfo();
@ -87,28 +82,6 @@ class DataGrip {
this.tasks.updateTotalInfo(this.pr); this.tasks.updateTotalInfo(this.pr);
this.release.updateTotalInfo(); this.release.updateTotalInfo();
} }
updateByInitialization() {
this.#updateTotalInfo();
this.initializationInfo = this.author.statistic
.reduce((info: any, author: any) => {
info[author.author] = { ...author };
return info;
}, {});
}
updateByFilters() {
this.clear();
settingsStore.commits.forEach((commit: ICommit) => {
const author = this.initializationInfo[commit.author] || { commits: 0 };
if (commit.timestamp < settingsStore.from
|| commit.timestamp > settingsStore.to
|| author.commits < settingsStore.minCommits) return;
this.addCommit(commit);
});
this.#updateTotalInfo();
this.hash = Math.random();
}
} }
const dataGrip = new DataGrip(); const dataGrip = new DataGrip();

View file

@ -47,10 +47,6 @@ export function get2Number(time: number) {
return time < 10 ? `0${time}` : time; return time < 10 ? `0${time}` : time;
} }
export function getClearHTML(text: string) {
return (text || '').trim().replace(/(>[\s\r\n]*<)/gim, '><');
}
export function getDate(timestamp: string) { export function getDate(timestamp: string) {
if (!timestamp) return ''; if (!timestamp) return '';
const date = new Date(timestamp); const date = new Date(timestamp);
@ -81,7 +77,7 @@ function getCurrencyFromUSD(money: number, currency: string) {
const k = { const k = {
USD: 1, USD: 1,
EUR: 0.92, EUR: 0.92,
RUB: 98, RUB: 90,
CNY: 7.26, CNY: 7.26,
JPY: 158, JPY: 158,
KRW: 1360, KRW: 1360,

View file

@ -22,7 +22,7 @@ export interface ILog {
month: number; // 1, month: number; // 1,
year: number; // 2021, year: number; // 2021,
timestamp: string; // 2021-02-09", timestamp: string; // 2021-02-09",
milliseconds: number; // 1612828800000, milliseconds: number; // 1612828800000,
week: number; // 42, week: number; // 42,
// user // user

View file

@ -1,7 +1,8 @@
import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import settingsStore from 'ts/store/Settings'; import filtersInHeaderStore from 'ts/store/FiltersInHeader';
import dataGripStore from 'ts/store/DataGrip';
import style from '../../styles/filters.module.scss'; import style from '../../styles/filters.module.scss';
@ -19,7 +20,8 @@ function Button({
<button <button
className={style.header_filters_fast_button} className={style.header_filters_fast_button}
onClick={() => { onClick={() => {
settingsStore.setFilterByDateType(type); filtersInHeaderStore.setFilterByDateType(type);
dataGripStore.updateStatistic();
}} }}
> >
{t(title)} {t(title)}

View file

@ -1,7 +1,8 @@
import React from 'react'; import React from 'react';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import settingsStore from 'ts/store/Settings'; import filtersInHeaderStore from 'ts/store/FiltersInHeader';
import dataGripStore from 'ts/store/DataGrip';
import style from '../../styles/filters.module.scss'; import style from '../../styles/filters.module.scss';
@ -18,10 +19,11 @@ const Input = observer(({
<input <input
type="date" type="date"
placeholder={placeholder || ''} placeholder={placeholder || ''}
value={settingsStore[type] ?? ''} value={filtersInHeaderStore[type] ?? ''}
className={style.header_filters_input} className={style.header_filters_input}
onChange={(event: any) => { onChange={(event: any) => {
settingsStore.updateProperty(type, event.target.value); filtersInHeaderStore.updateProperty(type, event.target.value);
dataGripStore.updateStatistic();
}} }}
/> />
); );

View file

@ -31,7 +31,7 @@ const Tasks = observer(({
loader={(pagination?: IPaginationRequest, sort?: ISort[]) => getFakeLoader({ loader={(pagination?: IPaginationRequest, sort?: ISort[]) => getFakeLoader({
content: rows, pagination, sort, mode, content: rows, pagination, sort, mode,
})} })}
watch={`${mode}${dataGripStore.dataGrip.hash}${user.author}`} watch={`${mode}${dataGripStore.hash}${user.author}`}
> >
<TasksView <TasksView
mode={mode} mode={mode}

View file

@ -227,7 +227,7 @@ const Author = observer(({
loader={(pagination?: IPaginationRequest, sort?: ISort[]) => getFakeLoader({ loader={(pagination?: IPaginationRequest, sort?: ISort[]) => getFakeLoader({
content: rows, pagination, sort, mode, content: rows, pagination, sort, mode,
})} })}
watch={`${mode}${dataGripStore.dataGrip.hash}`} watch={`${mode}${dataGripStore.hash}`}
> >
<AuthorView <AuthorView
mode={mode} mode={mode}

View file

@ -135,7 +135,7 @@ const Extension = observer(({
loader={(pagination?: IPaginationRequest) => getFakeLoader({ loader={(pagination?: IPaginationRequest) => getFakeLoader({
content: rows, pagination, mode, content: rows, pagination, mode,
})} })}
watch={`${mode}${dataGripStore.dataGrip.hash}`} watch={`${mode}${dataGripStore.hash}`}
> >
<ExtensionView <ExtensionView
mode={mode} mode={mode}

View file

@ -127,7 +127,7 @@ const Extension = observer(({
loader={(pagination?: IPaginationRequest) => getFakeLoader({ loader={(pagination?: IPaginationRequest) => getFakeLoader({
content: rows, pagination, mode, content: rows, pagination, mode,
})} })}
watch={`${mode}${dataGripStore.dataGrip.hash}`} watch={`${mode}${dataGripStore.hash}`}
> >
<ExtensionView <ExtensionView
mode={mode} mode={mode}

View file

@ -127,7 +127,7 @@ const Type = observer(({
loader={(pagination?: IPaginationRequest) => getFakeLoader({ loader={(pagination?: IPaginationRequest) => getFakeLoader({
content: rows, pagination, mode, content: rows, pagination, mode,
})} })}
watch={`${mode}${dataGripStore.dataGrip.hash}`} watch={`${mode}${dataGripStore.hash}`}
> >
<TypeView <TypeView
mode={mode} mode={mode}

View file

@ -149,7 +149,7 @@ const Release = observer(({
loader={(pagination?: IPaginationRequest) => getFakeLoader({ loader={(pagination?: IPaginationRequest) => getFakeLoader({
content: rows, pagination, mode, content: rows, pagination, mode,
})} })}
watch={`${mode}${dataGripStore.dataGrip.hash}`} watch={`${mode}${dataGripStore.hash}`}
> >
<ReleaseView <ReleaseView
mode={mode} mode={mode}

View file

@ -135,7 +135,7 @@ const Scope = observer(({
loader={(pagination?: IPaginationRequest) => getFakeLoader({ loader={(pagination?: IPaginationRequest) => getFakeLoader({
content: rows, pagination, mode, content: rows, pagination, mode,
})} })}
watch={`${mode}${dataGripStore.dataGrip.hash}`} watch={`${mode}${dataGripStore.hash}`}
> >
<ScopeView <ScopeView
mode={mode} mode={mode}

View file

@ -147,7 +147,7 @@ const Tasks = observer(({
loader={(pagination?: IPaginationRequest, sort?: ISort[]) => getFakeLoader({ loader={(pagination?: IPaginationRequest, sort?: ISort[]) => getFakeLoader({
content: rows, pagination, sort, mode, content: rows, pagination, sort, mode,
})} })}
watch={`${mode}${dataGripStore.dataGrip.hash}`} watch={`${mode}${dataGripStore.hash}`}
> >
<br/> <br/>
<br/> <br/>

View file

@ -139,7 +139,7 @@ const Type = observer(({
loader={(pagination?: IPaginationRequest, sort?: ISort[]) => getFakeLoader({ loader={(pagination?: IPaginationRequest, sort?: ISort[]) => getFakeLoader({
content: rows, pagination, sort, mode, content: rows, pagination, sort, mode,
})} })}
watch={`${mode}${dataGripStore.dataGrip.hash}`} watch={`${mode}${dataGripStore.hash}`}
> >
<TypeView <TypeView
mode={mode} mode={mode}

View file

@ -183,7 +183,7 @@ const Week = observer(({
loader={(pagination?: IPaginationRequest, sort?: ISort[]) => getFakeLoader({ loader={(pagination?: IPaginationRequest, sort?: ISort[]) => getFakeLoader({
content: rows, pagination, sort, content: rows, pagination, sort,
})} })}
watch={`${mode}${dataGripStore.dataGrip.hash}`} watch={`${mode}${dataGripStore.hash}`}
> >
<WeekView <WeekView
mode={mode} mode={mode}

View file

@ -11,7 +11,7 @@ import getTitle from 'ts/helpers/Title';
import { setDefaultValues } from 'ts/pages/Settings/helpers/getEmptySettings'; import { setDefaultValues } from 'ts/pages/Settings/helpers/getEmptySettings';
import { applicationHasCustom } from 'ts/helpers/RPC'; import { applicationHasCustom } from 'ts/helpers/RPC';
import settingsStore from './Settings'; import filtersInHeaderStore from './FiltersInHeader';
export enum DataParseStatusEnum { export enum DataParseStatusEnum {
WAITING = 'waiting', WAITING = 'waiting',
@ -34,14 +34,18 @@ class DataGripStore implements IDataGripStore {
fileGrip: any = null; fileGrip: any = null;
hash: number = 0;
status: DataParseStatusEnum = DataParseStatusEnum.PROCESSING; status: DataParseStatusEnum = DataParseStatusEnum.PROCESSING;
constructor() { constructor() {
makeObservable(this, { makeObservable(this, {
commits: observable, commits: observable,
dataGrip: observable, dataGrip: observable,
hash: observable,
status: observable, status: observable,
setCommits: action, setCommits: action,
updateStatistic: action,
}); });
} }
@ -65,20 +69,17 @@ class DataGripStore implements IDataGripStore {
: DataParseStatusEnum.WAITING; : DataParseStatusEnum.WAITING;
if (this.status === DataParseStatusEnum.DONE) { if (this.status === DataParseStatusEnum.DONE) {
setDefaultValues(dataGrip.firstLastCommit.minData, dataGrip.firstLastCommit.maxData); filtersInHeaderStore.updateByCommits(
settingsStore.updateByCommits(
this.commits,
dataGrip.firstLastCommit.minData, dataGrip.firstLastCommit.minData,
dataGrip.firstLastCommit.maxData, dataGrip.firstLastCommit.maxData,
); );
setDefaultValues(dataGrip.firstLastCommit.minData, dataGrip.firstLastCommit.maxData);
dataGrip.updateByInitialization(); dataGrip.updateTotalInfo();
achievements.updateByGrip(dataGrip, fileGrip); achievements.updateByGrip(dataGrip, fileGrip);
} }
this.dataGrip = null; this.#updateRender();
this.dataGrip = dataGrip;
this.fileGrip = fileGrip;
console.dir(this.dataGrip); console.dir(this.dataGrip);
console.dir(this.fileGrip); console.dir(this.fileGrip);
@ -87,13 +88,27 @@ class DataGripStore implements IDataGripStore {
} }
} }
updateChars() { // todo: remove, never use updateStatistic() {
console.log('need update data TODO'); dataGrip.clear();
dataGrip.updateByFilters(); fileGrip.clear();
if (!dataGrip.author.list.length) return; this.commits.forEach((commit: ICommit | ISystemCommit) => {
if (commit.timestamp < filtersInHeaderStore.from
|| commit.timestamp > filtersInHeaderStore.to) return;
dataGrip.addCommit(commit);
fileGrip.addCommit(commit);
});
fileGrip.updateTotalInfo();
dataGrip.updateTotalInfo();
achievements.updateByGrip(dataGrip, fileGrip); achievements.updateByGrip(dataGrip, fileGrip);
this.#updateRender();
}
#updateRender() {
this.dataGrip = null; this.dataGrip = null;
this.dataGrip = dataGrip; this.dataGrip = dataGrip;
this.fileGrip = null;
this.fileGrip = fileGrip;
this.hash = Math.random();
} }
} }

View file

@ -1,144 +0,0 @@
import { makeObservable, observable, action } from 'mobx';
import { ONE_DAY } from 'ts/helpers/formatter';
import ICommit from '../interfaces/Commit';
import dataGripStore from './DataGrip';
interface ISettingsStore {
commits: ICommit[];
defaultFrom: string;
defaultTo: string;
TODAY: Date;
from: string;
to: string;
minCommits: number;
isFullTime: boolean;
defaultSalary: number;
defaultWorkDays: number;
holidaysInYear: number;
currency: string;
salary: any;
workDays: any;
updateByCommits: (commits: ICommit[], first: ICommit, last: ICommit) => void,
setFilterByDateType: (type: string) => void,
}
class SettingsStore implements ISettingsStore {
commits: ICommit[] = [];
defaultFrom: string = '';
defaultTo: string = '';
TODAY: Date = new Date();
from: string = '';
to: string = '';
minCommits: number = 20;
isFullTime: boolean = true;
defaultSalary: number = 3000;
defaultWorkDays: number = 5;
holidaysInYear: number = 118 + 22; // праздники + выходные + отпуск
currency: string = 'USD';
salary: any = {};
workDays: any = {};
constructor() {
makeObservable(this, {
commits: observable,
defaultFrom: observable,
defaultTo: observable,
TODAY: observable,
from: observable,
to: observable,
minCommits: observable,
isFullTime: observable,
defaultSalary: observable,
defaultWorkDays: observable,
holidaysInYear: observable,
currency: observable,
salary: observable,
workDays: observable,
updateByCommits: action,
setFilterByDateType: action,
updateProperty: action,
setSalary: action,
});
}
getMiddleSalaryInMonth(name: string): number {
return this.salary[name] || this.defaultSalary;
}
getMiddleSalaryInDay(name: string) {
const salaryInMonth = this.getMiddleSalaryInMonth(name);
const workDaysInWeek = this.workDays[name] || this.defaultWorkDays;
const workDaysInMonth = Math.ceil(4.3 * workDaysInWeek);
return salaryInMonth / workDaysInMonth;
}
getValue(property: string) {
return property.split('.').reduce((acc, key) => acc[key], this);
}
updateByCommits(commits: ICommit[], firstCommit: ICommit, lastCommit: ICommit) {
this.commits = commits;
this.defaultFrom = firstCommit.timestamp;
this.defaultTo = lastCommit.timestamp;
this.TODAY = new Date(this.defaultTo);
this.from = this.defaultFrom;
this.to = this.defaultTo;
this.minCommits = 20;
}
setFilterByDateType(type: string) {
const count = {
year: 365,
halfYear: 183,
month: 30,
week: 7,
day: 1,
}[type];
this.from = count
? (new Date(this.TODAY.getTime() - ONE_DAY * count)).toISOString().split('T')[0]
: this.defaultFrom;
this.to = this.defaultTo;
this.minCommits = {
all: 20,
year: 20,
halfYear: 10,
month: 2,
}[type] || 1;
dataGripStore.updateChars();
}
updateProperty(propertyName: string, value?: any) {
this[propertyName] = value ?? null;
dataGripStore.updateChars();
}
setSalary(userName: string, salary?: number) {
this.salary[userName] = salary || this.defaultSalary;
}
}
const settingsStore = new SettingsStore();
export default settingsStore;

View file

@ -1,69 +0,0 @@
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;