Skip to content

Commit

Permalink
feat: Ability to remove inbox avatar (#2885)
Browse files Browse the repository at this point in the history
* Delete inbox avatar

1) New API endpoint added for deleting inbox avatar.
2) Delete avatar button in the inbox settings page.

Co-authored-by: Sojan Jose <sojan@pepalo.com>
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
  • Loading branch information
3 people committed Aug 31, 2021
1 parent fdcc322 commit 1ff9939
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 12 deletions.
5 changes: 5 additions & 0 deletions app/controllers/api/v1/accounts/inboxes_controller.rb
Expand Up @@ -15,6 +15,11 @@ def campaigns
@campaigns = @inbox.campaigns
end

def avatar
@inbox.avatar.attachment.destroy! if @inbox.avatar.attached?
head :ok
end

def create
ActiveRecord::Base.transaction do
channel = create_channel
Expand Down
4 changes: 4 additions & 0 deletions app/javascript/dashboard/api/inboxes.js
Expand Up @@ -13,6 +13,10 @@ class Inboxes extends ApiClient {
getCampaigns(inboxId) {
return axios.get(`${this.url}/${inboxId}/campaigns`);
}

deleteInboxAvatar(inboxId) {
return axios.delete(`${this.url}/${inboxId}/avatar`);
}
}

export default new Inboxes();
7 changes: 7 additions & 0 deletions app/javascript/dashboard/api/specs/inboxes.spec.js
Expand Up @@ -27,5 +27,12 @@ describe('#InboxesAPI', () => {
'/api/v1/inboxes/2/campaigns'
);
});

it('#deleteInboxAvatar', () => {
inboxesAPI.deleteInboxAvatar(2);
expect(context.axiosMock.delete).toHaveBeenCalledWith(
'/api/v1/inboxes/2/avatar'
);
});
});
});
@@ -1,16 +1,31 @@
<template>
<label>
<span v-if="label">{{ label }}</span>
<div>
<label>
<span v-if="label">{{ label }}</span>
</label>
<woot-thumbnail v-if="src" size="80px" :src="src" />
<input
id="file"
ref="file"
type="file"
accept="image/*"
@change="handleImageUpload"
/>
<slot></slot>
</label>
<div v-if="src && deleteAvatar" class="avatar-delete-btn">
<woot-button
color-scheme="alert"
variant="hollow"
size="tiny"
@click="onAvatarDelete"
>{{
this.$t('INBOX_MGMT.DELETE.AVATAR_DELETE_BUTTON_TEXT')
}}</woot-button
>
</div>
<label>
<input
id="file"
ref="file"
type="file"
accept="image/*"
@change="handleImageUpload"
/>
<slot></slot>
</label>
</div>
</template>

<script>
Expand All @@ -24,6 +39,10 @@ export default {
type: String,
default: '',
},
deleteAvatar: {
type: Boolean,
default: false,
},
},
watch: {},
methods: {
Expand All @@ -35,6 +54,17 @@ export default {
url: URL.createObjectURL(file),
});
},
onAvatarDelete() {
this.$refs.file.value = null;
this.$emit('onAvatarDelete');
},
},
};
</script>

<style lang="scss" scoped>
.avatar-delete-btn {
margin-top: var(--space-smaller);
margin-bottom: var(--space-smaller);
}
</style>
5 changes: 4 additions & 1 deletion app/javascript/dashboard/i18n/locale/en/inboxMgmt.json
Expand Up @@ -232,6 +232,7 @@
},
"DELETE": {
"BUTTON_TEXT": "Delete",
"AVATAR_DELETE_BUTTON_TEXT": "Delete Avatar",
"CONFIRM": {
"TITLE": "Confirm Deletion",
"MESSAGE": "Are you sure to delete ",
Expand All @@ -241,7 +242,9 @@
},
"API": {
"SUCCESS_MESSAGE": "Inbox deleted successfully",
"ERROR_MESSAGE": "Could not delete inbox. Please try again later."
"ERROR_MESSAGE": "Could not delete inbox. Please try again later.",
"AVATAR_SUCCESS_MESSAGE": "Inbox avatar deleted successfully",
"AVATAR_ERROR_MESSAGE": "Could not delete the inbox avatar. Please try again later."
}
},
"TABS": {
Expand Down
Expand Up @@ -22,7 +22,9 @@
<woot-avatar-uploader
:label="$t('INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_AVATAR.LABEL')"
:src="avatarUrl"
deleteAvatar
@change="handleImageUpload"
@onAvatarDelete="handleAvatarDelete"
/>
<woot-input
v-model.trim="selectedInboxName"
Expand Down Expand Up @@ -544,6 +546,23 @@ export default {
this.avatarFile = file;
this.avatarUrl = url;
},
async handleAvatarDelete() {
try {
await this.$store.dispatch(
'inboxes/deleteInboxAvatar',
this.currentInboxId
);
this.avatarFile = null;
this.avatarUrl = '';
this.showAlert(this.$t('INBOX_MGMT.DELETE.API.AVATAR_SUCCESS_MESSAGE'));
} catch (error) {
this.showAlert(
error.message
? error.message
: this.$t('INBOX_MGMT.DELETE.API.AVATAR_ERROR_MESSAGE')
);
}
},
},
validations: {
selectedAgents: {
Expand Down
7 changes: 7 additions & 0 deletions app/javascript/dashboard/store/modules/inboxes.js
Expand Up @@ -173,6 +173,13 @@ export const actions = {
throw new Error(error.message);
}
},
deleteInboxAvatar: async (_, inboxId) => {
try {
await InboxesAPI.deleteInboxAvatar(inboxId);
} catch (error) {
throw new Error(error);
}
},
};

export const mutations = {
Expand Down
Expand Up @@ -128,4 +128,19 @@ describe('#actions', () => {
]);
});
});

describe('#deleteInboxAvatar', () => {
it('sends correct actions if API is success', async () => {
axios.delete.mockResolvedValue();
await expect(
actions.deleteInboxAvatar({}, inboxList[0].id)
).resolves.toBe();
});
it('sends correct actions if API is error', async () => {
axios.delete.mockRejectedValue({ message: 'Incorrect header' });
await expect(
actions.deleteInboxAvatar({}, inboxList[0].id)
).rejects.toThrow(Error);
});
});
});
4 changes: 4 additions & 0 deletions app/policies/inbox_policy.rb
Expand Up @@ -53,4 +53,8 @@ def destroy?
def set_agent_bot?
@account_user.administrator?
end

def avatar?
@account_user.administrator?
end
end
1 change: 1 addition & 0 deletions config/routes.rb
Expand Up @@ -102,6 +102,7 @@
get :campaigns, on: :member
get :agent_bot, on: :member
post :set_agent_bot, on: :member
delete :avatar, on: :member
end
resources :inbox_members, only: [:create, :show], param: :inbox_id
resources :labels, only: [:index, :show, :create, :update, :destroy]
Expand Down
36 changes: 36 additions & 0 deletions spec/controllers/api/v1/accounts/inboxes_controller_spec.rb
Expand Up @@ -113,6 +113,42 @@
end
end

describe 'DELETE /api/v1/accounts/{account.id}/inboxes/{inbox.id}/avatar' do
let(:inbox) { create(:inbox, account: account) }

context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
delete "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}/avatar"

expect(response).to have_http_status(:unauthorized)
end
end

context 'when it is an authenticated user' do
before do
create(:inbox_member, user: agent, inbox: inbox)
inbox.avatar.attach(io: File.open(Rails.root.join('spec/assets/avatar.png')), filename: 'avatar.png', content_type: 'image/png')
end

it 'delete inbox avatar for administrator user' do
delete "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}/avatar",
headers: admin.create_new_auth_token,
as: :json

expect { inbox.avatar.attachment.reload }.to raise_error(ActiveRecord::RecordNotFound)
expect(response).to have_http_status(:success)
end

it 'returns unauthorized for agent user' do
delete "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}/avatar",
headers: agent.create_new_auth_token,
as: :json

expect(response).to have_http_status(:unauthorized)
end
end
end

describe 'DELETE /api/v1/accounts/{account.id}/inboxes/:id' do
let(:inbox) { create(:inbox, account: account) }

Expand Down

0 comments on commit 1ff9939

Please sign in to comment.