mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-03 04:27:53 +00:00
feat: Ability to choose the custom time for snooze conversation (#7257)
This commit is contained in:
@@ -26,7 +26,7 @@
|
|||||||
border-radius: var(--border-radius-normal);
|
border-radius: var(--border-radius-normal);
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 4.0rem;
|
height: 4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx-input:disabled,
|
.mx-input:disabled,
|
||||||
@@ -35,3 +35,32 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx-datepicker-inline {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.mx-calendar {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cell.disabled {
|
||||||
|
background-color: var(--s-25);
|
||||||
|
color: var(--s-200);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx-time-item.disabled {
|
||||||
|
background-color: var(--s-25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.today {
|
||||||
|
font-weight: var(--font-weight-bold);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx-datepicker-main {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx-time-header {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
75
app/javascript/dashboard/components/CustomSnoozeModal.vue
Normal file
75
app/javascript/dashboard/components/CustomSnoozeModal.vue
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
<template>
|
||||||
|
<div class="column">
|
||||||
|
<woot-modal-header :header-title="$t('CONVERSATION.CUSTOM_SNOOZE.TITLE')" />
|
||||||
|
<form class="row modal-content" @submit.prevent="chooseTime">
|
||||||
|
<date-picker
|
||||||
|
v-model="snoozeTime"
|
||||||
|
type="datetime"
|
||||||
|
inline
|
||||||
|
:lang="lang"
|
||||||
|
:disabled-date="disabledDate"
|
||||||
|
:disabled-time="disabledTime"
|
||||||
|
:popup-style="{ width: '100%' }"
|
||||||
|
/>
|
||||||
|
<div class="modal-footer justify-content-end w-full">
|
||||||
|
<woot-button variant="clear" @click.prevent="onClose">
|
||||||
|
{{ this.$t('CONVERSATION.CUSTOM_SNOOZE.CANCEL') }}
|
||||||
|
</woot-button>
|
||||||
|
<woot-button>
|
||||||
|
{{ this.$t('CONVERSATION.CUSTOM_SNOOZE.APPLY') }}
|
||||||
|
</woot-button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import DatePicker from 'vue2-datepicker';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
DatePicker,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
snoozeTime: null,
|
||||||
|
lang: {
|
||||||
|
days: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
|
||||||
|
yearFormat: 'YYYY',
|
||||||
|
monthFormat: 'MMMM',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onClose() {
|
||||||
|
this.$emit('close');
|
||||||
|
},
|
||||||
|
chooseTime() {
|
||||||
|
this.$emit('choose-time', this.snoozeTime);
|
||||||
|
},
|
||||||
|
disabledDate(date) {
|
||||||
|
// Disable all the previous dates
|
||||||
|
const yesterday = new Date();
|
||||||
|
yesterday.setDate(yesterday.getDate() - 1);
|
||||||
|
return date < yesterday;
|
||||||
|
},
|
||||||
|
disabledTime(date) {
|
||||||
|
// Allow only time after 1 hour
|
||||||
|
const now = new Date();
|
||||||
|
now.setHours(now.getHours() + 1);
|
||||||
|
return date < now;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.modal-footer {
|
||||||
|
padding: var(--space-two);
|
||||||
|
}
|
||||||
|
.modal-content {
|
||||||
|
padding: var(--space-small) var(--space-two) var(--space-zero);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -71,21 +71,30 @@
|
|||||||
</woot-dropdown-item>
|
</woot-dropdown-item>
|
||||||
</woot-dropdown-menu>
|
</woot-dropdown-menu>
|
||||||
</div>
|
</div>
|
||||||
|
<woot-modal
|
||||||
|
:show.sync="showCustomSnoozeModal"
|
||||||
|
:on-close="hideCustomSnoozeModal"
|
||||||
|
>
|
||||||
|
<custom-snooze-modal
|
||||||
|
@close="hideCustomSnoozeModal"
|
||||||
|
@choose-time="chooseSnoozeTime"
|
||||||
|
/>
|
||||||
|
</woot-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { getUnixTime } from 'date-fns';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { mixin as clickaway } from 'vue-clickaway';
|
import { mixin as clickaway } from 'vue-clickaway';
|
||||||
import alertMixin from 'shared/mixins/alertMixin';
|
import alertMixin from 'shared/mixins/alertMixin';
|
||||||
import snoozeTimesMixin from 'dashboard/mixins/conversation/snoozeTimesMixin.js';
|
import CustomSnoozeModal from 'dashboard/components/CustomSnoozeModal';
|
||||||
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
|
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
|
||||||
import {
|
import {
|
||||||
hasPressedAltAndEKey,
|
hasPressedAltAndEKey,
|
||||||
hasPressedCommandPlusAltAndEKey,
|
hasPressedCommandPlusAltAndEKey,
|
||||||
hasPressedAltAndMKey,
|
hasPressedAltAndMKey,
|
||||||
} from 'shared/helpers/KeyboardHelpers';
|
} from 'shared/helpers/KeyboardHelpers';
|
||||||
|
|
||||||
import { findSnoozeTime } from 'dashboard/helper/snoozeHelpers';
|
import { findSnoozeTime } from 'dashboard/helper/snoozeHelpers';
|
||||||
import WootDropdownItem from 'shared/components/ui/dropdown/DropdownItem.vue';
|
import WootDropdownItem from 'shared/components/ui/dropdown/DropdownItem.vue';
|
||||||
import WootDropdownMenu from 'shared/components/ui/dropdown/DropdownMenu.vue';
|
import WootDropdownMenu from 'shared/components/ui/dropdown/DropdownMenu.vue';
|
||||||
@@ -101,14 +110,16 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
WootDropdownItem,
|
WootDropdownItem,
|
||||||
WootDropdownMenu,
|
WootDropdownMenu,
|
||||||
|
CustomSnoozeModal,
|
||||||
},
|
},
|
||||||
mixins: [clickaway, alertMixin, eventListenerMixins, snoozeTimesMixin],
|
mixins: [clickaway, alertMixin, eventListenerMixins],
|
||||||
props: { conversationId: { type: [String, Number], required: true } },
|
props: { conversationId: { type: [String, Number], required: true } },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
showActionsDropdown: false,
|
showActionsDropdown: false,
|
||||||
STATUS_TYPE: wootConstants.STATUS_TYPE,
|
STATUS_TYPE: wootConstants.STATUS_TYPE,
|
||||||
|
showCustomSnoozeModal: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -180,10 +191,26 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onCmdSnoozeConversation(snoozeType) {
|
onCmdSnoozeConversation(snoozeType) {
|
||||||
|
if (snoozeType === wootConstants.SNOOZE_OPTIONS.UNTIL_CUSTOM_TIME) {
|
||||||
|
this.showCustomSnoozeModal = true;
|
||||||
|
} else {
|
||||||
this.toggleStatus(
|
this.toggleStatus(
|
||||||
this.STATUS_TYPE.SNOOZED,
|
this.STATUS_TYPE.SNOOZED,
|
||||||
findSnoozeTime(snoozeType) || null
|
findSnoozeTime(snoozeType) || null
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
chooseSnoozeTime(customSnoozeTime) {
|
||||||
|
this.showCustomSnoozeModal = false;
|
||||||
|
if (customSnoozeTime) {
|
||||||
|
this.toggleStatus(
|
||||||
|
this.STATUS_TYPE.SNOOZED,
|
||||||
|
getUnixTime(customSnoozeTime)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hideCustomSnoozeModal() {
|
||||||
|
this.showCustomSnoozeModal = false;
|
||||||
},
|
},
|
||||||
onCmdOpenConversation() {
|
onCmdOpenConversation() {
|
||||||
this.toggleStatus(this.STATUS_TYPE.OPEN);
|
this.toggleStatus(this.STATUS_TYPE.OPEN);
|
||||||
|
|||||||
@@ -36,6 +36,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_CUSTOM_TIME: 'until_custom_time',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
export const DEFAULT_REDIRECT_URL = '/app/';
|
export const DEFAULT_REDIRECT_URL = '/app/';
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
import {
|
|
||||||
getUnixTime,
|
|
||||||
addHours,
|
|
||||||
addWeeks,
|
|
||||||
startOfTomorrow,
|
|
||||||
startOfWeek,
|
|
||||||
} from 'date-fns';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
computed: {
|
|
||||||
snoozeTimes() {
|
|
||||||
return {
|
|
||||||
// tomorrow = 9AM next day
|
|
||||||
tomorrow: getUnixTime(addHours(startOfTomorrow(), 9)),
|
|
||||||
// next week = 9AM Monday, next week
|
|
||||||
nextWeek: getUnixTime(
|
|
||||||
addHours(startOfWeek(addWeeks(new Date(), 1), { weekStartsOn: 1 }), 9)
|
|
||||||
),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -93,6 +93,15 @@ const SNOOZE_CONVERSATION_ACTIONS = [
|
|||||||
handler: () =>
|
handler: () =>
|
||||||
bus.$emit(CMD_SNOOZE_CONVERSATION, SNOOZE_OPTIONS.UNTIL_NEXT_MONTH),
|
bus.$emit(CMD_SNOOZE_CONVERSATION, SNOOZE_OPTIONS.UNTIL_NEXT_MONTH),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: SNOOZE_OPTIONS.UNTIL_CUSTOM_TIME,
|
||||||
|
title: 'COMMAND_BAR.COMMANDS.CUSTOM',
|
||||||
|
section: 'COMMAND_BAR.SECTIONS.SNOOZE_CONVERSATION',
|
||||||
|
parent: 'snooze_conversation',
|
||||||
|
icon: ICON_SNOOZE_CONVERSATION,
|
||||||
|
handler: () =>
|
||||||
|
bus.$emit(CMD_SNOOZE_CONVERSATION, SNOOZE_OPTIONS.UNTIL_CUSTOM_TIME),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const RESOLVED_CONVERSATION_ACTIONS = [
|
const RESOLVED_CONVERSATION_ACTIONS = [
|
||||||
|
|||||||
Reference in New Issue
Block a user