fix: Add Attachment endpoint to save file against automation rule (#4480)

Co-authored-by: fayazara <fayazara@gmail.com>
Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
Tejaswini Chile
2022-04-24 12:02:40 +05:30
committed by GitHub
parent 2acb48bbe0
commit 1b3011b27b
18 changed files with 291 additions and 57 deletions

View File

@@ -9,6 +9,14 @@ class AutomationsAPI extends ApiClient {
clone(automationId) {
return axios.post(`${this.url}/${automationId}/clone`);
}
attachment(file) {
return axios.post(`${this.url}/attach_file`, file, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
}
}
export default new AutomationsAPI();

View File

@@ -52,6 +52,11 @@
class="answer--text-input"
placeholder="Enter url"
/>
<automation-action-file-input
v-if="inputType === 'attachment'"
v-model="action_params"
:initial-file-name="initialFileName"
/>
</div>
</div>
<woot-button
@@ -84,9 +89,11 @@
<script>
import AutomationActionTeamMessageInput from './AutomationActionTeamMessageInput.vue';
import AutomationActionFileInput from './AutomationFileInput.vue';
export default {
components: {
AutomationActionTeamMessageInput,
AutomationActionFileInput,
},
props: {
value: {
@@ -109,6 +116,10 @@ export default {
type: Boolean,
default: true,
},
initialFileName: {
type: String,
default: '',
},
},
computed: {
action_name: {
@@ -187,6 +198,7 @@ export default {
.filter__answer--wrap {
margin-right: var(--space-smaller);
flex-grow: 1;
max-width: 50%;
input {
margin-bottom: 0;

View File

@@ -0,0 +1,117 @@
<template>
<label class="input-wrapper" :class="uploadState">
<input
v-if="uploadState !== 'processing'"
type="file"
name="attachment"
:class="uploadState === 'processing' ? 'disabled' : ''"
@change="onChangeFile"
/>
<spinner v-if="uploadState === 'processing'" />
<fluent-icon v-if="uploadState === 'idle'" icon="file-upload" />
<fluent-icon
v-if="uploadState === 'uploaded'"
icon="checkmark-circle"
type="outline"
class="success-icon"
/>
<fluent-icon
v-if="uploadState === 'failed'"
icon="dismiss-circle"
type="outline"
class="error-icon"
/>
<p class="file-button">{{ label }}</p>
</label>
</template>
<script>
import Spinner from 'shared/components/Spinner';
import alertMixin from 'shared/mixins/alertMixin';
export default {
components: {
Spinner,
},
mixins: [alertMixin],
props: {
value: {
type: Array,
default: () => [],
},
initialFileName: {
type: String,
default: '',
},
},
data() {
return {
uploadState: 'idle',
label: this.$t('AUTOMATION.ATTACHMENT.LABEL_IDLE'),
};
},
mounted() {
if (this.initialFileName) {
this.label = this.initialFileName;
this.uploadState = 'uploaded';
}
},
methods: {
async onChangeFile(event) {
this.uploadState = 'processing';
this.label = this.$t('AUTOMATION.ATTACHMENT.LABEL_UPLOADING');
try {
const file = event.target.files[0];
const formData = new FormData();
formData.append('attachment', file, file.name);
const id = await this.$store.dispatch(
'automations/uploadAttachment',
formData
);
this.$emit('input', [id]);
this.uploadState = 'uploaded';
this.label = this.$t('AUTOMATION.ATTACHMENT.LABEL_UPLOADED');
} catch (error) {
this.uploadState = 'failed';
this.label = this.$t('AUTOMATION.ATTACHMENT.LABEL_UPLOAD_FAILED');
this.showAlert(this.$t('AUTOMATION.ATTACHMENT.UPLOAD_ERROR'));
}
},
},
};
</script>
<style scoped>
input[type='file'] {
display: none;
}
.input-wrapper {
display: flex;
height: 39px;
background-color: var(--white);
border-radius: var(--border-radius-small);
border: 1px dashed var(--w-100);
padding: var(--space-smaller) var(--space-small);
align-items: center;
font-size: var(--font-size-mini);
cursor: pointer;
}
.success-icon {
margin-right: var(--space-small);
color: var(--g-500);
}
.error-icon {
margin-right: var(--space-small);
color: var(--r-500);
}
.processing {
cursor: not-allowed;
opacity: 0.9;
}
.file-button {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
}
</style>

View File

@@ -1,7 +1,15 @@
const allElementsString = arr => {
return arr.every(elem => typeof elem === 'string');
};
const allElementsNumbers = arr => {
return arr.every(elem => typeof elem === 'number');
};
const formatArray = params => {
if (params.length <= 0) {
params = [];
} else if (params.every(elem => typeof elem === 'string')) {
} else if (allElementsString(params) || allElementsNumbers(params)) {
params = [...params];
} else {
params = params.map(val => val.id);

View File

@@ -104,6 +104,13 @@
"DEACTIVATION_ERROR": "Could not Deactivate Automation, Please try again later",
"CONFIRMATION_LABEL": "Yes",
"CANCEL_LABEL": "No"
},
"ATTACHMENT": {
"UPLOAD_ERROR": "Could not upload attachment, Please try again",
"LABEL_IDLE": "Upload Attachment",
"LABEL_UPLOADING": "Uploading...",
"LABEL_UPLOADED": "Succesfully Uploaded",
"LABEL_UPLOAD_FAILED": "Upload Failed"
}
}
}

View File

@@ -101,6 +101,12 @@
showActionInput(automation.actions[i].action_name)
"
:v="$v.automation.actions.$each[i]"
:initial-file-name="
getFileName(
automation.actions[i].action_params[0],
automation.actions[i].action_name
)
"
@removeAction="removeAction(i)"
/>
<div class="filter-actions">
@@ -507,6 +513,15 @@ export default {
if (type === null) return false;
return true;
},
getFileName(id, actionType) {
if (!id) return '';
if (actionType === 'send_attachment') {
const file = this.automation.files.find(item => item.blob_id === id);
// replace `blob_id.toString()` with file name once api is fixed.
if (file) return file.filename.toString();
}
return '';
},
},
};
</script>

View File

@@ -119,11 +119,11 @@ export const AUTOMATIONS = {
name: 'Send Webhook Event',
attributeI18nKey: 'SEND_WEBHOOK_EVENT',
},
// {
// key: 'send_attachment',
// name: 'Send Attachment',
// attributeI18nKey: 'SEND_ATTACHMENT',
// },
{
key: 'send_attachment',
name: 'Send Attachment',
attributeI18nKey: 'SEND_ATTACHMENT',
},
],
},
conversation_created: {
@@ -210,11 +210,11 @@ export const AUTOMATIONS = {
name: 'Send Webhook Event',
attributeI18nKey: 'SEND_WEBHOOK_EVENT',
},
// {
// key: 'send_attachment',
// name: 'Send Attachment',
// attributeI18nKey: 'SEND_ATTACHMENT',
// },
{
key: 'send_attachment',
name: 'Send Attachment',
attributeI18nKey: 'SEND_ATTACHMENT',
},
],
},
conversation_updated: {
@@ -315,11 +315,11 @@ export const AUTOMATIONS = {
name: 'Send Webhook Event',
attributeI18nKey: 'SEND_WEBHOOK_EVENT',
},
// {
// key: 'send_attachment',
// name: 'Send Attachment',
// attributeI18nKey: 'SEND_ATTACHMENT',
// },
{
key: 'send_attachment',
name: 'Send Attachment',
attributeI18nKey: 'SEND_ATTACHMENT',
},
],
},
};
@@ -380,11 +380,11 @@ export const AUTOMATION_ACTION_TYPES = [
label: 'Send Webhook Event',
inputType: 'url',
},
// {
// key: 'send_attachment',
// label: 'Send Attachment',
// inputType: 'file',
// },
{
key: 'send_attachment',
label: 'Send Attachment',
inputType: 'attachment',
},
{
key: 'send_message',
label: 'Send a message',

View File

@@ -76,6 +76,14 @@ export const actions = {
commit(types.SET_AUTOMATION_UI_FLAG, { isCloning: false });
}
},
uploadAttachment: async (_, file) => {
try {
const { data } = await AutomationAPI.attachment(file);
return data.blob_id;
} catch (error) {
throw new Error(error);
}
},
};
export const mutations = {