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 @@
+
+
+
+ {{ bannerMessage }}
+
+
+
+
+
+
+
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 @@
-
-
- {{ $t('START_NEW_CONVERSATION') }}
-
+
+
+
+
+ {{ $t('START_NEW_CONVERSATION') }}
+
+
+ {{ $t('EMAIL_TRANSCRIPT.BUTTON_TEXT') }}
+
+
+
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 @@
/>
-
-
- {{
- $t('FILE_SIZE_LIMIT', {
- MAXIMUM_FILE_UPLOAD_SIZE: fileUploadSizeLimit,
- })
- }}
-
-
+
{
- 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;
- }
}