feat: add last snoozed time as a snooze option
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
<script>
|
||||
import DatePicker from 'vue-datepicker-next';
|
||||
import NextButton from 'dashboard/components-next/button/Button.vue';
|
||||
import { getUnixTime } from 'date-fns';
|
||||
import { saveLastCustomSnoozeTime } from 'dashboard/helper/customSnoozeStorage';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -25,7 +27,12 @@ export default {
|
||||
this.$emit('close');
|
||||
},
|
||||
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);
|
||||
this.$emit('chooseTime', this.snoozeTime);
|
||||
}
|
||||
},
|
||||
disabledDate(date) {
|
||||
// Disable all the previous dates
|
||||
|
||||
+12
@@ -1,6 +1,7 @@
|
||||
<script>
|
||||
import { getUnixTime } from 'date-fns';
|
||||
import { findSnoozeTime } from 'dashboard/helper/snoozeHelpers';
|
||||
import { getLastCustomSnoozeTime } from 'dashboard/helper/customSnoozeStorage';
|
||||
import { emitter } from 'shared/helpers/mitt';
|
||||
import wootConstants from 'dashboard/constants/globals';
|
||||
import {
|
||||
@@ -100,6 +101,17 @@ export default {
|
||||
onCmdSnoozeConversation(snoozeType) {
|
||||
if (snoozeType === wootConstants.SNOOZE_OPTIONS.UNTIL_CUSTOM_TIME) {
|
||||
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 {
|
||||
this.updateConversations('snoozed', findSnoozeTime(snoozeType) || null);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useMapGetter } from 'dashboard/composables/store';
|
||||
import wootConstants from 'dashboard/constants/globals';
|
||||
import { hasLastCustomSnoozeTime } from 'dashboard/helper/customSnoozeStorage';
|
||||
|
||||
import {
|
||||
CMD_BULK_ACTION_SNOOZE_CONVERSATION,
|
||||
@@ -27,7 +28,16 @@ const SNOOZE_CONVERSATION_BULK_ACTIONS = [
|
||||
title: 'COMMAND_BAR.COMMANDS.SNOOZE_CONVERSATION',
|
||||
section: 'COMMAND_BAR.SECTIONS.BULK_ACTIONS',
|
||||
icon: ICON_SNOOZE_CONVERSATION,
|
||||
children: Object.values(SNOOZE_OPTIONS),
|
||||
children: () => {
|
||||
const availableOptions = Object.values(SNOOZE_OPTIONS);
|
||||
// Only include UNTIL_LAST_CUSTOM_TIME if there's a saved custom time
|
||||
return availableOptions.filter(option => {
|
||||
if (option === SNOOZE_OPTIONS.UNTIL_LAST_CUSTOM_TIME) {
|
||||
return hasLastCustomSnoozeTime();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
},
|
||||
...createSnoozeHandlers(
|
||||
CMD_BULK_ACTION_SNOOZE_CONVERSATION,
|
||||
|
||||
@@ -43,6 +43,7 @@ export default {
|
||||
UNTIL_TOMORROW: 'until_tomorrow',
|
||||
UNTIL_NEXT_WEEK: 'until_next_week',
|
||||
UNTIL_NEXT_MONTH: 'until_next_month',
|
||||
UNTIL_LAST_CUSTOM_TIME: 'until_last_custom_time',
|
||||
UNTIL_CUSTOM_TIME: 'until_custom_time',
|
||||
},
|
||||
EXAMPLE_URL: 'example.com',
|
||||
|
||||
@@ -32,7 +32,30 @@ export const OPEN_CONVERSATION_ACTIONS = [
|
||||
];
|
||||
|
||||
export const createSnoozeHandlers = (busEventName, parentId, section) => {
|
||||
return Object.values(SNOOZE_OPTIONS).map(option => ({
|
||||
// Only include UNTIL_LAST_CUSTOM_TIME in handlers if there's a saved custom time
|
||||
const LAST_CUSTOM_SNOOZE_KEY = 'chatwoot_last_custom_snooze_time';
|
||||
const hasLastCustomSnoozeTime = () => {
|
||||
try {
|
||||
const stored = localStorage.getItem(LAST_CUSTOM_SNOOZE_KEY);
|
||||
if (!stored) return false;
|
||||
const data = JSON.parse(stored);
|
||||
const now = Date.now();
|
||||
const sevenDaysInMs = 7 * 24 * 60 * 60 * 1000;
|
||||
return now - data.savedAt <= sevenDaysInMs;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
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 => ({
|
||||
id: option,
|
||||
title: `COMMAND_BAR.COMMANDS.${option.toUpperCase()}`,
|
||||
parent: parentId,
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
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(),
|
||||
})
|
||||
);
|
||||
} 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);
|
||||
|
||||
// Check if the saved time is still in the future (within 7 days of when it was saved)
|
||||
const now = Date.now();
|
||||
const savedAt = data.savedAt;
|
||||
const sevenDaysInMs = 7 * 24 * 60 * 60 * 1000;
|
||||
|
||||
// If saved more than 7 days ago, consider it stale
|
||||
if (now - savedAt > sevenDaysInMs) {
|
||||
localStorage.removeItem(LAST_CUSTOM_SNOOZE_KEY);
|
||||
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);
|
||||
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
|
||||
return date.toLocaleString();
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
setSeconds,
|
||||
} from 'date-fns';
|
||||
import wootConstants from 'dashboard/constants/globals';
|
||||
import { getLastCustomSnoozeTime } from './customSnoozeStorage';
|
||||
|
||||
const SNOOZE_OPTIONS = wootConstants.SNOOZE_OPTIONS;
|
||||
|
||||
@@ -51,6 +52,9 @@ export const findSnoozeTime = (snoozeType, currentDate = new Date()) => {
|
||||
parsedDate = setHoursToNine(findStartOfNextWeek(currentDate));
|
||||
} else if (snoozeType === SNOOZE_OPTIONS.UNTIL_NEXT_MONTH) {
|
||||
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;
|
||||
|
||||
@@ -233,6 +233,7 @@
|
||||
"UNTIL_TOMORROW": "Until tomorrow",
|
||||
"UNTIL_NEXT_MONTH": "Until next month",
|
||||
"AN_HOUR_FROM_NOW": "Until an hour from now",
|
||||
"UNTIL_LAST_CUSTOM_TIME": "Use last custom time",
|
||||
"UNTIL_CUSTOM_TIME": "Custom...",
|
||||
"CHANGE_APPEARANCE": "Change Appearance",
|
||||
"LIGHT_MODE": "Light",
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useI18n } from 'vue-i18n';
|
||||
import { useEmitter } from 'dashboard/composables/emitter';
|
||||
import { getUnixTime } from 'date-fns';
|
||||
import { findSnoozeTime } from 'dashboard/helper/snoozeHelpers';
|
||||
import { getLastCustomSnoozeTime } from 'dashboard/helper/customSnoozeStorage';
|
||||
import { CMD_SNOOZE_CONVERSATION } from 'dashboard/helper/commandbar/events';
|
||||
import wootConstants from 'dashboard/constants/globals';
|
||||
import CustomSnoozeModal from 'dashboard/components/CustomSnoozeModal.vue';
|
||||
@@ -31,6 +32,17 @@ const toggleStatus = async (status, snoozedUntil) => {
|
||||
const onCmdSnoozeConversation = snoozeType => {
|
||||
if (snoozeType === wootConstants.SNOOZE_OPTIONS.UNTIL_CUSTOM_TIME) {
|
||||
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 {
|
||||
toggleStatus(
|
||||
wootConstants.STATUS_TYPE.SNOOZED,
|
||||
|
||||
Reference in New Issue
Block a user