Format CSS and TSX files.

This commit is contained in:
Paulo Gustavo Veiga 2022-07-09 20:56:01 -07:00
parent 0f4a8ee087
commit ae02780a1a
56 changed files with 17369 additions and 4610 deletions

View File

@ -13,7 +13,7 @@
width: 100px; width: 100px;
height: 100px; height: 100px;
cursor: crosshair; cursor: crosshair;
background-image: url("../img/bootstrap-colorpicker/saturation.png"); background-image: url('../img/bootstrap-colorpicker/saturation.png');
} }
.colorpicker-saturation i { .colorpicker-saturation i {
@ -64,12 +64,12 @@
} }
.colorpicker-hue { .colorpicker-hue {
background-image: url("../img/bootstrap-colorpicker/hue.png"); background-image: url('../img/bootstrap-colorpicker/hue.png');
} }
.colorpicker-alpha { .colorpicker-alpha {
display: none; display: none;
background-image: url("../img/bootstrap-colorpicker/alpha.png"); background-image: url('../img/bootstrap-colorpicker/alpha.png');
} }
.colorpicker { .colorpicker {
@ -89,7 +89,7 @@
.colorpicker:after { .colorpicker:after {
display: table; display: table;
line-height: 0; line-height: 0;
content: ""; content: '';
} }
.colorpicker:after { .colorpicker:after {
@ -135,7 +135,7 @@
height: 10px; height: 10px;
margin-top: 5px; margin-top: 5px;
clear: both; clear: both;
background-image: url("../img/bootstrap-colorpicker/alpha.png"); background-image: url('../img/bootstrap-colorpicker/alpha.png');
background-position: 0 100%; background-position: 0 100%;
} }
@ -194,11 +194,11 @@
} }
.colorpicker.colorpicker-horizontal .colorpicker-hue { .colorpicker.colorpicker-horizontal .colorpicker-hue {
background-image: url("../img/bootstrap-colorpicker/hue-horizontal.png"); background-image: url('../img/bootstrap-colorpicker/hue-horizontal.png');
} }
.colorpicker.colorpicker-horizontal .colorpicker-alpha { .colorpicker.colorpicker-horizontal .colorpicker-alpha {
background-image: url("../img/bootstrap-colorpicker/alpha-horizontal.png"); background-image: url('../img/bootstrap-colorpicker/alpha-horizontal.png');
} }
.colorpicker.colorpicker-hidden { .colorpicker.colorpicker-hidden {

View File

@ -6,4 +6,180 @@
* Licensed under the Apache License v2.0 * Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0.txt * http://www.apache.org/licenses/LICENSE-2.0.txt
* *
*/.colorpicker-saturation{float:left;width:100px;height:100px;cursor:crosshair;background-image:url("../img/bootstrap-colorpicker/saturation.png")}.colorpicker-saturation i{position:absolute;top:0;left:0;display:block;width:5px;height:5px;margin:-4px 0 0 -4px;border:1px solid #000;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.colorpicker-saturation i b{display:block;width:5px;height:5px;border:1px solid #fff;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.colorpicker-hue,.colorpicker-alpha{float:left;width:15px;height:100px;margin-bottom:4px;margin-left:4px;cursor:row-resize}.colorpicker-hue i,.colorpicker-alpha i{position:absolute;top:0;left:0;display:block;width:100%;height:1px;margin-top:-1px;background:#000;border-top:1px solid #fff}.colorpicker-hue{background-image:url("../img/bootstrap-colorpicker/hue.png")}.colorpicker-alpha{display:none;background-image:url("../img/bootstrap-colorpicker/alpha.png")}.colorpicker{top:0;left:0;z-index:2500;min-width:130px;padding:4px;margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1}.colorpicker:before,.colorpicker:after{display:table;line-height:0;content:""}.colorpicker:after{clear:both}.colorpicker:before{position:absolute;top:-7px;left:6px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.colorpicker:after{position:absolute;top:-6px;left:7px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.colorpicker div{position:relative}.colorpicker.colorpicker-with-alpha{min-width:140px}.colorpicker.colorpicker-with-alpha .colorpicker-alpha{display:block}.colorpicker-color{height:10px;margin-top:5px;clear:both;background-image:url("../img/bootstrap-colorpicker/alpha.png");background-position:0 100%}.colorpicker-color div{height:10px}.colorpicker-element .input-group-addon i{display:block;width:16px;height:16px;cursor:pointer}.colorpicker.colorpicker-inline{position:relative;display:inline-block;float:none}.colorpicker.colorpicker-horizontal{width:110px;height:auto;min-width:110px}.colorpicker.colorpicker-horizontal .colorpicker-saturation{margin-bottom:4px}.colorpicker.colorpicker-horizontal .colorpicker-color{width:100px}.colorpicker.colorpicker-horizontal .colorpicker-hue,.colorpicker.colorpicker-horizontal .colorpicker-alpha{float:left;width:100px;height:15px;margin-bottom:4px;margin-left:0;cursor:col-resize}.colorpicker.colorpicker-horizontal .colorpicker-hue i,.colorpicker.colorpicker-horizontal .colorpicker-alpha i{position:absolute;top:0;left:0;display:block;width:1px;height:15px;margin-top:0;background:#fff;border:0}.colorpicker.colorpicker-horizontal .colorpicker-hue{background-image:url("../img/bootstrap-colorpicker/hue-horizontal.png")}.colorpicker.colorpicker-horizontal .colorpicker-alpha{background-image:url("../img/bootstrap-colorpicker/alpha-horizontal.png")}.colorpicker.colorpicker-hidden{display:none}.colorpicker.colorpicker-visible{display:block}.colorpicker-inline.colorpicker-visible{display:inline-block} */
.colorpicker-saturation {
float: left;
width: 100px;
height: 100px;
cursor: crosshair;
background-image: url('../img/bootstrap-colorpicker/saturation.png');
}
.colorpicker-saturation i {
position: absolute;
top: 0;
left: 0;
display: block;
width: 5px;
height: 5px;
margin: -4px 0 0 -4px;
border: 1px solid #000;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
.colorpicker-saturation i b {
display: block;
width: 5px;
height: 5px;
border: 1px solid #fff;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
.colorpicker-hue,
.colorpicker-alpha {
float: left;
width: 15px;
height: 100px;
margin-bottom: 4px;
margin-left: 4px;
cursor: row-resize;
}
.colorpicker-hue i,
.colorpicker-alpha i {
position: absolute;
top: 0;
left: 0;
display: block;
width: 100%;
height: 1px;
margin-top: -1px;
background: #000;
border-top: 1px solid #fff;
}
.colorpicker-hue {
background-image: url('../img/bootstrap-colorpicker/hue.png');
}
.colorpicker-alpha {
display: none;
background-image: url('../img/bootstrap-colorpicker/alpha.png');
}
.colorpicker {
top: 0;
left: 0;
z-index: 2500;
min-width: 130px;
padding: 4px;
margin-top: 1px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
*zoom: 1;
}
.colorpicker:before,
.colorpicker:after {
display: table;
line-height: 0;
content: '';
}
.colorpicker:after {
clear: both;
}
.colorpicker:before {
position: absolute;
top: -7px;
left: 6px;
display: inline-block;
border-right: 7px solid transparent;
border-bottom: 7px solid #ccc;
border-left: 7px solid transparent;
border-bottom-color: rgba(0, 0, 0, 0.2);
content: '';
}
.colorpicker:after {
position: absolute;
top: -6px;
left: 7px;
display: inline-block;
border-right: 6px solid transparent;
border-bottom: 6px solid #fff;
border-left: 6px solid transparent;
content: '';
}
.colorpicker div {
position: relative;
}
.colorpicker.colorpicker-with-alpha {
min-width: 140px;
}
.colorpicker.colorpicker-with-alpha .colorpicker-alpha {
display: block;
}
.colorpicker-color {
height: 10px;
margin-top: 5px;
clear: both;
background-image: url('../img/bootstrap-colorpicker/alpha.png');
background-position: 0 100%;
}
.colorpicker-color div {
height: 10px;
}
.colorpicker-element .input-group-addon i {
display: block;
width: 16px;
height: 16px;
cursor: pointer;
}
.colorpicker.colorpicker-inline {
position: relative;
display: inline-block;
float: none;
}
.colorpicker.colorpicker-horizontal {
width: 110px;
height: auto;
min-width: 110px;
}
.colorpicker.colorpicker-horizontal .colorpicker-saturation {
margin-bottom: 4px;
}
.colorpicker.colorpicker-horizontal .colorpicker-color {
width: 100px;
}
.colorpicker.colorpicker-horizontal .colorpicker-hue,
.colorpicker.colorpicker-horizontal .colorpicker-alpha {
float: left;
width: 100px;
height: 15px;
margin-bottom: 4px;
margin-left: 0;
cursor: col-resize;
}
.colorpicker.colorpicker-horizontal .colorpicker-hue i,
.colorpicker.colorpicker-horizontal .colorpicker-alpha i {
position: absolute;
top: 0;
left: 0;
display: block;
width: 1px;
height: 15px;
margin-top: 0;
background: #fff;
border: 0;
}
.colorpicker.colorpicker-horizontal .colorpicker-hue {
background-image: url('../img/bootstrap-colorpicker/hue-horizontal.png');
}
.colorpicker.colorpicker-horizontal .colorpicker-alpha {
background-image: url('../img/bootstrap-colorpicker/alpha-horizontal.png');
}
.colorpicker.colorpicker-hidden {
display: none;
}
.colorpicker.colorpicker-visible {
display: block;
}
.colorpicker-inline.colorpicker-visible {
display: inline-block;
}

View File

@ -10,9 +10,9 @@
.btn-info, .btn-info,
.btn-warning, .btn-warning,
.btn-danger { .btn-danger {
text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
} }
.btn-default:active, .btn-default:active,
.btn-primary:active, .btn-primary:active,
@ -26,8 +26,8 @@
.btn-info.active, .btn-info.active,
.btn-warning.active, .btn-warning.active,
.btn-danger.active { .btn-danger.active {
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
} }
.btn:active, .btn:active,
.btn.active { .btn.active {
@ -145,8 +145,8 @@
} }
.thumbnail, .thumbnail,
.img-thumbnail { .img-thumbnail {
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
box-shadow: 0 1px 2px rgba(0, 0, 0, .075); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
} }
.dropdown-menu > li > a:hover, .dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus { .dropdown-menu > li > a:focus {
@ -172,20 +172,20 @@
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x; background-repeat: repeat-x;
border-radius: 4px; border-radius: 4px;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);
} }
.navbar-default .navbar-nav > .active > a { .navbar-default .navbar-nav > .active > a {
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%); background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%);
background-image: linear-gradient(to bottom, #ebebeb 0%, #f3f3f3 100%); background-image: linear-gradient(to bottom, #ebebeb 0%, #f3f3f3 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);
background-repeat: repeat-x; background-repeat: repeat-x;
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);
} }
.navbar-brand, .navbar-brand,
.navbar-nav > li > a { .navbar-nav > li > a {
text-shadow: 0 1px 0 rgba(255, 255, 255, .25); text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
} }
.navbar-inverse { .navbar-inverse {
background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
@ -199,12 +199,12 @@
background-image: linear-gradient(to bottom, #222 0%, #282828 100%); background-image: linear-gradient(to bottom, #222 0%, #282828 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);
background-repeat: repeat-x; background-repeat: repeat-x;
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);
} }
.navbar-inverse .navbar-brand, .navbar-inverse .navbar-brand,
.navbar-inverse .navbar-nav > li > a { .navbar-inverse .navbar-nav > li > a {
text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
} }
.navbar-static-top, .navbar-static-top,
.navbar-fixed-top, .navbar-fixed-top,
@ -212,9 +212,9 @@
border-radius: 0; border-radius: 0;
} }
.alert { .alert {
text-shadow: 0 1px 0 rgba(255, 255, 255, .2); text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
} }
.alert-success { .alert-success {
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
@ -282,8 +282,8 @@
} }
.list-group { .list-group {
border-radius: 4px; border-radius: 4px;
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
box-shadow: 0 1px 2px rgba(0, 0, 0, .075); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
} }
.list-group-item.active, .list-group-item.active,
.list-group-item.active:hover, .list-group-item.active:hover,
@ -296,8 +296,8 @@
border-color: #3278b3; border-color: #3278b3;
} }
.panel { .panel {
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: 0 1px 2px rgba(0, 0, 0, .05); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
} }
.panel-default > .panel-heading { .panel-default > .panel-heading {
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
@ -341,7 +341,7 @@
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
background-repeat: repeat-x; background-repeat: repeat-x;
border-color: #dcdcdc; border-color: #dcdcdc;
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
} }
/*# sourceMappingURL=bootstrap-theme.css.map */ /*# sourceMappingURL=bootstrap-theme.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -64,7 +64,8 @@ div#toolbarRight {
} }
.actionButton:hover { .actionButton:hover {
transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,
box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
} }
div#toolbar { div#toolbar {
@ -165,7 +166,7 @@ div#toolbar .buttonExtActive {
div#toolbar .buttonExtOn { div#toolbar .buttonExtOn {
opacity: 0.8; opacity: 0.8;
cursor: pointer cursor: pointer;
} }
div#toolbar .buttonExtOff { div#toolbar .buttonExtOff {

View File

@ -56,7 +56,9 @@ export default function Toolbar({
</ToolbarButton> </ToolbarButton>
</div> </div>
)} )}
{(editorMode === 'edition-editor' || editorMode === 'edition-owner' || editorMode === 'showcase') && ( {(editorMode === 'edition-editor' ||
editorMode === 'edition-owner' ||
editorMode === 'showcase') && (
<> <>
<div id="edit" className="buttonContainer"> <div id="edit" className="buttonContainer">
<ToolbarButton id="undoEdition" className="buttonOn"> <ToolbarButton id="undoEdition" className="buttonOn">
@ -118,36 +120,22 @@ export default function Toolbar({
</> </>
)} )}
<ToolbarRightContainer> <ToolbarRightContainer>
<ToolbarButton <ToolbarButton id="export" className="buttonOn" onClick={() => onAction('export')}>
id="export"
className="buttonOn"
onClick={() => onAction('export')}
>
<img src={ExportSvg} /> <img src={ExportSvg} />
</ToolbarButton> </ToolbarButton>
{(editorMode === 'edition-owner' || editorMode === 'edition-editor' || editorMode === 'edition-viewer') && ( {(editorMode === 'edition-owner' ||
<ToolbarButton editorMode === 'edition-editor' ||
id="print" editorMode === 'edition-viewer') && (
className="buttonOn" <ToolbarButton id="print" className="buttonOn" onClick={() => onAction('print')}>
onClick={() => onAction('print')}
>
<img src={PrintSvg} /> <img src={PrintSvg} />
</ToolbarButton> </ToolbarButton>
)} )}
<ToolbarButton <ToolbarButton id="info" className="buttonOn" onClick={() => onAction('info')}>
id="info"
className="buttonOn"
onClick={() => onAction('info')}
>
<img src={InfoSvg} /> <img src={InfoSvg} />
</ToolbarButton> </ToolbarButton>
{editorMode === 'edition-owner' && ( {editorMode === 'edition-owner' && (
<> <>
<ToolbarButton <ToolbarButton id="history" className="buttonOn" onClick={() => onAction('history')}>
id="history"
className="buttonOn"
onClick={() => onAction('history')}
>
<img src={HistorySvg} /> <img src={HistorySvg} />
</ToolbarButton> </ToolbarButton>
<ToolbarButton <ToolbarButton
@ -168,7 +156,6 @@ export default function Toolbar({
<ActionButton onClick={() => onAction('share')}> <ActionButton onClick={() => onAction('share')}>
{intl.formatMessage({ id: 'action.share', defaultMessage: 'Share' })} {intl.formatMessage({ id: 'action.share', defaultMessage: 'Share' })}
</ActionButton> </ActionButton>
)} )}
</ToolbarRightContainer> </ToolbarRightContainer>
</div> </div>

View File

@ -1,8 +1,8 @@
/********************************************************************************/ /********************************************************************************/
/* Header & Toolbar Styles */ /* Header & Toolbar Styles */
/********************************************************************************/ /********************************************************************************/
@import "bootstrap-prefix.min.css"; @import 'bootstrap-prefix.min.css';
@import "bootstrap-fixes.css"; @import 'bootstrap-fixes.css';
html { html {
/* avoid bootstrap overriding font-size and breaking Mui */ /* avoid bootstrap overriding font-size and breaking Mui */
@ -32,7 +32,8 @@ div#mindplot {
overflow: hidden; overflow: hidden;
opacity: 1; opacity: 1;
background-color: #f2f2f2; background-color: #f2f2f2;
background-image: linear-gradient(#ebe9e7 1px, transparent 1px), linear-gradient(to right, #ebe9e7 1px, #f2f2f2 1px); background-image: linear-gradient(#ebe9e7 1px, transparent 1px),
linear-gradient(to right, #ebe9e7 1px, #f2f2f2 1px);
background-size: 50px 50px; background-size: 50px 50px;
} }
@ -124,7 +125,7 @@ div.shareModalDialog {
height: 20px; height: 20px;
margin-left: 4px; margin-left: 4px;
margin-top: 3px; margin-top: 3px;
cursor: pointer cursor: pointer;
} }
.panelIcon:hover { .panelIcon:hover {
@ -158,7 +159,7 @@ div#position {
background-position: center; background-position: center;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 40px 40px; background-size: 40px 40px;
background-color: #FFF; background-color: #fff;
border-radius: 8px; border-radius: 8px;
} }
@ -176,7 +177,7 @@ div#position {
background-size: 40px 40px; background-size: 40px 40px;
background-position: center; background-position: center;
cursor: pointer; cursor: pointer;
background-color: #FFF; background-color: #fff;
} }
#zoom-plus { #zoom-plus {

View File

@ -21,7 +21,6 @@ import Editor, { EditorOptions } from '../../../../src/index';
import { LocalStorageManager, Designer } from '@wisemapping/mindplot'; import { LocalStorageManager, Designer } from '@wisemapping/mindplot';
const initialization = (designer: Designer) => { const initialization = (designer: Designer) => {
designer.addEvent('loadSuccess', () => { designer.addEvent('loadSuccess', () => {
const elem = document.getElementById('mindplot'); const elem = document.getElementById('mindplot');
if (elem) { if (elem) {
@ -35,10 +34,10 @@ const mapId = 'welcome';
const options: EditorOptions = { const options: EditorOptions = {
zoom: 0.8, zoom: 0.8,
locked: false, locked: false,
mapTitle: "Develop WiseMapping", mapTitle: 'Develop WiseMapping',
mode: 'edition-owner', mode: 'edition-owner',
locale: 'en', locale: 'en',
enableKeyboardEvents: true enableKeyboardEvents: true,
}; };
ReactDOM.render( ReactDOM.render(

View File

@ -5,7 +5,6 @@ import Editor, { EditorOptions } from '../../../../src/index';
import { LocalStorageManager, Designer } from '@wisemapping/mindplot'; import { LocalStorageManager, Designer } from '@wisemapping/mindplot';
const initialization = (designer: Designer) => { const initialization = (designer: Designer) => {
designer.addEvent('loadSuccess', () => { designer.addEvent('loadSuccess', () => {
const elem = document.getElementById('mindplot'); const elem = document.getElementById('mindplot');
if (elem) { if (elem) {
@ -25,7 +24,6 @@ const initialization = (designer: Designer) => {
option.selected = option.value === mapId; option.selected = option.value === mapId;
}); });
} }
}); });
}; };
@ -36,10 +34,10 @@ const persistence = new LocalStorageManager('samples/{id}.wxml', false);
const options: EditorOptions = { const options: EditorOptions = {
zoom: 0.8, zoom: 0.8,
locked: false, locked: false,
mapTitle: "Develop WiseMapping", mapTitle: 'Develop WiseMapping',
mode: 'viewonly', mode: 'viewonly',
locale: 'en', locale: 'en',
enableKeyboardEvents: true enableKeyboardEvents: true,
}; };
ReactDOM.render( ReactDOM.render(

View File

@ -1,5 +1,4 @@
body body {
{
font-size: 1em !important; font-size: 1em !important;
color: #000 !important; color: #000 !important;
font-family: Arial !important; font-family: Arial !important;

View File

@ -26,10 +26,7 @@ const ClientHealthSentinel = (): React.ReactElement => {
fullWidth={true} fullWidth={true}
> >
<DialogTitle> <DialogTitle>
<FormattedMessage <FormattedMessage id="expired.title" defaultMessage="Your session has expired" />
id="expired.title"
defaultMessage="Your session has expired"
/>
</DialogTitle> </DialogTitle>
<DialogContent> <DialogContent>

View File

@ -40,13 +40,15 @@ const EditorPage = ({ isTryMode }: EditorPropsType): React.ReactElement => {
} }
if (!fetchResult.map) { if (!fetchResult.map) {
throw new Error(`Map info could not be loaded. Info not present: ${JSON.stringify(fetchResult)}`); throw new Error(
`Map info could not be loaded. Info not present: ${JSON.stringify(fetchResult)}`,
);
} }
result = `edition-${fetchResult.map.role}`; result = `edition-${fetchResult.map.role}`;
} }
} }
return result; return result;
} };
// What is the role ? // What is the role ?
const mapId = EditorOptionsBuilder.loadMapId(); const mapId = EditorOptionsBuilder.loadMapId();
@ -69,22 +71,24 @@ const EditorPage = ({ isTryMode }: EditorPropsType): React.ReactElement => {
defaultLocale={Locales.EN.code} defaultLocale={Locales.EN.code}
messages={userLocale.message as Record<string, string>} messages={userLocale.message as Record<string, string>}
> >
<Editor onAction={setActiveDialog} <Editor
onAction={setActiveDialog}
options={options} options={options}
persistenceManager={persistence} persistenceManager={persistence}
mapId={mapId} /> mapId={mapId}
{ />
activeDialog && {activeDialog && (
<ActionDispatcher <ActionDispatcher
action={activeDialog} action={activeDialog}
onClose={() => setActiveDialog(null)} onClose={() => setActiveDialog(null)}
mapsId={[mapId]} mapsId={[mapId]}
fromEditor fromEditor
/> />
} )}
</IntlProvider>) : <></> </IntlProvider>
} ) : (
<></>
);
};
export default EditorPage; export default EditorPage;

View File

@ -31,7 +31,7 @@ const ForgotPassword = () => {
onError: (error) => { onError: (error) => {
setError(error); setError(error);
}, },
} },
); );
const handleOnSubmit = (event: React.FormEvent<HTMLFormElement>) => { const handleOnSubmit = (event: React.FormEvent<HTMLFormElement>) => {
@ -55,7 +55,7 @@ const ForgotPassword = () => {
<GlobalError error={error} /> <GlobalError error={error} />
<form onSubmit={handleOnSubmit}> <form onSubmit={handleOnSubmit}>
<input type='hidden' value={getCsrfToken()} name={getCsrfTokenParameter()} /> <input type="hidden" value={getCsrfToken()} name={getCsrfTokenParameter()} />
<Input <Input
type="email" type="email"
name="email" name="email"
@ -79,8 +79,15 @@ const ForgotPassword = () => {
const ForgotPasswordPage = (): React.ReactElement => { const ForgotPasswordPage = (): React.ReactElement => {
const intl = useIntl(); const intl = useIntl();
useEffect(() => { useEffect(() => {
document.title = intl.formatMessage({ id: 'forgot.page-title', defaultMessage: 'Forgot Password | WiseMapping' }); document.title = intl.formatMessage({
ReactGA.send({ hitType: 'pageview', page: window.location.pathname, title: 'ForgotPassword:Init' }); id: 'forgot.page-title',
defaultMessage: 'Forgot Password | WiseMapping',
});
ReactGA.send({
hitType: 'pageview',
page: window.location.pathname,
title: 'ForgotPassword:Init',
});
}, []); }, []);
return ( return (

View File

@ -12,8 +12,15 @@ const ForgotPasswordSuccessPage = (): React.ReactElement => {
const intl = useIntl(); const intl = useIntl();
useEffect(() => { useEffect(() => {
document.title = intl.formatMessage({ id: 'forgotsuccess.page-title', defaultMessage: 'Password Recovered | WiseMapping' }); document.title = intl.formatMessage({
ReactGA.send({ hitType: 'pageview', page: window.location.pathname, title: 'ForgotPassword:Success' }); id: 'forgotsuccess.page-title',
defaultMessage: 'Password Recovered | WiseMapping',
});
ReactGA.send({
hitType: 'pageview',
page: window.location.pathname,
title: 'ForgotPassword:Success',
});
}); });
return ( return (

View File

@ -13,8 +13,8 @@ type InputProps = {
autoComplete?: string; autoComplete?: string;
fullWidth?: boolean; fullWidth?: boolean;
disabled?: boolean; disabled?: boolean;
maxLength?: number, maxLength?: number;
rows?: number rows?: number;
}; };
const Input = ({ const Input = ({

View File

@ -28,10 +28,7 @@ const Footer = (): React.ReactElement => {
</div> </div>
<div> <div>
<a href="https://www.wisemapping.com/termsofuse.html"> <a href="https://www.wisemapping.com/termsofuse.html">
<FormattedMessage <FormattedMessage id="footer.termsandconditions" defaultMessage="Term And Conditions" />
id="footer.termsandconditions"
defaultMessage="Term And Conditions"
/>
</a> </a>
</div> </div>
</div> </div>
@ -61,18 +58,12 @@ const Footer = (): React.ReactElement => {
</h4> </h4>
<div> <div>
<a href="https://www.paypal.com/donate/?hosted_button_id=CF7GJ7T6E4RS4"> <a href="https://www.paypal.com/donate/?hosted_button_id=CF7GJ7T6E4RS4">
<FormattedMessage <FormattedMessage id="footer.donations" defaultMessage="Donations" />
id="footer.donations"
defaultMessage="Donations"
/>
</a> </a>
</div> </div>
<div> <div>
<a href="http://www.wisemapping.org/"> <a href="http://www.wisemapping.org/">
<FormattedMessage <FormattedMessage id="footer.opensource" defaultMessage="Open Source" />
id="footer.opensource"
defaultMessage="Open Source"
/>
</a> </a>
</div> </div>
</div> </div>

View File

@ -19,10 +19,7 @@ export const Header = ({ type }: HeaderProps): React.ReactElement => {
text = ( text = (
<span className="header-area-content-span"> <span className="header-area-content-span">
<span> <span>
<FormattedMessage <FormattedMessage id="header.donthaveaccount" defaultMessage="Don't have an account ?" />
id="header.donthaveaccount"
defaultMessage="Don't have an account ?"
/>
</span> </span>
</span> </span>
); );
@ -31,10 +28,7 @@ export const Header = ({ type }: HeaderProps): React.ReactElement => {
text = ( text = (
<span className="header-area-content-span"> <span className="header-area-content-span">
<span> <span>
<FormattedMessage <FormattedMessage id="header.haveaccount" defaultMessage="Already have an account?" />
id="header.haveaccount"
defaultMessage="Already have an account?"
/>
</span> </span>
</span> </span>
); );

View File

@ -69,7 +69,10 @@ const LoginPage = (): React.ReactElement => {
const intl = useIntl(); const intl = useIntl();
useEffect(() => { useEffect(() => {
document.title = intl.formatMessage({ id: 'login.page-title', defaultMessage: 'Login | WiseMapping' }); document.title = intl.formatMessage({
id: 'login.page-title',
defaultMessage: 'Login | WiseMapping',
});
ReactGA.send({ hitType: 'pageview', page: window.location.pathname, title: 'Login' }); ReactGA.send({ hitType: 'pageview', page: window.location.pathname, title: 'Login' });
}, []); }, []);
@ -90,7 +93,7 @@ const LoginPage = (): React.ReactElement => {
<FormControl> <FormControl>
<form action="/c/perform-login" method="POST"> <form action="/c/perform-login" method="POST">
<input type='hidden' value={getCsrfToken()} name={getCsrfTokenParameter()} /> <input type="hidden" value={getCsrfToken()} name={getCsrfTokenParameter()} />
<Input <Input
name="username" name="username"
type="email" type="email"
@ -114,10 +117,7 @@ const LoginPage = (): React.ReactElement => {
<div> <div>
<input name="remember-me" id="remember-me" type="checkbox" /> <input name="remember-me" id="remember-me" type="checkbox" />
<label htmlFor="remember-me"> <label htmlFor="remember-me">
<FormattedMessage <FormattedMessage id="login.remberme" defaultMessage="Remember me" />
id="login.remberme"
defaultMessage="Remember me"
/>
</label> </label>
</div> </div>
<SubmitButton <SubmitButton

View File

@ -45,7 +45,7 @@ const AccountInfoDialog = ({ onClose }: AccountInfoDialogProps): React.ReactElem
onError: (error) => { onError: (error) => {
setError(error); setError(error);
}, },
} },
); );
const mutationRemove = useMutation<void, ErrorInfo, void>( const mutationRemove = useMutation<void, ErrorInfo, void>(
@ -60,7 +60,7 @@ const AccountInfoDialog = ({ onClose }: AccountInfoDialogProps): React.ReactElem
onError: (error) => { onError: (error) => {
setError(error); setError(error);
}, },
} },
); );
const account = fetchAccount(); const account = fetchAccount();
@ -168,7 +168,10 @@ const AccountInfoDialog = ({ onClose }: AccountInfoDialogProps): React.ReactElem
color="primary" color="primary"
/> />
} }
label={intl.formatMessage({ id: 'accountinfo.deleteaccount', defaultMessage: 'Delete Account' })} label={intl.formatMessage({
id: 'accountinfo.deleteaccount',
defaultMessage: 'Delete Account',
})}
/> />
</FormGroup> </FormGroup>
</FormControl> </FormControl>

View File

@ -35,7 +35,7 @@ const ChangePasswordDialog = ({ onClose }: ChangePasswordDialogProps): React.Rea
onError: (error) => { onError: (error) => {
setError(error); setError(error);
}, },
} },
); );
const handleOnClose = (): void => { const handleOnClose = (): void => {

View File

@ -83,7 +83,7 @@ const AccountMenu = (): React.ReactElement => {
</MenuItem> </MenuItem>
<MenuItem onClick={handleClose}> <MenuItem onClick={handleClose}>
<form action="/c/logout" method='POST' id="logoutFrom"></form> <form action="/c/logout" method="POST" id="logoutFrom"></form>
<Link color="textSecondary" href="/c/logout" onClick={(e) => handleLogout(e)}> <Link color="textSecondary" href="/c/logout" onClick={(e) => handleLogout(e)}>
<ListItemIcon> <ListItemIcon>
<ExitToAppOutlined fontSize="small" /> <ExitToAppOutlined fontSize="small" />
@ -92,11 +92,7 @@ const AccountMenu = (): React.ReactElement => {
</Link> </Link>
</MenuItem> </MenuItem>
</Menu> </Menu>
{ {action == 'change-password' && <ChangePasswordDialog onClose={() => setAction(undefined)} />}
action == 'change-password' && (
<ChangePasswordDialog onClose={() => setAction(undefined)} />
)
}
{action == 'account-info' && <AccountInfoDialog onClose={() => setAction(undefined)} />} {action == 'account-info' && <AccountInfoDialog onClose={() => setAction(undefined)} />}
</span> </span>
); );

View File

@ -44,7 +44,7 @@ const ActionChooser = (props: ActionProps): React.ReactElement => {
const { anchor, onClose, mapId } = props; const { anchor, onClose, mapId } = props;
const handleOnClose = ( const handleOnClose = (
action: ActionType action: ActionType,
): ((event: React.MouseEvent<HTMLLIElement>) => void) => { ): ((event: React.MouseEvent<HTMLLIElement>) => void) => {
return (event): void => { return (event): void => {
event.stopPropagation(); event.stopPropagation();

View File

@ -25,7 +25,7 @@ type AddLabelFormProps = {
const AddLabelDialog = ({ onAdd }: AddLabelFormProps): React.ReactElement => { const AddLabelDialog = ({ onAdd }: AddLabelFormProps): React.ReactElement => {
const intl = useIntl(); const intl = useIntl();
const [createLabelColorIndex, setCreateLabelColorIndex] = React.useState( const [createLabelColorIndex, setCreateLabelColorIndex] = React.useState(
Math.floor(Math.random() * labelColors.length) Math.floor(Math.random() * labelColors.length),
); );
const [newLabelTitle, setNewLabelTitle] = React.useState(''); const [newLabelTitle, setNewLabelTitle] = React.useState('');
@ -91,6 +91,6 @@ const AddLabelDialog = ({ onAdd }: AddLabelFormProps): React.ReactElement => {
</NewLabelContainer> </NewLabelContainer>
</CreateLabel> </CreateLabel>
); );
} };
export default AddLabelDialog; export default AddLabelDialog;

View File

@ -29,7 +29,7 @@ const BaseDialog = (props: DialogProps): React.ReactElement => {
useEffect(() => { useEffect(() => {
dispatch(disableHotkeys()); dispatch(disableHotkeys());
return () => { return () => {
dispatch(enableHotkeys()) dispatch(enableHotkeys());
}; };
}, []); }, []);
const { onClose, onSubmit, maxWidth = 'sm', PaperProps } = props; const { onClose, onSubmit, maxWidth = 'sm', PaperProps } = props;
@ -65,10 +65,7 @@ const BaseDialog = (props: DialogProps): React.ReactElement => {
<StyledDialogActions> <StyledDialogActions>
<Button type="button" color="primary" size="medium" onClick={onClose}> <Button type="button" color="primary" size="medium" onClick={onClose}>
{onSubmit ? ( {onSubmit ? (
<FormattedMessage <FormattedMessage id="action.cancel-button" defaultMessage="Cancel" />
id="action.cancel-button"
defaultMessage="Cancel"
/>
) : ( ) : (
<FormattedMessage id="action.close-button" defaultMessage="Close" /> <FormattedMessage id="action.close-button" defaultMessage="Close" />
)} )}

View File

@ -36,7 +36,7 @@ const CreateDialog = ({ onClose }: CreateProps): React.ReactElement => {
onError: (error) => { onError: (error) => {
setError(error); setError(error);
}, },
} },
); );
const handleOnClose = (): void => { const handleOnClose = (): void => {

View File

@ -30,8 +30,11 @@ const DeleteDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElement
mutation.mutate(mapId); mutation.mutate(mapId);
}; };
const { map } = fetchMapById(mapId) const { map } = fetchMapById(mapId);
const alertTitle = `${intl.formatMessage({ id: 'action.delete-title', defaultMessage: 'Delete' })} ${map?.title}`; const alertTitle = `${intl.formatMessage({
id: 'action.delete-title',
defaultMessage: 'Delete',
})} ${map?.title}`;
return ( return (
<div> <div>
<BaseDialog <BaseDialog

View File

@ -9,10 +9,7 @@ import BaseDialog from '../base-dialog';
import Alert from '@mui/material/Alert'; import Alert from '@mui/material/Alert';
import AlertTitle from '@mui/material/AlertTitle'; import AlertTitle from '@mui/material/AlertTitle';
const DeleteMultiselectDialog = ({ const DeleteMultiselectDialog = ({ onClose, mapsId }: MultiDialogProps): React.ReactElement => {
onClose,
mapsId,
}: MultiDialogProps): React.ReactElement => {
const intl = useIntl(); const intl = useIntl();
const client: Client = useSelector(activeInstance); const client: Client = useSelector(activeInstance);
const queryClient = useQueryClient(); const queryClient = useQueryClient();

View File

@ -36,7 +36,7 @@ const DuplicateDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElem
onError: (error) => { onError: (error) => {
setError(error); setError(error);
}, },
} },
); );
const handleOnClose = (): void => { const handleOnClose = (): void => {

View File

@ -10,7 +10,13 @@ import FormControlLabel from '@mui/material/FormControlLabel';
import Radio from '@mui/material/Radio'; import Radio from '@mui/material/Radio';
import Select from '@mui/material/Select'; import Select from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem'; import MenuItem from '@mui/material/MenuItem';
import { Designer, TextExporterFactory, ImageExporterFactory, Exporter, Mindmap } from '@wisemapping/mindplot'; import {
Designer,
TextExporterFactory,
ImageExporterFactory,
Exporter,
Mindmap,
} from '@wisemapping/mindplot';
import Client from '../../../../classes/client'; import Client from '../../../../classes/client';
import { activeInstance } from '../../../../redux/clientSlice'; import { activeInstance } from '../../../../redux/clientSlice';
@ -31,7 +37,7 @@ type ExportDialogProps = {
const ExportDialog = ({ const ExportDialog = ({
mapId, mapId,
onClose, onClose,
enableImgExport enableImgExport,
}: ExportDialogProps): React.ReactElement => { }: ExportDialogProps): React.ReactElement => {
const intl = useIntl(); const intl = useIntl();
const [submit, setSubmit] = React.useState<boolean>(false); const [submit, setSubmit] = React.useState<boolean>(false);
@ -39,13 +45,13 @@ const ExportDialog = ({
const client: Client = useSelector(activeInstance); const client: Client = useSelector(activeInstance);
const [exportGroup, setExportGroup] = React.useState<ExportGroup>( const [exportGroup, setExportGroup] = React.useState<ExportGroup>(
enableImgExport ? 'image' : 'document' enableImgExport ? 'image' : 'document',
); );
const [exportFormat, setExportFormat] = React.useState<ExportFormat>( const [exportFormat, setExportFormat] = React.useState<ExportFormat>(
enableImgExport ? 'svg' : 'txt' enableImgExport ? 'svg' : 'txt',
); );
const [zoomToFit, setZoomToFit] = React.useState<boolean>(true) const [zoomToFit, setZoomToFit] = React.useState<boolean>(true);
const classes = useStyles(); const classes = useStyles();
@ -105,7 +111,13 @@ const ExportDialog = ({
case 'png': case 'png':
case 'jpg': case 'jpg':
case 'svg': { case 'svg': {
exporter = ImageExporterFactory.create(formatType, svgElement, size.width, size.height, zoomToFit); exporter = ImageExporterFactory.create(
formatType,
svgElement,
size.width,
size.height,
zoomToFit,
);
break; break;
} }
case 'wxml': case 'wxml':
@ -139,8 +151,9 @@ const ExportDialog = ({
// Clean up ... // Clean up ...
URL.revokeObjectURL(url); URL.revokeObjectURL(url);
document.body.removeChild(anchor); document.body.removeChild(anchor);
}).catch((fail) => { })
console.error("Unexpected error during export:" + fail); .catch((fail) => {
console.error('Unexpected error during export:' + fail);
}); });
onClose(); onClose();
@ -153,18 +166,21 @@ const ExportDialog = ({
onClose={handleOnClose} onClose={handleOnClose}
onSubmit={handleOnSubmit} onSubmit={handleOnSubmit}
title={intl.formatMessage({ id: 'export.title', defaultMessage: 'Export' })} title={intl.formatMessage({ id: 'export.title', defaultMessage: 'Export' })}
description={intl.formatMessage({ id: 'export.desc', defaultMessage: 'Export this map in the format that you want and start using it in your presentations or sharing by email' })} description={intl.formatMessage({
id: 'export.desc',
defaultMessage:
'Export this map in the format that you want and start using it in your presentations or sharing by email',
})}
submitButton={intl.formatMessage({ id: 'export.title', defaultMessage: 'Export' })} submitButton={intl.formatMessage({ id: 'export.title', defaultMessage: 'Export' })}
> >
{ {!enableImgExport && (
!enableImgExport &&
<Alert severity="info"> <Alert severity="info">
<FormattedMessage <FormattedMessage
id="export.warning" id="export.warning"
defaultMessage="Exporting to Image (SVG,PNG,JPEG,PDF) is only available in the editor toolbar." defaultMessage="Exporting to Image (SVG,PNG,JPEG,PDF) is only available in the editor toolbar."
/> />
</Alert> </Alert>
} )}
<FormControl component="fieldset"> <FormControl component="fieldset">
<RadioGroup name="export" value={exportGroup} onChange={handleOnGroupChange}> <RadioGroup name="export" value={exportGroup} onChange={handleOnGroupChange}>
<FormControl> <FormControl>
@ -204,9 +220,9 @@ const ExportDialog = ({
control={<Checkbox checked={zoomToFit} onChange={handleOnZoomToFit} />} control={<Checkbox checked={zoomToFit} onChange={handleOnZoomToFit} />}
label={intl.formatMessage({ label={intl.formatMessage({
id: 'export.img-center', id: 'export.img-center',
defaultMessage: defaultMessage: 'Center and zoom to fit',
'Center and zoom to fit', })}
})} /> />
</> </>
)} )}
</FormControl> </FormControl>

View File

@ -57,16 +57,10 @@ const HistoryDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElemen
<TableHead> <TableHead>
<TableRow> <TableRow>
<TableCell align="left"> <TableCell align="left">
<FormattedMessage <FormattedMessage id="maps.modified-by" defaultMessage="Modified By" />
id="maps.modified-by"
defaultMessage="Modified By"
/>
</TableCell> </TableCell>
<TableCell align="left"> <TableCell align="left">
<FormattedMessage <FormattedMessage id="maps.modified" defaultMessage="Modified" />
id="maps.modified"
defaultMessage="Modified"
/>
</TableCell> </TableCell>
<TableCell align="left"></TableCell> <TableCell align="left"></TableCell>
<TableCell align="left"></TableCell> <TableCell align="left"></TableCell>
@ -88,35 +82,20 @@ const HistoryDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElemen
<TableCell align="left">{row.lastModificationBy}</TableCell> <TableCell align="left">{row.lastModificationBy}</TableCell>
<TableCell align="left"> <TableCell align="left">
<Tooltip <Tooltip
title={dayjs(row.lastModificationTime).format( title={dayjs(row.lastModificationTime).format('lll')}
'lll'
)}
placement="bottom-start" placement="bottom-start"
> >
<span> <span>{dayjs(row.lastModificationTime).fromNow()}</span>
{dayjs(row.lastModificationTime).fromNow()}
</span>
</Tooltip> </Tooltip>
</TableCell> </TableCell>
<TableCell align="left"> <TableCell align="left">
<Link <Link href={`/c/maps/${mapId}/${row.id}/view`} target="history">
href={`/c/maps/${mapId}/${row.id}/view`} <FormattedMessage id="maps.view" defaultMessage="View" />
target="history"
>
<FormattedMessage
id="maps.view"
defaultMessage="View"
/>
</Link> </Link>
</TableCell> </TableCell>
<TableCell align="left"> <TableCell align="left">
<Link <Link href="#" onClick={(e) => handleOnClick(e, row.id)}>
href="#" <FormattedMessage id="maps.revert" defaultMessage="Revert" />
onClick={(e) => handleOnClick(e, row.id)}>
<FormattedMessage
id="maps.revert"
defaultMessage="Revert"
/>
</Link> </Link>
</TableCell> </TableCell>
</TableRow> </TableRow>

View File

@ -26,7 +26,7 @@ export type CreateProps = {
type ErrorFile = { type ErrorFile = {
error: boolean; error: boolean;
message: string; message: string;
} };
const defaultModel: ImportModel = { title: '' }; const defaultModel: ImportModel = { title: '' };
const ImportDialog = ({ onClose }: CreateProps): React.ReactElement => { const ImportDialog = ({ onClose }: CreateProps): React.ReactElement => {
@ -47,7 +47,7 @@ const ImportDialog = ({ onClose }: CreateProps): React.ReactElement => {
onError: (error) => { onError: (error) => {
setError(error); setError(error);
}, },
} },
); );
const handleOnClose = (): void => { const handleOnClose = (): void => {
@ -92,40 +92,45 @@ const ImportDialog = ({ onClose }: CreateProps): React.ReactElement => {
if (!extensionAccept.includes(extensionFile)) { if (!extensionAccept.includes(extensionFile)) {
setErrorFile({ setErrorFile({
error: true, error: true,
message: intl.formatMessage({ message: intl.formatMessage(
{
id: 'import.error-file', id: 'import.error-file',
defaultMessage: 'Import error {error}', defaultMessage: 'Import error {error}',
}, },
{ {
error: 'You can import WiseMapping and Freemind maps to your list of maps. Select the file you want to import.' error:
}) 'You can import WiseMapping and Freemind maps to your list of maps. Select the file you want to import.',
},
),
}); });
} }
model.contentType = 'application/xml' model.contentType = 'application/xml';
const fileContent = event?.target?.result; const fileContent = event?.target?.result;
const mapConent: string = typeof fileContent === 'string' ? fileContent : fileContent.toString(); const mapConent: string =
typeof fileContent === 'string' ? fileContent : fileContent.toString();
try { try {
const importer: Importer = TextImporterFactory.create(extensionFile, mapConent) const importer: Importer = TextImporterFactory.create(extensionFile, mapConent);
importer.import(model.title, model.description) importer.import(model.title, model.description).then((res) => {
.then(res => {
model.content = res; model.content = res;
setModel({ ...model }); setModel({ ...model });
}) });
} catch (e) { } catch (e) {
if (e instanceof Error) { if (e instanceof Error) {
setErrorFile({ setErrorFile({
error: true, error: true,
message: intl.formatMessage({ message: intl.formatMessage(
{
id: 'import.error-file', id: 'import.error-file',
defaultMessage: 'Import error {error}', defaultMessage: 'Import error {error}',
}, },
{ {
error: e.message error: e.message,
}) },
),
}); });
} }
} }
@ -153,11 +158,11 @@ const ImportDialog = ({ onClose }: CreateProps): React.ReactElement => {
})} })}
submitButton={intl.formatMessage({ id: 'import.button', defaultMessage: 'Create' })} submitButton={intl.formatMessage({ id: 'import.button', defaultMessage: 'Create' })}
> >
{errorFile.error && {errorFile.error && (
<Alert severity='error'> <Alert severity="error">
<p>{errorFile.message}</p> <p>{errorFile.message}</p>
</Alert> </Alert>
} )}
<FormControl fullWidth={true}> <FormControl fullWidth={true}>
<input <input
accept=".wxml,.mm" accept=".wxml,.mm"
@ -201,10 +206,7 @@ const ImportDialog = ({ onClose }: CreateProps): React.ReactElement => {
component="span" component="span"
style={{ margin: '10px 5px', width: '100%' }} style={{ margin: '10px 5px', width: '100%' }}
> >
<FormattedMessage <FormattedMessage id="maps.choose-file" defaultMessage="Choose a file" />
id="maps.choose-file"
defaultMessage="Choose a file"
/>
</Button> </Button>
</label> </label>
</FormControl> </FormControl>

View File

@ -15,7 +15,6 @@ import ShareDialog from './share-dialog';
import LabelDialog from './label-dialog'; import LabelDialog from './label-dialog';
import ReactGA from 'react-ga4'; import ReactGA from 'react-ga4';
export type BasicMapInfo = { export type BasicMapInfo = {
name: string; name: string;
description: string | undefined; description: string | undefined;
@ -28,14 +27,17 @@ type ActionDialogProps = {
fromEditor: boolean; fromEditor: boolean;
}; };
const ActionDispatcher = ({ mapsId, action, onClose, fromEditor }: ActionDialogProps): React.ReactElement => { const ActionDispatcher = ({
mapsId,
action,
onClose,
fromEditor,
}: ActionDialogProps): React.ReactElement => {
useEffect(() => { useEffect(() => {
ReactGA.event({ ReactGA.event({
category: 'map metadata', category: 'map metadata',
action: action, action: action,
nonInteraction: true nonInteraction: true,
}); });
}, [action]); }, [action]);
@ -62,9 +64,7 @@ const ActionDispatcher = ({ mapsId, action, onClose, fromEditor }: ActionDialogP
<DeleteMultiselectDialog onClose={handleOnClose} mapsId={mapsId} /> <DeleteMultiselectDialog onClose={handleOnClose} mapsId={mapsId} />
)} )}
{action === 'rename' && <RenameDialog onClose={handleOnClose} mapId={mapsId[0]} />} {action === 'rename' && <RenameDialog onClose={handleOnClose} mapId={mapsId[0]} />}
{action === 'duplicate' && ( {action === 'duplicate' && <DuplicateDialog onClose={handleOnClose} mapId={mapsId[0]} />}
<DuplicateDialog onClose={handleOnClose} mapId={mapsId[0]} />
)}
{action === 'history' && <HistoryDialog onClose={handleOnClose} mapId={mapsId[0]} />} {action === 'history' && <HistoryDialog onClose={handleOnClose} mapId={mapsId[0]} />}
{action === 'import' && <ImportDialog onClose={handleOnClose} />} {action === 'import' && <ImportDialog onClose={handleOnClose} />}
{action === 'publish' && <PublishDialog onClose={handleOnClose} mapId={mapsId[0]} />} {action === 'publish' && <PublishDialog onClose={handleOnClose} mapId={mapsId[0]} />}

View File

@ -14,10 +14,8 @@ import Typography from '@mui/material/Typography';
import List from '@mui/material/List'; import List from '@mui/material/List';
import LocalizedFormat from 'dayjs/plugin/localizedFormat'; import LocalizedFormat from 'dayjs/plugin/localizedFormat';
// Load fromNow pluggin // Load fromNow pluggin
dayjs.extend(LocalizedFormat) dayjs.extend(LocalizedFormat);
const InfoDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElement => { const InfoDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElement => {
const { map } = fetchMapById(mapId); const { map } = fetchMapById(mapId);
@ -38,8 +36,7 @@ const InfoDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElement =
title={intl.formatMessage({ id: 'info.title', defaultMessage: 'Info' })} title={intl.formatMessage({ id: 'info.title', defaultMessage: 'Info' })}
description={intl.formatMessage({ description={intl.formatMessage({
id: 'info.description-msg', id: 'info.description-msg',
defaultMessage: defaultMessage: 'By publishing the map you make it visible to everyone on the Internet.',
'By publishing the map you make it visible to everyone on the Internet.',
})} })}
submitButton={intl.formatMessage({ id: 'info.button', defaultMessage: 'Accept' })} submitButton={intl.formatMessage({ id: 'info.button', defaultMessage: 'Accept' })}
> >
@ -48,93 +45,48 @@ const InfoDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElement =
<List dense={true}> <List dense={true}>
<ListItem> <ListItem>
<Typography variant="body1" style={{ fontWeight: 'bold' }}> <Typography variant="body1" style={{ fontWeight: 'bold' }}>
<FormattedMessage <FormattedMessage id="info.basic-info" defaultMessage="Basic Info" />
id="info.basic-info"
defaultMessage="Basic Info"
/>
</Typography> </Typography>
</ListItem> </ListItem>
<ListItem> <ListItem>
<Typography <Typography variant="caption" color="textPrimary" className={classes.textDesc}>
variant="caption"
color="textPrimary"
className={classes.textDesc}
>
<FormattedMessage id="info.name" defaultMessage="Name" />: <FormattedMessage id="info.name" defaultMessage="Name" />:
</Typography> </Typography>
<Typography variant="body2">{map?.title}</Typography> <Typography variant="body2">{map?.title}</Typography>
</ListItem> </ListItem>
<ListItem> <ListItem>
<Typography <Typography variant="caption" color="textPrimary" className={classes.textDesc}>
variant="caption" <FormattedMessage id="info.description" defaultMessage="Description" />:
color="textPrimary"
className={classes.textDesc}
>
<FormattedMessage
id="info.description"
defaultMessage="Description"
/>
:
</Typography> </Typography>
<Typography variant="body2">{map?.description}</Typography> <Typography variant="body2">{map?.description}</Typography>
</ListItem> </ListItem>
<ListItem> <ListItem>
<Typography <Typography variant="caption" color="textPrimary" className={classes.textDesc}>
variant="caption"
color="textPrimary"
className={classes.textDesc}
>
<FormattedMessage id="info.creator" defaultMessage="Creator" />: <FormattedMessage id="info.creator" defaultMessage="Creator" />:
</Typography> </Typography>
<Typography variant="body2">{map?.createdBy}</Typography> <Typography variant="body2">{map?.createdBy}</Typography>
</ListItem> </ListItem>
<ListItem> <ListItem>
<Typography <Typography variant="caption" color="textPrimary" className={classes.textDesc}>
variant="caption" <FormattedMessage id="info.creation-time" defaultMessage="Creation Date" />:
color="textPrimary"
className={classes.textDesc}
>
<FormattedMessage
id="info.creation-time"
defaultMessage="Creation Date"
/>
:
</Typography>
<Typography variant="body2">
{dayjs(map?.creationTime).format('LLL')}
</Typography> </Typography>
<Typography variant="body2">{dayjs(map?.creationTime).format('LLL')}</Typography>
</ListItem> </ListItem>
<ListItem> <ListItem>
<Typography <Typography variant="caption" color="textPrimary" className={classes.textDesc}>
variant="caption" <FormattedMessage id="info.modified-tny" defaultMessage="Last Modified By" />:
color="textPrimary"
className={classes.textDesc}
>
<FormattedMessage
id="info.modified-tny"
defaultMessage="Last Modified By"
/>
:
</Typography> </Typography>
<Typography variant="body2">{map?.lastModificationBy}</Typography> <Typography variant="body2">{map?.lastModificationBy}</Typography>
</ListItem> </ListItem>
<ListItem> <ListItem>
<Typography <Typography variant="caption" color="textPrimary" className={classes.textDesc}>
variant="caption" <FormattedMessage id="info.modified-time" defaultMessage="Last Modified Date" />:
color="textPrimary"
className={classes.textDesc}
>
<FormattedMessage
id="info.modified-time"
defaultMessage="Last Modified Date"
/>
:
</Typography> </Typography>
<Typography variant="body2"> <Typography variant="body2">
{dayjs(map?.lastModificationTime).format('LLL')} {dayjs(map?.lastModificationTime).format('LLL')}
@ -142,16 +94,10 @@ const InfoDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElement =
</ListItem> </ListItem>
<ListItem> <ListItem>
<Typography <Typography variant="caption" color="textPrimary" className={classes.textDesc}>
variant="caption"
color="textPrimary"
className={classes.textDesc}
>
<FormattedMessage id="info.starred" defaultMessage="Starred" />: <FormattedMessage id="info.starred" defaultMessage="Starred" />:
</Typography> </Typography>
<Typography variant="body2"> <Typography variant="body2">{Boolean(map?.starred).toString()}</Typography>
{Boolean(map?.starred).toString()}
</Typography>
</ListItem> </ListItem>
</List> </List>
</Card> </Card>
@ -165,16 +111,8 @@ const InfoDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElement =
</ListItem> </ListItem>
</List> </List>
<ListItem> <ListItem>
<Typography <Typography variant="caption" color="textPrimary" className={classes.textDesc}>
variant="caption" <FormattedMessage id="info.public-visibility" defaultMessage="Publicly Visible" />:
color="textPrimary"
className={classes.textDesc}
>
<FormattedMessage
id="info.public-visibility"
defaultMessage="Publicly Visible"
/>
:
</Typography> </Typography>
<Typography variant="body2">{Boolean(map?.isPublic).toString()}</Typography> <Typography variant="body2">{Boolean(map?.isPublic).toString()}</Typography>
</ListItem> </ListItem>

View File

@ -12,7 +12,6 @@ import { LabelSelector } from '../../maps-list/label-selector';
import { activeInstance } from '../../../../redux/clientSlice'; import { activeInstance } from '../../../../redux/clientSlice';
import { ChangeLabelMutationFunctionParam, getChangeLabelMutationFunction } from '../../maps-list'; import { ChangeLabelMutationFunctionParam, getChangeLabelMutationFunction } from '../../maps-list';
const LabelDialog = ({ mapsId, onClose }: MultiDialogProps): React.ReactElement => { const LabelDialog = ({ mapsId, onClose }: MultiDialogProps): React.ReactElement => {
const intl = useIntl(); const intl = useIntl();
const classes = useStyles(); const classes = useStyles();
@ -25,27 +24,29 @@ const LabelDialog = ({ mapsId, onClose }: MultiDialogProps): React.ReactElement
}); });
const [error, setError] = React.useState<ErrorInfo>(); const [error, setError] = React.useState<ErrorInfo>();
const maps = data.filter(m => mapsId.includes(m.id)); const maps = data.filter((m) => mapsId.includes(m.id));
const changeLabelMutation = useMutation<void, ErrorInfo, ChangeLabelMutationFunctionParam, number>( const changeLabelMutation = useMutation<
getChangeLabelMutationFunction(client), void,
{ ErrorInfo,
ChangeLabelMutationFunctionParam,
number
>(getChangeLabelMutationFunction(client), {
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries('maps'); queryClient.invalidateQueries('maps');
queryClient.invalidateQueries('labels'); queryClient.invalidateQueries('labels');
}, },
onError: (error) => { onError: (error) => {
setError(error); setError(error);
} },
} });
);
const handleChangesInLabels = (label: Label, checked: boolean) => { const handleChangesInLabels = (label: Label, checked: boolean) => {
setError(undefined); setError(undefined);
changeLabelMutation.mutate({ changeLabelMutation.mutate({
maps, maps,
label, label,
checked checked,
}); });
}; };
@ -59,8 +60,7 @@ const LabelDialog = ({ mapsId, onClose }: MultiDialogProps): React.ReactElement
})} })}
description={intl.formatMessage({ description={intl.formatMessage({
id: 'label.description', id: 'label.description',
defaultMessage: defaultMessage: 'Use labels to organize your maps.',
'Use labels to organize your maps.',
})} })}
PaperProps={{ classes: { root: classes.paper } }} PaperProps={{ classes: { root: classes.paper } }}
error={error} error={error}
@ -68,19 +68,21 @@ const LabelDialog = ({ mapsId, onClose }: MultiDialogProps): React.ReactElement
<> <>
<Typography variant="body2" marginTop="10px"> <Typography variant="body2" marginTop="10px">
<FormattedMessage id="label.add-for" defaultMessage="Editing labels for " /> <FormattedMessage id="label.add-for" defaultMessage="Editing labels for " />
{ {maps.length > 1 ? (
maps.length > 1 ? <FormattedMessage
<FormattedMessage id="label.maps-count" id="label.maps-count"
defaultMessage="{count} maps" defaultMessage="{count} maps"
values={{ count: maps.length }} values={{ count: maps.length }}
/> : />
maps.map(m => m.title).join(', ') ) : (
} maps.map((m) => m.title).join(', ')
)}
</Typography> </Typography>
<LabelSelector onChange={handleChangesInLabels} maps={maps} /> <LabelSelector onChange={handleChangesInLabels} maps={maps} />
</> </>
</BaseDialog> </BaseDialog>
</div>); </div>
);
}; };
export default LabelDialog; export default LabelDialog;

View File

@ -42,7 +42,7 @@ const PublishDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElemen
onError: (error) => { onError: (error) => {
setError(error); setError(error);
}, },
} },
); );
const handleOnClose = (): void => { const handleOnClose = (): void => {
@ -74,8 +74,7 @@ const PublishDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElemen
title={intl.formatMessage({ id: 'publish.title', defaultMessage: 'Publish' })} title={intl.formatMessage({ id: 'publish.title', defaultMessage: 'Publish' })}
description={intl.formatMessage({ description={intl.formatMessage({
id: 'publish.description', id: 'publish.description',
defaultMessage: defaultMessage: 'By publishing the map you make it visible to everyone on the Internet.',
'By publishing the map you make it visible to everyone on the Internet.',
})} })}
submitButton={intl.formatMessage({ submitButton={intl.formatMessage({
id: 'publish.button', id: 'publish.button',
@ -85,12 +84,7 @@ const PublishDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElemen
<FormControl fullWidth={true}> <FormControl fullWidth={true}>
<FormControlLabel <FormControlLabel
control={ control={
<Checkbox <Checkbox checked={model} onChange={handleOnChange} name="public" color="primary" />
checked={model}
onChange={handleOnChange}
name="public"
color="primary"
/>
} }
label={intl.formatMessage({ label={intl.formatMessage({
id: 'publish.checkbox', id: 'publish.checkbox',

View File

@ -36,7 +36,7 @@ const RenameDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElement
onError: (error) => { onError: (error) => {
setError(error); setError(error);
}, },
} },
); );
const handleOnClose = (): void => { const handleOnClose = (): void => {

View File

@ -53,15 +53,15 @@ const ShareDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElement
onError: (error: ErrorInfo) => { onError: (error: ErrorInfo) => {
setError(error); setError(error);
}, },
} },
); );
const splitEmail = (emails: string): string[] => { const splitEmail = (emails: string): string[] => {
return emails.split(/,|;/) return emails
.map(e => e.trim().replace(/\s/g, '')) .split(/,|;/)
.filter(e => e.trim().length > 0); .map((e) => e.trim().replace(/\s/g, ''))
} .filter((e) => e.trim().length > 0);
};
const addMutation = useMutation( const addMutation = useMutation(
(model: ShareModel) => { (model: ShareModel) => {
@ -79,14 +79,13 @@ const ShareDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElement
onError: (error: ErrorInfo) => { onError: (error: ErrorInfo) => {
setError(error); setError(error);
}, },
} },
); );
const handleOnClose = (): void => { const handleOnClose = (): void => {
// Invalidate cache ... // Invalidate cache ...
queryClient.invalidateQueries(`perm-${mapId}`); queryClient.invalidateQueries(`perm-${mapId}`);
onClose(); onClose();
}; };
const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>): void => { const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
@ -106,16 +105,17 @@ const ShareDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElement
const handleOnDeleteClick = ( const handleOnDeleteClick = (
event: React.MouseEvent<HTMLButtonElement, MouseEvent>, event: React.MouseEvent<HTMLButtonElement, MouseEvent>,
email: string email: string,
): void => { ): void => {
event.stopPropagation(); event.stopPropagation();
deleteMutation.mutate(email); deleteMutation.mutate(email);
}; };
const { isLoading, data: permissions = [] } = useQuery<unknown, ErrorInfo, Permission[]>(`perm-${mapId}`, const { isLoading, data: permissions = [] } = useQuery<unknown, ErrorInfo, Permission[]>(
`perm-${mapId}`,
() => { () => {
return client.fetchMapPermissions(mapId); return client.fetchMapPermissions(mapId);
} },
); );
const formatName = (perm: Permission): string => { const formatName = (perm: Permission): string => {
@ -123,9 +123,7 @@ const ShareDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElement
}; };
// very basic email validation, just make sure the basic syntax is fine // very basic email validation, just make sure the basic syntax is fine
const isValid = splitEmail(model.emails) const isValid = splitEmail(model.emails).every((str) => /\S+@\S+\.\S+/.test((str || '').trim()));
.every(str => /\S+@\S+\.\S+/.test((str || '')
.trim()));
return ( return (
<div> <div>
@ -182,10 +180,7 @@ const ShareDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElement
control={<Checkbox color="primary" />} control={<Checkbox color="primary" />}
label={ label={
<Typography variant="subtitle2"> <Typography variant="subtitle2">
<FormattedMessage <FormattedMessage id="share.add-message" defaultMessage="Add message" />
id="share.add-message"
defaultMessage="Add message"
/>
</Typography> </Typography>
} }
labelPlacement="end" labelPlacement="end"
@ -226,16 +221,8 @@ const ShareDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElement
{permissions && {permissions &&
permissions.map((permission) => { permissions.map((permission) => {
return ( return (
<ListItem <ListItem key={permission.email} role={undefined} dense button>
key={permission.email} <ListItemText id={permission.email} primary={formatName(permission)} />
role={undefined}
dense
button
>
<ListItemText
id={permission.email}
primary={formatName(permission)}
/>
<RoleIcon role={permission.role} /> <RoleIcon role={permission.role} />
<ListItemSecondaryAction> <ListItemSecondaryAction>
@ -250,10 +237,9 @@ const ShareDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElement
<IconButton <IconButton
edge="end" edge="end"
disabled={permission.role == 'owner'} disabled={permission.role == 'owner'}
onClick={(e) => onClick={(e) => handleOnDeleteClick(e, permission.email)}
handleOnDeleteClick(e, permission.email) size="large"
} >
size="large">
<DeleteIcon /> <DeleteIcon />
</IconButton> </IconButton>
</Tooltip> </Tooltip>

View File

@ -60,10 +60,7 @@ const HelpMenu = (): React.ReactElement => {
<ListItemIcon> <ListItemIcon>
<PolicyOutlined fontSize="small" /> <PolicyOutlined fontSize="small" />
</ListItemIcon> </ListItemIcon>
<FormattedMessage <FormattedMessage id="footer.termsandconditions" defaultMessage="Term And Conditions" />
id="footer.termsandconditions"
defaultMessage="Term And Conditions"
/>
</Link> </Link>
</MenuItem> </MenuItem>
@ -86,11 +83,7 @@ const HelpMenu = (): React.ReactElement => {
</MenuItem> </MenuItem>
<MenuItem onClick={handleClose}> <MenuItem onClick={handleClose}>
<Link <Link color="textSecondary" href="https://www.wisemapping.com/aboutus.html" target="help">
color="textSecondary"
href="https://www.wisemapping.com/aboutus.html"
target="help"
>
<ListItemIcon> <ListItemIcon>
<EmojiPeopleOutlined fontSize="small" /> <EmojiPeopleOutlined fontSize="small" />
</ListItemIcon> </ListItemIcon>

View File

@ -135,8 +135,7 @@ const HelpUsToTranslateDialog = ({ onClose }: HelpUsToTranslateDialogProp) => {
<DialogTitle>Help us to support more languages !</DialogTitle> <DialogTitle>Help us to support more languages !</DialogTitle>
<DialogContent> <DialogContent>
<DialogContentText> <DialogContentText>
We need your help !. If you are interested, send us an email to We need your help !. If you are interested, send us an email to team@wisemapping.com.
team@wisemapping.com.
</DialogContentText> </DialogContentText>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>

View File

@ -57,10 +57,10 @@ type Order = 'asc' | 'desc';
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
function getComparator<Key extends keyof any>( function getComparator<Key extends keyof any>(
order: Order, order: Order,
orderBy: Key orderBy: Key,
): ( ): (
a: { [key in Key]: number | string | boolean | Label[] | undefined }, a: { [key in Key]: number | string | boolean | Label[] | undefined },
b: { [key in Key]: number | string | Label[] | boolean } b: { [key in Key]: number | string | Label[] | boolean },
) => number { ) => number {
return order === 'desc' return order === 'desc'
? (a, b) => descendingComparator(a, b, orderBy) ? (a, b) => descendingComparator(a, b, orderBy)
@ -97,8 +97,7 @@ interface EnhancedTableProps {
function EnhancedTableHead(props: EnhancedTableProps) { function EnhancedTableHead(props: EnhancedTableProps) {
const intl = useIntl(); const intl = useIntl();
const { classes, onSelectAllClick, order, orderBy, numSelected, rowCount, onRequestSort } = const { classes, onSelectAllClick, order, orderBy, numSelected, rowCount, onRequestSort } = props;
props;
const createSortHandler = (property: keyof MapInfo) => (event: React.MouseEvent<unknown>) => { const createSortHandler = (property: keyof MapInfo) => (event: React.MouseEvent<unknown>) => {
onRequestSort(event, property); onRequestSort(event, property);
@ -146,11 +145,7 @@ function EnhancedTableHead(props: EnhancedTableProps) {
/> />
</TableCell> </TableCell>
<TableCell <TableCell padding="checkbox" key="starred" className={classes.headerCell}></TableCell>
padding="checkbox"
key="starred"
className={classes.headerCell}
></TableCell>
{headCells.map((headCell) => { {headCells.map((headCell) => {
return ( return (
@ -169,9 +164,7 @@ function EnhancedTableHead(props: EnhancedTableProps) {
{orderBy === headCell.id && ( {orderBy === headCell.id && (
<span className={classes.visuallyHidden}> <span className={classes.visuallyHidden}>
{order === 'desc' {order === 'desc' ? 'sorted descending' : 'sorted ascending'}
? 'sorted descending'
: 'sorted ascending'}
</span> </span>
)} )}
</TableSortLabel> </TableSortLabel>
@ -179,11 +172,7 @@ function EnhancedTableHead(props: EnhancedTableProps) {
); );
})} })}
<TableCell <TableCell padding="checkbox" key="action" className={classes.headerCell}></TableCell>
padding="checkbox"
key="action"
className={classes.headerCell}
></TableCell>
</TableRow> </TableRow>
</TableHead> </TableHead>
); );
@ -286,7 +275,7 @@ export const MapsList = (props: MapsListProps): React.ReactElement => {
const mapsInfo: MapInfo[] = data ? data.filter(mapsFilter(filter, searchCondition)) : []; const mapsInfo: MapInfo[] = data ? data.filter(mapsFilter(filter, searchCondition)) : [];
const [activeRowAction, setActiveRowAction] = React.useState<ActionPanelState | undefined>( const [activeRowAction, setActiveRowAction] = React.useState<ActionPanelState | undefined>(
undefined undefined,
); );
type ActiveDialog = { type ActiveDialog = {
@ -323,7 +312,7 @@ export const MapsList = (props: MapsListProps): React.ReactElement => {
} else if (selectedIndex > 0) { } else if (selectedIndex > 0) {
newSelected = newSelected.concat( newSelected = newSelected.concat(
selected.slice(0, selectedIndex), selected.slice(0, selectedIndex),
selected.slice(selectedIndex + 1) selected.slice(selectedIndex + 1),
); );
} }
@ -371,7 +360,7 @@ export const MapsList = (props: MapsListProps): React.ReactElement => {
queryClient.invalidateQueries('maps'); queryClient.invalidateQueries('maps');
console.error(error); console.error(error);
}, },
} },
); );
const handleStarred = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>, id: number) => { const handleStarred = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>, id: number) => {
@ -425,7 +414,7 @@ export const MapsList = (props: MapsListProps): React.ReactElement => {
onError: (error) => { onError: (error) => {
console.error(error); console.error(error);
}, },
} },
); );
const handleRemoveLabel = (mapId: number, labelId: number) => { const handleRemoveLabel = (mapId: number, labelId: number) => {
@ -484,10 +473,7 @@ export const MapsList = (props: MapsListProps): React.ReactElement => {
startIcon={<LabelTwoTone />} startIcon={<LabelTwoTone />}
onClick={handleAddLabelClick} onClick={handleAddLabelClick}
> >
<FormattedMessage <FormattedMessage id="action.label" defaultMessage="Add Label" />
id="action.label"
defaultMessage="Add Label"
/>
</Button> </Button>
</Tooltip> </Tooltip>
)} )}
@ -569,10 +555,7 @@ export const MapsList = (props: MapsListProps): React.ReactElement => {
selected={isItemSelected} selected={isItemSelected}
style={{ border: '0' }} style={{ border: '0' }}
> >
<TableCell <TableCell padding="checkbox" className={classes.bodyCell}>
padding="checkbox"
className={classes.bodyCell}
>
<Checkbox <Checkbox
checked={isItemSelected} checked={isItemSelected}
inputProps={{ inputProps={{
@ -582,10 +565,7 @@ export const MapsList = (props: MapsListProps): React.ReactElement => {
/> />
</TableCell> </TableCell>
<TableCell <TableCell padding="checkbox" className={classes.bodyCell}>
padding="checkbox"
className={classes.bodyCell}
>
<Tooltip <Tooltip
arrow={true} arrow={true}
title={intl.formatMessage({ title={intl.formatMessage({
@ -593,18 +573,11 @@ export const MapsList = (props: MapsListProps): React.ReactElement => {
defaultMessage: 'Starred', defaultMessage: 'Starred',
})} })}
> >
<IconButton <IconButton size="small" onClick={(e) => handleStarred(e, row.id)}>
size="small"
onClick={(e) =>
handleStarred(e, row.id)
}
>
<StarRateRoundedIcon <StarRateRoundedIcon
color="action" color="action"
style={{ style={{
color: row.starred color: row.starred ? 'yellow' : 'gray',
? 'yellow'
: 'gray',
}} }}
/> />
</IconButton> </IconButton>
@ -640,9 +613,7 @@ export const MapsList = (props: MapsListProps): React.ReactElement => {
/> />
</TableCell> </TableCell>
<TableCell className={classes.bodyCell}> <TableCell className={classes.bodyCell}>{row.createdBy}</TableCell>
{row.createdBy}
</TableCell>
<TableCell className={classes.bodyCell}> <TableCell className={classes.bodyCell}>
<Tooltip <Tooltip
@ -650,23 +621,16 @@ export const MapsList = (props: MapsListProps): React.ReactElement => {
title={intl.formatMessage( title={intl.formatMessage(
{ {
id: 'maps.modified-by-desc', id: 'maps.modified-by-desc',
defaultMessage: defaultMessage: 'Modified by {by} on {on}',
'Modified by {by} on {on}',
}, },
{ {
by: row.lastModificationBy, by: row.lastModificationBy,
on: dayjs( on: dayjs(row.lastModificationTime).format('lll'),
row.lastModificationTime },
).format('lll'),
}
)} )}
placement="bottom-start" placement="bottom-start"
> >
<span> <span>{dayjs(row.lastModificationTime).fromNow()}</span>
{dayjs(
row.lastModificationTime
).fromNow()}
</span>
</Tooltip> </Tooltip>
</TableCell> </TableCell>

View File

@ -13,7 +13,11 @@ export type LabelDeleteConfirmType = {
onConfirm: () => void; onConfirm: () => void;
}; };
const LabelDeleteConfirm = ({ label, onClose, onConfirm }: LabelDeleteConfirmType): React.ReactElement => { const LabelDeleteConfirm = ({
label,
onClose,
onConfirm,
}: LabelDeleteConfirmType): React.ReactElement => {
const intl = useIntl(); const intl = useIntl();
return ( return (
@ -21,16 +25,26 @@ const LabelDeleteConfirm = ({ label, onClose, onConfirm }: LabelDeleteConfirmTyp
<BaseDialog <BaseDialog
onClose={onClose} onClose={onClose}
onSubmit={onConfirm} onSubmit={onConfirm}
title={intl.formatMessage({ id: 'label.delete-title', defaultMessage: 'Confirm label deletion' })} title={intl.formatMessage({
id: 'label.delete-title',
defaultMessage: 'Confirm label deletion',
})}
submitButton={intl.formatMessage({ submitButton={intl.formatMessage({
id: 'action.delete-title', id: 'action.delete-title',
defaultMessage: 'Delete', defaultMessage: 'Delete',
})} })}
> >
<Alert severity="warning"> <Alert severity="warning">
<AlertTitle>{intl.formatMessage({ id: 'label.delete-title', defaultMessage: 'Confirm label deletion' })}</AlertTitle> <AlertTitle>
{intl.formatMessage({
id: 'label.delete-title',
defaultMessage: 'Confirm label deletion',
})}
</AlertTitle>
<span> <span>
<Typography fontWeight="bold" component="span">{label.title} </Typography> <Typography fontWeight="bold" component="span">
{label.title}{' '}
</Typography>
<FormattedMessage <FormattedMessage
id="label.delete-description" id="label.delete-description"
defaultMessage="will be deleted, including its associations to all existing maps. Do you want to continue?" defaultMessage="will be deleted, including its associations to all existing maps. Do you want to continue?"

View File

@ -19,7 +19,7 @@ export type LabelSelectorProps = {
export function LabelSelector({ onChange, maps }: LabelSelectorProps): React.ReactElement { export function LabelSelector({ onChange, maps }: LabelSelectorProps): React.ReactElement {
const client: Client = useSelector(activeInstance); const client: Client = useSelector(activeInstance);
const { data: labels = [] } = useQuery<unknown, ErrorInfo, Label[]>('labels', async () => const { data: labels = [] } = useQuery<unknown, ErrorInfo, Label[]>('labels', async () =>
client.fetchLabels() client.fetchLabels(),
); );
const checkedLabelIds = labels const checkedLabelIds = labels

View File

@ -6,14 +6,21 @@ import LabelTwoTone from '@mui/icons-material/LabelTwoTone';
import DeleteIcon from '@mui/icons-material/Clear'; import DeleteIcon from '@mui/icons-material/Clear';
import IconButton from '@mui/material/IconButton'; import IconButton from '@mui/material/IconButton';
type LabelSize = 'small' | 'big'; type LabelSize = 'small' | 'big';
type LabelComponentProps = { label: Label; onDelete?: (label: Label) => void; size?: LabelSize }; type LabelComponentProps = { label: Label; onDelete?: (label: Label) => void; size?: LabelSize };
export default function LabelComponent({ label, onDelete, size = 'small' }: LabelComponentProps): React.ReactElement<LabelComponentProps> { export default function LabelComponent({
const iconSize = size === 'small' ? { label,
height: '0.6em', width: '0.6em' onDelete,
} : { height: '0.9em', width: '0.9em' }; size = 'small',
}: LabelComponentProps): React.ReactElement<LabelComponentProps> {
const iconSize =
size === 'small'
? {
height: '0.6em',
width: '0.6em',
}
: { height: '0.9em', width: '0.9em' };
return ( return (
<LabelContainer color={label.color}> <LabelContainer color={label.color}>

View File

@ -7,21 +7,22 @@ import DeleteIcon from '@mui/icons-material/Clear';
import IconButton from '@mui/material/IconButton'; import IconButton from '@mui/material/IconButton';
type Props = { type Props = {
labels: Label[], labels: Label[];
onDelete: (label: Label) => void, onDelete: (label: Label) => void;
}; };
export function LabelsCell({ labels, onDelete }: Props): React.ReactElement<Props> { export function LabelsCell({ labels, onDelete }: Props): React.ReactElement<Props> {
return ( return (
<> <>
{labels.map(label => ( {labels.map((label) => (
<LabelContainer <LabelContainer key={label.id} color={label.color}>
key={label.id}
color={label.color}
>
<LabelTwoTone htmlColor={label.color} style={{ height: '0.6em', width: '0.6em' }} /> <LabelTwoTone htmlColor={label.color} style={{ height: '0.6em', width: '0.6em' }} />
<LabelText>{label.title}</LabelText> <LabelText>{label.title}</LabelText>
<IconButton color="default" size='small' aria-label="delete tag" component="span" <IconButton
color="default"
size="small"
aria-label="delete tag"
component="span"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
onDelete(label); onDelete(label);

View File

@ -16,28 +16,19 @@ const RoleIcon = ({ role }: RoleIconProps): React.ReactElement => {
return ( return (
<span> <span>
{role == 'owner' && ( {role == 'owner' && (
<Tooltip <Tooltip title={<FormattedMessage id="role.owner" defaultMessage="Owner" />} arrow={true}>
title={<FormattedMessage id="role.owner" defaultMessage="Owner" />}
arrow={true}
>
<PersonSharpIcon /> <PersonSharpIcon />
</Tooltip> </Tooltip>
)} )}
{role == 'editor' && ( {role == 'editor' && (
<Tooltip <Tooltip title={<FormattedMessage id="role.editor" defaultMessage="Editor" />} arrow={true}>
title={<FormattedMessage id="role.editor" defaultMessage="Editor" />}
arrow={true}
>
<EditSharpIcon /> <EditSharpIcon />
</Tooltip> </Tooltip>
)} )}
{role == 'viewer' && ( {role == 'viewer' && (
<Tooltip <Tooltip title={<FormattedMessage id="role.viewer" defaultMessage="Viewer" />} arrow={true}>
title={<FormattedMessage id="role.viewer" defaultMessage="Viewer" />}
arrow={true}
>
<VisibilitySharpIcon /> <VisibilitySharpIcon />
</Tooltip> </Tooltip>
)} )}

View File

@ -45,7 +45,7 @@ const RegistrationForm = () => {
setError(error); setError(error);
captcha.reset(); captcha.reset();
}, },
} },
); );
const handleOnSubmit = (event: React.FormEvent<HTMLFormElement>): void => { const handleOnSubmit = (event: React.FormEvent<HTMLFormElement>): void => {
@ -126,10 +126,10 @@ const RegistrationForm = () => {
error={error} error={error}
/> />
{AppConfig.isRecaptcha2Enabled() && {AppConfig.isRecaptcha2Enabled() && (
<div style={{ width: '330px', padding: '5px 0px 5px 20px' }}> <div style={{ width: '330px', padding: '5px 0px 5px 20px' }}>
<ReCAPTCHA <ReCAPTCHA
ref={el => setCaptcha(el)} ref={(el) => setCaptcha(el)}
sitekey={AppConfig.getRecaptcha2SiteKey()} sitekey={AppConfig.getRecaptcha2SiteKey()}
onChange={(value: string) => { onChange={(value: string) => {
model.recaptcha = value; model.recaptcha = value;
@ -137,7 +137,7 @@ const RegistrationForm = () => {
}} }}
/> />
</div> </div>
} )}
<div style={{ fontSize: '12px', padding: '10px 0px' }}> <div style={{ fontSize: '12px', padding: '10px 0px' }}>
<FormattedMessage <FormattedMessage
id="registration.termandconditions" id="registration.termandconditions"
@ -165,7 +165,11 @@ const RegistationPage = (): React.ReactElement => {
id: 'registration.page-title', id: 'registration.page-title',
defaultMessage: 'Registration | WiseMapping', defaultMessage: 'Registration | WiseMapping',
}); });
ReactGA.send({ hitType: 'pageview', page: window.location.pathname, title: 'Registration:Init' }); ReactGA.send({
hitType: 'pageview',
page: window.location.pathname,
title: 'Registration:Init',
});
}, []); }, []);
return ( return (

View File

@ -8,13 +8,19 @@ import Typography from '@mui/material/Typography';
import Button from '@mui/material/Button'; import Button from '@mui/material/Button';
import ReactGA from 'react-ga4'; import ReactGA from 'react-ga4';
const RegistrationSuccessPage = (): React.ReactElement => { const RegistrationSuccessPage = (): React.ReactElement => {
const intl = useIntl(); const intl = useIntl();
useEffect(() => { useEffect(() => {
document.title = intl.formatMessage({ id: 'registation.success-title', defaultMessage: 'Registation Success | WiseMapping' }); document.title = intl.formatMessage({
ReactGA.send({ hitType: 'pageview', page: window.location.pathname, title: 'Registration:Success' }); id: 'registation.success-title',
defaultMessage: 'Registation Success | WiseMapping',
});
ReactGA.send({
hitType: 'pageview',
page: window.location.pathname,
title: 'Registration:Success',
});
}); });
return ( return (