feat: Add the ability to create dashboard apps from the UI (#4924)
Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
parent
e4b159dd54
commit
ef1d117717
14 changed files with 713 additions and 64 deletions
|
@ -18,6 +18,7 @@ const settings = accountId => ({
|
|||
'settings_integrations_webhook',
|
||||
'settings_integrations_integration',
|
||||
'settings_applications',
|
||||
'settings_integrations_dashboard_apps',
|
||||
'settings_applications_webhook',
|
||||
'settings_applications_integration',
|
||||
'general_settings',
|
||||
|
|
|
@ -35,7 +35,10 @@
|
|||
"LIST": {
|
||||
"404": "There are no webhooks configured for this account.",
|
||||
"TITLE": "Manage webhooks",
|
||||
"TABLE_HEADER": ["Webhook endpoint", "Actions"]
|
||||
"TABLE_HEADER": [
|
||||
"Webhook endpoint",
|
||||
"Actions"
|
||||
]
|
||||
},
|
||||
"EDIT": {
|
||||
"BUTTON_TEXT": "Edit",
|
||||
|
@ -68,7 +71,7 @@
|
|||
}
|
||||
},
|
||||
"SLACK": {
|
||||
"HELP_TEXT" : {
|
||||
"HELP_TEXT": {
|
||||
"TITLE": "Using Slack Integration",
|
||||
"BODY": "<br/><p>Chatwoot will now sync all the incoming conversations into the <b><i>customer-conversations</i></b> channel inside your slack workplace.</p><p>Replying to a conversation thread in <b><i>customer-conversations</i></b> slack channel will create a response back to the customer through chatwoot.</p><p>Start the replies with <b><i>note:</i></b> to create private notes instead of replies.</p><p>If the replier on slack has an agent profile in chatwoot under the same email, the replies will be associated accordingly.</p><p>When the replier doesn't have an associated agent profile, the replies will be made from the bot profile.</p>"
|
||||
}
|
||||
|
@ -81,6 +84,52 @@
|
|||
},
|
||||
"CONNECT": {
|
||||
"BUTTON_TEXT": "Connect"
|
||||
},
|
||||
"DASHBOARD_APPS": {
|
||||
"TITLE": "Dashboard Apps",
|
||||
"HEADER_BTN_TXT": "Add a new dashboard app",
|
||||
"SIDEBAR_TXT": "<p><b>Dashboard Apps</b></p><p>Dashboard Apps allow organizations to embed an application inside the Chatwoot dashboard to provide the context for customer support agents. This feature allows you to create an application independently and embed that inside the dashboard to provide user information, their orders, or their previous payment history.</p><p>When you embed your application using the dashboard in Chatwoot, your application will get the context of the conversation and contact as a window event. Implement a listener for the message event on your page to receive the context.</p><p>To add a new dashboard app, click on the button 'Add a new dashboard app'.</p>",
|
||||
"DESCRIPTION": "Dashboard Apps allow organizations to embed an application inside the dashboard to provide the context for customer support agents. This feature allows you to create an application independently and embed that to provide user information, their orders, or their previous payment history.",
|
||||
"LIST": {
|
||||
"404": "There are no dashboard apps configured on this account yet",
|
||||
"LOADING": "Fetching dashboard apps...",
|
||||
"TABLE_HEADER": [
|
||||
"Name",
|
||||
"Endpoint"
|
||||
],
|
||||
"EDIT_TOOLTIP": "Edit app",
|
||||
"DELETE_TOOLTIP": "Delete app"
|
||||
},
|
||||
"FORM": {
|
||||
"TITLE_LABEL": "Name",
|
||||
"TITLE_PLACEHOLDER": "Enter a name for your dashboard app",
|
||||
"TITLE_ERROR": "A name for the dashboard app is required",
|
||||
"URL_LABEL": "Endpoint",
|
||||
"URL_PLACEHOLDER": "Enter the endpoint URL where your app is hosted",
|
||||
"URL_ERROR": "A valid URL is required"
|
||||
},
|
||||
"CREATE": {
|
||||
"HEADER": "Add a new dashboard app",
|
||||
"FORM_SUBMIT": "Submit",
|
||||
"FORM_CANCEL": "Cancel",
|
||||
"API_SUCCESS": "Dashboard app configured successfully",
|
||||
"API_ERROR": "We couldn't create an app. Please try again later"
|
||||
},
|
||||
"UPDATE": {
|
||||
"HEADER": "Edit dashboard app",
|
||||
"FORM_SUBMIT": "Update",
|
||||
"FORM_CANCEL": "Cancel",
|
||||
"API_SUCCESS": "Dashboard app updated successfully",
|
||||
"API_ERROR": "We couldn't update the app. Please try again later"
|
||||
},
|
||||
"DELETE": {
|
||||
"CONFIRM_YES": "Yes, delete it",
|
||||
"CONFIRM_NO": "No, keep it",
|
||||
"TITLE": "Confirm deletion",
|
||||
"MESSAGE": "Are you sure to delete the app - %{appName}?",
|
||||
"API_SUCCESS": "Dashboard app deleted successfully",
|
||||
"API_ERROR": "We couldn't delete the app. Please try again later"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
<template>
|
||||
<woot-modal :show="show" :on-close="closeModal">
|
||||
<div class="column content-box">
|
||||
<woot-modal-header :header-title="header" />
|
||||
|
||||
<form class="row" @submit.prevent="submit">
|
||||
<woot-input
|
||||
v-model.trim="app.title"
|
||||
:class="{ error: $v.app.title.$error }"
|
||||
class="medium-12 columns"
|
||||
:label="$t('INTEGRATION_SETTINGS.DASHBOARD_APPS.FORM.TITLE_LABEL')"
|
||||
:placeholder="
|
||||
$t('INTEGRATION_SETTINGS.DASHBOARD_APPS.FORM.TITLE_PLACEHOLDER')
|
||||
"
|
||||
:error="
|
||||
$v.app.title.$error
|
||||
? $t('INTEGRATION_SETTINGS.DASHBOARD_APPS.FORM.TITLE_ERROR')
|
||||
: null
|
||||
"
|
||||
data-testid="app-title"
|
||||
@input="$v.app.title.$touch"
|
||||
/>
|
||||
<woot-input
|
||||
v-model.trim="app.content.url"
|
||||
:class="{ error: $v.app.content.url.$error }"
|
||||
class="medium-12 columns app--url_input"
|
||||
:label="$t('INTEGRATION_SETTINGS.DASHBOARD_APPS.FORM.URL_LABEL')"
|
||||
:placeholder="
|
||||
$t('INTEGRATION_SETTINGS.DASHBOARD_APPS.FORM.URL_PLACEHOLDER')
|
||||
"
|
||||
:error="
|
||||
$v.app.content.url.$error
|
||||
? $t('INTEGRATION_SETTINGS.DASHBOARD_APPS.FORM.URL_ERROR')
|
||||
: null
|
||||
"
|
||||
data-testid="app-url"
|
||||
@input="$v.app.content.url.$touch"
|
||||
/>
|
||||
<div class="modal-footer">
|
||||
<div class="medium-12 columns">
|
||||
<woot-button
|
||||
:is-loading="isLoading"
|
||||
:is-disabled="$v.$invalid"
|
||||
data-testid="label-submit"
|
||||
>
|
||||
{{ submitButtonLabel }}
|
||||
</woot-button>
|
||||
<woot-button class="button clear" @click.prevent="closeModal">
|
||||
{{ $t('INTEGRATION_SETTINGS.DASHBOARD_APPS.CREATE.FORM_CANCEL') }}
|
||||
</woot-button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</woot-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { required, url } from 'vuelidate/lib/validators';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
|
||||
export default {
|
||||
mixins: [alertMixin],
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'create',
|
||||
},
|
||||
selectedAppData: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
validations: {
|
||||
app: {
|
||||
title: { required },
|
||||
content: {
|
||||
type: { required },
|
||||
url: { required, url },
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
app: {
|
||||
title: '',
|
||||
content: {
|
||||
type: 'frame',
|
||||
url: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
header() {
|
||||
return this.$t(`INTEGRATION_SETTINGS.DASHBOARD_APPS.${this.mode}.HEADER`);
|
||||
},
|
||||
submitButtonLabel() {
|
||||
return this.$t(
|
||||
`INTEGRATION_SETTINGS.DASHBOARD_APPS.${this.mode}.FORM_SUBMIT`
|
||||
);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (this.mode === 'UPDATE' && this.selectedAppData) {
|
||||
this.app.title = this.selectedAppData.title;
|
||||
this.app.content = this.selectedAppData.content[0];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
closeModal() {
|
||||
// Reset the data once closed
|
||||
this.app = {
|
||||
title: '',
|
||||
content: { type: 'frame', url: '' },
|
||||
};
|
||||
this.$emit('close');
|
||||
},
|
||||
async submit() {
|
||||
try {
|
||||
this.$v.$touch();
|
||||
if (this.$v.$invalid) {
|
||||
return;
|
||||
}
|
||||
|
||||
const action = this.mode.toLowerCase();
|
||||
const payload = {
|
||||
title: this.app.title,
|
||||
content: [this.app.content],
|
||||
};
|
||||
|
||||
if (action === 'update') {
|
||||
payload.id = this.selectedAppData.id;
|
||||
}
|
||||
|
||||
this.isLoading = true;
|
||||
await this.$store.dispatch(`dashboardApps/${action}`, payload);
|
||||
this.showAlert(
|
||||
this.$t(
|
||||
`INTEGRATION_SETTINGS.DASHBOARD_APPS.${this.mode}.API_SUCCESS`
|
||||
)
|
||||
);
|
||||
this.closeModal();
|
||||
} catch (err) {
|
||||
this.showAlert(
|
||||
this.$t(`INTEGRATION_SETTINGS.DASHBOARD_APPS.${this.mode}.API_ERROR`)
|
||||
);
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
.app--url_input {
|
||||
flex: 1;
|
||||
}
|
||||
.app--url_add_btn {
|
||||
margin-left: var(--space-one);
|
||||
margin-top: var(--space-one);
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,45 @@
|
|||
<template>
|
||||
<tr>
|
||||
<td>{{ app.title }}</td>
|
||||
<td>{{ app.content[0].url }}</td>
|
||||
<td class="button-wrapper">
|
||||
<woot-button
|
||||
v-tooltip.top="
|
||||
$t('INTEGRATION_SETTINGS.DASHBOARD_APPS.LIST.EDIT_TOOLTIP')
|
||||
"
|
||||
variant="smooth"
|
||||
size="tiny"
|
||||
color-scheme="secondary"
|
||||
class-names="grey-btn"
|
||||
icon="edit"
|
||||
@click="$emit('edit', app)"
|
||||
/>
|
||||
<woot-button
|
||||
v-tooltip.top="
|
||||
$t('INTEGRATION_SETTINGS.DASHBOARD_APPS.LIST.DELETE_TOOLTIP')
|
||||
"
|
||||
variant="smooth"
|
||||
color-scheme="alert"
|
||||
size="tiny"
|
||||
icon="dismiss-circle"
|
||||
class-names="grey-btn"
|
||||
@click="$emit('delete', app)"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
app: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,158 @@
|
|||
<template>
|
||||
<div class="row content-box full-height">
|
||||
<woot-button
|
||||
color-scheme="success"
|
||||
class-names="button--fixed-right-top"
|
||||
icon="add-circle"
|
||||
@click="openCreatePopup"
|
||||
>
|
||||
{{ $t('INTEGRATION_SETTINGS.DASHBOARD_APPS.HEADER_BTN_TXT') }}
|
||||
</woot-button>
|
||||
<div class="row">
|
||||
<div class="small-8 columns with-right-space ">
|
||||
<p
|
||||
v-if="!uiFlags.isFetching && !records.length"
|
||||
class="no-items-error-message"
|
||||
>
|
||||
{{ $t('INTEGRATION_SETTINGS.DASHBOARD_APPS.LIST.404') }}
|
||||
</p>
|
||||
<woot-loading-state
|
||||
v-if="uiFlags.isFetching"
|
||||
:message="$t('INTEGRATION_SETTINGS.DASHBOARD_APPS.LIST.LOADING')"
|
||||
/>
|
||||
<table v-if="!uiFlags.isFetching && records.length" class="woot-table">
|
||||
<thead>
|
||||
<th
|
||||
v-for="thHeader in $t(
|
||||
'INTEGRATION_SETTINGS.DASHBOARD_APPS.LIST.TABLE_HEADER'
|
||||
)"
|
||||
:key="thHeader"
|
||||
>
|
||||
{{ thHeader }}
|
||||
</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<dashboard-apps-row
|
||||
v-for="(dashboardAppItem, index) in records"
|
||||
:key="dashboardAppItem.id"
|
||||
:index="index"
|
||||
:app="dashboardAppItem"
|
||||
@edit="editApp"
|
||||
@delete="openDeletePopup"
|
||||
/>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="small-4 columns">
|
||||
<span
|
||||
v-dompurify-html="
|
||||
useInstallationName(
|
||||
$t('INTEGRATION_SETTINGS.DASHBOARD_APPS.SIDEBAR_TXT'),
|
||||
globalConfig.installationName
|
||||
)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<dashboard-app-modal
|
||||
v-if="showDashboardAppPopup"
|
||||
:show="showDashboardAppPopup"
|
||||
:mode="mode"
|
||||
:selected-app-data="selectedApp"
|
||||
@close="toggleDashboardAppPopup"
|
||||
/>
|
||||
|
||||
<woot-delete-modal
|
||||
:show.sync="showDeleteConfirmationPopup"
|
||||
:on-close="closeDeletePopup"
|
||||
:on-confirm="confirmDeletion"
|
||||
:title="$t('INTEGRATION_SETTINGS.DASHBOARD_APPS.DELETE.TITLE')"
|
||||
:message="
|
||||
$t('INTEGRATION_SETTINGS.DASHBOARD_APPS.DELETE.MESSAGE', {
|
||||
appName: selectedApp.title,
|
||||
})
|
||||
"
|
||||
:confirm-text="
|
||||
$t('INTEGRATION_SETTINGS.DASHBOARD_APPS.DELETE.CONFIRM_YES')
|
||||
"
|
||||
:reject-text="$t('INTEGRATION_SETTINGS.DASHBOARD_APPS.DELETE.CONFIRM_NO')"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import DashboardAppModal from './DashboardAppModal.vue';
|
||||
import DashboardAppsRow from './DashboardAppsRow.vue';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import globalConfigMixin from 'shared/mixins/globalConfigMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DashboardAppModal,
|
||||
DashboardAppsRow,
|
||||
},
|
||||
mixins: [alertMixin, globalConfigMixin],
|
||||
data() {
|
||||
return {
|
||||
loading: {},
|
||||
showDashboardAppPopup: false,
|
||||
showDeleteConfirmationPopup: false,
|
||||
selectedApp: {},
|
||||
mode: 'CREATE',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
globalConfig: 'globalConfig/get',
|
||||
records: 'dashboardApps/getRecords',
|
||||
uiFlags: 'dashboardApps/getUIFlags',
|
||||
}),
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('dashboardApps/get');
|
||||
},
|
||||
methods: {
|
||||
toggleDashboardAppPopup() {
|
||||
this.showDashboardAppPopup = !this.showDashboardAppPopup;
|
||||
this.selectedApp = {};
|
||||
},
|
||||
openDeletePopup(response) {
|
||||
this.showDeleteConfirmationPopup = true;
|
||||
this.selectedApp = response;
|
||||
},
|
||||
openCreatePopup() {
|
||||
this.mode = 'CREATE';
|
||||
this.selectedApp = {};
|
||||
this.showDashboardAppPopup = true;
|
||||
},
|
||||
closeDeletePopup() {
|
||||
this.showDeleteConfirmationPopup = false;
|
||||
},
|
||||
editApp(app) {
|
||||
this.loading[app.id] = true;
|
||||
this.mode = 'UPDATE';
|
||||
this.selectedApp = app;
|
||||
this.showDashboardAppPopup = true;
|
||||
},
|
||||
confirmDeletion() {
|
||||
this.loading[this.selectedApp.id] = true;
|
||||
this.closeDeletePopup();
|
||||
this.deleteApp(this.selectedApp.id);
|
||||
},
|
||||
async deleteApp(id) {
|
||||
try {
|
||||
await this.$store.dispatch('dashboardApps/delete', id);
|
||||
this.showAlert(
|
||||
this.$t('INTEGRATION_SETTINGS.DASHBOARD_APPS.DELETE.API_SUCCESS')
|
||||
);
|
||||
} catch (error) {
|
||||
this.showAlert(
|
||||
this.$t('INTEGRATION_SETTINGS.DASHBOARD_APPS.DELETE.API_ERROR')
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -17,6 +17,20 @@
|
|||
:integration-action="item.action"
|
||||
/>
|
||||
</div>
|
||||
<div class="small-12 columns integration">
|
||||
<integration
|
||||
integration-id="dashboard-apps"
|
||||
integration-logo="dashboard-apps.svg"
|
||||
:integration-name="
|
||||
$t('INTEGRATION_SETTINGS.DASHBOARD_APPS.TITLE')
|
||||
"
|
||||
:integration-description="
|
||||
$t('INTEGRATION_SETTINGS.DASHBOARD_APPS.DESCRIPTION')
|
||||
"
|
||||
integration-enabled
|
||||
integration-action="/dashboard-apps"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import Index from './Index';
|
||||
import SettingsContent from '../Wrapper';
|
||||
import Webhook from './Webhooks/Index';
|
||||
import DashboardApps from './DashboardApps/Index';
|
||||
import ShowIntegration from './ShowIntegration';
|
||||
import { frontendURL } from '../../../../helper/URLHelper';
|
||||
|
||||
|
@ -35,6 +36,12 @@ export default {
|
|||
name: 'settings_integrations_webhook',
|
||||
roles: ['administrator'],
|
||||
},
|
||||
{
|
||||
path: 'dashboard-apps',
|
||||
component: DashboardApps,
|
||||
name: 'settings_integrations_dashboard_apps',
|
||||
roles: ['administrator'],
|
||||
},
|
||||
{
|
||||
path: ':integration_id',
|
||||
name: 'settings_integrations_integration',
|
||||
|
|
|
@ -32,6 +32,40 @@ export const actions = {
|
|||
commit(types.SET_DASHBOARD_APPS_UI_FLAG, { isFetching: false });
|
||||
}
|
||||
},
|
||||
create: async function createApp({ commit }, appObj) {
|
||||
commit(types.SET_DASHBOARD_APPS_UI_FLAG, { isCreating: true });
|
||||
try {
|
||||
const response = await DashboardAppsAPI.create(appObj);
|
||||
commit(types.CREATE_DASHBOARD_APP, response.data);
|
||||
} catch (error) {
|
||||
const errorMessage = error?.response?.data?.message;
|
||||
throw new Error(errorMessage);
|
||||
} finally {
|
||||
commit(types.SET_DASHBOARD_APPS_UI_FLAG, { isCreating: false });
|
||||
}
|
||||
},
|
||||
update: async function updateApp({ commit }, { id, ...updateObj }) {
|
||||
commit(types.SET_DASHBOARD_APPS_UI_FLAG, { isUpdating: true });
|
||||
try {
|
||||
const response = await DashboardAppsAPI.update(id, updateObj);
|
||||
commit(types.EDIT_DASHBOARD_APP, response.data);
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
} finally {
|
||||
commit(types.SET_DASHBOARD_APPS_UI_FLAG, { isUpdating: false });
|
||||
}
|
||||
},
|
||||
delete: async function deleteApp({ commit }, id) {
|
||||
commit(types.SET_DASHBOARD_APPS_UI_FLAG, { isDeleting: true });
|
||||
try {
|
||||
await DashboardAppsAPI.delete(id);
|
||||
commit(types.DELETE_DASHBOARD_APP, id);
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
} finally {
|
||||
commit(types.SET_DASHBOARD_APPS_UI_FLAG, { isDeleting: false });
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export const mutations = {
|
||||
|
@ -43,6 +77,9 @@ export const mutations = {
|
|||
},
|
||||
|
||||
[types.SET_DASHBOARD_APPS]: MutationHelpers.set,
|
||||
[types.CREATE_DASHBOARD_APP]: MutationHelpers.create,
|
||||
[types.EDIT_DASHBOARD_APP]: MutationHelpers.update,
|
||||
[types.DELETE_DASHBOARD_APP]: MutationHelpers.destroy,
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import axios from 'axios';
|
||||
import { actions } from '../../dashboardApps';
|
||||
import types from '../../../mutation-types';
|
||||
|
||||
import { payload, automationsList } from './fixtures';
|
||||
const commit = jest.fn();
|
||||
global.axios = axios;
|
||||
jest.mock('axios');
|
||||
|
@ -18,4 +18,68 @@ describe('#actions', () => {
|
|||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#create', () => {
|
||||
it('sends correct actions if API is success', async () => {
|
||||
axios.post.mockResolvedValue({ data: payload });
|
||||
await actions.create({ commit }, payload);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.SET_DASHBOARD_APPS_UI_FLAG, { isCreating: true }],
|
||||
[types.CREATE_DASHBOARD_APP, payload],
|
||||
[types.SET_DASHBOARD_APPS_UI_FLAG, { isCreating: false }],
|
||||
]);
|
||||
});
|
||||
it('sends correct actions if API is error', async () => {
|
||||
axios.post.mockRejectedValue({ message: 'Incorrect header' });
|
||||
await expect(actions.create({ commit })).rejects.toThrow(Error);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.SET_DASHBOARD_APPS_UI_FLAG, { isCreating: true }],
|
||||
[types.SET_DASHBOARD_APPS_UI_FLAG, { isCreating: false }],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#update', () => {
|
||||
it('sends correct actions if API is success', async () => {
|
||||
axios.patch.mockResolvedValue({ data: automationsList[0] });
|
||||
await actions.update({ commit }, automationsList[0]);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.SET_DASHBOARD_APPS_UI_FLAG, { isUpdating: true }],
|
||||
[types.EDIT_DASHBOARD_APP, automationsList[0]],
|
||||
[types.SET_DASHBOARD_APPS_UI_FLAG, { isUpdating: false }],
|
||||
]);
|
||||
});
|
||||
it('sends correct actions if API is error', async () => {
|
||||
axios.patch.mockRejectedValue({ message: 'Incorrect header' });
|
||||
await expect(
|
||||
actions.update({ commit }, automationsList[0])
|
||||
).rejects.toThrow(Error);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.SET_DASHBOARD_APPS_UI_FLAG, { isUpdating: true }],
|
||||
[types.SET_DASHBOARD_APPS_UI_FLAG, { isUpdating: false }],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#delete', () => {
|
||||
it('sends correct actions if API is success', async () => {
|
||||
axios.delete.mockResolvedValue({ data: automationsList[0] });
|
||||
await actions.delete({ commit }, automationsList[0].id);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.SET_DASHBOARD_APPS_UI_FLAG, { isDeleting: true }],
|
||||
[types.DELETE_DASHBOARD_APP, automationsList[0].id],
|
||||
[types.SET_DASHBOARD_APPS_UI_FLAG, { isDeleting: false }],
|
||||
]);
|
||||
});
|
||||
it('sends correct actions if API is error', async () => {
|
||||
axios.delete.mockRejectedValue({ message: 'Incorrect header' });
|
||||
await expect(
|
||||
actions.delete({ commit }, automationsList[0].id)
|
||||
).rejects.toThrow(Error);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.SET_DASHBOARD_APPS_UI_FLAG, { isDeleting: true }],
|
||||
[types.SET_DASHBOARD_APPS_UI_FLAG, { isDeleting: false }],
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
export const payload = {
|
||||
title: 'Test',
|
||||
content: [
|
||||
{ url: 'https://example.com', type: 'frame' },
|
||||
{ url: 'https://chatwoot.com', type: 'frame' },
|
||||
],
|
||||
};
|
||||
|
||||
export const automationsList = [
|
||||
{
|
||||
id: 15,
|
||||
title: 'Test',
|
||||
content: [
|
||||
{ url: 'https://example.com', type: 'frame' },
|
||||
{ url: 'https://chatwoot.com', type: 'frame' },
|
||||
],
|
||||
created_at: '2022-06-27T08:28:29.841Z',
|
||||
},
|
||||
];
|
|
@ -1,5 +1,6 @@
|
|||
import types from '../../../mutation-types';
|
||||
import { mutations } from '../../dashboardApps';
|
||||
import { automationsList } from './fixtures';
|
||||
|
||||
describe('#mutations', () => {
|
||||
describe('#SET_DASHBOARD_APPS_UI_FLAG', () => {
|
||||
|
@ -17,4 +18,31 @@ describe('#mutations', () => {
|
|||
expect(state.records).toEqual([{ title: 'Title 1' }]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#ADD_DASHBOARD_APP', () => {
|
||||
it('push newly created app to the store', () => {
|
||||
const state = { records: [automationsList[0]] };
|
||||
mutations[types.CREATE_DASHBOARD_APP](state, automationsList[1]);
|
||||
expect(state.records).toEqual([automationsList[0], automationsList[1]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#EDIT_DASHBOARD_APP', () => {
|
||||
it('update label record', () => {
|
||||
const state = { records: [automationsList[0]] };
|
||||
mutations[types.EDIT_DASHBOARD_APP](state, {
|
||||
id: 15,
|
||||
title: 'updated-title',
|
||||
});
|
||||
expect(state.records[0].title).toEqual('updated-title');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#DELETE_DASHBOARD_APP', () => {
|
||||
it('delete label record', () => {
|
||||
const state = { records: [automationsList[0]] };
|
||||
mutations[types.DELETE_DASHBOARD_APP](state, 15);
|
||||
expect(state.records).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -217,4 +217,7 @@ export default {
|
|||
// Dashboard Apps
|
||||
SET_DASHBOARD_APPS_UI_FLAG: 'SET_DASHBOARD_APPS_UI_FLAG',
|
||||
SET_DASHBOARD_APPS: 'SET_DASHBOARD_APPS',
|
||||
CREATE_DASHBOARD_APP: 'CREATE_DASHBOARD_APP',
|
||||
EDIT_DASHBOARD_APP: 'EDIT_DASHBOARD_APP',
|
||||
DELETE_DASHBOARD_APP: 'DELETE_DASHBOARD_APP',
|
||||
};
|
||||
|
|
|
@ -1,64 +1,39 @@
|
|||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<path style="fill:#4D4D4D;" d="M188.287,512c-41.473,0-75.213-33.74-75.213-75.213V246.75c0-4.142,3.358-7.5,7.5-7.5
|
||||
s7.5,3.358,7.5,7.5v190.037c0,33.202,27.011,60.213,60.213,60.213c16.082,0,31.204-6.266,42.582-17.644
|
||||
c11.37-11.37,17.631-26.488,17.631-42.569V75.213C248.5,33.74,282.24,0,323.713,0c20.088,0,38.978,7.826,53.189,22.037
|
||||
c14.203,14.202,22.024,33.087,22.024,53.176V256c0,4.142-3.358,7.5-7.5,7.5s-7.5-3.358-7.5-7.5V75.213
|
||||
c0-16.082-6.261-31.2-17.63-42.569C354.918,21.266,339.794,15,323.713,15C290.511,15,263.5,42.011,263.5,75.213v361.574
|
||||
c0,20.088-7.822,38.973-22.024,53.176C227.265,504.174,208.376,512,188.287,512z"/>
|
||||
<g>
|
||||
<rect x="113.07" y="246.75" style="fill:#3B3B3B;" width="15" height="26.875"/>
|
||||
<rect x="383.93" y="235.31" style="fill:#3B3B3B;" width="15" height="26.875"/>
|
||||
<svg width="1142" height="970" viewBox="0 0 1142 970" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1141.84 613.27H1124.39V596H1109.44V613.27H1092V628.566H1109.44V645.836H1124.39V628.566H1141.84V613.27Z" fill="#1F93FF"/>
|
||||
<path d="M263.905 82.1199H238.534V57H216.787V82.1199H191.416V104.369H216.787V129.489H238.534V104.369H263.905V82.1199Z" fill="#1F93FF"/>
|
||||
<path d="M41.9077 453.222H27.24V438.7H14.6677V453.222H0V466.085H14.6677V480.607H27.24V466.085H41.9077V453.222Z" fill="#1F93FF"/>
|
||||
<path d="M1011.02 237.048C1025.95 237.048 1038.05 224.949 1038.05 210.024C1038.05 195.099 1025.95 183 1011.02 183C996.099 183 984 195.099 984 210.024C984 224.949 996.099 237.048 1011.02 237.048Z" fill="#EAEEF9"/>
|
||||
<path d="M834.455 74.9107C844.648 74.9107 852.911 66.6479 852.911 56.4553C852.911 46.2627 844.648 38 834.455 38C824.263 38 816 46.2627 816 56.4553C816 66.6479 824.263 74.9107 834.455 74.9107Z" fill="#EAEEF9"/>
|
||||
<path d="M99.4124 277.995C109.605 277.995 117.868 269.732 117.868 259.54C117.868 249.347 109.605 241.084 99.4124 241.084C89.2198 241.084 80.957 249.347 80.957 259.54C80.957 269.732 89.2198 277.995 99.4124 277.995Z" fill="#EAEEF9"/>
|
||||
<path d="M225.274 932.548C244.203 932.548 259.548 917.203 259.548 898.274C259.548 879.345 244.203 864 225.274 864C206.345 864 191 879.345 191 898.274C191 917.203 206.345 932.548 225.274 932.548Z" fill="#EAEEF9"/>
|
||||
<path d="M1038 508.5C1038 637.502 985.262 753.785 900.7 837.364C817.957 920.035 703.389 970 577 970C451.521 970 336.953 919.126 253.3 837.364C168.738 753.785 116 637.502 116 508.5C116 253.221 322.404 47 577 47C831.596 47 1038 254.13 1038 508.5Z" fill="#EAEEF9"/>
|
||||
<mask id="mask0_422_14" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="97" y="0" width="960" height="962">
|
||||
<path d="M1057 480.947C1057 615.385 1002.09 736.568 914.041 823.669C827.888 909.823 708.598 961.894 577 961.894C446.349 961.894 327.059 908.876 239.959 823.669C151.911 736.568 97 615.385 97 480.947C97 214.911 311.911 0 577 0C842.089 0 1057 215.858 1057 480.947Z" fill="#EAEEF9"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_422_14)">
|
||||
<g filter="url(#filter0_d_422_14)">
|
||||
<path d="M884.279 404.235L891.357 973.972C891.357 993.435 875.432 1008.48 855.969 1008.48H300.387C280.924 1008.48 265 992.551 265 973.972V241.453C265 221.99 280.924 206.951 300.387 206.951H702.919L884.279 404.235Z" fill="url(#paint0_linear_422_14)"/>
|
||||
</g>
|
||||
<rect x="361.9" y="385" style="fill:#CCCCCC;" width="57.983" height="39.944"/>
|
||||
<rect x="361.9" y="385" style="fill:#ADADAD;" width="57.983" height="22.19"/>
|
||||
<path style="fill:#A6E2E3;" d="M432.802,298.678v86.977c0,3.616-2.932,6.548-6.548,6.548h-70.721c-3.617,0-6.548-2.932-6.548-6.548
|
||||
v-87.746c0-23.439,19.239-42.39,42.803-41.899C414.709,256.486,432.802,275.751,432.802,298.678z"/>
|
||||
<rect x="92.11" y="87.06" style="fill:#CCCCCC;" width="57.983" height="36.28"/>
|
||||
<rect x="92.11" y="105.43" style="fill:#ADADAD;" width="57.983" height="17.907"/>
|
||||
<path style="fill:#FFA638;" d="M163.015,126.345v86.977c0,22.927-18.093,42.191-41.015,42.668
|
||||
c-23.564,0.49-42.803-18.461-42.803-41.899v-87.746c0-3.616,2.932-6.548,6.548-6.548l0,0h70.721l0,0
|
||||
C160.083,119.797,163.015,122.729,163.015,126.345z"/>
|
||||
<path style="fill:#7CCBCC;" d="M391.787,256.009c-5.066-0.105-9.93,0.693-14.447,2.236c0.396-0.081,0.781-0.166,1.142-0.257
|
||||
c2.982-0.755,5.201-0.896,7.513-0.85c18.954,0.395,34.375,16.494,34.375,35.888v86.981c0,3.614-2.93,6.544-6.544,6.544H355.53
|
||||
c-3.614,0-6.544-2.93-6.544-6.544l0,0v5.648c0,3.616,2.932,6.548,6.548,6.548h70.721c3.617,0,6.548-2.932,6.548-6.548v-86.977
|
||||
C432.802,275.751,414.709,256.486,391.787,256.009z"/>
|
||||
<path style="fill:#EB7100;" d="M79.527,217.153l-0.23-0.322c0.081,1.261,0.209,2.509,0.399,3.737
|
||||
C79.586,219.444,79.527,218.305,79.527,217.153z"/>
|
||||
<path style="fill:#ED8300;" d="M156.467,119.797h-11.188c2.613,0.858,4.502,3.314,4.502,6.215v90.372
|
||||
c0,19.395-15.42,35.494-34.375,35.888c-0.251,0.005-0.503,0.008-0.753,0.008c-9.651,0-18.405-3.914-24.76-10.236
|
||||
c7.856,8.766,19.342,14.212,32.106,13.947c22.922-0.477,41.015-19.741,41.015-42.668v-86.977
|
||||
C163.015,122.728,160.083,119.797,156.467,119.797z"/>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M702.837 206.844V364.318C702.837 386.435 722.3 404.129 744.418 404.129H884.198" fill="#D5DDEA"/>
|
||||
<path d="M340 752.964C340 709.203 363.75 670.912 398.9 650.221C414.813 640.946 435 652.124 435 670.675C435 679.237 430.488 686.847 423.125 691.128C401.75 703.495 387.5 726.565 387.5 752.964C387.5 796.963 427.4 831.687 473 822.887C506.725 816.228 530 784.596 530 750.11C530 738.457 539.263 729.181 550.9 729.181H669.65C676.063 721.808 685.563 717.29 696.25 717.29C715.963 717.29 731.875 733.224 731.875 752.964C731.875 772.704 715.963 788.639 696.25 788.639C685.8 788.639 676.3 784.12 669.65 776.748H575.125C569.265 805.648 552.89 831.336 529.18 848.827C505.47 866.317 476.116 874.361 446.816 871.398C417.516 868.434 390.361 854.674 370.623 832.789C350.884 810.903 339.97 782.454 340 752.964V752.964ZM681.288 538.916C696.725 538.916 708.363 524.17 704.325 509.187C697.782 483.646 682.93 461.014 662.115 444.864C641.3 428.714 615.707 419.966 589.375 420C565.653 420.019 542.479 427.15 522.839 440.474C503.199 453.798 487.993 472.705 479.178 494.759C470.363 516.814 468.344 541.007 473.381 564.221C478.417 587.435 490.279 608.607 507.438 625.011L451.625 717.765C435.475 721.095 423.125 735.603 423.125 752.964C423.125 772.704 439.038 788.639 458.75 788.639C464.345 788.646 469.863 787.331 474.856 784.802C479.848 782.272 484.174 778.599 487.483 774.081C490.792 769.562 492.99 764.326 493.898 758.798C494.807 753.269 494.401 747.604 492.713 742.262L560.638 629.292C566.575 619.541 563.725 606.698 553.988 600.99C532.613 588.385 518.125 565.315 518.125 538.916C518.125 499.674 550.188 467.566 589.375 467.566C622.15 467.566 649.7 489.685 658.013 519.889C661.1 530.83 670.125 538.916 681.288 538.916V538.916ZM696.25 681.615C687.225 681.615 678.438 683.28 670.363 686.372C660.863 690.177 649.938 685.42 644.713 676.62L582.963 573.877C566.338 571.023 553.75 556.515 553.75 538.916C553.75 519.176 569.663 503.241 589.375 503.241C609.088 503.241 625 519.176 625 538.916C625 542.483 624.525 545.813 623.575 549.143L675.588 635.951C682.238 634.762 689.125 634.049 696.25 634.049C761.8 634.049 815 687.323 815 752.964C815 818.606 761.8 871.88 696.25 871.88C675.825 871.88 656.35 866.648 639.488 857.372C617.638 845.481 625.713 812.422 650.65 812.422C654.688 812.422 658.725 813.611 662.288 815.752C672.263 821.222 683.9 824.314 696.25 824.314C735.438 824.314 767.5 792.207 767.5 752.964C767.5 713.722 735.438 681.615 696.25 681.615V681.615Z" fill="url(#paint1_linear_422_14)"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d_422_14" x="243" y="195.951" width="670.356" height="845.524" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="11"/>
|
||||
<feGaussianBlur stdDeviation="11"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.397708 0 0 0 0 0.47749 0 0 0 0 0.575 0 0 0 0.27 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_422_14"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_422_14" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_422_14" x1="577.974" y1="188.411" x2="577.974" y2="1017.12" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FDFEFF"/>
|
||||
<stop offset="0.9964" stop-color="#ECF0F5"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_422_14" x1="577.5" y1="420" x2="577.5" y2="872" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#2094FF"/>
|
||||
<stop offset="1" stop-color="#53B6FD"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 5.8 KiB |
75
public/dashboard/images/integrations/dashboard-apps.svg
Normal file
75
public/dashboard/images/integrations/dashboard-apps.svg
Normal file
|
@ -0,0 +1,75 @@
|
|||
<svg width="748" height="744" viewBox="0 0 748 744" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M326.92 744.001C507.474 744.001 653.841 597.135 653.841 415.967C653.841 234.799 507.474 87.9326 326.92 87.9326C146.367 87.9326 0 234.799 0 415.967C0 597.135 146.367 744.001 326.92 744.001Z" fill="#EAEEF9"/>
|
||||
<path d="M699.264 140.632C703.555 136.698 703.855 130.018 699.934 125.713C696.013 121.407 689.355 121.106 685.065 125.041C680.774 128.975 680.474 135.655 684.395 139.961C688.316 144.266 694.974 144.567 699.264 140.632Z" fill="#EAEEF9"/>
|
||||
<path opacity="0.3" d="M524.644 264.296C536.27 264.296 545.694 254.839 545.694 243.175C545.694 231.51 536.27 222.054 524.644 222.054C513.019 222.054 503.595 231.51 503.595 243.175C503.595 254.839 513.019 264.296 524.644 264.296Z" fill="#AAB2C5"/>
|
||||
<g filter="url(#filter0_d_415_54)">
|
||||
<path d="M382.773 292.041C380.146 306.049 368.765 319.182 353.881 322.685C342.499 325.311 331.117 322.685 323.237 316.556V418.118H228.679C232.181 411.113 233.057 404.109 232.181 396.229C230.43 378.719 215.546 364.71 198.911 362.959C176.147 360.333 156.01 377.843 156.01 400.607C156.01 406.736 156.886 412.864 159.512 417.242H52.6973V221.998C52.6973 181.724 85.092 149.329 126.242 149.329H322.361V250.891C329.366 246.513 336.37 243.887 344.25 243.887C367.889 247.389 387.151 267.526 382.773 292.041Z" fill="url(#paint0_linear_415_54)"/>
|
||||
</g>
|
||||
<g filter="url(#filter1_d_415_54)">
|
||||
<path d="M259.323 545.944C255.821 569.583 274.207 589.72 297.847 589.72C307.478 589.72 316.233 586.218 323.237 580.965V686.029H127.118C86.8435 686.029 53.5732 652.759 53.5732 613.36V417.241H159.513C156.886 411.987 156.011 406.734 156.011 399.73C156.886 381.344 170.895 365.584 188.405 362.958C212.045 360.331 232.182 377.842 232.182 400.605C232.182 406.734 231.306 411.987 228.68 417.241H321.486V522.304C313.606 515.3 303.1 511.798 291.718 513.549C275.083 515.3 261.95 529.309 259.323 545.944Z" fill="url(#paint1_linear_415_54)"/>
|
||||
</g>
|
||||
<g filter="url(#filter2_d_415_54)">
|
||||
<path d="M592.9 417.24V611.609C592.9 651.883 559.63 684.278 519.356 684.278H323.236V579.214C316.232 585.343 307.477 587.969 297.846 587.969C275.082 587.969 257.571 567.832 259.322 544.193C261.949 526.682 275.958 513.549 291.717 510.922C303.099 510.047 314.481 513.549 321.485 519.678V414.614H434.429C430.927 419.867 430.051 425.996 430.051 432.124C430.051 454.013 449.313 472.399 472.952 469.772C490.463 468.021 505.347 453.137 507.098 436.502C507.974 428.622 506.223 421.618 503.596 414.614L592.9 417.24Z" fill="url(#paint2_linear_415_54)"/>
|
||||
</g>
|
||||
<g filter="url(#filter3_d_415_54)">
|
||||
<path d="M675.2 337.567L588.522 322.683C590.273 329.688 591.149 336.692 588.522 343.696C583.269 360.331 567.509 371.713 549.999 370.838C527.235 369.087 510.6 348.949 514.102 327.061C514.978 320.932 517.604 315.679 521.106 311.301L409.038 291.164L426.549 190.478C433.553 197.482 444.059 201.86 456.317 201.86C472.076 200.984 485.209 191.353 489.587 177.345C498.342 154.581 483.458 130.066 459.819 126.564C451.939 124.813 444.059 126.564 437.055 129.191L454.566 28.5044L647.183 61.7746C687.457 68.7789 713.723 106.427 706.719 145.826L675.2 337.567Z" fill="url(#paint3_linear_415_54)"/>
|
||||
</g>
|
||||
<path d="M717.255 411.396L746.365 402.622C748.473 402.01 748.473 398.95 746.365 398.338L717.255 389.564C716.507 389.36 715.963 388.816 715.759 388.068L706.986 359.027C706.374 356.918 703.313 356.918 702.701 359.027L693.927 388.068C693.723 388.816 693.179 389.36 692.431 389.564L663.39 398.338C661.281 398.95 661.281 402.01 663.39 402.622L692.499 411.396C693.247 411.6 693.791 412.144 693.995 412.892L702.769 442.001C703.381 444.11 706.442 444.11 707.054 442.001L715.827 412.892C715.963 412.144 716.507 411.6 717.255 411.396Z" fill="#1F93FF"/>
|
||||
<path d="M652.853 156.709L689.058 145.797C691.681 145.036 691.681 141.229 689.058 140.468L652.853 129.555C651.923 129.302 651.246 128.625 650.992 127.694L640.08 91.5737C639.318 88.9513 635.512 88.9513 634.75 91.5737L623.838 127.694C623.584 128.625 622.908 129.302 621.977 129.555L585.856 140.468C583.234 141.229 583.234 145.036 585.856 145.797L622.062 156.709C622.992 156.963 623.669 157.64 623.923 158.57L634.835 194.776C635.596 197.398 639.403 197.398 640.164 194.776L651.077 158.57C651.246 157.64 651.923 156.963 652.853 156.709Z" fill="white"/>
|
||||
<path d="M389.665 33.7165L407.858 28.2334C409.176 27.8509 409.176 25.9382 407.858 25.5557L389.665 20.0726C389.197 19.9451 388.857 19.6051 388.73 19.1375L383.246 0.988223C382.864 -0.329408 380.951 -0.329408 380.568 0.988223L375.085 19.1375C374.957 19.6051 374.617 19.9451 374.15 20.0726L355.999 25.5557C354.681 25.9382 354.681 27.8509 355.999 28.2334L374.192 33.7165C374.66 33.844 375 34.184 375.127 34.6516L380.611 52.8433C380.993 54.161 382.906 54.161 383.289 52.8433L388.772 34.6516C388.857 34.184 389.197 33.844 389.665 33.7165Z" fill="#3099F0"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_415_54" x="30.6973" y="138.329" width="374.7" height="312.789" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="11"/>
|
||||
<feGaussianBlur stdDeviation="11"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.397708 0 0 0 0 0.47749 0 0 0 0 0.575 0 0 0 0.27 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_415_54"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_415_54" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter1_d_415_54" x="31.5732" y="351.696" width="313.664" height="367.333" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="11"/>
|
||||
<feGaussianBlur stdDeviation="11"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.397708 0 0 0 0 0.47749 0 0 0 0 0.575 0 0 0 0.27 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_415_54"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_415_54" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter2_d_415_54" x="237.202" y="403.614" width="377.699" height="313.664" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="11"/>
|
||||
<feGaussianBlur stdDeviation="11"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.397708 0 0 0 0 0.47749 0 0 0 0 0.575 0 0 0 0.27 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_415_54"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_415_54" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter3_d_415_54" x="387.038" y="17.5044" width="342.811" height="386.38" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="11"/>
|
||||
<feGaussianBlur stdDeviation="11"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.396078 0 0 0 0 0.478431 0 0 0 0 0.576471 0 0 0 0.25 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_415_54"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_415_54" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_415_54" x1="217.94" y1="143.112" x2="217.94" y2="421.015" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="0.9964" stop-color="#ECF0F5"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_415_54" x1="188.317" y1="355.217" x2="188.317" y2="689.515" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="0.9964" stop-color="#ECF0F5"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_415_54" x1="425.942" y1="408.376" x2="425.942" y2="687.185" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="0.9964" stop-color="#ECF0F5"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_415_54" x1="408.901" y1="199.732" x2="707.903" y2="199.732" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#1F93FF"/>
|
||||
<stop offset="1" stop-color="#56B7FC"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 8.2 KiB |
Loading…
Reference in a new issue