This commit is contained in:
Бахирев 2024-04-04 20:06:41 +03:00
parent c3e8f39cf0
commit b3bd463d84
87 changed files with 362 additions and 230 deletions

37
LICENSE
View file

@ -1,37 +0,0 @@
Copyright (c) Aleksei Bakhirev <alexey-bakhirev@yandex.ru>
-- EN
The purpose of this license is to protect the copyrights and limit the use of the Software .
Terms of the license:
01. The copyright holder grants the user the non-exclusive right to use the Software for personal, non-commercial or educational purposes.
02. The user is not allowed to modify, distribute, sublicense, translate, create derivative works based on the Software without the prior written consent of the Copyright Holder.
03. When using the Software, the user must include the name of the author and a link to the license.
04. If the Software is modified, the user should notify the Copyright Holder and obtain their permission for the changes.
05. This license cannot be transferred to another person or organization without the prior written permission of the Copyright Holder.
06. This license does not grant the user ownership rights to the Software.
07. All rights not granted under this license are reserved by the Copyright Holder.
08. If the user violates the terms of this license, the Copyright Holder has the right to require the termination of use of the protected work, removal of the protected work from any media, as well as compensation for damages.
09. The author assumes no responsibility for any damage, including direct, indirect, incidental, special or other damage, resulting from the use or inability to use the software.
10. The author also does not warrant that the software will run without interruptions, errors or other problems, and reserves the right to modify or update the software at any time without prior notice.
11. Additionally, the author does not warrant the softwares conformity to any specific purpose or requirement, and the use of the software is at the users own risk.
12. All these terms and conditions are part of the license agreement that the user accepts when using the software.
-- RU
Эта лицензия предназначена для обеспечения защиты авторских прав и ограничения использования защищенного произведения.
Условия лицензии:
01. Правообладатель предоставляет пользователю неисключительное право на использование защищенного произведения для личных, некоммерческих или образовательных целей.
02. Пользователь не имеет права изменять, распространять, сублицензировать, переводить, создавать производные произведения на основе защищенного произведения без предварительного письменного согласия Правообладателя.
03. При использовании защищенного произведения пользователь обязан указывать имя автора и ссылку на лицензию.
04. В случае внесения изменений в защищенное произведение, пользователь должен уведомить об этом Правообладателя и получить его разрешение на внесение изменений.
05. Эта лицензия не может быть передана другому лицу или организации без предварительного письменного разрешения Правообладателя.
06. Данная лицензия не предоставляет пользователю права собственности на защищенное произведение.
07. Все права, не предоставленные в рамках этой лицензии, сохраняются за Правообладателем.
08. Если пользователь нарушает условия данной лицензии, Правообладатель имеет право потребовать прекращения использования защищенного произведения, удаления защищенного произведения с любых носителей, а также возмещение ущерба.
09. Автор не несет ответственности за любой ущерб, включая прямой, косвенный, случайный, специальный или другой, возникший в результате использования или невозможности использования программного обеспечения.
10. Автор также не гарантирует, что программное обеспечение будет работать без сбоев, ошибок или других проблем, и оставляет за собой право изменять или обновлять программное обеспечение в любое время без предварительного уведомления.
11. Кроме того, автор не гарантирует соответствие программного обеспечения каким-либо конкретным целям или требованиям, и использование программного обеспечения осуществляется пользователем на свой страх и риск.
12. Все эти условия и ограничения являются частью лицензионного соглашения, которое пользователь принимает при использовании программного обеспечения.

View file

@ -1,17 +1,17 @@
{ {
"files": { "files": {
"main.css": "./static/css/main.8e65d99e.css", "main.css": "./static/css/main.83b4380c.css",
"main.js": "./static/js/main.cb604897.js", "main.js": "./static/js/main.2f9b2b48.js",
"static/media/car.png": "./static/media/car.b8dd8738e37fe866285f.png", "static/media/car.png": "./static/media/car.b8dd8738e37fe866285f.png",
"index.html": "./index.html", "index.html": "./index.html",
"static/media/warning.svg": "./static/media/warning.e39a87773603f3ab157f.svg", "static/media/warning.svg": "./static/media/warning.e39a87773603f3ab157f.svg",
"static/media/info.svg": "./static/media/info.954631f6b19e3fe9c495.svg", "static/media/info.svg": "./static/media/info.954631f6b19e3fe9c495.svg",
"static/media/alert.svg": "./static/media/alert.41e2b99c481139c13074.svg", "static/media/alert.svg": "./static/media/alert.41e2b99c481139c13074.svg",
"main.8e65d99e.css.map": "./static/css/main.8e65d99e.css.map", "main.83b4380c.css.map": "./static/css/main.83b4380c.css.map",
"main.cb604897.js.map": "./static/js/main.cb604897.js.map" "main.2f9b2b48.js.map": "./static/js/main.2f9b2b48.js.map"
}, },
"entrypoints": [ "entrypoints": [
"static/css/main.8e65d99e.css", "static/css/main.83b4380c.css",
"static/js/main.cb604897.js" "static/js/main.2f9b2b48.js"
] ]
} }

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Capa_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 612 612" xml:space="preserve">
<path d="M175.205,239.62c0.127-1.965-0.533-3.902-1.833-5.381l-58.84-66.941c-1.3-1.479-3.135-2.381-5.102-2.508 c-1.975-0.126-3.902,0.533-5.381,1.833c-27.037,23.766-49.479,51.794-66.706,83.305c-0.944,1.729-1.165,3.762-0.611,5.651 c0.554,1.89,1.836,3.483,3.565,4.427l78.205,42.748c1.131,0.619,2.352,0.912,3.557,0.912c2.627,0,5.174-1.398,6.523-3.866 c11.386-20.828,26.229-39.359,44.114-55.08C174.178,243.422,175.08,241.587,175.205,239.62z"/>
<path d="M201.462,214.829c1.334,2.515,3.907,3.948,6.568,3.948c1.174,0,2.365-0.279,3.473-0.867 c20.962-11.117,43.512-18.371,67.025-21.561c4.064-0.551,6.913-4.293,6.362-8.358l-11.979-88.316 c-0.551-4.064-4.304-6.909-8.358-6.362c-35.708,4.843-69.949,15.857-101.772,32.736c-3.623,1.922-5.002,6.416-3.082,10.041 L201.462,214.829z"/>
<path d="M105.785,334.345l-86.017-23.338c-1.901-0.514-3.929-0.255-5.638,0.725s-2.958,2.598-3.475,4.499 C3.586,342.295,0,369.309,0,396.523c0,4.657,0.111,9.329,0.342,14.284c0.185,3.981,3.468,7.083,7.414,7.083 c0.116,0,0.234-0.002,0.35-0.008l89.031-4.113c1.967-0.09,3.82-0.96,5.145-2.415c1.327-1.455,2.022-3.38,1.93-5.347 c-0.155-3.341-0.23-6.444-0.23-9.484c0-18.02,2.365-35.873,7.029-53.066C112.082,339.499,109.743,335.42,105.785,334.345z"/>
<path d="M438.731,120.745c-32.411-15.625-67.04-25.308-102.925-28.786c-1.972-0.198-3.918,0.408-5.439,1.659 c-1.521,1.252-2.481,3.056-2.671,5.018l-8.593,88.712c-0.396,4.082,2.594,7.713,6.677,8.108 c23.652,2.291,46.463,8.669,67.8,18.954c1.015,0.49,2.118,0.738,3.225,0.738c0.826,0,1.654-0.139,2.45-0.416 c1.859-0.649,3.385-2.012,4.24-3.786l38.7-80.287C443.978,126.965,442.427,122.525,438.731,120.745z"/>
<path d="M569.642,245.337c0.48-1.911,0.184-3.932-0.828-5.624c-18.432-30.835-41.933-57.983-69.848-80.686 c-1.529-1.242-3.48-1.824-5.447-1.627c-1.959,0.203-3.758,1.174-5,2.702l-56.237,69.144c-1.242,1.529-1.828,3.488-1.625,5.447 c0.201,1.959,1.173,3.758,2.702,5.002c18.47,15.019,34.015,32.975,46.205,53.369c1.392,2.326,3.855,3.618,6.383,3.618 c1.297,0,2.61-0.34,3.803-1.054l76.501-45.728C567.94,248.889,569.16,247.248,569.642,245.337z"/>
<path d="M598.044,304.939c-1.228-3.915-5.397-6.096-9.308-4.867l-85.048,26.648c-3.915,1.226-6.093,5.393-4.867,9.306 c6.104,19.486,9.199,39.839,9.199,60.494c0,3.041-0.076,6.144-0.23,9.484c-0.092,1.967,0.602,3.892,1.93,5.347 c1.327,1.456,3.178,2.325,5.145,2.415l89.031,4.113c0.118,0.005,0.234,0.008,0.35,0.008c3.944,0,7.228-3.103,7.414-7.083 c0.229-4.955,0.342-9.627,0.342-14.284C612,365.306,607.306,334.494,598.044,304.939z"/>
<path d="M305.737,380.755c-1.281,0-2.555,0.042-3.824,0.11l-120.65-71.185c-2.953-1.745-6.702-1.308-9.176,1.065 c-2.476,2.371-3.07,6.099-1.456,9.121l65.815,123.355c-0.242,2.376-0.371,4.775-0.371,7.195c0,18.608,7.246,36.101,20.403,49.258 c13.158,13.158,30.652,20.404,49.26,20.404c18.608,0,36.101-7.248,49.258-20.404c13.158-13.157,20.403-30.65,20.403-49.258 c0-18.608-7.246-36.101-20.403-49.258C341.839,388.001,324.344,380.755,305.737,380.755z"/>
</svg>

After

Width:  |  Height:  |  Size: 3 KiB

View file

@ -1 +1 @@
<!doctype html><html><head><meta name="viewport" content="width=device-width,height=device-height,initial-scale=1,user-scalable=no,maximum-scale=1"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="Cache-Control" content="no-cache"><meta http-equiv="cleartype" content="on"><meta name="HandheldFriendly" content="True"><meta name="format-detection" content="telephone=no"><meta name="format-detection" content="address=no"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="default"><meta name="theme-color" content="white"/><script type="text/javascript">var report=[]</script><script src="/log.txt"></script><script src="./log.txt"></script><script src="../log.txt"></script><script src="./log-0.txt"></script><script src="./log-1.txt"></script><script src="./log-2.txt"></script><script src="./log-3.txt"></script><script src="./log-4.txt"></script><script src="./log-5.txt"></script><script src="./log-6.txt"></script><script src="./report/log-0.txt"></script><script src="./report/log-1.txt"></script><script src="./report/log-2.txt"></script><script src="./report/log-3.txt"></script><script src="./report/log-4.txt"></script><script src="./report/log-5.txt"></script><script src="./report/log-6.txt"></script><link rel="icon" href="./favicon.svg"/><link rel="apple-touch-icon" href="./logo192.png"/><link rel="manifest" href="./manifest.json"/><title>Git Statistics</title><meta name="description" content="Simple and fast report on git commit history."><meta name="keywords" content="git, statistics, audit, history, log, monitoring, employee control"><meta name="author" content="Bakhirev Aleksei"><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="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."><meta property="og:image" content="http://assayo.jp/assets/seo/custom_icon_256.png"><meta property="og:site_name" content="Assayo"><meta property="og:url" content="http://assayo.jp/"><meta name="twitter:card" content="summary"><meta name="twitter:title" content="Git Statistics"><meta name="twitter:description" content="Simple and fast report on Git commit history."><meta name="twitter:creator" content="Bakhirev Aleksei"><meta name="twitter:image:src" content="http://assayo.jp/assets/seo/custom_icon_256.png"><meta name="twitter:domain" content="assayo.jp"><meta name="twitter:site" content="assayo.jp"><meta itemprop="name" content="Git Statistics"><meta itemprop="description" content="Simple and fast report on Git commit history."><meta itemprop="image" content="http://assayo.jp/assets/seo/custom_icon_256.png"><script defer="defer" src="./static/js/main.cb604897.js"></script><link href="./static/css/main.8e65d99e.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html> <!doctype html><html><head><meta name="viewport" content="width=device-width,height=device-height,initial-scale=1,user-scalable=no,maximum-scale=1"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="Cache-Control" content="no-cache"><meta http-equiv="cleartype" content="on"><meta name="HandheldFriendly" content="True"><meta name="format-detection" content="telephone=no"><meta name="format-detection" content="address=no"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="default"><meta name="theme-color" content="white"/><script type="text/javascript">var report=[]</script><script src="/log.txt"></script><script src="./log.txt"></script><script src="../log.txt"></script><script src="./log-0.txt"></script><script src="./log-1.txt"></script><script src="./log-2.txt"></script><script src="./log-3.txt"></script><script src="./log-4.txt"></script><script src="./log-5.txt"></script><script src="./log-6.txt"></script><script src="./report/log-0.txt"></script><script src="./report/log-1.txt"></script><script src="./report/log-2.txt"></script><script src="./report/log-3.txt"></script><script src="./report/log-4.txt"></script><script src="./report/log-5.txt"></script><script src="./report/log-6.txt"></script><link rel="icon" href="./favicon.svg"/><link rel="apple-touch-icon" href="./logo192.png"/><link rel="manifest" href="./manifest.json"/><title>Git Statistics</title><meta name="description" content="Simple and fast report on git commit history."><meta name="keywords" content="git, statistics, audit, history, log, monitoring, employee control"><meta name="author" content="Bakhirev Aleksei"><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="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."><meta property="og:image" content="http://assayo.jp/assets/seo/custom_icon_256.png"><meta property="og:site_name" content="Assayo"><meta property="og:url" content="http://assayo.jp/"><meta name="twitter:card" content="summary"><meta name="twitter:title" content="Git Statistics"><meta name="twitter:description" content="Simple and fast report on Git commit history."><meta name="twitter:creator" content="Bakhirev Aleksei"><meta name="twitter:image:src" content="http://assayo.jp/assets/seo/custom_icon_256.png"><meta name="twitter:domain" content="assayo.jp"><meta name="twitter:site" content="assayo.jp"><meta itemprop="name" content="Git Statistics"><meta itemprop="description" content="Simple and fast report on Git commit history."><meta itemprop="image" content="http://assayo.jp/assets/seo/custom_icon_256.png"><script defer="defer" src="./static/js/main.2f9b2b48.js"></script><link href="./static/css/main.83b4380c.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,5 @@
/*! sheetjs (C) 2013-present SheetJS -- http://sheetjs.com */
/*! xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ /*! xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
/** /**

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Capa_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 612 612" xml:space="preserve">
<path d="M175.205,239.62c0.127-1.965-0.533-3.902-1.833-5.381l-58.84-66.941c-1.3-1.479-3.135-2.381-5.102-2.508 c-1.975-0.126-3.902,0.533-5.381,1.833c-27.037,23.766-49.479,51.794-66.706,83.305c-0.944,1.729-1.165,3.762-0.611,5.651 c0.554,1.89,1.836,3.483,3.565,4.427l78.205,42.748c1.131,0.619,2.352,0.912,3.557,0.912c2.627,0,5.174-1.398,6.523-3.866 c11.386-20.828,26.229-39.359,44.114-55.08C174.178,243.422,175.08,241.587,175.205,239.62z"/>
<path d="M201.462,214.829c1.334,2.515,3.907,3.948,6.568,3.948c1.174,0,2.365-0.279,3.473-0.867 c20.962-11.117,43.512-18.371,67.025-21.561c4.064-0.551,6.913-4.293,6.362-8.358l-11.979-88.316 c-0.551-4.064-4.304-6.909-8.358-6.362c-35.708,4.843-69.949,15.857-101.772,32.736c-3.623,1.922-5.002,6.416-3.082,10.041 L201.462,214.829z"/>
<path d="M105.785,334.345l-86.017-23.338c-1.901-0.514-3.929-0.255-5.638,0.725s-2.958,2.598-3.475,4.499 C3.586,342.295,0,369.309,0,396.523c0,4.657,0.111,9.329,0.342,14.284c0.185,3.981,3.468,7.083,7.414,7.083 c0.116,0,0.234-0.002,0.35-0.008l89.031-4.113c1.967-0.09,3.82-0.96,5.145-2.415c1.327-1.455,2.022-3.38,1.93-5.347 c-0.155-3.341-0.23-6.444-0.23-9.484c0-18.02,2.365-35.873,7.029-53.066C112.082,339.499,109.743,335.42,105.785,334.345z"/>
<path d="M438.731,120.745c-32.411-15.625-67.04-25.308-102.925-28.786c-1.972-0.198-3.918,0.408-5.439,1.659 c-1.521,1.252-2.481,3.056-2.671,5.018l-8.593,88.712c-0.396,4.082,2.594,7.713,6.677,8.108 c23.652,2.291,46.463,8.669,67.8,18.954c1.015,0.49,2.118,0.738,3.225,0.738c0.826,0,1.654-0.139,2.45-0.416 c1.859-0.649,3.385-2.012,4.24-3.786l38.7-80.287C443.978,126.965,442.427,122.525,438.731,120.745z"/>
<path d="M569.642,245.337c0.48-1.911,0.184-3.932-0.828-5.624c-18.432-30.835-41.933-57.983-69.848-80.686 c-1.529-1.242-3.48-1.824-5.447-1.627c-1.959,0.203-3.758,1.174-5,2.702l-56.237,69.144c-1.242,1.529-1.828,3.488-1.625,5.447 c0.201,1.959,1.173,3.758,2.702,5.002c18.47,15.019,34.015,32.975,46.205,53.369c1.392,2.326,3.855,3.618,6.383,3.618 c1.297,0,2.61-0.34,3.803-1.054l76.501-45.728C567.94,248.889,569.16,247.248,569.642,245.337z"/>
<path d="M598.044,304.939c-1.228-3.915-5.397-6.096-9.308-4.867l-85.048,26.648c-3.915,1.226-6.093,5.393-4.867,9.306 c6.104,19.486,9.199,39.839,9.199,60.494c0,3.041-0.076,6.144-0.23,9.484c-0.092,1.967,0.602,3.892,1.93,5.347 c1.327,1.456,3.178,2.325,5.145,2.415l89.031,4.113c0.118,0.005,0.234,0.008,0.35,0.008c3.944,0,7.228-3.103,7.414-7.083 c0.229-4.955,0.342-9.627,0.342-14.284C612,365.306,607.306,334.494,598.044,304.939z"/>
<path d="M305.737,380.755c-1.281,0-2.555,0.042-3.824,0.11l-120.65-71.185c-2.953-1.745-6.702-1.308-9.176,1.065 c-2.476,2.371-3.07,6.099-1.456,9.121l65.815,123.355c-0.242,2.376-0.371,4.775-0.371,7.195c0,18.608,7.246,36.101,20.403,49.258 c13.158,13.158,30.652,20.404,49.26,20.404c18.608,0,36.101-7.248,49.258-20.404c13.158-13.157,20.403-30.65,20.403-49.258 c0-18.608-7.246-36.101-20.403-49.258C341.839,388.001,324.344,380.755,305.737,380.755z"/>
</svg>

After

Width:  |  Height:  |  Size: 3 KiB

View file

@ -124,7 +124,7 @@ function SimplePagination({
}} }}
/> />
<p className={style.paginator_text}> <p className={style.paginator_text}>
строк. {t('uiKit.dataLoader.rows')}
</p> </p>
{canShowMore && ( {canShowMore && (
<UiKitButton <UiKitButton

View file

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next';
import IHashMap from 'ts/interfaces/HashMap'; import IHashMap from 'ts/interfaces/HashMap';
import ExternalLink from 'ts/components/ExternalLink'; import ExternalLink from 'ts/components/ExternalLink';
@ -69,6 +70,7 @@ interface IDayInfoProps {
} }
function DayInfo({ day, order, events, timestamp }: IDayInfoProps): React.ReactElement { function DayInfo({ day, order, events, timestamp }: IDayInfoProps): React.ReactElement {
const { t } = useTranslation();
const firstCommit = events?.firstCommit?.[timestamp || ''] || []; const firstCommit = events?.firstCommit?.[timestamp || ''] || [];
const lastCommit = events?.lastCommit?.[timestamp || ''] || []; const lastCommit = events?.lastCommit?.[timestamp || ''] || [];
let taskNumber = 0; let taskNumber = 0;
@ -79,8 +81,8 @@ function DayInfo({ day, order, events, timestamp }: IDayInfoProps): React.ReactE
taskNumber += Object.keys(tasks).length; taskNumber += Object.keys(tasks).length;
let suffix = ''; let suffix = '';
if (firstCommit.includes(author)) suffix = '(первый рабочий день)'; if (firstCommit.includes(author)) suffix = t('page.team.month.first');
if (lastCommit.includes(author)) suffix = '(последний рабочий день)'; if (lastCommit.includes(author)) suffix = t('page.team.month.last');
return ( return (
<div <div

View file

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { getDayPrefix } from 'ts/helpers/formatter'; import { getDayName } from 'ts/helpers/formatter';
import Header from './components/Header'; import Header from './components/Header';
import Columns from './components/Columns'; import Columns from './components/Columns';
@ -24,7 +24,7 @@ function HoursChart({
className={style.day} className={style.day}
> >
<div className={style.day_name}> <div className={style.day_name}>
{getDayPrefix(day)} {getDayName(day, 'short')}
</div> </div>
<Columns <Columns
week={week} week={week}

View file

@ -21,8 +21,8 @@ export default function getOptions({
return { return {
max: max instanceof Array ? Math.max(...max) : (max || 100), max: max instanceof Array ? Math.max(...max) : (max || 100),
order: order || [], order: order || [],
suffix: suffix ?? 'коммитов', suffix: suffix ?? 'commits',
otherTitle: other ?? 'Остальные', otherTitle: other ?? '...',
color: order?.length ? (new ColorGenerator(order)) : null, color: order?.length ? (new ColorGenerator(order)) : null,
limit: limit || 15, limit: limit || 15,
formatter: formatter || ((v: any) => v), formatter: formatter || ((v: any) => v),

View file

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next';
import Description from 'ts/components/Description'; import Description from 'ts/components/Description';
import UiKitButton from 'ts/components/UiKit/components/Button'; import UiKitButton from 'ts/components/UiKit/components/Button';
@ -28,6 +29,8 @@ function Card({
recommendation, recommendation,
onClick, onClick,
}: IRecommendationsProps) { }: IRecommendationsProps) {
const { t } = useTranslation();
if (!recommendation) return null; if (!recommendation) return null;
const className = getClassName(recommendation); const className = getClassName(recommendation);
@ -55,12 +58,11 @@ function Card({
className={style.recommendations_card_button} className={style.recommendations_card_button}
onClick={onClick} onClick={onClick}
> >
Подробнее {t('recommendations.modal.open')}
</UiKitButton> </UiKitButton>
)} )}
</div> </div>
); );
} }
export default Card; export default Card;

View file

@ -56,7 +56,7 @@ const RecommendationDescription = observer(() => {
</Body> </Body>
<Footer className={style.recommendations_modal_footer}> <Footer className={style.recommendations_modal_footer}>
<UiKitButton <UiKitButton
mode={[ isMobile ? 'primary' : 'slim', 'full_size']} mode={[ isMobile ? 'primary' : 'border', 'full_size']}
onClick={() => { onClick={() => {
recommendationStore.close(); recommendationStore.close();
}} }}

View file

@ -15,7 +15,7 @@ function Header({ dayInfo }: IHeaderProps) {
{getDate(dayInfo?.timestamp)} {getDate(dayInfo?.timestamp)}
</p> </p>
<p className={style.tempo_header_day}> <p className={style.tempo_header_day}>
{getDayName(dayInfo?.day)} {getDayName(dayInfo?.day, 'long')}
</p> </p>
</div> </div>
); );

View file

@ -3,7 +3,7 @@ import React from 'react';
import { IUiKitWrapperProps } from './Wrapper'; import { IUiKitWrapperProps } from './Wrapper';
import style from '../styles/button.module.scss'; import style from '../styles/button.module.scss';
export type Mode = 'primary' | 'second' | 'link' | 'slim' | 'full_size'; export type Mode = 'primary' | 'second' | 'border' | 'link' | 'slim' | 'full_size';
export function getClassNameForMode(mode?: string) { export function getClassNameForMode(mode?: string) {
return { return {
@ -11,6 +11,7 @@ export function getClassNameForMode(mode?: string) {
slim: style.ui_kit_button_slim, slim: style.ui_kit_button_slim,
second: style.ui_kit_button_second, second: style.ui_kit_button_second,
primary: style.ui_kit_button_primary, primary: style.ui_kit_button_primary,
border: style.ui_kit_button_border,
full_size: style.ui_kit_button_full_size, full_size: style.ui_kit_button_full_size,
}[mode || ''] || ''; }[mode || ''] || '';
} }

View file

@ -16,6 +16,13 @@
--button-color-active: var(--color-border); --button-color-active: var(--color-border);
} }
&_border {
--button-color-bg: transparent;
--button-color-text: var(--color-button);
--button-color-hover: var(--color-border);
--button-color-active: var(--color-border);
}
&_link { &_link {
--button-color-bg: transparent; --button-color-bg: transparent;
--button-color-text: var(--color-button); --button-color-text: var(--color-button);
@ -63,6 +70,11 @@
font-weight: 100; font-weight: 100;
} }
&_border {
line-height: 38px;
border-width: 3px
}
&_link { &_link {
font-weight: 100; font-weight: 100;
height: auto; height: auto;

View file

@ -42,7 +42,7 @@ function Day({
return ( // @ts-ignore return ( // @ts-ignore
<div <div
className={style.year_chart_month_body_day} className={style.year_chart_month_body_day}
title={`коммитов: ${dayInfo.commits}, задач: ${dayInfo.tasksInDay || 0}`} title={`commits: ${dayInfo.commits}, tasks: ${dayInfo.tasksInDay || 0}`}
style={{ style={{
backgroundColor, backgroundColor,
backgroundImage: iconUrl ? `url(${iconUrl})` : '', backgroundImage: iconUrl ? `url(${iconUrl})` : '',

View file

@ -1,5 +1,7 @@
import React from 'react'; import React from 'react';
import { getLangPrefix } from 'ts/helpers/formatter';
import IMonth from '../interfaces/Month'; import IMonth from '../interfaces/Month';
import style from '../styles/index.module.scss'; import style from '../styles/index.module.scss';
@ -10,7 +12,7 @@ interface IHeaderProps {
function Header({ function Header({
month, month,
}: IHeaderProps): React.ReactElement | null { }: IHeaderProps): React.ReactElement | null {
const name = month.date.toLocaleString('ru-RU', { month: 'long' }); const name = month.date.toLocaleString(getLangPrefix(), { month: 'long' });
const showYear = month.first || month.last || !month.month; const showYear = month.first || month.last || !month.month;
return ( return (

View file

@ -1,8 +1,6 @@
import React from 'react'; import React from 'react';
import IHashMap from 'ts/interfaces/HashMap'; import IHashMap from 'ts/interfaces/HashMap';
import LineChart from 'ts/components/LineChart';
import getOptions from 'ts/components/LineChart/helpers/getOptions';
import { getShortMoney } from 'ts/helpers/formatter'; import { getShortMoney } from 'ts/helpers/formatter';
import IMonth from '../interfaces/Month'; import IMonth from '../interfaces/Month';
@ -12,31 +10,6 @@ import Body from './Body';
import styleChart from '../styles/line.module.scss'; import styleChart from '../styles/line.module.scss';
import style from '../styles/index.module.scss'; import style from '../styles/index.module.scss';
interface IMonthTotalProps {
title: string;
options: any;
value: any;
}
function MonthTotal({
title,
options,
value,
}: IMonthTotalProps) {
return (
<div className={styleChart.year_chart_month_info}>
<span className={styleChart.year_chart_month_text}>
{title}
</span>
<LineChart
options={options}
value={value}
className={styleChart.year_chart_month_chart}
/>
</div>
);
}
interface IMonthProps { interface IMonthProps {
max: IHashMap<number>; max: IHashMap<number>;
month: IMonth; month: IMonth;
@ -50,12 +23,17 @@ function Month({
showEvents, showEvents,
hideMoney, hideMoney,
}: IMonthProps): React.ReactElement | null { }: IMonthProps): React.ReactElement | null {
const tasksChart = getOptions({ max: max.tasks, suffix: 'задач' }); let value = '';
const moneyChart = getOptions({ if (month.tasks) {
max: max.money, value = `${month.tasks || 0}`;
suffix: '', }
formatter: getShortMoney, if (!hideMoney && month.money) {
}); value = `${month.tasks || 0}${getShortMoney(month.money || 0, 0)}`;
}
const title = hideMoney
? 'tasks'
: 'tasks and money';
return ( return (
<div className={style.year_chart_month}> <div className={style.year_chart_month}>
@ -65,18 +43,12 @@ function Month({
maxCommits={max.commits} maxCommits={max.commits}
showEvents={showEvents} showEvents={showEvents}
/> />
{!hideMoney && ( <div
<MonthTotal title={title}
title="$" className={styleChart.year_chart_month_info}
options={moneyChart} >
value={month.money} {value}
/> </div>
)}
<MonthTotal
title="☑"
options={tasksChart}
value={month.tasks}
/>
</div> </div>
); );
} }

View file

@ -1,4 +1,4 @@
import React from 'react'; import React, { useEffect, useRef, useState } from 'react';
import MinMaxCounter from 'ts/helpers/DataGrip/components/counter'; import MinMaxCounter from 'ts/helpers/DataGrip/components/counter';
@ -7,6 +7,19 @@ import getAuthorByDate from './helpers/getAuthorByDate';
import Month from './components/Month'; import Month from './components/Month';
import IMonth from './interfaces/Month'; import IMonth from './interfaces/Month';
import style from './styles/index.module.scss';
function getDayWidth(wrapperWidth: number, monthNumber: number) {
const step = 0.3;
const borders = 7;
for (let px = 16; px <= 24; px += step) {
const monthWidth = borders + 8 * px;
const size = monthWidth * monthNumber;
if (size > wrapperWidth) return (px - step);
}
return 24;
}
interface IYearChartProps { interface IYearChartProps {
maxCommits: number; maxCommits: number;
showEvents?: boolean; showEvents?: boolean;
@ -20,6 +33,22 @@ function YearChart({
wordDays = [], wordDays = [],
authors = [], authors = [],
}: IYearChartProps): React.ReactElement | null { }: IYearChartProps): React.ReactElement | null {
const wrapper = useRef(null);
const [dayWidth, setDayWidth] = useState<number>(16);
const [monthNumber, setMonthNumber] = useState<number>(7);
console.log(monthNumber);
useEffect(() => {
if (!wrapper.current) return; // @ts-ignore
const size = wrapper.current?.getBoundingClientRect() || {};
const minMonthWidth = 7 + 8 * 16;
const newMonthNumber = Math.floor(size.width / minMonthWidth);
const width = getDayWidth(size.width, newMonthNumber);
setDayWidth(width);
setMonthNumber(newMonthNumber);
}, []);
if (!wordDays || !wordDays.length) return null; if (!wordDays || !wordDays.length) return null;
const authorsByDate = getAuthorByDate(authors); const authorsByDate = getAuthorByDate(authors);
@ -50,10 +79,17 @@ function YearChart({
/> />
)); ));
const customStyle = { '--day-size': `${dayWidth.toFixed(1)}px` } as React.CSSProperties;
return ( return (
<> <div
ref={wrapper}
style={customStyle}
className={style.year_chart}
>
{elements} {elements}
</> </div>
); );
} }

View file

@ -1,20 +1,24 @@
@import 'src/styles/variables'; @import 'src/styles/variables';
.year_chart_month { .year_chart {
--day-size: 16px; --day-size: 16px;
padding: var(--space-xs) 0;
margin: 0 calc(var(--day-size) / -2);
}
.year_chart_month {
--month-size: calc(var(--day-size) * 7 + 7px); --month-size: calc(var(--day-size) * 7 + 7px);
display: inline-block; display: inline-block;
width: var(--month-size); width: var(--month-size);
margin: var(--day-size) var(--day-size) 0 0; margin: var(--day-size) calc(var(--day-size) / 2) 0;
vertical-align: top; vertical-align: top;
&_header { &_header {
position: relative;
display: block; display: block;
height: 24px; height: 24px;
&_title, &_title {
&_money {
font-weight: 100; font-weight: 100;
font-size: var(--font-xs); font-size: var(--font-xs);
font-family: Arial, Verdana, sans-serif; font-family: Arial, Verdana, sans-serif;
@ -23,18 +27,12 @@
padding: 0; padding: 0;
margin: 0 auto; margin: 0 auto;
text-align: left; text-align: center;
line-height: var(--font-m); line-height: var(--font-m);
text-decoration: none; text-decoration: none;
vertical-align: bottom; vertical-align: bottom;
color: var(--color-black); color: var(--color-black);
} }
&_money {
position: absolute;
top: 0;
right: 0;
}
} }
&_body { &_body {

View file

@ -3,37 +3,22 @@
.year_chart_month { .year_chart_month {
&_info { &_info {
display: block; display: block;
white-space: nowrap;
}
&_text {
font-weight: 100; font-weight: 100;
font-size: var(--font-xs); font-size: var(--font-xs);
font-family: Arial, Verdana, sans-serif; font-family: Arial, Verdana, sans-serif;
display: inline-block;
width: 16px;
padding: 0; padding: 0;
margin: 0; margin: var(--space-s) 0 0;
text-align: left;
line-height: var(--font-xs); line-height: var(--font-xs);
white-space: nowrap;
text-decoration: none; text-decoration: none;
vertical-align: middle; vertical-align: middle;
overflow: hidden;
text-overflow: ellipsis;
text-align: center;
color: var(--color-11); color: var(--color-11);
} }
&_chart {
display: inline-block;
width: 94px;
height: var(--space-s);
margin: 0;
border-radius: 0;
vertical-align: middle;
> div:last-child {
border-radius: 0;
background-color: #C2CEE4;
}
}
} }

View file

@ -63,7 +63,6 @@ export default class DataGripByTasks {
if (commit.scope !== 'неопределенна') scope.add(commit.scope); if (commit.scope !== 'неопределенна') scope.add(commit.scope);
}); });
const authorsList = Array.from(authors).join(', ');
const comments = Array.from(messages).join(', '); const comments = Array.from(messages).join(', ');
const to = lastCommit.milliseconds; const to = lastCommit.milliseconds;
const daysInWork = Math.ceil((to - from) / settingsStore.ONE_DAY) + 1; const daysInWork = Math.ceil((to - from) / settingsStore.ONE_DAY) + 1;
@ -73,7 +72,7 @@ export default class DataGripByTasks {
to: to !== from ? to : undefined, to: to !== from ? to : undefined,
commits: commits.length, commits: commits.length,
daysInWork, daysInWork,
authors: authorsList, authors: Array.from(authors),
comments, comments,
types: Array.from(types), types: Array.from(types),
scope: Array.from(scope), scope: Array.from(scope),

View file

@ -46,6 +46,8 @@ class DataGrip {
initializationInfo: any = {}; initializationInfo: any = {};
hash: number = 0;
clear() { clear() {
this.firstLastCommit.clear(); this.firstLastCommit.clear();
this.author.clear(); this.author.clear();
@ -110,6 +112,7 @@ class DataGrip {
this.addCommit(commit); this.addCommit(commit);
}); });
this.#updateTotalInfo(); this.#updateTotalInfo();
this.hash = Math.random();
} }
updateByFiles(fileList: IDirtyFile[], removedFileList: IDirtyFile[]) { updateByFiles(fileList: IDirtyFile[], removedFileList: IDirtyFile[]) {

View file

@ -23,7 +23,8 @@ export default function Parser(report: string[]) {
const index = message.indexOf('\t'); const index = message.indexOf('\t');
if (index > 0 && index < 10) { if (index > 0 && index < 10) {
let [addedRaw, removedRaw, fileName] = message.split('\t'); let [addedRaw, removedRaw, fileName] = message.split('\t');
fileName = getNewFileName(fileName, allFiles); const formattedFileName = fileName?.replace(/"/gm, '');
fileName = getNewFileName(formattedFileName, allFiles);
let added = parseInt(addedRaw, 10) || 0; let added = parseInt(addedRaw, 10) || 0;
let removed = parseInt(removedRaw, 10) || 0; let removed = parseInt(removedRaw, 10) || 0;
const diff = added - removed; const diff = added - removed;

View file

@ -1,5 +1,6 @@
import IHashMap from 'ts/interfaces/HashMap'; import IHashMap from 'ts/interfaces/HashMap';
import localization from 'ts/helpers/Localization'; import localization from 'ts/helpers/Localization';
import notificationsStore from 'ts/components/Notifications/store';
function getParametersFromString(text: string): IHashMap<string> { function getParametersFromString(text: string): IHashMap<string> {
return Object.fromEntries((text || '') return Object.fromEntries((text || '')
@ -20,7 +21,9 @@ function loadJsDump(url: string, callback: Function) {
script.src = url; script.src = url;
script.async = true; // @ts-ignore script.async = true; // @ts-ignore
script.onload = callback; // @ts-ignore script.onload = callback; // @ts-ignore
script.onerror = callback; script.onerror = () => {
notificationsStore.show('common.fileLoader.notification');
};
document.body.appendChild(script); document.body.appendChild(script);
} }

View file

@ -1,36 +1,7 @@
import settingsStore from 'ts/store/Settings'; import settingsStore from 'ts/store/Settings';
export function getDayName(index: number, value?: string) {
const name = [
'понедельник',
'вторник',
'среда',
'четверг',
'пятница',
'суббота',
'воскресенье',
][index];
if (value) {
if (index == 2) return 'среду';
else if (index == 4) return 'пятницу';
else if (index == 5) return 'субботу';
}
return name;
}
export function getDayPrefix(index:number) { export function getLangPrefix() {
return [
'пн',
'вт',
'ср',
'чт',
'пт',
'сб',
'вс',
][index];
}
function getLangPrefix() {
// @ts-ignore // @ts-ignore
const code = window?.localization?.language || 'ru'; const code = window?.localization?.language || 'ru';
return { return {
@ -45,12 +16,28 @@ function getLangPrefix() {
}[code] || 'ru-RU'; }[code] || 'ru-RU';
} }
const ONE_DAY = 24 * 60 * 60 * 1000;
const TIMESTAMP = [
ONE_DAY * 4,
ONE_DAY * 5,
ONE_DAY * 6,
0,
ONE_DAY,
ONE_DAY * 2,
ONE_DAY * 3,
];
export function getDayName(index:number, weekday: 'long' | 'short') {
const date = new Date(TIMESTAMP[index]);
return date.toLocaleString(getLangPrefix(), { weekday: weekday || 'long' });
}
export function getDateByTimestamp(timestamp: string) { export function getDateByTimestamp(timestamp: string) {
const date = new Date(timestamp); const date = new Date(timestamp);
const day = date.getDay() - 1; const day = date.getDay() - 1;
return [ return [
date.toLocaleString(getLangPrefix(), { day: 'numeric', month: 'long', year: 'numeric' }), date.toLocaleString(getLangPrefix(), { day: 'numeric', month: 'long', year: 'numeric' }),
getDayName(day < 0 ? 6 : day), getDayName(day < 0 ? 6 : day, 'long'),
]; ];
} }
@ -83,7 +70,7 @@ export function getShortDate(timestamp: string) {
export function getShortTime(timestamp: string) { export function getShortTime(timestamp: string) {
if (!timestamp) return ''; if (!timestamp) return '';
const date = new Date(timestamp); const date = new Date(timestamp);
return date.toLocaleString('ru-RU', { hour: 'numeric', minute: 'numeric' }); return date.toLocaleString(getLangPrefix(), { hour: 'numeric', minute: 'numeric' });
} }
export function getMoney(value: number, options?: any) { export function getMoney(value: number, options?: any) {

View file

@ -164,6 +164,13 @@ export const PERSON = [
icon: './assets/menu/team_date_2.svg', icon: './assets/menu/team_date_2.svg',
}, },
{}, {},
{
id: 'tasks',
link: '/person/tasks/',
title: 'sidebar.person.tasks',
icon: './assets/menu/team_date_1.svg',
},
{},
{ {
id: 'commits', id: 'commits',
link: '/person/commits/', link: '/person/commits/',

View file

@ -0,0 +1,48 @@
import React from 'react';
import { observer } from 'mobx-react-lite';
import ISort from 'ts/interfaces/Sort';
import { IPaginationRequest } from 'ts/interfaces/Pagination';
import dataGripStore from 'ts/store/DataGrip';
import DataLoader from 'ts/components/DataLoader';
import Pagination from 'ts/components/DataLoader/components/Pagination';
import getFakeLoader from 'ts/components/DataLoader/helpers/formatter';
import NothingFound from 'ts/components/NothingFound';
import { TasksView } from 'ts/pages/Team/components/Tasks';
import IPersonCommonProps from '../interfaces/CommonProps';
const Tasks = observer(({
user,
mode,
}: IPersonCommonProps): React.ReactElement | null => {
const allRows = dataGripStore.dataGrip.tasks.statistic;
const rows = allRows.filter((row: any) => (
row.author === user.author
|| (row.authors || []).includes(user.author)
));
if (!rows?.length) return mode !== 'print' ? (<NothingFound />) : null;
return (
<DataLoader
to="response"
loader={(pagination?: IPaginationRequest, sort?: ISort[]) => getFakeLoader({
content: rows, pagination, sort, mode,
})}
watch={`${mode}${dataGripStore.dataGrip.hash}${user.author}`}
>
<br/>
<br/>
<br/>
<TasksView
mode={mode}
rowsForExcel={rows}
/>
<Pagination />
</DataLoader>
);
});
export default Tasks;

View file

@ -39,7 +39,7 @@ const Total = observer(({ user }: IPersonCommonProps): React.ReactElement => {
const commitsWithGet = dataGripStore.dataGrip.get.getsByAuthor[user.author]; const commitsWithGet = dataGripStore.dataGrip.get.getsByAuthor[user.author];
const taskNumber = statistic.tasks.length; const taskNumber = statistic.tasks.length;
const achievements = getAchievementByAuthor(statistic.author); const achievements = getAchievementByAuthor(statistic.author);
console.dir(achievements);
return ( return (
<PageWrapper> <PageWrapper>
<PageColumn> <PageColumn>
@ -77,15 +77,15 @@ const Total = observer(({ user }: IPersonCommonProps): React.ReactElement => {
<Title title="page.person.achievement.title"/> <Title title="page.person.achievement.title"/>
<AchievementBlock <AchievementBlock
title="page.person.achievement.positive" title="page.person.achievement.positive"
achievements={achievements[ACHIEVEMENT_TYPE.GOOD]} achievements={achievements[ACHIEVEMENT_TYPE.GOOD - 1]}
/> />
<AchievementBlock <AchievementBlock
title="page.person.achievement.normal" title="page.person.achievement.normal"
achievements={achievements[ACHIEVEMENT_TYPE.NORMAL]} achievements={achievements[ACHIEVEMENT_TYPE.NORMAL - 1]}
/> />
<AchievementBlock <AchievementBlock
title="page.person.achievement.negative" title="page.person.achievement.negative"
achievements={achievements[ACHIEVEMENT_TYPE.BAD]} achievements={achievements[ACHIEVEMENT_TYPE.BAD - 1]}
/> />
<Description <Description
text={t('page.person.achievement.description')} text={t('page.person.achievement.description')}

View file

@ -44,18 +44,18 @@ const Total = observer(({
<Title title="page.person.achievement.title"/> <Title title="page.person.achievement.title"/>
<AchievementBlock <AchievementBlock
title="page.person.achievement.positive" title="page.person.achievement.positive"
achievements={achievements[ACHIEVEMENT_TYPE.GOOD]} achievements={achievements[ACHIEVEMENT_TYPE.GOOD - 1]}
/> />
</PageColumn> </PageColumn>
<PageColumn> <PageColumn>
<Title title={t('_')}/> <Title title={t('_')}/>
<AchievementBlock <AchievementBlock
title="page.person.achievement.normal" title="page.person.achievement.normal"
achievements={achievements[ACHIEVEMENT_TYPE.NORMAL]} achievements={achievements[ACHIEVEMENT_TYPE.NORMAL - 1]}
/> />
<AchievementBlock <AchievementBlock
title="page.person.achievement.negative" title="page.person.achievement.negative"
achievements={achievements[ACHIEVEMENT_TYPE.BAD]} achievements={achievements[ACHIEVEMENT_TYPE.BAD - 1]}
/> />
<br /> <br />
<br /> <br />

View file

@ -19,6 +19,7 @@ import Speed from './components/Speed';
import Total from './components/Total'; import Total from './components/Total';
import Week from './components/Week'; import Week from './components/Week';
import Month from './components/Month'; import Month from './components/Month';
import Tasks from './components/Tasks';
import Tempo from './components/Tempo'; import Tempo from './components/Tempo';
import Print from './components/Print'; import Print from './components/Print';
@ -55,6 +56,7 @@ function getViewByIdByUser(user: any, filters: any) {
/> />
); );
if (page === 'print') return <Print user={user}/>; if (page === 'print') return <Print user={user}/>;
if (page === 'tasks') return <Tasks user={user}/>;
return <Total user={user}/>; return <Total user={user}/>;
}; };
} }

View file

@ -1,4 +1,5 @@
export default interface IPersonCommonProps { export default interface IPersonCommonProps {
user: any; user: any;
mode?: string;
filters?: any; filters?: any;
} }

View file

@ -38,6 +38,12 @@ function AuthorView({ response, updateSort, rowsForExcel, mode }: IAuthorViewPro
const { t } = useTranslation(); const { t } = useTranslation();
if (!response) return null; if (!response) return null;
const [works, dismissed, staff] = [
t('page.team.author.type.work'),
t('page.team.author.type.dismissed'),
t('page.team.author.type.staff'),
];
const textWork = t('page.team.author.worked'); const textWork = t('page.team.author.worked');
const textLosses = t('page.team.author.losses'); const textLosses = t('page.team.author.losses');
const daysWorked = getOptions({ order: [textWork, textLosses], suffix: 'page.team.author.days' }); const daysWorked = getOptions({ order: [textWork, textLosses], suffix: 'page.team.author.days' });
@ -62,9 +68,9 @@ function AuthorView({ response, updateSort, rowsForExcel, mode }: IAuthorViewPro
/> />
<Column <Column
template={(row: any) => { template={(row: any) => {
let value = 'работает'; let value = works;
if (row.isDismissed) value = 'уволен'; if (row.isDismissed) value = dismissed;
if (row.isStaff) value = 'помощник'; if (row.isStaff) value = staff;
return <UiKitTags value={value} />; return <UiKitTags value={value} />;
}} }}
width={100} width={100}
@ -189,7 +195,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} watch={`${mode}${dataGripStore.dataGrip.hash}`}
> >
<AuthorView <AuthorView
mode={mode} mode={mode}

View file

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

View file

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

View file

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

View file

@ -30,7 +30,7 @@ interface ITasksViewProps {
mode?: string; mode?: string;
} }
function TasksView({ response, updateSort, rowsForExcel, mode }: ITasksViewProps) { export function TasksView({ response, updateSort, rowsForExcel, mode }: ITasksViewProps) {
if (!response) return null; if (!response) return null;
const commitsChart = getOptions({ max: getMax(response, 'commits'), suffix: 'page.team.type.tasksSmall' }); const commitsChart = getOptions({ max: getMax(response, 'commits'), suffix: 'page.team.type.tasksSmall' });
@ -155,7 +155,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} watch={`${mode}${dataGripStore.dataGrip.hash}`}
> >
<br/> <br/>
<br/> <br/>

View file

@ -133,6 +133,8 @@ const Tree = observer(({ type }: ITreeProps): React.ReactElement => {
: dataGripStore.fileTree; : dataGripStore.fileTree;
const subTree = getSubTreeByPath(fileTree, treeStore.selectedPath); const subTree = getSubTreeByPath(fileTree, treeStore.selectedPath);
const fileList = getArrayFromTree(subTree); const fileList = getArrayFromTree(subTree);
console.dir(dataGripStore.removedFileTree);
console.dir(fileList);
// @ts-ignore // @ts-ignore
if (!fileTree?.lines) return <NothingFound />; if (!fileTree?.lines) return <NothingFound />;
@ -145,6 +147,7 @@ const Tree = observer(({ type }: ITreeProps): React.ReactElement => {
<> <>
<Title title={t('common.filters')} /> <Title title={t('common.filters')} />
<TreeFilters/> <TreeFilters/>
{false && treeStore.selectedPath?.join('/')}
<Title title="page.team.tree.title"/> <Title title="page.team.tree.title"/>
<PageWrapper template="table"> <PageWrapper template="table">
<DataLoader <DataLoader

View file

@ -137,7 +137,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} watch={`${mode}${dataGripStore.dataGrip.hash}`}
> >
<TypeView <TypeView
mode={mode} mode={mode}

View file

@ -181,7 +181,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} watch={`${mode}${dataGripStore.dataGrip.hash}`}
> >
<WeekView <WeekView
mode={mode} mode={mode}

View file

@ -51,13 +51,13 @@ export default `
§ achievements.lessDaysInProject.description: least days in the project § achievements.lessDaysInProject.description: least days in the project
§ achievements.more90DaysInProject.title: Welcome aboard § achievements.more90DaysInProject.title: Welcome aboard
§ achievements.more90DaysInProject.description: not fired during the probation period § achievements.more90DaysInProject.description: not fired during the probation period
§ achievements.lessDaysForTask.title: Quick draw § achievements.lessDaysForTask.title: Fast shooting
§ achievements.lessDaysForTask.description: a task takes less than a day § achievements.lessDaysForTask.description: a task takes less than a day
§ achievements.adam.title: Adam § achievements.adam.title: Adam
§ achievements.adam.description: the first stable employee on the project § achievements.adam.description: the first stable employee on the project
§ achievements.more666DaysInProject.title: Devil § achievements.more666DaysInProject.title: Devil
§ achievements.more666DaysInProject.description: worked 666 days on the project § achievements.more666DaysInProject.description: worked 666 days on the project
§ achievements.more777DaysInProject.title: Azino three axes § achievements.more777DaysInProject.title: Las Vegas
§ achievements.more777DaysInProject.description: worked 777 days on the project § achievements.more777DaysInProject.description: worked 777 days on the project
§ achievements.moreRefactoring.title: Executive editor § achievements.moreRefactoring.title: Executive editor
§ achievements.moreRefactoring.description: made the most 'refactoring' tags § achievements.moreRefactoring.description: made the most 'refactoring' tags

View file

@ -3,6 +3,7 @@ export default `
§ uiKit.console.notification: Der Text wurde kopiert § uiKit.console.notification: Der Text wurde kopiert
§ uiKit.dataLoader.page: Seite § uiKit.dataLoader.page: Seite
§ uiKit.dataLoader.size: Wird nach angezeigt § uiKit.dataLoader.size: Wird nach angezeigt
§ uiKit.dataLoader.rows: lines.
§ uiKit.dataLoader.from: aus § uiKit.dataLoader.from: aus
§ uiKit.dataLoader.all: Alles anzeigen § uiKit.dataLoader.all: Alles anzeigen
§ uiKit.hoursChart.work: normale Arbeitszeit (wochentags von 07:00 bis 20:00 Uhr) § uiKit.hoursChart.work: normale Arbeitszeit (wochentags von 07:00 bis 20:00 Uhr)
@ -24,4 +25,5 @@ Wenn dies ein Fehler ist und die Statistiken für diesen Mitarbeiter berücksich
§ common.filters: Filter § common.filters: Filter
§ common.notifications.save: Änderungen gespeichert § common.notifications.save: Änderungen gespeichert
§ common.notifications.setting: Einstellungen gespeichert § common.notifications.setting: Einstellungen gespeichert
§ common.fileLoader.notification: Cant open file $1
`; `;

View file

@ -35,6 +35,7 @@ export default `
§ sidebar.person.day: Tageweise § sidebar.person.day: Tageweise
§ sidebar.person.week: Nach Wochen § sidebar.person.week: Nach Wochen
§ sidebar.person.month: Nach Monaten § sidebar.person.month: Nach Monaten
§ sidebar.person.tasks: Tasks
§ sidebar.person.hours: Zeitplan § sidebar.person.hours: Zeitplan
§ sidebar.person.commits: All commits § sidebar.person.commits: All commits
§ sidebar.person.changes: Alle Änderungen § sidebar.person.changes: Alle Änderungen

View file

@ -37,8 +37,13 @@ export default `
§ page.team.author.moneyAll: Received § page.team.author.moneyAll: Received
§ page.team.author.moneyWorked: Worked for § page.team.author.moneyWorked: Worked for
§ page.team.author.moneyLosses: Overpayment § page.team.author.moneyLosses: Overpayment
§ page.team.author.type.work: works
§ page.team.author.type.dismissed: dismissed
§ page.team.author.type.staff: staff
§ page.team.hours.title: Distribution of commits during each day of the week § page.team.hours.title: Distribution of commits during each day of the week
§ page.team.month.title: Project work calendar § page.team.month.title: Project work calendar
§ page.team.month.first: (first work day)
§ page.team.month.last: (last work day)
§ page.team.scope.title: Feature statistics § page.team.scope.title: Feature statistics
§ page.team.scope.scope: Feature § page.team.scope.scope: Feature
§ page.team.scope.days: Working Days § page.team.scope.days: Working Days
@ -86,7 +91,7 @@ export default `
§ page.team.total.description3: The *working and dismissed* card shows the actual composition of employees who are continuously involved in work. Additionally, there are "assistants" typically employees of a different specialization who may occasionally make commits to the project. § page.team.total.description3: The *working and dismissed* card shows the actual composition of employees who are continuously involved in work. Additionally, there are "assistants" typically employees of a different specialization who may occasionally make commits to the project.
§ page.team.total.description4: *Overpayment* includes only working days when commits could have been made. Weekends, public holidays, and vacations are not included in the calculation. This is why overpayment + actual cost != total. The total cost includes payment for weekends, public holidays, and vacations. § page.team.total.description4: *Overpayment* includes only working days when commits could have been made. Weekends, public holidays, and vacations are not included in the calculation. This is why overpayment + actual cost != total. The total cost includes payment for weekends, public holidays, and vacations.
§ page.team.total.description5: *Weekend work* is calculated at a rate of x2 the payment of a regular day. The displayed amount is specifically the overpayment (x1), as the fact of overtime in this context is not of interest. We focus on overpayment when increasing work speed. § page.team.total.description5: *Weekend work* is calculated at a rate of x2 the payment of a regular day. The displayed amount is specifically the overpayment (x1), as the fact of overtime in this context is not of interest. We focus on overpayment when increasing work speed.
§ page.team.tree.title: Project Tree Considering Selected Filters § page.team.tree.title: Project tree considering selected filters
§ page.team.tree.filters.author: Employee § page.team.tree.filters.author: Employee
§ page.team.tree.filters.commits: Number of commits § page.team.tree.filters.commits: Number of commits
§ page.team.tree.filters.help: The minimum number of commits an employee has made in a file § page.team.tree.filters.help: The minimum number of commits an employee has made in a file
@ -101,7 +106,7 @@ export default `
§ page.team.week.date: Date § page.team.week.date: Date
§ page.team.week.numberTasks: Number of tasks § page.team.week.numberTasks: Number of tasks
§ page.team.week.people: Number of people § page.team.week.people: Number of people
§ page.team.week.line: Line Changes § page.team.week.line: Line changes
§ page.team.week.days: Days with and without commits § page.team.week.days: Days with and without commits
§ page.team.week.lossesDetails: Who did not commit § page.team.week.lossesDetails: Who did not commit
§ page.team.week.add: added § page.team.week.add: added

View file

@ -1,7 +1,8 @@
export default ` export default `
§ recommendations.modal.cancel: Ok § recommendations.modal.cancel: Ok
§ recommendations.modal.open: More
§ recommendations.title § recommendations.title
Recommendations and Facts Recommendations and facts
§ recommendations.timestamp.firstCommit.description § recommendations.timestamp.firstCommit.description
made the first commit made the first commit

View file

@ -51,13 +51,13 @@ export default `
§ achievements.lessDaysInProject.description: least days in the project § achievements.lessDaysInProject.description: least days in the project
§ achievements.more90DaysInProject.title: Welcome aboard § achievements.more90DaysInProject.title: Welcome aboard
§ achievements.more90DaysInProject.description: not fired during the probation period § achievements.more90DaysInProject.description: not fired during the probation period
§ achievements.lessDaysForTask.title: Quick draw § achievements.lessDaysForTask.title: Fast shooting
§ achievements.lessDaysForTask.description: a task takes less than a day § achievements.lessDaysForTask.description: a task takes less than a day
§ achievements.adam.title: Adam § achievements.adam.title: Adam
§ achievements.adam.description: the first stable employee on the project § achievements.adam.description: the first stable employee on the project
§ achievements.more666DaysInProject.title: Devil § achievements.more666DaysInProject.title: Devil
§ achievements.more666DaysInProject.description: worked 666 days on the project § achievements.more666DaysInProject.description: worked 666 days on the project
§ achievements.more777DaysInProject.title: Azino three axes § achievements.more777DaysInProject.title: Las Vegas
§ achievements.more777DaysInProject.description: worked 777 days on the project § achievements.more777DaysInProject.description: worked 777 days on the project
§ achievements.moreRefactoring.title: Executive editor § achievements.moreRefactoring.title: Executive editor
§ achievements.moreRefactoring.description: made the most 'refactoring' tags § achievements.moreRefactoring.description: made the most 'refactoring' tags

View file

@ -3,6 +3,7 @@ export default `
§ uiKit.console.notification: Text was copied § uiKit.console.notification: Text was copied
§ uiKit.dataLoader.page: Page § uiKit.dataLoader.page: Page
§ uiKit.dataLoader.size: Displayed § uiKit.dataLoader.size: Displayed
§ uiKit.dataLoader.rows: lines.
§ uiKit.dataLoader.from: out of § uiKit.dataLoader.from: out of
§ uiKit.dataLoader.all: Show all § uiKit.dataLoader.all: Show all
§ uiKit.hoursChart.work: standard working hours (weekdays, 07:00 to 20:00) § uiKit.hoursChart.work: standard working hours (weekdays, 07:00 to 20:00)
@ -27,4 +28,5 @@ If this is an error and this employee needs to be calculated as usual, go to the
§ 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
`; § common.fileLoader.notification: Cant open file $1
`;

View file

@ -35,6 +35,7 @@ export default `
§ sidebar.person.day: By day § sidebar.person.day: By day
§ sidebar.person.week: By week § sidebar.person.week: By week
§ sidebar.person.month: By month § sidebar.person.month: By month
§ sidebar.person.tasks: Tasks
§ sidebar.person.hours: Work schedule § sidebar.person.hours: Work schedule
§ sidebar.person.commits: All commits § sidebar.person.commits: All commits
§ sidebar.person.changes: All changes § sidebar.person.changes: All changes

View file

@ -37,8 +37,13 @@ export default `
§ page.team.author.moneyAll: Received § page.team.author.moneyAll: Received
§ page.team.author.moneyWorked: Worked for § page.team.author.moneyWorked: Worked for
§ page.team.author.moneyLosses: Overpayment § page.team.author.moneyLosses: Overpayment
§ page.team.author.type.work: works
§ page.team.author.type.dismissed: dismissed
§ page.team.author.type.staff: staff
§ page.team.hours.title: Distribution of commits during each day of the week § page.team.hours.title: Distribution of commits during each day of the week
§ page.team.month.title: Project work calendar § page.team.month.title: Project work calendar
§ page.team.month.first: (first work day)
§ page.team.month.last: (last work day)
§ page.team.scope.title: Feature statistics § page.team.scope.title: Feature statistics
§ page.team.scope.scope: Feature § page.team.scope.scope: Feature
§ page.team.scope.days: Working Days § page.team.scope.days: Working Days
@ -86,7 +91,7 @@ export default `
§ page.team.total.description3: The *working and dismissed* card shows the actual composition of employees who are continuously involved in work. Additionally, there are "assistants" typically employees of a different specialization who may occasionally make commits to the project. § page.team.total.description3: The *working and dismissed* card shows the actual composition of employees who are continuously involved in work. Additionally, there are "assistants" typically employees of a different specialization who may occasionally make commits to the project.
§ page.team.total.description4: *Overpayment* includes only working days when commits could have been made. Weekends, public holidays, and vacations are not included in the calculation. This is why overpayment + actual cost != total. The total cost includes payment for weekends, public holidays, and vacations. § page.team.total.description4: *Overpayment* includes only working days when commits could have been made. Weekends, public holidays, and vacations are not included in the calculation. This is why overpayment + actual cost != total. The total cost includes payment for weekends, public holidays, and vacations.
§ page.team.total.description5: *Weekend work* is calculated at a rate of x2 the payment of a regular day. The displayed amount is specifically the overpayment (x1), as the fact of overtime in this context is not of interest. We focus on overpayment when increasing work speed. § page.team.total.description5: *Weekend work* is calculated at a rate of x2 the payment of a regular day. The displayed amount is specifically the overpayment (x1), as the fact of overtime in this context is not of interest. We focus on overpayment when increasing work speed.
§ page.team.tree.title: Project Tree Considering Selected Filters § page.team.tree.title: Project tree considering selected filters
§ page.team.tree.filters.author: Employee § page.team.tree.filters.author: Employee
§ page.team.tree.filters.commits: Number of commits § page.team.tree.filters.commits: Number of commits
§ page.team.tree.filters.help: The minimum number of commits an employee has made in a file § page.team.tree.filters.help: The minimum number of commits an employee has made in a file
@ -101,7 +106,7 @@ export default `
§ page.team.week.date: Date § page.team.week.date: Date
§ page.team.week.numberTasks: Number of tasks § page.team.week.numberTasks: Number of tasks
§ page.team.week.people: Number of people § page.team.week.people: Number of people
§ page.team.week.line: Line Changes § page.team.week.line: Line changes
§ page.team.week.days: Days with and without commits § page.team.week.days: Days with and without commits
§ page.team.week.lossesDetails: Who did not commit § page.team.week.lossesDetails: Who did not commit
§ page.team.week.add: added § page.team.week.add: added

View file

@ -1,7 +1,8 @@
export default ` export default `
§ recommendations.modal.cancel: Ok § recommendations.modal.cancel: Ok
§ recommendations.modal.open: More
§ recommendations.title § recommendations.title
Recommendations and Facts Recommendations and facts
§ recommendations.timestamp.firstCommit.description § recommendations.timestamp.firstCommit.description
made the first commit made the first commit

View file

@ -3,6 +3,7 @@ export default `
§ uiKit.console.notification: Texto copiado § uiKit.console.notification: Texto copiado
§ uiKit.dataLoader.page: Página § uiKit.dataLoader.page: Página
§ uiKit.dataLoader.size: Se muestra por § uiKit.dataLoader.size: Se muestra por
§ uiKit.dataLoader.rows: lines.
§ uiKit.dataLoader.from: de § uiKit.dataLoader.from: de
§ uiKit.dataLoader.all: Mostrar todo § uiKit.dataLoader.all: Mostrar todo
§ uiKit.hoursChart.work: tiempo de trabajo estándar (lunes a viernes, de 07:00 a 20:00) § uiKit.hoursChart.work: tiempo de trabajo estándar (lunes a viernes, de 07:00 a 20:00)

View file

@ -3,6 +3,7 @@ export default `
§ uiKit.console.notification: El texto ha sido copiado § uiKit.console.notification: El texto ha sido copiado
§ uiKit.dataLoader.page: Página § uiKit.dataLoader.page: Página
§ uiKit.dataLoader.size: Mostrando hasta § uiKit.dataLoader.size: Mostrando hasta
§ uiKit.dataLoader.rows: lines.
§ uiKit.dataLoader.from: de § uiKit.dataLoader.from: de
§ uiKit.dataLoader.all: Mostrar todo § uiKit.dataLoader.all: Mostrar todo
§ uiKit.hoursChart.work: horario laboral normal (lunes a viernes, de 07:00 a 20:00) § uiKit.hoursChart.work: horario laboral normal (lunes a viernes, de 07:00 a 20:00)
@ -26,4 +27,5 @@ El trabajo de los colaboradores con este estatus en este proyecto puede desestim
§ common.filters: Filtros § common.filters: Filtros
§ common.notifications.save: Cambios guardados § common.notifications.save: Cambios guardados
§ common.notifications.setting: Ajustes guardados § common.notifications.setting: Ajustes guardados
`; § common.fileLoader.notification: Cant open file $1
`;

View file

@ -35,6 +35,7 @@ export default `
§ sidebar.person.day: Por días § sidebar.person.day: Por días
§ sidebar.person.week: Por semana § sidebar.person.week: Por semana
§ sidebar.person.month: Por mes § sidebar.person.month: Por mes
§ sidebar.person.tasks: Tasks
§ sidebar.person.hours: Horario § sidebar.person.hours: Horario
§ sidebar.person.commits: All commits § sidebar.person.commits: All commits
§ sidebar.person.changes: Todos los cambios § sidebar.person.changes: Todos los cambios

View file

@ -37,8 +37,13 @@ export default `
§ page.team.author.moneyAll: Dinero recibido § page.team.author.moneyAll: Dinero recibido
§ page.team.author.moneyWorked: Trabajo § page.team.author.moneyWorked: Trabajo
§ page.team.author.moneyLosses: Sobrepago § page.team.author.moneyLosses: Sobrepago
§ page.team.author.type.work: works
§ page.team.author.type.dismissed: dismissed
§ page.team.author.type.staff: staff
§ page.team.hours.title: Distribución del trabajo cada día de la semana § page.team.hours.title: Distribución del trabajo cada día de la semana
§ page.team.month.title: Calendario del proyecto § page.team.month.title: Calendario del proyecto
§ page.team.month.first: (first work day)
§ page.team.month.last: (last work day)
§ page.team.scope.title: Estadísticas de módulos § page.team.scope.title: Estadísticas de módulos
§ page.team.scope.scope: Elaboración definitiva § page.team.scope.scope: Elaboración definitiva
§ page.team.scope.days: Siervo. día § page.team.scope.days: Siervo. día

View file

@ -51,13 +51,13 @@ export default `
§ achievements.lessDaysInProject.description: least days in the project § achievements.lessDaysInProject.description: least days in the project
§ achievements.more90DaysInProject.title: Welcome aboard § achievements.more90DaysInProject.title: Welcome aboard
§ achievements.more90DaysInProject.description: not fired during the probation period § achievements.more90DaysInProject.description: not fired during the probation period
§ achievements.lessDaysForTask.title: Quick draw § achievements.lessDaysForTask.title: Fast shooting
§ achievements.lessDaysForTask.description: a task takes less than a day § achievements.lessDaysForTask.description: a task takes less than a day
§ achievements.adam.title: Adam § achievements.adam.title: Adam
§ achievements.adam.description: the first stable employee on the project § achievements.adam.description: the first stable employee on the project
§ achievements.more666DaysInProject.title: Devil § achievements.more666DaysInProject.title: Devil
§ achievements.more666DaysInProject.description: worked 666 days on the project § achievements.more666DaysInProject.description: worked 666 days on the project
§ achievements.more777DaysInProject.title: Azino three axes § achievements.more777DaysInProject.title: Las Vegas
§ achievements.more777DaysInProject.description: worked 777 days on the project § achievements.more777DaysInProject.description: worked 777 days on the project
§ achievements.moreRefactoring.title: Executive editor § achievements.moreRefactoring.title: Executive editor
§ achievements.moreRefactoring.description: made the most 'refactoring' tags § achievements.moreRefactoring.description: made the most 'refactoring' tags

View file

@ -3,6 +3,7 @@ export default `
§ uiKit.console.notification: Texte copié § uiKit.console.notification: Texte copié
§ uiKit.dataLoader.page: Page § uiKit.dataLoader.page: Page
§ uiKit.dataLoader.size: Affiché par § uiKit.dataLoader.size: Affiché par
§ uiKit.dataLoader.rows: lines.
§ uiKit.dataLoader.from: de § uiKit.dataLoader.from: de
§ uiKit.dataLoader.all: Afficher tout § uiKit.dataLoader.all: Afficher tout
§ uiKit.hoursChart.work: temps de travail standard (Les jours ouvrables de 07h00 à 20h00) § uiKit.hoursChart.work: temps de travail standard (Les jours ouvrables de 07h00 à 20h00)
@ -24,4 +25,5 @@ Si cest une erreur et que la statistique pour ce collaborateur doit être pri
§ common.filters: Filtres § common.filters: Filtres
§ common.notifications.save: Modifications enregistrées § common.notifications.save: Modifications enregistrées
§ common.notifications.setting: Paramètres enregistrés § common.notifications.setting: Paramètres enregistrés
§ common.fileLoader.notification: Cant open file $1
`; `;

View file

@ -33,6 +33,7 @@ export default `
§ sidebar.person.day: Au jour le jour § sidebar.person.day: Au jour le jour
§ sidebar.person.week: Une semaine § sidebar.person.week: Une semaine
§ sidebar.person.month: Par mois § sidebar.person.month: Par mois
§ sidebar.person.tasks: Tasks
§ sidebar.person.hours: Horaire § sidebar.person.hours: Horaire
§ sidebar.person.commits: all commits § sidebar.person.commits: all commits
§ sidebar.person.changes: Tous les changements § sidebar.person.changes: Tous les changements

View file

@ -37,8 +37,13 @@ export default `
§ page.team.author.moneyAll: L'argent reçu § page.team.author.moneyAll: L'argent reçu
§ page.team.author.moneyWorked: Travaillas § page.team.author.moneyWorked: Travaillas
§ page.team.author.moneyLosses: Trop-perçu § page.team.author.moneyLosses: Trop-perçu
§ page.team.author.type.work: works
§ page.team.author.type.dismissed: dismissed
§ page.team.author.type.staff: staff
§ page.team.hours.title: Répartition du travail pour chaque jour de la semaine § page.team.hours.title: Répartition du travail pour chaque jour de la semaine
§ page.team.month.title: Calendrier du projet § page.team.month.title: Calendrier du projet
§ page.team.month.first: (first work day)
§ page.team.month.last: (last work day)
§ page.team.scope.title: Statistiques par module § page.team.scope.title: Statistiques par module
§ page.team.scope.scope: Mise au point § page.team.scope.scope: Mise au point
§ page.team.scope.days: Esclave. jours § page.team.scope.days: Esclave. jours

View file

@ -1,7 +1,8 @@
export default ` export default `
§ recommendations.modal.cancel: Ok § recommendations.modal.cancel: Ok
§ recommendations.modal.open: More
§ recommendations.title § recommendations.title
Recommendations and Facts Recommendations and facts
§ recommendations.timestamp.firstCommit.description § recommendations.timestamp.firstCommit.description
made the first commit made the first commit

View file

@ -51,13 +51,13 @@ export default `
§ achievements.lessDaysInProject.description: least days in the project § achievements.lessDaysInProject.description: least days in the project
§ achievements.more90DaysInProject.title: Welcome aboard § achievements.more90DaysInProject.title: Welcome aboard
§ achievements.more90DaysInProject.description: not fired during the probation period § achievements.more90DaysInProject.description: not fired during the probation period
§ achievements.lessDaysForTask.title: Quick draw § achievements.lessDaysForTask.title: Fast shooting
§ achievements.lessDaysForTask.description: a task takes less than a day § achievements.lessDaysForTask.description: a task takes less than a day
§ achievements.adam.title: Adam § achievements.adam.title: Adam
§ achievements.adam.description: the first stable employee on the project § achievements.adam.description: the first stable employee on the project
§ achievements.more666DaysInProject.title: Devil § achievements.more666DaysInProject.title: Devil
§ achievements.more666DaysInProject.description: worked 666 days on the project § achievements.more666DaysInProject.description: worked 666 days on the project
§ achievements.more777DaysInProject.title: Azino three axes § achievements.more777DaysInProject.title: Las Vegas
§ achievements.more777DaysInProject.description: worked 777 days on the project § achievements.more777DaysInProject.description: worked 777 days on the project
§ achievements.moreRefactoring.title: Executive editor § achievements.moreRefactoring.title: Executive editor
§ achievements.moreRefactoring.description: made the most 'refactoring' tags § achievements.moreRefactoring.description: made the most 'refactoring' tags

View file

@ -3,6 +3,7 @@ export default `
§ uiKit.console.notification: テキストがコピーされました § uiKit.console.notification: テキストがコピーされました
§ uiKit.dataLoader.page: ページ § uiKit.dataLoader.page: ページ
§ uiKit.dataLoader.size: によって表示される § uiKit.dataLoader.size: によって表示される
§ uiKit.dataLoader.rows: lines.
§ uiKit.dataLoader.from: から § uiKit.dataLoader.from: から
§ uiKit.dataLoader.all: すべて表示 § uiKit.dataLoader.all: すべて表示
§ uiKit.hoursChart.work: 標準労働時間 (,から07:00へ20:00) § uiKit.hoursChart.work: 標準労働時間 (,から07:00へ20:00)
@ -24,4 +25,5 @@ export default `
§ common.filters: フィルター § common.filters: フィルター
§ common.notifications.save: 変更は保存されます § common.notifications.save: 変更は保存されます
§ common.notifications.setting: 設定が保存されます § common.notifications.setting: 設定が保存されます
§ common.fileLoader.notification: Cant open file $1
`; `;

View file

@ -34,6 +34,7 @@ export default `
§ sidebar.person.day: 日によって § sidebar.person.day: 日によって
§ sidebar.person.week: 週ごと § sidebar.person.week: 週ごと
§ sidebar.person.month: 月別 § sidebar.person.month: 月別
§ sidebar.person.tasks: Tasks
§ sidebar.person.hours: スケジュール § sidebar.person.hours: スケジュール
§ sidebar.person.commits: All commits § sidebar.person.commits: All commits
§ sidebar.person.changes: すべての変更 § sidebar.person.changes: すべての変更

View file

@ -37,8 +37,13 @@ export default `
§ page.team.author.moneyAll: Received § page.team.author.moneyAll: Received
§ page.team.author.moneyWorked: Worked for § page.team.author.moneyWorked: Worked for
§ page.team.author.moneyLosses: Overpayment § page.team.author.moneyLosses: Overpayment
§ page.team.author.type.work: works
§ page.team.author.type.dismissed: dismissed
§ page.team.author.type.staff: staff
§ page.team.hours.title: Distribution of commits during each day of the week § page.team.hours.title: Distribution of commits during each day of the week
§ page.team.month.title: Project work calendar § page.team.month.title: Project work calendar
§ page.team.month.first: (first work day)
§ page.team.month.last: (last work day)
§ page.team.scope.title: Feature statistics § page.team.scope.title: Feature statistics
§ page.team.scope.scope: Feature § page.team.scope.scope: Feature
§ page.team.scope.days: Working Days § page.team.scope.days: Working Days
@ -86,7 +91,7 @@ export default `
§ page.team.total.description3: The *working and dismissed* card shows the actual composition of employees who are continuously involved in work. Additionally, there are "assistants" typically employees of a different specialization who may occasionally make commits to the project. § page.team.total.description3: The *working and dismissed* card shows the actual composition of employees who are continuously involved in work. Additionally, there are "assistants" typically employees of a different specialization who may occasionally make commits to the project.
§ page.team.total.description4: *Overpayment* includes only working days when commits could have been made. Weekends, public holidays, and vacations are not included in the calculation. This is why overpayment + actual cost != total. The total cost includes payment for weekends, public holidays, and vacations. § page.team.total.description4: *Overpayment* includes only working days when commits could have been made. Weekends, public holidays, and vacations are not included in the calculation. This is why overpayment + actual cost != total. The total cost includes payment for weekends, public holidays, and vacations.
§ page.team.total.description5: *Weekend work* is calculated at a rate of x2 the payment of a regular day. The displayed amount is specifically the overpayment (x1), as the fact of overtime in this context is not of interest. We focus on overpayment when increasing work speed. § page.team.total.description5: *Weekend work* is calculated at a rate of x2 the payment of a regular day. The displayed amount is specifically the overpayment (x1), as the fact of overtime in this context is not of interest. We focus on overpayment when increasing work speed.
§ page.team.tree.title: Project Tree Considering Selected Filters § page.team.tree.title: Project tree considering selected filters
§ page.team.tree.filters.author: Employee § page.team.tree.filters.author: Employee
§ page.team.tree.filters.commits: Number of commits § page.team.tree.filters.commits: Number of commits
§ page.team.tree.filters.help: The minimum number of commits an employee has made in a file § page.team.tree.filters.help: The minimum number of commits an employee has made in a file
@ -101,7 +106,7 @@ export default `
§ page.team.week.date: Date § page.team.week.date: Date
§ page.team.week.numberTasks: Number of tasks § page.team.week.numberTasks: Number of tasks
§ page.team.week.people: Number of people § page.team.week.people: Number of people
§ page.team.week.line: Line Changes § page.team.week.line: Line changes
§ page.team.week.days: Days with and without commits § page.team.week.days: Days with and without commits
§ page.team.week.lossesDetails: Who did not commit § page.team.week.lossesDetails: Who did not commit
§ page.team.week.add: added § page.team.week.add: added

View file

@ -1,7 +1,8 @@
export default ` export default `
§ recommendations.modal.cancel: Ok § recommendations.modal.cancel: Ok
§ recommendations.modal.open: More
§ recommendations.title § recommendations.title
Recommendations and Facts Recommendations and facts
§ recommendations.timestamp.firstCommit.description § recommendations.timestamp.firstCommit.description
made the first commit made the first commit

View file

@ -51,13 +51,13 @@ export default `
§ achievements.lessDaysInProject.description: least days in the project § achievements.lessDaysInProject.description: least days in the project
§ achievements.more90DaysInProject.title: Welcome aboard § achievements.more90DaysInProject.title: Welcome aboard
§ achievements.more90DaysInProject.description: not fired during the probation period § achievements.more90DaysInProject.description: not fired during the probation period
§ achievements.lessDaysForTask.title: Quick draw § achievements.lessDaysForTask.title: Fast shooting
§ achievements.lessDaysForTask.description: a task takes less than a day § achievements.lessDaysForTask.description: a task takes less than a day
§ achievements.adam.title: Adam § achievements.adam.title: Adam
§ achievements.adam.description: the first stable employee on the project § achievements.adam.description: the first stable employee on the project
§ achievements.more666DaysInProject.title: Devil § achievements.more666DaysInProject.title: Devil
§ achievements.more666DaysInProject.description: worked 666 days on the project § achievements.more666DaysInProject.description: worked 666 days on the project
§ achievements.more777DaysInProject.title: Azino three axes § achievements.more777DaysInProject.title: Las Vegas
§ achievements.more777DaysInProject.description: worked 777 days on the project § achievements.more777DaysInProject.description: worked 777 days on the project
§ achievements.moreRefactoring.title: Executive editor § achievements.moreRefactoring.title: Executive editor
§ achievements.moreRefactoring.description: made the most 'refactoring' tags § achievements.moreRefactoring.description: made the most 'refactoring' tags

View file

@ -3,6 +3,7 @@ export default `
§ uiKit.console.notification: Texto copiado § uiKit.console.notification: Texto copiado
§ uiKit.dataLoader.page: Página § uiKit.dataLoader.page: Página
§ uiKit.dataLoader.size: Exibido por § uiKit.dataLoader.size: Exibido por
§ uiKit.dataLoader.rows: lines.
§ uiKit.dataLoader.from: de § uiKit.dataLoader.from: de
§ uiKit.dataLoader.all: Mostrar tudo § uiKit.dataLoader.all: Mostrar tudo
§ uiKit.hoursChart.work: Tempo de trabalho padrão. (dias de semana, das 07: 00 às 20:00) § uiKit.hoursChart.work: Tempo de trabalho padrão. (dias de semana, das 07: 00 às 20:00)
@ -24,4 +25,5 @@ Se este for um erro e a estatística para esse funcionário precisar ser levada
§ common.filters: Filtro § common.filters: Filtro
§ common.notifications.save: Alterações salvas § common.notifications.save: Alterações salvas
§ common.notifications.setting: Configuração guardada § common.notifications.setting: Configuração guardada
§ common.fileLoader.notification: Cant open file $1
`; `;

View file

@ -34,6 +34,7 @@ export default `
§ sidebar.person.day: Por dia § sidebar.person.day: Por dia
§ sidebar.person.week: Por semana § sidebar.person.week: Por semana
§ sidebar.person.month: Por mês § sidebar.person.month: Por mês
§ sidebar.person.tasks: Tasks
§ sidebar.person.hours: Horário § sidebar.person.hours: Horário
§ sidebar.person.commits: All commits § sidebar.person.commits: All commits
§ sidebar.person.changes: Todas as alterações § sidebar.person.changes: Todas as alterações

View file

@ -37,8 +37,13 @@ export default `
§ page.team.author.moneyAll: Received § page.team.author.moneyAll: Received
§ page.team.author.moneyWorked: Worked for § page.team.author.moneyWorked: Worked for
§ page.team.author.moneyLosses: Overpayment § page.team.author.moneyLosses: Overpayment
§ page.team.author.type.work: works
§ page.team.author.type.dismissed: dismissed
§ page.team.author.type.staff: staff
§ page.team.hours.title: Distribution of commits during each day of the week § page.team.hours.title: Distribution of commits during each day of the week
§ page.team.month.title: Project work calendar § page.team.month.title: Project work calendar
§ page.team.month.first: (first work day)
§ page.team.month.last: (last work day)
§ page.team.scope.title: Feature statistics § page.team.scope.title: Feature statistics
§ page.team.scope.scope: Feature § page.team.scope.scope: Feature
§ page.team.scope.days: Working Days § page.team.scope.days: Working Days
@ -86,7 +91,7 @@ export default `
§ page.team.total.description3: The *working and dismissed* card shows the actual composition of employees who are continuously involved in work. Additionally, there are "assistants" typically employees of a different specialization who may occasionally make commits to the project. § page.team.total.description3: The *working and dismissed* card shows the actual composition of employees who are continuously involved in work. Additionally, there are "assistants" typically employees of a different specialization who may occasionally make commits to the project.
§ page.team.total.description4: *Overpayment* includes only working days when commits could have been made. Weekends, public holidays, and vacations are not included in the calculation. This is why overpayment + actual cost != total. The total cost includes payment for weekends, public holidays, and vacations. § page.team.total.description4: *Overpayment* includes only working days when commits could have been made. Weekends, public holidays, and vacations are not included in the calculation. This is why overpayment + actual cost != total. The total cost includes payment for weekends, public holidays, and vacations.
§ page.team.total.description5: *Weekend work* is calculated at a rate of x2 the payment of a regular day. The displayed amount is specifically the overpayment (x1), as the fact of overtime in this context is not of interest. We focus on overpayment when increasing work speed. § page.team.total.description5: *Weekend work* is calculated at a rate of x2 the payment of a regular day. The displayed amount is specifically the overpayment (x1), as the fact of overtime in this context is not of interest. We focus on overpayment when increasing work speed.
§ page.team.tree.title: Project Tree Considering Selected Filters § page.team.tree.title: Project tree considering selected filters
§ page.team.tree.filters.author: Employee § page.team.tree.filters.author: Employee
§ page.team.tree.filters.commits: Number of commits § page.team.tree.filters.commits: Number of commits
§ page.team.tree.filters.help: The minimum number of commits an employee has made in a file § page.team.tree.filters.help: The minimum number of commits an employee has made in a file
@ -101,7 +106,7 @@ export default `
§ page.team.week.date: Date § page.team.week.date: Date
§ page.team.week.numberTasks: Number of tasks § page.team.week.numberTasks: Number of tasks
§ page.team.week.people: Number of people § page.team.week.people: Number of people
§ page.team.week.line: Line Changes § page.team.week.line: Line changes
§ page.team.week.days: Days with and without commits § page.team.week.days: Days with and without commits
§ page.team.week.lossesDetails: Who did not commit § page.team.week.lossesDetails: Who did not commit
§ page.team.week.add: added § page.team.week.add: added

View file

@ -1,7 +1,8 @@
export default ` export default `
§ recommendations.modal.cancel: Ok § recommendations.modal.cancel: Ok
§ recommendations.modal.open: More
§ recommendations.title § recommendations.title
Recommendations and Facts Recommendations and facts
§ recommendations.timestamp.firstCommit.description § recommendations.timestamp.firstCommit.description
made the first commit made the first commit

View file

@ -3,6 +3,7 @@ export default `
§ uiKit.console.notification: Текст скопирован § uiKit.console.notification: Текст скопирован
§ uiKit.dataLoader.page: Страница § uiKit.dataLoader.page: Страница
§ uiKit.dataLoader.size: Отображается по § uiKit.dataLoader.size: Отображается по
§ uiKit.dataLoader.rows: строк.
§ uiKit.dataLoader.from: из § uiKit.dataLoader.from: из
§ uiKit.dataLoader.all: Показать все § uiKit.dataLoader.all: Показать все
§ uiKit.hoursChart.work: стандартное рабочее время (будни, с 07:00 до 20:00) § uiKit.hoursChart.work: стандартное рабочее время (будни, с 07:00 до 20:00)
@ -24,4 +25,5 @@ export default `
§ common.filters: Фильтры § common.filters: Фильтры
§ common.notifications.save: Изменения сохранены § common.notifications.save: Изменения сохранены
§ common.notifications.setting: Настройки сохранены § common.notifications.setting: Настройки сохранены
§ common.fileLoader.notification: Ошибка загрузки файла $1
`; `;

View file

@ -35,6 +35,7 @@ export default `
§ sidebar.person.day: По дням § sidebar.person.day: По дням
§ sidebar.person.week: По неделям § sidebar.person.week: По неделям
§ sidebar.person.month: По месяцам § sidebar.person.month: По месяцам
§ sidebar.person.tasks: Список задач
§ sidebar.person.hours: Расписание § sidebar.person.hours: Расписание
§ sidebar.person.commits: Все коммиты § sidebar.person.commits: Все коммиты
§ sidebar.person.changes: Все изменения § sidebar.person.changes: Все изменения

View file

@ -37,8 +37,13 @@ export default `
§ page.team.author.moneyAll: Получил § page.team.author.moneyAll: Получил
§ page.team.author.moneyWorked: Отработал § page.team.author.moneyWorked: Отработал
§ page.team.author.moneyLosses: Переплата § page.team.author.moneyLosses: Переплата
§ page.team.author.type.work: работает
§ page.team.author.type.dismissed: уволен
§ page.team.author.type.staff: помощник
§ page.team.hours.title: Распределение коммитов в течении каждого дня недели § page.team.hours.title: Распределение коммитов в течении каждого дня недели
§ page.team.month.title: Календарь работы по проекту § page.team.month.title: Календарь работы по проекту
§ page.team.month.first: (первый рабочий день)
§ page.team.month.last: (последний рабочий день)
§ page.team.scope.title: Статистика по фичам § page.team.scope.title: Статистика по фичам
§ page.team.scope.scope: Фича § page.team.scope.scope: Фича
§ page.team.scope.days: Раб. дней § page.team.scope.days: Раб. дней
@ -177,7 +182,7 @@ export default `
§ page.person.business.time.description: Время от первого, до последнего коммита (в том числе, нерабочие дни) § page.person.business.time.description: Время от первого, до последнего коммита (в том числе, нерабочие дни)
§ page.person.business.time.title: Дней на проекте: § page.person.business.time.title: Дней на проекте:
§ page.person.business.time.dismissed: (уволен) § page.person.business.time.dismissed: (уволен)
§ page.person.business.time.staff: (не в команде) § page.person.business.time.staff: (помощник)
§ page.person.business.achievements: Достижения § page.person.business.achievements: Достижения
§ page.person.changes.title: Достижения § page.person.changes.title: Достижения
§ page.person.changes.description: § page.person.changes.description:

View file

@ -37,8 +37,13 @@ export default `
§ page.team.author.moneyAll: Денег получил § page.team.author.moneyAll: Денег получил
§ page.team.author.moneyWorked: Отработал § page.team.author.moneyWorked: Отработал
§ page.team.author.moneyLosses: Переплата § page.team.author.moneyLosses: Переплата
§ page.team.author.type.work: works
§ page.team.author.type.dismissed: dismissed
§ page.team.author.type.staff: staff
§ page.team.hours.title: Распределение работы в течении каждого дня недели § page.team.hours.title: Распределение работы в течении каждого дня недели
§ page.team.month.title: Календарь работы по проекту § page.team.month.title: Календарь работы по проекту
§ page.team.month.first: (first work day)
§ page.team.month.last: (last work day)
§ page.team.scope.title: Статистика по фичам § page.team.scope.title: Статистика по фичам
§ page.team.scope.scope: Доработка § page.team.scope.scope: Доработка
§ page.team.scope.days: Раб. дней § page.team.scope.days: Раб. дней
@ -170,7 +175,7 @@ export default `
§ page.person.business.time.staff: (не в команде) § page.person.business.time.staff: (не в команде)
§ page.person.business.achievements: Достижения § page.person.business.achievements: Достижения
§ page.person.changes.title: Достижения § page.person.changes.title: Достижения
§ page.person.changes.description: § page.person.changes.description:
При некоторых видах форматирования git отмечает строки как «удалённые» и «добавленные», При некоторых видах форматирования git отмечает строки как «удалённые» и «добавленные»,
хотя на самом деле они были «изменены». Поэтому, если вы провели большой рефакторинг, хотя на самом деле они были «изменены». Поэтому, если вы провели большой рефакторинг,
git может показать малое количество изменений в статистике, а фактический результат git может показать малое количество изменений в статистике, а фактический результат

View file

@ -1,5 +1,6 @@
export default ` export default `
§ recommendations.modal.cancel: Закрыть § recommendations.modal.cancel: Закрыть
§ recommendations.modal.open: Подробнее
§ recommendations.title § recommendations.title
Рекомендации и факты Рекомендации и факты

View file

@ -51,13 +51,13 @@ export default `
§ achievements.lessDaysInProject.description: least days in the project § achievements.lessDaysInProject.description: least days in the project
§ achievements.more90DaysInProject.title: Welcome aboard § achievements.more90DaysInProject.title: Welcome aboard
§ achievements.more90DaysInProject.description: not fired during the probation period § achievements.more90DaysInProject.description: not fired during the probation period
§ achievements.lessDaysForTask.title: Quick draw § achievements.lessDaysForTask.title: Fast shooting
§ achievements.lessDaysForTask.description: a task takes less than a day § achievements.lessDaysForTask.description: a task takes less than a day
§ achievements.adam.title: Adam § achievements.adam.title: Adam
§ achievements.adam.description: the first stable employee on the project § achievements.adam.description: the first stable employee on the project
§ achievements.more666DaysInProject.title: Devil § achievements.more666DaysInProject.title: Devil
§ achievements.more666DaysInProject.description: worked 666 days on the project § achievements.more666DaysInProject.description: worked 666 days on the project
§ achievements.more777DaysInProject.title: Azino three axes § achievements.more777DaysInProject.title: Las Vegas
§ achievements.more777DaysInProject.description: worked 777 days on the project § achievements.more777DaysInProject.description: worked 777 days on the project
§ achievements.moreRefactoring.title: Executive editor § achievements.moreRefactoring.title: Executive editor
§ achievements.moreRefactoring.description: made the most 'refactoring' tags § achievements.moreRefactoring.description: made the most 'refactoring' tags

View file

@ -3,6 +3,7 @@ export default `
§ uiKit.console.notification: 文本已被复制 § uiKit.console.notification: 文本已被复制
§ uiKit.dataLoader.page: 页面 § uiKit.dataLoader.page: 页面
§ uiKit.dataLoader.size: 显示的 § uiKit.dataLoader.size: 显示的
§ uiKit.dataLoader.rows: lines.
§ uiKit.dataLoader.from: § uiKit.dataLoader.from:
§ uiKit.dataLoader.all: 全部展示 § uiKit.dataLoader.all: 全部展示
§ uiKit.hoursChart.work: 标准工作时间 (平日07:0020:00) § uiKit.hoursChart.work: 标准工作时间 (平日07:0020:00)
@ -24,4 +25,5 @@ export default `
§ common.filters: 过滤器 § common.filters: 过滤器
§ common.notifications.save: 将保存更改 § common.notifications.save: 将保存更改
§ common.notifications.setting: 设置被保存 § common.notifications.setting: 设置被保存
§ common.fileLoader.notification: Cant open file $1
`; `;

View file

@ -34,6 +34,7 @@ export default `
§ sidebar.person.day: 白天 § sidebar.person.day: 白天
§ sidebar.person.week: 按星期计算 § sidebar.person.week: 按星期计算
§ sidebar.person.month: 按月计算 § sidebar.person.month: 按月计算
§ sidebar.person.tasks: Tasks
§ sidebar.person.hours: 时间表 § sidebar.person.hours: 时间表
§ sidebar.person.commits: All commits § sidebar.person.commits: All commits
§ sidebar.person.changes: 所有更改 § sidebar.person.changes: 所有更改

View file

@ -37,8 +37,13 @@ export default `
§ page.team.author.moneyAll: 我拿到钱了 § page.team.author.moneyAll: 我拿到钱了
§ page.team.author.moneyWorked: 工作了 § page.team.author.moneyWorked: 工作了
§ page.team.author.moneyLosses: 多付 § page.team.author.moneyLosses: 多付
§ page.team.author.type.work: works
§ page.team.author.type.dismissed: dismissed
§ page.team.author.type.staff: staff
§ page.team.hours.title: 每周每一天的工作分配 § page.team.hours.title: 每周每一天的工作分配
§ page.team.month.title: 项目工作日历 § page.team.month.title: 项目工作日历
§ page.team.month.first: (first work day)
§ page.team.month.last: (last work day)
§ page.team.scope.title: 按模块划分的统计数字 § page.team.scope.title: 按模块划分的统计数字
§ page.team.scope.scope: 修改 § page.team.scope.scope: 修改
§ page.team.scope.days: 工作天 § page.team.scope.days: 工作天

View file

@ -1,7 +1,8 @@
export default ` export default `
§ recommendations.modal.cancel: Ok § recommendations.modal.cancel: Ok
§ recommendations.modal.open: More
§ recommendations.title § recommendations.title
Recommendations and Facts Recommendations and facts
§ recommendations.timestamp.firstCommit.description § recommendations.timestamp.firstCommit.description
made the first commit made the first commit