mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-27 01:13:27 +03:00
initial attributes bar
Signed-off-by: Andrey Platov <andrey@hardcoreeng.com>
This commit is contained in:
parent
1bdc5c98d6
commit
d4a03393ff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -81,6 +81,10 @@ export function createModel (builder: Builder): void {
|
|||||||
presenter: view.component.StringPresenter
|
presenter: view.component.StringPresenter
|
||||||
})
|
})
|
||||||
|
|
||||||
|
builder.mixin(core.class.TypeBoolean, core.class.Class, view.mixin.AttributeEditor, {
|
||||||
|
editor: view.component.BooleanEditor
|
||||||
|
})
|
||||||
|
|
||||||
builder.mixin(core.class.State, core.class.Class, view.mixin.AttributePresenter, {
|
builder.mixin(core.class.State, core.class.Class, view.mixin.AttributePresenter, {
|
||||||
presenter: view.component.StatePresenter
|
presenter: view.component.StatePresenter
|
||||||
})
|
})
|
||||||
|
@ -29,6 +29,7 @@ export default mergeIds(viewId, view, {
|
|||||||
component: {
|
component: {
|
||||||
StringEditor: '' as AnyComponent,
|
StringEditor: '' as AnyComponent,
|
||||||
StringPresenter: '' as AnyComponent,
|
StringPresenter: '' as AnyComponent,
|
||||||
|
BooleanEditor: '' as AnyComponent,
|
||||||
StatePresenter: '' as AnyComponent,
|
StatePresenter: '' as AnyComponent,
|
||||||
|
|
||||||
TableView: '' as AnyComponent,
|
TableView: '' as AnyComponent,
|
||||||
|
@ -0,0 +1,76 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
||||||
|
// Copyright © 2021 Hardcore Engineering Inc.
|
||||||
|
//
|
||||||
|
// 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 type { Ref, Class, Doc } from '@anticrm/core'
|
||||||
|
import { getResource } from '@anticrm/platform'
|
||||||
|
import type { AnySvelteComponent } from '@anticrm/ui'
|
||||||
|
import { CircleButton, Label } from '@anticrm/ui'
|
||||||
|
import { getClient } from '../utils'
|
||||||
|
import view from '@anticrm/view'
|
||||||
|
|
||||||
|
// export let _class: Ref<Class<Doc>>
|
||||||
|
export let key: string
|
||||||
|
export let object: Doc
|
||||||
|
export let maxWidth: string
|
||||||
|
export let focus: boolean = false
|
||||||
|
export let minimize: boolean = false
|
||||||
|
|
||||||
|
const _class = object._class
|
||||||
|
const client = getClient()
|
||||||
|
const hierarchy = client.getHierarchy()
|
||||||
|
const attribute = hierarchy.getAttribute(_class, key)
|
||||||
|
|
||||||
|
const typeClassId = attribute?.type._class
|
||||||
|
|
||||||
|
let editor: Promise<AnySvelteComponent> | undefined
|
||||||
|
|
||||||
|
if (typeClassId !== undefined) {
|
||||||
|
const typeClass = hierarchy.getClass(typeClassId)
|
||||||
|
const editorMixin = hierarchy.as(typeClass, view.mixin.AttributeEditor)
|
||||||
|
editor = getResource(editorMixin.editor)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChange(value: any) {
|
||||||
|
client.updateDoc(_class, object.space, object._id, { [key]: value })
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if editor}
|
||||||
|
{#await editor}
|
||||||
|
...
|
||||||
|
{:then instance}
|
||||||
|
|
||||||
|
{#if attribute.icon}
|
||||||
|
<div class="flex-row-center">
|
||||||
|
<CircleButton icon={attribute.icon} size={'large'} />
|
||||||
|
{#if !minimize}
|
||||||
|
<div class="flex-col with-icon">
|
||||||
|
<Label label={attribute.label} />
|
||||||
|
<div class="value"><svelte:component this={instance} label={attribute?.label} placeholder={attribute?.label} {maxWidth} bind:value={object[key]} {onChange} {focus}/></div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div class="flex-col">
|
||||||
|
<Label label={attribute.label} />
|
||||||
|
<div class="value"><svelte:component this={instance} label={attribute?.label} placeholder={attribute?.label} {maxWidth} bind:value={object[key]} {onChange} {focus}/></div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{/await}
|
||||||
|
{/if}
|
||||||
|
|
@ -21,6 +21,7 @@ export { default as UserInfo } from './components/UserInfo.svelte'
|
|||||||
export { default as Avatar } from './components/Avatar.svelte'
|
export { default as Avatar } from './components/Avatar.svelte'
|
||||||
export { default as MessageViewer } from './components/MessageViewer.svelte'
|
export { default as MessageViewer } from './components/MessageViewer.svelte'
|
||||||
export { default as AttributeEditor } from './components/AttributeEditor.svelte'
|
export { default as AttributeEditor } from './components/AttributeEditor.svelte'
|
||||||
|
export { default as AttributeBarEditor } from './components/AttributeBarEditor.svelte'
|
||||||
export { default as Card } from './components/Card.svelte'
|
export { default as Card } from './components/Card.svelte'
|
||||||
export { default as Channels } from './components/Channels.svelte'
|
export { default as Channels } from './components/Channels.svelte'
|
||||||
export { default as Backlink } from './components/Backlink.svelte'
|
export { default as Backlink } from './components/Backlink.svelte'
|
||||||
|
@ -15,23 +15,19 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { CircleButton, Label } from '@anticrm/ui'
|
import { CircleButton, Label } from '@anticrm/ui'
|
||||||
import Location from './icons/Location.svelte'
|
import type { Ref, Class, Obj, Doc } from '@anticrm/core'
|
||||||
import YesNoPresenter from './YesNoPresenter.svelte'
|
import { AttributeBarEditor } from '@anticrm/presentation'
|
||||||
import AttributeEditor from './AttributeEditor.svelte'
|
|
||||||
|
|
||||||
export let minimize: boolean = false
|
export let object: Doc
|
||||||
|
export let keys: string[]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex-row-center small-text">
|
<div class="flex-row-center small-text">
|
||||||
<div class="column">
|
{#each keys as key}
|
||||||
<AttributeEditor icon={Location} label={'Location'} component={Label} props={{ label: 'Moscow' }} />
|
<div class="column">
|
||||||
</div>
|
<AttributeBarEditor {key} {object} />
|
||||||
<div class="column">
|
</div>
|
||||||
<AttributeEditor label={'Onsite'} component={YesNoPresenter} props={{ state: 'yes' }} />
|
{/each}
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
<AttributeEditor label={'Remote'} component={YesNoPresenter} props={{ state: 'no' }} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
|
|
||||||
{#if object !== undefined}
|
{#if object !== undefined}
|
||||||
<Panel icon={Contact} title={formatName(object.name)} {object} on:close={() => { dispatch('close') }}>
|
<Panel icon={Contact} title={formatName(object.name)} {object} on:close={() => { dispatch('close') }}>
|
||||||
<AttributesBar slot="subtitle" />
|
<AttributesBar {object} keys={['city', 'onsite', 'remote']} slot="subtitle" />
|
||||||
|
|
||||||
<div class="flex-row-center">
|
<div class="flex-row-center">
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
|
72
plugins/view-resources/src/components/BooleanEditor.svelte
Normal file
72
plugins/view-resources/src/components/BooleanEditor.svelte
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
||||||
|
// Copyright © 2021 Hardcore Engineering Inc.
|
||||||
|
//
|
||||||
|
// 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 type { IntlString } from '@anticrm/platform'
|
||||||
|
import { Label } from '@anticrm/ui'
|
||||||
|
|
||||||
|
export let label: IntlString
|
||||||
|
export let placeholder: IntlString
|
||||||
|
export let value: any
|
||||||
|
export let focus: boolean
|
||||||
|
export let maxWidth: string
|
||||||
|
export let onChange: (value: any) => void
|
||||||
|
|
||||||
|
function getLabel(value: boolean | undefined) {
|
||||||
|
if (value === true) return 'Yes'
|
||||||
|
if (value === false) return 'No'
|
||||||
|
return 'Unknown'
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex-row-center yesno-container" class:yes={value === true} class:no={value === false} class:unknown={value === undefined} on:click={() => {
|
||||||
|
if (value === true) value = false
|
||||||
|
else if (value === false) value = undefined
|
||||||
|
else value = true
|
||||||
|
onChange(value)
|
||||||
|
}}>
|
||||||
|
<svg class="svg-small" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||||
|
<circle class:yes={value === true} class:no={value === false} class:unknown={value === undefined} cx="8" cy="8" r="6"/>
|
||||||
|
{#if value === true}
|
||||||
|
<polygon fill="#fff" points="7.4,10.9 4.9,8.4 5.7,7.6 7.3,9.1 10.2,5.6 11.1,6.4 "/>
|
||||||
|
{:else if value === false}
|
||||||
|
<polygon fill="#fff" points="10.7,6 10,5.3 8,7.3 6,5.3 5.3,6 7.3,8 5.3,10 6,10.7 8,8.7 10,10.7 10.7,10 8.7,8 "/>
|
||||||
|
{:else}
|
||||||
|
<path fill="#fff" d="M7.3,9.3h1.3V9c0.1-0.5,0.6-0.9,1.1-1.4c0.4-0.4,0.8-0.9,0.8-1.6c0-1.1-0.8-1.8-2.2-1.8c-1.4,0-2.4,0.8-2.5,2.2 h1.4c0.1-0.6,0.4-1,1-1C8.8,5.4,9,5.7,9,6.2c0,0.4-0.3,0.7-0.7,1.1c-0.5,0.5-1,0.9-1,1.7V9.3z M8,11.6c0.5,0,0.9-0.4,0.9-0.9 c0-0.5-0.4-0.9-0.9-0.9c-0.5,0-0.9,0.4-0.9,0.9C7.1,11.2,7.5,11.6,8,11.6z"/>
|
||||||
|
{/if}
|
||||||
|
</svg>
|
||||||
|
<span><Label label={getLabel(value)} /></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.yesno-container {
|
||||||
|
max-width: fit-content;
|
||||||
|
user-select: none;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.yes { fill: #77C07B; }
|
||||||
|
&.no { fill: #F96E50; }
|
||||||
|
&.unknown { fill: #77818E; }
|
||||||
|
span {
|
||||||
|
margin-left: .25rem;
|
||||||
|
text-transform: capitalize;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--theme-caption-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -17,6 +17,7 @@ import type { Doc } from '@anticrm/core'
|
|||||||
|
|
||||||
import StringEditor from './components/StringEditor.svelte'
|
import StringEditor from './components/StringEditor.svelte'
|
||||||
import StringPresenter from './components/StringPresenter.svelte'
|
import StringPresenter from './components/StringPresenter.svelte'
|
||||||
|
import BooleanEditor from './components/BooleanEditor.svelte'
|
||||||
import StatePresenter from './components/StatePresenter.svelte'
|
import StatePresenter from './components/StatePresenter.svelte'
|
||||||
import TableView from './components/TableView.svelte'
|
import TableView from './components/TableView.svelte'
|
||||||
import KanbanView from './components/KanbanView.svelte'
|
import KanbanView from './components/KanbanView.svelte'
|
||||||
@ -35,6 +36,7 @@ export default async () => ({
|
|||||||
component: {
|
component: {
|
||||||
StringEditor,
|
StringEditor,
|
||||||
StringPresenter,
|
StringPresenter,
|
||||||
|
BooleanEditor,
|
||||||
StatePresenter,
|
StatePresenter,
|
||||||
TableView,
|
TableView,
|
||||||
KanbanView
|
KanbanView
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user