Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73abdfc1b7 | ||
|
|
b7454c5d87 | ||
|
|
7b9ebaf90c | ||
|
|
d3ad267227 | ||
|
|
2762da5636 | ||
|
|
1fed175e65 |
@@ -1,6 +1,8 @@
|
|||||||
<script>
|
<script>
|
||||||
import DatePicker from 'vue-datepicker-next';
|
import DatePicker from 'vue-datepicker-next';
|
||||||
import NextButton from 'dashboard/components-next/button/Button.vue';
|
import NextButton from 'dashboard/components-next/button/Button.vue';
|
||||||
|
import { getUnixTime } from 'date-fns';
|
||||||
|
import { saveLastCustomSnoozeTime } from 'dashboard/helper/customSnoozeStorage';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -25,7 +27,13 @@ export default {
|
|||||||
this.$emit('close');
|
this.$emit('close');
|
||||||
},
|
},
|
||||||
chooseTime() {
|
chooseTime() {
|
||||||
this.$emit('chooseTime', this.snoozeTime);
|
if (this.snoozeTime) {
|
||||||
|
const unixTimestamp = getUnixTime(this.snoozeTime);
|
||||||
|
// Save the custom time to localStorage for future use
|
||||||
|
saveLastCustomSnoozeTime(unixTimestamp);
|
||||||
|
// The saveLastCustomSnoozeTime function will emit the event automatically
|
||||||
|
this.$emit('chooseTime', this.snoozeTime);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
disabledDate(date) {
|
disabledDate(date) {
|
||||||
// Disable all the previous dates
|
// Disable all the previous dates
|
||||||
|
|||||||
+12
@@ -1,6 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { getUnixTime } from 'date-fns';
|
import { getUnixTime } from 'date-fns';
|
||||||
import { findSnoozeTime } from 'dashboard/helper/snoozeHelpers';
|
import { findSnoozeTime } from 'dashboard/helper/snoozeHelpers';
|
||||||
|
import { getLastCustomSnoozeTime } from 'dashboard/helper/customSnoozeStorage';
|
||||||
import { emitter } from 'shared/helpers/mitt';
|
import { emitter } from 'shared/helpers/mitt';
|
||||||
import wootConstants from 'dashboard/constants/globals';
|
import wootConstants from 'dashboard/constants/globals';
|
||||||
import {
|
import {
|
||||||
@@ -100,6 +101,17 @@ export default {
|
|||||||
onCmdSnoozeConversation(snoozeType) {
|
onCmdSnoozeConversation(snoozeType) {
|
||||||
if (snoozeType === wootConstants.SNOOZE_OPTIONS.UNTIL_CUSTOM_TIME) {
|
if (snoozeType === wootConstants.SNOOZE_OPTIONS.UNTIL_CUSTOM_TIME) {
|
||||||
this.showCustomTimeSnoozeModal = true;
|
this.showCustomTimeSnoozeModal = true;
|
||||||
|
} else if (
|
||||||
|
snoozeType === wootConstants.SNOOZE_OPTIONS.UNTIL_LAST_CUSTOM_TIME
|
||||||
|
) {
|
||||||
|
// Use the saved custom time
|
||||||
|
const lastCustomTime = getLastCustomSnoozeTime();
|
||||||
|
if (lastCustomTime) {
|
||||||
|
this.updateConversations('snoozed', lastCustomTime);
|
||||||
|
} else {
|
||||||
|
// Fallback to showing custom modal if no saved time exists
|
||||||
|
this.showCustomTimeSnoozeModal = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.updateConversations('snoozed', findSnoozeTime(snoozeType) || null);
|
this.updateConversations('snoozed', findSnoozeTime(snoozeType) || null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,8 +66,9 @@ export function useBulkActionsHotKeys() {
|
|||||||
const prepareActions = actions => {
|
const prepareActions = actions => {
|
||||||
return actions.map(action => ({
|
return actions.map(action => ({
|
||||||
...action,
|
...action,
|
||||||
title: t(action.title),
|
title: typeof action.title === 'string' ? t(action.title) : action.title,
|
||||||
section: t(action.section),
|
section:
|
||||||
|
typeof action.section === 'string' ? t(action.section) : action.section,
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { computed } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useStore, useMapGetter } from 'dashboard/composables/store';
|
import { useStore, useMapGetter } from 'dashboard/composables/store';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
@@ -31,22 +31,25 @@ import {
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
OPEN_CONVERSATION_ACTIONS,
|
OPEN_CONVERSATION_ACTIONS,
|
||||||
SNOOZE_CONVERSATION_ACTIONS,
|
|
||||||
RESOLVED_CONVERSATION_ACTIONS,
|
RESOLVED_CONVERSATION_ACTIONS,
|
||||||
SEND_TRANSCRIPT_ACTION,
|
SEND_TRANSCRIPT_ACTION,
|
||||||
UNMUTE_ACTION,
|
UNMUTE_ACTION,
|
||||||
MUTE_ACTION,
|
MUTE_ACTION,
|
||||||
|
createSnoozeHandlers,
|
||||||
} from 'dashboard/helper/commandbar/actions';
|
} from 'dashboard/helper/commandbar/actions';
|
||||||
import {
|
import {
|
||||||
isAConversationRoute,
|
isAConversationRoute,
|
||||||
isAInboxViewRoute,
|
isAInboxViewRoute,
|
||||||
} from 'dashboard/helper/routeHelpers';
|
} from 'dashboard/helper/routeHelpers';
|
||||||
|
import { CMD_SNOOZE_CONVERSATION } from 'dashboard/helper/commandbar/events';
|
||||||
|
import { ICON_SNOOZE_CONVERSATION } from 'dashboard/helper/commandbar/icons';
|
||||||
|
|
||||||
const prepareActions = (actions, t) => {
|
const prepareActions = (actions, t) => {
|
||||||
return actions.map(action => ({
|
return actions.map(action => ({
|
||||||
...action,
|
...action,
|
||||||
title: t(action.title),
|
title: typeof action.title === 'string' ? t(action.title) : action.title,
|
||||||
section: t(action.section),
|
section:
|
||||||
|
typeof action.section === 'string' ? t(action.section) : action.section,
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -144,6 +147,14 @@ export function useConversationHotKeys() {
|
|||||||
const store = useStore();
|
const store = useStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
|
// Create a reactive trigger for localStorage changes
|
||||||
|
const localStorageTrigger = ref(0);
|
||||||
|
|
||||||
|
// Watch for localStorage changes (we'll trigger this manually when needed)
|
||||||
|
const forceSnoozeActionsUpdate = () => {
|
||||||
|
localStorageTrigger.value += 1;
|
||||||
|
};
|
||||||
|
|
||||||
const {
|
const {
|
||||||
activeLabels,
|
activeLabels,
|
||||||
inactiveLabels,
|
inactiveLabels,
|
||||||
@@ -197,6 +208,28 @@ export function useConversationHotKeys() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Create reactive snooze conversation actions that update when localStorage changes
|
||||||
|
const snoozeConversationActions = computed(() => {
|
||||||
|
// This computed will re-run when localStorageTrigger changes
|
||||||
|
// eslint-disable-next-line no-unused-expressions
|
||||||
|
localStorageTrigger.value; // Access to make it reactive
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: 'snooze_conversation',
|
||||||
|
title: 'COMMAND_BAR.COMMANDS.SNOOZE_CONVERSATION',
|
||||||
|
section: 'COMMAND_BAR.SECTIONS.CONVERSATION',
|
||||||
|
icon: ICON_SNOOZE_CONVERSATION,
|
||||||
|
children: Object.values(wootConstants.SNOOZE_OPTIONS),
|
||||||
|
},
|
||||||
|
...createSnoozeHandlers(
|
||||||
|
CMD_SNOOZE_CONVERSATION,
|
||||||
|
'snooze_conversation',
|
||||||
|
'COMMAND_BAR.SECTIONS.SNOOZE_CONVERSATION'
|
||||||
|
),
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
const statusActions = computed(() => {
|
const statusActions = computed(() => {
|
||||||
const isOpen = currentChat.value?.status === wootConstants.STATUS_TYPE.OPEN;
|
const isOpen = currentChat.value?.status === wootConstants.STATUS_TYPE.OPEN;
|
||||||
const isSnoozed =
|
const isSnoozed =
|
||||||
@@ -206,7 +239,10 @@ export function useConversationHotKeys() {
|
|||||||
|
|
||||||
let actions = [];
|
let actions = [];
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
actions = [...OPEN_CONVERSATION_ACTIONS, ...SNOOZE_CONVERSATION_ACTIONS];
|
actions = [
|
||||||
|
...OPEN_CONVERSATION_ACTIONS,
|
||||||
|
...snoozeConversationActions.value,
|
||||||
|
];
|
||||||
} else if (isResolved || isSnoozed) {
|
} else if (isResolved || isSnoozed) {
|
||||||
actions = RESOLVED_CONVERSATION_ACTIONS;
|
actions = RESOLVED_CONVERSATION_ACTIONS;
|
||||||
}
|
}
|
||||||
@@ -394,7 +430,7 @@ export function useConversationHotKeys() {
|
|||||||
|
|
||||||
const conversationHotKeys = computed(() => {
|
const conversationHotKeys = computed(() => {
|
||||||
if (shouldShowSnoozeOption.value) {
|
if (shouldShowSnoozeOption.value) {
|
||||||
return prepareActions(SNOOZE_CONVERSATION_ACTIONS, t);
|
return prepareActions(snoozeConversationActions.value, t);
|
||||||
}
|
}
|
||||||
if (isConversationOrInboxRoute.value) {
|
if (isConversationOrInboxRoute.value) {
|
||||||
return getDefaultConversationHotKeys.value;
|
return getDefaultConversationHotKeys.value;
|
||||||
@@ -404,5 +440,6 @@ export function useConversationHotKeys() {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
conversationHotKeys,
|
conversationHotKeys,
|
||||||
|
forceSnoozeActionsUpdate,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ export default {
|
|||||||
UNTIL_TOMORROW: 'until_tomorrow',
|
UNTIL_TOMORROW: 'until_tomorrow',
|
||||||
UNTIL_NEXT_WEEK: 'until_next_week',
|
UNTIL_NEXT_WEEK: 'until_next_week',
|
||||||
UNTIL_NEXT_MONTH: 'until_next_month',
|
UNTIL_NEXT_MONTH: 'until_next_month',
|
||||||
|
UNTIL_LAST_CUSTOM_TIME: 'until_last_custom_time',
|
||||||
UNTIL_CUSTOM_TIME: 'until_custom_time',
|
UNTIL_CUSTOM_TIME: 'until_custom_time',
|
||||||
},
|
},
|
||||||
EXAMPLE_URL: 'example.com',
|
EXAMPLE_URL: 'example.com',
|
||||||
|
|||||||
@@ -32,14 +32,97 @@ export const OPEN_CONVERSATION_ACTIONS = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export const createSnoozeHandlers = (busEventName, parentId, section) => {
|
export const createSnoozeHandlers = (busEventName, parentId, section) => {
|
||||||
return Object.values(SNOOZE_OPTIONS).map(option => ({
|
// Import the helper functions inline to avoid import issues
|
||||||
id: option,
|
const LAST_CUSTOM_SNOOZE_KEY = 'chatwoot_last_custom_snooze_time';
|
||||||
title: `COMMAND_BAR.COMMANDS.${option.toUpperCase()}`,
|
|
||||||
parent: parentId,
|
const getLastCustomSnoozeTime = () => {
|
||||||
section: section,
|
try {
|
||||||
icon: ICON_SNOOZE_CONVERSATION,
|
const stored = localStorage.getItem(LAST_CUSTOM_SNOOZE_KEY);
|
||||||
handler: () => emitter.emit(busEventName, option),
|
if (!stored) return null;
|
||||||
}));
|
|
||||||
|
const data = JSON.parse(stored);
|
||||||
|
const now = Date.now();
|
||||||
|
const nowUnix = Math.floor(now / 1000);
|
||||||
|
const savedAt = data.savedAt;
|
||||||
|
const sevenDaysInMs = 7 * 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
|
// Check if the saved time has already passed OR if it was saved more than 7 days ago
|
||||||
|
const timeHasPassed = data.timestamp <= nowUnix;
|
||||||
|
const tooOld = now - savedAt > sevenDaysInMs;
|
||||||
|
|
||||||
|
if (timeHasPassed || tooOld) {
|
||||||
|
localStorage.removeItem(LAST_CUSTOM_SNOOZE_KEY);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.timestamp;
|
||||||
|
} catch (error) {
|
||||||
|
localStorage.removeItem(LAST_CUSTOM_SNOOZE_KEY);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatLastCustomSnoozeTime = () => {
|
||||||
|
const timestamp = getLastCustomSnoozeTime();
|
||||||
|
if (!timestamp) return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const date = new Date(timestamp * 1000);
|
||||||
|
|
||||||
|
// Format as "Sat, 23 Aug, 8.16pm"
|
||||||
|
const dayOfWeek = date.toLocaleDateString('en-US', { weekday: 'short' });
|
||||||
|
const day = date.getDate();
|
||||||
|
const month = date.toLocaleDateString('en-US', { month: 'short' });
|
||||||
|
|
||||||
|
// Format time as 8.16pm (with dots instead of colons)
|
||||||
|
let hours = date.getHours();
|
||||||
|
const minutes = date.getMinutes().toString().padStart(2, '0');
|
||||||
|
const ampm = hours >= 12 ? 'pm' : 'am';
|
||||||
|
|
||||||
|
// Convert to 12-hour format
|
||||||
|
hours %= 12;
|
||||||
|
if (hours === 0) hours = 12; // 12am/12pm instead of 0am/0pm
|
||||||
|
|
||||||
|
const timeString = `${hours}.${minutes}${ampm}`;
|
||||||
|
|
||||||
|
return `${dayOfWeek}, ${day} ${month}, ${timeString}`;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const hasLastCustomSnoozeTime = () => {
|
||||||
|
return getLastCustomSnoozeTime() !== null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const availableOptions = Object.values(SNOOZE_OPTIONS);
|
||||||
|
const snoozeOptions = availableOptions.filter(option => {
|
||||||
|
if (option === SNOOZE_OPTIONS.UNTIL_LAST_CUSTOM_TIME) {
|
||||||
|
return hasLastCustomSnoozeTime();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return snoozeOptions.map(option => {
|
||||||
|
let title = `COMMAND_BAR.COMMANDS.${option.toUpperCase()}`;
|
||||||
|
|
||||||
|
// For the last custom time option, show the formatted time instead of using translation
|
||||||
|
if (option === SNOOZE_OPTIONS.UNTIL_LAST_CUSTOM_TIME) {
|
||||||
|
const formattedTime = formatLastCustomSnoozeTime();
|
||||||
|
if (formattedTime) {
|
||||||
|
title = `Last snoozed ${formattedTime}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: option,
|
||||||
|
title: title,
|
||||||
|
parent: parentId,
|
||||||
|
section: section,
|
||||||
|
icon: ICON_SNOOZE_CONVERSATION,
|
||||||
|
handler: () => emitter.emit(busEventName, option),
|
||||||
|
};
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SNOOZE_CONVERSATION_ACTIONS = [
|
export const SNOOZE_CONVERSATION_ACTIONS = [
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
const LAST_CUSTOM_SNOOZE_KEY = 'chatwoot_last_custom_snooze_time';
|
||||||
|
|
||||||
|
export const saveLastCustomSnoozeTime = snoozedUntil => {
|
||||||
|
if (!snoozedUntil) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
localStorage.setItem(
|
||||||
|
LAST_CUSTOM_SNOOZE_KEY,
|
||||||
|
JSON.stringify({
|
||||||
|
timestamp: snoozedUntil,
|
||||||
|
savedAt: Date.now(),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
// Emit event to update command bar
|
||||||
|
if (typeof window !== 'undefined' && window.emitter) {
|
||||||
|
window.emitter.emit('CUSTOM_SNOOZE_TIME_CHANGED');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('Failed to save custom snooze time:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getLastCustomSnoozeTime = () => {
|
||||||
|
try {
|
||||||
|
const stored = localStorage.getItem(LAST_CUSTOM_SNOOZE_KEY);
|
||||||
|
if (!stored) return null;
|
||||||
|
|
||||||
|
const data = JSON.parse(stored);
|
||||||
|
const now = Date.now();
|
||||||
|
const nowUnix = Math.floor(now / 1000);
|
||||||
|
const savedAt = data.savedAt;
|
||||||
|
const sevenDaysInMs = 7 * 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
|
// Check if the saved time has already passed OR if it was saved more than 7 days ago
|
||||||
|
const timeHasPassed = data.timestamp <= nowUnix;
|
||||||
|
const tooOld = now - savedAt > sevenDaysInMs;
|
||||||
|
|
||||||
|
if (timeHasPassed || tooOld) {
|
||||||
|
localStorage.removeItem(LAST_CUSTOM_SNOOZE_KEY);
|
||||||
|
// Emit event when data is cleared due to expiration
|
||||||
|
if (typeof window !== 'undefined' && window.emitter) {
|
||||||
|
window.emitter.emit('CUSTOM_SNOOZE_TIME_CHANGED');
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.timestamp;
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('Failed to get custom snooze time:', error);
|
||||||
|
localStorage.removeItem(LAST_CUSTOM_SNOOZE_KEY);
|
||||||
|
// Emit event when data is cleared due to error
|
||||||
|
if (typeof window !== 'undefined' && window.emitter) {
|
||||||
|
window.emitter.emit('CUSTOM_SNOOZE_TIME_CHANGED');
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const hasLastCustomSnoozeTime = () => {
|
||||||
|
return getLastCustomSnoozeTime() !== null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const formatLastCustomSnoozeTime = () => {
|
||||||
|
const timestamp = getLastCustomSnoozeTime();
|
||||||
|
if (!timestamp) return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const date = new Date(timestamp * 1000); // Convert Unix timestamp to milliseconds
|
||||||
|
|
||||||
|
// Format as "Sat, 23 Aug, 8.16pm"
|
||||||
|
const dayOfWeek = date.toLocaleDateString('en-US', { weekday: 'short' });
|
||||||
|
const day = date.getDate();
|
||||||
|
const month = date.toLocaleDateString('en-US', { month: 'short' });
|
||||||
|
|
||||||
|
// Format time as 8.16pm (with dots instead of colons)
|
||||||
|
let hours = date.getHours();
|
||||||
|
const minutes = date.getMinutes().toString().padStart(2, '0');
|
||||||
|
const ampm = hours >= 12 ? 'pm' : 'am';
|
||||||
|
|
||||||
|
// Convert to 12-hour format
|
||||||
|
hours %= 12;
|
||||||
|
if (hours === 0) hours = 12; // 12am/12pm instead of 0am/0pm
|
||||||
|
|
||||||
|
const timeString = `${hours}.${minutes}${ampm}`;
|
||||||
|
|
||||||
|
return `${dayOfWeek}, ${day} ${month}, ${timeString}`;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
setSeconds,
|
setSeconds,
|
||||||
} from 'date-fns';
|
} from 'date-fns';
|
||||||
import wootConstants from 'dashboard/constants/globals';
|
import wootConstants from 'dashboard/constants/globals';
|
||||||
|
import { getLastCustomSnoozeTime } from './customSnoozeStorage';
|
||||||
|
|
||||||
const SNOOZE_OPTIONS = wootConstants.SNOOZE_OPTIONS;
|
const SNOOZE_OPTIONS = wootConstants.SNOOZE_OPTIONS;
|
||||||
|
|
||||||
@@ -51,6 +52,9 @@ export const findSnoozeTime = (snoozeType, currentDate = new Date()) => {
|
|||||||
parsedDate = setHoursToNine(findStartOfNextWeek(currentDate));
|
parsedDate = setHoursToNine(findStartOfNextWeek(currentDate));
|
||||||
} else if (snoozeType === SNOOZE_OPTIONS.UNTIL_NEXT_MONTH) {
|
} else if (snoozeType === SNOOZE_OPTIONS.UNTIL_NEXT_MONTH) {
|
||||||
parsedDate = setHoursToNine(findStartOfNextMonth(currentDate));
|
parsedDate = setHoursToNine(findStartOfNextMonth(currentDate));
|
||||||
|
} else if (snoozeType === SNOOZE_OPTIONS.UNTIL_LAST_CUSTOM_TIME) {
|
||||||
|
// Return the stored timestamp directly (already in Unix format)
|
||||||
|
return getLastCustomSnoozeTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
return parsedDate ? getUnixTime(parsedDate) : null;
|
return parsedDate ? getUnixTime(parsedDate) : null;
|
||||||
|
|||||||
@@ -233,6 +233,7 @@
|
|||||||
"UNTIL_TOMORROW": "Until tomorrow",
|
"UNTIL_TOMORROW": "Until tomorrow",
|
||||||
"UNTIL_NEXT_MONTH": "Until next month",
|
"UNTIL_NEXT_MONTH": "Until next month",
|
||||||
"AN_HOUR_FROM_NOW": "Until an hour from now",
|
"AN_HOUR_FROM_NOW": "Until an hour from now",
|
||||||
|
"UNTIL_LAST_CUSTOM_TIME": "Last snoozed {time}",
|
||||||
"UNTIL_CUSTOM_TIME": "Custom...",
|
"UNTIL_CUSTOM_TIME": "Custom...",
|
||||||
"CHANGE_APPEARANCE": "Change Appearance",
|
"CHANGE_APPEARANCE": "Change Appearance",
|
||||||
"LIGHT_MODE": "Light",
|
"LIGHT_MODE": "Light",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { useI18n } from 'vue-i18n';
|
|||||||
import { useEmitter } from 'dashboard/composables/emitter';
|
import { useEmitter } from 'dashboard/composables/emitter';
|
||||||
import { getUnixTime } from 'date-fns';
|
import { getUnixTime } from 'date-fns';
|
||||||
import { findSnoozeTime } from 'dashboard/helper/snoozeHelpers';
|
import { findSnoozeTime } from 'dashboard/helper/snoozeHelpers';
|
||||||
|
import { getLastCustomSnoozeTime } from 'dashboard/helper/customSnoozeStorage';
|
||||||
import { CMD_SNOOZE_CONVERSATION } from 'dashboard/helper/commandbar/events';
|
import { CMD_SNOOZE_CONVERSATION } from 'dashboard/helper/commandbar/events';
|
||||||
import wootConstants from 'dashboard/constants/globals';
|
import wootConstants from 'dashboard/constants/globals';
|
||||||
import CustomSnoozeModal from 'dashboard/components/CustomSnoozeModal.vue';
|
import CustomSnoozeModal from 'dashboard/components/CustomSnoozeModal.vue';
|
||||||
@@ -31,6 +32,17 @@ const toggleStatus = async (status, snoozedUntil) => {
|
|||||||
const onCmdSnoozeConversation = snoozeType => {
|
const onCmdSnoozeConversation = snoozeType => {
|
||||||
if (snoozeType === wootConstants.SNOOZE_OPTIONS.UNTIL_CUSTOM_TIME) {
|
if (snoozeType === wootConstants.SNOOZE_OPTIONS.UNTIL_CUSTOM_TIME) {
|
||||||
showCustomSnoozeModal.value = true;
|
showCustomSnoozeModal.value = true;
|
||||||
|
} else if (
|
||||||
|
snoozeType === wootConstants.SNOOZE_OPTIONS.UNTIL_LAST_CUSTOM_TIME
|
||||||
|
) {
|
||||||
|
// Use the saved custom time
|
||||||
|
const lastCustomTime = getLastCustomSnoozeTime();
|
||||||
|
if (lastCustomTime) {
|
||||||
|
toggleStatus(wootConstants.STATUS_TYPE.SNOOZED, lastCustomTime);
|
||||||
|
} else {
|
||||||
|
// Fallback to showing custom modal if no saved time exists
|
||||||
|
showCustomSnoozeModal.value = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
toggleStatus(
|
toggleStatus(
|
||||||
wootConstants.STATUS_TYPE.SNOOZED,
|
wootConstants.STATUS_TYPE.SNOOZED,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import '@chatwoot/ninja-keys';
|
import '@chatwoot/ninja-keys';
|
||||||
import { ref, computed, watchEffect, onMounted } from 'vue';
|
import { ref, computed, watchEffect, onMounted, onUnmounted } from 'vue';
|
||||||
import { useStore } from 'dashboard/composables/store';
|
import { useStore } from 'dashboard/composables/store';
|
||||||
import { useTrack } from 'dashboard/composables';
|
import { useTrack } from 'dashboard/composables';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
@@ -11,6 +11,7 @@ import { useBulkActionsHotKeys } from 'dashboard/composables/commands/useBulkAct
|
|||||||
import { useConversationHotKeys } from 'dashboard/composables/commands/useConversationHotKeys';
|
import { useConversationHotKeys } from 'dashboard/composables/commands/useConversationHotKeys';
|
||||||
import wootConstants from 'dashboard/constants/globals';
|
import wootConstants from 'dashboard/constants/globals';
|
||||||
import { GENERAL_EVENTS } from 'dashboard/helper/AnalyticsHelper/events';
|
import { GENERAL_EVENTS } from 'dashboard/helper/AnalyticsHelper/events';
|
||||||
|
import { emitter } from 'shared/helpers/mitt';
|
||||||
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@@ -26,7 +27,8 @@ const { goToAppearanceHotKeys } = useAppearanceHotKeys();
|
|||||||
const { inboxHotKeys } = useInboxHotKeys();
|
const { inboxHotKeys } = useInboxHotKeys();
|
||||||
const { goToCommandHotKeys } = useGoToCommandHotKeys();
|
const { goToCommandHotKeys } = useGoToCommandHotKeys();
|
||||||
const { bulkActionsHotKeys } = useBulkActionsHotKeys();
|
const { bulkActionsHotKeys } = useBulkActionsHotKeys();
|
||||||
const { conversationHotKeys } = useConversationHotKeys();
|
const { conversationHotKeys, forceSnoozeActionsUpdate } =
|
||||||
|
useConversationHotKeys();
|
||||||
|
|
||||||
const placeholder = computed(() => t('COMMAND_BAR.SEARCH_PLACEHOLDER'));
|
const placeholder = computed(() => t('COMMAND_BAR.SEARCH_PLACEHOLDER'));
|
||||||
|
|
||||||
@@ -78,7 +80,37 @@ watchEffect(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(setCommandBarData);
|
onMounted(() => {
|
||||||
|
setCommandBarData();
|
||||||
|
|
||||||
|
// Make emitter globally available for storage helpers
|
||||||
|
window.emitter = emitter;
|
||||||
|
|
||||||
|
// Listen for custom snooze time changes to update actions
|
||||||
|
emitter.on('CUSTOM_SNOOZE_TIME_CHANGED', () => {
|
||||||
|
if (forceSnoozeActionsUpdate) {
|
||||||
|
forceSnoozeActionsUpdate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Backward compatibility
|
||||||
|
emitter.on('CUSTOM_SNOOZE_TIME_SAVED', () => {
|
||||||
|
if (forceSnoozeActionsUpdate) {
|
||||||
|
forceSnoozeActionsUpdate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
// Clean up event listeners
|
||||||
|
emitter.off('CUSTOM_SNOOZE_TIME_CHANGED');
|
||||||
|
emitter.off('CUSTOM_SNOOZE_TIME_SAVED');
|
||||||
|
|
||||||
|
// Clean up global reference
|
||||||
|
if (window.emitter === emitter) {
|
||||||
|
delete window.emitter;
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- eslint-disable vue/attribute-hyphenation -->
|
<!-- eslint-disable vue/attribute-hyphenation -->
|
||||||
|
|||||||
Reference in New Issue
Block a user