From ca665fae2acff7255bd5a22baafc87cf3c437c41 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Tue, 5 May 2020 19:44:18 -0300 Subject: [PATCH] [NEW] Rewrite admin pages (#17388) Co-authored-by: Maria Eduarda Cunha <42151808+mariaeduardacunha@users.noreply.github.com> Co-authored-by: Tasso Evangelista Co-authored-by: gabriellsh <40830821+gabriellsh@users.noreply.github.com> Co-authored-by: Gabriel Henriques Co-authored-by: Martin Schoeler --- .storybook/.babelrc | 19 - .storybook/addons.js | 4 - .storybook/babel.config.js | 20 + .storybook/config.js | 20 - .storybook/main.js | 11 + .storybook/mocks/meteor.js | 16 +- .storybook/preview.js | 7 + .storybook/webpack.config.js | 38 +- app/api/server/lib/rooms.js | 28 + app/api/server/v1/rooms.js | 43 +- app/api/server/v1/users.js | 3 + app/apps/client/orchestrator.js | 2 +- app/apps/client/routes.js | 2 +- app/authorization/client/route.js | 2 +- app/authorization/client/startup.js | 2 +- .../client/views/Multiselect.js | 2 +- app/chatpal-search/client/route.js | 2 +- app/cloud/client/index.js | 2 +- .../assets/stylesheets/customSoundsAdmin.css | 111 - .../client/admin/adminSoundEdit.html | 7 - .../client/admin/adminSoundInfo.html | 7 - .../client/admin/adminSounds.html | 78 - app/custom-sounds/client/admin/adminSounds.js | 176 - app/custom-sounds/client/admin/route.js | 11 - app/custom-sounds/client/admin/soundEdit.html | 25 - app/custom-sounds/client/admin/soundEdit.js | 155 - app/custom-sounds/client/admin/soundInfo.html | 19 - app/custom-sounds/client/admin/soundInfo.js | 118 - app/custom-sounds/client/admin/startup.js | 11 - app/custom-sounds/client/admin/views.js | 8 - app/custom-sounds/client/index.js | 3 - app/custom-sounds/client/lib/CustomSounds.js | 6 +- .../server/methods/insertOrUpdateSound.js | 2 + .../assets/stylesheets/emojiCustomAdmin.css | 132 - app/emoji-custom/client/admin/adminEmoji.html | 76 - app/emoji-custom/client/admin/adminEmoji.js | 141 - .../client/admin/adminEmojiEdit.html | 7 - .../client/admin/adminEmojiInfo.html | 7 - app/emoji-custom/client/admin/emojiEdit.html | 31 - app/emoji-custom/client/admin/emojiEdit.js | 158 - app/emoji-custom/client/admin/emojiInfo.html | 23 - app/emoji-custom/client/admin/emojiInfo.js | 126 - .../client/admin/emojiPreview.html | 5 - app/emoji-custom/client/admin/route.js | 11 - app/emoji-custom/client/admin/startup.js | 2 +- app/emoji-custom/client/admin/views.js | 9 - app/emoji-custom/client/index.js | 2 - app/federation/client/admin/dashboard.js | 2 +- .../client/ImporterWebsocketReceiver.js | 35 - .../client/admin/importOperationSummary.html | 115 - .../client/functions/showImporterException.js | 41 - app/importer/client/index.js | 3 - app/importer/client/routes.js | 25 - app/integrations/client/route.js | 2 +- app/integrations/client/startup.js | 2 +- app/invites/client/admin/adminInvites.html | 80 - app/invites/client/admin/adminInvites.js | 93 - app/invites/client/admin/route.js | 11 - app/invites/client/admin/startup.js | 11 - app/invites/client/index.js | 2 - app/lib/lib/roomTypes/direct.js | 2 +- app/logger/client/ansispan.js | 34 - app/logger/client/index.js | 1 - app/logger/client/viewLogs.js | 33 - app/logger/client/views/viewLogs.css | 29 - app/logger/client/views/viewLogs.html | 17 - app/logger/client/views/viewLogs.js | 121 - app/mail-messages/client/startup.js | 2 +- .../client/admin/route.js | 2 +- .../client/admin/startup.js | 2 +- app/theme/client/imports/general/base_old.css | 47 - app/theme/client/imports/general/rtl.css | 7 - .../client/components/NotAuthorizedPage.js | 17 - .../info/BuildEnvironmentSection.js | 22 - .../client/components/info/CommitSection.js | 22 - .../client/components/info/DescriptionList.js | 16 - .../components/info/RocketChatSection.js | 29 - .../info/RuntimeEnvironmentSection.js | 31 - .../client/components/info/UsageSection.js | 51 - .../client/components/info/formatters.js | 43 - app/ui-admin/client/hooks/useAdminSideNav.js | 10 - app/ui-admin/client/rooms/adminRoomInfo.html | 102 - app/ui-admin/client/rooms/adminRoomInfo.js | 304 -- app/ui-admin/client/rooms/adminRooms.html | 78 - app/ui-admin/client/rooms/adminRooms.js | 210 - .../client/rooms/channelSettingsDefault.html | 20 - .../client/rooms/channelSettingsDefault.js | 84 - .../client/rooms/channelSettingsFeatured.html | 15 - .../client/rooms/channelSettingsFeatured.js | 65 - app/ui-admin/client/rooms/views.js | 7 - app/ui-admin/client/routes.js | 67 - app/ui-admin/client/sidebarItems.js | 10 - .../client/users/adminInviteUser.html | 31 - app/ui-admin/client/users/adminInviteUser.js | 54 - app/ui-admin/client/users/adminUserEdit.html | 3 - app/ui-admin/client/users/adminUserInfo.html | 9 - app/ui-admin/client/users/adminUsers.html | 101 - app/ui-admin/client/users/adminUsers.js | 183 - app/ui-admin/client/users/views.js | 6 - app/ui-message/client/blocks/MessageBlock.js | 3 +- app/ui-message/client/blocks/ModalBlock.js | 3 +- .../client/messageBox/messageBoxAutogrow.js | 4 +- app/ui-sidenav/client/SortList.js | 8 +- .../GenericTable.js} | 106 +- .../client/components/GenericTable.stories.js | 27 + app/ui/client/views/app/RoomForeword.js | 61 +- .../app/components/Directory/ChannelsTab.js | 80 +- .../components/Directory/Directory.stories.js | 19 - .../views/app/components/Directory/UserTab.js | 76 +- .../views/app/components/Directory/index.js | 27 +- app/ui/client/views/app/components/hooks.js | 98 +- .../client/admin/adminUserStatus.html | 78 - .../client/admin/adminUserStatus.js | 163 - .../client/admin/adminUserStatusEdit.html | 7 - .../client/admin/adminUserStatusInfo.html | 7 - app/user-status/client/admin/route.js | 11 - app/user-status/client/admin/startup.js | 4 +- .../client/admin/userStatusEdit.html | 44 - .../client/admin/userStatusEdit.js | 116 - .../client/admin/userStatusInfo.html | 22 - .../client/admin/userStatusInfo.js | 119 - .../client/admin/userStatusPreview.html | 5 - app/user-status/client/admin/views.js | 9 - app/user-status/client/index.js | 1 - app/utils/client/lib/RestApiClient.js | 7 +- .../admin}/AdministrationRouter.js | 9 +- client/admin/NotAuthorizedPage.js | 17 + .../admin}/NotAuthorizedPage.stories.js | 0 .../admin}/PageSkeleton.js | 10 +- .../admin/PrivateSettingsCachedCollection.js | 4 +- .../client => client/admin}/adminFlex.html | 26 +- .../client => client/admin}/adminFlex.js | 85 +- client/admin/customEmoji/AddCustomEmoji.js | 79 + client/admin/customEmoji/CustomEmoji.js | 44 + .../admin/customEmoji/CustomEmoji.stories.js | 0 client/admin/customEmoji/CustomEmojiRoute.js | 106 + client/admin/customEmoji/EditCustomEmoji.js | 178 + client/admin/customSounds/AddCustomSound.js | 100 + client/admin/customSounds/AdminSounds.js | 56 + client/admin/customSounds/AdminSoundsRoute.js | 109 + client/admin/customSounds/EditCustomSound.js | 201 + client/admin/customSounds/lib.js | 41 + .../customUserStatus/AddCustomUserStatus.js | 60 + .../customUserStatus/CustomUserStatus.js | 46 + .../customUserStatus/CustomUserStatusRoute.js | 106 + .../customUserStatus/EditCustomUserStatus.js | 167 + .../admin/import}/ImportHistoryPage.js | 19 +- .../import}/ImportHistoryPage.stories.js | 0 .../admin/import}/ImportOperationSummary.js | 8 +- .../import}/ImportOperationSummary.stories.js | 0 .../admin/import}/ImportProgressPage.js | 40 +- .../admin/import}/ImportRoute.js | 4 +- .../admin/import}/NewImportPage.js | 32 +- .../admin/import}/NewImportPage.stories.js | 0 .../admin/import}/PrepareImportPage.js | 51 +- client/admin/import/useErrorHandler.js | 34 + .../ui-admin/client => client/admin}/index.js | 1 - client/admin/info/BuildEnvironmentSection.js | 23 + .../info/BuildEnvironmentSection.stories.js | 2 +- client/admin/info/CommitSection.js | 22 + .../admin}/info/CommitSection.stories.js | 0 client/admin/info/DescriptionList.js | 23 + .../admin}/info/DescriptionList.stories.js | 2 +- .../admin}/info/InformationPage.js | 46 +- .../admin}/info/InformationPage.stories.js | 2 +- .../admin}/info/InformationRoute.js | 6 +- .../admin}/info/InstancesSection.js | 14 +- .../admin}/info/InstancesSection.stories.js | 2 +- client/admin/info/RocketChatSection.js | 34 + .../admin}/info/RocketChatSection.stories.js | 2 +- .../admin/info/RuntimeEnvironmentSection.js | 43 + .../info/RuntimeEnvironmentSection.stories.js | 0 client/admin/info/UsageSection.js | 52 + .../admin}/info/UsageSection.stories.js | 0 client/admin/invites/InvitesPage.js | 158 + client/admin/invites/InvitesRoute.js | 17 + .../admin}/mailer/Mailer.js | 40 +- .../admin}/mailer/Mailer.stories.js | 0 .../admin}/mailer/MailerRoute.js | 10 +- client/admin/rooms/EditRoom.js | 191 + client/admin/rooms/RoomsPage.js | 41 + client/admin/rooms/RoomsRoute.js | 17 + client/admin/rooms/RoomsTable.js | 168 + client/admin/routes.js | 110 + .../admin}/settings/GroupPage.js | 12 +- .../admin}/settings/GroupPage.stories.js | 0 .../admin}/settings/GroupSelector.js | 0 .../admin}/settings/GroupSelector.stories.js | 0 .../admin}/settings/ResetSettingButton.js | 2 +- .../settings/ResetSettingButton.stories.js | 0 .../admin}/settings/Section.js | 6 +- .../admin}/settings/Section.stories.js | 0 .../admin}/settings/Setting.js | 6 +- .../admin}/settings/Setting.stories.js | 0 .../admin}/settings/SettingsRoute.js | 4 +- .../admin}/settings/SettingsState.js | 34 +- .../admin}/settings/groups/AssetsGroupPage.js | 6 +- .../settings/groups/GenericGroupPage.js | 0 .../admin}/settings/groups/OAuthGroupPage.js | 10 +- .../settings/inputs/ActionSettingInput.js | 6 +- .../inputs/ActionSettingInput.stories.js | 0 .../settings/inputs/AssetSettingInput.css | 0 .../settings/inputs/AssetSettingInput.js | 6 +- .../inputs/AssetSettingInput.stories.js | 0 .../settings/inputs/BooleanSettingInput.js | 0 .../inputs/BooleanSettingInput.stories.js | 0 .../settings/inputs/CodeSettingInput.js | 4 +- .../inputs/CodeSettingInput.stories.js | 0 .../settings/inputs/ColorSettingInput.js | 2 +- .../inputs/ColorSettingInput.stories.js | 0 .../settings/inputs/FontSettingInput.js | 0 .../inputs/FontSettingInput.stories.js | 0 .../settings/inputs/GenericSettingInput.js | 0 .../inputs/GenericSettingInput.stories.js | 0 .../admin}/settings/inputs/IntSettingInput.js | 0 .../inputs/IntSettingInput.stories.js | 0 .../settings/inputs/LanguageSettingInput.js | 2 +- .../inputs/LanguageSettingInput.stories.js | 0 .../inputs/MultiSelectSettingInput.js | 2 +- .../inputs/MultiSelectSettingInput.stories.js | 0 .../settings/inputs/PasswordSettingInput.js | 0 .../inputs/PasswordSettingInput.stories.js | 0 .../inputs/RelativeUrlSettingInput.js | 2 +- .../inputs/RelativeUrlSettingInput.stories.js | 0 .../settings/inputs/RoomPickSettingInput.js | 0 .../settings/inputs/SelectSettingInput.js | 2 +- .../inputs/SelectSettingInput.stories.js | 0 .../settings/inputs/StringSettingInput.js | 0 .../inputs/StringSettingInput.stories.js | 0 client/admin/sidebarItems.js | 59 + client/admin/users/AddUser.js | 147 + client/admin/users/EditUser.js | 189 + client/admin/users/InviteUsers.js | 35 + client/admin/users/UserInfo.js | 113 + client/admin/users/UserInfoActions.js | 157 + client/admin/users/UsersPage.js | 68 + client/admin/users/UsersRoute.js | 17 + client/admin/users/UsersTable.js | 108 + client/admin/viewLogs/ViewLogs.js | 245 + client/admin/viewLogs/ViewLogs.stories.js | 16 + client/admin/viewLogs/ViewLogsRoute.js | 15 + client/components/basic/BurgerMenuButton.js | 3 +- client/components/basic/Button.js | 27 - client/components/basic/Button.stories.js | 33 - client/components/basic/Icon.js | 22 - client/components/basic/Input.js | 67 - client/components/basic/Input.stories.js | 26 - client/components/basic/Link.js | 11 - client/components/basic/Link.stories.js | 12 - client/components/basic/MarkdownText.js | 6 +- client/components/basic/Modal.js | 45 + client/components/basic/Page.js | 83 +- client/components/basic/Page.stories.js | 2 +- client/components/basic/RawText.js | 4 +- client/components/basic/Subtitle.js | 15 + client/components/basic/VerticalBar.js | 66 + client/components/basic/avatar/RoomAvatar.js | 12 + client/components/basic/avatar/UserAvatar.js | 9 + .../basic/avatar/UserAvatarEditor.js | 54 + .../components/pageNotFound/PageNotFound.css | 17 - .../components/pageNotFound/PageNotFound.js | 26 +- .../pageNotFound/PageNotFound.stories.js | 2 +- client/components/setupWizard/Logo.js | 26 +- client/components/setupWizard/Logo.stories.js | 2 +- .../setupWizard/SetupWizardPage.css | 37 - .../components/setupWizard/SetupWizardPage.js | 39 +- .../setupWizard/SetupWizardPage.stories.js | 2 +- .../setupWizard/SetupWizardRoute.js | 7 +- .../setupWizard/SetupWizardState.js | 6 +- .../setupWizard/SetupWizardState.stories.js | 10 - client/components/setupWizard/SideBar.css | 133 +- client/components/setupWizard/SideBar.js | 93 +- .../components/setupWizard/SideBar.stories.js | 2 +- client/components/setupWizard/StepHeader.js | 2 +- .../steps/AdminUserInformationStep.js | 25 +- .../steps/AdminUserInformationStep.stories.js | 2 +- .../setupWizard/steps/FinalStep.css | 40 - .../components/setupWizard/steps/FinalStep.js | 29 +- .../setupWizard/steps/FinalStep.stories.js | 2 +- .../setupWizard/steps/RegisterServerStep.css | 96 - .../setupWizard/steps/RegisterServerStep.js | 64 +- .../steps/RegisterServerStep.stories.js | 2 +- .../setupWizard/steps/SettingsBasedStep.js | 11 +- .../steps/SettingsBasedStep.stories.js | 2 +- client/contexts/CustomSoundContext.js | 7 + client/contexts/ServerContext.js | 6 + client/hooks/useEndpointAction.js | 26 + .../hooks/useEndpointData.js | 8 +- client/hooks/useEndpointDataExperimental.js | 62 + client/hooks/useEndpointUpload.js | 28 + client/hooks/useEventCallback.js | 13 - client/hooks/useFileInput.js | 25 + client/hooks/useFocus.js | 13 - client/hooks/useFormatDate.js | 9 + client/hooks/useFormatDateAndTime.js | 21 + client/hooks/useFormatDuration.js | 28 + client/hooks/useFormatMemorySize.js | 24 + client/hooks/useFormatTime.js | 22 + client/hooks/useLazyRef.js | 6 - client/hooks/useSafely.js | 24 - client/importPackages.js | 2 - client/main.js | 1 + client/polyfills/index.js | 4 + client/providers/AvatarUrlProvider.js | 14 + client/providers/CustomSoundProvides.js | 9 + client/providers/MeteorProvider.js | 16 +- client/providers/ServerProvider.js | 3 + client/reactAdapters.js | 4 + ee/app/authorization/client/index.ts | 2 +- .../components/ChannelsTab/TableSection.js | 6 +- .../components/EngagementDashboardPage.js | 2 +- .../components/EngagementDashboardRoute.js | 3 - .../MessagesTab/MessagesPerChannelSection.js | 18 +- .../MessagesTab/MessagesSentSection.js | 6 +- .../client/components/Section.js | 2 +- .../components/UsersTab/ActiveUsersSection.js | 6 +- .../UsersTab/BusiestChatTimesSection.js | 8 +- .../components/UsersTab/NewUsersSection.js | 6 +- .../UsersTab/UsersByTimeOfTheDaySection.js | 6 +- .../client/components/data/Counter.js | 6 +- .../client/components/data/Growth.js | 2 +- .../client/components/data/Growth.stories.js | 6 +- .../data/NegativeGrowthSymbol.stories.js | 2 +- .../data/PositiveGrowthSymbol.stories.js | 2 +- ee/app/engagement-dashboard/client/routes.js | 2 +- package-lock.json | 4601 +++++++++-------- package.json | 28 +- packages/rocketchat-i18n/i18n/en.i18n.json | 12 +- private/server/colors.less | 4 - typings.d.ts | 2 + 330 files changed, 7396 insertions(+), 7922 deletions(-) delete mode 100644 .storybook/.babelrc delete mode 100644 .storybook/addons.js create mode 100644 .storybook/babel.config.js delete mode 100644 .storybook/config.js create mode 100644 .storybook/main.js create mode 100644 .storybook/preview.js delete mode 100644 app/custom-sounds/assets/stylesheets/customSoundsAdmin.css delete mode 100644 app/custom-sounds/client/admin/adminSoundEdit.html delete mode 100644 app/custom-sounds/client/admin/adminSoundInfo.html delete mode 100644 app/custom-sounds/client/admin/adminSounds.html delete mode 100644 app/custom-sounds/client/admin/adminSounds.js delete mode 100644 app/custom-sounds/client/admin/route.js delete mode 100644 app/custom-sounds/client/admin/soundEdit.html delete mode 100644 app/custom-sounds/client/admin/soundEdit.js delete mode 100644 app/custom-sounds/client/admin/soundInfo.html delete mode 100644 app/custom-sounds/client/admin/soundInfo.js delete mode 100644 app/custom-sounds/client/admin/startup.js delete mode 100644 app/custom-sounds/client/admin/views.js delete mode 100644 app/emoji-custom/assets/stylesheets/emojiCustomAdmin.css delete mode 100644 app/emoji-custom/client/admin/adminEmoji.html delete mode 100644 app/emoji-custom/client/admin/adminEmoji.js delete mode 100644 app/emoji-custom/client/admin/adminEmojiEdit.html delete mode 100644 app/emoji-custom/client/admin/adminEmojiInfo.html delete mode 100644 app/emoji-custom/client/admin/emojiEdit.html delete mode 100644 app/emoji-custom/client/admin/emojiEdit.js delete mode 100644 app/emoji-custom/client/admin/emojiInfo.html delete mode 100644 app/emoji-custom/client/admin/emojiInfo.js delete mode 100644 app/emoji-custom/client/admin/emojiPreview.html delete mode 100644 app/emoji-custom/client/admin/route.js delete mode 100644 app/emoji-custom/client/admin/views.js delete mode 100644 app/importer/client/ImporterWebsocketReceiver.js delete mode 100644 app/importer/client/admin/importOperationSummary.html delete mode 100644 app/importer/client/functions/showImporterException.js delete mode 100644 app/importer/client/routes.js delete mode 100644 app/invites/client/admin/adminInvites.html delete mode 100644 app/invites/client/admin/adminInvites.js delete mode 100644 app/invites/client/admin/route.js delete mode 100644 app/invites/client/admin/startup.js delete mode 100644 app/invites/client/index.js delete mode 100644 app/logger/client/ansispan.js delete mode 100644 app/logger/client/viewLogs.js delete mode 100644 app/logger/client/views/viewLogs.css delete mode 100644 app/logger/client/views/viewLogs.html delete mode 100644 app/logger/client/views/viewLogs.js delete mode 100644 app/ui-admin/client/components/NotAuthorizedPage.js delete mode 100644 app/ui-admin/client/components/info/BuildEnvironmentSection.js delete mode 100644 app/ui-admin/client/components/info/CommitSection.js delete mode 100644 app/ui-admin/client/components/info/DescriptionList.js delete mode 100644 app/ui-admin/client/components/info/RocketChatSection.js delete mode 100644 app/ui-admin/client/components/info/RuntimeEnvironmentSection.js delete mode 100644 app/ui-admin/client/components/info/UsageSection.js delete mode 100644 app/ui-admin/client/components/info/formatters.js delete mode 100644 app/ui-admin/client/hooks/useAdminSideNav.js delete mode 100644 app/ui-admin/client/rooms/adminRoomInfo.html delete mode 100644 app/ui-admin/client/rooms/adminRoomInfo.js delete mode 100644 app/ui-admin/client/rooms/adminRooms.html delete mode 100644 app/ui-admin/client/rooms/adminRooms.js delete mode 100644 app/ui-admin/client/rooms/channelSettingsDefault.html delete mode 100644 app/ui-admin/client/rooms/channelSettingsDefault.js delete mode 100644 app/ui-admin/client/rooms/channelSettingsFeatured.html delete mode 100644 app/ui-admin/client/rooms/channelSettingsFeatured.js delete mode 100644 app/ui-admin/client/rooms/views.js delete mode 100644 app/ui-admin/client/routes.js delete mode 100644 app/ui-admin/client/sidebarItems.js delete mode 100644 app/ui-admin/client/users/adminInviteUser.html delete mode 100644 app/ui-admin/client/users/adminInviteUser.js delete mode 100644 app/ui-admin/client/users/adminUserEdit.html delete mode 100644 app/ui-admin/client/users/adminUserInfo.html delete mode 100644 app/ui-admin/client/users/adminUsers.html delete mode 100644 app/ui-admin/client/users/adminUsers.js delete mode 100644 app/ui-admin/client/users/views.js rename app/ui/client/{views/app/components/Directory/DirectoryTable.js => components/GenericTable.js} (50%) create mode 100644 app/ui/client/components/GenericTable.stories.js delete mode 100644 app/ui/client/views/app/components/Directory/Directory.stories.js delete mode 100644 app/user-status/client/admin/adminUserStatus.html delete mode 100644 app/user-status/client/admin/adminUserStatus.js delete mode 100644 app/user-status/client/admin/adminUserStatusEdit.html delete mode 100644 app/user-status/client/admin/adminUserStatusInfo.html delete mode 100644 app/user-status/client/admin/route.js delete mode 100644 app/user-status/client/admin/userStatusEdit.html delete mode 100644 app/user-status/client/admin/userStatusEdit.js delete mode 100644 app/user-status/client/admin/userStatusInfo.html delete mode 100644 app/user-status/client/admin/userStatusInfo.js delete mode 100644 app/user-status/client/admin/userStatusPreview.html delete mode 100644 app/user-status/client/admin/views.js rename {app/ui-admin/client/components => client/admin}/AdministrationRouter.js (62%) create mode 100644 client/admin/NotAuthorizedPage.js rename {app/ui-admin/client/components => client/admin}/NotAuthorizedPage.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/PageSkeleton.js (59%) rename app/ui-admin/client/SettingsCachedCollection.js => client/admin/PrivateSettingsCachedCollection.js (80%) rename {app/ui-admin/client => client/admin}/adminFlex.html (59%) rename {app/ui-admin/client => client/admin}/adminFlex.js (51%) create mode 100644 client/admin/customEmoji/AddCustomEmoji.js create mode 100644 client/admin/customEmoji/CustomEmoji.js rename app/ui-admin/README.md => client/admin/customEmoji/CustomEmoji.stories.js (100%) create mode 100644 client/admin/customEmoji/CustomEmojiRoute.js create mode 100644 client/admin/customEmoji/EditCustomEmoji.js create mode 100644 client/admin/customSounds/AddCustomSound.js create mode 100644 client/admin/customSounds/AdminSounds.js create mode 100644 client/admin/customSounds/AdminSoundsRoute.js create mode 100644 client/admin/customSounds/EditCustomSound.js create mode 100644 client/admin/customSounds/lib.js create mode 100644 client/admin/customUserStatus/AddCustomUserStatus.js create mode 100644 client/admin/customUserStatus/CustomUserStatus.js create mode 100644 client/admin/customUserStatus/CustomUserStatusRoute.js create mode 100644 client/admin/customUserStatus/EditCustomUserStatus.js rename {app/importer/client/components => client/admin/import}/ImportHistoryPage.js (86%) rename {app/importer/client/components => client/admin/import}/ImportHistoryPage.stories.js (100%) rename {app/importer/client/components => client/admin/import}/ImportOperationSummary.js (90%) rename {app/importer/client/components => client/admin/import}/ImportOperationSummary.stories.js (100%) rename {app/importer/client/components => client/admin/import}/ImportProgressPage.js (68%) rename {app/importer/client/components => client/admin/import}/ImportRoute.js (80%) rename {app/importer/client/components => client/admin/import}/NewImportPage.js (87%) rename {app/importer/client/components => client/admin/import}/NewImportPage.stories.js (100%) rename {app/importer/client/components => client/admin/import}/PrepareImportPage.js (85%) create mode 100644 client/admin/import/useErrorHandler.js rename {app/ui-admin/client => client/admin}/index.js (82%) create mode 100644 client/admin/info/BuildEnvironmentSection.js rename {app/ui-admin/client/components => client/admin}/info/BuildEnvironmentSection.stories.js (89%) create mode 100644 client/admin/info/CommitSection.js rename {app/ui-admin/client/components => client/admin}/info/CommitSection.stories.js (100%) create mode 100644 client/admin/info/DescriptionList.js rename {app/ui-admin/client/components => client/admin}/info/DescriptionList.stories.js (86%) rename {app/ui-admin/client/components => client/admin}/info/InformationPage.js (51%) rename {app/ui-admin/client/components => client/admin}/info/InformationPage.stories.js (98%) rename {app/ui-admin/client/components => client/admin}/info/InformationRoute.js (89%) rename {app/ui-admin/client/components => client/admin}/info/InstancesSection.js (71%) rename {app/ui-admin/client/components => client/admin}/info/InstancesSection.stories.js (92%) create mode 100644 client/admin/info/RocketChatSection.js rename {app/ui-admin/client/components => client/admin}/info/RocketChatSection.stories.js (92%) create mode 100644 client/admin/info/RuntimeEnvironmentSection.js rename {app/ui-admin/client/components => client/admin}/info/RuntimeEnvironmentSection.stories.js (100%) create mode 100644 client/admin/info/UsageSection.js rename {app/ui-admin/client/components => client/admin}/info/UsageSection.stories.js (100%) create mode 100644 client/admin/invites/InvitesPage.js create mode 100644 client/admin/invites/InvitesRoute.js rename {app/ui-admin/client/components => client/admin}/mailer/Mailer.js (65%) rename {app/ui-admin/client/components => client/admin}/mailer/Mailer.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/mailer/MailerRoute.js (73%) create mode 100644 client/admin/rooms/EditRoom.js create mode 100644 client/admin/rooms/RoomsPage.js create mode 100644 client/admin/rooms/RoomsRoute.js create mode 100644 client/admin/rooms/RoomsTable.js create mode 100644 client/admin/routes.js rename {app/ui-admin/client/components => client/admin}/settings/GroupPage.js (84%) rename {app/ui-admin/client/components => client/admin}/settings/GroupPage.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/GroupSelector.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/GroupSelector.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/ResetSettingButton.js (79%) rename {app/ui-admin/client/components => client/admin}/settings/ResetSettingButton.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/Section.js (86%) rename {app/ui-admin/client/components => client/admin}/settings/Section.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/Setting.js (94%) rename {app/ui-admin/client/components => client/admin}/settings/Setting.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/SettingsRoute.js (76%) rename {app/ui-admin/client/components => client/admin}/settings/SettingsState.js (90%) rename {app/ui-admin/client/components => client/admin}/settings/groups/AssetsGroupPage.js (79%) rename {app/ui-admin/client/components => client/admin}/settings/groups/GenericGroupPage.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/groups/OAuthGroupPage.js (88%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/ActionSettingInput.js (77%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/ActionSettingInput.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/AssetSettingInput.css (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/AssetSettingInput.js (89%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/AssetSettingInput.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/BooleanSettingInput.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/BooleanSettingInput.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/CodeSettingInput.js (95%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/CodeSettingInput.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/ColorSettingInput.js (96%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/ColorSettingInput.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/FontSettingInput.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/FontSettingInput.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/GenericSettingInput.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/GenericSettingInput.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/IntSettingInput.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/IntSettingInput.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/LanguageSettingInput.js (92%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/LanguageSettingInput.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/MultiSelectSettingInput.js (94%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/MultiSelectSettingInput.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/PasswordSettingInput.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/PasswordSettingInput.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/RelativeUrlSettingInput.js (92%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/RelativeUrlSettingInput.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/RoomPickSettingInput.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/SelectSettingInput.js (93%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/SelectSettingInput.stories.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/StringSettingInput.js (100%) rename {app/ui-admin/client/components => client/admin}/settings/inputs/StringSettingInput.stories.js (100%) create mode 100644 client/admin/sidebarItems.js create mode 100644 client/admin/users/AddUser.js create mode 100644 client/admin/users/EditUser.js create mode 100644 client/admin/users/InviteUsers.js create mode 100644 client/admin/users/UserInfo.js create mode 100644 client/admin/users/UserInfoActions.js create mode 100644 client/admin/users/UsersPage.js create mode 100644 client/admin/users/UsersRoute.js create mode 100644 client/admin/users/UsersTable.js create mode 100644 client/admin/viewLogs/ViewLogs.js create mode 100644 client/admin/viewLogs/ViewLogs.stories.js create mode 100644 client/admin/viewLogs/ViewLogsRoute.js delete mode 100644 client/components/basic/Button.js delete mode 100644 client/components/basic/Button.stories.js delete mode 100644 client/components/basic/Icon.js delete mode 100644 client/components/basic/Input.js delete mode 100644 client/components/basic/Input.stories.js delete mode 100644 client/components/basic/Link.js delete mode 100644 client/components/basic/Link.stories.js create mode 100644 client/components/basic/Modal.js create mode 100644 client/components/basic/Subtitle.js create mode 100644 client/components/basic/VerticalBar.js create mode 100644 client/components/basic/avatar/RoomAvatar.js create mode 100644 client/components/basic/avatar/UserAvatar.js create mode 100644 client/components/basic/avatar/UserAvatarEditor.js delete mode 100644 client/components/pageNotFound/PageNotFound.css delete mode 100644 client/components/setupWizard/SetupWizardPage.css delete mode 100644 client/components/setupWizard/SetupWizardState.stories.js delete mode 100644 client/components/setupWizard/steps/FinalStep.css delete mode 100644 client/components/setupWizard/steps/RegisterServerStep.css create mode 100644 client/contexts/CustomSoundContext.js create mode 100644 client/hooks/useEndpointAction.js rename {ee/app/engagement-dashboard/client => client}/hooks/useEndpointData.js (72%) create mode 100644 client/hooks/useEndpointDataExperimental.js create mode 100644 client/hooks/useEndpointUpload.js delete mode 100644 client/hooks/useEventCallback.js create mode 100644 client/hooks/useFileInput.js delete mode 100644 client/hooks/useFocus.js create mode 100644 client/hooks/useFormatDate.js create mode 100644 client/hooks/useFormatDateAndTime.js create mode 100644 client/hooks/useFormatDuration.js create mode 100644 client/hooks/useFormatMemorySize.js create mode 100644 client/hooks/useFormatTime.js delete mode 100644 client/hooks/useLazyRef.js delete mode 100644 client/hooks/useSafely.js create mode 100644 client/providers/AvatarUrlProvider.js create mode 100644 client/providers/CustomSoundProvides.js create mode 100644 typings.d.ts diff --git a/.storybook/.babelrc b/.storybook/.babelrc deleted file mode 100644 index 97ab12b7f95..00000000000 --- a/.storybook/.babelrc +++ /dev/null @@ -1,19 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "shippedProposals": true, - "useBuiltIns": "usage", - "corejs": "3", - "modules": "commonjs" - } - ], - "@babel/preset-react", - "@babel/preset-flow" - ], - "plugins": [ - "@babel/plugin-proposal-class-properties", - "@babel/plugin-proposal-optional-chaining" - ] -} diff --git a/.storybook/addons.js b/.storybook/addons.js deleted file mode 100644 index 9d64a3d0a8f..00000000000 --- a/.storybook/addons.js +++ /dev/null @@ -1,4 +0,0 @@ -import '@storybook/addon-actions/register'; -import '@storybook/addon-knobs/register'; -import '@storybook/addon-links/register'; -import '@storybook/addon-viewport/register'; diff --git a/.storybook/babel.config.js b/.storybook/babel.config.js new file mode 100644 index 00000000000..f028aa2d294 --- /dev/null +++ b/.storybook/babel.config.js @@ -0,0 +1,20 @@ +module.exports = { + presets: [ + [ + '@babel/preset-env', + { + shippedProposals: true, + useBuiltIns: 'usage', + corejs: '3', + modules: 'commonjs', + }, + ], + '@babel/preset-react', + '@babel/preset-flow', + ], + plugins: [ + '@babel/plugin-proposal-class-properties', + '@babel/plugin-proposal-optional-chaining', + '@babel/plugin-proposal-nullish-coalescing-operator', + ], +}; diff --git a/.storybook/config.js b/.storybook/config.js deleted file mode 100644 index c7fb95b2124..00000000000 --- a/.storybook/config.js +++ /dev/null @@ -1,20 +0,0 @@ -import { withKnobs } from '@storybook/addon-knobs'; -import { MINIMAL_VIEWPORTS } from '@storybook/addon-viewport/dist/defaults'; -import { addDecorator, addParameters, configure } from '@storybook/react'; - -import { rocketChatDecorator } from './mocks/decorators'; - -addParameters({ - viewport: { - viewports: MINIMAL_VIEWPORTS, - }, -}); - -addDecorator(rocketChatDecorator); -addDecorator(withKnobs); - -configure([ - require.context('../app', true, /\.stories\.js$/), - require.context('../client', true, /\.stories\.js$/), - require.context('../ee/app', true, /\.stories\.js$/), -], module); diff --git a/.storybook/main.js b/.storybook/main.js new file mode 100644 index 00000000000..2b53b2635b3 --- /dev/null +++ b/.storybook/main.js @@ -0,0 +1,11 @@ +module.exports = { + stories: [ + '../app/**/*.stories.js', + '../client/**/*.stories.js', + '../ee/app/**/*.stories.js', + ], + addons: [ + '@storybook/addon-actions', + '@storybook/addon-knobs', + ], +}; diff --git a/.storybook/mocks/meteor.js b/.storybook/mocks/meteor.js index d85c752a2b2..a690a4db684 100644 --- a/.storybook/mocks/meteor.js +++ b/.storybook/mocks/meteor.js @@ -4,7 +4,10 @@ export const Meteor = { _localStorage: window.localStorage, absoluteUrl: () => {}, userId: () => {}, - Streamer: () => {}, + Streamer: () => ({ + on: () => {}, + removeListener: () => {}, + }), startup: () => {}, methods: () => {}, call: () => {}, @@ -31,10 +34,13 @@ export const Mongo = { }), }; -export const ReactiveVar = () => ({ - get: () => {}, - set: () => {}, -}); +export const ReactiveVar = (val) => { + let currentVal = val; + return { + get: () => currentVal, + set: (val) => { currentVal = val; }, + }; +}; export const ReactiveDict = () => ({ get: () => {}, diff --git a/.storybook/preview.js b/.storybook/preview.js new file mode 100644 index 00000000000..c4b6fca4894 --- /dev/null +++ b/.storybook/preview.js @@ -0,0 +1,7 @@ +import { withKnobs } from '@storybook/addon-knobs'; +import { addDecorator } from '@storybook/react'; + +import { rocketChatDecorator } from './mocks/decorators'; + +addDecorator(rocketChatDecorator); +addDecorator(withKnobs); diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js index 03a6a91feed..1d47404d267 100644 --- a/.storybook/webpack.config.js +++ b/.storybook/webpack.config.js @@ -31,15 +31,35 @@ module.exports = async ({ config }) => { use: '@settlin/spacebars-loader', }); - config.plugins.push(new webpack.NormalModuleReplacementPlugin( - /^meteor/, - require.resolve('./mocks/meteor.js'), - )); - - config.plugins.push(new webpack.NormalModuleReplacementPlugin( - /\.\/server\/index.js/, - require.resolve('./mocks/empty.js'), - )); + config.module.rules.push({ + test: /\.(ts|tsx)$/, + use: [ + { + loader: 'ts-loader', + options: { + compilerOptions: { + noEmit: false, + }, + }, + }, + { + loader: 'react-docgen-typescript-loader', + }, + ], + }); + + config.resolve.extensions.push('.ts', '.tsx'); + + config.plugins.push( + new webpack.NormalModuleReplacementPlugin( + /^meteor/, + require.resolve('./mocks/meteor.js'), + ), + new webpack.NormalModuleReplacementPlugin( + /\/server(\/index.js)$/, + require.resolve('./mocks/empty.js'), + ), + ); config.mode = 'development'; config.optimization.usedExports = true; diff --git a/app/api/server/lib/rooms.js b/app/api/server/lib/rooms.js index 94eb63685f3..b9e73acbfa6 100644 --- a/app/api/server/lib/rooms.js +++ b/app/api/server/lib/rooms.js @@ -56,6 +56,34 @@ export async function findAdminRooms({ uid, filter, types = [], pagination: { of }; } +export async function findAdminRoom({ uid, rid }) { + if (!await hasPermissionAsync(uid, 'view-room-administration')) { + throw new Error('error-not-authorized'); + } + const fields = { + prid: 1, + fname: 1, + name: 1, + t: 1, + cl: 1, + u: 1, + usernames: 1, + usersCount: 1, + muted: 1, + unmuted: 1, + ro: 1, + default: 1, + favorite: 1, + featured: 1, + topic: 1, + msgs: 1, + archived: 1, + tokenpass: 1, + }; + + return Rooms.findOneById(rid, { fields }); +} + export async function findChannelAndPrivateAutocomplete({ uid, selector }) { if (!await hasPermissionAsync(uid, 'view-other-user-channels')) { return { items: [] }; diff --git a/app/api/server/v1/rooms.js b/app/api/server/v1/rooms.js index 2f8a7df23e0..86711691782 100644 --- a/app/api/server/v1/rooms.js +++ b/app/api/server/v1/rooms.js @@ -4,7 +4,7 @@ import Busboy from 'busboy'; import { FileUpload } from '../../../file-upload'; import { Rooms, Messages } from '../../../models'; import { API } from '../api'; -import { findAdminRooms, findChannelAndPrivateAutocomplete } from '../lib/rooms'; +import { findAdminRooms, findChannelAndPrivateAutocomplete, findAdminRoom } from '../lib/rooms'; function findRoomByIdOrName({ params, checkedArchived = true }) { if ((!params.roomId || !params.roomId.trim()) && (!params.roomName || !params.roomName.trim())) { @@ -299,6 +299,22 @@ API.v1.addRoute('rooms.adminRooms', { authRequired: true }, { }, }); +API.v1.addRoute('rooms.adminRooms.getRoom', { authRequired: true }, { + get() { + const { rid } = this.requestParams(); + const room = Promise.await(findAdminRoom({ + uid: this.userId, + rid, + })); + + if (!room) { + return API.v1.failure('not-allowed', 'Not Allowed'); + } + return API.v1.success(room); + }, +}); + + API.v1.addRoute('rooms.autocomplete.channelAndPrivate', { authRequired: true }, { get() { const { selector } = this.queryParams; @@ -312,3 +328,28 @@ API.v1.addRoute('rooms.autocomplete.channelAndPrivate', { authRequired: true }, }))); }, }); + +API.v1.addRoute('rooms.saveRoomSettings', { authRequired: true }, { + post() { + const { rid, ...params } = this.bodyParams; + + const result = Meteor.runAsUser(this.userId, () => Meteor.call('saveRoomSettings', rid, params)); + + return API.v1.success({ rid: result.rid }); + }, +}); + +API.v1.addRoute('rooms.changeArchivationState', { authRequired: true }, { + post() { + const { rid, action } = this.bodyParams; + + let result; + if (action === 'archive') { + result = Meteor.runAsUser(this.userId, () => Meteor.call('archiveRoom', rid)); + } else { + result = Meteor.runAsUser(this.userId, () => Meteor.call('unarchiveRoom', rid)); + } + + return API.v1.success({ result }); + }, +}); diff --git a/app/api/server/v1/users.js b/app/api/server/v1/users.js index 0598d8a430a..5a8be4493a0 100644 --- a/app/api/server/v1/users.js +++ b/app/api/server/v1/users.js @@ -30,6 +30,8 @@ API.v1.addRoute('users.create', { authRequired: true }, { password: String, username: String, active: Match.Maybe(Boolean), + bio: Match.Maybe(String), + statusText: Match.Maybe(String), roles: Match.Maybe(Array), joinDefaultChannels: Match.Maybe(Boolean), requirePasswordChange: Match.Maybe(Boolean), @@ -431,6 +433,7 @@ API.v1.addRoute('users.update', { authRequired: true, twoFactorRequired: true }, name: Match.Maybe(String), password: Match.Maybe(String), username: Match.Maybe(String), + bio: Match.Maybe(String), statusText: Match.Maybe(String), active: Match.Maybe(Boolean), roles: Match.Maybe(Array), diff --git a/app/apps/client/orchestrator.js b/app/apps/client/orchestrator.js index 54c614044fe..0b7bdfd5883 100644 --- a/app/apps/client/orchestrator.js +++ b/app/apps/client/orchestrator.js @@ -4,7 +4,7 @@ import toastr from 'toastr'; import { AppWebsocketReceiver } from './communication'; import { APIClient } from '../../utils'; -import { registerAdminSidebarItem } from '../../ui-admin/client'; +import { registerAdminSidebarItem } from '../../../client/admin'; import { CachedCollectionManager } from '../../ui-cached-collection'; import { hasAtLeastOnePermission } from '../../authorization'; import { handleI18nResources } from './i18n'; diff --git a/app/apps/client/routes.js b/app/apps/client/routes.js index 66005d26b87..c8ff516040e 100644 --- a/app/apps/client/routes.js +++ b/app/apps/client/routes.js @@ -1,7 +1,7 @@ import { FlowRouter } from 'meteor/kadira:flow-router'; import { BlazeLayout } from 'meteor/kadira:blaze-layout'; -import { registerAdminRoute } from '../../ui-admin/client'; +import { registerAdminRoute } from '../../../client/admin'; import { Apps } from './orchestrator'; registerAdminRoute('/apps/what-is-it', { diff --git a/app/authorization/client/route.js b/app/authorization/client/route.js index 95ccd464cc4..2a09c78da6d 100644 --- a/app/authorization/client/route.js +++ b/app/authorization/client/route.js @@ -1,6 +1,6 @@ import { BlazeLayout } from 'meteor/kadira:blaze-layout'; -import { registerAdminRoute } from '../../ui-admin/client'; +import { registerAdminRoute } from '../../../client/admin'; import { t } from '../../utils/client'; registerAdminRoute('/permissions', { diff --git a/app/authorization/client/startup.js b/app/authorization/client/startup.js index 9e437c26c05..2dd50b95fa2 100644 --- a/app/authorization/client/startup.js +++ b/app/authorization/client/startup.js @@ -2,7 +2,7 @@ import { Meteor } from 'meteor/meteor'; import { Tracker } from 'meteor/tracker'; import { hasAtLeastOnePermission } from './hasPermission'; -import { registerAdminSidebarItem } from '../../ui-admin/client'; +import { registerAdminSidebarItem } from '../../../client/admin'; import { CachedCollectionManager } from '../../ui-cached-collection'; import { APIClient } from '../../utils/client'; import { Roles } from '../../models/client'; diff --git a/app/channel-settings/client/views/Multiselect.js b/app/channel-settings/client/views/Multiselect.js index a63fa1981cd..1f90cc45a38 100644 --- a/app/channel-settings/client/views/Multiselect.js +++ b/app/channel-settings/client/views/Multiselect.js @@ -4,7 +4,7 @@ import { createTemplateForComponent } from '../../../../client/reactAdapters'; createTemplateForComponent( 'Multiselect', - () => import('../../../ui-admin/client/components/settings/inputs/MultiSelectSettingInput'), + () => import('../../../../client/admin/settings/inputs/MultiSelectSettingInput'), { // eslint-disable-next-line new-cap renderContainerView: () => HTML.DIV({ class: 'rc-multiselect', style: 'display: flex;' }), diff --git a/app/chatpal-search/client/route.js b/app/chatpal-search/client/route.js index 86c6ad276c4..29695aa215a 100644 --- a/app/chatpal-search/client/route.js +++ b/app/chatpal-search/client/route.js @@ -1,6 +1,6 @@ import { BlazeLayout } from 'meteor/kadira:blaze-layout'; -import { registerAdminRoute } from '../../ui-admin/client'; +import { registerAdminRoute } from '../../../client/admin'; import { t } from '../../utils'; registerAdminRoute('/chatpal', { diff --git a/app/cloud/client/index.js b/app/cloud/client/index.js index 0c8025d22db..ce6ceecd3d5 100644 --- a/app/cloud/client/index.js +++ b/app/cloud/client/index.js @@ -4,7 +4,7 @@ import './admin/cloudRegisterManually'; import { BlazeLayout } from 'meteor/kadira:blaze-layout'; -import { registerAdminRoute, registerAdminSidebarItem } from '../../ui-admin/client'; +import { registerAdminRoute, registerAdminSidebarItem } from '../../../client/admin'; import { hasAtLeastOnePermission } from '../../authorization'; registerAdminRoute('/cloud', { diff --git a/app/custom-sounds/assets/stylesheets/customSoundsAdmin.css b/app/custom-sounds/assets/stylesheets/customSoundsAdmin.css deleted file mode 100644 index c96075a621e..00000000000 --- a/app/custom-sounds/assets/stylesheets/customSoundsAdmin.css +++ /dev/null @@ -1,111 +0,0 @@ -.sound-info { - & .icon-play-circled { - cursor: pointer; - } -} - -.sound-view { - z-index: 15; - - overflow-x: hidden; - overflow-y: auto; - - & .thumb { - width: 100%; - height: 350px; - padding: 20px; - } - - & nav { - padding: 0 20px; - } - - & .info { - padding: 0 20px; - - white-space: normal; - - & h3 { - overflow: hidden; - - width: 100%; - margin: 8px 0; - - user-select: text; - white-space: nowrap; - text-overflow: ellipsis; - - font-size: 24px; - line-height: 27px; - - & i::after { - display: inline-block; - - width: 8px; - height: 8px; - - content: " "; - vertical-align: middle; - - border-radius: 4px; - } - } - - & p { - -webkit-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; - - font-size: 12px; - font-weight: 300; - line-height: 18px; - } - } - - & .edit-form { - padding: 20px 20px 0; - - white-space: normal; - - & h3 { - margin-bottom: 8px; - - font-size: 24px; - line-height: 22px; - } - - & p { - font-size: 12px; - font-weight: 300; - line-height: 18px; - } - - & > .input-line { - margin-top: 20px; - } - - & nav { - padding: 0; - - &.buttons { - margin-top: 2em; - } - } - - & .form-divisor { - height: 9px; - margin: 2em 0; - - text-align: center; - - & > span { - padding: 0 1em; - } - } - } - - & .room-info-content > div { - margin: 0 0 20px; - } -} diff --git a/app/custom-sounds/client/admin/adminSoundEdit.html b/app/custom-sounds/client/admin/adminSoundEdit.html deleted file mode 100644 index c6f4ef42f9b..00000000000 --- a/app/custom-sounds/client/admin/adminSoundEdit.html +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/app/custom-sounds/client/admin/adminSoundInfo.html b/app/custom-sounds/client/admin/adminSoundInfo.html deleted file mode 100644 index f9676c22303..00000000000 --- a/app/custom-sounds/client/admin/adminSoundInfo.html +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/app/custom-sounds/client/admin/adminSounds.html b/app/custom-sounds/client/admin/adminSounds.html deleted file mode 100644 index c9a20bd9c4f..00000000000 --- a/app/custom-sounds/client/admin/adminSounds.html +++ /dev/null @@ -1,78 +0,0 @@ - diff --git a/app/custom-sounds/client/admin/adminSounds.js b/app/custom-sounds/client/admin/adminSounds.js deleted file mode 100644 index 9de092e3c14..00000000000 --- a/app/custom-sounds/client/admin/adminSounds.js +++ /dev/null @@ -1,176 +0,0 @@ -import { ReactiveVar } from 'meteor/reactive-var'; -import { Tracker } from 'meteor/tracker'; -import { FlowRouter } from 'meteor/kadira:flow-router'; -import { Template } from 'meteor/templating'; -import _ from 'underscore'; - -import { RocketChatTabBar, SideNav, TabBar } from '../../../ui-utils'; -import { CustomSounds } from '../lib/CustomSounds'; -import { APIClient } from '../../../utils/client'; - -const LIST_SIZE = 50; -const DEBOUNCE_TIME_TO_SEARCH_IN_MS = 500; - -Template.adminSounds.helpers({ - searchText() { - const instance = Template.instance(); - return instance.filter && instance.filter.get(); - }, - isPlaying(_id) { - return Template.instance().isPlayingId.get() === _id; - }, - customsounds() { - return Template.instance().sounds.get(); - }, - isLoading() { - return Template.instance().isLoading.get(); - }, - flexData() { - return { - tabBar: Template.instance().tabBar, - data: Template.instance().tabBarData.get(), - }; - }, - - onTableScroll() { - const instance = Template.instance(); - return function(currentTarget) { - if (currentTarget.offsetHeight + currentTarget.scrollTop < currentTarget.scrollHeight - 100) { - return; - } - const sounds = instance.sounds.get(); - if (instance.total.get() > sounds.length) { - instance.offset.set(instance.offset.get() + LIST_SIZE); - } - }; - }, - onTableItemClick() { - const instance = Template.instance(); - return function(item) { - instance.tabBarData.set({ - sound: instance.sounds.get().find((sound) => sound._id === item._id), - onSuccess: instance.onSuccessCallback, - }); - instance.tabBar.showGroup('custom-sounds-selected'); - instance.tabBar.open('admin-sound-info'); - }; - }, -}); - -Template.adminSounds.onCreated(function() { - const instance = this; - this.sounds = new ReactiveVar([]); - this.offset = new ReactiveVar(0); - this.total = new ReactiveVar(0); - this.query = new ReactiveVar({}); - this.isLoading = new ReactiveVar(false); - this.filter = new ReactiveVar(''); - this.isPlayingId = new ReactiveVar(''); - - this.tabBar = new RocketChatTabBar(); - this.tabBar.showGroup(FlowRouter.current().route.name); - this.tabBarData = new ReactiveVar(); - - TabBar.addButton({ - groups: ['custom-sounds', 'custom-sounds-selected'], - id: 'add-sound', - i18nTitle: 'Custom_Sound_Add', - icon: 'plus', - template: 'adminSoundEdit', - order: 1, - }); - - TabBar.addButton({ - groups: ['custom-sounds-selected'], - id: 'admin-sound-info', - i18nTitle: 'Custom_Sound_Info', - icon: 'customize', - template: 'adminSoundInfo', - order: 2, - }); - - this.onSuccessCallback = () => { - this.offset.set(0); - return this.loadSounds(this.query.get(), this.offset.get()); - }; - - this.tabBarData.set({ - onSuccess: instance.onSuccessCallback, - }); - - this.loadSounds = _.debounce(async (query, offset) => { - this.isLoading.set(true); - const { sounds, total } = await APIClient.v1.get(`custom-sounds.list?count=${ LIST_SIZE }&offset=${ offset }&query=${ JSON.stringify(query) }`); - this.total.set(total); - if (offset === 0) { - this.sounds.set(sounds); - } else { - this.sounds.set(this.sounds.get().concat(sounds)); - } - this.isLoading.set(false); - }, DEBOUNCE_TIME_TO_SEARCH_IN_MS); - - this.autorun(() => { - const filter = this.filter.get() && this.filter.get().trim(); - const offset = this.offset.get(); - if (filter) { - const regex = { $regex: filter, $options: 'i' }; - return this.loadSounds({ name: regex }, offset); - } - return this.loadSounds({}, offset); - }); -}); - -Template.adminSounds.onRendered(() => - Tracker.afterFlush(function() { - SideNav.setFlex('adminFlex'); - SideNav.openFlex(); - }), -); - -Template.adminSounds.events({ - 'keydown #sound-filter'(e) { - // stop enter key - if (e.which === 13) { - e.stopPropagation(); - e.preventDefault(); - } - }, - 'keyup #sound-filter'(e, t) { - e.stopPropagation(); - e.preventDefault(); - t.filter.set(e.currentTarget.value); - t.offset.set(0); - }, - 'click .icon-play-circled'(e, t) { - e.preventDefault(); - e.stopPropagation(); - CustomSounds.play(this._id); - const audio = document.getElementById(t.isPlayingId.get()); - if (audio) { - audio.pause(); - } - document.getElementById(this._id).onended = () => { - t.isPlayingId.set(''); - this.onended = null; - }; - t.isPlayingId.set(this._id); - }, - 'click .icon-pause-circled'(e, t) { - e.preventDefault(); - e.stopPropagation(); - const audio = document.getElementById(this._id); - if (audio && !audio.paused) { - audio.pause(); - } - t.isPlayingId.set(''); - }, - 'click .icon-reset-circled'(e) { - e.preventDefault(); - e.stopPropagation(); - const audio = document.getElementById(this._id); - if (audio) { - audio.currentTime = 0; - } - }, -}); diff --git a/app/custom-sounds/client/admin/route.js b/app/custom-sounds/client/admin/route.js deleted file mode 100644 index 0f181fda578..00000000000 --- a/app/custom-sounds/client/admin/route.js +++ /dev/null @@ -1,11 +0,0 @@ -import { BlazeLayout } from 'meteor/kadira:blaze-layout'; - -import { registerAdminRoute } from '../../../ui-admin/client'; - -registerAdminRoute('/custom-sounds', { - name: 'custom-sounds', - async action(/* params*/) { - await import('./views'); - BlazeLayout.render('main', { center: 'adminSounds' }); - }, -}); diff --git a/app/custom-sounds/client/admin/soundEdit.html b/app/custom-sounds/client/admin/soundEdit.html deleted file mode 100644 index 63caf62d4dd..00000000000 --- a/app/custom-sounds/client/admin/soundEdit.html +++ /dev/null @@ -1,25 +0,0 @@ - diff --git a/app/custom-sounds/client/admin/soundEdit.js b/app/custom-sounds/client/admin/soundEdit.js deleted file mode 100644 index cffe9c92d10..00000000000 --- a/app/custom-sounds/client/admin/soundEdit.js +++ /dev/null @@ -1,155 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { Template } from 'meteor/templating'; -import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; -import toastr from 'toastr'; -import s from 'underscore.string'; - -import { t, handleError } from '../../../utils'; - -Template.soundEdit.helpers({ - sound() { - return Template.instance().sound; - }, - - name() { - return this.name || this._id; - }, -}); - -Template.soundEdit.events({ - 'click .cancel'(e, t) { - e.stopPropagation(); - e.preventDefault(); - delete Template.instance().soundFile; - t.cancel(t.find('form')); - }, - - 'submit form'(e, t) { - e.stopPropagation(); - e.preventDefault(); - t.save(e.currentTarget); - }, - - 'change input[type=file]'(ev) { - const e = ev.originalEvent != null ? ev.originalEvent : ev; - let { files } = e.target; - if (e.target.files == null || files.length === 0) { - if (e.dataTransfer.files != null) { - files = e.dataTransfer.files; - } else { - files = []; - } - } - - // using let x of y here seems to have incompatibility with some phones - for (const file in files) { - if (files.hasOwnProperty(file)) { - Template.instance().soundFile = files[file]; - } - } - }, -}); - -Template.soundEdit.onCreated(function() { - if (this.data != null) { - this.sound = this.data.sound; - } else { - this.sound = undefined; - this.data.tabBar.showGroup('custom-sounds'); - } - this.onSuccess = Template.currentData().onSuccess; - this.cancel = (form, name) => { - form.reset(); - this.data.tabBar.close(); - if (this.sound) { - this.data.back(name); - } - }; - - this.getSoundData = () => { - const soundData = {}; - if (this.sound != null) { - soundData._id = this.sound._id; - soundData.previousName = this.sound.name; - soundData.extension = this.sound.extension; - soundData.previousExtension = this.sound.extension; - } - soundData.name = s.trim(this.$('#name').val()); - soundData.newFile = false; - return soundData; - }; - - this.validate = () => { - const soundData = this.getSoundData(); - - const errors = []; - if (!soundData.name) { - errors.push('Name'); - } - - if (!soundData._id) { - if (!this.soundFile) { - errors.push('Sound_File_mp3'); - } - } - - for (const error of errors) { - toastr.error(TAPi18n.__('error-the-field-is-required', { field: TAPi18n.__(error) })); - } - - if (this.soundFile) { - if (!/audio\/mp3/.test(this.soundFile.type) && !/audio\/mpeg/.test(this.soundFile.type) && !/audio\/x-mpeg/.test(this.soundFile.type)) { - errors.push('FileType'); - toastr.error(TAPi18n.__('error-invalid-file-type')); - } - } - - return errors.length === 0; - }; - - this.save = (form) => { - if (this.validate()) { - const soundData = this.getSoundData(); - - if (this.soundFile) { - soundData.newFile = true; - soundData.extension = this.soundFile.name.split('.').pop(); - soundData.type = this.soundFile.type; - } - - Meteor.call('insertOrUpdateSound', soundData, (error, result) => { - if (result) { - soundData._id = result; - soundData.random = Math.round(Math.random() * 1000); - - if (this.soundFile) { - toastr.info(TAPi18n.__('Uploading_file')); - - const reader = new FileReader(); - reader.readAsBinaryString(this.soundFile); - reader.onloadend = () => { - Meteor.call('uploadCustomSound', reader.result, this.soundFile.type, soundData, (uploadError/* , data*/) => { - if (uploadError != null) { - handleError(uploadError); - console.log(uploadError); - } - }, - ); - delete this.soundFile; - toastr.success(TAPi18n.__('File_uploaded')); - }; - } - - toastr.success(t('Custom_Sound_Saved_Successfully')); - this.onSuccess(); - - this.cancel(form, soundData.name); - } - - if (error) { - handleError(error); - } - }); - } - }; -}); diff --git a/app/custom-sounds/client/admin/soundInfo.html b/app/custom-sounds/client/admin/soundInfo.html deleted file mode 100644 index 09374f00609..00000000000 --- a/app/custom-sounds/client/admin/soundInfo.html +++ /dev/null @@ -1,19 +0,0 @@ - diff --git a/app/custom-sounds/client/admin/soundInfo.js b/app/custom-sounds/client/admin/soundInfo.js deleted file mode 100644 index a27c74a03b2..00000000000 --- a/app/custom-sounds/client/admin/soundInfo.js +++ /dev/null @@ -1,118 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { Template } from 'meteor/templating'; - -import { modal } from '../../../ui-utils'; -import { t, handleError } from '../../../utils'; - -Template.soundInfo.helpers({ - name() { - const sound = Template.instance().sound.get(); - return sound.name; - }, - - sound() { - return Template.instance().sound.get(); - }, - - editingSound() { - return Template.instance().editingSound.get(); - }, - - soundToEdit() { - const instance = Template.instance(); - return { - tabBar: instance.data.tabBar, - data: instance.data.data, - sound: instance.sound.get(), - onSuccess: instance.onSuccess, - back(name) { - instance.editingSound.set(); - - if (name != null) { - const sound = instance.sound.get(); - if (sound.name != null && sound.name !== name) { - return instance.loadedName.set(name); - } - } - }, - }; - }, -}); - -Template.soundInfo.events({ - 'click .delete'(e, instance) { - e.stopPropagation(); - e.preventDefault(); - const sound = instance.sound.get(); - if (sound != null) { - const { _id } = sound; - modal.open({ - title: t('Are_you_sure'), - text: t('Custom_Sound_Delete_Warning'), - type: 'warning', - showCancelButton: true, - confirmButtonColor: '#DD6B55', - confirmButtonText: t('Yes_delete_it'), - cancelButtonText: t('Cancel'), - closeOnConfirm: false, - html: false, - }, function() { - Meteor.call('deleteCustomSound', _id, (error/* , result*/) => { - if (error) { - handleError(error); - } else { - modal.open({ - title: t('Deleted'), - text: t('Custom_Sound_Has_Been_Deleted'), - type: 'success', - timer: 2000, - showConfirmButton: false, - }); - instance.onSuccess(); - instance.data.tabBar.showGroup('custom-sounds'); - instance.data.tabBar.close(); - } - }); - }); - } - }, - - 'click .edit-sound'(e, instance) { - e.stopPropagation(); - e.preventDefault(); - - instance.editingSound.set(instance.sound.get()._id); - }, -}); - -Template.soundInfo.onCreated(function() { - this.sound = new ReactiveVar(); - - this.editingSound = new ReactiveVar(); - - this.loadedName = new ReactiveVar(); - this.onSuccess = Template.currentData().onSuccess; - - this.autorun(() => { - const data = Template.currentData(); - if (data && data.clear != null) { - this.clear = data.clear; - } - }); - - this.autorun(() => { - const data = Template.currentData().sound; - const sound = this.sound.get(); - if (sound && sound.name != null) { - this.loadedName.set(sound.name); - } else if (data.name != null) { - this.loadedName.set(data.name); - } - }); - - this.autorun(() => { - const data = Template.currentData().sound; - this.sound.set(data); - }); -}); diff --git a/app/custom-sounds/client/admin/startup.js b/app/custom-sounds/client/admin/startup.js deleted file mode 100644 index 2647b17ea42..00000000000 --- a/app/custom-sounds/client/admin/startup.js +++ /dev/null @@ -1,11 +0,0 @@ -import { hasAtLeastOnePermission } from '../../../authorization'; -import { registerAdminSidebarItem } from '../../../ui-admin/client'; - -registerAdminSidebarItem({ - href: 'custom-sounds', - i18nLabel: 'Custom_Sounds', - icon: 'volume', - permissionGranted() { - return hasAtLeastOnePermission(['manage-sounds']); - }, -}); diff --git a/app/custom-sounds/client/admin/views.js b/app/custom-sounds/client/admin/views.js deleted file mode 100644 index 3a2397b2bda..00000000000 --- a/app/custom-sounds/client/admin/views.js +++ /dev/null @@ -1,8 +0,0 @@ -import './adminSoundEdit.html'; -import './adminSoundInfo.html'; -import './adminSounds.html'; -import './adminSounds'; -import './soundEdit.html'; -import './soundEdit'; -import './soundInfo.html'; -import './soundInfo'; diff --git a/app/custom-sounds/client/index.js b/app/custom-sounds/client/index.js index eb17166ef2b..77706dca50e 100644 --- a/app/custom-sounds/client/index.js +++ b/app/custom-sounds/client/index.js @@ -1,7 +1,4 @@ import './notifications/deleteCustomSound'; import './notifications/updateCustomSound'; -import './admin/route'; -import './admin/startup'; -import '../assets/stylesheets/customSoundsAdmin.css'; export { CustomSounds } from './lib/CustomSounds'; diff --git a/app/custom-sounds/client/lib/CustomSounds.js b/app/custom-sounds/client/lib/CustomSounds.js index 09c175ac6c0..a0422581f6a 100644 --- a/app/custom-sounds/client/lib/CustomSounds.js +++ b/app/custom-sounds/client/lib/CustomSounds.js @@ -4,6 +4,8 @@ import _ from 'underscore'; import { CachedCollectionManager } from '../../../ui-cached-collection'; +const getCustomSoundId = (sound) => `custom-sound-${ sound }`; + class CustomSoundsClass { constructor() { this.list = new ReactiveVar({}); @@ -19,7 +21,7 @@ class CustomSoundsClass { if (!sound.src) { sound.src = this.getURL(sound); } - const audio = $('