@jetbrains/ring-ui 5.0.136 → 5.0.138
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/auth/auth__core.d.ts +1 -1
- package/components/auth/auth__core.js +21 -26
- package/components/auth-dialog/auth-dialog.js +3 -1
- package/components/button/button.css +7 -7
- package/components/button/button.d.ts +0 -1
- package/components/button/button.js +0 -1
- package/components/button-group/button-group.css +2 -2
- package/components/button-group/button-group.d.ts +0 -1
- package/components/button-group/button-group.js +0 -1
- package/components/button-group-ng/button-group-ng.js +0 -1
- package/components/button-ng/button-ng.js +0 -1
- package/components/checkbox/checkbox.css +1 -1
- package/components/checkbox/checkbox.d.ts +0 -1
- package/components/checkbox/checkbox.js +0 -1
- package/components/checkbox-ng/checkbox-ng.js +0 -1
- package/components/date-picker/date-input.js +3 -1
- package/components/editable-heading/editable-heading.css +7 -3
- package/components/editable-heading/editable-heading.js +29 -8
- package/components/global/react-render-adapter.js +16 -31
- package/components/header/profile.d.ts +54 -1
- package/components/header/profile.js +15 -11
- package/components/i18n/README.md +3 -0
- package/components/i18n/i18n-context.d.ts +54 -0
- package/components/i18n/i18n-context.js +3 -0
- package/components/i18n/i18n.d.ts +56 -0
- package/components/i18n/i18n.js +8 -0
- package/components/i18n/messages.json +53 -0
- package/components/input/input.d.ts +1 -4
- package/components/input/input.js +16 -16
- package/components/island/island.css +1 -1
- package/components/island/island.d.ts +0 -1
- package/components/island/island.js +0 -1
- package/components/island-ng/island-ng.js +0 -1
- package/components/link/link.css +1 -1
- package/components/link/link.d.ts +0 -1
- package/components/link/link.js +0 -1
- package/components/link-ng/link-ng.js +0 -1
- package/components/message/message.d.ts +1 -5
- package/components/message/message.js +15 -16
- package/components/pager/pager.d.ts +54 -8
- package/components/pager/pager.js +10 -12
- package/components/query-assist/query-assist.d.ts +1 -5
- package/components/query-assist/query-assist.js +30 -29
- package/components/select/select.css +2 -2
- package/components/select/select.d.ts +2 -5
- package/components/select/select.js +14 -12
- package/components/select/select__filter.d.ts +0 -1
- package/components/select/select__filter.js +4 -2
- package/components/tabs/dumb-tabs.d.ts +0 -1
- package/components/tabs/dumb-tabs.js +0 -1
- package/components/tabs/tabs.css +1 -1
- package/components/tabs-ng/tabs-ng.js +0 -1
- package/components/tag/tag.css +3 -3
- package/components/tag/tag.d.ts +0 -1
- package/components/tag/tag.js +0 -1
- package/components/user-agreement/user-agreement.d.ts +1 -9
- package/components/user-agreement/user-agreement.js +31 -30
- package/components/user-card/card.d.ts +65 -13
- package/components/user-card/card.js +19 -22
- package/dist/_helpers/card.js +19 -28
- package/dist/_helpers/select__filter.js +14 -10
- package/dist/alert/alert.js +0 -1
- package/dist/alert-service/alert-service.js +0 -1
- package/dist/auth/auth.js +1 -1
- package/dist/auth/auth__core.d.ts +1 -1
- package/dist/auth/auth__core.js +19 -28
- package/dist/auth/down-notification.js +0 -1
- package/dist/auth/iframe-flow.js +0 -1
- package/dist/auth/landing.js +1 -1
- package/dist/auth/storage.js +0 -1
- package/dist/auth-dialog/auth-dialog.js +1 -2
- package/dist/auth-dialog-service/auth-dialog-service.js +0 -1
- package/dist/auth-ng/auth-ng.js +1 -1
- package/dist/avatar-editor-ng/avatar-editor-ng.js +0 -1
- package/dist/breadcrumb-ng/breadcrumb-ng.js +0 -1
- package/dist/button/button.d.ts +0 -1
- package/dist/button/button.js +0 -1
- package/dist/button-group/button-group.d.ts +0 -1
- package/dist/button-group/button-group.js +0 -1
- package/dist/button-group-ng/button-group-ng.js +0 -1
- package/dist/button-ng/button-ng.js +0 -1
- package/dist/checkbox/checkbox.d.ts +0 -1
- package/dist/checkbox/checkbox.js +0 -1
- package/dist/checkbox-ng/checkbox-ng.js +0 -1
- package/dist/clipboard/clipboard.js +0 -1
- package/dist/confirm/confirm.js +0 -1
- package/dist/confirm-ng/confirm-ng.js +0 -1
- package/dist/confirm-service/confirm-service.js +0 -1
- package/dist/data-list/data-list.js +0 -1
- package/dist/data-list/data-list.mock.js +0 -1
- package/dist/data-list/item.js +0 -1
- package/dist/data-list/title.js +0 -1
- package/dist/data-list-ng/data-list-ng.js +0 -1
- package/dist/date-picker/date-input.js +3 -2
- package/dist/date-picker/date-picker.js +2 -1
- package/dist/date-picker/date-popup.js +2 -1
- package/dist/dialog/dialog.js +0 -1
- package/dist/dialog-ng/dialog-ng.js +0 -1
- package/dist/dropdown/anchor.js +0 -1
- package/dist/dropdown/dropdown.js +0 -1
- package/dist/dropdown-menu/dropdown-menu.js +0 -1
- package/dist/editable-heading/editable-heading.js +32 -10
- package/dist/error-message-ng/error-message-ng.js +0 -1
- package/dist/footer/footer.js +0 -1
- package/dist/footer-ng/footer-ng.js +0 -1
- package/dist/global/react-render-adapter.js +0 -2
- package/dist/header/header.js +2 -1
- package/dist/header/profile.d.ts +54 -1
- package/dist/header/profile.js +22 -16
- package/dist/header/services-link.js +0 -1
- package/dist/header/services.js +0 -1
- package/dist/header/smart-profile.js +2 -1
- package/dist/header/smart-services.js +1 -1
- package/dist/header/tray-icon.js +0 -1
- package/dist/i18n/i18n-context.d.ts +54 -0
- package/dist/i18n/i18n-context.js +6 -0
- package/dist/i18n/i18n.d.ts +56 -0
- package/dist/i18n/i18n.js +114 -0
- package/dist/input/input.d.ts +1 -4
- package/dist/input/input.js +6 -8
- package/dist/input-ng/input-ng.js +0 -1
- package/dist/island/island.d.ts +0 -1
- package/dist/island/island.js +0 -1
- package/dist/island-ng/island-ng.js +0 -1
- package/dist/link/link.d.ts +0 -1
- package/dist/link/link.js +0 -1
- package/dist/link-ng/link-ng.js +0 -1
- package/dist/list/list.js +0 -1
- package/dist/list/list__item.js +0 -1
- package/dist/list/list__link.js +0 -1
- package/dist/list/list__users-groups-source.js +0 -1
- package/dist/login-dialog/login-dialog.js +0 -1
- package/dist/login-dialog/service.js +0 -1
- package/dist/markdown/link.js +0 -1
- package/dist/markdown/markdown.js +0 -1
- package/dist/message/message.d.ts +1 -5
- package/dist/message/message.js +5 -8
- package/dist/pager/pager.d.ts +54 -8
- package/dist/pager/pager.js +19 -16
- package/dist/pager-ng/pager-ng.js +2 -1
- package/dist/permissions-ng/permissions-ng.js +1 -1
- package/dist/popup-menu/popup-menu.js +0 -1
- package/dist/promised-click-ng/promised-click-ng.js +0 -1
- package/dist/query-assist/query-assist.d.ts +1 -5
- package/dist/query-assist/query-assist.js +22 -20
- package/dist/query-assist/query-assist__suggestions.js +0 -1
- package/dist/query-assist-ng/query-assist-ng.js +2 -1
- package/dist/save-field-ng/save-field-ng.js +0 -1
- package/dist/select/select.d.ts +2 -5
- package/dist/select/select.js +49 -46
- package/dist/select/select__filter.d.ts +0 -1
- package/dist/select/select__filter.js +2 -1
- package/dist/select/select__popup.js +2 -1
- package/dist/select-ng/select-ng.js +2 -1
- package/dist/select-ng/select-ng__lazy.js +2 -1
- package/dist/shortcuts-hint-ng/shortcuts-hint-ng.js +0 -1
- package/dist/sidebar-ng/sidebar-ng.js +0 -1
- package/dist/storage/storage.js +0 -1
- package/dist/storage/storage__local.js +0 -1
- package/dist/style.css +1 -1
- package/dist/table/header.js +0 -1
- package/dist/table/row-with-focus-sensor.js +0 -1
- package/dist/table/row.js +0 -1
- package/dist/table/smart-table.js +0 -1
- package/dist/table/table.js +0 -1
- package/dist/table-legacy-ng/table-legacy-ng.js +2 -1
- package/dist/table-legacy-ng/table-legacy-ng__pager.js +2 -1
- package/dist/table-ng/smart-table-ng.js +0 -1
- package/dist/table-ng/table-ng.js +0 -1
- package/dist/tabs/collapsible-more.js +0 -1
- package/dist/tabs/collapsible-tab.js +0 -1
- package/dist/tabs/collapsible-tabs.js +0 -1
- package/dist/tabs/dumb-tabs.d.ts +0 -1
- package/dist/tabs/dumb-tabs.js +0 -1
- package/dist/tabs/smart-tabs.js +0 -1
- package/dist/tabs/tab-link.js +0 -1
- package/dist/tabs/tabs.js +0 -1
- package/dist/tabs-ng/tabs-ng.js +0 -1
- package/dist/tag/tag.d.ts +0 -1
- package/dist/tag/tag.js +0 -1
- package/dist/tags-input/tags-input.js +2 -1
- package/dist/tags-input-ng/tags-input-ng.js +2 -1
- package/dist/tags-list/tags-list.js +0 -1
- package/dist/user-agreement/service.js +2 -1
- package/dist/user-agreement/user-agreement.d.ts +1 -9
- package/dist/user-agreement/user-agreement.js +11 -18
- package/dist/user-card/card.d.ts +65 -13
- package/dist/user-card/card.js +2 -1
- package/dist/user-card/smart-user-card-tooltip.js +2 -1
- package/dist/user-card/tooltip.js +2 -1
- package/dist/user-card/user-card.js +2 -1
- package/dist/user-card-ng/user-card-ng.js +2 -1
- package/package.json +37 -38
|
@@ -77,7 +77,7 @@ export interface AuthConfig extends TokenValidatorConfig {
|
|
|
77
77
|
checkBackendIsUp: () => Promise<unknown>;
|
|
78
78
|
onBackendDown: (params: BackendDownParams) => () => void;
|
|
79
79
|
defaultExpiresIn: number;
|
|
80
|
-
translations
|
|
80
|
+
translations?: AuthTranslations | null | undefined;
|
|
81
81
|
userParams?: RequestParams | undefined;
|
|
82
82
|
waitForRedirectTimeout: number;
|
|
83
83
|
}
|
|
@@ -2,6 +2,7 @@ import { fixUrl, getAbsoluteBaseURL } from '../global/url';
|
|
|
2
2
|
import Listeners from '../global/listeners';
|
|
3
3
|
import HTTP from '../http/http';
|
|
4
4
|
import promiseWithTimeout from '../global/promise-with-timeout';
|
|
5
|
+
import { getTranslations } from '../i18n/i18n';
|
|
5
6
|
import AuthStorage from './storage';
|
|
6
7
|
import AuthResponseParser from './response-parser';
|
|
7
8
|
import AuthRequestBuilder from './request-builder';
|
|
@@ -42,19 +43,7 @@ const DEFAULT_CONFIG = {
|
|
|
42
43
|
onBackendDown: () => () => { },
|
|
43
44
|
defaultExpiresIn: DEFAULT_EXPIRES_TIMEOUT,
|
|
44
45
|
waitForRedirectTimeout: DEFAULT_WAIT_FOR_REDIRECT_TIMEOUT,
|
|
45
|
-
translations:
|
|
46
|
-
login: 'Log in',
|
|
47
|
-
loginTo: 'Log in to %serviceName%',
|
|
48
|
-
cancel: 'Cancel',
|
|
49
|
-
tryAgainLabel: 'Try again',
|
|
50
|
-
postpone: 'Postpone',
|
|
51
|
-
youHaveLoggedInAs: 'You have logged in as another user: %userName%',
|
|
52
|
-
applyChange: 'Apply change',
|
|
53
|
-
backendIsNotAvailable: 'Connection lost',
|
|
54
|
-
checkAgain: 'try again',
|
|
55
|
-
nothingHappensLink: 'Click here if nothing happens',
|
|
56
|
-
errorMessage: 'There may be a problem with your network connection. Make sure that you are online and'
|
|
57
|
-
}
|
|
46
|
+
translations: null
|
|
58
47
|
};
|
|
59
48
|
class Auth {
|
|
60
49
|
static DEFAULT_CONFIG = DEFAULT_CONFIG;
|
|
@@ -131,7 +120,7 @@ class Auth {
|
|
|
131
120
|
}
|
|
132
121
|
this._backgroundFlow = new BackgroundFlow(this._requestBuilder, this._storage, backgroundRefreshTimeout);
|
|
133
122
|
if (this.config.EmbeddedLoginFlow) {
|
|
134
|
-
this._embeddedFlow = new this.config.EmbeddedLoginFlow(this._requestBuilder, this._storage, this.config.translations);
|
|
123
|
+
this._embeddedFlow = new this.config.EmbeddedLoginFlow(this._requestBuilder, this._storage, this.config.translations ?? getTranslations());
|
|
135
124
|
}
|
|
136
125
|
const API_BASE = this.config.serverUri + Auth.API_PATH;
|
|
137
126
|
const fetchConfig = config.fetchCredentials
|
|
@@ -491,6 +480,7 @@ class Auth {
|
|
|
491
480
|
_showAuthDialog({ nonInteractive, error, canCancel, onTryAgain } = {}) {
|
|
492
481
|
const { embeddedLogin, onPostponeLogout, translations } = this.config;
|
|
493
482
|
const cancelable = this.user?.guest || canCancel;
|
|
483
|
+
const actualTranslations = translations ?? getTranslations();
|
|
494
484
|
this._createInitDeferred();
|
|
495
485
|
const closeDialog = () => {
|
|
496
486
|
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
@@ -530,11 +520,11 @@ class Auth {
|
|
|
530
520
|
};
|
|
531
521
|
const hide = this._authDialogService?.({
|
|
532
522
|
...this._service,
|
|
533
|
-
loginCaption:
|
|
534
|
-
loginToCaption:
|
|
535
|
-
confirmLabel:
|
|
536
|
-
tryAgainLabel:
|
|
537
|
-
cancelLabel: cancelable ?
|
|
523
|
+
loginCaption: actualTranslations.login,
|
|
524
|
+
loginToCaption: actualTranslations.loginTo,
|
|
525
|
+
confirmLabel: actualTranslations.login,
|
|
526
|
+
tryAgainLabel: actualTranslations.tryAgainLabel,
|
|
527
|
+
cancelLabel: cancelable ? actualTranslations.cancel : actualTranslations.postpone,
|
|
538
528
|
errorMessage: this._extractErrorMessage(error, true),
|
|
539
529
|
onConfirm,
|
|
540
530
|
onCancel,
|
|
@@ -550,6 +540,7 @@ class Auth {
|
|
|
550
540
|
}
|
|
551
541
|
_showUserChangedDialog({ newUser, onApply, onPostpone }) {
|
|
552
542
|
const { translations } = this.config;
|
|
543
|
+
const actualTranslations = translations ?? getTranslations();
|
|
553
544
|
this._createInitDeferred();
|
|
554
545
|
const done = () => {
|
|
555
546
|
this._initDeferred?.resolve?.();
|
|
@@ -558,12 +549,14 @@ class Auth {
|
|
|
558
549
|
};
|
|
559
550
|
const hide = this._authDialogService?.({
|
|
560
551
|
...this._service,
|
|
561
|
-
title:
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
552
|
+
title: actualTranslations.youHaveLoggedInAs.
|
|
553
|
+
replace('%userName%', newUser.name ?? '').
|
|
554
|
+
replace('{{userName}}', newUser.name ?? ''),
|
|
555
|
+
loginCaption: actualTranslations.login,
|
|
556
|
+
loginToCaption: actualTranslations.loginTo,
|
|
557
|
+
confirmLabel: actualTranslations.applyChange,
|
|
558
|
+
tryAgainLabel: actualTranslations.tryAgainLabel,
|
|
559
|
+
cancelLabel: actualTranslations.postpone,
|
|
567
560
|
onConfirm: () => {
|
|
568
561
|
done();
|
|
569
562
|
onApply();
|
|
@@ -623,7 +616,9 @@ class Auth {
|
|
|
623
616
|
done();
|
|
624
617
|
reject(new Error('Auth(@jetbrains/ring-ui): postponed by user'));
|
|
625
618
|
};
|
|
626
|
-
const hide = onBackendDown({
|
|
619
|
+
const hide = onBackendDown({
|
|
620
|
+
onCheckAgain, onPostpone, backendError, translations: translations ?? getTranslations()
|
|
621
|
+
});
|
|
627
622
|
window.addEventListener('online', onCheckAgain);
|
|
628
623
|
function networkWatchdog() {
|
|
629
624
|
if (navigator && navigator.onLine) {
|
|
@@ -68,7 +68,9 @@ class AuthDialog extends Component {
|
|
|
68
68
|
const { show, className, errorMessage, serviceImage, serviceName, loginCaption, loginToCaption, confirmLabel, cancelLabel, tryAgainLabel, onConfirm, onCancel, onTryAgain } = this.props;
|
|
69
69
|
const { retrying } = this.state;
|
|
70
70
|
const defaultTitle = serviceName ? loginToCaption : loginCaption;
|
|
71
|
-
const title = (this.props.title || defaultTitle).
|
|
71
|
+
const title = (this.props.title || defaultTitle).
|
|
72
|
+
replace('%serviceName%', serviceName ?? '').
|
|
73
|
+
replace('{{serviceName}}', serviceName ?? '');
|
|
72
74
|
return (<Dialog label={title} data-test="ring-auth-dialog" className={className} contentClassName={classNames(className, styles.dialog)} onEscPress={this.onEscPress} show={show} trapFocus>
|
|
73
75
|
<Content>
|
|
74
76
|
<div className={styles.content}>
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
box-shadow: button-shadow var(--ring-border-hover-color);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
&:
|
|
63
|
+
&:focus-visible {
|
|
64
64
|
transition: none;
|
|
65
65
|
|
|
66
66
|
box-shadow: button-shadow var(--ring-border-hover-color), 0 0 0 1px var(--ring-border-hover-color);
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
box-shadow: button-shadow var(--ring-main-color);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
&:
|
|
76
|
+
&:focus-visible.active {
|
|
77
77
|
box-shadow: inset 0 0 0 2px var(--ring-main-color), 0 0 0 1px var(--ring-border-hover-color);
|
|
78
78
|
}
|
|
79
79
|
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
color: var(--ring-action-link-color);
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
&:
|
|
131
|
+
&:focus-visible,
|
|
132
132
|
&:active,
|
|
133
133
|
&.active {
|
|
134
134
|
background-color: var(--ring-button-primary-background-color);
|
|
@@ -186,12 +186,12 @@
|
|
|
186
186
|
|
|
187
187
|
&:active,
|
|
188
188
|
&.active,
|
|
189
|
-
&:
|
|
189
|
+
&:focus-visible,
|
|
190
190
|
&:hover {
|
|
191
191
|
box-shadow: button-shadow var(--ring-button-danger-hover-color);
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
&:
|
|
194
|
+
&:focus-visible,
|
|
195
195
|
&:hover {
|
|
196
196
|
transition: none;
|
|
197
197
|
}
|
|
@@ -212,7 +212,7 @@
|
|
|
212
212
|
box-shadow: none;
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
-
&:
|
|
215
|
+
&:focus-visible {
|
|
216
216
|
box-shadow: inset 0 0 0 2px var(--ring-border-hover-color);
|
|
217
217
|
}
|
|
218
218
|
}
|
|
@@ -228,7 +228,7 @@
|
|
|
228
228
|
box-shadow: none;
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
-
.withIcon:hover:not(:
|
|
231
|
+
.withIcon:hover:not(:focus-visible) {
|
|
232
232
|
background-color: transparent;
|
|
233
233
|
box-shadow: none;
|
|
234
234
|
}
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
/* stylelint-disable-next-line selector-max-specificity */
|
|
114
|
-
.buttonGroup .button.button:
|
|
114
|
+
.buttonGroup .button.button:focus-visible {
|
|
115
115
|
border-radius: var(--ring-border-radius);
|
|
116
116
|
box-shadow: button-shadow var(--ring-border-hover-color), 0 0 0 1px var(--ring-border-hover-color);
|
|
117
117
|
}
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
/* stylelint-disable-next-line selector-max-specificity */
|
|
126
|
-
.buttonGroup .button:
|
|
126
|
+
.buttonGroup .button:focus-visible.active {
|
|
127
127
|
border-radius: var(--ring-border-radius);
|
|
128
128
|
box-shadow: button-shadow var(--ring-main-color), 0 0 0 1px var(--ring-border-hover-color);
|
|
129
129
|
}
|
|
@@ -89,7 +89,9 @@ class DateInput extends React.PureComponent {
|
|
|
89
89
|
case 'time':
|
|
90
90
|
return timePlaceholder || translations.addTime;
|
|
91
91
|
default:
|
|
92
|
-
return translations.selectName.
|
|
92
|
+
return translations.selectName.
|
|
93
|
+
replace('%name%', name).
|
|
94
|
+
replace('{{name}}', name);
|
|
93
95
|
}
|
|
94
96
|
})();
|
|
95
97
|
const classes = classNames(styles.filter, styles[`${name}Input`], divider && styles[`${name}InputWithDivider`], 'ring-js-shortcuts');
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
padding: 0;
|
|
23
23
|
|
|
24
24
|
cursor: pointer;
|
|
25
|
+
user-select: text;
|
|
25
26
|
|
|
26
27
|
text-align: inherit;
|
|
27
28
|
|
|
@@ -33,7 +34,8 @@
|
|
|
33
34
|
|
|
34
35
|
font-size: inherit;
|
|
35
36
|
|
|
36
|
-
@nest .disabled
|
|
37
|
+
@nest .disabled &,
|
|
38
|
+
.selectionMode & {
|
|
37
39
|
user-select: text;
|
|
38
40
|
|
|
39
41
|
border-radius: 0;
|
|
@@ -43,7 +45,8 @@
|
|
|
43
45
|
outline: 1px solid var(--ring-border-hover-color);
|
|
44
46
|
}
|
|
45
47
|
|
|
46
|
-
@nest .disabled &:focus
|
|
48
|
+
@nest .disabled &:focus,
|
|
49
|
+
.selectionMode &:focus {
|
|
47
50
|
outline: none;
|
|
48
51
|
}
|
|
49
52
|
|
|
@@ -51,7 +54,8 @@
|
|
|
51
54
|
background-color: var(--ring-hover-background-color);
|
|
52
55
|
}
|
|
53
56
|
|
|
54
|
-
@nest .disabled &:hover
|
|
57
|
+
@nest .disabled &:hover,
|
|
58
|
+
.selectionMode &:hover {
|
|
55
59
|
cursor: initial;
|
|
56
60
|
|
|
57
61
|
background-color: initial;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
3
|
import Heading, { Levels } from '../heading/heading';
|
|
4
4
|
import Button from '../button/button';
|
|
@@ -17,6 +17,8 @@ export const EditableHeading = (props) => {
|
|
|
17
17
|
}, ...restProps } = props;
|
|
18
18
|
const [shortcutsScope] = React.useState(getUID('ring-editable-heading-'));
|
|
19
19
|
const [isInFocus, setIsInFocus] = React.useState(false);
|
|
20
|
+
const [isMouseDown, setIsMouseDown] = React.useState(false);
|
|
21
|
+
const [isInSelectionMode, setIsInSelectionMode] = React.useState(false);
|
|
20
22
|
const hasError = error !== undefined;
|
|
21
23
|
const isSaveDisabled = !isSavingPossible || !children || children.trim() === '' || hasError || isSaving;
|
|
22
24
|
const isCancelDisabled = isSaving;
|
|
@@ -36,16 +38,27 @@ export const EditableHeading = (props) => {
|
|
|
36
38
|
[styles.isEditing]: isEditing,
|
|
37
39
|
[styles.error]: hasError,
|
|
38
40
|
[styles.disabled]: disabled,
|
|
39
|
-
[styles.multiline]: multiline
|
|
41
|
+
[styles.multiline]: multiline,
|
|
42
|
+
[styles.selectionMode]: isInSelectionMode
|
|
40
43
|
});
|
|
41
44
|
const headingClasses = classNames(styles.heading, headingClassName, styles[`size${size}`]);
|
|
42
45
|
const inputClasses = classNames('ring-js-shortcuts', styles.input, inputStyles[`size${size}`], styles[`level${level}`], inputClassName);
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
const onHeadingMouseDown = React.useCallback(() => {
|
|
47
|
+
setIsMouseDown(true);
|
|
48
|
+
}, []);
|
|
49
|
+
const onMouseMove = React.useCallback(() => {
|
|
50
|
+
if (!isMouseDown) {
|
|
51
|
+
return;
|
|
46
52
|
}
|
|
47
|
-
|
|
48
|
-
}, [
|
|
53
|
+
setIsInSelectionMode(true);
|
|
54
|
+
}, [isMouseDown]);
|
|
55
|
+
const onMouseUp = React.useCallback(() => {
|
|
56
|
+
if (isMouseDown && !isInSelectionMode && !disabled) {
|
|
57
|
+
onEdit();
|
|
58
|
+
}
|
|
59
|
+
setIsMouseDown(false);
|
|
60
|
+
setIsInSelectionMode(false);
|
|
61
|
+
}, [isMouseDown, isInSelectionMode, disabled, onEdit]);
|
|
49
62
|
const onInputFocus = React.useCallback((e) => {
|
|
50
63
|
setIsInFocus(true);
|
|
51
64
|
onFocus?.(e);
|
|
@@ -54,6 +67,14 @@ export const EditableHeading = (props) => {
|
|
|
54
67
|
setIsInFocus(false);
|
|
55
68
|
onBlur?.(e);
|
|
56
69
|
}, [onBlur]);
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
window.addEventListener('mousemove', onMouseMove);
|
|
72
|
+
window.addEventListener('mouseup', onMouseUp);
|
|
73
|
+
return () => {
|
|
74
|
+
window.removeEventListener('mousemove', onMouseMove);
|
|
75
|
+
window.removeEventListener('mouseup', onMouseUp);
|
|
76
|
+
};
|
|
77
|
+
});
|
|
57
78
|
return (<>
|
|
58
79
|
<div className={classes}>
|
|
59
80
|
{!disabled && isEditing
|
|
@@ -62,7 +83,7 @@ export const EditableHeading = (props) => {
|
|
|
62
83
|
|
|
63
84
|
<input className={inputClasses} value={children} autoFocus={autoFocus} data-test={dataTest} disabled={isSaving} {...restProps} onFocus={onInputFocus} onBlur={onInputBlur}/>
|
|
64
85
|
</>)
|
|
65
|
-
: (<button type="button" className={styles.headingWrapperButton}
|
|
86
|
+
: (<button type="button" className={styles.headingWrapperButton} onMouseDown={onHeadingMouseDown}>
|
|
66
87
|
<Heading className={headingClasses} level={level} data-test={dataTest}>{children}</Heading>
|
|
67
88
|
</button>)}
|
|
68
89
|
|
|
@@ -1,36 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
// import * as client from 'react-dom/client'
|
|
3
|
-
// import {setClient} from '@jetbrains/ring-ui/components/global/react-render-adapter'
|
|
4
|
-
//
|
|
5
|
-
// setClient(client)
|
|
6
|
-
import {
|
|
7
|
-
render as legacyRender,
|
|
8
|
-
unmountComponentAtNode as legacyUnmountComponentAtNode,
|
|
9
|
-
hydrate as legacyHydrate
|
|
10
|
-
} from 'react-dom';
|
|
11
|
-
|
|
1
|
+
import { render as legacyRender, unmountComponentAtNode as legacyUnmountComponentAtNode, hydrate as legacyHydrate } from 'react-dom';
|
|
12
2
|
/* eslint-disable import/no-mutable-exports */
|
|
13
3
|
export let render = legacyRender;
|
|
14
4
|
export let unmountComponentAtNode = legacyUnmountComponentAtNode;
|
|
15
5
|
export let hydrate = legacyHydrate;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
hydrate = (element, container) => {
|
|
33
|
-
const root = hydrateRoot(container, element);
|
|
34
|
-
roots.set(container, root);
|
|
35
|
-
};
|
|
6
|
+
export function setClient({ createRoot, hydrateRoot }) {
|
|
7
|
+
const roots = new WeakMap();
|
|
8
|
+
render = (element, container) => {
|
|
9
|
+
let root = roots.get(container);
|
|
10
|
+
if (root == null) {
|
|
11
|
+
root = createRoot(container);
|
|
12
|
+
roots.set(container, root);
|
|
13
|
+
}
|
|
14
|
+
root.render(element);
|
|
15
|
+
};
|
|
16
|
+
unmountComponentAtNode = container => roots.get(container)?.unmount();
|
|
17
|
+
hydrate = (element, container) => {
|
|
18
|
+
const root = hydrateRoot(container, element);
|
|
19
|
+
roots.set(container, root);
|
|
20
|
+
};
|
|
36
21
|
}
|
|
@@ -15,7 +15,7 @@ export interface ProfileTranslations {
|
|
|
15
15
|
export interface ProfileProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onSelect'> {
|
|
16
16
|
closeOnSelect: boolean;
|
|
17
17
|
renderPopupItems: (items: ListDataItem[]) => readonly ListDataItem[];
|
|
18
|
-
translations
|
|
18
|
+
translations?: ProfileTranslations | null | undefined;
|
|
19
19
|
size: Size;
|
|
20
20
|
renderGuest: (props: ProfileProps) => ReactNode;
|
|
21
21
|
hasUpdates?: boolean | null | undefined;
|
|
@@ -67,6 +67,59 @@ export default class Profile extends PureComponent<ProfileProps> {
|
|
|
67
67
|
renderGuest: PropTypes.Requireable<(...args: any[]) => any>;
|
|
68
68
|
};
|
|
69
69
|
static defaultProps: ProfileProps;
|
|
70
|
+
static contextType: React.Context<{
|
|
71
|
+
login: string;
|
|
72
|
+
logout: string;
|
|
73
|
+
loginTo: string;
|
|
74
|
+
ok: string;
|
|
75
|
+
cancel: string;
|
|
76
|
+
tryAgainLabel: string;
|
|
77
|
+
postpone: string;
|
|
78
|
+
youHaveLoggedInAs: string;
|
|
79
|
+
applyChange: string;
|
|
80
|
+
backendIsNotAvailable: string;
|
|
81
|
+
checkAgain: string;
|
|
82
|
+
nothingHappensLink: string;
|
|
83
|
+
errorMessage: string;
|
|
84
|
+
applyChangedUser: string;
|
|
85
|
+
profile: string;
|
|
86
|
+
switchUser: string;
|
|
87
|
+
addFirstDate: string;
|
|
88
|
+
addSecondDate: string;
|
|
89
|
+
addTime: string;
|
|
90
|
+
selectName: string;
|
|
91
|
+
setDate: string;
|
|
92
|
+
setDateTime: string;
|
|
93
|
+
setPeriod: string;
|
|
94
|
+
clear: string;
|
|
95
|
+
gotIt: string;
|
|
96
|
+
dismiss: string;
|
|
97
|
+
perPage: string;
|
|
98
|
+
firstPage: string;
|
|
99
|
+
lastPage: string;
|
|
100
|
+
nextPage: string;
|
|
101
|
+
previousPage: string;
|
|
102
|
+
searchTitle: string;
|
|
103
|
+
clearTitle: string;
|
|
104
|
+
userAgreement: string;
|
|
105
|
+
accept: string;
|
|
106
|
+
decline: string;
|
|
107
|
+
close: string;
|
|
108
|
+
scrollToAccept: string;
|
|
109
|
+
remindLater: string;
|
|
110
|
+
filterItems: string;
|
|
111
|
+
selectOption: string;
|
|
112
|
+
progress: string;
|
|
113
|
+
loading: string;
|
|
114
|
+
noOptionsFound: string;
|
|
115
|
+
banned: string;
|
|
116
|
+
online: string;
|
|
117
|
+
offline: string;
|
|
118
|
+
copyToClipboard: string;
|
|
119
|
+
copiedToClipboard: string;
|
|
120
|
+
copingToClipboardError: string;
|
|
121
|
+
unverified: string;
|
|
122
|
+
}>;
|
|
70
123
|
static Size: typeof Size;
|
|
71
124
|
render(): string | number | boolean | JSX.Element | React.ReactFragment | null | undefined;
|
|
72
125
|
}
|
|
@@ -5,6 +5,7 @@ import Avatar, { Size } from '../avatar/avatar';
|
|
|
5
5
|
import Button from '../button/button';
|
|
6
6
|
import DropdownMenu from '../dropdown-menu/dropdown-menu';
|
|
7
7
|
import PopupMenu from '../popup-menu/popup-menu';
|
|
8
|
+
import { I18nContext } from '../i18n/i18n-context';
|
|
8
9
|
import { isTruthy } from '../global/typescript-utils';
|
|
9
10
|
import styles from './header.css';
|
|
10
11
|
const rgItemType = PopupMenu.ListProps.Type.LINK;
|
|
@@ -48,17 +49,20 @@ class Profile extends PureComponent {
|
|
|
48
49
|
static defaultProps = {
|
|
49
50
|
closeOnSelect: true,
|
|
50
51
|
renderPopupItems: items => items,
|
|
51
|
-
translations: {},
|
|
52
52
|
size: Size.Size32,
|
|
53
|
-
renderGuest: ({ loading, onLogin, className, translations }) => (<
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
renderGuest: ({ loading, onLogin, className, translations }) => (<I18nContext.Consumer>
|
|
54
|
+
{messages => (<div className={classNames(styles.profileEmpty, className)}>
|
|
55
|
+
<Button primary data-test="ring-header-login-button" disabled={loading} loader={loading} onClick={onLogin}>
|
|
56
|
+
{translations?.login ?? messages.login}
|
|
57
|
+
</Button>
|
|
58
|
+
</div>)}
|
|
59
|
+
</I18nContext.Consumer>)
|
|
58
60
|
};
|
|
61
|
+
static contextType = I18nContext;
|
|
59
62
|
static Size = Size;
|
|
60
63
|
render() {
|
|
61
64
|
const { className, closeOnSelect, hasUpdates, onLogout, user, profileUrl, LinkComponent, onSwitchUser, renderPopupItems, onRevertPostponement, showApplyChangedUser, showLogIn, showLogOut, showSwitchUser, renderGuest, translations, size, round, loading, onLogin, ...props } = this.props;
|
|
65
|
+
const messages = this.context;
|
|
62
66
|
if (!user) {
|
|
63
67
|
return (<div {...props} className={classNames(styles.profileEmpty, className)}>
|
|
64
68
|
<Avatar size={size} round={round}/>
|
|
@@ -76,32 +80,32 @@ class Profile extends PureComponent {
|
|
|
76
80
|
const items = [
|
|
77
81
|
showApplyChangedUser && {
|
|
78
82
|
rgItemType,
|
|
79
|
-
label: translations
|
|
83
|
+
label: translations?.applyChangedUser ?? messages.applyChangedUser,
|
|
80
84
|
className: styles.profileMenuItem,
|
|
81
85
|
onClick: onRevertPostponement
|
|
82
86
|
},
|
|
83
87
|
showLogIn && {
|
|
84
88
|
rgItemType,
|
|
85
|
-
label: translations
|
|
89
|
+
label: translations?.login ?? messages.login,
|
|
86
90
|
className: styles.profileMenuItem,
|
|
87
91
|
onClick: onRevertPostponement
|
|
88
92
|
},
|
|
89
93
|
{
|
|
90
94
|
rgItemType: PopupMenu.ListProps.Type.LINK,
|
|
91
|
-
label: translations
|
|
95
|
+
label: translations?.profile ?? messages.profile,
|
|
92
96
|
target: '_self',
|
|
93
97
|
href: profileUrl,
|
|
94
98
|
LinkComponent
|
|
95
99
|
},
|
|
96
100
|
showSwitchUser && {
|
|
97
101
|
rgItemType,
|
|
98
|
-
label: translations
|
|
102
|
+
label: translations?.switchUser ?? messages.switchUser,
|
|
99
103
|
className: styles.profileMenuItem,
|
|
100
104
|
onClick: onSwitchUser
|
|
101
105
|
},
|
|
102
106
|
showLogOut && {
|
|
103
107
|
rgItemType,
|
|
104
|
-
label: translations
|
|
108
|
+
label: translations?.logout ?? messages.logout,
|
|
105
109
|
onClick: onLogout
|
|
106
110
|
}
|
|
107
111
|
].filter(isTruthy);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export declare const I18nContext: React.Context<{
|
|
3
|
+
login: string;
|
|
4
|
+
logout: string;
|
|
5
|
+
loginTo: string;
|
|
6
|
+
ok: string;
|
|
7
|
+
cancel: string;
|
|
8
|
+
tryAgainLabel: string;
|
|
9
|
+
postpone: string;
|
|
10
|
+
youHaveLoggedInAs: string;
|
|
11
|
+
applyChange: string;
|
|
12
|
+
backendIsNotAvailable: string;
|
|
13
|
+
checkAgain: string;
|
|
14
|
+
nothingHappensLink: string;
|
|
15
|
+
errorMessage: string;
|
|
16
|
+
applyChangedUser: string;
|
|
17
|
+
profile: string;
|
|
18
|
+
switchUser: string;
|
|
19
|
+
addFirstDate: string;
|
|
20
|
+
addSecondDate: string;
|
|
21
|
+
addTime: string;
|
|
22
|
+
selectName: string;
|
|
23
|
+
setDate: string;
|
|
24
|
+
setDateTime: string;
|
|
25
|
+
setPeriod: string;
|
|
26
|
+
clear: string;
|
|
27
|
+
gotIt: string;
|
|
28
|
+
dismiss: string;
|
|
29
|
+
perPage: string;
|
|
30
|
+
firstPage: string;
|
|
31
|
+
lastPage: string;
|
|
32
|
+
nextPage: string;
|
|
33
|
+
previousPage: string;
|
|
34
|
+
searchTitle: string;
|
|
35
|
+
clearTitle: string;
|
|
36
|
+
userAgreement: string;
|
|
37
|
+
accept: string;
|
|
38
|
+
decline: string;
|
|
39
|
+
close: string;
|
|
40
|
+
scrollToAccept: string;
|
|
41
|
+
remindLater: string;
|
|
42
|
+
filterItems: string;
|
|
43
|
+
selectOption: string;
|
|
44
|
+
progress: string;
|
|
45
|
+
loading: string;
|
|
46
|
+
noOptionsFound: string;
|
|
47
|
+
banned: string;
|
|
48
|
+
online: string;
|
|
49
|
+
offline: string;
|
|
50
|
+
copyToClipboard: string;
|
|
51
|
+
copiedToClipboard: string;
|
|
52
|
+
copingToClipboardError: string;
|
|
53
|
+
unverified: string;
|
|
54
|
+
}>;
|