From ac249c75c43bb53c7fb3d69e3dbda5a560c4b6a2 Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Wed, 28 Feb 2024 07:21:06 +0530 Subject: [PATCH] chore: Update the metric card component to support generic cases (#9030) Rename the CSAT metric card to a generic name, updated the implementation to use composition API and removed all the custom CSS in the component to conform with TailwindCSS styles --------- Co-authored-by: Pranav --- .../settings/reports/ReportContainer.vue | 35 ++++----- .../reports/components/CsatMetricCard.vue | 77 ------------------- .../reports/components/CsatMetrics.vue | 13 ++-- ...stories.js => ReportMetricCard.stories.js} | 12 +-- .../reports/components/ReportMetricCard.vue | 48 ++++++++++++ ...cCard.spec.js => ReportMetricCard.spec.js} | 28 ++++--- 6 files changed, 93 insertions(+), 120 deletions(-) delete mode 100644 app/javascript/dashboard/routes/dashboard/settings/reports/components/CsatMetricCard.vue rename app/javascript/dashboard/routes/dashboard/settings/reports/components/{CsatMetricCard.stories.js => ReportMetricCard.stories.js} (71%) create mode 100644 app/javascript/dashboard/routes/dashboard/settings/reports/components/ReportMetricCard.vue rename app/javascript/dashboard/routes/dashboard/settings/reports/components/specs/{CsatMetricCard.spec.js => ReportMetricCard.spec.js} (52%) diff --git a/app/javascript/dashboard/routes/dashboard/settings/reports/ReportContainer.vue b/app/javascript/dashboard/routes/dashboard/settings/reports/ReportContainer.vue index 6710187fd..c601b4277 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/reports/ReportContainer.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/reports/ReportContainer.vue @@ -37,15 +37,6 @@ import format from 'date-fns/format'; import { formatTime } from '@chatwoot/utils'; import reportMixin from 'dashboard/mixins/reportMixin'; import ChartStats from './components/ChartElements/ChartStats.vue'; -const REPORTS_KEYS = { - CONVERSATIONS: 'conversations_count', - INCOMING_MESSAGES: 'incoming_messages_count', - OUTGOING_MESSAGES: 'outgoing_messages_count', - FIRST_RESPONSE_TIME: 'avg_first_response_time', - RESOLUTION_TIME: 'avg_resolution_time', - RESOLUTION_COUNT: 'resolutions_count', - REPLY_TIME: 'reply_time', -}; export default { components: { ChartStats }, @@ -55,18 +46,22 @@ export default { type: Object, default: () => ({}), }, + reportKeys: { + type: Object, + default: () => ({ + CONVERSATIONS: 'conversations_count', + INCOMING_MESSAGES: 'incoming_messages_count', + OUTGOING_MESSAGES: 'outgoing_messages_count', + FIRST_RESPONSE_TIME: 'avg_first_response_time', + RESOLUTION_TIME: 'avg_resolution_time', + RESOLUTION_COUNT: 'resolutions_count', + REPLY_TIME: 'reply_time', + }), + }, }, computed: { metrics() { - const reportKeys = [ - 'CONVERSATIONS', - 'FIRST_RESPONSE_TIME', - 'REPLY_TIME', - 'RESOLUTION_TIME', - 'RESOLUTION_COUNT', - 'INCOMING_MESSAGES', - 'OUTGOING_MESSAGES', - ]; + const reportKeys = Object.keys(this.reportKeys); const infoText = { FIRST_RESPONSE_TIME: this.$t( `REPORT.METRICS.FIRST_RESPONSE_TIME.INFO_TEXT` @@ -75,11 +70,11 @@ export default { }; return reportKeys.map(key => ({ NAME: this.$t(`REPORT.METRICS.${key}.NAME`), - KEY: REPORTS_KEYS[key], + KEY: this.reportKeys[key], DESC: this.$t(`REPORT.METRICS.${key}.DESC`), INFO_TEXT: infoText[key], TOOLTIP_TEXT: `REPORT.METRICS.${key}.TOOLTIP_TEXT`, - trend: this.calculateTrend(REPORTS_KEYS[key]), + trend: this.calculateTrend(this.reportKeys[key]), })); }, }, diff --git a/app/javascript/dashboard/routes/dashboard/settings/reports/components/CsatMetricCard.vue b/app/javascript/dashboard/routes/dashboard/settings/reports/components/CsatMetricCard.vue deleted file mode 100644 index aa014a763..000000000 --- a/app/javascript/dashboard/routes/dashboard/settings/reports/components/CsatMetricCard.vue +++ /dev/null @@ -1,77 +0,0 @@ - - - diff --git a/app/javascript/dashboard/routes/dashboard/settings/reports/components/CsatMetrics.vue b/app/javascript/dashboard/routes/dashboard/settings/reports/components/CsatMetrics.vue index d1b9866b0..2c90f987e 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/reports/components/CsatMetrics.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/reports/components/CsatMetrics.vue @@ -1,6 +1,6 @@ + diff --git a/app/javascript/dashboard/routes/dashboard/settings/reports/components/specs/CsatMetricCard.spec.js b/app/javascript/dashboard/routes/dashboard/settings/reports/components/specs/ReportMetricCard.spec.js similarity index 52% rename from app/javascript/dashboard/routes/dashboard/settings/reports/components/specs/CsatMetricCard.spec.js rename to app/javascript/dashboard/routes/dashboard/settings/reports/components/specs/ReportMetricCard.spec.js index 8c52d2e1a..a2e194333 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/reports/components/specs/CsatMetricCard.spec.js +++ b/app/javascript/dashboard/routes/dashboard/settings/reports/components/specs/ReportMetricCard.spec.js @@ -1,46 +1,50 @@ import { createLocalVue, shallowMount } from '@vue/test-utils'; -import CsatMetricCard from '../CsatMetricCard.vue'; +import ReportMetricCard from '../ReportMetricCard.vue'; import VTooltip from 'v-tooltip'; const localVue = createLocalVue(); localVue.use(VTooltip); -describe('CsatMetricCard.vue', () => { +describe('ReportMetricCard.vue', () => { it('renders props correctly', () => { const label = 'Total Responses'; const value = '100'; const infoText = 'Total number of responses'; - const wrapper = shallowMount(CsatMetricCard, { + const wrapper = shallowMount(ReportMetricCard, { propsData: { label, value, infoText }, localVue, stubs: ['fluent-icon'], }); - expect(wrapper.find('.heading span').text()).toMatch(label); - expect(wrapper.find('.metric').text()).toMatch(value); - expect(wrapper.find('.csat--icon').classes()).toContain('has-tooltip'); + expect(wrapper.find({ ref: 'reportMetricLabel' }).text()).toMatch(label); + expect(wrapper.find({ ref: 'reportMetricValue' }).text()).toMatch(value); + expect(wrapper.find({ ref: 'reportMetricInfo' }).classes()).toContain( + 'has-tooltip' + ); }); it('adds disabled class when disabled prop is true', () => { - const wrapper = shallowMount(CsatMetricCard, { + const wrapper = shallowMount(ReportMetricCard, { propsData: { label: '', value: '', infoText: '', disabled: true }, localVue, stubs: ['fluent-icon'], }); - expect(wrapper.find('.csat--metric-card').classes()).toContain('disabled'); + expect(wrapper.classes().join(' ')).toContain( + 'grayscale pointer-events-none opacity-30' + ); }); it('does not add disabled class when disabled prop is false', () => { - const wrapper = shallowMount(CsatMetricCard, { + const wrapper = shallowMount(ReportMetricCard, { propsData: { label: '', value: '', infoText: '', disabled: false }, localVue, stubs: ['fluent-icon'], }); - expect(wrapper.find('.csat--metric-card').classes()).not.toContain( - 'disabled' - ); + expect( + wrapper.find({ ref: 'reportMetricContainer' }).classes().join(' ') + ).not.toContain('grayscale pointer-events-none opacity-30'); }); });