Skip to content

Commit

Permalink
feature 6506 multiple questions csat
Browse files Browse the repository at this point in the history
  • Loading branch information
jderecho committed Nov 22, 2023
1 parent eea197c commit fd2612d
Show file tree
Hide file tree
Showing 23 changed files with 212 additions and 76 deletions.
14 changes: 12 additions & 2 deletions app/controllers/api/v1/accounts/csat_templates_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Api::V1::Accounts::CsatTemplatesController < Api::V1::Accounts::BaseController
before_action :load_template, only: [:show, :destroy]
before_action :load_template, only: [:show, :update, :destroy]
def index
@templates = csat_templates
@templates_count = @templates.count
Expand All @@ -9,10 +9,20 @@ def show; end

def create
@template = csat_templates.create(csat_template_params)
# rubocop:disable Rails/SkipsModelValidations
Current.account.inboxes.where(id: inbox_id_params).update_all(csat_template_id: @template.id)
# rubocop:enable Rails/SkipsModelValidations
render json: @template
end

def update
@template.update(csat_template_params)
# rubocop:disable Rails/SkipsModelValidations
Current.account.inboxes.where(csat_template_id: params[:id]).update_all(csat_template_id: nil)
Current.account.inboxes.where(id: inbox_id_params).update_all(csat_template_id: @template.id)
# rubocop:enable Rails/SkipsModelValidations
end

def destroy
@template.destroy
render json: { success: @template.destroyed? }
Expand Down Expand Up @@ -45,7 +55,7 @@ def csat_questions
end

def csat_template_params
params.require(:csat_template).permit(csat_template_questions_attributes: [:id, :content])
params.require(:csat_template).permit(csat_template_questions_attributes: [:id, :content, :_destroy])
end

def inbox_id_params
Expand Down
4 changes: 4 additions & 0 deletions app/javascript/dashboard/api/csatTemplates.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ class CsatTemplatesAPI extends ApiClient {
return axios.post(this.url, params);
}

update(id, params) {
return axios.patch(`${this.url}/${id}`, params);
}

getStatus() {
return axios.get(`${this.url}/setting_status`);
}
Expand Down
10 changes: 10 additions & 0 deletions app/javascript/dashboard/i18n/locale/en/csatSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@
"QUESTIONS": "Questions",
"INBOX": "Inbox"
}
},
"FORM": {
"INBOXES": {
"LABEL": "Inbox",
"ERROR": "Please select atleast 1 inbox"
},
"QUESTION": {
"ERROR": "Question is required",
"ERROR_MAX_LENGTH": "Question limit is reached"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,41 @@
<div class="h-auto overflow-auto flex flex-col">
<woot-modal-header :header-title="$t('CSAT_SETTINGS.TEMPLATE.ADD')" />
<form class="flex flex-col w-full" @submit.prevent="addCsatTemplate()">
<label>Inbox</label>
<multiselect
v-model="inboxes"
:options="dropdownValues"
track-by="id"
label="name"
:placeholder="$t('FORMS.MULTISELECT.SELECT')"
:multiple="true"
:close-on-select="false"
:clear-on-select="false"
:hide-selected="true"
selected-label
:select-label="$t('FORMS.MULTISELECT.ENTER_TO_SELECT')"
deselect-label=""
:max-height="160"
:option-height="104"
/>
<label :class="{ error: $v.inboxes.$error }">
{{ $t('CSAT_SETTINGS.FORM.INBOXES.LABEL') }}
<multiselect
v-model="inboxes"
:options="dropdownValues"
track-by="id"
label="name"
:placeholder="$t('FORMS.MULTISELECT.SELECT')"
:multiple="true"
:close-on-select="false"
:clear-on-select="false"
:hide-selected="true"
selected-label
:select-label="$t('FORMS.MULTISELECT.ENTER_TO_SELECT')"
deselect-label=""
:max-height="160"
:option-height="104"
/>
<span v-if="$v.inboxes.$error" class="message">
{{ $t('CSAT_SETTINGS.FORM.INBOXES.ERROR') }}
</span>
</label>
<div
v-for="(question, index) in custom_questions"
:key="index"
class="w-full"
>
<label>
<label
:class="{ error: $v.custom_questions.$each[index].content.$error }"
>
{{ question.label }}
<div class="flex">
<input
v-model="question.content"
class="mb-1"
type="text"
:placeholder="$t('CSAT_SETTINGS.TEMPLATE.PLACEHOLDER')"
/>
Expand All @@ -40,10 +48,18 @@
@click.prevent="deleteQuestion(index)"
/>
</div>
<span
v-if="$v.custom_questions.$each[index].content.$error"
class="message"
>
{{ $t('CSAT_SETTINGS.FORM.QUESTION.ERROR') }}
</span>
</label>
</div>

<div class="w-full">
<span v-if="!$v.custom_questions.maxLength">
{{ $t('CSAT_SETTINGS.FORM.QUESTION.ERROR_MAX_LENGTH') }}
</span>
<div v-if="$v.custom_questions.maxLength" class="mt-2 w-full">
<woot-button
type="button"
color-scheme="success"
Expand All @@ -67,6 +83,7 @@
</template>

<script>
import { required, minLength, maxLength } from 'vuelidate/lib/validators';
import { mapGetters } from 'vuex';
import alertMixin from 'shared/mixins/alertMixin';
Expand All @@ -84,6 +101,21 @@ export default {
inboxes: [],
};
},
validations: {
custom_questions: {
required,
minLength: minLength(1),
maxLength: maxLength(20),
$each: {
content: {
required,
},
},
},
inboxes: {
required,
},
},
computed: {
...mapGetters({
dropdownValues: 'csatTemplates/inboxesForSelect',
Expand All @@ -110,6 +142,13 @@ export default {
this.custom_questions.splice(index, 1);
},
addCsatTemplate() {
this.$v.$touch();
if (this.$v.$invalid) {
this.showAlert(this.$t('GENERAL_SETTINGS.FORM.ERROR'));
return;
}
this.$store
.dispatch('csatTemplates/create', this.csatTemplate())
.then(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,38 @@
<div class="h-auto overflow-auto flex flex-col">
<woot-modal-header :header-title="$t('CSAT_SETTINGS.TEMPLATE.EDIT')" />
<form class="flex flex-col w-full" @submit.prevent="editCsatTemplate()">
<label>Inbox</label>
<multiselect
v-model="inboxes"
:options="dropdownValues"
track-by="id"
label="name"
:placeholder="$t('FORMS.MULTISELECT.SELECT')"
:multiple="true"
:close-on-select="false"
:clear-on-select="false"
:hide-selected="true"
selected-label
:select-label="$t('FORMS.MULTISELECT.ENTER_TO_SELECT')"
deselect-label=""
:max-height="160"
:option-height="104"
/>
<label :class="{ error: $v.inboxes.$error }">
{{ $t('CSAT_SETTINGS.FORM.INBOXES.LABEL') }}
<multiselect
v-model="inboxes"
:options="dropdownValues"
track-by="id"
label="name"
:placeholder="$t('FORMS.MULTISELECT.SELECT')"
:multiple="true"
:close-on-select="false"
:clear-on-select="false"
:hide-selected="true"
selected-label
:select-label="$t('FORMS.MULTISELECT.ENTER_TO_SELECT')"
deselect-label=""
:max-height="160"
:option-height="104"
/>
</label>
<div
v-for="(question, index) in custom_questions"
:key="index"
class="w-full"
>
<label>
{{ question.label }}
<label
:class="{ error: $v.custom_questions.$each[index].content.$error }"
>
{{ question.label }} {{ question._destroy }}
<div class="flex">
<input
v-model="question.content"
class="mb-1"
type="text"
:placeholder="$t('CSAT_SETTINGS.TEMPLATE.PLACEHOLDER')"
/>
Expand All @@ -40,9 +45,18 @@
@click.prevent="deleteQuestion(index)"
/>
</div>
<span
v-if="$v.custom_questions.$each[index].content.$error"
class="message"
>
{{ $t('CSAT_SETTINGS.FORM.QUESTION.ERROR') }}
</span>
</label>
</div>
<div class="w-full">
<span v-if="!$v.custom_questions.maxLength">
{{ $t('CSAT_SETTINGS.FORM.QUESTION.ERROR_MAX_LENGTH') }}
</span>
<div v-if="!maxQuestionReached" class="mt-2 w-full">
<woot-button
type="button"
color-scheme="success"
Expand All @@ -64,6 +78,7 @@
</template>

<script>
import { required, minLength, maxLength } from 'vuelidate/lib/validators';
import { mapGetters } from 'vuex';
import alertMixin from 'shared/mixins/alertMixin';
export default {
Expand All @@ -78,25 +93,37 @@ export default {
return {
custom_questions: [],
inboxes: [],
deleted_questions: [],
};
},
validations: {
custom_questions: {
required,
minLength: minLength(1),
maxLength: maxLength(20),
$each: {
content: {
required,
},
},
},
inboxes: {
required,
},
},
computed: {
...mapGetters({
dropdownValues: 'csatTemplates/inboxesForSelect',
currentTemplateId: 'csatTemplates/getCurrentTemplateId',
currentTemplate: 'csatTemplates/getCurrentTemplate',
}),
maxQuestionReached() {
return this.custom_questions.length >= 20;
},
},
watch: {
currentTemplate(temp) {
const saved_q = [];
for (let index = 0; index < temp.questions.length; index = +1) {
const question = temp.questions[index];
saved_q.push({ ...question, label: 'Question' + (index + 1) });
}
this.custom_questions = saved_q;
this.custom_questions = temp.questions;
this.inboxes = temp.selected_inboxes;
},
},
Expand All @@ -118,11 +145,39 @@ export default {
return 'Question ' + (this.custom_questions.length + 1);
},
deleteQuestion(index) {
const question = this.custom_questions[index];
if (question.id) {
// eslint-disable-next-line no-underscore-dangle
question._destroy = true;
this.deleted_questions.push(question);
}
this.custom_questions.splice(index, 1);
},
editCsatTemplate() {
this.showAlert('Successfully updated.');
this.$v.$touch();
if (this.$v.$invalid) {
this.showAlert(this.$t('GENERAL_SETTINGS.FORM.ERROR'));
return;
}
this.$store.dispatch('csatTemplates/update', {
id: this.currentTemplateId,
...this.csatTemplate(),
});
this.onClose();
this.showAlert('Successfully updated.');
},
csatTemplate() {
return {
csat_template: {
inbox_ids: this.inboxes.map(inbox => inbox.id),
csat_template_questions_attributes: this.csatTemplateQuestions(),
},
};
},
csatTemplateQuestions() {
return [...this.custom_questions, ...this.deleted_questions];
},
},
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="-mt-px text-sm">
<button
class="flex items-center select-none w-full bg-slate-50 dark:bg-slate-800 border border-l-0 border-r-0 border-solid m-0 border-slate-100 dark:border-slate-700/50 cursor-grab justify-between py-2 px-4 drag-handle"
class="flex items-center select-none w-full bg-slate-50 dark:bg-slate-800 border border-l-0 border-r-0 border-solid m-0 border-slate-100 dark:border-slate-700/50 cursor-grab justify-between px-4 drag-handle"
@click="toggleAccordion"
>
<div class="flex justify-between mb-0.5">
Expand All @@ -17,7 +17,7 @@
</div>
<div />
<div>
<div class="w-[100%] report-card rtl:[direction:initial]">
<div class="w-[100%] report-card rtl:[direction:initial] p-2">
<h3 class="heading text-slate-800 dark:text-slate-100">
<div class="flex justify-end flex-row-reverse">
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,7 @@ export default {
.grouped-csat .ve-table-header-tr {
display: none;
}
.ve-table-container.ve-table-border-around {
overflow: hidden;
}
</style>
Loading

0 comments on commit fd2612d

Please sign in to comment.