diff --git a/app/authorization/client/startup.js b/app/authorization/client/startup.js
index 5f26b56bbdf4e..a9cf0250f45c2 100644
--- a/app/authorization/client/startup.js
+++ b/app/authorization/client/startup.js
@@ -13,9 +13,10 @@ Meteor.startup(() => {
CachedCollectionManager.onLogin(async () => {
const { roles } = await APIClient.v1.get('roles.list');
// if a role is checked before this collection is populated, it will return undefined
- for await (const role of roles) {
- await Roles.upsert({ _id: role._id }, role);
- }
+ Roles._collection._docs._map = Object.fromEntries(roles.map((record) => [record._id, record]));
+ Object.values(Roles._collection.queries).forEach((query) => Roles._collection._recomputeResults(query));
+
+ Roles.ready.set(true);
});
registerAdminSidebarItem({
diff --git a/app/lib/client/lib/settings.js b/app/lib/client/lib/settings.js
index 62806990bd6ad..5d909e0a2d395 100644
--- a/app/lib/client/lib/settings.js
+++ b/app/lib/client/lib/settings.js
@@ -1,48 +1,58 @@
import { Meteor } from 'meteor/meteor';
import { Tracker } from 'meteor/tracker';
+import toastr from 'toastr';
import { t } from '../../../utils';
-import { modal } from '../../../ui-utils';
import { settings } from '../../../settings';
import { hasRole } from '../../../authorization';
+import { Roles } from '../../../models/client';
+import { imperativeModal } from '../../../../client/lib/imperativeModal';
+import UrlChangeModal from '../../../../client/components/UrlChangeModal';
+import { isSyncReady } from '../../../../client/lib/userData';
Meteor.startup(function() {
Tracker.autorun(function(c) {
- const siteUrl = settings.get('Site_Url');
- if (!siteUrl || (Meteor.userId() == null)) {
+ if (!Meteor.userId()) {
+ return;
+ }
+
+ if (!Roles.ready.get() || !isSyncReady.get()) {
return;
}
+
if (hasRole(Meteor.userId(), 'admin') === false) {
return c.stop();
}
- Meteor.setTimeout(function() {
- const currentUrl = location.origin + __meteor_runtime_config__.ROOT_URL_PATH_PREFIX;
- if (__meteor_runtime_config__.ROOT_URL.replace(/\/$/, '') !== currentUrl) {
- modal.open({
- type: 'warning',
- title: t('Warning'),
- text: `${ t('The_setting_s_is_configured_to_s_and_you_are_accessing_from_s', t('Site_Url'), siteUrl, currentUrl) }
${ t('Do_you_want_to_change_to_s_question', currentUrl) }`,
- showCancelButton: true,
- confirmButtonText: t('Yes'),
- cancelButtonText: t('Cancel'),
- closeOnConfirm: false,
- html: true,
- }, function() {
- Meteor.call('saveSetting', 'Site_Url', currentUrl, function() {
- modal.open({
- title: t('Saved'),
- type: 'success',
- timer: 1000,
- showConfirmButton: false,
- });
- });
+
+ const siteUrl = settings.get('Site_Url');
+ if (!siteUrl) {
+ return;
+ }
+
+ const currentUrl = location.origin + __meteor_runtime_config__.ROOT_URL_PATH_PREFIX;
+ if (__meteor_runtime_config__.ROOT_URL.replace(/\/$/, '') !== currentUrl) {
+ const confirm = () => {
+ imperativeModal.close();
+ Meteor.call('saveSetting', 'Site_Url', currentUrl, function() {
+ toastr.success(t('Saved'));
});
- }
- }, 100);
+ };
+ imperativeModal.open({
+ component: UrlChangeModal,
+ props: {
+ onConfirm: confirm,
+ siteUrl,
+ currentUrl,
+ onClose: imperativeModal.close,
+ },
+ });
+ }
+
const documentDomain = settings.get('Document_Domain');
if (documentDomain) {
window.document.domain = documentDomain;
}
+
return c.stop();
});
});
diff --git a/app/models/client/models/Roles.js b/app/models/client/models/Roles.js
index b0acacdfd1842..ed4ed9fc71e61 100644
--- a/app/models/client/models/Roles.js
+++ b/app/models/client/models/Roles.js
@@ -1,4 +1,5 @@
import { Mongo } from 'meteor/mongo';
+import { ReactiveVar } from 'meteor/reactive-var';
import * as Models from '..';
@@ -21,6 +22,8 @@ Object.assign(Roles, {
return model && model.isUserInRole && model.isUserInRole(userId, roleName, scope);
});
},
+
+ ready: new ReactiveVar(false),
});
export { Roles };
diff --git a/client/components/UrlChangeModal.tsx b/client/components/UrlChangeModal.tsx
new file mode 100644
index 0000000000000..df4db6caf581b
--- /dev/null
+++ b/client/components/UrlChangeModal.tsx
@@ -0,0 +1,49 @@
+import { Box } from '@rocket.chat/fuselage';
+import React, { ReactElement } from 'react';
+
+import { useTranslation } from '../contexts/TranslationContext';
+import GenericModal from './GenericModal';
+
+type UrlChangeModalProps = {
+ onConfirm: () => void;
+ siteUrl: string;
+ currentUrl: string;
+ onClose: () => void;
+};
+
+const UrlChangeModal = ({
+ onConfirm,
+ siteUrl,
+ currentUrl,
+ onClose,
+}: UrlChangeModalProps): ReactElement => {
+ const t = useTranslation();
+ return (
+
+
+
+
+ );
+};
+
+export default UrlChangeModal;