feat: Move timeMixin to a helper (#9799)

# Pull Request Template

## Description

This PR will replace the usage of `timeMixin` with `timeHelper`

Fixes
https://linear.app/chatwoot/issue/CW-3451/move-time-mixin-to-a-helper

## Type of change

- [x] New feature (non-breaking change which adds functionality)

## How Has This Been Tested?

Please refer to this issue description.
https://linear.app/chatwoot/issue/CW-3451/move-time-mixin-to-a-helper

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules

---------

Co-authored-by: Sojan Jose <sojan@pepalo.com>
This commit is contained in:
Sivin Varghese
2024-07-22 13:07:29 +05:30
committed by GitHub
parent 84c380c8c4
commit 79381b08cc
25 changed files with 305 additions and 314 deletions

View File

@@ -1,6 +1,6 @@
<template>
<section
class="contacts-table-wrap bg-white dark:bg-slate-900 flex-1 h-full overflow-hidden -mt-1"
class="flex-1 h-full -mt-1 overflow-hidden bg-white contacts-table-wrap dark:bg-slate-900"
>
<ve-table
:fixed-header="true"
@@ -20,7 +20,7 @@
v-else-if="!isLoading && !contacts.length"
:title="$t('CONTACTS_PAGE.LIST.NO_CONTACTS')"
/>
<div v-if="isLoading" class="items-center flex text-base justify-center">
<div v-if="isLoading" class="flex items-center justify-center text-base">
<spinner />
<span>{{ $t('CONTACTS_PAGE.LIST.LOADING_MESSAGE') }}</span>
</div>
@@ -34,7 +34,7 @@ import { getCountryFlag } from 'dashboard/helper/flag';
import Spinner from 'shared/components/Spinner.vue';
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
import EmptyState from 'dashboard/components/widgets/EmptyState.vue';
import timeMixin from 'dashboard/mixins/time';
import { dynamicTime } from 'shared/helpers/timeHelper';
import rtlMixin from 'shared/mixins/rtlMixin';
import FluentIcon from 'shared/components/FluentIcon/DashboardIcon.vue';
@@ -44,7 +44,7 @@ export default {
Spinner,
VeTable,
},
mixins: [timeMixin, rtlMixin],
mixins: [rtlMixin],
props: {
contacts: {
type: Array,
@@ -105,9 +105,9 @@ export default {
countryCode: additional.country_code,
conversationsCount: item.conversations_count || '---',
last_activity_at: lastActivityAt
? this.dynamicTime(lastActivityAt)
? dynamicTime(lastActivityAt)
: '---',
created_at: createdAt ? this.dynamicTime(createdAt) : '---',
created_at: createdAt ? dynamicTime(createdAt) : '---',
};
});
},
@@ -134,7 +134,7 @@ export default {
status={row.availability_status}
/>
<div class="user-block">
<h6 class="text-base overflow-hidden whitespace-nowrap text-ellipsis">
<h6 class="overflow-hidden text-base whitespace-nowrap text-ellipsis">
<router-link
to={`/app/accounts/${this.$route.params.accountId}/contacts/${row.id}`}
class="user-name"

View File

@@ -28,10 +28,8 @@
</template>
<script>
import timeMixin from 'dashboard/mixins/time';
import { dynamicTime } from 'shared/helpers/timeHelper';
export default {
mixins: [timeMixin],
props: {
eventType: {
type: String,
@@ -53,7 +51,7 @@ export default {
computed: {
readableTime() {
return this.dynamicTime(this.timeStamp);
return dynamicTime(this.timeStamp);
},
},

View File

@@ -1,7 +1,7 @@
<template>
<div class="relative items-center p-4 bg-white dark:bg-slate-900 w-full">
<div class="text-left rtl:text-right flex flex-col gap-2 w-full">
<div class="flex justify-between flex-row">
<div class="relative items-center w-full p-4 bg-white dark:bg-slate-900">
<div class="flex flex-col w-full gap-2 text-left rtl:text-right">
<div class="flex flex-row justify-between">
<thumbnail
v-if="showAvatar"
:src="contact.thumbnail"
@@ -18,9 +18,9 @@
</div>
<div class="flex flex-col items-start gap-1.5 min-w-0 w-full">
<div v-if="showAvatar" class="flex items-start gap-2 min-w-0 w-full">
<div v-if="showAvatar" class="flex items-start w-full min-w-0 gap-2">
<h3
class="flex-shrink min-w-0 text-base text-slate-800 dark:text-slate-100 capitalize my-0 max-w-full break-words"
class="flex-shrink max-w-full min-w-0 my-0 text-base capitalize break-words text-slate-800 dark:text-slate-100"
>
{{ contact.name }}
</h3>
@@ -55,7 +55,7 @@
<p v-if="additionalAttributes.description" class="break-words mb-0.5">
{{ additionalAttributes.description }}
</p>
<div class="flex flex-col gap-2 items-start w-full">
<div class="flex flex-col items-start w-full gap-2">
<contact-info-row
:href="contact.email ? `mailto:${contact.email}` : ''"
:value="contact.email"
@@ -166,7 +166,7 @@
</div>
</template>
<script>
import timeMixin from 'dashboard/mixins/time';
import { dynamicTime } from 'shared/helpers/timeHelper';
import ContactInfoRow from './ContactInfoRow.vue';
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
import SocialIcons from './SocialIcons.vue';
@@ -194,7 +194,7 @@ export default {
NewConversation,
ContactMergeModal,
},
mixins: [alertMixin, adminMixin, timeMixin],
mixins: [alertMixin, adminMixin],
props: {
contact: {
type: Object,
@@ -260,6 +260,7 @@ export default {
},
},
methods: {
dynamicTime,
toggleMergeModal() {
this.showMergeModal = !this.showMergeModal;
},

View File

@@ -9,7 +9,7 @@
/>
<router-link
:to="searchUrl"
class="search-link flex-1 items-center gap-1 text-left h-6 rtl:mr-3 rtl:text-right rounded-md px-2 py-0 bg-slate-25 dark:bg-slate-800 inline-flex"
class="inline-flex items-center flex-1 h-6 gap-1 px-2 py-0 text-left rounded-md search-link rtl:mr-3 rtl:text-right bg-slate-25 dark:bg-slate-800"
>
<div class="flex">
<fluent-icon
@@ -19,7 +19,7 @@
/>
</div>
<p
class="search--label mb-0 overflow-hidden whitespace-nowrap text-ellipsis text-sm text-slate-800 dark:text-slate-200"
class="mb-0 overflow-hidden text-sm search--label whitespace-nowrap text-ellipsis text-slate-800 dark:text-slate-200"
>
{{ $t('CONVERSATION.SEARCH_MESSAGES') }}
</p>
@@ -34,7 +34,6 @@
<script>
import { mapGetters } from 'vuex';
import timeMixin from '../../../../mixins/time';
import messageFormatterMixin from 'shared/mixins/messageFormatterMixin';
import SwitchLayout from './SwitchLayout.vue';
import { frontendURL } from 'dashboard/helper/URLHelper';
@@ -49,7 +48,7 @@ export default {
},
},
},
mixins: [timeMixin, messageFormatterMixin],
mixins: [messageFormatterMixin],
props: {
isOnExpandedLayout: {
type: Boolean,

View File

@@ -1,12 +1,12 @@
<template>
<div
class="text-slate-700 dark:text-slate-100 last:border-b-0 bg-white dark:bg-slate-900 my-0 -mx-4 grid grid-cols-1 lg:grid-cols-12 gap-4 border-b border-slate-50 dark:border-slate-800 px-6 py-3"
class="grid grid-cols-1 gap-4 px-6 py-3 my-0 -mx-4 bg-white border-b text-slate-700 dark:text-slate-100 last:border-b-0 dark:bg-slate-900 lg:grid-cols-12 border-slate-50 dark:border-slate-800"
>
<span class="items-start flex gap-2 col-span-6 text-left">
<span class="flex items-start col-span-6 gap-2 text-left">
<fluent-icon
v-if="showDragIcon"
size="20"
class="block cursor-move flex-shrink-0 h-4 mt-1 w-4 text-slate-200 dark:text-slate-700 hover:text-slate-400 hover:dark:text-slate-200"
class="flex-shrink-0 block w-4 h-4 mt-1 cursor-move text-slate-200 dark:text-slate-700 hover:text-slate-400 hover:dark:text-slate-200"
icon="grab-handle"
/>
<div class="flex flex-col truncate">
@@ -18,7 +18,7 @@
{{ title }}
</h6>
</router-link>
<div class="flex gap-1 items-center">
<div class="flex items-center gap-1">
<Thumbnail
v-if="author"
:src="author.thumbnail"
@@ -39,7 +39,7 @@
class="text-woot-300 dark:text-woot-300"
/>
</div>
<span class="font-normal text-slate-700 dark:text-slate-200 text-sm">
<span class="text-sm font-normal text-slate-700 dark:text-slate-200">
{{ articleAuthorName }}
</span>
</div>
@@ -60,7 +60,7 @@
:title="formattedViewCount"
>
{{ readableViewCount }}
<span class="lg:hidden ml-1">
<span class="ml-1 lg:hidden">
{{ ` ${$t('HELP_CENTER.TABLE.HEADERS.READ_COUNT')}` }}
</span>
</span>
@@ -74,7 +74,7 @@
/>
</span>
<span
class="flex items-center justify-end col-span-2 first-letter:uppercase text-slate-700 dark:text-slate-100 text-xs"
class="flex items-center justify-end col-span-2 text-xs first-letter:uppercase text-slate-700 dark:text-slate-100"
>
{{ lastUpdatedAt }}
</span>
@@ -82,7 +82,7 @@
</template>
<script>
import timeMixin from 'dashboard/mixins/time';
import { dynamicTime } from 'shared/helpers/timeHelper';
import portalMixin from '../mixins/portalMixin';
import { frontendURL } from 'dashboard/helper/URLHelper';
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
@@ -91,7 +91,7 @@ export default {
components: {
Thumbnail,
},
mixins: [timeMixin, portalMixin],
mixins: [portalMixin],
props: {
showDragIcon: {
type: Boolean,
@@ -131,7 +131,7 @@ export default {
computed: {
lastUpdatedAt() {
return this.dynamicTime(this.updatedAt);
return dynamicTime(this.updatedAt);
},
formattedViewCount() {
return Number(this.views || 0).toLocaleString('en');

View File

@@ -10,7 +10,7 @@
@contextmenu="openContextMenu($event)"
@click="openConversation(notificationItem)"
>
<div class="flex relative items-center justify-between w-full">
<div class="relative flex items-center justify-between w-full">
<div
v-if="isUnread"
class="absolute ltr:-left-3.5 rtl:-right-3.5 flex w-2 h-2 rounded bg-woot-500 dark:bg-woot-500"
@@ -23,7 +23,7 @@
</div>
</div>
<div class="flex flex-row justify-between items-center w-full gap-2">
<div class="flex flex-row items-center justify-between w-full gap-2">
<Thumbnail
v-if="assigneeMeta"
:src="assigneeMeta.thumbnail"
@@ -31,19 +31,19 @@
size="16px"
/>
<span
class="flex-1 text-slate-800 dark:text-slate-50 text-sm overflow-hidden text-ellipsis whitespace-nowrap"
class="flex-1 overflow-hidden text-sm text-slate-800 dark:text-slate-50 text-ellipsis whitespace-nowrap"
:class="isUnread ? 'font-medium' : 'font-normal'"
>
{{ pushTitle }}
</span>
<span
class="font-medium text-slate-600 dark:text-slate-300 text-xs whitespace-nowrap"
class="text-xs font-medium text-slate-600 dark:text-slate-300 whitespace-nowrap"
>
{{ lastActivityAt }}
</span>
</div>
<div v-if="snoozedUntilTime" class="flex items-center">
<span class="text-woot-500 dark:text-woot-500 text-xs font-medium">
<span class="text-xs font-medium text-woot-500 dark:text-woot-500">
{{ snoozedDisplayText }}
</span>
</div>
@@ -63,7 +63,7 @@ import StatusIcon from './StatusIcon.vue';
import InboxNameAndId from './InboxNameAndId.vue';
import InboxContextMenu from './InboxContextMenu.vue';
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
import timeMixin from 'dashboard/mixins/time';
import { dynamicTime, shortTimestamp } from 'shared/helpers/timeHelper';
import { snoozedReopenTime } from 'dashboard/helper/snoozeHelpers';
import { INBOX_EVENTS } from 'dashboard/helper/AnalyticsHelper/events';
export default {
@@ -74,7 +74,6 @@ export default {
InboxNameAndId,
Thumbnail,
},
mixins: [timeMixin],
props: {
notificationItem: {
type: Object,
@@ -115,10 +114,8 @@ export default {
);
},
lastActivityAt() {
const dynamicTime = this.dynamicTime(
this.notificationItem?.last_activity_at
);
return this.shortTimestamp(dynamicTime, true);
const time = dynamicTime(this.notificationItem?.last_activity_at);
return shortTimestamp(time, true);
},
menuItems() {
const items = [

View File

@@ -14,12 +14,12 @@
v-if="!notificationItem.read_at"
class="w-2 h-2 rounded-full bg-woot-500"
/>
<div v-else class="w-2 flex" />
<div v-else class="flex w-2" />
<div
class="flex-col ml-2.5 overflow-hidden w-full flex justify-between"
>
<div class="flex justify-between">
<div class="items-center flex">
<div class="flex items-center">
<span class="font-bold text-slate-800 dark:text-slate-100">
{{
`#${
@@ -47,15 +47,15 @@
/>
</div>
</div>
<div class="w-full flex">
<div class="flex w-full">
<span
class="text-slate-700 dark:text-slate-200 font-normal overflow-hidden whitespace-nowrap text-ellipsis"
class="overflow-hidden font-normal text-slate-700 dark:text-slate-200 whitespace-nowrap text-ellipsis"
>
{{ notificationItem.push_message_title }}
</span>
</div>
<span
class="mt-1 text-slate-500 dark:text-slate-400 text-xxs font-semibold flex"
class="flex mt-1 font-semibold text-slate-500 dark:text-slate-400 text-xxs"
>
{{ dynamicTime(notificationItem.last_activity_at) }}
</span>
@@ -67,13 +67,12 @@
<script>
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
import timeMixin from 'dashboard/mixins/time';
import { dynamicTime } from 'shared/helpers/timeHelper';
export default {
components: {
Thumbnail,
},
mixins: [timeMixin],
props: {
notificationItem: {
type: Object,
@@ -96,6 +95,7 @@ export default {
},
},
methods: {
dynamicTime,
onClickOpenNotification() {
this.$emit('open-notification', this.notificationItem);
},

View File

@@ -1,6 +1,6 @@
<template>
<section
class="h-full flex-shrink flex-grow overflow-hidden py-8 px-4 bg-white dark:bg-slate-900"
class="flex-grow flex-shrink h-full px-4 py-8 overflow-hidden bg-white dark:bg-slate-900"
>
<woot-submit-button
v-if="notificationMetadata.unreadCount"
@@ -22,7 +22,7 @@
>
<td>
<div
class="flex-view notification-contant--wrap overflow-hidden whitespace-nowrap text-ellipsis"
class="overflow-hidden flex-view notification-contant--wrap whitespace-nowrap text-ellipsis"
>
<h5 class="notification--title">
{{
@@ -34,7 +34,7 @@
}}
</h5>
<span
class="notification--message-title overflow-hidden whitespace-nowrap text-ellipsis"
class="overflow-hidden notification--message-title whitespace-nowrap text-ellipsis"
>
{{ notificationItem.push_message_title }}
</span>
@@ -88,7 +88,7 @@
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
import Spinner from 'shared/components/Spinner.vue';
import EmptyState from 'dashboard/components/widgets/EmptyState.vue';
import timeMixin from '../../../../mixins/time';
import { dynamicTime } from 'shared/helpers/timeHelper';
import { mapGetters } from 'vuex';
export default {
@@ -97,7 +97,6 @@ export default {
Spinner,
EmptyState,
},
mixins: [timeMixin],
props: {
notifications: {
type: Array,
@@ -128,6 +127,9 @@ export default {
return !this.isLoading && this.notifications.length === 0;
},
},
methods: {
dynamicTime,
},
};
</script>

View File

@@ -1,11 +1,11 @@
<template>
<div class="flex-1 overflow-auto p-4 flex justify-between flex-col">
<div class="flex flex-col justify-between flex-1 p-4 overflow-auto">
<!-- List Audit Logs -->
<div>
<div>
<p
v-if="!uiFlags.fetchingList && !records.length"
class="flex h-full items-center flex-col justify-center"
class="flex flex-col items-center justify-center h-full"
>
{{ $t('AUDIT_LOGS.LIST.404') }}
</p>
@@ -16,7 +16,7 @@
<table
v-if="!uiFlags.fetchingList && records.length"
class="woot-table w-full"
class="w-full woot-table"
>
<colgroup>
<col class="w-3/5" />
@@ -34,10 +34,10 @@
</thead>
<tbody>
<tr v-for="auditLogItem in records" :key="auditLogItem.id">
<td class="whitespace-nowrap break-all">
<td class="break-all whitespace-nowrap">
{{ generateLogText(auditLogItem) }}
</td>
<td class="whitespace-nowrap break-all">
<td class="break-all whitespace-nowrap">
{{
messageTimestamp(
auditLogItem.created_at,
@@ -65,7 +65,7 @@
<script>
import { mapGetters } from 'vuex';
import TableFooter from 'dashboard/components/widgets/TableFooter.vue';
import timeMixin from 'dashboard/mixins/time';
import { messageTimestamp } from 'shared/helpers/timeHelper';
import alertMixin from 'shared/mixins/alertMixin';
import {
generateTranslationPayload,
@@ -76,7 +76,7 @@ export default {
components: {
TableFooter,
},
mixins: [alertMixin, timeMixin],
mixins: [alertMixin],
beforeRouteEnter(to, from, next) {
// Fetch Audit Logs on page load without manual refresh
next(vm => {
@@ -104,6 +104,7 @@ export default {
this.$store.dispatch('agents/get');
},
methods: {
messageTimestamp,
fetchAuditLogs() {
const page = this.$route.query.page ?? 1;
this.$store.dispatch('auditlogs/fetch', { page }).catch(error => {

View File

@@ -1,5 +1,5 @@
<template>
<div class="flex-1 overflow-auto p-4">
<div class="flex-1 p-4 overflow-auto">
<woot-button
color-scheme="success"
class-names="button--fixed-top"
@@ -12,7 +12,7 @@
<div class="w-full lg:w-3/5">
<p
v-if="!uiFlags.isFetching && !records.length"
class="flex h-full items-center flex-col justify-center"
class="flex flex-col items-center justify-center h-full"
>
{{ $t('AUTOMATION.LIST.404') }}
</p>
@@ -77,7 +77,7 @@
</table>
</div>
<div class="hidden lg:block w-1/3">
<div class="hidden w-1/3 lg:block">
<span v-dompurify-html="$t('AUTOMATION.SIDEBAR_TXT')" />
</div>
</div>
@@ -128,14 +128,14 @@ import { mapGetters } from 'vuex';
import AddAutomationRule from './AddAutomationRule.vue';
import EditAutomationRule from './EditAutomationRule.vue';
import alertMixin from 'shared/mixins/alertMixin';
import timeMixin from 'dashboard/mixins/time';
import { messageStamp } from 'shared/helpers/timeHelper';
export default {
components: {
AddAutomationRule,
EditAutomationRule,
},
mixins: [alertMixin, timeMixin],
mixins: [alertMixin],
data() {
return {
loading: {},
@@ -278,7 +278,7 @@ export default {
}
},
readableTime(date) {
return this.messageStamp(new Date(date), 'LLL d, h:mm a');
return messageStamp(new Date(date), 'LLL d, h:mm a');
},
},
};

View File

@@ -70,14 +70,14 @@
import UserAvatarWithName from 'dashboard/components/widgets/UserAvatarWithName.vue';
import InboxName from 'dashboard/components/widgets/InboxName.vue';
import messageFormatterMixin from 'shared/mixins/messageFormatterMixin';
import timeMixin from 'dashboard/mixins/time';
import { messageStamp } from 'shared/helpers/timeHelper';
export default {
components: {
UserAvatarWithName,
InboxName,
},
mixins: [messageFormatterMixin, timeMixin],
mixins: [messageFormatterMixin],
props: {
campaign: {
type: Object,
@@ -110,5 +110,8 @@ export default {
: 'success';
},
},
methods: {
messageStamp,
},
};
</script>

View File

@@ -26,7 +26,7 @@ import { VeTable, VePagination } from 'vue-easytable';
import UserAvatarWithName from 'dashboard/components/widgets/UserAvatarWithName.vue';
import { CSAT_RATINGS } from 'shared/constants/messages';
import { mapGetters } from 'vuex';
import timeMixin from 'dashboard/mixins/time';
import { messageStamp, dynamicTime } from 'shared/helpers/timeHelper';
import rtlMixin from 'shared/mixins/rtlMixin';
export default {
@@ -34,7 +34,7 @@ export default {
VeTable,
VePagination,
},
mixins: [timeMixin, rtlMixin],
mixins: [rtlMixin],
props: {
pageIndex: {
type: Number,
@@ -137,8 +137,8 @@ export default {
rating: response.rating,
feedbackText: response.feedback_message || '---',
conversationId: response.conversation_id,
createdAgo: this.dynamicTime(response.created_at),
createdAt: this.messageStamp(response.created_at, 'LLL d yyyy, h:mm a'),
createdAgo: dynamicTime(response.created_at),
createdAt: messageStamp(response.created_at, 'LLL d yyyy, h:mm a'),
}));
},
},