mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-13 13:17:45 +02:00
Add Task Kanban and States
Add Task Kanban and States Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
@@ -12,7 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import type { Attachment } from '@anticrm/chunter'
|
||||
import chunter from '@anticrm/chunter'
|
||||
@@ -32,7 +31,9 @@
|
||||
let attachments: Attachment[] = []
|
||||
|
||||
const query = createQuery()
|
||||
$: query.query(chunter.class.Attachment, { attachedTo: objectId }, result => { attachments = result })
|
||||
$: query.query(chunter.class.Attachment, { attachedTo: objectId }, (result) => {
|
||||
attachments = result
|
||||
})
|
||||
|
||||
let inputFile: HTMLInputElement
|
||||
let loading = 0
|
||||
@@ -84,17 +85,37 @@
|
||||
<div class="flex-row-center">
|
||||
<span class="title">Attachments</span>
|
||||
{#if loading}
|
||||
<Spinner/>
|
||||
<Spinner />
|
||||
{:else}
|
||||
<CircleButton icon={IconAdd} size={'small'} on:click={ () => { inputFile.click() } } />
|
||||
<CircleButton
|
||||
icon={IconAdd}
|
||||
size={'small'}
|
||||
on:click={() => {
|
||||
inputFile.click()
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
<input bind:this={inputFile} multiple type="file" name="file" id="file" style="display: none" on:change={fileSelected}/>
|
||||
<input
|
||||
bind:this={inputFile}
|
||||
multiple
|
||||
type="file"
|
||||
name="file"
|
||||
id="file"
|
||||
style="display: none"
|
||||
on:change={fileSelected}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if attachments.length === 0 && !loading}
|
||||
<div class="flex-col-center mt-5 zone-container" class:solid={dragover}
|
||||
on:dragover|preventDefault={ () => { dragover = true } }
|
||||
on:dragleave={ () => { dragover = false } }
|
||||
<div
|
||||
class="flex-col-center mt-5 zone-container"
|
||||
class:solid={dragover}
|
||||
on:dragover|preventDefault={() => {
|
||||
dragover = true
|
||||
}}
|
||||
on:dragleave={() => {
|
||||
dragover = false
|
||||
}}
|
||||
on:drop|preventDefault|stopPropagation={fileDrop}
|
||||
>
|
||||
<UploadDuo size={'large'} />
|
||||
@@ -106,11 +127,11 @@
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<Table
|
||||
<Table
|
||||
_class={chunter.class.Attachment}
|
||||
config={['', 'lastModified']}
|
||||
options={ {} }
|
||||
query={ { attachedTo: objectId } }
|
||||
options={{}}
|
||||
query={{ attachedTo: objectId }}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -121,7 +142,7 @@
|
||||
flex-direction: column;
|
||||
|
||||
.title {
|
||||
margin-right: .75rem;
|
||||
margin-right: 0.75rem;
|
||||
font-weight: 500;
|
||||
font-size: 1.25rem;
|
||||
color: var(--theme-caption-color);
|
||||
@@ -131,8 +152,8 @@
|
||||
.zone-container {
|
||||
padding: 1rem;
|
||||
color: var(--theme-caption-color);
|
||||
background: rgba(255, 255, 255, .03);
|
||||
border: 1px dashed rgba(255, 255, 255, .16);
|
||||
border-radius: .75rem;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border: 1px dashed rgba(255, 255, 255, 0.16);
|
||||
border-radius: 0.75rem;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -12,15 +12,14 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { IconFolder, EditBox, ToggleWithLabel, Grid } from '@anticrm/ui'
|
||||
|
||||
import core, { generateId, Ref } from '@anticrm/core'
|
||||
import { getClient, SpaceCreateCard } from '@anticrm/presentation'
|
||||
|
||||
import { Project } from '@anticrm/task'
|
||||
import { EditBox, Grid, IconFolder, ToggleWithLabel } from '@anticrm/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import task from '../plugin'
|
||||
import core from '@anticrm/core'
|
||||
import { createProjectKanban } from '../utils'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@@ -33,24 +32,36 @@
|
||||
|
||||
const client = getClient()
|
||||
|
||||
function createProject () {
|
||||
client.createDoc(task.class.Project, core.space.Model, {
|
||||
name,
|
||||
description,
|
||||
private: false,
|
||||
members: []
|
||||
async function createProject (): Promise<void> {
|
||||
const id: Ref<Project> = generateId()
|
||||
await client.createDoc(
|
||||
task.class.Project,
|
||||
core.space.Model,
|
||||
{
|
||||
name,
|
||||
description,
|
||||
private: false,
|
||||
members: []
|
||||
},
|
||||
id
|
||||
)
|
||||
|
||||
await createProjectKanban(id, async (_class, space, data, id) => {
|
||||
await client.createDoc(_class, space, data, id)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<SpaceCreateCard
|
||||
label={task.string.CreateProject}
|
||||
label={task.string.CreateProject}
|
||||
okAction={createProject}
|
||||
canSave={name.length > 0}
|
||||
on:close={() => { dispatch('close') }}
|
||||
on:close={() => {
|
||||
dispatch('close')
|
||||
}}
|
||||
>
|
||||
<Grid column={1} rowGap={1.5}>
|
||||
<EditBox label={task.string.ProjectName} icon={IconFolder} bind:value={name} placeholder={'Project name'} focus/>
|
||||
<ToggleWithLabel label={task.string.MakePrivate} description={task.string.MakePrivateDescription}/>
|
||||
<EditBox label={task.string.ProjectName} icon={IconFolder} bind:value={name} placeholder={'Project name'} focus />
|
||||
<ToggleWithLabel label={task.string.MakePrivate} description={task.string.MakePrivateDescription} />
|
||||
</Grid>
|
||||
</SpaceCreateCard>
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import contact, { Employee, EmployeeAccount } from '@anticrm/contact'
|
||||
import type { Data, Ref, Space } from '@anticrm/core'
|
||||
@@ -31,14 +30,14 @@
|
||||
const status: Status = OK
|
||||
|
||||
let assignee: Ref<EmployeeAccount> // | null = null
|
||||
|
||||
|
||||
const object: Data<Task> = {
|
||||
name: '',
|
||||
description: '',
|
||||
assignee: undefined as unknown as Ref<Employee>,
|
||||
number: 0
|
||||
}
|
||||
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const client = getClient()
|
||||
const taskId = generateId()
|
||||
@@ -52,11 +51,17 @@
|
||||
if (sequence === undefined) {
|
||||
throw new Error('sequence object not found')
|
||||
}
|
||||
|
||||
const incResult = await client.updateDoc(view.class.Sequence, view.space.Sequence, sequence._id, {
|
||||
$inc: { sequence: 1 }
|
||||
}, true)
|
||||
|
||||
|
||||
const incResult = await client.updateDoc(
|
||||
view.class.Sequence,
|
||||
view.space.Sequence,
|
||||
sequence._id,
|
||||
{
|
||||
$inc: { sequence: 1 }
|
||||
},
|
||||
true
|
||||
)
|
||||
|
||||
const value: Data<Task> = {
|
||||
name: object.name,
|
||||
description: object.description,
|
||||
@@ -71,32 +76,50 @@
|
||||
|
||||
<!-- <DialogHeader {space} {object} {newValue} {resume} create={true} on:save={createCandidate}/> -->
|
||||
|
||||
<Card label={task.string.CreateTask}
|
||||
okAction={createTask}
|
||||
canSave={object.name.length > 0 && assignee !== undefined}
|
||||
spaceClass={task.class.Project}
|
||||
spaceLabel={task.string.ProjectName}
|
||||
spacePlaceholder={task.string.SelectProject}
|
||||
bind:space={_space}
|
||||
on:close={() => { dispatch('close') }}>
|
||||
<StatusControl slot="error" {status} />
|
||||
<Grid column={1} rowGap={1.5}>
|
||||
<EditBox label={task.string.TaskName} bind:value={object.name} icon={task.icon.Task} placeholder="The boring task" maxWidth="39rem" focus/>
|
||||
<UserBox _class={contact.class.EmployeeAccount} title='Assignee *' caption='Assign this task' bind:value={assignee} />
|
||||
</Grid>
|
||||
<Card
|
||||
label={task.string.CreateTask}
|
||||
okAction={createTask}
|
||||
canSave={object.name.length > 0 && assignee !== undefined}
|
||||
spaceClass={task.class.Project}
|
||||
spaceLabel={task.string.ProjectName}
|
||||
spacePlaceholder={task.string.SelectProject}
|
||||
bind:space={_space}
|
||||
on:close={() => {
|
||||
dispatch('close')
|
||||
}}
|
||||
>
|
||||
<StatusControl slot="error" {status} />
|
||||
<Grid column={1} rowGap={1.5}>
|
||||
<EditBox
|
||||
label={task.string.TaskName}
|
||||
bind:value={object.name}
|
||||
icon={task.icon.Task}
|
||||
placeholder="The boring task"
|
||||
maxWidth="39rem"
|
||||
focus
|
||||
/>
|
||||
<UserBox
|
||||
_class={contact.class.EmployeeAccount}
|
||||
title="Assignee *"
|
||||
caption="Assign this task"
|
||||
bind:value={assignee}
|
||||
/>
|
||||
</Grid>
|
||||
</Card>
|
||||
|
||||
<style lang="scss">
|
||||
.channels {
|
||||
margin-top: 1.25rem;
|
||||
span { margin-left: .5rem; }
|
||||
span {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.locations {
|
||||
span {
|
||||
margin-bottom: .125rem;
|
||||
margin-bottom: 0.125rem;
|
||||
font-weight: 500;
|
||||
font-size: .75rem;
|
||||
font-size: 0.75rem;
|
||||
color: var(--theme-content-accent-color);
|
||||
}
|
||||
|
||||
@@ -104,7 +127,7 @@
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: .75rem;
|
||||
margin-top: 0.75rem;
|
||||
color: var(--theme-caption-color);
|
||||
}
|
||||
}
|
||||
@@ -117,12 +140,14 @@
|
||||
|
||||
.resume {
|
||||
margin-top: 1rem;
|
||||
padding: .75rem;
|
||||
background: rgba(255, 255, 255, .05);
|
||||
border: 1px dashed rgba(255, 255, 255, .2);
|
||||
border-radius: .5rem;
|
||||
padding: 0.75rem;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px dashed rgba(255, 255, 255, 0.2);
|
||||
border-radius: 0.5rem;
|
||||
backdrop-filter: blur(10px);
|
||||
&.solid { border-style: solid; }
|
||||
&.solid {
|
||||
border-style: solid;
|
||||
}
|
||||
}
|
||||
// .resume a {
|
||||
// font-size: .75rem;
|
||||
|
||||
@@ -12,24 +12,25 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import type { Ref } from '@anticrm/core'
|
||||
import { Panel } from '@anticrm/panel'
|
||||
import { createQuery, getClient } from '@anticrm/presentation'
|
||||
import type { Task } from '@anticrm/task'
|
||||
import { EditBox, Grid } from '@anticrm/ui'
|
||||
import { EditBox, Grid } from '@anticrm/ui'
|
||||
import view from '@anticrm/view'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import task from '../plugin'
|
||||
import Attachments from './Attachments.svelte'
|
||||
import TaskHeader from './TaskHeader.svelte'
|
||||
|
||||
|
||||
export let _id: Ref<Task>
|
||||
let object: Task
|
||||
|
||||
const query = createQuery()
|
||||
$: query.query(task.class.Task, { _id }, result => { object = result[0] })
|
||||
$: query.query(task.class.Task, { _id }, (result) => {
|
||||
object = result[0]
|
||||
})
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const client = getClient()
|
||||
@@ -40,19 +41,40 @@ import { EditBox, Grid } from '@anticrm/ui'
|
||||
</script>
|
||||
|
||||
{#if object !== undefined}
|
||||
<Panel icon={view.icon.Table} title={object.name} {object} on:close={() => { dispatch('close') }}>
|
||||
<TaskHeader {object} slot="subtitle" />
|
||||
<Panel
|
||||
icon={view.icon.Table}
|
||||
title={object.name}
|
||||
{object}
|
||||
on:close={() => {
|
||||
dispatch('close')
|
||||
}}
|
||||
>
|
||||
<TaskHeader {object} slot="subtitle" />
|
||||
|
||||
|
||||
<Grid column={1} rowGap={1.5}>
|
||||
<EditBox label={task.string.TaskName} bind:value={object.name} icon={task.icon.Task} placeholder="The boring task" maxWidth="39rem" focus on:change={(evt) => change('name', object.name)}/>
|
||||
<EditBox label={task.string.TaskDescription} bind:value={object.description} icon={task.icon.Task} placeholder="Description" maxWidth="39rem" on:change={(evt) => change('description', object.description)}/>
|
||||
</Grid>
|
||||
|
||||
<div class="mt-14">
|
||||
<Attachments objectId={object._id} _class={object._class} space={object.space} />
|
||||
</div>
|
||||
</Panel>
|
||||
<Grid column={1} rowGap={1.5}>
|
||||
<EditBox
|
||||
label={task.string.TaskName}
|
||||
bind:value={object.name}
|
||||
icon={task.icon.Task}
|
||||
placeholder="The boring task"
|
||||
maxWidth="39rem"
|
||||
focus
|
||||
on:change={(evt) => change('name', object.name)}
|
||||
/>
|
||||
<EditBox
|
||||
label={task.string.TaskDescription}
|
||||
bind:value={object.description}
|
||||
icon={task.icon.Task}
|
||||
placeholder="Description"
|
||||
maxWidth="39rem"
|
||||
on:change={(evt) => change('description', object.description)}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<div class="mt-14">
|
||||
<Attachments objectId={object._id} _class={object._class} space={object.space} />
|
||||
</div>
|
||||
</Panel>
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
<!--
|
||||
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { AttachmentsPresenter, CommentsPresenter } from '@anticrm/chunter-resources'
|
||||
import { formatName } from '@anticrm/contact'
|
||||
import type { WithLookup } from '@anticrm/core'
|
||||
import { Avatar } from '@anticrm/presentation'
|
||||
import type { Task } from '@anticrm/task'
|
||||
import { ActionIcon, IconMoreH, Label, showPopup } from '@anticrm/ui'
|
||||
import { ContextMenu } from '@anticrm/view-resources'
|
||||
import task from '../plugin'
|
||||
import TaskPresenter from './TaskPresenter.svelte'
|
||||
|
||||
export let object: WithLookup<Task>
|
||||
export let draggable: boolean
|
||||
|
||||
const showMenu = (ev?: Event): void => {
|
||||
showPopup(ContextMenu, { object }, (ev as MouseEvent).target as HTMLElement)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="card-container" {draggable} class:draggable on:dragstart on:dragend>
|
||||
<div class="content">
|
||||
<div class="flex-row-center">
|
||||
<div class="flex-col ml-2">
|
||||
<div class="sm-tool-icon step-lr75">
|
||||
<TaskPresenter value={object} />
|
||||
</div>
|
||||
<div class="fs-title">{object.name}</div>
|
||||
<div class="small-text">{object.description}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-between">
|
||||
{#if object.$lookup?.assignee}
|
||||
<div class="flex-center safari-gap-1">
|
||||
<Avatar avatar={object.$lookup?.assignee?.avatar} size={'x-small'} />
|
||||
<Label label={formatName(object.$lookup?.assignee?.name)} />
|
||||
</div>
|
||||
{/if}
|
||||
<div class="flex-row-reverse">
|
||||
<ActionIcon
|
||||
label={task.string.More}
|
||||
action={(evt) => {
|
||||
showMenu(evt)
|
||||
}}
|
||||
icon={IconMoreH}
|
||||
size={'small'}
|
||||
/>
|
||||
{#if (object.comments ?? 0) > 0}
|
||||
<div class="step-lr75"><CommentsPresenter value={object} /></div>
|
||||
{/if}
|
||||
{#if (object.attachments ?? 0) > 0}
|
||||
<div class="step-lr75"><AttachmentsPresenter value={object} /></div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.card-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1rem 1.25rem;
|
||||
background-color: rgba(222, 222, 240, 0.06);
|
||||
border-radius: 0.75rem;
|
||||
user-select: none;
|
||||
backdrop-filter: blur(10px);
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
&.draggable {
|
||||
cursor: grab;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -13,10 +13,9 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import contact from '@anticrm/contact'
|
||||
import { getClient, UserBox } from '@anticrm/presentation'
|
||||
import { AttributeBarEditor, getClient, UserBox } from '@anticrm/presentation'
|
||||
import { Task } from '@anticrm/task'
|
||||
import task from '../plugin'
|
||||
|
||||
@@ -29,13 +28,19 @@
|
||||
</script>
|
||||
|
||||
<div class="flex-between header">
|
||||
<UserBox _class={contact.class.Employee} title={task.string.TaskAssignee} caption='Assignee' bind:value={object.assignee} on:change={change} />
|
||||
<!-- <AttributeBarEditor key={'state'} {object} showHeader={false} /> -->
|
||||
<UserBox
|
||||
_class={contact.class.Employee}
|
||||
title={task.string.TaskAssignee}
|
||||
caption="Assignee"
|
||||
bind:value={object.assignee}
|
||||
on:change={change}
|
||||
/>
|
||||
<AttributeBarEditor key={'state'} {object} showHeader={false} />
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.header {
|
||||
width: 100%;
|
||||
padding: 0 .5rem;
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -13,27 +13,24 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import type { Task } from '@anticrm/task'
|
||||
import { closeTooltip, Icon, showPopup } from '@anticrm/ui'
|
||||
import EditTask from './EditTask.svelte'
|
||||
import { getClient } from '@anticrm/presentation'
|
||||
import task from '../plugin'
|
||||
|
||||
import type { Task } from '@anticrm/task'
|
||||
import { closeTooltip, Icon, showPopup } from '@anticrm/ui'
|
||||
import EditTask from './EditTask.svelte'
|
||||
import { getClient } from '@anticrm/presentation'
|
||||
import task from '../plugin'
|
||||
export let value: Task
|
||||
|
||||
export let value: Task
|
||||
|
||||
const client = getClient()
|
||||
const shortLabel = client.getHierarchy().getClass(value._class).shortLabel
|
||||
|
||||
function show () {
|
||||
closeTooltip()
|
||||
showPopup(EditTask, { _id: value._id }, 'full')
|
||||
}
|
||||
const client = getClient()
|
||||
const shortLabel = client.getHierarchy().getClass(value._class).shortLabel
|
||||
|
||||
function show () {
|
||||
closeTooltip()
|
||||
showPopup(EditTask, { _id: value._id }, 'full')
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="sm-tool-icon" on:click={show}>
|
||||
<span class="icon"><Icon icon={task.icon.Task} size={'small'}/></span>{shortLabel}-{value.number}
|
||||
<span class="icon"><Icon icon={task.icon.Task} size={'small'} /></span>{shortLabel}-{value.number}
|
||||
</div>
|
||||
|
||||
@@ -13,16 +13,20 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
export let size: 'small' | 'medium' | 'large'
|
||||
const fill: string = 'currentColor'
|
||||
</script>
|
||||
|
||||
<svg class="svg-{size}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="var(--duotone-color)" d="M18,6.4c-0.1,0-0.2,0-0.3,0c-0.1,0-0.1,0-0.1,0c-0.1,0-0.1,0-0.1,0c0,0,0,0-0.1-0.1c0,0,0,0-0.1-0.1 c0-0.1-0.1-0.2-0.2-0.4c-0.9-1.9-2.8-3.3-5.1-3.3c-2.3,0-4.2,1.4-5.1,3.3C6.8,5.9,6.7,6,6.7,6.1c0,0.1-0.1,0.1-0.1,0.1 C6.6,6.3,6.6,6.3,6.5,6.3c0,0,0,0-0.1,0c0,0,0,0-0.1,0c-0.1,0-0.2,0-0.3,0C4,6.4,2.4,8,2.4,10S4,13.6,6,13.6h6h6 c2,0,3.6-1.6,3.6-3.6S20,6.4,18,6.4z"/>
|
||||
<path
|
||||
fill="var(--duotone-color)"
|
||||
d="M18,6.4c-0.1,0-0.2,0-0.3,0c-0.1,0-0.1,0-0.1,0c-0.1,0-0.1,0-0.1,0c0,0,0,0-0.1-0.1c0,0,0,0-0.1-0.1 c0-0.1-0.1-0.2-0.2-0.4c-0.9-1.9-2.8-3.3-5.1-3.3c-2.3,0-4.2,1.4-5.1,3.3C6.8,5.9,6.7,6,6.7,6.1c0,0.1-0.1,0.1-0.1,0.1 C6.6,6.3,6.6,6.3,6.5,6.3c0,0,0,0-0.1,0c0,0,0,0-0.1,0c-0.1,0-0.2,0-0.3,0C4,6.4,2.4,8,2.4,10S4,13.6,6,13.6h6h6 c2,0,3.6-1.6,3.6-3.6S20,6.4,18,6.4z"
|
||||
/>
|
||||
<g {fill}>
|
||||
<path d="M18,6.4c-0.1,0-0.2,0-0.3,0c-0.1,0-0.1,0-0.1,0c-0.1,0-0.1,0-0.1,0c0,0,0,0-0.1-0.1c0,0,0,0,0,0c0,0,0,0,0,0 c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0-0.1-0.1c0-0.1-0.1-0.2-0.2-0.4c-0.9-1.9-2.8-3.3-5.1-3.3c-2.3,0-4.2,1.4-5.1,3.3 C6.8,5.9,6.7,6,6.7,6.1c0,0.1-0.1,0.1-0.1,0.1c0,0,0,0,0,0C6.6,6.3,6.6,6.3,6.5,6.3c0,0,0,0-0.1,0c0,0,0,0-0.1,0 c-0.1,0-0.2,0-0.3,0C4,6.4,2.4,8,2.4,10S4,13.6,6,13.6h0.6l1.2-1.2H6c-1.3,0-2.4-1.1-2.4-2.4c0-1.3,1.1-2.4,2.4-2.4h0.1 c0.2,0,0.4,0,0.6,0c0.2,0,0.4-0.1,0.6-0.2c0.2-0.1,0.3-0.3,0.4-0.4c0.1-0.1,0.1-0.2,0.2-0.3C7.8,6.5,7.9,6.4,8,6.2l0,0 c0.7-1.5,2.2-2.6,4-2.6s3.3,1.1,4,2.6l0,0c0.1,0.2,0.1,0.3,0.2,0.4c0,0.1,0.1,0.2,0.2,0.3c0.1,0.2,0.2,0.3,0.4,0.4 c0.2,0.1,0.4,0.2,0.6,0.2c0.2,0,0.4,0,0.6,0H18c1.3,0,2.4,1.1,2.4,2.4c0,1.3-1.1,2.4-2.4,2.4h-1.8l1.2,1.2H18c2,0,3.6-1.6,3.6-3.6 S20,6.4,18,6.4z"/>
|
||||
<path d="M12,11.2l-4.4,4.4l0.8,0.8l3-3V21c0,0.3,0.3,0.6,0.6,0.6s0.6-0.3,0.6-0.6v-7.6l3,3l0.8-0.8L12,11.2z"/>
|
||||
<path
|
||||
d="M18,6.4c-0.1,0-0.2,0-0.3,0c-0.1,0-0.1,0-0.1,0c-0.1,0-0.1,0-0.1,0c0,0,0,0-0.1-0.1c0,0,0,0,0,0c0,0,0,0,0,0 c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0-0.1-0.1c0-0.1-0.1-0.2-0.2-0.4c-0.9-1.9-2.8-3.3-5.1-3.3c-2.3,0-4.2,1.4-5.1,3.3 C6.8,5.9,6.7,6,6.7,6.1c0,0.1-0.1,0.1-0.1,0.1c0,0,0,0,0,0C6.6,6.3,6.6,6.3,6.5,6.3c0,0,0,0-0.1,0c0,0,0,0-0.1,0 c-0.1,0-0.2,0-0.3,0C4,6.4,2.4,8,2.4,10S4,13.6,6,13.6h0.6l1.2-1.2H6c-1.3,0-2.4-1.1-2.4-2.4c0-1.3,1.1-2.4,2.4-2.4h0.1 c0.2,0,0.4,0,0.6,0c0.2,0,0.4-0.1,0.6-0.2c0.2-0.1,0.3-0.3,0.4-0.4c0.1-0.1,0.1-0.2,0.2-0.3C7.8,6.5,7.9,6.4,8,6.2l0,0 c0.7-1.5,2.2-2.6,4-2.6s3.3,1.1,4,2.6l0,0c0.1,0.2,0.1,0.3,0.2,0.4c0,0.1,0.1,0.2,0.2,0.3c0.1,0.2,0.2,0.3,0.4,0.4 c0.2,0.1,0.4,0.2,0.6,0.2c0.2,0,0.4,0,0.6,0H18c1.3,0,2.4,1.1,2.4,2.4c0,1.3-1.1,2.4-2.4,2.4h-1.8l1.2,1.2H18c2,0,3.6-1.6,3.6-3.6 S20,6.4,18,6.4z"
|
||||
/>
|
||||
<path d="M12,11.2l-4.4,4.4l0.8,0.8l3-3V21c0,0.3,0.3,0.6,0.6,0.6s0.6-0.3,0.6-0.6v-7.6l3,3l0.8-0.8L12,11.2z" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
Reference in New Issue
Block a user