diff --git a/app/javascript/shared/components/Button.vue b/app/javascript/shared/components/Button.vue index 1f099b04e..051c42eba 100644 --- a/app/javascript/shared/components/Button.vue +++ b/app/javascript/shared/components/Button.vue @@ -26,6 +26,10 @@ export default { computed: { buttonClassName() { let className = 'text-white py-3 px-4 rounded shadow-sm'; + if (this.type === 'clear') { + className = 'flex mx-auto mt-4 text-xs w-auto text-black-600'; + } + if (this.type === 'blue' && !Object.keys(this.buttonStyles).length) { className = `${className} bg-woot-500 hover:bg-woot-700`; } diff --git a/app/javascript/shared/constants/busEvents.js b/app/javascript/shared/constants/busEvents.js index 6958f755f..f868e5734 100644 --- a/app/javascript/shared/constants/busEvents.js +++ b/app/javascript/shared/constants/busEvents.js @@ -1,6 +1,6 @@ export const BUS_EVENTS = { SET_REFERRER_HOST: 'SET_REFERRER_HOST', SET_TWEET_REPLY: 'SET_TWEET_REPLY', - ATTACHMENT_SIZE_CHECK_ERROR: 'ATTACHMENT_SIZE_CHECK_ERROR', + SHOW_ALERT: 'SHOW_ALERT', START_NEW_CONVERSATION: 'START_NEW_CONVERSATION', }; diff --git a/app/javascript/widget/api/conversation.js b/app/javascript/widget/api/conversation.js index f22cf8ed9..3552765c7 100755 --- a/app/javascript/widget/api/conversation.js +++ b/app/javascript/widget/api/conversation.js @@ -42,6 +42,12 @@ const setUserLastSeenAt = async ({ lastSeen }) => { { contact_last_seen_at: lastSeen } ); }; +const sendEmailTranscript = async ({ email }) => { + return API.post( + `/api/v1/widget/conversations/transcript${window.location.search}`, + { email } + ); +}; export { createConversationAPI, @@ -51,4 +57,5 @@ export { sendAttachmentAPI, toggleTyping, setUserLastSeenAt, + sendEmailTranscript, }; diff --git a/app/javascript/widget/assets/scss/_variables.scss b/app/javascript/widget/assets/scss/_variables.scss index c47e4a8df..8840c0263 100755 --- a/app/javascript/widget/assets/scss/_variables.scss +++ b/app/javascript/widget/assets/scss/_variables.scss @@ -49,6 +49,7 @@ $color-white: #fff; $color-body: #3c4858; $color-heading: #1f2d3d; $color-error: #ff382d; +$color-success: #44ce4b; // Color-palettes diff --git a/app/javascript/widget/components/Banner.vue b/app/javascript/widget/components/Banner.vue new file mode 100644 index 000000000..d07266745 --- /dev/null +++ b/app/javascript/widget/components/Banner.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/app/javascript/widget/components/ChatAttachment.vue b/app/javascript/widget/components/ChatAttachment.vue index 4c872939c..3a8dc1950 100755 --- a/app/javascript/widget/components/ChatAttachment.vue +++ b/app/javascript/widget/components/ChatAttachment.vue @@ -29,6 +29,11 @@ export default { data() { return { isUploading: false }; }, + computed: { + fileUploadSizeLimit() { + return MAXIMUM_FILE_UPLOAD_SIZE; + }, + }, methods: { getFileType(fileType) { return fileType.includes('image') ? 'image' : 'file'; @@ -47,7 +52,11 @@ export default { thumbUrl, }); } else { - window.bus.$emit(BUS_EVENTS.ATTACHMENT_SIZE_CHECK_ERROR); + window.bus.$emit(BUS_EVENTS.SHOW_ALERT, { + message: this.$t('FILE_SIZE_LIMIT', { + MAXIMUM_FILE_UPLOAD_SIZE: this.fileUploadSizeLimit, + }), + }); } } catch (error) { // Error diff --git a/app/javascript/widget/components/ChatFooter.vue b/app/javascript/widget/components/ChatFooter.vue index 75d64cae2..3deaf06db 100755 --- a/app/javascript/widget/components/ChatFooter.vue +++ b/app/javascript/widget/components/ChatFooter.vue @@ -1,20 +1,31 @@ diff --git a/app/javascript/widget/i18n/locale/en.json b/app/javascript/widget/i18n/locale/en.json index bbb43acfa..2f1c50762 100644 --- a/app/javascript/widget/i18n/locale/en.json +++ b/app/javascript/widget/i18n/locale/en.json @@ -62,5 +62,10 @@ "TITLE": "Rate your conversation", "SUBMITTED_TITLE": "Thank you for submitting the rating", "PLACEHOLDER": "Tell us more..." + }, + "EMAIL_TRANSCRIPT": { + "BUTTON_TEXT": "Request a conversation transcript", + "SEND_EMAIL_SUCCESS": "The chat transcript was sent successfully", + "SEND_EMAIL_ERROR": "There was an error, please try again" } } diff --git a/app/javascript/widget/store/modules/message.js b/app/javascript/widget/store/modules/message.js index 839305d03..b11c5cdd4 100644 --- a/app/javascript/widget/store/modules/message.js +++ b/app/javascript/widget/store/modules/message.js @@ -7,12 +7,15 @@ const state = { }, }; -const getters = { +export const getters = { getUIFlags: $state => $state.uiFlags, }; -const actions = { - update: async ({ commit }, { email, messageId, submittedValues }) => { +export const actions = { + update: async ( + { commit, dispatch }, + { email, messageId, submittedValues } + ) => { commit('toggleUpdateStatus', true); try { const { @@ -33,6 +36,7 @@ const actions = { }, { root: true } ); + dispatch('contacts/get', {}, { root: true }); refreshActionCableConnector(pubsubToken); } catch (error) { // Ignore error @@ -41,7 +45,7 @@ const actions = { }, }; -const mutations = { +export const mutations = { toggleUpdateStatus($state, status) { $state.uiFlags.isUpdating = status; }, diff --git a/app/javascript/widget/store/modules/specs/message/actions.spec.js b/app/javascript/widget/store/modules/specs/message/actions.spec.js new file mode 100644 index 000000000..36e4341ef --- /dev/null +++ b/app/javascript/widget/store/modules/specs/message/actions.spec.js @@ -0,0 +1,38 @@ +import { API } from 'widget/helpers/axios'; +import { actions } from '../../message'; + +const commit = jest.fn(); +jest.mock('widget/helpers/axios'); + +describe('#actions', () => { + describe('#update', () => { + it('sends correct actions', async () => { + const user = { + email: 'john@acme.inc', + messageId: 10, + submittedValues: { + email: 'john@acme.inc', + }, + }; + API.patch.mockResolvedValue({ + data: { contact: { pubsub_token: '8npuMUfDgizrwVoqcK1t7FMY' } }, + }); + await actions.update({ commit }, user); + expect(commit.mock.calls).toEqual([ + ['toggleUpdateStatus', true], + [ + 'conversation/updateMessage', + { + id: 10, + content_attributes: { + submitted_email: 'john@acme.inc', + submitted_values: null, + }, + }, + { root: true }, + ], + ['toggleUpdateStatus', false], + ]); + }); + }); +}); diff --git a/app/javascript/widget/store/modules/specs/message/getters.spec.js b/app/javascript/widget/store/modules/specs/message/getters.spec.js new file mode 100644 index 000000000..400690f4d --- /dev/null +++ b/app/javascript/widget/store/modules/specs/message/getters.spec.js @@ -0,0 +1,14 @@ +import { getters } from '../../message'; + +describe('#getters', () => { + it('getUIFlags', () => { + const state = { + uiFlags: { + isUpdating: false, + }, + }; + expect(getters.getUIFlags(state)).toEqual({ + isUpdating: false, + }); + }); +}); diff --git a/app/javascript/widget/store/modules/specs/message/mutations.spec.js b/app/javascript/widget/store/modules/specs/message/mutations.spec.js new file mode 100644 index 000000000..3c7e6b30d --- /dev/null +++ b/app/javascript/widget/store/modules/specs/message/mutations.spec.js @@ -0,0 +1,11 @@ +import { mutations } from '../../message'; + +describe('#mutations', () => { + describe('#toggleUpdateStatus', () => { + it('set update flags', () => { + const state = { uiFlags: { status: '' } }; + mutations.toggleUpdateStatus(state, 'sent'); + expect(state.uiFlags.isUpdating).toEqual('sent'); + }); + }); +}); diff --git a/app/javascript/widget/views/Home.vue b/app/javascript/widget/views/Home.vue index 539d12922..c8d89cbe2 100755 --- a/app/javascript/widget/views/Home.vue +++ b/app/javascript/widget/views/Home.vue @@ -34,15 +34,7 @@ /> - +
{ - this.showAttachmentError = true; - setTimeout(() => { - this.showAttachmentError = false; - }, 3000); - }); bus.$on(BUS_EVENTS.START_NEW_CONVERSATION, () => { this.isOnCollapsedView = true; this.isOnNewConversation = true; @@ -242,13 +229,5 @@ export default { .input-wrap { padding: 0 $space-normal; } - .banner { - background: $color-error; - color: $color-white; - font-size: $font-size-default; - font-weight: $font-weight-bold; - padding: $space-slab; - text-align: center; - } }