Add resources Task Tag, Space Tag & Task List to ClickUp Node (#1539)

*  Add resources Task Tag and Space Tag to ClickUp Node

*  Add Task List resource

*  Fix spaceTag:update

*  Fix icon and formatting

Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
This commit is contained in:
Ricardo Espinoza 2021-03-24 18:01:12 -04:00 committed by GitHub
parent 80db50282e
commit 0c3a191859
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 706 additions and 163 deletions

View file

@ -100,6 +100,7 @@ export const checklistItemFields = [
}, },
], ],
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* checklistItem:delete */ /* checklistItem:delete */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -137,6 +138,7 @@ export const checklistItemFields = [
}, },
required: true, required: true,
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* checklistItem:update */ /* checklistItem:update */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */

View file

@ -57,6 +57,21 @@ import {
taskOperations, taskOperations,
} from './TaskDescription'; } from './TaskDescription';
import {
taskListFields,
taskListOperations,
} from './TaskListDescription';
import {
taskTagFields,
taskTagOperations,
} from './TaskTagDescription';
import {
spaceTagFields,
spaceTagOperations,
} from './SpaceTagDescription';
import { import {
taskDependencyFields, taskDependencyFields,
taskDependencyOperations, taskDependencyOperations,
@ -91,7 +106,7 @@ export class ClickUp implements INodeType {
description: INodeTypeDescription = { description: INodeTypeDescription = {
displayName: 'ClickUp', displayName: 'ClickUp',
name: 'clickUp', name: 'clickUp',
icon: 'file:clickup.png', icon: 'file:clickup.svg',
group: ['output'], group: ['output'],
version: 1, version: 1,
subtitle: '={{$parameter["operation"] + ":" + $parameter["resource"]}}', subtitle: '={{$parameter["operation"] + ":" + $parameter["resource"]}}',
@ -180,10 +195,22 @@ export class ClickUp implements INodeType {
name: 'List', name: 'List',
value: 'list', value: 'list',
}, },
{
name: 'Space Tag',
value: 'spaceTag',
},
{ {
name: 'Task', name: 'Task',
value: 'task', value: 'task',
}, },
{
name: 'Task List',
value: 'taskList',
},
{
name: 'Task Tag',
value: 'taskTag',
},
{ {
name: 'Task Dependency', name: 'Task Dependency',
value: 'taskDependency', value: 'taskDependency',
@ -221,6 +248,15 @@ export class ClickUp implements INodeType {
// GUEST // GUEST
// ...guestOperations, // ...guestOperations,
// ...guestFields, // ...guestFields,
// TASK TAG
...taskTagOperations,
...taskTagFields,
// TASK LIST
...taskListOperations,
...taskListFields,
// SPACE TAG
...spaceTagOperations,
...spaceTagFields,
// TASK // TASK
...taskOperations, ...taskOperations,
...taskFields, ...taskFields,
@ -1022,6 +1058,40 @@ export class ClickUp implements INodeType {
responseData = { success: true }; responseData = { success: true };
} }
} }
if (resource === 'taskTag') {
if (operation === 'add') {
const taskId = this.getNodeParameter('taskId', i) as string;
const name = this.getNodeParameter('tagName', i) as string;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
const qs: IDataObject = {};
Object.assign(qs, additionalFields);
responseData = await clickupApiRequest.call(this, 'POST', `/task/${taskId}/tag/${name}`, {}, qs);
responseData = { success: true };
}
if (operation === 'remove') {
const taskId = this.getNodeParameter('taskId', i) as string;
const name = this.getNodeParameter('tagName', i) as string;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
const qs: IDataObject = {};
Object.assign(qs, additionalFields);
responseData = await clickupApiRequest.call(this, 'DELETE', `/task/${taskId}/tag/${name}`, {}, qs);
responseData = { success: true };
}
}
if (resource === 'taskList') {
if (operation === 'add') {
const taskId = this.getNodeParameter('taskId', i) as string;
const listId = this.getNodeParameter('listId', i) as string;
responseData = await clickupApiRequest.call(this, 'POST', `/list/${listId}/task/${taskId}`);
responseData = { success: true };
}
if (operation === 'remove') {
const taskId = this.getNodeParameter('taskId', i) as string;
const listId = this.getNodeParameter('listId', i) as string;
responseData = await clickupApiRequest.call(this, 'DELETE', `/list/${listId}/task/${taskId}`);
responseData = { success: true };
}
}
if (resource === 'taskDependency') { if (resource === 'taskDependency') {
if (operation === 'create') { if (operation === 'create') {
const taskId = this.getNodeParameter('task', i) as string; const taskId = this.getNodeParameter('task', i) as string;
@ -1195,6 +1265,55 @@ export class ClickUp implements INodeType {
} }
} }
if (resource === 'spaceTag') {
if (operation === 'create') {
const spaceId = this.getNodeParameter('space', i) as string;
const name = this.getNodeParameter('name', i) as string;
const foregroundColor = this.getNodeParameter('foregroundColor', i) as string;
const backgroundColor = this.getNodeParameter('backgroundColor', i) as string;
const body: IDataObject = {
tag: {
name,
tag_bg: backgroundColor,
tag_fg: foregroundColor,
},
};
responseData = await clickupApiRequest.call(this, 'POST', `/space/${spaceId}/tag`, body);
responseData = { success: true };
}
if (operation === 'delete') {
const spaceId = this.getNodeParameter('space', i) as string;
const name = this.getNodeParameter('name', i) as string;
responseData = await clickupApiRequest.call(this, 'DELETE', `/space/${spaceId}/tag/${name}`);
responseData = { success: true };
}
if (operation === 'getAll') {
const spaceId = this.getNodeParameter('space', i) as string;
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
responseData = await clickupApiRequest.call(this, 'GET', `/space/${spaceId}/tag`);
responseData = responseData.tags;
if (returnAll === false) {
const limit = this.getNodeParameter('limit', i) as number;
responseData = responseData.splice(0, limit);
}
}
if (operation === 'update') {
const spaceId = this.getNodeParameter('space', i) as string;
const tagName = this.getNodeParameter('name', i) as string;
const newTagName = this.getNodeParameter('newName', i) as string;
const foregroundColor = this.getNodeParameter('foregroundColor', i) as string;
const backgroundColor = this.getNodeParameter('backgroundColor', i) as string;
const body: IDataObject = {
tag: {
name: newTagName,
tag_bg: backgroundColor,
tag_fg: foregroundColor,
},
};
await clickupApiRequest.call(this, 'PUT', `/space/${spaceId}/tag/${tagName}`, body);
responseData = { success: true };
}
}
if (resource === 'list') { if (resource === 'list') {
if (operation === 'create') { if (operation === 'create') {
const spaceId = this.getNodeParameter('space', i) as string; const spaceId = this.getNodeParameter('space', i) as string;

View file

@ -16,13 +16,15 @@ import {
clickupApiRequest, clickupApiRequest,
} from './GenericFunctions'; } from './GenericFunctions';
import { createHmac } from 'crypto'; import {
createHmac,
} from 'crypto';
export class ClickUpTrigger implements INodeType { export class ClickUpTrigger implements INodeType {
description: INodeTypeDescription = { description: INodeTypeDescription = {
displayName: 'ClickUp Trigger', displayName: 'ClickUp Trigger',
name: 'clickUpTrigger', name: 'clickUpTrigger',
icon: 'file:clickup.png', icon: 'file:clickup.svg',
group: ['trigger'], group: ['trigger'],
version: 1, version: 1,
description: 'Handle ClickUp events via webhooks (Beta)', description: 'Handle ClickUp events via webhooks (Beta)',

View file

@ -141,6 +141,7 @@ export const commentFields = [
}, },
], ],
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* comment:delete */ /* comment:delete */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -161,6 +162,7 @@ export const commentFields = [
}, },
required: true, required: true,
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* comment:getAll */ /* comment:getAll */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -232,6 +234,7 @@ export const commentFields = [
default: 50, default: 50,
description: 'How many results to return.', description: 'How many results to return.',
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* comment:update */ /* comment:update */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */

View file

@ -111,6 +111,7 @@ export const folderFields = [
}, },
required: true, required: true,
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* folder:delete */ /* folder:delete */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -180,6 +181,7 @@ export const folderFields = [
}, },
required: true, required: true,
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* folder:get */ /* folder:get */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -249,6 +251,7 @@ export const folderFields = [
}, },
required: true, required: true,
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* folder:getAll */ /* folder:getAll */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -341,6 +344,7 @@ export const folderFields = [
}, },
], ],
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* folder:update */ /* folder:update */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */

View file

@ -140,6 +140,7 @@ export const goalFields = [
}, },
], ],
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* goal:delete */ /* goal:delete */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -160,6 +161,7 @@ export const goalFields = [
}, },
required: true, required: true,
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* goal:get */ /* goal:get */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -180,6 +182,7 @@ export const goalFields = [
}, },
required: true, required: true,
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* goal:getAll */ /* goal:getAll */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -224,6 +227,7 @@ export const goalFields = [
default: 50, default: 50,
description: 'How many results to return.', description: 'How many results to return.',
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* goal:update */ /* goal:update */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */

View file

@ -178,6 +178,7 @@ export const goalKeyResultFields = [
}, },
], ],
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* goalKeyResult:delete */ /* goalKeyResult:delete */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -198,6 +199,7 @@ export const goalKeyResultFields = [
}, },
required: true, required: true,
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* goalKeyResult:update */ /* goalKeyResult:update */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */

View file

@ -119,6 +119,7 @@ export const guestFields = [
}, },
], ],
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* guest:delete */ /* guest:delete */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -159,6 +160,7 @@ export const guestFields = [
}, },
required: true, required: true,
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* guest:get */ /* guest:get */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -199,6 +201,7 @@ export const guestFields = [
}, },
required: true, required: true,
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* guest:update */ /* guest:update */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */

View file

@ -233,6 +233,7 @@ export const listFields = [
}, },
], ],
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* list:member */ /* list:member */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -436,6 +437,7 @@ export const listFields = [
}, },
required: true, required: true,
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* list:delete */ /* list:delete */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -542,6 +544,7 @@ export const listFields = [
}, },
required: true, required: true,
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* list:get */ /* list:get */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -648,6 +651,7 @@ export const listFields = [
}, },
required: true, required: true,
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* list:getAll */ /* list:getAll */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -783,6 +787,7 @@ export const listFields = [
}, },
], ],
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* list:update */ /* list:update */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */

View file

@ -0,0 +1,204 @@
import {
INodeProperties,
} from 'n8n-workflow';
export const spaceTagOperations = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'spaceTag',
],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a space tag',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a space tag',
},
{
name: 'Get All',
value: 'getAll',
description: 'Get all space tags',
},
{
name: 'Update',
value: 'update',
description: 'Update a space tag',
},
],
default: 'create',
description: 'The operation to perform.',
},
] as INodeProperties[];
export const spaceTagFields = [
/* -------------------------------------------------------------------------- */
/* spaceTag:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'Space ID',
name: 'space',
type: 'string',
default: '',
displayOptions: {
show: {
resource: [
'spaceTag',
],
operation: [
'create',
'delete',
'getAll',
'update',
],
},
},
required: true,
},
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
displayOptions: {
show: {
resource: [
'spaceTag',
],
operation: [
'create',
],
},
},
required: true,
},
{
displayName: 'Name',
name: 'name',
type: 'options',
typeOptions: {
loadOptionsDependsOn: [
'space',
],
loadOptionsMethod: 'getTags',
},
default: '',
displayOptions: {
show: {
resource: [
'spaceTag',
],
operation: [
'delete',
'update',
],
},
},
required: true,
},
{
displayName: 'New Name',
name: 'newName',
type: 'string',
description: 'New name to set for the tag.',
default: '',
displayOptions: {
show: {
resource: [
'spaceTag',
],
operation: [
'update',
],
},
},
required: true,
},
{
displayName: 'Foreground Color',
name: 'foregroundColor',
type: 'color',
default: '#000000',
displayOptions: {
show: {
resource: [
'spaceTag',
],
operation: [
'create',
'update',
],
},
},
required: true,
},
{
displayName: 'Background Color',
name: 'backgroundColor',
type: 'color',
default: '#000000',
displayOptions: {
show: {
resource: [
'spaceTag',
],
operation: [
'create',
'update',
],
},
},
required: true,
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: [
'spaceTag',
],
operation: [
'getAll',
],
},
},
default: true,
description: 'If all results should be returned or only up to a given limit.',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
resource: [
'spaceTag',
],
operation: [
'getAll',
],
returnAll: [
false,
],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 50,
description: 'How many results to return.',
},
] as INodeProperties[];

View file

@ -69,6 +69,7 @@ export const taskDependencyFields = [
}, },
required: true, required: true,
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* taskDependency:delete */ /* taskDependency:delete */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */

View file

@ -352,6 +352,7 @@ export const taskFields = [
}, },
], ],
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* task:update */ /* task:update */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -489,6 +490,7 @@ export const taskFields = [
], ],
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* task:get */ /* task:get */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -510,6 +512,7 @@ export const taskFields = [
}, },
description: 'Task ID', description: 'Task ID',
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* task:getAll */ /* task:getAll */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -920,6 +923,7 @@ export const taskFields = [
}, },
], ],
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* task:delete */ /* task:delete */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -941,6 +945,7 @@ export const taskFields = [
}, },
description: 'task ID', description: 'task ID',
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* task:member */ /* task:member */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -1003,6 +1008,7 @@ export const taskFields = [
default: 50, default: 50,
description: 'How many results to return.', description: 'How many results to return.',
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* task:setCustomField */ /* task:setCustomField */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */

View file

@ -0,0 +1,74 @@
import {
INodeProperties,
} from 'n8n-workflow';
export const taskListOperations = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'taskList',
],
},
},
options: [
{
name: 'Add',
value: 'add',
description: 'Add a task to a list',
},
{
name: 'Remove',
value: 'remove',
description: 'Remove a task from a list',
},
],
default: 'add',
description: 'The operation to perform.',
},
] as INodeProperties[];
export const taskListFields = [
/* -------------------------------------------------------------------------- */
/* taskList:add */
/* -------------------------------------------------------------------------- */
{
displayName: 'Task ID',
name: 'taskId',
type: 'string',
default: '',
displayOptions: {
show: {
resource: [
'taskList',
],
operation: [
'remove',
'add',
],
},
},
required: true,
},
{
displayName: 'List ID',
name: 'listId',
type: 'string',
default: '',
displayOptions: {
show: {
resource: [
'taskList',
],
operation: [
'remove',
'add',
],
},
},
required: true,
},
] as INodeProperties[];

View file

@ -0,0 +1,111 @@
import {
INodeProperties,
} from 'n8n-workflow';
export const taskTagOperations = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'taskTag',
],
},
},
options: [
{
name: 'Add',
value: 'add',
description: 'Add a tag to a task',
},
{
name: 'Remove',
value: 'remove',
description: 'Remove a tag from a task',
},
],
default: 'add',
description: 'The operation to perform.',
},
] as INodeProperties[];
export const taskTagFields = [
/* -------------------------------------------------------------------------- */
/* taskTag:add */
/* -------------------------------------------------------------------------- */
{
displayName: 'Task ID',
name: 'taskId',
type: 'string',
default: '',
displayOptions: {
show: {
resource: [
'taskTag',
],
operation: [
'remove',
'add',
],
},
},
required: true,
},
{
displayName: 'Tag Name',
name: 'tagName',
type: 'string',
default: '',
displayOptions: {
show: {
resource: [
'taskTag',
],
operation: [
'remove',
'add',
],
},
},
required: true,
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'taskTag',
],
operation: [
'remove',
'add',
],
},
},
options: [
{
displayName: 'Custom Task IDs',
name: 'custom_task_ids',
type: 'boolean',
default: false,
description: `If you want to reference a task by it's custom task id, this value must be true`,
},
{
displayName: 'Team ID',
name: 'team_id',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getTeams',
},
default: '',
description: `Only used when the parameter is set to custom_task_ids=true`,
},
],
},
] as INodeProperties[];

View file

@ -102,6 +102,7 @@ export const timeEntryTagFields = [
default: 5, default: 5,
description: 'How many results to return.', description: 'How many results to return.',
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* timeEntryTag:add */ /* timeEntryTag:add */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -188,6 +189,7 @@ export const timeEntryTagFields = [
}, },
], ],
}, },
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* timeEntryTag:remove */ /* timeEntryTag:remove */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1 @@
<svg width="130" height="155" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="0%" y1="68.01%" y2="68.01%" id="a"><stop stop-color="#8930FD" offset="0%"/><stop stop-color="#49CCF9" offset="100%"/></linearGradient><linearGradient x1="0%" y1="68.01%" y2="68.01%" id="b"><stop stop-color="#FF02F0" offset="0%"/><stop stop-color="#FFC800" offset="100%"/></linearGradient></defs><g fill-rule="nonzero" fill="none"><path d="M.4 119.12l23.81-18.24C36.86 117.39 50.3 125 65.26 125c14.88 0 27.94-7.52 40.02-23.9l24.15 17.8C112 142.52 90.34 155 65.26 155c-25 0-46.87-12.4-64.86-35.88z" fill="url(#a)"/><path fill="url(#b)" d="M65.18 39.84L22.8 76.36 3.21 53.64 65.27.16l61.57 53.52-19.68 22.64z"/></g></svg>

After

Width:  |  Height:  |  Size: 709 B