From ed7ff1f01d3f08f1b5608fb9eb8d9883a79cf053 Mon Sep 17 00:00:00 2001 From: gabriellsh <40830821+gabriellsh@users.noreply.github.com> Date: Sat, 22 Aug 2020 00:41:39 -0300 Subject: [PATCH] Omnichannel Admin rewritten in React (#18438) Co-authored-by: Martin Schoeler Co-authored-by: Tasso Evangelista Co-authored-by: Guilherme Gazzo --- .eslintrc | 3 + .storybook/main.js | 2 +- app/api/server/v1/users.js | 1 + app/livechat/client/index.js | 1 - app/livechat/client/route.js | 129 +- app/livechat/client/ui.js | 4 +- app/livechat/client/views/admin.js | 15 - .../livechatBusinessHoursForm.html | 65 - .../livechatBusinessHoursForm.js | 186 -- .../livechatMainBusinessHours.html | 5 - .../livechatMainBusinessHours.js | 10 - .../livechatIntegrationFacebook.html | 43 - .../livechatIntegrationFacebook.js | 157 - .../livechatIntegrationWebhook.html | 88 - .../livechatIntegrationWebhook.js | 146 - .../client/views/app/livechatAgents.html | 103 - .../client/views/app/livechatAgents.js | 234 -- .../client/views/app/livechatAppearance.html | 145 - .../client/views/app/livechatAppearance.js | 345 -- .../client/views/app/livechatCurrentChats.css | 25 - .../views/app/livechatCurrentChats.html | 196 -- .../client/views/app/livechatCurrentChats.js | 519 --- .../views/app/livechatCustomFieldForm.html | 57 - .../views/app/livechatCustomFieldForm.js | 100 - .../views/app/livechatCustomFields.html | 37 - .../client/views/app/livechatCustomFields.js | 83 - .../views/app/livechatInstallation.html | 10 - .../client/views/app/livechatInstallation.js | 21 - .../client/views/app/livechatManagers.html | 88 - .../client/views/app/livechatManagers.js | 192 -- .../client/views/app/livechatTriggers.html | 33 - .../client/views/app/livechatTriggers.js | 62 - .../views/app/livechatTriggersForm.html | 62 - .../client/views/app/livechatTriggersForm.js | 118 - .../app/triggers/livechatTriggerAction.html | 20 - .../app/triggers/livechatTriggerAction.js | 54 - .../triggers/livechatTriggerCondition.html | 18 - .../app/triggers/livechatTriggerCondition.js | 34 - .../client/views/sideNav/livechatFlex.html | 19 - .../client/views/sideNav/livechatFlex.js | 34 - .../views/sideNav/livechatSideNavItems.js | 27 - app/ui-sidenav/client/sidebarHeader.js | 21 +- client/account/AccountSidebar.js | 8 +- client/admin/AdministrationRouter.js | 2 +- client/admin/apps/AppsRoute.js | 2 +- client/admin/routes.js | 26 +- client/admin/sidebar/AdminSidebar.js | 8 +- client/admin/users/EditUser.js | 4 +- client/components/GenericTable.js | 3 +- client/{admin => components}/PageSkeleton.js | 2 +- client/components/basic/AutoComplete.js | 23 + .../components/basic/AutoComplete.stories.js | 10 + client/components/basic/ExternalLink.js | 10 - client/components/basic/ExternalLink.tsx | 13 + client/components/basic/{Page.js => Page.tsx} | 52 +- client/components/basic/Sidebar.js | 2 +- client/components/basic/TextCopy.js | 30 +- client/components/basic/UserInfo.js | 8 +- client/contexts/ConnectionStatusContext.js | 11 - client/contexts/ConnectionStatusContext.ts | 20 + client/contexts/CustomSoundContext.js | 7 - client/contexts/CustomSoundContext.ts | 12 + client/contexts/RouterContext.js | 83 - client/contexts/RouterContext.ts | 156 + client/contexts/ServerContext.ts | 18 +- client/contexts/SidebarContext.js | 5 - client/contexts/SidebarContext.ts | 8 + client/contexts/ToastMessagesContext.js | 7 - client/contexts/ToastMessagesContext.ts | 19 + client/helpers/createRouteGroup.js | 30 + ...ntal.js => useEndpointDataExperimental.ts} | 42 +- client/hooks/useForm.ts | 25 +- client/hooks/useTimezoneNameList.js | 4 + client/omnichannel/DeleteWarningModal.js | 23 + client/omnichannel/OmnichannelRouter.tsx | 22 + client/omnichannel/additionalForms.js | 26 + client/omnichannel/agents/AgentEdit.js | 154 + client/omnichannel/agents/AgentInfo.js | 77 + client/omnichannel/agents/AgentsPage.js | 72 + client/omnichannel/agents/AgentsRoute.js | 170 + client/omnichannel/agents/Skeleton.js | 11 + .../appearance/AppearanceForm.stories.js | 10 + .../omnichannel/appearance/AppearanceForm.tsx | 251 ++ .../omnichannel/appearance/AppearancePage.tsx | 128 + .../businessHours/BusinessHoursForm.js | 37 + .../BusinessHoursForm.stories.js | 25 + .../BusinessHoursFormContainer.js | 56 + .../businessHours/BusinessHoursPage.js | 36 + .../businessHours/BusinessHoursRouter.js | 41 + .../businessHours/EditBusinessHoursPage.js | 122 + .../businessHours/NewBusinessHoursPage.js | 97 + .../businessHours/TimeRangeFieldsAssembler.js | 29 + .../businessHours/TimeRangeInput.js | 43 + .../businessHours/mapBusinessHoursForm.js | 13 + .../currentChats/CurrentChatsPage.js | 174 + .../currentChats/CurrentChatsRoute.js | 137 + .../customFields/CustomFieldsForm.js | 66 + .../customFields/CustomFieldsForm.stories.js | 24 + .../customFields/CustomFieldsPage.js | 29 + .../customFields/CustomFieldsRouter.js | 27 + .../customFields/CustomFieldsTable.js | 124 + .../customFields/CustomFieldsTable.stories.js | 39 + .../customFields/EditCustomFieldsPage.js | 114 + .../customFields/NewCustomFieldsPage.js | 84 + client/omnichannel/facebook/FacebookPage.tsx | 216 ++ .../omnichannel/installation/Installation.js | 56 + .../installation/Installation.stories.js | 10 + client/omnichannel/managers/ManagersPage.js | 71 + client/omnichannel/managers/ManagersRoute.js | 98 + client/omnichannel/routes.js | 75 + .../sidebar/OmnichannelSidebar.tsx | 45 + client/omnichannel/sidebarItems.js | 62 + .../omnichannel/triggers/EditTriggerPage.js | 113 + client/omnichannel/triggers/NewTriggerPage.js | 74 + .../triggers/TriggersForm.stories.js | 36 + client/omnichannel/triggers/TriggersForm.tsx | 185 ++ client/omnichannel/triggers/TriggersPage.js | 63 + client/omnichannel/triggers/TriggersTable.js | 145 + client/omnichannel/webhooks/WebhooksPage.js | 196 ++ client/providers/RouterProvider.js | 101 - client/providers/RouterProvider.tsx | 89 + client/providers/SidebarProvider.js | 15 - client/providers/SidebarProvider.tsx | 21 + client/providers/ToastMessagesProvider.js | 20 - client/providers/ToastMessagesProvider.tsx | 25 + client/types/fuselage.d.ts | 252 ++ client/types/kadira-flow-router.d.ts | 142 + client/{ => types}/main.d.ts | 0 client/{ => types}/meteor.d.ts | 0 client/{ => types}/window.d.ts | 0 definition/ISetting.ts | 2 +- ee/app/livechat-enterprise/client/index.js | 8 - ee/app/livechat-enterprise/client/route.js | 60 +- ee/app/livechat-enterprise/client/startup.ts | 13 - .../businessHoursCustomFieldsForm.html | 48 - .../businessHoursCustomFieldsForm.js | 89 - .../customTemplates/businessHoursFormField.js | 34 - .../businessHoursTimezoneFormField.html | 13 - .../livechatAgentEditCustomFieldsForm.html | 12 - .../livechatAgentEditCustomFieldsForm.js | 21 - .../livechatAgentInfoCustomFieldsForm.html | 6 - .../livechatAgentInfoCustomFieldsForm.js | 24 - .../livechatCustomFieldsAdditionalForm.html | 42 - .../livechatCustomFieldsAdditionalForm.js | 37 - .../views/app/registerCustomTemplates.js | 8 - .../business-hours/livechatBusinessHours.html | 86 - .../business-hours/livechatBusinessHours.js | 133 - .../client/views/livechatMonitors.html | 91 - .../client/views/livechatMonitors.js | 200 -- .../client/views/livechatPriorities.html | 30 - .../client/views/livechatPriorities.js | 97 - .../client/views/livechatPriorityForm.html | 35 - .../client/views/livechatPriorityForm.js | 77 - .../client/views/livechatSideNavItems.js | 30 +- .../client/views/livechatTagForm.html | 77 - .../client/views/livechatTagForm.js | 116 - .../client/views/livechatTags.html | 30 - .../client/views/livechatTags.js | 97 - .../client/views/livechatUnitForm.html | 135 - .../client/views/livechatUnitForm.js | 249 -- .../client/views/livechatUnits.html | 30 - .../client/views/livechatUnits.js | 96 - ee/client/hooks/useHasLicense.js | 18 + ee/client/index.js | 1 + ee/client/omnichannel/BusinessHoursTable.js | 138 + .../omnichannel/BusinessHoursTable.stories.js | 49 + ee/client/omnichannel/MonitorsPage.js | 98 + ee/client/omnichannel/MonitorsTable.js | 119 + .../additionalForms/BusinessHoursMultiple.js | 75 + .../BusinessHoursMultiple.stories.js | 19 + .../additionalForms/BusinessHoursTimeZone.js | 36 + .../BusinessHoursTimeZone.stories.js | 13 + .../CustomFieldsAdditionalForm.js | 120 + .../additionalForms/MaxChatsPerAgent.js | 29 + .../MaxChatsPerAgentDisplay.js | 15 + .../omnichannel/additionalForms/register.js | 18 + ee/client/omnichannel/index.js | 2 + .../omnichannel/priorities/EditPriority.js | 115 + .../omnichannel/priorities/PrioritiesPage.js | 59 + .../omnichannel/priorities/PrioritiesRoute.js | 130 + ee/client/omnichannel/priorities/Skeleton.js | 11 + ee/client/omnichannel/routes.js | 11 + ee/client/omnichannel/tags/CurrentChatTags.js | 13 + ee/client/omnichannel/tags/EditTag.js | 130 + ee/client/omnichannel/tags/Skeleton.js | 11 + ee/client/omnichannel/tags/TagsPage.js | 59 + ee/client/omnichannel/tags/TagsRoute.js | 131 + ee/client/omnichannel/units/EditUnit.js | 163 + ee/client/omnichannel/units/Skeleton.js | 11 + ee/client/omnichannel/units/UnitsPage.js | 59 + ee/client/omnichannel/units/UnitsRoute.js | 131 + ee/i18n/en.i18n.json | 4 +- package-lock.json | 2912 +++++++++++------ package.json | 17 +- packages/rocketchat-i18n/i18n/en.i18n.json | 13 +- tsconfig.json | 2 +- 196 files changed, 8503 insertions(+), 6788 deletions(-) delete mode 100644 app/livechat/client/views/app/business-hours/livechatBusinessHoursForm.html delete mode 100644 app/livechat/client/views/app/business-hours/livechatBusinessHoursForm.js delete mode 100644 app/livechat/client/views/app/business-hours/livechatMainBusinessHours.html delete mode 100644 app/livechat/client/views/app/business-hours/livechatMainBusinessHours.js delete mode 100644 app/livechat/client/views/app/integrations/livechatIntegrationFacebook.html delete mode 100644 app/livechat/client/views/app/integrations/livechatIntegrationFacebook.js delete mode 100644 app/livechat/client/views/app/integrations/livechatIntegrationWebhook.html delete mode 100644 app/livechat/client/views/app/integrations/livechatIntegrationWebhook.js delete mode 100644 app/livechat/client/views/app/livechatAgents.html delete mode 100644 app/livechat/client/views/app/livechatAgents.js delete mode 100644 app/livechat/client/views/app/livechatAppearance.html delete mode 100644 app/livechat/client/views/app/livechatAppearance.js delete mode 100644 app/livechat/client/views/app/livechatCurrentChats.css delete mode 100644 app/livechat/client/views/app/livechatCurrentChats.html delete mode 100644 app/livechat/client/views/app/livechatCurrentChats.js delete mode 100644 app/livechat/client/views/app/livechatCustomFieldForm.html delete mode 100644 app/livechat/client/views/app/livechatCustomFieldForm.js delete mode 100644 app/livechat/client/views/app/livechatCustomFields.html delete mode 100644 app/livechat/client/views/app/livechatCustomFields.js delete mode 100644 app/livechat/client/views/app/livechatInstallation.html delete mode 100644 app/livechat/client/views/app/livechatInstallation.js delete mode 100644 app/livechat/client/views/app/livechatManagers.html delete mode 100644 app/livechat/client/views/app/livechatManagers.js delete mode 100644 app/livechat/client/views/app/livechatTriggers.html delete mode 100644 app/livechat/client/views/app/livechatTriggers.js delete mode 100644 app/livechat/client/views/app/livechatTriggersForm.html delete mode 100644 app/livechat/client/views/app/livechatTriggersForm.js delete mode 100644 app/livechat/client/views/app/triggers/livechatTriggerAction.html delete mode 100644 app/livechat/client/views/app/triggers/livechatTriggerAction.js delete mode 100644 app/livechat/client/views/app/triggers/livechatTriggerCondition.html delete mode 100644 app/livechat/client/views/app/triggers/livechatTriggerCondition.js delete mode 100644 app/livechat/client/views/sideNav/livechatFlex.html delete mode 100644 app/livechat/client/views/sideNav/livechatFlex.js delete mode 100644 app/livechat/client/views/sideNav/livechatSideNavItems.js rename client/{admin => components}/PageSkeleton.js (93%) create mode 100644 client/components/basic/AutoComplete.js create mode 100644 client/components/basic/AutoComplete.stories.js delete mode 100644 client/components/basic/ExternalLink.js create mode 100644 client/components/basic/ExternalLink.tsx rename client/components/basic/{Page.js => Page.tsx} (62%) delete mode 100644 client/contexts/ConnectionStatusContext.js create mode 100644 client/contexts/ConnectionStatusContext.ts delete mode 100644 client/contexts/CustomSoundContext.js create mode 100644 client/contexts/CustomSoundContext.ts delete mode 100644 client/contexts/RouterContext.js create mode 100644 client/contexts/RouterContext.ts delete mode 100644 client/contexts/SidebarContext.js create mode 100644 client/contexts/SidebarContext.ts delete mode 100644 client/contexts/ToastMessagesContext.js create mode 100644 client/contexts/ToastMessagesContext.ts create mode 100644 client/helpers/createRouteGroup.js rename client/hooks/{useEndpointDataExperimental.js => useEndpointDataExperimental.ts} (54%) create mode 100644 client/hooks/useTimezoneNameList.js create mode 100644 client/omnichannel/DeleteWarningModal.js create mode 100644 client/omnichannel/OmnichannelRouter.tsx create mode 100644 client/omnichannel/additionalForms.js create mode 100644 client/omnichannel/agents/AgentEdit.js create mode 100644 client/omnichannel/agents/AgentInfo.js create mode 100644 client/omnichannel/agents/AgentsPage.js create mode 100644 client/omnichannel/agents/AgentsRoute.js create mode 100644 client/omnichannel/agents/Skeleton.js create mode 100644 client/omnichannel/appearance/AppearanceForm.stories.js create mode 100644 client/omnichannel/appearance/AppearanceForm.tsx create mode 100644 client/omnichannel/appearance/AppearancePage.tsx create mode 100644 client/omnichannel/businessHours/BusinessHoursForm.js create mode 100644 client/omnichannel/businessHours/BusinessHoursForm.stories.js create mode 100644 client/omnichannel/businessHours/BusinessHoursFormContainer.js create mode 100644 client/omnichannel/businessHours/BusinessHoursPage.js create mode 100644 client/omnichannel/businessHours/BusinessHoursRouter.js create mode 100644 client/omnichannel/businessHours/EditBusinessHoursPage.js create mode 100644 client/omnichannel/businessHours/NewBusinessHoursPage.js create mode 100644 client/omnichannel/businessHours/TimeRangeFieldsAssembler.js create mode 100644 client/omnichannel/businessHours/TimeRangeInput.js create mode 100644 client/omnichannel/businessHours/mapBusinessHoursForm.js create mode 100644 client/omnichannel/currentChats/CurrentChatsPage.js create mode 100644 client/omnichannel/currentChats/CurrentChatsRoute.js create mode 100644 client/omnichannel/customFields/CustomFieldsForm.js create mode 100644 client/omnichannel/customFields/CustomFieldsForm.stories.js create mode 100644 client/omnichannel/customFields/CustomFieldsPage.js create mode 100644 client/omnichannel/customFields/CustomFieldsRouter.js create mode 100644 client/omnichannel/customFields/CustomFieldsTable.js create mode 100644 client/omnichannel/customFields/CustomFieldsTable.stories.js create mode 100644 client/omnichannel/customFields/EditCustomFieldsPage.js create mode 100644 client/omnichannel/customFields/NewCustomFieldsPage.js create mode 100644 client/omnichannel/facebook/FacebookPage.tsx create mode 100644 client/omnichannel/installation/Installation.js create mode 100644 client/omnichannel/installation/Installation.stories.js create mode 100644 client/omnichannel/managers/ManagersPage.js create mode 100644 client/omnichannel/managers/ManagersRoute.js create mode 100644 client/omnichannel/routes.js create mode 100644 client/omnichannel/sidebar/OmnichannelSidebar.tsx create mode 100644 client/omnichannel/sidebarItems.js create mode 100644 client/omnichannel/triggers/EditTriggerPage.js create mode 100644 client/omnichannel/triggers/NewTriggerPage.js create mode 100644 client/omnichannel/triggers/TriggersForm.stories.js create mode 100644 client/omnichannel/triggers/TriggersForm.tsx create mode 100644 client/omnichannel/triggers/TriggersPage.js create mode 100644 client/omnichannel/triggers/TriggersTable.js create mode 100644 client/omnichannel/webhooks/WebhooksPage.js delete mode 100644 client/providers/RouterProvider.js create mode 100644 client/providers/RouterProvider.tsx delete mode 100644 client/providers/SidebarProvider.js create mode 100644 client/providers/SidebarProvider.tsx delete mode 100644 client/providers/ToastMessagesProvider.js create mode 100644 client/providers/ToastMessagesProvider.tsx create mode 100644 client/types/fuselage.d.ts create mode 100644 client/types/kadira-flow-router.d.ts rename client/{ => types}/main.d.ts (100%) rename client/{ => types}/meteor.d.ts (100%) rename client/{ => types}/window.d.ts (100%) delete mode 100644 ee/app/livechat-enterprise/client/views/app/customTemplates/businessHoursCustomFieldsForm.html delete mode 100644 ee/app/livechat-enterprise/client/views/app/customTemplates/businessHoursCustomFieldsForm.js delete mode 100644 ee/app/livechat-enterprise/client/views/app/customTemplates/businessHoursFormField.js delete mode 100644 ee/app/livechat-enterprise/client/views/app/customTemplates/businessHoursTimezoneFormField.html delete mode 100644 ee/app/livechat-enterprise/client/views/app/customTemplates/livechatAgentEditCustomFieldsForm.html delete mode 100644 ee/app/livechat-enterprise/client/views/app/customTemplates/livechatAgentEditCustomFieldsForm.js delete mode 100644 ee/app/livechat-enterprise/client/views/app/customTemplates/livechatAgentInfoCustomFieldsForm.html delete mode 100644 ee/app/livechat-enterprise/client/views/app/customTemplates/livechatAgentInfoCustomFieldsForm.js delete mode 100644 ee/app/livechat-enterprise/client/views/app/customTemplates/livechatCustomFieldsAdditionalForm.html delete mode 100644 ee/app/livechat-enterprise/client/views/app/customTemplates/livechatCustomFieldsAdditionalForm.js delete mode 100644 ee/app/livechat-enterprise/client/views/business-hours/livechatBusinessHours.html delete mode 100644 ee/app/livechat-enterprise/client/views/business-hours/livechatBusinessHours.js delete mode 100644 ee/app/livechat-enterprise/client/views/livechatMonitors.html delete mode 100644 ee/app/livechat-enterprise/client/views/livechatMonitors.js delete mode 100644 ee/app/livechat-enterprise/client/views/livechatPriorities.html delete mode 100644 ee/app/livechat-enterprise/client/views/livechatPriorities.js delete mode 100644 ee/app/livechat-enterprise/client/views/livechatPriorityForm.html delete mode 100644 ee/app/livechat-enterprise/client/views/livechatPriorityForm.js delete mode 100644 ee/app/livechat-enterprise/client/views/livechatTagForm.html delete mode 100644 ee/app/livechat-enterprise/client/views/livechatTagForm.js delete mode 100644 ee/app/livechat-enterprise/client/views/livechatTags.html delete mode 100644 ee/app/livechat-enterprise/client/views/livechatTags.js delete mode 100644 ee/app/livechat-enterprise/client/views/livechatUnitForm.html delete mode 100644 ee/app/livechat-enterprise/client/views/livechatUnitForm.js delete mode 100644 ee/app/livechat-enterprise/client/views/livechatUnits.html delete mode 100644 ee/app/livechat-enterprise/client/views/livechatUnits.js create mode 100644 ee/client/hooks/useHasLicense.js create mode 100644 ee/client/omnichannel/BusinessHoursTable.js create mode 100644 ee/client/omnichannel/BusinessHoursTable.stories.js create mode 100644 ee/client/omnichannel/MonitorsPage.js create mode 100644 ee/client/omnichannel/MonitorsTable.js create mode 100644 ee/client/omnichannel/additionalForms/BusinessHoursMultiple.js create mode 100644 ee/client/omnichannel/additionalForms/BusinessHoursMultiple.stories.js create mode 100644 ee/client/omnichannel/additionalForms/BusinessHoursTimeZone.js create mode 100644 ee/client/omnichannel/additionalForms/BusinessHoursTimeZone.stories.js create mode 100644 ee/client/omnichannel/additionalForms/CustomFieldsAdditionalForm.js create mode 100644 ee/client/omnichannel/additionalForms/MaxChatsPerAgent.js create mode 100644 ee/client/omnichannel/additionalForms/MaxChatsPerAgentDisplay.js create mode 100644 ee/client/omnichannel/additionalForms/register.js create mode 100644 ee/client/omnichannel/index.js create mode 100644 ee/client/omnichannel/priorities/EditPriority.js create mode 100644 ee/client/omnichannel/priorities/PrioritiesPage.js create mode 100644 ee/client/omnichannel/priorities/PrioritiesRoute.js create mode 100644 ee/client/omnichannel/priorities/Skeleton.js create mode 100644 ee/client/omnichannel/routes.js create mode 100644 ee/client/omnichannel/tags/CurrentChatTags.js create mode 100644 ee/client/omnichannel/tags/EditTag.js create mode 100644 ee/client/omnichannel/tags/Skeleton.js create mode 100644 ee/client/omnichannel/tags/TagsPage.js create mode 100644 ee/client/omnichannel/tags/TagsRoute.js create mode 100644 ee/client/omnichannel/units/EditUnit.js create mode 100644 ee/client/omnichannel/units/Skeleton.js create mode 100644 ee/client/omnichannel/units/UnitsPage.js create mode 100644 ee/client/omnichannel/units/UnitsRoute.js diff --git a/.eslintrc b/.eslintrc index 84f6452c94e..ff4471548fc 100644 --- a/.eslintrc +++ b/.eslintrc @@ -73,12 +73,15 @@ "@typescript-eslint" ], "rules": { + "func-call-spacing": "off", "jsx-quotes": [ "error", "prefer-single" ], "indent": "off", "no-extra-parens": "off", + "no-spaced-func": "off", + "no-useless-constructor": "off", "react/jsx-uses-react": "error", "react/jsx-uses-vars": "error", "react/jsx-no-undef": "error", diff --git a/.storybook/main.js b/.storybook/main.js index d3ce1eb94ef..c1730b0e818 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -2,7 +2,7 @@ module.exports = { stories: [ '../app/**/*.stories.js', '../client/**/*.stories.js', - '../ee/app/**/*.stories.js', + '../ee/**/*.stories.js', ], addons: [ '@storybook/addon-actions', diff --git a/app/api/server/v1/users.js b/app/api/server/v1/users.js index c41ff7e90d9..222f47c1038 100644 --- a/app/api/server/v1/users.js +++ b/app/api/server/v1/users.js @@ -771,6 +771,7 @@ API.v1.addRoute('users.requestDataDownload', { authRequired: true }, { API.v1.addRoute('users.autocomplete', { authRequired: true }, { get() { const { selector } = this.queryParams; + if (!selector) { return API.v1.failure('The \'selector\' param is required'); } diff --git a/app/livechat/client/index.js b/app/livechat/client/index.js index 0174884f532..de62b38f780 100644 --- a/app/livechat/client/index.js +++ b/app/livechat/client/index.js @@ -7,6 +7,5 @@ import './startup/notifyUnreadRooms'; import './views/app/dialog/closeRoom'; import './stylesheets/livechat.css'; import './views/sideNav/livechat'; -import './views/sideNav/livechatFlex'; import './externalFrame'; import './lib/messageTypes'; diff --git a/app/livechat/client/route.js b/app/livechat/client/route.js index b2e488bad93..98be3912c97 100644 --- a/app/livechat/client/route.js +++ b/app/livechat/client/route.js @@ -1,10 +1,11 @@ import { FlowRouter } from 'meteor/kadira:flow-router'; import { AccountBox } from '../../ui-utils'; +import '../../../client/omnichannel/routes'; export const livechatManagerRoutes = FlowRouter.group({ - prefix: '/livechat-manager', - name: 'livechat-manager', + prefix: '/omnichannel', + name: 'omnichannel', }); export const load = () => import('./views/admin'); @@ -12,23 +13,15 @@ export const load = () => import('./views/admin'); AccountBox.addRoute({ name: 'livechat-dashboard', path: '/dashboard', - sideNav: 'livechatFlex', + sideNav: 'omnichannelFlex', i18nPageTitle: 'Livechat_Dashboard', pageTemplate: 'livechatDashboard', }, livechatManagerRoutes, load); -AccountBox.addRoute({ - name: 'livechat-current-chats', - path: '/current', - sideNav: 'livechatFlex', - i18nPageTitle: 'Current_Chats', - pageTemplate: 'livechatCurrentChats', -}, livechatManagerRoutes, load); - AccountBox.addRoute({ name: 'livechat-analytics', path: '/analytics', - sideNav: 'livechatFlex', + sideNav: 'omnichannelFlex', i18nPageTitle: 'Analytics', pageTemplate: 'livechatAnalytics', }, livechatManagerRoutes, load); @@ -36,31 +29,15 @@ AccountBox.addRoute({ AccountBox.addRoute({ name: 'livechat-real-time-monitoring', path: '/real-time-monitoring', - sideNav: 'livechatFlex', + sideNav: 'omnichannelFlex', i18nPageTitle: 'Real_Time_Monitoring', pageTemplate: 'livechatRealTimeMonitoring', }, livechatManagerRoutes, load); -AccountBox.addRoute({ - name: 'livechat-managers', - path: '/managers', - sideNav: 'livechatFlex', - i18nPageTitle: 'Livechat_Managers', - pageTemplate: 'livechatManagers', -}, livechatManagerRoutes, load); - -AccountBox.addRoute({ - name: 'livechat-agents', - path: '/agents', - sideNav: 'livechatFlex', - pageTemplate: 'livechatAgents', - customContainer: true, -}, livechatManagerRoutes, load); - AccountBox.addRoute({ name: 'livechat-departments', path: '/departments', - sideNav: 'livechatFlex', + sideNav: 'omnichannelFlex', i18nPageTitle: 'Departments', pageTemplate: 'livechatDepartments', }, livechatManagerRoutes, load); @@ -68,7 +45,7 @@ AccountBox.addRoute({ AccountBox.addRoute({ name: 'livechat-department-edit', path: '/departments/:_id/edit', - sideNav: 'livechatFlex', + sideNav: 'omnichannelFlex', i18nPageTitle: 'Edit_Department', pageTemplate: 'livechatDepartmentForm', customContainer: true, @@ -77,100 +54,12 @@ AccountBox.addRoute({ AccountBox.addRoute({ name: 'livechat-department-new', path: '/departments/new', - sideNav: 'livechatFlex', + sideNav: 'omnichannelFlex', i18nPageTitle: 'New_Department', pageTemplate: 'livechatDepartmentForm', customContainer: true, }, livechatManagerRoutes, load); -AccountBox.addRoute({ - name: 'livechat-triggers', - path: '/triggers', - sideNav: 'livechatFlex', - i18nPageTitle: 'Triggers', - pageTemplate: 'livechatTriggers', -}, livechatManagerRoutes, load); - -AccountBox.addRoute({ - name: 'livechat-trigger-edit', - path: '/triggers/:_id/edit', - sideNav: 'livechatFlex', - i18nPageTitle: 'Edit_Trigger', - pageTemplate: 'livechatTriggersForm', -}, livechatManagerRoutes, load); - -AccountBox.addRoute({ - name: 'livechat-trigger-new', - path: '/triggers/new', - sideNav: 'livechatFlex', - i18nPageTitle: 'New_Trigger', - pageTemplate: 'livechatTriggersForm', -}, livechatManagerRoutes, load); - -AccountBox.addRoute({ - name: 'livechat-installation', - path: '/installation', - sideNav: 'livechatFlex', - i18nPageTitle: 'Installation', - pageTemplate: 'livechatInstallation', -}, livechatManagerRoutes, load); - -AccountBox.addRoute({ - name: 'livechat-appearance', - path: '/appearance', - sideNav: 'livechatFlex', - i18nPageTitle: 'Appearance', - pageTemplate: 'livechatAppearance', -}, livechatManagerRoutes, load); - -AccountBox.addRoute({ - name: 'livechat-business-hours', - path: '/businessHours', - sideNav: 'livechatFlex', - i18nPageTitle: 'Business_Hours', - pageTemplate: 'livechatMainBusinessHours', -}, livechatManagerRoutes, load); - -AccountBox.addRoute({ - name: 'livechat-customfields', - path: '/customfields', - sideNav: 'livechatFlex', - i18nPageTitle: 'Custom_Fields', - pageTemplate: 'livechatCustomFields', -}, livechatManagerRoutes, load); - -AccountBox.addRoute({ - name: 'livechat-customfield-edit', - path: '/customfields/:_id/edit', - sideNav: 'livechatFlex', - i18nPageTitle: 'Edit_Custom_Field', - pageTemplate: 'livechatCustomFieldForm', -}, livechatManagerRoutes, load); - -AccountBox.addRoute({ - name: 'livechat-customfield-new', - path: '/customfields/new', - sideNav: 'livechatFlex', - i18nPageTitle: 'New_Custom_Field', - pageTemplate: 'livechatCustomFieldForm', -}, livechatManagerRoutes, load); - -AccountBox.addRoute({ - name: 'livechat-webhooks', - path: '/webhooks', - sideNav: 'livechatFlex', - i18nPageTitle: 'Webhooks', - pageTemplate: 'livechatIntegrationWebhook', -}, livechatManagerRoutes, load); - -AccountBox.addRoute({ - name: 'livechat-facebook', - path: '/facebook', - sideNav: 'livechatFlex', - i18nPageTitle: 'Facebook Messenger', - pageTemplate: 'livechatIntegrationFacebook', -}, livechatManagerRoutes, load); - AccountBox.addRoute({ name: 'livechat-queue', path: '/livechat-queue', diff --git a/app/livechat/client/ui.js b/app/livechat/client/ui.js index d15f32244f5..1da170bdf38 100644 --- a/app/livechat/client/ui.js +++ b/app/livechat/client/ui.js @@ -16,8 +16,8 @@ Tracker.autorun((c) => { AccountBox.addItem({ name: 'Omnichannel', icon: 'omnichannel', - href: 'livechat-current-chats', - sideNav: 'livechatFlex', + href: '/omnichannel/current', + sideNav: 'omnichannelFlex', condition: () => settings.get('Livechat_enabled') && hasAllPermission('view-livechat-manager'), }); diff --git a/app/livechat/client/views/admin.js b/app/livechat/client/views/admin.js index 330eb4f5d46..495de3e9d6d 100644 --- a/app/livechat/client/views/admin.js +++ b/app/livechat/client/views/admin.js @@ -2,21 +2,6 @@ import './app/analytics/livechatAnalytics'; import './app/analytics/livechatAnalyticsCustomDaterange'; import './app/analytics/livechatAnalyticsDaterange'; import './app/analytics/livechatRealTimeMonitoring'; -import './app/livechatAgents'; -import './app/livechatAppearance'; import './app/livechatDashboard.html'; -import './app/livechatCurrentChats'; -import './app/livechatCustomFields'; -import './app/livechatCustomFieldForm'; import './app/livechatDepartmentForm'; import './app/livechatDepartments'; -import './app/livechatInstallation'; -import './app/livechatTriggers'; -import './app/livechatTriggersForm'; -import './app/livechatManagers'; -import './app/integrations/livechatIntegrationWebhook'; -import './app/integrations/livechatIntegrationFacebook'; -import './app/triggers/livechatTriggerAction'; -import './app/triggers/livechatTriggerCondition'; -import './app/business-hours/livechatBusinessHoursForm'; -import './app/business-hours/livechatMainBusinessHours'; diff --git a/app/livechat/client/views/app/business-hours/livechatBusinessHoursForm.html b/app/livechat/client/views/app/business-hours/livechatBusinessHoursForm.html deleted file mode 100644 index 0fc164fee9f..00000000000 --- a/app/livechat/client/views/app/business-hours/livechatBusinessHoursForm.html +++ /dev/null @@ -1,65 +0,0 @@ - diff --git a/app/livechat/client/views/app/business-hours/livechatBusinessHoursForm.js b/app/livechat/client/views/app/business-hours/livechatBusinessHoursForm.js deleted file mode 100644 index 30e6bced1e2..00000000000 --- a/app/livechat/client/views/app/business-hours/livechatBusinessHoursForm.js +++ /dev/null @@ -1,186 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { Template } from 'meteor/templating'; -import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; -import { FlowRouter } from 'meteor/kadira:flow-router'; -import toastr from 'toastr'; -import moment from 'moment'; - -import { t, handleError, APIClient } from '../../../../../utils/client'; -import './livechatBusinessHoursForm.html'; -import { getCustomFormTemplate } from '../customTemplates/register'; -import { businessHourManager } from './BusinessHours'; - -Template.livechatBusinessHoursForm.helpers({ - days() { - return Template.instance().businessHour.get().workHours; - }, - startName(day) { - return `${ day.day }_start`; - }, - finishName(day) { - return `${ day.day }_finish`; - }, - openName(day) { - return `${ day.day }_open`; - }, - start(day) { - return Template.instance().dayVars[day.day].start.get(); - }, - finish(day) { - return Template.instance().dayVars[day.day].finish.get(); - }, - name(day) { - return TAPi18n.__(day.day); - }, - open(day) { - return Template.instance().dayVars[day.day].open.get(); - }, - customFieldsTemplate() { - if (!businessHourManager.showCustomTemplate(Template.instance().businessHour.get())) { - return; - } - return getCustomFormTemplate('livechatBusinessHoursForm'); - }, - timezoneTemplate() { - if (!businessHourManager.showTimezoneTemplate()) { - return; - } - return getCustomFormTemplate('livechatBusinessHoursTimezoneForm'); - }, - showBackButton() { - return businessHourManager.showBackButton(); - }, - data() { - return Template.instance().businessHour; - }, -}); - -const splitDayAndPeriod = (value) => value.split('_'); - -Template.livechatBusinessHoursForm.events({ - 'change .preview-settings, keydown .preview-settings'(e, instance) { - const [day, period] = splitDayAndPeriod(e.currentTarget.name); - - const newTime = moment(e.currentTarget.value, 'HH:mm'); - - // check if start and stop do not cross - if (period === 'start') { - if (newTime.isSameOrBefore(moment(instance.dayVars[day].finish.get(), 'HH:mm'))) { - instance.dayVars[day].start.set(e.currentTarget.value); - } else { - e.currentTarget.value = instance.dayVars[day].start.get(); - } - } else if (period === 'finish') { - if (newTime.isSameOrAfter(moment(instance.dayVars[day].start.get(), 'HH:mm'))) { - instance.dayVars[day].finish.set(e.currentTarget.value); - } else { - e.currentTarget.value = instance.dayVars[day].finish.get(); - } - } - }, - 'change .dayOpenCheck input'(e, instance) { - const [day, period] = splitDayAndPeriod(e.currentTarget.name); - instance.dayVars[day][period].set(e.target.checked); - }, - 'change .preview-settings, keyup .preview-settings'(e, instance) { - let { value } = e.currentTarget; - if (e.currentTarget.type === 'radio') { - value = value === 'true'; - instance[e.currentTarget.name].set(value); - } - }, - - 'click button.back'(e/* , instance*/) { - e.preventDefault(); - FlowRouter.go('livechat-business-hours'); - }, - - 'submit .rocket-form'(e, instance) { - e.preventDefault(); - - // convert all times to utc then update them in db - const days = []; - for (const d in instance.dayVars) { - if (instance.dayVars.hasOwnProperty(d)) { - const day = instance.dayVars[d]; - const start = moment(day.start.get(), 'HH:mm').format('HH:mm'); - const finish = moment(day.finish.get(), 'HH:mm').format('HH:mm'); - days.push({ - day: d, - start, - finish, - open: day.open.get(), - }); - } - } - - const businessHourData = { - ...instance.businessHour.get(), - workHours: days, - }; - - instance.$('.customFormField').each((i, el) => { - const elField = instance.$(el); - const name = elField.attr('name'); - businessHourData[name] = elField.val(); - }); - Meteor.call('livechat:saveBusinessHour', businessHourData, function(err /* ,result*/) { - if (err) { - return handleError(err); - } - toastr.success(t('Business_hours_updated')); - FlowRouter.go('livechat-business-hours'); - }); - }, -}); - -const createDefaultBusinessHour = () => { - const days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; - const closedDays = ['Saturday', 'Sunday']; - return { - workHours: days.map((day) => ({ - day, - start: '00:00', - finish: '00:00', - open: !closedDays.includes(day), - })), - }; -}; - -Template.livechatBusinessHoursForm.onCreated(async function() { - this.dayVars = createDefaultBusinessHour().workHours.reduce((acc, day) => { - acc[day.day] = { - start: new ReactiveVar(day.start), - finish: new ReactiveVar(day.finish), - open: new ReactiveVar(day.open), - }; - return acc; - }, {}); - this.businessHour = new ReactiveVar({}); - - this.businessHour.set({ - ...createDefaultBusinessHour(), - }); - this.autorun(async () => { - if (FlowRouter.current().route.name.includes('new')) { - return; - } - const id = FlowRouter.getParam('_id'); - const type = FlowRouter.getParam('type'); - let url = 'livechat/business-hour'; - if (id && type) { - url += `?_id=${ id }&type=${ type }`; - } - const { businessHour } = await APIClient.v1.get(url); - if (!businessHour) { - return; - } - this.businessHour.set(businessHour); - businessHour.workHours.forEach((d) => { - this.dayVars[d.day].start.set(moment.utc(d.start.utc.time, 'HH:mm').tz(businessHour.timezone.name).format('HH:mm')); - this.dayVars[d.day].finish.set(moment.utc(d.finish.utc.time, 'HH:mm').tz(businessHour.timezone.name).format('HH:mm')); - this.dayVars[d.day].open.set(d.open); - }); - }); -}); diff --git a/app/livechat/client/views/app/business-hours/livechatMainBusinessHours.html b/app/livechat/client/views/app/business-hours/livechatMainBusinessHours.html deleted file mode 100644 index 91a112cf915..00000000000 --- a/app/livechat/client/views/app/business-hours/livechatMainBusinessHours.html +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/app/livechat/client/views/app/business-hours/livechatMainBusinessHours.js b/app/livechat/client/views/app/business-hours/livechatMainBusinessHours.js deleted file mode 100644 index 476175a04d0..00000000000 --- a/app/livechat/client/views/app/business-hours/livechatMainBusinessHours.js +++ /dev/null @@ -1,10 +0,0 @@ -import { Template } from 'meteor/templating'; - -import './livechatMainBusinessHours.html'; -import { businessHourManager } from './BusinessHours'; - -Template.livechatMainBusinessHours.helpers({ - getTemplate() { - return businessHourManager.getTemplate(); - }, -}); diff --git a/app/livechat/client/views/app/integrations/livechatIntegrationFacebook.html b/app/livechat/client/views/app/integrations/livechatIntegrationFacebook.html deleted file mode 100644 index 6686dbde984..00000000000 --- a/app/livechat/client/views/app/integrations/livechatIntegrationFacebook.html +++ /dev/null @@ -1,43 +0,0 @@ - diff --git a/app/livechat/client/views/app/integrations/livechatIntegrationFacebook.js b/app/livechat/client/views/app/integrations/livechatIntegrationFacebook.js deleted file mode 100644 index f76f0733cc1..00000000000 --- a/app/livechat/client/views/app/integrations/livechatIntegrationFacebook.js +++ /dev/null @@ -1,157 +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'; -import './livechatIntegrationFacebook.html'; - -Template.livechatIntegrationFacebook.helpers({ - pages() { - return Template.instance().pages.get(); - }, - subscribed() { - return this.subscribed ? 'checked' : ''; - }, - enabled() { - return Template.instance().enabled.get(); - }, - hasToken() { - return Template.instance().hasToken.get(); - }, - enableButtonDisabled() { - return !Template.instance().hasToken.get() ? 'disabled' : ''; - }, - isLoading() { - return Template.instance().loading.get(); - }, -}); - -Template.livechatIntegrationFacebook.onCreated(function() { - this.enabled = new ReactiveVar(false); - this.hasToken = new ReactiveVar(false); - this.pages = new ReactiveVar([]); - this.loading = new ReactiveVar(false); - - this.autorun(() => { - if (this.enabled.get()) { - this.loadPages(); - } - }); - - this.result = (successFn, errorFn = () => {}) => (error, result) => { - // fix the state where user it was enabled on admin - if (error && error.error) { - switch (error.error) { - case 'invalid-facebook-token': - case 'invalid-instance-url': - case 'integration-disabled': - return Meteor.call('livechat:facebook', { action: 'enable' }, this.result(() => { - this.enabled.set(true); - this.loadPages(); - }, () => this.loadPages())); - } - } - - if (result && result.success === false && (result.type === 'OAuthException' || typeof result.url !== 'undefined')) { - const oauthWindow = window.open(result.url, 'facebook-integration-oauth', 'width=600,height=400'); - - const checkInterval = setInterval(() => { - if (oauthWindow.closed) { - clearInterval(checkInterval); - errorFn(error); - } - }, 300); - return; - } - if (error) { - errorFn(error); - return modal.open({ - title: t('Error_loading_pages'), - text: error.reason, - type: 'error', - }); - } - successFn(result); - }; - - this.loadPages = () => { - this.pages.set([]); - this.loading.set(true); - Meteor.call('livechat:facebook', { action: 'list-pages' }, this.result((result) => { - this.pages.set(result.pages); - this.loading.set(false); - }, () => this.loading.set(false))); - }; -}); - -Template.livechatIntegrationFacebook.onRendered(function() { - this.loading.set(true); - Meteor.call('livechat:facebook', { action: 'initialState' }, this.result((result) => { - this.enabled.set(result.enabled); - this.hasToken.set(result.hasToken); - this.loading.set(false); - })); -}); - -Template.livechatIntegrationFacebook.events({ - 'click .reload'(event, instance) { - event.preventDefault(); - - instance.loadPages(); - }, - 'click .enable'(event, instance) { - event.preventDefault(); - - Meteor.call('livechat:facebook', { action: 'enable' }, instance.result(() => { - instance.enabled.set(true); - }, () => instance.enabled.set(true))); - }, - 'click .disable'(event, instance) { - event.preventDefault(); - - modal.open({ - title: t('Disable_Facebook_integration'), - text: t('Are_you_sure_you_want_to_disable_Facebook_integration'), - type: 'warning', - showCancelButton: true, - confirmButtonColor: '#DD6B55', - confirmButtonText: t('Yes'), - cancelButtonText: t('Cancel'), - closeOnConfirm: false, - html: false, - }, () => { - Meteor.call('livechat:facebook', { action: 'disable' }, (err) => { - if (err) { - return handleError(err); - } - instance.enabled.set(false); - instance.pages.set([]); - - modal.open({ - title: t('Disabled'), - text: t('Integration_disabled'), - type: 'success', - timer: 2000, - showConfirmButton: false, - }); - }); - }); - }, - 'change [name=subscribe]'(event, instance) { - Meteor.call('livechat:facebook', { - action: !event.currentTarget.checked ? 'unsubscribe' : 'subscribe', - page: this.id, - }, (err, result) => { - if (result.success) { - const pages = instance.pages.get(); - pages.forEach((page) => { - if (page.id === this.id) { - page.subscribed = event.currentTarget.checked; - } - }); - instance.pages.set(pages); - } - }); - }, -}); diff --git a/app/livechat/client/views/app/integrations/livechatIntegrationWebhook.html b/app/livechat/client/views/app/integrations/livechatIntegrationWebhook.html deleted file mode 100644 index 761aaac87b5..00000000000 --- a/app/livechat/client/views/app/integrations/livechatIntegrationWebhook.html +++ /dev/null @@ -1,88 +0,0 @@ - diff --git a/app/livechat/client/views/app/integrations/livechatIntegrationWebhook.js b/app/livechat/client/views/app/integrations/livechatIntegrationWebhook.js deleted file mode 100644 index 2e6e7d8c439..00000000000 --- a/app/livechat/client/views/app/integrations/livechatIntegrationWebhook.js +++ /dev/null @@ -1,146 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { Template } from 'meteor/templating'; -import _ from 'underscore'; -import s from 'underscore.string'; -import toastr from 'toastr'; - -import { modal } from '../../../../../ui-utils'; -import { t, handleError } from '../../../../../utils'; -import './livechatIntegrationWebhook.html'; -import { APIClient } from '../../../../../utils/client'; - -const getIntegrationSettingById = (settings, id) => settings.find((setting) => setting._id === id); - -Template.livechatIntegrationWebhook.helpers({ - webhookUrl() { - const setting = getIntegrationSettingById(Template.instance().settings.get(), 'Livechat_webhookUrl'); - return setting && setting.value; - }, - secretToken() { - const setting = getIntegrationSettingById(Template.instance().settings.get(), 'Livechat_secret_token'); - return setting && setting.value; - }, - disableTest() { - return Template.instance().disableTest.get(); - }, - sendOnStartChecked() { - const setting = getIntegrationSettingById(Template.instance().settings.get(), 'Livechat_webhook_on_start'); - return setting && setting.value; - }, - sendOnCloseChecked() { - const setting = getIntegrationSettingById(Template.instance().settings.get(), 'Livechat_webhook_on_close'); - return setting && setting.value; - }, - sendOnChatTakenChecked() { - const setting = getIntegrationSettingById(Template.instance().settings.get(), 'Livechat_webhook_on_chat_taken'); - return setting && setting.value; - }, - sendOnChatQueuedChecked() { - const setting = getIntegrationSettingById(Template.instance().settings.get(), 'Livechat_webhook_on_chat_queued'); - return setting && setting.value; - }, - sendOnForwardChecked() { - const setting = getIntegrationSettingById(Template.instance().settings.get(), 'Livechat_webhook_on_forward'); - return setting && setting.value; - }, - sendOnOfflineChecked() { - const setting = getIntegrationSettingById(Template.instance().settings.get(), 'Livechat_webhook_on_offline_msg'); - return setting && setting.value; - }, - sendOnVisitorMessageChecked() { - const setting = getIntegrationSettingById(Template.instance().settings.get(), 'Livechat_webhook_on_visitor_message'); - return setting && setting.value; - }, - sendOnAgentMessageChecked() { - const setting = getIntegrationSettingById(Template.instance().settings.get(), 'Livechat_webhook_on_agent_message'); - return setting && setting.value; - }, -}); - -Template.livechatIntegrationWebhook.onCreated(async function() { - this.disableTest = new ReactiveVar(true); - this.settings = new ReactiveVar([]); - - this.autorun(() => { - const webhook = getIntegrationSettingById(this.settings.get(), 'Livechat_webhookUrl'); - this.disableTest.set(!webhook || _.isEmpty(webhook.value)); - }); - const { settings } = await APIClient.v1.get('livechat/integrations.settings'); - this.settings.set(settings); -}); - -Template.livechatIntegrationWebhook.events({ - 'change #webhookUrl, blur #webhookUrl'(e, instance) { - const setting = getIntegrationSettingById(instance.settings.get(), 'Livechat_webhookUrl'); - instance.disableTest.set(!setting || e.currentTarget.value !== setting.value); - }, - 'click .test'(e, instance) { - if (!instance.disableTest.get()) { - Meteor.call('livechat:webhookTest', (err) => { - if (err) { - return handleError(err); - } - modal.open({ - title: t('It_works'), - type: 'success', - timer: 2000, - }); - }); - } - }, - 'click .reset-settings'(e, instance) { - e.preventDefault(); - - const webhookUrl = getIntegrationSettingById(instance.settings.get(), 'Livechat_webhookUrl'); - const secretToken = getIntegrationSettingById(instance.settings.get(), 'Livechat_secret_token'); - const webhookOnStart = getIntegrationSettingById(instance.settings.get(), 'Livechat_webhook_on_start'); - const webhookOnClose = getIntegrationSettingById(instance.settings.get(), 'Livechat_webhook_on_close'); - const webhookOnChatTaken = getIntegrationSettingById(instance.settings.get(), 'Livechat_webhook_on_chat_taken'); - const webhookOnChatQueued = getIntegrationSettingById(instance.settings.get(), 'Livechat_webhook_on_chat_queued'); - const webhookOnForward = getIntegrationSettingById(instance.settings.get(), 'Livechat_webhook_on_forward'); - const webhookOnOfflineMsg = getIntegrationSettingById(instance.settings.get(), 'Livechat_webhook_on_offline_msg'); - const webhookOnVisitorMessage = getIntegrationSettingById(instance.settings.get(), 'Livechat_webhook_on_visitor_message'); - const webhookOnAgentMessage = getIntegrationSettingById(instance.settings.get(), 'Livechat_webhook_on_agent_message'); - - instance.$('#webhookUrl').val(webhookUrl && webhookUrl.value); - instance.$('#secretToken').val(secretToken && secretToken.value); - instance.$('#sendOnStart').get(0).checked = webhookOnStart && webhookOnStart.value; - instance.$('#sendOnClose').get(0).checked = webhookOnClose && webhookOnClose.value; - instance.$('#sendOnChatTaken').get(0).checked = webhookOnChatTaken && webhookOnChatTaken.value; - instance.$('#sendOnChatQueued').get(0).checked = webhookOnChatQueued && webhookOnChatQueued.value; - instance.$('#sendOnForward').get(0).checked = webhookOnForward && webhookOnForward.value; - instance.$('#sendOnOffline').get(0).checked = webhookOnOfflineMsg && webhookOnOfflineMsg.value; - instance.$('#sendOnVisitorMessage').get(0).checked = webhookOnVisitorMessage && webhookOnVisitorMessage.value; - instance.$('#sendOnAgentMessage').get(0).checked = webhookOnAgentMessage && webhookOnAgentMessage.value; - - instance.disableTest.set(!webhookUrl || _.isEmpty(webhookUrl.value)); - }, - 'submit .rocket-form'(e, instance) { - e.preventDefault(); - - const settings = { - Livechat_webhookUrl: s.trim(instance.$('#webhookUrl').val()), - Livechat_secret_token: s.trim(instance.$('#secretToken').val()), - Livechat_webhook_on_start: instance.$('#sendOnStart').get(0).checked, - Livechat_webhook_on_close: instance.$('#sendOnClose').get(0).checked, - Livechat_webhook_on_chat_taken: instance.$('#sendOnChatTaken').get(0).checked, - Livechat_webhook_on_chat_queued: instance.$('#sendOnChatQueued').get(0).checked, - Livechat_webhook_on_forward: instance.$('#sendOnForward').get(0).checked, - Livechat_webhook_on_offline_msg: instance.$('#sendOnOffline').get(0).checked, - Livechat_webhook_on_visitor_message: instance.$('#sendOnVisitorMessage').get(0).checked, - Livechat_webhook_on_agent_message: instance.$('#sendOnAgentMessage').get(0).checked, - }; - Meteor.call('livechat:saveIntegration', settings, (err) => { - if (err) { - return handleError(err); - } - const savedValues = instance.settings.get().map((setting) => { - setting.value = settings[setting._id]; - return setting; - }); - instance.settings.set(savedValues); - toastr.success(t('Saved')); - }); - }, -}); diff --git a/app/livechat/client/views/app/livechatAgents.html b/app/livechat/client/views/app/livechatAgents.html deleted file mode 100644 index a32d04763b8..00000000000 --- a/app/livechat/client/views/app/livechatAgents.html +++ /dev/null @@ -1,103 +0,0 @@ - diff --git a/app/livechat/client/views/app/livechatAgents.js b/app/livechat/client/views/app/livechatAgents.js deleted file mode 100644 index af3b68b8885..00000000000 --- a/app/livechat/client/views/app/livechatAgents.js +++ /dev/null @@ -1,234 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { Template } from 'meteor/templating'; -import { FlowRouter } from 'meteor/kadira:flow-router'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { ReactiveDict } from 'meteor/reactive-dict'; -import _ from 'underscore'; - -import { modal, call, TabBar, RocketChatTabBar } from '../../../../ui-utils'; -import { t, handleError, APIClient } from '../../../../utils/client'; -import './livechatAgents.html'; - -const loadAgents = async (instance, limit = 50, text) => { - let baseUrl = `livechat/users/agent?count=${ limit }`; - - if (text) { - baseUrl += `&text=${ encodeURIComponent(text) }`; - } - - const { users } = await APIClient.v1.get(baseUrl); - instance.agents.set(users); - instance.ready.set(true); -}; - -const getUsername = (user) => user.username; -Template.livechatAgents.helpers({ - exceptionsAgents() { - const { selectedAgents } = Template.instance(); - return Template.instance().agents.get() - .map(getUsername).concat(selectedAgents.get().map(getUsername)); - }, - deleteLastAgent() { - const i = Template.instance(); - return () => { - const arr = i.selectedAgents.curValue; - arr.pop(); - i.selectedAgents.set(arr); - }; - }, - isLoading() { - return Template.instance().state.get('loading'); - }, - agents() { - return Template.instance().agents.get(); - }, - emailAddress() { - if (this.emails && this.emails.length > 0) { - return this.emails[0].address; - } - }, - agentModifier() { - return (filter, text = '') => { - const f = filter.get(); - return `@${ - f.length === 0 - ? text - : text.replace( - new RegExp(filter.get()), - (part) => `${ part }`, - ) - }`; - }; - }, - onSelectAgents() { - return Template.instance().onSelectAgents; - }, - selectedAgents() { - return Template.instance().selectedAgents.get(); - }, - onClickTagAgents() { - return Template.instance().onClickTagAgents; - }, - isReady() { - const instance = Template.instance(); - return instance.ready && instance.ready.get(); - }, - onTableScroll() { - const instance = Template.instance(); - return function(currentTarget) { - if ( - currentTarget.offsetHeight + currentTarget.scrollTop - >= currentTarget.scrollHeight - 100 - ) { - return instance.limit.set(instance.limit.get() + 50); - } - }; - }, - flexData() { - return { - tabBar: Template.instance().tabBar, - data: Template.instance().tabBarData.get(), - }; - }, - statusService() { - const { status, statusLivechat } = this; - return statusLivechat === 'available' && status !== 'offline' ? t('Available') : t('Unavailable'); - }, -}); - -const DEBOUNCE_TIME_FOR_SEARCH_AGENTS_IN_MS = 300; - -Template.livechatAgents.events({ - 'click .remove-agent'(e, instance) { - e.preventDefault(); - - modal.open( - { - title: t('Are_you_sure'), - type: 'warning', - showCancelButton: true, - confirmButtonColor: '#DD6B55', - confirmButtonText: t('Yes'), - cancelButtonText: t('Cancel'), - closeOnConfirm: false, - html: false, - }, - () => { - Meteor.call('livechat:removeAgent', this.username, async function( - error, /* , result*/ - ) { - if (error) { - return handleError(error); - } - - if (instance.tabBar.getState() === 'opened') { - instance.tabBar.close(); - } - - await loadAgents(instance); - - modal.open({ - title: t('Removed'), - text: t('Agent_removed'), - type: 'success', - timer: 1000, - showConfirmButton: false, - }); - }); - }, - ); - }, - - async 'submit #form-agent'(e, instance) { - e.preventDefault(); - const { selectedAgents, state, limit, filter } = instance; - - const users = selectedAgents.get(); - - if (!users.length) { - return; - } - - state.set('loading', true); - try { - await Promise.all( - users.map(({ username }) => call('livechat:addAgent', username)), - ); - - await loadAgents(instance, limit.get(), filter.get()); - selectedAgents.set([]); - } finally { - state.set('loading', false); - } - }, - - 'keydown #agents-filter'(e) { - if (e.which === 13) { - e.stopPropagation(); - e.preventDefault(); - } - }, - - 'keyup #agents-filter': _.debounce((e, t) => { - e.preventDefault(); - t.filter.set(e.currentTarget.value); - }, DEBOUNCE_TIME_FOR_SEARCH_AGENTS_IN_MS), - - 'click .user-info'(e, instance) { - e.preventDefault(); - instance.tabBarData.set({ - agentId: this._id, - onRemoveAgent: () => loadAgents(instance), - }); - - instance.tabBar.setData({ label: t('Agent_Info'), icon: 'livechat' }); - instance.tabBar.open('livechat-agent-info'); - }, - /* - 'click .info-tabs button'(e) { - e.preventDefault(); - $('.info-tabs button').removeClass('active'); - $(e.currentTarget).addClass('active'); - $('.user-info-content').hide(); - $($(e.currentTarget).attr('href')).show(); - }, - */ -}); - -Template.livechatAgents.onCreated(function() { - const instance = this; - this.limit = new ReactiveVar(50); - this.filter = new ReactiveVar(''); - this.state = new ReactiveDict({ - loading: false, - }); - this.ready = new ReactiveVar(true); - this.selectedAgents = new ReactiveVar([]); - this.agents = new ReactiveVar([]); - this.tabBar = new RocketChatTabBar(); - this.tabBar.showGroup(FlowRouter.current().route.name); - this.tabBarData = new ReactiveVar(); - - TabBar.addButton({ - groups: ['livechat-agent-users'], - id: 'livechat-agent-info', - i18nTitle: 'Agent_Info', - icon: 'livechat', - template: 'agentInfo', - order: 1, - }); - - this.onSelectAgents = ({ item: agent }) => { - this.selectedAgents.set([...this.selectedAgents.curValue, agent]); - }; - - this.onClickTagAgents = ({ username }) => { - this.selectedAgents.set(this.selectedAgents.curValue.filter((user) => user.username !== username)); - }; - - this.autorun(function() { - const limit = instance.limit.get(); - const filter = instance.filter.get(); - loadAgents(instance, limit, filter); - }); -}); diff --git a/app/livechat/client/views/app/livechatAppearance.html b/app/livechat/client/views/app/livechatAppearance.html deleted file mode 100644 index ea0fc5b5f18..00000000000 --- a/app/livechat/client/views/app/livechatAppearance.html +++ /dev/null @@ -1,145 +0,0 @@ - diff --git a/app/livechat/client/views/app/livechatAppearance.js b/app/livechat/client/views/app/livechatAppearance.js deleted file mode 100644 index e3366267802..00000000000 --- a/app/livechat/client/views/app/livechatAppearance.js +++ /dev/null @@ -1,345 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { Template } from 'meteor/templating'; -import s from 'underscore.string'; -import toastr from 'toastr'; - -import { t, handleError } from '../../../../utils'; -import './livechatAppearance.html'; -import { APIClient } from '../../../../utils/client'; - -const getSettingFromAppearance = (instance, settingName) => instance.appearance.get() && instance.appearance.get().find((setting) => setting._id === settingName); - -Template.livechatAppearance.helpers({ - showLimitTextLengthFormTrueChecked() { - if (Template.instance().showLimitTextLength.get()) { - return 'checked'; - } - }, - showLimitTextLengthFormFalseChecked() { - if (!Template.instance().showLimitTextLength.get()) { - return 'checked'; - } - }, - limitTextLength() { - return Template.instance().limitTextLength.get(); - }, - color() { - return Template.instance().color.get(); - }, - showAgentInfo() { - return Template.instance().showAgentInfo.get(); - }, - showAgentEmail() { - return Template.instance().showAgentEmail.get(); - }, - title() { - return Template.instance().title.get(); - }, - colorOffline() { - return Template.instance().colorOffline.get(); - }, - titleOffline() { - return Template.instance().titleOffline.get(); - }, - offlineMessage() { - return Template.instance().offlineMessage.get(); - }, - sampleOfflineMessage() { - return Template.instance().offlineMessage.get().replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1
$2'); - }, - offlineSuccessMessage() { - return Template.instance().offlineSuccessMessage.get(); - }, - sampleOfflineSuccessMessage() { - return Template.instance().offlineSuccessMessage.get().replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1
$2'); - }, - showAgentInfoFormTrueChecked() { - if (Template.instance().showAgentInfo.get()) { - return 'checked'; - } - }, - showAgentInfoFormFalseChecked() { - if (!Template.instance().showAgentInfo.get()) { - return 'checked'; - } - }, - showAgentEmailFormTrueChecked() { - if (Template.instance().showAgentEmail.get()) { - return 'checked'; - } - }, - showAgentEmailFormFalseChecked() { - if (!Template.instance().showAgentEmail.get()) { - return 'checked'; - } - }, - displayOfflineFormTrueChecked() { - if (Template.instance().displayOfflineForm.get()) { - return 'checked'; - } - }, - displayOfflineFormFalseChecked() { - if (!Template.instance().displayOfflineForm.get()) { - return 'checked'; - } - }, - offlineUnavailableMessage() { - return Template.instance().offlineUnavailableMessage.get(); - }, - sampleOfflineUnavailableMessage() { - return Template.instance().offlineUnavailableMessage.get().replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1
$2'); - }, - emailOffline() { - return Template.instance().offlineEmail.get(); - }, - conversationFinishedMessage() { - return Template.instance().conversationFinishedMessage.get(); - }, - conversationFinishedText() { - return Template.instance().conversationFinishedText.get(); - }, - registrationFormEnabled() { - if (Template.instance().registrationFormEnabled.get()) { - return 'checked'; - } - }, - registrationFormNameFieldEnabled() { - if (Template.instance().registrationFormNameFieldEnabled.get()) { - return 'checked'; - } - }, - registrationFormEmailFieldEnabled() { - if (Template.instance().registrationFormEmailFieldEnabled.get()) { - return 'checked'; - } - }, - registrationFormMessage() { - return Template.instance().registrationFormMessage.get(); - }, -}); - -Template.livechatAppearance.onCreated(async function() { - this.appearance = new ReactiveVar([]); - this.title = new ReactiveVar(null); - this.color = new ReactiveVar(null); - this.showLimitTextLength = new ReactiveVar(null); - this.limitTextLength = new ReactiveVar(null); - this.showAgentInfo = new ReactiveVar(null); - this.showAgentEmail = new ReactiveVar(null); - this.displayOfflineForm = new ReactiveVar(null); - this.offlineUnavailableMessage = new ReactiveVar(null); - this.offlineMessage = new ReactiveVar(null); - this.offlineSuccessMessage = new ReactiveVar(null); - this.titleOffline = new ReactiveVar(null); - this.colorOffline = new ReactiveVar(null); - this.offlineEmail = new ReactiveVar(null); - this.conversationFinishedMessage = new ReactiveVar(null); - this.conversationFinishedText = new ReactiveVar(null); - this.registrationFormEnabled = new ReactiveVar(null); - this.registrationFormNameFieldEnabled = new ReactiveVar(null); - this.registrationFormEmailFieldEnabled = new ReactiveVar(null); - this.registrationFormMessage = new ReactiveVar(null); - - const { appearance } = await APIClient.v1.get('livechat/appearance'); - this.appearance.set(appearance); - - const livechatTitle = getSettingFromAppearance(this, 'Livechat_title'); - const livechatTitleColor = getSettingFromAppearance(this, 'Livechat_title_color'); - const livechatShowMessageCharacterLimit = getSettingFromAppearance(this, 'Livechat_enable_message_character_limit'); - const livechatMessageCharacterLimit = getSettingFromAppearance(this, 'Livechat_message_character_limit'); - const livechatShowAgentInfo = getSettingFromAppearance(this, 'Livechat_show_agent_info'); - const livechatShowAgentEmail = getSettingFromAppearance(this, 'Livechat_show_agent_email'); - const livechatDisplayOfflineForm = getSettingFromAppearance(this, 'Livechat_display_offline_form'); - const livechatOfflineFormUnavailable = getSettingFromAppearance(this, 'Livechat_offline_form_unavailable'); - const livechatOfflineMessage = getSettingFromAppearance(this, 'Livechat_offline_message'); - const livechatOfflineSuccessMessage = getSettingFromAppearance(this, 'Livechat_offline_success_message'); - const livechatOfflineTitle = getSettingFromAppearance(this, 'Livechat_offline_title'); - const livechatOfflineTitleColor = getSettingFromAppearance(this, 'Livechat_offline_title_color'); - const livechatOfflineEmail = getSettingFromAppearance(this, 'Livechat_offline_email'); - const livechatConversationFinishedMessage = getSettingFromAppearance(this, 'Livechat_conversation_finished_message'); - const livechatRegistrationFormMessage = getSettingFromAppearance(this, 'Livechat_registration_form_message'); - const livechatRegistrationForm = getSettingFromAppearance(this, 'Livechat_registration_form'); - const livechatNameFieldRegistrationForm = getSettingFromAppearance(this, 'Livechat_name_field_registration_form'); - const livechatEmailFieldRegistrationForm = getSettingFromAppearance(this, 'Livechat_email_field_registration_form'); - const conversationFinishedText = getSettingFromAppearance(this, 'Livechat_conversation_finished_text'); - - this.title.set(livechatTitle && livechatTitle.value); - this.color.set(livechatTitleColor && livechatTitleColor.value); - this.showLimitTextLength.set(livechatShowMessageCharacterLimit && livechatShowMessageCharacterLimit.value); - this.limitTextLength.set(livechatMessageCharacterLimit && livechatMessageCharacterLimit.value); - this.showAgentInfo.set(livechatShowAgentInfo && livechatShowAgentInfo.value); - this.showAgentEmail.set(livechatShowAgentEmail && livechatShowAgentEmail.value); - this.displayOfflineForm.set(livechatDisplayOfflineForm && livechatDisplayOfflineForm.value); - this.offlineUnavailableMessage.set(livechatOfflineFormUnavailable && livechatOfflineFormUnavailable.value); - this.offlineMessage.set(livechatOfflineMessage && livechatOfflineMessage.value); - this.offlineSuccessMessage.set(livechatOfflineSuccessMessage && livechatOfflineSuccessMessage.value); - this.titleOffline.set(livechatOfflineTitle && livechatOfflineTitle.value); - this.colorOffline.set(livechatOfflineTitleColor && livechatOfflineTitleColor.value); - this.offlineEmail.set(livechatOfflineEmail && livechatOfflineEmail.value); - this.conversationFinishedMessage.set(livechatConversationFinishedMessage && livechatConversationFinishedMessage.value); - this.registrationFormMessage.set(livechatRegistrationFormMessage && livechatRegistrationFormMessage.value); - this.registrationFormEnabled.set(livechatRegistrationForm && livechatRegistrationForm.value); - this.registrationFormNameFieldEnabled.set(livechatNameFieldRegistrationForm && livechatNameFieldRegistrationForm.value); - this.registrationFormEmailFieldEnabled.set(livechatEmailFieldRegistrationForm && livechatEmailFieldRegistrationForm.value); - this.conversationFinishedText.set(conversationFinishedText && conversationFinishedText.value); -}); - -Template.livechatAppearance.events({ - 'change .js-input-check'(e, instance) { - instance[e.currentTarget.name].set(e.currentTarget.checked); - }, - 'change .preview-settings, keyup .preview-settings'(e, instance) { - let { value } = e.currentTarget; - if (e.currentTarget.type === 'radio') { - value = value === 'true'; - } - instance[e.currentTarget.name].set(value); - }, - 'click .reset-settings'(e, instance) { - e.preventDefault(); - - const settingTitle = getSettingFromAppearance(instance, 'Livechat_title'); - instance.title.set(settingTitle && settingTitle.value); - - const settingTitleColor = getSettingFromAppearance(instance, 'Livechat_title_color'); - instance.color.set(settingTitleColor && settingTitleColor.value); - - const settinglivechatShowMessageCharacterLimit = getSettingFromAppearance(instance, 'Livechat_enable_message_character_limit'); - instance.showLimitTextLength.set(settinglivechatShowMessageCharacterLimit && settinglivechatShowMessageCharacterLimit.value); - - const settinglivechatMessageCharacterLimit = getSettingFromAppearance(instance, 'Livechat_message_character_limit'); - instance.limitTextLength.set(settinglivechatMessageCharacterLimit && settinglivechatMessageCharacterLimit.value); - - const settingShowAgentInfo = getSettingFromAppearance(instance, 'Livechat_show_agent_info'); - instance.showAgentInfo.set(settingShowAgentInfo && settingShowAgentInfo.value); - - const settingShowAgentEmail = getSettingFromAppearance(instance, 'Livechat_show_agent_email'); - instance.showAgentEmail.set(settingShowAgentEmail && settingShowAgentEmail.value); - - const settingDiplayOffline = getSettingFromAppearance(instance, 'Livechat_display_offline_form'); - instance.displayOfflineForm.set(settingDiplayOffline && settingDiplayOffline.value); - - const settingFormUnavailable = getSettingFromAppearance(instance, 'Livechat_offline_form_unavailable'); - instance.offlineUnavailableMessage.set(settingFormUnavailable && settingFormUnavailable.value); - - const settingOfflineMessage = getSettingFromAppearance(instance, 'Livechat_offline_message'); - instance.offlineMessage.set(settingOfflineMessage && settingOfflineMessage.value); - - const settingOfflineSuccess = getSettingFromAppearance(instance, 'Livechat_offline_success_message'); - instance.offlineSuccessMessage.set(settingOfflineSuccess && settingOfflineSuccess.value); - - const settingOfflineTitle = getSettingFromAppearance(instance, 'Livechat_offline_title'); - instance.titleOffline.set(settingOfflineTitle && settingOfflineTitle.value); - - const settingOfflineTitleColor = getSettingFromAppearance(instance, 'Livechat_offline_title_color'); - instance.colorOffline.set(settingOfflineTitleColor && settingOfflineTitleColor.value); - - const settingConversationFinishedMessage = getSettingFromAppearance(instance, 'Livechat_conversation_finished_message'); - instance.conversationFinishedMessage.set(settingConversationFinishedMessage && settingConversationFinishedMessage.value); - - const settingConversationFinishedText = getSettingFromAppearance(instance, 'Livechat_conversation_finished_text'); - instance.conversationFinishedText.set(settingConversationFinishedText && settingConversationFinishedText.value); - - const settingRegistrationFormEnabled = getSettingFromAppearance(instance, 'Livechat_registration_form'); - instance.registrationFormEnabled.set(settingRegistrationFormEnabled && settingRegistrationFormEnabled.value); - - const settingRegistrationFormNameFieldEnabled = getSettingFromAppearance(instance, 'Livechat_name_field_registration_form'); - instance.registrationFormNameFieldEnabled.set(settingRegistrationFormNameFieldEnabled && settingRegistrationFormNameFieldEnabled.value); - - const settingRegistrationFormEmailFieldEnabled = getSettingFromAppearance(instance, 'Livechat_email_field_registration_form'); - instance.registrationFormEmailFieldEnabled.set(settingRegistrationFormEmailFieldEnabled && settingRegistrationFormEmailFieldEnabled.value); - - const settingRegistrationFormMessage = getSettingFromAppearance(instance, 'Livechat_registration_form_message'); - instance.registrationFormMessage.set(settingRegistrationFormMessage && settingRegistrationFormMessage.value); - }, - 'submit .rocket-form'(e, instance) { - e.preventDefault(); - const settings = [ - { - _id: 'Livechat_title', - value: s.trim(instance.title.get()), - }, - { - _id: 'Livechat_title_color', - value: instance.color.get(), - }, - { - _id: 'Livechat_enable_message_character_limit', - value: instance.showLimitTextLength.get(), - }, - { - _id: 'Livechat_message_character_limit', - value: parseInt(instance.limitTextLength.get()), - }, - { - _id: 'Livechat_show_agent_info', - value: instance.showAgentInfo.get(), - }, - { - _id: 'Livechat_show_agent_email', - value: instance.showAgentEmail.get(), - }, - { - _id: 'Livechat_display_offline_form', - value: instance.displayOfflineForm.get(), - }, - { - _id: 'Livechat_offline_form_unavailable', - value: s.trim(instance.offlineUnavailableMessage.get()), - }, - { - _id: 'Livechat_offline_message', - value: s.trim(instance.offlineMessage.get()), - }, - { - _id: 'Livechat_offline_success_message', - value: s.trim(instance.offlineSuccessMessage.get()), - }, - { - _id: 'Livechat_offline_title', - value: s.trim(instance.titleOffline.get()), - }, - { - _id: 'Livechat_offline_title_color', - value: instance.colorOffline.get(), - }, - { - _id: 'Livechat_offline_email', - value: instance.$('#emailOffline').val(), - }, - { - _id: 'Livechat_conversation_finished_message', - value: s.trim(instance.conversationFinishedMessage.get()), - }, - { - _id: 'Livechat_conversation_finished_text', - value: s.trim(instance.conversationFinishedText.get()), - }, - { - _id: 'Livechat_registration_form', - value: instance.registrationFormEnabled.get(), - }, - { - _id: 'Livechat_name_field_registration_form', - value: instance.registrationFormNameFieldEnabled.get(), - }, - { - _id: 'Livechat_email_field_registration_form', - value: instance.registrationFormEmailFieldEnabled.get(), - }, - { - _id: 'Livechat_registration_form_message', - value: s.trim(instance.registrationFormMessage.get()), - }, - ]; - - Meteor.call('livechat:saveAppearance', settings, (err/* , success*/) => { - if (err) { - return handleError(err); - } - instance.appearance.set(settings); - toastr.success(t('Settings_updated')); - }); - }, -}); diff --git a/app/livechat/client/views/app/livechatCurrentChats.css b/app/livechat/client/views/app/livechatCurrentChats.css deleted file mode 100644 index 7345337d597..00000000000 --- a/app/livechat/client/views/app/livechatCurrentChats.css +++ /dev/null @@ -1,25 +0,0 @@ -.rc-table-content { - & .js-sort { - cursor: pointer; - - &.is-sorting .table-fake-th .rc-icon { - opacity: 1; - } - } - - & .table-fake-th { - color: #444444; - - &:hover .rc-icon { - opacity: 1; - } - - & .rc-icon { - transition: opacity 0.3s; - - opacity: 0; - - font-size: 1rem; - } - } -} diff --git a/app/livechat/client/views/app/livechatCurrentChats.html b/app/livechat/client/views/app/livechatCurrentChats.html deleted file mode 100644 index df4720ba423..00000000000 --- a/app/livechat/client/views/app/livechatCurrentChats.html +++ /dev/null @@ -1,196 +0,0 @@ - diff --git a/app/livechat/client/views/app/livechatCurrentChats.js b/app/livechat/client/views/app/livechatCurrentChats.js deleted file mode 100644 index bb5dbd0915d..00000000000 --- a/app/livechat/client/views/app/livechatCurrentChats.js +++ /dev/null @@ -1,519 +0,0 @@ -import 'moment-timezone'; -import _ from 'underscore'; -import moment from 'moment'; -import './livechatCurrentChats.css'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { FlowRouter } from 'meteor/kadira:flow-router'; -import { Template } from 'meteor/templating'; -import { Meteor } from 'meteor/meteor'; -import { Random } from 'meteor/random'; -import toastr from 'toastr'; -import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; - -import { modal, call, popover } from '../../../../ui-utils'; -import { t, handleError, APIClient } from '../../../../utils/client'; -import { hasRole, hasPermission } from '../../../../authorization'; -import './livechatCurrentChats.html'; - -const ROOMS_COUNT = 50; -const FILTER_STORE_NAME = 'Filters.LivechatCurrentChats'; - -const loadStoredFilters = () => { - let storedFilters; - try { - const storeItem = Meteor._localStorage.getItem(FILTER_STORE_NAME); - storedFilters = storeItem ? JSON.parse(Meteor._localStorage.getItem(FILTER_STORE_NAME)) : {}; - } catch (e) { - storedFilters = {}; - } - - return storedFilters; -}; - -const storeFilters = (filters) => { - Meteor._localStorage.setItem(FILTER_STORE_NAME, JSON.stringify(filters)); -}; - -const removeStoredFilters = () => { - Meteor._localStorage.removeItem(FILTER_STORE_NAME); -}; - -Template.livechatCurrentChats.helpers({ - hasMore() { - const instance = Template.instance(); - return instance.total.get() > instance.livechatRooms.get().length; - }, - isLoading() { - return Template.instance().isLoading.get(); - }, - livechatRoom() { - return Template.instance().livechatRooms.get(); - }, - startedAt() { - return moment(this.ts).format('L LTS'); - }, - lastMessage() { - return moment(this.lm).format('L LTS'); - }, - servedBy() { - return this.servedBy && this.servedBy.username; - }, - status() { - return this.open ? t('Opened') : t('Closed'); - }, - isClosed() { - return !this.open; - }, - onSelectAgents() { - return Template.instance().onSelectAgents; - }, - agentModifier() { - return (filter, text = '') => { - const f = filter.get(); - return `@${ f.length === 0 ? text : text.replace(new RegExp(filter.get()), (part) => `${ part }`) }`; - }; - }, - selectedAgents() { - return Template.instance().selectedAgents.get(); - }, - onClickTagAgent() { - return Template.instance().onClickTagAgent; - }, - customFilters() { - return Template.instance().customFilters.get(); - }, - tagFilters() { - return Template.instance().tagFilters.get(); - }, - tagId() { - return this; - }, - departmentModifier() { - return (filter, text = '') => { - const f = filter.get(); - return `${ f.length === 0 ? text : text.replace(new RegExp(filter.get(), 'i'), (part) => `${ part }`) }`; - }; - }, - onClickTagDepartment() { - return Template.instance().onClickTagDepartment; - }, - selectedDepartments() { - return Template.instance().selectedDepartments.get(); - }, - onSelectDepartments() { - return Template.instance().onSelectDepartments; - }, - onTableSort() { - const { sortDirection, sortBy } = Template.instance(); - return function(type) { - if (sortBy.get() === type) { - return sortDirection.set(sortDirection.get() === 'asc' ? 'desc' : 'asc'); - } - sortBy.set(type); - sortDirection.set('asc'); - }; - }, - sortBy(key) { - return Template.instance().sortBy.get() === key; - }, - sortIcon(key) { - const { sortDirection, sortBy } = Template.instance(); - return key === sortBy.get() && sortDirection.get() === 'asc' - ? 'sort-up' - : 'sort-down'; - }, -}); - -Template.livechatCurrentChats.events({ - 'click .row-link'() { - FlowRouter.go('live', { id: this._id }); - }, - 'click .js-load-more'(event, instance) { - instance.offset.set(instance.offset.get() + ROOMS_COUNT); - }, - 'click .add-filter-button'(event, instance) { - event.preventDefault(); - - const customFields = instance.customFields.get(); - const filters = instance.customFilters.get(); - const tagFilters = instance.tagFilters.get(); - const options = []; - - options.push({ - name: t('Tags'), - action: () => { - tagFilters.push(Random.id()); - instance.tagFilters.set(tagFilters); - }, - }); - - for (const field of customFields) { - if (field.visibility !== 'visible') { - continue; - } - if (field.scope !== 'room') { - continue; - } - - if (filters.find((filter) => filter.name === field._id)) { - continue; - } - - options.push({ - name: field.label, - action: () => { - filters.push({ - _id: field._id, - name: field._id, - label: field.label, - }); - instance.customFilters.set(filters); - }, - }); - } - - const config = { - popoverClass: 'livechat-current-chats-add-filter', - columns: [ - { - groups: [ - { - items: options, - }, - ], - }, - ], - currentTarget: event.currentTarget, - offsetVertical: event.currentTarget.clientHeight, - }; - - popover.open(config); - }, - 'click .livechat-current-chats-extra-actions'(event, instance) { - event.preventDefault(); - event.stopPropagation(); - const { currentTarget } = event; - - const canRemoveAllClosedRooms = hasPermission('remove-closed-livechat-rooms'); - const allowedDepartments = () => { - if (hasRole(Meteor.userId(), ['admin', 'livechat-manager'])) { - return; - } - - const departments = instance.departments.get(); - return departments && departments.map((d) => d._id); - }; - - const config = { - popoverClass: 'livechat-current-chats-add-filter', - columns: [{ - groups: [ - { - items: [ - { - icon: 'customize', - name: t('Clear_filters'), - action: instance.clearFilters, - }, - canRemoveAllClosedRooms - && { - icon: 'trash', - name: t('Delete_all_closed_chats'), - modifier: 'alert', - action: () => { - modal.open({ - title: t('Are_you_sure'), - type: 'warning', - showCancelButton: true, - confirmButtonColor: '#DD6B55', - confirmButtonText: t('Yes'), - cancelButtonText: t('Cancel'), - closeOnConfirm: true, - html: false, - }, () => { - Meteor.call('livechat:removeAllClosedRooms', allowedDepartments(), (err, result) => { - if (err) { - return handleError(err); - } - - if (result) { - instance.loadRooms(instance.filter.get(), instance.offset.get()); - toastr.success(TAPi18n.__('All_closed_chats_have_been_removed')); - } - }); - }); - }, - }, - ], - }, - ], - }], - currentTarget, - offsetVertical: currentTarget.clientHeight, - }; - - popover.open(config); - }, - 'click .remove-livechat-tags-filter'(event, instance) { - event.preventDefault(); - - const { id } = event.currentTarget.dataset; - const tagFilters = instance.tagFilters.get(); - const index = tagFilters.indexOf(id); - - if (index >= 0) { - tagFilters.splice(index, 1); - } - instance.tagFilters.set(tagFilters); - }, - 'click .remove-livechat-custom-filter'(event, instance) { - event.preventDefault(); - const fieldName = event.currentTarget.dataset.name; - - const filters = instance.customFilters.get(); - const index = filters.findIndex((filter) => filter.name === fieldName); - - if (index >= 0) { - filters.splice(index, 1); - } - - instance.customFilters.set(filters); - }, - 'submit form'(event, instance) { - event.preventDefault(); - - const filter = {}; - $(':input', event.currentTarget).each(function() { - if (!this.name) { - return; - } - - const value = $(this).val(); - if (!value) { - return; - } - - if (this.name.startsWith('custom-field-')) { - if (!filter.customFields) { - filter.customFields = {}; - } - - filter.customFields[this.name.replace('custom-field-', '')] = value; - return; - } - - if (this.name === 'tags') { - if (!filter.tags) { - filter.tags = []; - } - - if (value) { - filter.tags.push(value); - } - - return; - } - - filter[this.name] = value; - }); - - if (!_.isEmpty(filter.from)) { - filter.from = moment(filter.from, moment.localeData().longDateFormat('L')).toDate(); - } else { - delete filter.from; - } - - if (!_.isEmpty(filter.to)) { - filter.to = moment(filter.to, moment.localeData().longDateFormat('L')).toDate(); - } else { - delete filter.to; - } - - const agents = instance.selectedAgents.get(); - if (agents && agents.length > 0) { - filter.agents = [agents[0]]; - } - - const departments = instance.selectedDepartments.get(); - if (departments && departments.length > 0) { - filter.department = [departments[0]]; - } - - instance.filter.set(filter); - instance.offset.set(0); - storeFilters(filter); - }, - 'click .remove-livechat-room'(event, instance) { - event.preventDefault(); - event.stopPropagation(); - - modal.open({ - title: t('Are_you_sure'), - type: 'warning', - showCancelButton: true, - confirmButtonColor: '#DD6B55', - confirmButtonText: t('Yes'), - cancelButtonText: t('Cancel'), - closeOnConfirm: false, - html: false, - }, async (confirmed) => { - if (!confirmed) { - return; - } - await call('livechat:removeRoom', this._id); - instance.loadRooms(instance.filter.get(), instance.offset.get()); - modal.open({ - title: t('Deleted'), - text: t('Room_has_been_deleted'), - type: 'success', - timer: 1000, - showConfirmButton: false, - }); - }); - }, - - 'input [id=agent]'(event, template) { - const input = event.currentTarget; - if (input.value === '') { - template.selectedAgents.set([]); - } - }, -}); - -Template.livechatCurrentChats.onCreated(async function() { - this.isLoading = new ReactiveVar(false); - this.offset = new ReactiveVar(0); - this.total = new ReactiveVar(0); - this.filter = new ReactiveVar(loadStoredFilters()); - this.livechatRooms = new ReactiveVar([]); - this.selectedAgents = new ReactiveVar([]); - this.customFilters = new ReactiveVar([]); - this.customFields = new ReactiveVar([]); - this.tagFilters = new ReactiveVar([]); - this.selectedDepartments = new ReactiveVar([]); - this.sortBy = new ReactiveVar('ts'); - this.sortDirection = new ReactiveVar('desc'); - - this.onSelectDepartments = ({ item: department }) => { - department.text = department.name; - this.selectedDepartments.set([department]); - }; - - this.onClickTagDepartment = () => { - this.selectedDepartments.set([]); - }; - - const mountArrayQueryParameters = (label, items, index) => items.reduce((acc, item) => { - const isTheLastElement = index === items.length - 1; - acc += `${ label }[]=${ item }${ isTheLastElement ? '' : '&' }`; - return acc; - }, ''); - - const mountUrlWithParams = (filter, offset, sort) => { - const { status, agents, department, from, to, tags, customFields, name: roomName } = filter; - let url = `livechat/rooms?count=${ ROOMS_COUNT }&offset=${ offset }&sort=${ JSON.stringify(sort) }`; - const dateRange = {}; - if (status) { - url += `&open=${ status === 'opened' }`; - } - if (department && Array.isArray(department) && department.length) { - url += `&departmentId=${ department[0]._id }`; - } - if (from) { - dateRange.start = `${ moment(new Date(from)).utc().format('YYYY-MM-DDTHH:mm:ss') }Z`; - } - if (to) { - dateRange.end = `${ moment(new Date(to).setHours(23, 59, 59)).utc().format('YYYY-MM-DDTHH:mm:ss') }Z`; - } - if (tags) { - url += `&${ mountArrayQueryParameters('tags', tags) }`; - } - if (agents && Array.isArray(agents) && agents.length) { - url += `&${ mountArrayQueryParameters('agents', agents.map((agent) => agent._id)) }`; - } - if (customFields) { - url += `&customFields=${ JSON.stringify(customFields) }`; - } - if (Object.keys(dateRange).length) { - url += `&createdAt=${ JSON.stringify(dateRange) }`; - } - if (roomName) { - url += `&roomName=${ roomName }`; - } - return url; - }; - - this.loadDefaultFilters = () => { - const defaultFilters = this.filter.get(); - - Object.keys(defaultFilters).forEach((key) => { - const value = defaultFilters[key]; - if (!value) { - return; - } - - switch (key) { - case 'agents': - return this.selectedAgents.set(value); - case 'department': - return this.selectedDepartments.set(value); - case 'from': - case 'to': - return $(`#${ key }`).datepicker('setDate', new Date(value)); - } - - $(`#${ key }`).val(value); - }); - }; - - this.clearFilters = () => { - removeStoredFilters(); - $('#form-filters').get(0).reset(); - this.selectedAgents.set([]); - this.selectedDepartments.set([]); - this.filter.set({}); - }; - - this.loadRooms = async (filter, offset, sort) => { - this.isLoading.set(true); - const { rooms, total } = await APIClient.v1.get(mountUrlWithParams(filter, offset, sort)); - this.total.set(total); - if (offset === 0) { - this.livechatRooms.set(rooms); - } else { - this.livechatRooms.set(this.livechatRooms.get().concat(rooms)); - } - this.isLoading.set(false); - }; - - this.onSelectAgents = ({ item: agent }) => { - this.selectedAgents.set([agent]); - }; - - this.onClickTagAgent = ({ username }) => { - this.selectedAgents.set(this.selectedAgents.get().filter((user) => user.username !== username)); - }; - - this.autorun(async () => { - const filter = this.filter.get(); - const offset = this.offset.get(); - const { sortDirection, sortBy } = Template.instance(); - this.loadRooms(filter, offset, { [sortBy.get()]: sortDirection.get() === 'asc' ? 1 : -1 }); - }); - - Meteor.call('livechat:getCustomFields', (err, customFields) => { - if (customFields) { - this.customFields.set(customFields); - } - }); -}); - -Template.livechatCurrentChats.onRendered(function() { - this.$('.input-daterange').datepicker({ - autoclose: true, - todayHighlight: true, - format: moment.localeData().longDateFormat('L').toLowerCase(), - }); - - this.loadDefaultFilters(); -}); diff --git a/app/livechat/client/views/app/livechatCustomFieldForm.html b/app/livechat/client/views/app/livechatCustomFieldForm.html deleted file mode 100644 index 0dcf4e1ae79..00000000000 --- a/app/livechat/client/views/app/livechatCustomFieldForm.html +++ /dev/null @@ -1,57 +0,0 @@ - diff --git a/app/livechat/client/views/app/livechatCustomFieldForm.js b/app/livechat/client/views/app/livechatCustomFieldForm.js deleted file mode 100644 index 9f8944dfdd7..00000000000 --- a/app/livechat/client/views/app/livechatCustomFieldForm.js +++ /dev/null @@ -1,100 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { FlowRouter } from 'meteor/kadira:flow-router'; -import { Template } from 'meteor/templating'; -import toastr from 'toastr'; - -import { t, handleError } from '../../../../utils'; -import { getCustomFormTemplate } from './customTemplates/register'; -import './livechatCustomFieldForm.html'; -import { APIClient } from '../../../../utils/client'; - -Template.livechatCustomFieldForm.helpers({ - customField() { - return Template.instance().customField.get(); - }, - - customFieldsTemplate() { - return getCustomFormTemplate('livechatCustomFieldsAdditionalForm'); - }, - - dataContext() { - // To make the dynamic template reactive we need to pass a ReactiveVar through the data property - // because only the dynamic template data will be reloaded - return Template.instance().localFields; - }, -}); - -Template.livechatCustomFieldForm.events({ - 'submit #customField-form'(e, instance) { - e.preventDefault(); - const $btn = instance.$('button.save'); - - const _id = $(e.currentTarget).data('id'); - const field = instance.$('input[name=field]').val(); - const label = instance.$('input[name=label]').val(); - const scope = instance.$('select[name=scope]').val(); - const visibility = instance.$('select[name=visibility]').val(); - const regexp = instance.$('input[name=regexp]').val(); - - if (!/^[0-9a-zA-Z-_]+$/.test(field)) { - return toastr.error(t('error-invalid-custom-field-name')); - } - - if (label.trim() === '') { - return toastr.error(t('Please_fill_a_label')); - } - - const oldBtnValue = $btn.html(); - $btn.html(t('Saving')); - - const customFieldData = { - field, - label, - scope: scope.trim(), - visibility: visibility.trim(), - regexp: regexp.trim(), - }; - - instance.$('.additional-field').each((i, el) => { - const elField = instance.$(el); - const name = elField.attr('name'); - let value = elField.val(); - if (['true', 'false'].includes(value) && el.tagName === 'SELECT') { - value = value === 'true'; - } - customFieldData[name] = value; - }); - - Meteor.call('livechat:saveCustomField', _id, customFieldData, function(error) { - $btn.html(oldBtnValue); - if (error) { - return handleError(error); - } - - toastr.success(t('Saved')); - FlowRouter.go('livechat-customfields'); - }); - }, - - 'click button.back'(e/* , instance*/) { - e.preventDefault(); - FlowRouter.go('livechat-customfields'); - }, - - 'change .custom-field-input'(e, instance) { - const { target: { name, value } } = e; - instance.localFields.set({ ...instance.localFields.get(), [name]: value }); - }, -}); - -Template.livechatCustomFieldForm.onCreated(async function() { - this.customField = new ReactiveVar({}); - this.localFields = new ReactiveVar({}); - - const { customField } = await APIClient.v1.get(`livechat/custom-fields/${ FlowRouter.getParam('_id') }`); - if (customField) { - this.customField.set(customField); - this.localFields.set({ ...customField }); - } -}); diff --git a/app/livechat/client/views/app/livechatCustomFields.html b/app/livechat/client/views/app/livechatCustomFields.html deleted file mode 100644 index 07fbeaedcfb..00000000000 --- a/app/livechat/client/views/app/livechatCustomFields.html +++ /dev/null @@ -1,37 +0,0 @@ - diff --git a/app/livechat/client/views/app/livechatCustomFields.js b/app/livechat/client/views/app/livechatCustomFields.js deleted file mode 100644 index 30d66e021fa..00000000000 --- a/app/livechat/client/views/app/livechatCustomFields.js +++ /dev/null @@ -1,83 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { FlowRouter } from 'meteor/kadira:flow-router'; -import { Template } from 'meteor/templating'; -import { ReactiveVar } from 'meteor/reactive-var'; - -import { modal } from '../../../../ui-utils'; -import { t, handleError, APIClient } from '../../../../utils/client'; -import './livechatCustomFields.html'; - -const CUSTOM_FIELDS_COUNT = 50; - -Template.livechatCustomFields.helpers({ - customFields() { - return Template.instance().customFields.get(); - }, - onTableScroll() { - const instance = Template.instance(); - return function(currentTarget) { - if (currentTarget.offsetHeight + currentTarget.scrollTop < currentTarget.scrollHeight - 100) { - return; - } - const customFields = instance.customFields.get(); - if (instance.total.get() <= customFields.length) { - return; - } - return instance.offset.set(instance.offset.get() + CUSTOM_FIELDS_COUNT); - }; - }, -}); - -Template.livechatCustomFields.events({ - 'click .remove-custom-field'(e, instance) { - e.preventDefault(); - e.stopPropagation(); - - modal.open({ - title: t('Are_you_sure'), - type: 'warning', - showCancelButton: true, - confirmButtonColor: '#DD6B55', - confirmButtonText: t('Yes'), - cancelButtonText: t('Cancel'), - closeOnConfirm: false, - html: false, - }, () => { - Meteor.call('livechat:removeCustomField', this._id, function(error/* , result*/) { - if (error) { - return handleError(error); - } - instance.offset.set(0); - modal.open({ - title: t('Removed'), - text: t('Field_removed'), - type: 'success', - timer: 1000, - showConfirmButton: false, - }); - }); - }); - }, - - 'click .custom-field-info'(e/* , instance*/) { - e.preventDefault(); - FlowRouter.go('livechat-customfield-edit', { _id: this._id }); - }, -}); - -Template.livechatCustomFields.onCreated(function() { - this.customFields = new ReactiveVar([]); - this.offset = new ReactiveVar(0); - this.total = new ReactiveVar(0); - - this.autorun(async () => { - const offset = this.offset.get(); - const { customFields, total } = await APIClient.v1.get(`livechat/custom-fields?count=${ CUSTOM_FIELDS_COUNT }&offset=${ offset }`); - if (offset === 0) { - this.customFields.set(customFields); - } else { - this.customFields.set(this.customFields.get().concat(customFields)); - } - this.total.set(total); - }); -}); diff --git a/app/livechat/client/views/app/livechatInstallation.html b/app/livechat/client/views/app/livechatInstallation.html deleted file mode 100644 index f91bcc4d665..00000000000 --- a/app/livechat/client/views/app/livechatInstallation.html +++ /dev/null @@ -1,10 +0,0 @@ - diff --git a/app/livechat/client/views/app/livechatInstallation.js b/app/livechat/client/views/app/livechatInstallation.js deleted file mode 100644 index 4c00cac4190..00000000000 --- a/app/livechat/client/views/app/livechatInstallation.js +++ /dev/null @@ -1,21 +0,0 @@ -import { Template } from 'meteor/templating'; -import s from 'underscore.string'; - -import { settings } from '../../../../settings'; -import './livechatInstallation.html'; - -Template.livechatInstallation.helpers({ - script() { - const siteUrl = s.rtrim(settings.get('Site_Url'), '/'); - return ` - -`; - }, -}); diff --git a/app/livechat/client/views/app/livechatManagers.html b/app/livechat/client/views/app/livechatManagers.html deleted file mode 100644 index d35e2d33be4..00000000000 --- a/app/livechat/client/views/app/livechatManagers.html +++ /dev/null @@ -1,88 +0,0 @@ - diff --git a/app/livechat/client/views/app/livechatManagers.js b/app/livechat/client/views/app/livechatManagers.js deleted file mode 100644 index 94684c1ee93..00000000000 --- a/app/livechat/client/views/app/livechatManagers.js +++ /dev/null @@ -1,192 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { Template } from 'meteor/templating'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { ReactiveDict } from 'meteor/reactive-dict'; -import _ from 'underscore'; - -import { modal, call } from '../../../../ui-utils'; -import { t, handleError } from '../../../../utils'; -import { APIClient } from '../../../../utils/client'; - -import './livechatManagers.html'; - -const MANAGERS_COUNT = 50; -const DEBOUNCE_TIME_TO_SEARCH_IN_MS = 500; - -const getUsername = (user) => user.username; -Template.livechatManagers.helpers({ - exceptionsManagers() { - const { selectedManagers } = Template.instance(); - return Template.instance() - .managers - .get() - .map(getUsername) - .concat(selectedManagers.get().map(getUsername)); - }, - deleteLastManager() { - const i = Template.instance(); - return () => { - const arr = i.selectedManagers.curValue; - arr.pop(); - i.selectedManagers.set(arr); - }; - }, - isLoading() { - return Template.instance().state.get('loading'); - }, - managers() { - return Template.instance().managers.get(); - }, - emailAddress() { - if (this.emails && this.emails.length > 0) { - return this.emails[0].address; - } - }, - managerModifier() { - return (filter, text = '') => { - const f = filter.get(); - return `@${ - f.length === 0 - ? text - : text.replace( - new RegExp(filter.get()), - (part) => `${ part }`, - ) - }`; - }; - }, - onSelectManagers() { - return Template.instance().onSelectManagers; - }, - selectedManagers() { - return Template.instance().selectedManagers.get(); - }, - onClickTagManagers() { - return Template.instance().onClickTagManagers; - }, - onTableScroll() { - const instance = Template.instance(); - return function(currentTarget) { - if (currentTarget.offsetHeight + currentTarget.scrollTop < currentTarget.scrollHeight - 100) { - return; - } - const managers = instance.managers.get(); - if (instance.total.get() > managers.length) { - instance.offset.set(instance.offset.get() + MANAGERS_COUNT); - } - }; - }, -}); - -Template.livechatManagers.events({ - 'click .remove-manager'(e, instance) { - e.preventDefault(); - - modal.open( - { - title: t('Are_you_sure'), - type: 'warning', - showCancelButton: true, - confirmButtonColor: '#DD6B55', - confirmButtonText: t('Yes'), - cancelButtonText: t('Cancel'), - closeOnConfirm: false, - html: false, - }, - () => { - Meteor.call('livechat:removeManager', this.username, function( - error, /* , result*/ - ) { - if (error) { - return handleError(error); - } - instance.loadManagers(instance.filter.get(), 0); - modal.open({ - title: t('Removed'), - text: t('Manager_removed'), - type: 'success', - timer: 1000, - showConfirmButton: false, - }); - }); - }, - ); - }, - async 'submit #form-manager'(e, instance) { - e.preventDefault(); - const { selectedManagers, state } = instance; - - const users = selectedManagers.get(); - - if (!users.length) { - return; - } - - state.set('loading', true); - try { - await Promise.all( - users.map(({ username }) => call('livechat:addManager', username)), - ); - selectedManagers.set([]); - } finally { - state.set('loading', false); - instance.loadManagers(instance.filter.get(), 0); - } - }, - 'keydown #managers-filter'(e) { - if (e.which === 13) { - e.stopPropagation(); - e.preventDefault(); - } - }, - 'keyup #managers-filter': _.debounce((e, t) => { - e.stopPropagation(); - e.preventDefault(); - t.filter.set(e.currentTarget.value); - t.offset.set(0); - }, DEBOUNCE_TIME_TO_SEARCH_IN_MS), -}); - -Template.livechatManagers.onCreated(function() { - const instance = this; - this.offset = new ReactiveVar(0); - this.filter = new ReactiveVar(''); - this.state = new ReactiveDict({ - loading: false, - }); - this.total = new ReactiveVar(0); - this.managers = new ReactiveVar([]); - this.selectedManagers = new ReactiveVar([]); - - this.onSelectManagers = ({ item: manager }) => { - this.selectedManagers.set([...this.selectedManagers.curValue, manager]); - }; - - this.onClickTagManagers = ({ username }) => { - this.selectedManagers.set( - this.selectedManagers.curValue.filter((user) => user.username !== username), - ); - }; - - this.loadManagers = _.debounce(async (filter, offset) => { - this.state.set('loading', true); - let url = `livechat/users/manager?count=${ MANAGERS_COUNT }&offset=${ offset }`; - if (filter) { - url += `&text=${ encodeURIComponent(filter) }`; - } - const { users, total } = await APIClient.v1.get(url); - this.total.set(total); - if (offset === 0) { - this.managers.set(users); - } else { - this.managers.set(this.managers.get().concat(users)); - } - this.state.set('loading', false); - }, DEBOUNCE_TIME_TO_SEARCH_IN_MS); - - this.autorun(async () => { - const filter = instance.filter.get(); - const offset = instance.offset.get(); - return this.loadManagers(filter, offset); - }); -}); diff --git a/app/livechat/client/views/app/livechatTriggers.html b/app/livechat/client/views/app/livechatTriggers.html deleted file mode 100644 index 7af6b8206e2..00000000000 --- a/app/livechat/client/views/app/livechatTriggers.html +++ /dev/null @@ -1,33 +0,0 @@ - diff --git a/app/livechat/client/views/app/livechatTriggers.js b/app/livechat/client/views/app/livechatTriggers.js deleted file mode 100644 index 6341dc63c4d..00000000000 --- a/app/livechat/client/views/app/livechatTriggers.js +++ /dev/null @@ -1,62 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { FlowRouter } from 'meteor/kadira:flow-router'; -import { Template } from 'meteor/templating'; - -import { modal } from '../../../../ui-utils'; -import { t, handleError } from '../../../../utils'; -import './livechatTriggers.html'; -import { APIClient } from '../../../../utils/client'; - -const loadTriggers = async (instance) => { - const { triggers } = await APIClient.v1.get('livechat/triggers'); - instance.triggers.set(triggers); -}; - -Template.livechatTriggers.helpers({ - triggers() { - return Template.instance().triggers.get(); - }, -}); - -Template.livechatTriggers.events({ - 'click .remove-trigger'(e, instance) { - e.preventDefault(); - e.stopPropagation(); - - modal.open({ - title: t('Are_you_sure'), - type: 'warning', - showCancelButton: true, - confirmButtonColor: '#DD6B55', - confirmButtonText: t('Yes'), - cancelButtonText: t('Cancel'), - closeOnConfirm: false, - html: false, - }, () => { - Meteor.call('livechat:removeTrigger', this._id, async function(error/* , result*/) { - if (error) { - return handleError(error); - } - await loadTriggers(instance); - modal.open({ - title: t('Removed'), - text: t('Trigger_removed'), - type: 'success', - timer: 1000, - showConfirmButton: false, - }); - }); - }); - }, - - 'click .trigger-info'(e/* , instance*/) { - e.preventDefault(); - FlowRouter.go('livechat-trigger-edit', { _id: this._id }); - }, -}); - -Template.livechatTriggers.onCreated(async function() { - this.triggers = new ReactiveVar([]); - await loadTriggers(this); -}); diff --git a/app/livechat/client/views/app/livechatTriggersForm.html b/app/livechat/client/views/app/livechatTriggersForm.html deleted file mode 100644 index 2ff035139de..00000000000 --- a/app/livechat/client/views/app/livechatTriggersForm.html +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/app/livechat/client/views/app/livechatTriggersForm.js b/app/livechat/client/views/app/livechatTriggersForm.js deleted file mode 100644 index 12f5cee015d..00000000000 --- a/app/livechat/client/views/app/livechatTriggersForm.js +++ /dev/null @@ -1,118 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { FlowRouter } from 'meteor/kadira:flow-router'; -import { Template } from 'meteor/templating'; -import toastr from 'toastr'; - -import { t, handleError } from '../../../../utils'; -import './livechatTriggersForm.html'; -import { APIClient } from '../../../../utils/client'; - -Template.livechatTriggersForm.helpers({ - name() { - const trigger = Template.instance().trigger.get(); - return trigger && trigger.name; - }, - description() { - const trigger = Template.instance().trigger.get(); - return trigger && trigger.description; - }, - enabled() { - const trigger = Template.instance().trigger.get(); - return trigger && trigger.enabled; - }, - runOnce() { - const trigger = Template.instance().trigger.get(); - return (trigger && trigger.runOnce) || false; - }, - conditions() { - const trigger = Template.instance().trigger.get(); - if (!trigger) { - return []; - } - - return trigger.conditions; - }, - actions() { - const trigger = Template.instance().trigger.get(); - if (!trigger) { - return []; - } - - return trigger.actions; - }, -}); - -Template.livechatTriggersForm.events({ - 'submit #trigger-form'(e, instance) { - e.preventDefault(); - const $btn = instance.$('button.save'); - - const oldBtnValue = $btn.html(); - $btn.html(t('Saving')); - - const data = { - _id: FlowRouter.getParam('_id'), - name: instance.$('input[name=name]').val(), - description: instance.$('input[name=description]').val(), - enabled: instance.$('input[name=enabled]:checked').val() === '1', - runOnce: instance.$('input[name=runOnce]:checked').val() === '1', - conditions: [], - actions: [], - }; - - $('.each-condition').each(function() { - data.conditions.push({ - name: $('.trigger-condition', this).val(), - value: $(`.${ $('.trigger-condition', this).val() }-value`).val(), - }); - }); - - $('.each-action').each(function() { - if ($('.trigger-action', this).val() === 'send-message') { - const params = { - sender: $('[name=send-message-sender]', this).val(), - msg: $('[name=send-message-msg]', this).val(), - }; - if (params.sender === 'custom') { - params.name = $('[name=send-message-name]', this).val(); - } - data.actions.push({ - name: $('.trigger-action', this).val(), - params, - }); - } else { - data.actions.push({ - name: $('.trigger-action', this).val(), - value: $(`.${ $('.trigger-action', this).val() }-value`).val(), - }); - } - }); - - Meteor.call('livechat:saveTrigger', data, function(error/* , result*/) { - $btn.html(oldBtnValue); - if (error) { - return handleError(error); - } - - FlowRouter.go('livechat-triggers'); - - toastr.success(t('Saved')); - }); - }, - - 'click button.back'(e/* , instance*/) { - e.preventDefault(); - FlowRouter.go('livechat-triggers'); - }, -}); - -Template.livechatTriggersForm.onCreated(async function() { - this.trigger = new ReactiveVar({}); - const id = FlowRouter.getParam('_id'); - - if (id) { - const { trigger } = await APIClient.v1.get(`livechat/triggers/${ id }`); - this.trigger.set(trigger); - } -}); diff --git a/app/livechat/client/views/app/triggers/livechatTriggerAction.html b/app/livechat/client/views/app/triggers/livechatTriggerAction.html deleted file mode 100644 index f4f8d3a4dc9..00000000000 --- a/app/livechat/client/views/app/triggers/livechatTriggerAction.html +++ /dev/null @@ -1,20 +0,0 @@ - diff --git a/app/livechat/client/views/app/triggers/livechatTriggerAction.js b/app/livechat/client/views/app/triggers/livechatTriggerAction.js deleted file mode 100644 index f8c35d94451..00000000000 --- a/app/livechat/client/views/app/triggers/livechatTriggerAction.js +++ /dev/null @@ -1,54 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { Template } from 'meteor/templating'; - -import './livechatTriggerAction.html'; - -Template.livechatTriggerAction.helpers({ - hiddenValue(current) { - if (this.name === undefined && Template.instance().firstAction) { - Template.instance().firstAction = false; - return ''; - } if (this.name !== current) { - return 'hidden'; - } - }, - showCustomName() { - return Template.instance().sender.get() === 'custom' ? '' : 'hidden'; - }, - senderSelected(current) { - return !!(this.params && this.params.sender === current); - }, - disableGetNextAgent() { - const config = Template.instance().routingConfig.get(); - return !config.enableTriggerAction; - }, -}); - -Template.livechatTriggerAction.events({ - 'change .trigger-action'(e, instance) { - instance.$('.trigger-action-value ').addClass('hidden'); - instance.$(`.${ e.currentTarget.value }`).removeClass('hidden'); - }, - 'change [name=send-message-sender]'(e, instance) { - instance.sender.set(e.currentTarget.value); - }, -}); - -Template.livechatTriggerAction.onCreated(function() { - this.firstAction = true; - - this.sender = new ReactiveVar(''); - this.routingConfig = new ReactiveVar({}); - - Meteor.call('livechat:getRoutingConfig', (err, config) => { - if (config) { - this.routingConfig.set(config); - } - }); - - const data = Template.currentData(); - if (data && data.name === 'send-message') { - this.sender.set(data.params.sender); - } -}); diff --git a/app/livechat/client/views/app/triggers/livechatTriggerCondition.html b/app/livechat/client/views/app/triggers/livechatTriggerCondition.html deleted file mode 100644 index 4daefc60d5e..00000000000 --- a/app/livechat/client/views/app/triggers/livechatTriggerCondition.html +++ /dev/null @@ -1,18 +0,0 @@ - diff --git a/app/livechat/client/views/app/triggers/livechatTriggerCondition.js b/app/livechat/client/views/app/triggers/livechatTriggerCondition.js deleted file mode 100644 index 02c8ce64a44..00000000000 --- a/app/livechat/client/views/app/triggers/livechatTriggerCondition.js +++ /dev/null @@ -1,34 +0,0 @@ -import { Template } from 'meteor/templating'; -import './livechatTriggerCondition.html'; - -Template.livechatTriggerCondition.helpers({ - hiddenValue(current) { - if (this.name === undefined && Template.instance().firstCondition) { - Template.instance().firstCondition = false; - return ''; - } if (this.name !== current) { - return 'hidden'; - } - }, - conditionSelected(current) { - if (this.name === current) { - return 'selected'; - } - }, - valueFor(condition) { - if (this.name === condition) { - return this.value; - } - }, -}); - -Template.livechatTriggerCondition.events({ - 'change .trigger-condition'(e, instance) { - instance.$('.trigger-condition-value ').addClass('hidden'); - instance.$(`.${ e.currentTarget.value }`).removeClass('hidden'); - }, -}); - -Template.livechatTriggerCondition.onCreated(function() { - this.firstCondition = true; -}); diff --git a/app/livechat/client/views/sideNav/livechatFlex.html b/app/livechat/client/views/sideNav/livechatFlex.html deleted file mode 100644 index df02ebe0a40..00000000000 --- a/app/livechat/client/views/sideNav/livechatFlex.html +++ /dev/null @@ -1,19 +0,0 @@ - diff --git a/app/livechat/client/views/sideNav/livechatFlex.js b/app/livechat/client/views/sideNav/livechatFlex.js deleted file mode 100644 index f57b76c313d..00000000000 --- a/app/livechat/client/views/sideNav/livechatFlex.js +++ /dev/null @@ -1,34 +0,0 @@ -import { Template } from 'meteor/templating'; -import { FlowRouter } from 'meteor/kadira:flow-router'; - -import { SideNav, Layout } from '../../../../ui-utils'; -import { t } from '../../../../utils'; -import { hasPermission } from '../../../../authorization'; -import './livechatFlex.html'; -import { sidebarItems } from './livechatSideNavItems'; - -Template.livechatFlex.helpers({ - menuItem(name, icon, section) { - const routeName = FlowRouter.getRouteName(); - return { - name: t(name), - icon, - pathSection: section, - darken: true, - active: section === routeName, - }; - }, - embeddedVersion() { - return Layout.isEmbedded(); - }, - sidebarItems() { - const items = sidebarItems.get(); - return items.filter((item) => !item.permission || hasPermission(item.permission)); - }, -}); - -Template.livechatFlex.events({ - 'click [data-action="close"]'() { - SideNav.closeFlex(); - }, -}); diff --git a/app/livechat/client/views/sideNav/livechatSideNavItems.js b/app/livechat/client/views/sideNav/livechatSideNavItems.js deleted file mode 100644 index 74d64d19d9d..00000000000 --- a/app/livechat/client/views/sideNav/livechatSideNavItems.js +++ /dev/null @@ -1,27 +0,0 @@ -import { ReactiveVar } from 'meteor/reactive-var'; - -export const sidebarItems = new ReactiveVar([]); -export const addSidebarItem = (title, slug, permission) => { - sidebarItems.set([ - ...sidebarItems.get(), - { - title, - slug, - permission, - }, - ]); -}; - -addSidebarItem('Current_Chats', 'livechat-current-chats', 'view-livechat-current-chats'); -addSidebarItem('Analytics', 'livechat-analytics', 'view-livechat-analytics'); -addSidebarItem('Real_Time_Monitoring', 'livechat-real-time-monitoring', 'view-livechat-real-time-monitoring'); -addSidebarItem('Managers', 'livechat-managers', 'manage-livechat-managers'); -addSidebarItem('Agents', 'livechat-agents', 'manage-livechat-agents'); -addSidebarItem('Departments', 'livechat-departments', 'view-livechat-departments'); -addSidebarItem('Custom_Fields', 'livechat-customfields', 'view-livechat-customfields'); -addSidebarItem('Livechat_Triggers', 'livechat-triggers', 'view-livechat-triggers'); -addSidebarItem('Livechat_Installation', 'livechat-installation', 'view-livechat-installation'); -addSidebarItem('Livechat_Appearance', 'livechat-appearance', 'view-livechat-appearance'); -addSidebarItem('Webhooks', 'livechat-webhooks', 'view-livechat-webhooks'); -addSidebarItem('Facebook Messenger', 'livechat-facebook', 'view-livechat-facebook'); -addSidebarItem('Business_Hours', 'livechat-business-hours', 'view-livechat-business-hours'); diff --git a/app/ui-sidenav/client/sidebarHeader.js b/app/ui-sidenav/client/sidebarHeader.js index f1bc60b7bf5..0d3f95e189e 100644 --- a/app/ui-sidenav/client/sidebarHeader.js +++ b/app/ui-sidenav/client/sidebarHeader.js @@ -174,18 +174,17 @@ const toolbarButtons = (/* user */) => [{ items: AccountBox.getItems().map((item) => { let action; - if (item.href) { + if (item.href || item.sideNav) { action = () => { - FlowRouter.go(item.href); - popover.close(); - }; - } - - if (item.sideNav) { - action = () => { - SideNav.setFlex(item.sideNav); - SideNav.openFlex(); - popover.close(); + if (item.href) { + FlowRouter.go(item.href); + popover.close(); + } + if (item.sideNav) { + SideNav.setFlex(item.sideNav); + SideNav.openFlex(); + popover.close(); + } }; } diff --git a/client/account/AccountSidebar.js b/client/account/AccountSidebar.js index 3ea419af1f0..3aa09ae3f94 100644 --- a/client/account/AccountSidebar.js +++ b/client/account/AccountSidebar.js @@ -22,14 +22,14 @@ export default React.memo(function AccountSidebar() { SideNav.closeFlex(); }, []); - const currentRoute = useCurrentRoute(); - const currentPath = useRoutePath(...currentRoute); + const [currentRouteName, ...rest] = useCurrentRoute(); + const currentPath = useRoutePath(currentRouteName, ...rest); useEffect(() => { - if (currentRoute[0] !== 'account') { + if (currentRouteName !== 'account') { SideNav.closeFlex(); } - }, [currentRoute, currentPath]); + }, [currentRouteName]); // TODO: uplift this provider return diff --git a/client/admin/AdministrationRouter.js b/client/admin/AdministrationRouter.js index 381bfa8ceee..cb52f420572 100644 --- a/client/admin/AdministrationRouter.js +++ b/client/admin/AdministrationRouter.js @@ -2,7 +2,7 @@ import React, { lazy, useMemo, Suspense } from 'react'; import SettingsProvider from '../providers/SettingsProvider'; import AdministrationLayout from './AdministrationLayout'; -import PageSkeleton from './PageSkeleton'; +import PageSkeleton from '../components/PageSkeleton'; function AdministrationRouter({ lazyRouteComponent, ...props }) { const LazyRouteComponent = useMemo(() => lazy(lazyRouteComponent), [lazyRouteComponent]); diff --git a/client/admin/apps/AppsRoute.js b/client/admin/apps/AppsRoute.js index cbbbd1cb8c9..ee38688fb71 100644 --- a/client/admin/apps/AppsRoute.js +++ b/client/admin/apps/AppsRoute.js @@ -4,7 +4,7 @@ import { usePermission } from '../../contexts/AuthorizationContext'; import { useRouteParameter, useRoute, useCurrentRoute } from '../../contexts/RouterContext'; import { useMethod } from '../../contexts/ServerContext'; import NotAuthorizedPage from '../../components/NotAuthorizedPage'; -import PageSkeleton from '../PageSkeleton'; +import PageSkeleton from '../../components/PageSkeleton'; import AppDetailsPage from './AppDetailsPage'; import MarketplacePage from './MarketplacePage'; import AppsPage from './AppsPage'; diff --git a/client/admin/routes.js b/client/admin/routes.js index 9a30bad67d3..d8a13b7990f 100644 --- a/client/admin/routes.js +++ b/client/admin/routes.js @@ -1,30 +1,8 @@ -import { FlowRouter } from 'meteor/kadira:flow-router'; import { Meteor } from 'meteor/meteor'; -import { renderRouteComponent } from '../reactAdapters'; +import { createRouteGroup } from '../helpers/createRouteGroup'; -const routeGroup = FlowRouter.group({ - name: 'admin', - prefix: '/admin', -}); - -export const registerAdminRoute = (path, { lazyRouteComponent, props, action, ...options } = {}) => { - routeGroup.route(path, { - ...options, - action: (params, queryParams) => { - if (action) { - action(params, queryParams); - return; - } - - renderRouteComponent(() => import('./AdministrationRouter'), { - template: 'main', - region: 'center', - propsFn: () => ({ lazyRouteComponent, ...options, params, queryParams, ...props }), - }); - }, - }); -}; +export const registerAdminRoute = createRouteGroup('admin', '/admin', () => import('./AdministrationRouter')); registerAdminRoute('/', { triggersEnter: [(context, redirect) => { diff --git a/client/admin/sidebar/AdminSidebar.js b/client/admin/sidebar/AdminSidebar.js index 27a29fcd930..2ea9ff38571 100644 --- a/client/admin/sidebar/AdminSidebar.js +++ b/client/admin/sidebar/AdminSidebar.js @@ -8,7 +8,6 @@ import { SettingType } from '../../../definition/ISetting'; import { useSettings } from '../../contexts/SettingsContext'; import { useTranslation } from '../../contexts/TranslationContext'; import { useRoutePath, useCurrentRoute } from '../../contexts/RouterContext'; -import { useAbsoluteUrl } from '../../contexts/ServerContext'; import { useAtLeastOnePermission } from '../../contexts/AuthorizationContext'; import Sidebar from '../../components/basic/Sidebar'; import SettingsProvider from '../../providers/SettingsProvider'; @@ -123,14 +122,13 @@ export default React.memo(function AdminSidebar() { const currentRoute = useCurrentRoute(); const currentPath = useRoutePath(...currentRoute); - const absoluteUrl = useAbsoluteUrl(); + const [,,, currentRouteGroupName] = currentRoute; useEffect(() => { - const { pathname: adminPath } = new URL(absoluteUrl('admin/')); - if (!currentPath.startsWith(adminPath)) { + if (currentRouteGroupName !== 'admin') { SideNav.closeFlex(); } - }, [absoluteUrl, currentPath]); + }, [currentRouteGroupName]); // TODO: uplift this provider return diff --git a/client/admin/users/EditUser.js b/client/admin/users/EditUser.js index 2780db30956..03e1867585b 100644 --- a/client/admin/users/EditUser.js +++ b/client/admin/users/EditUser.js @@ -1,5 +1,5 @@ import React, { useMemo, useState, useCallback } from 'react'; -import { Box, Field, Margins, Button } from '@rocket.chat/fuselage'; +import { Box, Field, Margins, Button, Callout } from '@rocket.chat/fuselage'; import { useTranslation } from '../../contexts/TranslationContext'; import { useEndpointDataExperimental, ENDPOINT_STATES } from '../../hooks/useEndpointDataExperimental'; @@ -21,7 +21,7 @@ export function EditUserWithData({ uid, ...props }) { } if (error || roleError) { - return {t('User_not_found')}; + return {t('User_not_found')}; } return ; diff --git a/client/components/GenericTable.js b/client/components/GenericTable.js index da13d250547..c8398dbb450 100644 --- a/client/components/GenericTable.js +++ b/client/components/GenericTable.js @@ -45,6 +45,7 @@ export const GenericTable = forwardRef(function GenericTable({ setParams = () => { }, params: paramsDefault = '', FilterComponent = () => null, + ...props }, ref) { const t = useTranslation(); @@ -70,7 +71,7 @@ export const GenericTable = forwardRef(function GenericTable({ const itemsPerPageLabel = useCallback(() => t('Items_per_page:'), [t]); return <> - + {results && !results.length ? {t('No_data_found')} diff --git a/client/admin/PageSkeleton.js b/client/components/PageSkeleton.js similarity index 93% rename from client/admin/PageSkeleton.js rename to client/components/PageSkeleton.js index 875b6a7fa2d..7a5b17a7d0e 100644 --- a/client/admin/PageSkeleton.js +++ b/client/components/PageSkeleton.js @@ -1,7 +1,7 @@ import { Box, Button, ButtonGroup, Skeleton } from '@rocket.chat/fuselage'; import React from 'react'; -import Page from '../components/basic/Page'; +import Page from './basic/Page'; function PageSkeleton() { return diff --git a/client/components/basic/AutoComplete.js b/client/components/basic/AutoComplete.js new file mode 100644 index 00000000000..1acbd81c888 --- /dev/null +++ b/client/components/basic/AutoComplete.js @@ -0,0 +1,23 @@ +import React, { useMemo, useState } from 'react'; +import { AutoComplete, Option, Options } from '@rocket.chat/fuselage'; + +import { useEndpointDataExperimental } from '../../hooks/useEndpointDataExperimental'; +import UserAvatar from './avatar/UserAvatar'; + +const query = (term = '') => ({ selector: JSON.stringify({ term }) }); + +const Avatar = ({ value, ...props }) => ; + +export const UserAutoComplete = React.memo((props) => { + const [filter, setFilter] = useState(''); + const { data } = useEndpointDataExperimental('users.autocomplete', useMemo(() => query(filter), [filter])); + const options = useMemo(() => (data && data.items.map((user) => ({ value: user.username, label: user.name }))) || [], [data]); + return <> {label}} + renderItem={({ value, ...props }) =>