diff --git a/.changeset/tidy-cows-destroy.md b/.changeset/tidy-cows-destroy.md new file mode 100644 index 000000000000..0b222f8157a9 --- /dev/null +++ b/.changeset/tidy-cows-destroy.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +feat: Community users will now be able to customize their Business hour timezone diff --git a/apps/meteor/app/livechat/client/views/app/business-hours/BusinessHours.ts b/apps/meteor/app/livechat/client/views/app/business-hours/BusinessHours.ts index 0935ac7554e4..3c723cc46257 100644 --- a/apps/meteor/app/livechat/client/views/app/business-hours/BusinessHours.ts +++ b/apps/meteor/app/livechat/client/views/app/business-hours/BusinessHours.ts @@ -29,10 +29,6 @@ class BusinessHoursManager { showBackButton(): boolean { return this.behavior.showBackButton(); } - - showTimezoneTemplate(): boolean { - return this.behavior.showTimezoneTemplate(); - } } export const businessHourManager = new BusinessHoursManager(new SingleBusinessHourBehavior()); diff --git a/apps/meteor/app/livechat/client/views/app/business-hours/IBusinessHourBehavior.ts b/apps/meteor/app/livechat/client/views/app/business-hours/IBusinessHourBehavior.ts index 10a51fe25e25..1ba6e4a56907 100644 --- a/apps/meteor/app/livechat/client/views/app/business-hours/IBusinessHourBehavior.ts +++ b/apps/meteor/app/livechat/client/views/app/business-hours/IBusinessHourBehavior.ts @@ -4,5 +4,4 @@ export interface IBusinessHourBehavior { getView(): string; showCustomTemplate(businessHourData: ILivechatBusinessHour): boolean; showBackButton(): boolean; - showTimezoneTemplate(): boolean; } diff --git a/apps/meteor/app/livechat/client/views/app/business-hours/Single.ts b/apps/meteor/app/livechat/client/views/app/business-hours/Single.ts index 1ce09a63d79a..9b343264ca54 100644 --- a/apps/meteor/app/livechat/client/views/app/business-hours/Single.ts +++ b/apps/meteor/app/livechat/client/views/app/business-hours/Single.ts @@ -12,8 +12,4 @@ export class SingleBusinessHourBehavior implements IBusinessHourBehavior { showBackButton(): boolean { return false; } - - showTimezoneTemplate(): boolean { - return false; - } } diff --git a/apps/meteor/client/views/omnichannel/businessHours/BusinessHoursFormContainer.js b/apps/meteor/client/views/omnichannel/businessHours/BusinessHoursFormContainer.js index c274ebee272d..9acf9d2fd167 100644 --- a/apps/meteor/client/views/omnichannel/businessHours/BusinessHoursFormContainer.js +++ b/apps/meteor/client/views/omnichannel/businessHours/BusinessHoursFormContainer.js @@ -7,6 +7,7 @@ import { useForm } from '../../../hooks/useForm'; import { useReactiveValue } from '../../../hooks/useReactiveValue'; import { useFormsSubscription } from '../additionalForms'; import BusinessHourForm from './BusinessHoursForm'; +import BusinessHoursTimeZone from './BusinessHoursTimeZone'; const useChangeHandler = (name, ref) => useMutableCallback((val) => { @@ -29,12 +30,10 @@ const BusinessHoursFormContainer = ({ data, saveRef, onChange = () => {} }) => { const [hasChangesMultiple, setHasChangesMultiple] = useState(false); const [hasChangesTimeZone, setHasChangesTimeZone] = useState(false); - const { useBusinessHoursTimeZone = cleanFunc, useBusinessHoursMultiple = cleanFunc } = forms; + const { useBusinessHoursMultiple = cleanFunc } = forms; - const TimezoneForm = useBusinessHoursTimeZone(); const MultipleBHForm = useBusinessHoursMultiple(); - const showTimezone = useReactiveValue(useMutableCallback(() => businessHourManager.showTimezoneTemplate())); const showMultipleBHForm = useReactiveValue(useMutableCallback(() => businessHourManager.showCustomTemplate(data))); const onChangeTimezone = useChangeHandler('timezone', saveRef); @@ -45,7 +44,7 @@ const BusinessHoursFormContainer = ({ data, saveRef, onChange = () => {} }) => { saveRef.current.form = values; useEffect(() => { - onChange(hasUnsavedChanges || (showMultipleBHForm && hasChangesMultiple) || (showTimezone && hasChangesTimeZone)); + onChange(hasUnsavedChanges || (showMultipleBHForm && hasChangesMultiple) || hasChangesTimeZone); }); return ( @@ -54,9 +53,11 @@ const BusinessHoursFormContainer = ({ data, saveRef, onChange = () => {} }) => { {showMultipleBHForm && MultipleBHForm && ( )} - {showTimezone && TimezoneForm && ( - - )} + diff --git a/apps/meteor/ee/client/omnichannel/additionalForms/BusinessHoursTimeZone.js b/apps/meteor/client/views/omnichannel/businessHours/BusinessHoursTimeZone.js similarity index 86% rename from apps/meteor/ee/client/omnichannel/additionalForms/BusinessHoursTimeZone.js rename to apps/meteor/client/views/omnichannel/businessHours/BusinessHoursTimeZone.js index c305dc084e68..8826fc621455 100644 --- a/apps/meteor/ee/client/omnichannel/additionalForms/BusinessHoursTimeZone.js +++ b/apps/meteor/client/views/omnichannel/businessHours/BusinessHoursTimeZone.js @@ -2,8 +2,8 @@ import { SelectFiltered, Field } from '@rocket.chat/fuselage'; import { useTranslation } from '@rocket.chat/ui-contexts'; import React, { useMemo } from 'react'; -import { useForm } from '../../../../client/hooks/useForm'; -import { useTimezoneNameList } from '../../../../client/hooks/useTimezoneNameList'; +import { useForm } from '../../../hooks/useForm'; +import { useTimezoneNameList } from '../../../hooks/useTimezoneNameList'; const getInitialData = (data = {}) => ({ name: data ?? '', diff --git a/apps/meteor/ee/client/omnichannel/additionalForms/BusinessHoursTimeZone.stories.tsx b/apps/meteor/client/views/omnichannel/businessHours/BusinessHoursTimeZone.stories.tsx similarity index 91% rename from apps/meteor/ee/client/omnichannel/additionalForms/BusinessHoursTimeZone.stories.tsx rename to apps/meteor/client/views/omnichannel/businessHours/BusinessHoursTimeZone.stories.tsx index 35c133caf72a..af00db33322e 100644 --- a/apps/meteor/ee/client/omnichannel/additionalForms/BusinessHoursTimeZone.stories.tsx +++ b/apps/meteor/client/views/omnichannel/businessHours/BusinessHoursTimeZone.stories.tsx @@ -5,7 +5,7 @@ import React from 'react'; import BusinessHoursTimeZone from './BusinessHoursTimeZone'; export default { - title: 'Enterprise/Omnichannel/BusinessHoursTimeZone', + title: 'Omnichannel/BusinessHoursTimeZone', component: BusinessHoursTimeZone, decorators: [ (fn) => ( diff --git a/apps/meteor/ee/app/livechat-enterprise/client/SingleBusinessHour.ts b/apps/meteor/ee/app/livechat-enterprise/client/SingleBusinessHour.ts deleted file mode 100644 index e1f8b852fbc6..000000000000 --- a/apps/meteor/ee/app/livechat-enterprise/client/SingleBusinessHour.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { SingleBusinessHourBehavior } from '../../../../app/livechat/client/views/app/business-hours/Single'; - -export class EESingleBusinessHourBehaviour extends SingleBusinessHourBehavior { - showTimezoneTemplate(): boolean { - return true; - } -} diff --git a/apps/meteor/ee/app/livechat-enterprise/client/startup.ts b/apps/meteor/ee/app/livechat-enterprise/client/startup.ts index 11027a62439b..3c3ec1c02139 100644 --- a/apps/meteor/ee/app/livechat-enterprise/client/startup.ts +++ b/apps/meteor/ee/app/livechat-enterprise/client/startup.ts @@ -2,20 +2,21 @@ import { Meteor } from 'meteor/meteor'; import { businessHourManager } from '../../../../app/livechat/client/views/app/business-hours/BusinessHours'; import type { IBusinessHourBehavior } from '../../../../app/livechat/client/views/app/business-hours/IBusinessHourBehavior'; +import { SingleBusinessHourBehavior } from '../../../../app/livechat/client/views/app/business-hours/Single'; import { settings } from '../../../../app/settings/client'; import { hasLicense } from '../../license/client'; -import { EESingleBusinessHourBehaviour } from './SingleBusinessHour'; import { MultipleBusinessHoursBehavior } from './views/business-hours/Multiple'; const businessHours: Record = { multiple: new MultipleBusinessHoursBehavior(), - single: new EESingleBusinessHourBehaviour(), + single: new SingleBusinessHourBehavior(), }; Meteor.startup(() => { - settings.onload('Livechat_business_hour_type', async (_, value) => { + Tracker.autorun(async () => { + const bhType = settings.get('Livechat_business_hour_type'); if (await hasLicense('livechat-enterprise')) { - businessHourManager.registerBusinessHourBehavior(businessHours[(value as string).toLowerCase()]); + businessHourManager.registerBusinessHourBehavior(businessHours[bhType.toLowerCase()]); } }); }); diff --git a/apps/meteor/ee/app/livechat-enterprise/client/views/business-hours/Multiple.ts b/apps/meteor/ee/app/livechat-enterprise/client/views/business-hours/Multiple.ts index cbe3fe9088fe..a57344da73dc 100644 --- a/apps/meteor/ee/app/livechat-enterprise/client/views/business-hours/Multiple.ts +++ b/apps/meteor/ee/app/livechat-enterprise/client/views/business-hours/Multiple.ts @@ -12,10 +12,6 @@ export class MultipleBusinessHoursBehavior implements IBusinessHourBehavior { return !businessHourData._id || businessHourData.type !== LivechatBusinessHourTypes.DEFAULT; } - showTimezoneTemplate(): boolean { - return true; - } - showBackButton(): boolean { return true; } diff --git a/apps/meteor/ee/app/livechat-enterprise/server/business-hour/Helper.ts b/apps/meteor/ee/app/livechat-enterprise/server/business-hour/Helper.ts index a441e122ef99..a91bb87f28bb 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/business-hour/Helper.ts +++ b/apps/meteor/ee/app/livechat-enterprise/server/business-hour/Helper.ts @@ -1,8 +1,6 @@ import type { ILivechatBusinessHour } from '@rocket.chat/core-typings'; import { LivechatBusinessHourTypes } from '@rocket.chat/core-typings'; -import { License } from '@rocket.chat/license'; -import { LivechatBusinessHours, LivechatDepartment, LivechatDepartmentAgents, Users } from '@rocket.chat/models'; -import moment from 'moment-timezone'; +import { LivechatDepartment, LivechatDepartmentAgents, Users } from '@rocket.chat/models'; import { businessHourLogger } from '../../../../../app/livechat/server/lib/logger'; @@ -103,28 +101,3 @@ export const removeBusinessHourByAgentIds = async (agentIds: string[], businessH await Users.removeBusinessHourByAgentIds(agentIds, businessHourId); await Users.updateLivechatStatusBasedOnBusinessHours(); }; - -export const resetDefaultBusinessHourIfNeeded = async (): Promise => { - if (License.hasValidLicense()) { - return; - } - - const defaultBusinessHour = await LivechatBusinessHours.findOneDefaultBusinessHour>({ - projection: { _id: 1 }, - }); - if (!defaultBusinessHour) { - return; - } - - await LivechatBusinessHours.updateOne( - { _id: defaultBusinessHour._id }, - { - $set: { - timezone: { - name: moment.tz.guess(), - utc: String(moment().utcOffset() / 60), - }, - }, - }, - ); -}; diff --git a/apps/meteor/ee/app/livechat-enterprise/server/startup.ts b/apps/meteor/ee/app/livechat-enterprise/server/startup.ts index 29cf5c308d71..1b277d6fba52 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/startup.ts +++ b/apps/meteor/ee/app/livechat-enterprise/server/startup.ts @@ -3,7 +3,6 @@ import { Meteor } from 'meteor/meteor'; import { businessHourManager } from '../../../../app/livechat/server/business-hour'; import { SingleBusinessHourBehavior } from '../../../../app/livechat/server/business-hour/Single'; import { settings } from '../../../../app/settings/server'; -import { resetDefaultBusinessHourIfNeeded } from './business-hour/Helper'; import { MultipleBusinessHoursBehavior } from './business-hour/Multiple'; import { updatePredictedVisitorAbandonment, updateQueueInactivityTimeout } from './lib/Helper'; import { VisitorInactivityMonitor } from './lib/VisitorInactivityMonitor'; @@ -43,6 +42,4 @@ Meteor.startup(async () => { logger.debug(`Business hour manager started`); } }); - - await resetDefaultBusinessHourIfNeeded(); }); diff --git a/apps/meteor/ee/client/omnichannel/additionalForms/register.ts b/apps/meteor/ee/client/omnichannel/additionalForms/register.ts index df11a435ab5c..d52a20e40734 100644 --- a/apps/meteor/ee/client/omnichannel/additionalForms/register.ts +++ b/apps/meteor/ee/client/omnichannel/additionalForms/register.ts @@ -6,7 +6,6 @@ import { registerForm } from '../../../../client/views/omnichannel/additionalFor import { hasLicense } from '../../../app/license/client'; import type CurrentChatTags from '../tags/CurrentChatTags'; import type BusinessHoursMultipleContainer from './BusinessHoursMultipleContainer'; -import type BusinessHoursTimeZone from './BusinessHoursTimeZone'; import type ContactManager from './ContactManager'; import type CustomFieldsAdditionalFormContainer from './CustomFieldsAdditionalFormContainer'; import type DepartmentBusinessHours from './DepartmentBusinessHours'; @@ -29,7 +28,6 @@ declare module '../../../../client/views/omnichannel/additionalForms' { useEeTextAreaInput?: () => LazyExoticComponent; useBusinessHoursMultiple?: () => LazyExoticComponent; useEeTextInput?: () => LazyExoticComponent; - useBusinessHoursTimeZone?: () => LazyExoticComponent; useContactManager?: () => LazyExoticComponent; useCurrentChatTags?: () => LazyExoticComponent; @@ -54,7 +52,6 @@ hasLicense('livechat-enterprise').then((enabled) => { useEeTextAreaInput: () => useMemo(() => lazy(() => import('./EeTextAreaInput')), []), useBusinessHoursMultiple: () => useMemo(() => lazy(() => import('./BusinessHoursMultipleContainer')), []), useEeTextInput: () => useMemo(() => lazy(() => import('./EeTextInput')), []), - useBusinessHoursTimeZone: () => useMemo(() => lazy(() => import('./BusinessHoursTimeZone')), []), useContactManager: () => useMemo(() => lazy(() => import('./ContactManager')), []), useCurrentChatTags: () => useMemo(() => lazy(() => import('../tags/CurrentChatTags')), []), useDepartmentBusinessHours: () => useMemo(() => lazy(() => import('./DepartmentBusinessHours')), []),