mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-30 02:37:46 +03:00
Updated Enums in Settings, EditEnum (#4423)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
parent
b87bcf2ebe
commit
1024faa46e
@ -22,6 +22,7 @@
|
|||||||
"NoMatchesInThis": "No matches in this {space}",
|
"NoMatchesInThis": "No matches in this {space}",
|
||||||
"NoMatchesFound": "No matches found",
|
"NoMatchesFound": "No matches found",
|
||||||
"NotInThis": "Not in this {space}",
|
"NotInThis": "Not in this {space}",
|
||||||
|
"Match": "Match",
|
||||||
"Add": "Add",
|
"Add": "Add",
|
||||||
"Edit": "Edit",
|
"Edit": "Edit",
|
||||||
"DocumentPreview": "Preview",
|
"DocumentPreview": "Preview",
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
"NoMatchesInThis": "В этом {space} совпадения не обнаружены",
|
"NoMatchesInThis": "В этом {space} совпадения не обнаружены",
|
||||||
"NoMatchesFound": "Не найдено соответствий",
|
"NoMatchesFound": "Не найдено соответствий",
|
||||||
"NotInThis": "Не в этом {space}",
|
"NotInThis": "Не в этом {space}",
|
||||||
|
"Match": "Совпадение",
|
||||||
"Add": "Добавить",
|
"Add": "Добавить",
|
||||||
"Edit": "Редактировать",
|
"Edit": "Редактировать",
|
||||||
"DocumentPreview": "Предпросмотр",
|
"DocumentPreview": "Предпросмотр",
|
||||||
|
@ -62,6 +62,7 @@ export default plugin(presentationId, {
|
|||||||
NoMatchesInThis: '' as IntlString,
|
NoMatchesInThis: '' as IntlString,
|
||||||
NoMatchesFound: '' as IntlString,
|
NoMatchesFound: '' as IntlString,
|
||||||
NotInThis: '' as IntlString,
|
NotInThis: '' as IntlString,
|
||||||
|
Match: '' as IntlString,
|
||||||
Add: '' as IntlString,
|
Add: '' as IntlString,
|
||||||
Edit: '' as IntlString,
|
Edit: '' as IntlString,
|
||||||
DocumentPreview: '' as IntlString,
|
DocumentPreview: '' as IntlString,
|
||||||
|
@ -968,6 +968,9 @@ a.no-line {
|
|||||||
.content-color { color: var(--theme-content-color); }
|
.content-color { color: var(--theme-content-color); }
|
||||||
.caption-color { color: var(--theme-caption-color); }
|
.caption-color { color: var(--theme-caption-color); }
|
||||||
|
|
||||||
|
.secondary-textColor { color: var(--global-secondary-TextColor) !important; }
|
||||||
|
.tertiary-textColor { color: var(--global-tertiary-TextColor) !important; }
|
||||||
|
|
||||||
.content-primary-color { color: var(--primary-button-color); }
|
.content-primary-color { color: var(--primary-button-color); }
|
||||||
.red-color { color: var(--highlight-red); }
|
.red-color { color: var(--highlight-red); }
|
||||||
.error-color { color: var(--theme-error-color); }
|
.error-color { color: var(--theme-error-color); }
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
--global-accent-TextColor: #4D7FF5;
|
--global-accent-TextColor: #4D7FF5;
|
||||||
--global-focus-BorderColor: #2A59D6;
|
--global-focus-BorderColor: #2A59D6;
|
||||||
--global-popover-ShadowColor: #0E131E59;
|
--global-popover-ShadowColor: #0E131E59;
|
||||||
|
--global-modal-ShadowColor: #0E131E73;
|
||||||
|
|
||||||
/** Buttons **/
|
/** Buttons **/
|
||||||
--button-subtle-LabelColor: #fff;
|
--button-subtle-LabelColor: #fff;
|
||||||
@ -102,6 +103,7 @@
|
|||||||
--global-accent-TextColor: #3566E2;
|
--global-accent-TextColor: #3566E2;
|
||||||
--global-focus-BorderColor: #204DC8;
|
--global-focus-BorderColor: #204DC8;
|
||||||
--global-popover-ShadowColor: #0E131E1F;
|
--global-popover-ShadowColor: #0E131E1F;
|
||||||
|
--global-modal-ShadowColor: #0E131E14;
|
||||||
|
|
||||||
/** Buttons **/
|
/** Buttons **/
|
||||||
--button-subtle-LabelColor: #000;
|
--button-subtle-LabelColor: #000;
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
--spacing-0_5: 0.25rem;
|
--spacing-0_5: 0.25rem;
|
||||||
--spacing-0_75: 0.375rem;
|
--spacing-0_75: 0.375rem;
|
||||||
--spacing-1: 0.5rem;
|
--spacing-1: 0.5rem;
|
||||||
|
--spacing-1_25: 0.625rem;
|
||||||
--spacing-1_5: 0.75rem;
|
--spacing-1_5: 0.75rem;
|
||||||
--spacing-1_75: 0.875rem;
|
--spacing-1_75: 0.875rem;
|
||||||
--spacing-2: 1rem;
|
--spacing-2: 1rem;
|
||||||
@ -63,4 +64,8 @@
|
|||||||
--global-popover-ShadowSpread: 0;
|
--global-popover-ShadowSpread: 0;
|
||||||
--global-popover-ShadowX: 0;
|
--global-popover-ShadowX: 0;
|
||||||
--global-popover-ShadowY: 0.5rem;
|
--global-popover-ShadowY: 0.5rem;
|
||||||
|
--global-modal-ShadowBlur: 1.5rem;
|
||||||
|
--global-modal-ShadowSpread: 0.25rem;
|
||||||
|
--global-modal-ShadowX: 0;
|
||||||
|
--global-modal-ShadowY: 1.5rem;
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,6 @@
|
|||||||
border-top: 1px solid transparent;
|
border-top: 1px solid transparent;
|
||||||
|
|
||||||
.hulyModal-content {
|
.hulyModal-content {
|
||||||
padding: var(--spacing-2) var(--spacing-1_5);
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
&__titleGroup {
|
&__titleGroup {
|
||||||
@ -222,14 +221,35 @@
|
|||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
gap: var(--spacing-1);
|
gap: var(--spacing-1);
|
||||||
padding: var(--spacing-2) var(--spacing-2_5);
|
|
||||||
border-top: 1px solid var(--theme-divider-color); // var(--global-surface-01-BorderColor);
|
border-top: 1px solid var(--theme-divider-color); // var(--global-surface-01-BorderColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.type-aside .hulyHeader-container {
|
&.type-aside {
|
||||||
border-radius: 0 var(--small-focus-BorderRadius) 0 0;
|
.hulyHeader-container {
|
||||||
|
border-radius: 0 var(--small-focus-BorderRadius) 0 0;
|
||||||
|
|
||||||
.hulyHeader-titleGroup {
|
.hulyHeader-buttonsGroup {
|
||||||
|
gap: var(--spacing-0_5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.hulyModal-footer {
|
||||||
|
padding: var(--spacing-2) var(--spacing-2_5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.type-popup {
|
||||||
|
min-width: 45rem;
|
||||||
|
background-color: var(--theme-popup-color); // var(--global-surface-02-BackgroundColor);
|
||||||
|
border: 1px solid var(--theme-popup-divider); // var(--global-surface-02-BorderColor);
|
||||||
|
border-radius: var(--large-BorderRadius);
|
||||||
|
box-shadow: var(--global-modal-ShadowX) var(--global-modal-ShadowY) var(--global-modal-ShadowBlur) var(--global-modal-ShadowSpread) var(--global-popover-ShadowColor);
|
||||||
|
|
||||||
|
.hulyModal-footer {
|
||||||
|
padding: var(--spacing-1_5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.type-aside,
|
||||||
|
&.type-popup {
|
||||||
|
.hulyHeader-container .hulyHeader-titleGroup {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-family: var(--font-family);
|
font-family: var(--font-family);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
@ -238,9 +258,6 @@
|
|||||||
line-height: 1rem;
|
line-height: 1rem;
|
||||||
color: var(--global-secondary-TextColor);
|
color: var(--global-secondary-TextColor);
|
||||||
}
|
}
|
||||||
.hulyHeader-buttonsGroup {
|
|
||||||
gap: var(--spacing-0_5);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
textarea {
|
textarea {
|
||||||
font-weight: 400 !important;
|
font-weight: 400 !important;
|
||||||
@ -255,6 +272,10 @@
|
|||||||
color: var(--global-tertiary-TextColor);
|
color: var(--global-tertiary-TextColor);
|
||||||
background-color: var(--global-ui-BackgroundColor);
|
background-color: var(--global-ui-BackgroundColor);
|
||||||
border-radius: var(--extra-small-BorderRadius);
|
border-radius: var(--extra-small-BorderRadius);
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
color: var(--button-negative-loading-LabelColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.hulyHotKey-item {
|
.hulyHotKey-item {
|
||||||
|
@ -64,8 +64,12 @@
|
|||||||
|
|
||||||
&:not(.small) { font-size: .875rem; }
|
&:not(.small) { font-size: .875rem; }
|
||||||
&.small { font-size: .75rem; }
|
&.small { font-size: .75rem; }
|
||||||
&:not(.dark) { color: var(--global-on-accent-TextColor); }
|
&:not(.dark) {
|
||||||
&.dark { color: var(--global-secondary-TextColor); }
|
color: var(--global-primary-TextColor); // var(--global-on-accent-TextColor);
|
||||||
|
}
|
||||||
|
&.dark {
|
||||||
|
color: var(--theme-dark-color); // var(--global-secondary-TextColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@ -41,6 +41,13 @@
|
|||||||
width: var(--global-min-Size);
|
width: var(--global-min-Size);
|
||||||
height: var(--global-min-Size);
|
height: var(--global-min-Size);
|
||||||
}
|
}
|
||||||
|
.buttons-group {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--spacing-1);
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.hulyTableAttr-content {
|
.hulyTableAttr-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -108,6 +115,10 @@
|
|||||||
border-radius: var(--extra-small-BorderRadius);
|
border-radius: var(--extra-small-BorderRadius);
|
||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
||||||
|
&.drag {
|
||||||
|
cursor: grab !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&-icon {
|
&-icon {
|
||||||
width: var(--global-min-Size);
|
width: var(--global-min-Size);
|
||||||
@ -173,10 +184,11 @@
|
|||||||
color: var(--global-primary-LinkColor);
|
color: var(--global-primary-LinkColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.options .hulyTableAttr-content__row,
|
||||||
&.class .hulyTableAttr-content__row,
|
&.class .hulyTableAttr-content__row,
|
||||||
&.task .hulyTableAttr-content__row {
|
&.task .hulyTableAttr-content__row {
|
||||||
&.hovered,
|
&.hovered,
|
||||||
&:hover {
|
&:not(.disableMouseOver):hover {
|
||||||
background-color: var(--theme-table-header-color); // var(--global-surface-03-hover-BackgroundColor);
|
background-color: var(--theme-table-header-color); // var(--global-surface-03-hover-BackgroundColor);
|
||||||
}
|
}
|
||||||
&.selected {
|
&.selected {
|
||||||
@ -195,6 +207,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.options,
|
||||||
&.class {
|
&.class {
|
||||||
padding: var(--spacing-1);
|
padding: var(--spacing-1);
|
||||||
|
|
||||||
@ -203,12 +216,31 @@
|
|||||||
padding: var(--spacing-1) var(--spacing-2) var(--spacing-1) var(--spacing-1);
|
padding: var(--spacing-1) var(--spacing-2) var(--spacing-1) var(--spacing-1);
|
||||||
|
|
||||||
&.hovered .hulyTableAttr-content__row-arrow,
|
&.hovered .hulyTableAttr-content__row-arrow,
|
||||||
&:hover .hulyTableAttr-content__row-arrow,
|
&:not(.disableMouseOver):hover .hulyTableAttr-content__row-arrow,
|
||||||
&.selected .hulyTableAttr-content__row-arrow {
|
&.selected .hulyTableAttr-content__row-arrow {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.options .hulyTableAttr-content__row {
|
||||||
|
padding: var(--spacing-1);
|
||||||
|
min-height: var(--global-large-Size);
|
||||||
|
|
||||||
|
&:not(.hovered) button.type-button-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
&.disableMouseOver,
|
||||||
|
&-dragMenu {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
label.editbox-wrapper {
|
||||||
|
padding: 0 !important;
|
||||||
|
height: var(--global-extra-small-Size) !important;
|
||||||
|
}
|
||||||
|
&:hover button.type-button-icon {
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
&.task {
|
&.task {
|
||||||
.hulyTableAttr-content__row {
|
.hulyTableAttr-content__row {
|
||||||
gap: var(--spacing-1);
|
gap: var(--spacing-1);
|
||||||
|
@ -14,7 +14,8 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Asset, IntlString } from '@hcengineering/platform'
|
import type { Asset, IntlString } from '@hcengineering/platform'
|
||||||
import { AnySvelteComponent } from '../types'
|
import { AnySvelteComponent, LabelAndProps } from '../types'
|
||||||
|
import { tooltip as tp } from '../tooltips'
|
||||||
import { ComponentType } from 'svelte'
|
import { ComponentType } from 'svelte'
|
||||||
import Spinner from './Spinner.svelte'
|
import Spinner from './Spinner.svelte'
|
||||||
import Icon from './Icon.svelte'
|
import Icon from './Icon.svelte'
|
||||||
@ -33,6 +34,7 @@
|
|||||||
export let hasMenu: boolean = false
|
export let hasMenu: boolean = false
|
||||||
export let type: 'type-button' | 'type-button-icon'
|
export let type: 'type-button' | 'type-button-icon'
|
||||||
export let inheritColor: boolean = false
|
export let inheritColor: boolean = false
|
||||||
|
export let tooltip: LabelAndProps | undefined = undefined
|
||||||
export let element: HTMLButtonElement | undefined = undefined
|
export let element: HTMLButtonElement | undefined = undefined
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -44,6 +46,7 @@
|
|||||||
class:inheritColor
|
class:inheritColor
|
||||||
class:menu={hasMenu}
|
class:menu={hasMenu}
|
||||||
disabled={loading || disabled}
|
disabled={loading || disabled}
|
||||||
|
use:tp={tooltip}
|
||||||
on:click
|
on:click
|
||||||
>
|
>
|
||||||
{#if loading}
|
{#if loading}
|
||||||
@ -299,6 +302,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
& > * {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes rotate {
|
@keyframes rotate {
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Asset } from '@hcengineering/platform'
|
import type { Asset } from '@hcengineering/platform'
|
||||||
import { AnySvelteComponent } from '../types'
|
import { AnySvelteComponent, LabelAndProps } from '../types'
|
||||||
import { ComponentType } from 'svelte'
|
import { ComponentType } from 'svelte'
|
||||||
import ButtonBase from './ButtonBase.svelte'
|
import ButtonBase from './ButtonBase.svelte'
|
||||||
|
|
||||||
@ -24,8 +24,10 @@
|
|||||||
export let iconProps: any | undefined = undefined
|
export let iconProps: any | undefined = undefined
|
||||||
export let disabled: boolean = false
|
export let disabled: boolean = false
|
||||||
export let pressed: boolean = false
|
export let pressed: boolean = false
|
||||||
|
export let hasMenu: boolean = false
|
||||||
export let loading: boolean = false
|
export let loading: boolean = false
|
||||||
export let inheritColor: boolean = false
|
export let inheritColor: boolean = false
|
||||||
|
export let tooltip: LabelAndProps | undefined = undefined
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ButtonBase
|
<ButtonBase
|
||||||
@ -38,5 +40,7 @@
|
|||||||
{loading}
|
{loading}
|
||||||
{inheritColor}
|
{inheritColor}
|
||||||
{pressed}
|
{pressed}
|
||||||
|
{hasMenu}
|
||||||
|
{tooltip}
|
||||||
on:click
|
on:click
|
||||||
/>
|
/>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import { IconMaximize, IconMinimize, IconClose, ButtonIcon } from '..'
|
import { IconMaximize, IconMinimize, IconClose, ButtonIcon } from '..'
|
||||||
|
|
||||||
export let type: 'type-aside' | 'type-component' = 'type-component'
|
export let type: 'type-aside' | 'type-popup' | 'type-component' = 'type-component'
|
||||||
export let minimize: boolean = false
|
export let minimize: boolean = false
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
@ -41,8 +41,8 @@
|
|||||||
<slot name="actions" />
|
<slot name="actions" />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if type === 'type-aside'}
|
{#if type !== 'type-component'}
|
||||||
<div class="hulyHeader-divider" />
|
{#if type !== 'type-popup'}<div class="hulyHeader-divider" />{/if}
|
||||||
<div class="hulyHotKey-item">Esc</div>
|
<div class="hulyHotKey-item">Esc</div>
|
||||||
<ButtonIcon icon={IconClose} kind={'tertiary'} size={'small'} on:click={() => dispatch('close')} />
|
<ButtonIcon icon={IconClose} kind={'tertiary'} size={'small'} on:click={() => dispatch('close')} />
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -20,11 +20,9 @@
|
|||||||
import ButtonIcon from './ButtonIcon.svelte'
|
import ButtonIcon from './ButtonIcon.svelte'
|
||||||
import ButtonBase from './ButtonBase.svelte'
|
import ButtonBase from './ButtonBase.svelte'
|
||||||
import Scroller from './Scroller.svelte'
|
import Scroller from './Scroller.svelte'
|
||||||
import IconDelete from './icons/Delete.svelte'
|
|
||||||
import IconCopy from './icons/Copy.svelte'
|
|
||||||
import ui from '..'
|
import ui from '..'
|
||||||
|
|
||||||
export let type: 'type-aside' | 'type-component'
|
export let type: 'type-aside' | 'type-popup' | 'type-component'
|
||||||
export let label: IntlString
|
export let label: IntlString
|
||||||
export let labelProps: any | undefined = undefined
|
export let labelProps: any | undefined = undefined
|
||||||
export let okAction: () => Promise<void> | void
|
export let okAction: () => Promise<void> | void
|
||||||
@ -49,26 +47,42 @@
|
|||||||
<Header {type} on:close={close}>
|
<Header {type} on:close={close}>
|
||||||
<Label {label} params={labelProps} />
|
<Label {label} params={labelProps} />
|
||||||
<svelte:fragment slot="actions">
|
<svelte:fragment slot="actions">
|
||||||
<ButtonIcon icon={IconDelete} size={'small'} kind={'tertiary'} />
|
<slot name="actions" />
|
||||||
<ButtonIcon icon={IconCopy} size={'small'} kind={'tertiary'} />
|
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
</Header>
|
</Header>
|
||||||
<div class="hulyModal-content">
|
<div class="hulyModal-content">
|
||||||
<Scroller>
|
<Scroller
|
||||||
|
padding={type === 'type-popup'
|
||||||
|
? 'var(--spacing-2) var(--spacing-3) var(--spacing-4)'
|
||||||
|
: type === 'type-aside'
|
||||||
|
? 'var(--spacing-2) var(--spacing-1_5)'
|
||||||
|
: 'var(--spacing-3)'}
|
||||||
|
bottomPadding={type === 'type-popup'
|
||||||
|
? undefined
|
||||||
|
: type === 'type-aside'
|
||||||
|
? 'var(--spacing-2)'
|
||||||
|
: 'var(--spacing-3)'}
|
||||||
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</Scroller>
|
</Scroller>
|
||||||
</div>
|
</div>
|
||||||
{#if type === 'type-aside'}
|
{#if type !== 'type-component'}
|
||||||
<div class="hulyModal-footer">
|
<div class="hulyModal-footer">
|
||||||
<ButtonBase
|
<ButtonBase
|
||||||
type={'type-button'}
|
type={'type-button'}
|
||||||
kind={'primary'}
|
kind={'primary'}
|
||||||
size={'large'}
|
size={type === 'type-aside' ? 'large' : 'medium'}
|
||||||
label={okLabel}
|
label={okLabel}
|
||||||
on:click={okAction}
|
on:click={okAction}
|
||||||
disabled={!canSave}
|
disabled={!canSave}
|
||||||
/>
|
/>
|
||||||
<ButtonBase type={'type-button'} kind={'secondary'} size={'large'} label={ui.string.Cancel} on:click={onCancel} />
|
<ButtonBase
|
||||||
|
type={'type-button'}
|
||||||
|
kind={'secondary'}
|
||||||
|
size={type === 'type-aside' ? 'large' : 'medium'}
|
||||||
|
label={ui.string.Cancel}
|
||||||
|
on:click={onCancel}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
// Licensed under the Eclipse Public License v2.0 (SPDX: EPL-2.0).
|
// Licensed under the Eclipse Public License v2.0 (SPDX: EPL-2.0).
|
||||||
//
|
//
|
||||||
|
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher, onMount } from 'svelte'
|
||||||
import { IntlString, translate } from '@hcengineering/platform'
|
import { IntlString, translate } from '@hcengineering/platform'
|
||||||
import Label from './Label.svelte'
|
import Label from './Label.svelte'
|
||||||
import { themeStore } from '..'
|
import { themeStore } from '..'
|
||||||
@ -17,6 +17,9 @@
|
|||||||
export let error: boolean = false
|
export let error: boolean = false
|
||||||
export let password: boolean = false
|
export let password: boolean = false
|
||||||
export let limit: number = 0
|
export let limit: number = 0
|
||||||
|
export let element: HTMLInputElement | undefined = undefined
|
||||||
|
export let autoFocus: boolean = false
|
||||||
|
export let width: string = ''
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
@ -28,14 +31,23 @@
|
|||||||
})
|
})
|
||||||
$: labeled = kind === 'default' && size === 'large'
|
$: labeled = kind === 'default' && size === 'large'
|
||||||
$: placeholder = labeled ? ' ' : placeholderStr
|
$: placeholder = labeled ? ' ' : placeholderStr
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (autoFocus && element) {
|
||||||
|
autoFocus = false
|
||||||
|
element.focus()
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label class="editbox-wrapper {kind} {size}" class:error class:disabled>
|
<label class="editbox-wrapper {kind} {size}" class:error class:disabled>
|
||||||
{#if password}
|
{#if password}
|
||||||
<input
|
<input
|
||||||
|
bind:this={element}
|
||||||
type="password"
|
type="password"
|
||||||
class="font-regular-14"
|
class="font-regular-14"
|
||||||
class:labeled
|
class:labeled
|
||||||
|
style:width
|
||||||
bind:value
|
bind:value
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
{placeholder}
|
{placeholder}
|
||||||
@ -44,6 +56,7 @@
|
|||||||
{maxlength}
|
{maxlength}
|
||||||
on:change
|
on:change
|
||||||
on:keyup
|
on:keyup
|
||||||
|
on:keydown
|
||||||
on:input
|
on:input
|
||||||
on:blur={() => {
|
on:blur={() => {
|
||||||
dispatch('blur', value)
|
dispatch('blur', value)
|
||||||
@ -51,9 +64,11 @@
|
|||||||
/>
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<input
|
<input
|
||||||
|
bind:this={element}
|
||||||
type="text"
|
type="text"
|
||||||
class="font-regular-14"
|
class="font-regular-14"
|
||||||
class:labeled
|
class:labeled
|
||||||
|
style:width
|
||||||
bind:value
|
bind:value
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
{placeholder}
|
{placeholder}
|
||||||
@ -62,6 +77,7 @@
|
|||||||
{maxlength}
|
{maxlength}
|
||||||
on:change
|
on:change
|
||||||
on:keyup
|
on:keyup
|
||||||
|
on:keydown
|
||||||
on:input
|
on:input
|
||||||
on:blur={() => {
|
on:blur={() => {
|
||||||
dispatch('blur', value)
|
dispatch('blur', value)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let size: 'small' | 'medium' | 'large'
|
export let size: 'small' | 'medium' | 'large'
|
||||||
const fill: string = 'currentColor'
|
export let fill: string = 'currentColor'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svg class="svg-{size}" {fill} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
<svg class="svg-{size}" {fill} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
35
packages/ui/src/components/icons/TableOfContents.svelte
Normal file
35
packages/ui/src/components/icons/TableOfContents.svelte
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2024 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">
|
||||||
|
export let size: 'small' | 'medium' | 'large'
|
||||||
|
const fill: string = 'currentColor'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg class="svg-{size}" {fill} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M26 11.0005C26 10.4482 25.5523 10.0005 25 10.0005H20C19.4477 10.0005 19 10.4482 19 11.0005C19 11.5528 19.4477 12.0005 20 12.0005H25C25.5523 12.0005 26 11.5528 26 11.0005Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M26 16.0005C26 15.4482 25.5523 15.0005 25 15.0005H20C19.4477 15.0005 19 15.4482 19 16.0005C19 16.5528 19.4477 17.0005 20 17.0005H25C25.5523 17.0005 26 16.5528 26 16.0005Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M19 21.0005C19 20.4482 19.4477 20.0005 20 20.0005H25C25.5523 20.0005 26 20.4482 26 21.0005C26 21.5528 25.5523 22.0005 25 22.0005H20C19.4477 22.0005 19 21.5528 19 21.0005Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M6 4.00012C3.79086 4.00012 2 5.79098 2 8.00012V24.0001C2 26.2093 3.79086 28.0001 6 28.0001H26C28.2091 28.0001 30 26.2093 30 24.0001V8.00012C30 5.79098 28.2091 4.00012 26 4.00012H6ZM15 6.00012H6C4.89543 6.00012 4 6.89555 4 8.00012V24.0001C4 25.1047 4.89543 26.0001 6 26.0001H15V6.00012ZM17 6.00012V26.0001H26C27.1046 26.0001 28 25.1047 28 24.0001V8.00012C28 6.89555 27.1046 6.00012 26 6.00012H17Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
@ -131,6 +131,7 @@ export { default as ButtonIcon } from './components/ButtonIcon.svelte'
|
|||||||
export { default as ButtonMenu } from './components/ButtonMenu.svelte'
|
export { default as ButtonMenu } from './components/ButtonMenu.svelte'
|
||||||
export { default as ModernButton } from './components/ModernButton.svelte'
|
export { default as ModernButton } from './components/ModernButton.svelte'
|
||||||
export { default as ModernEditbox } from './components/ModernEditbox.svelte'
|
export { default as ModernEditbox } from './components/ModernEditbox.svelte'
|
||||||
|
export { default as ModernPopup } from './components/ModernPopup.svelte'
|
||||||
export { default as NavItem } from './components/NavItem.svelte'
|
export { default as NavItem } from './components/NavItem.svelte'
|
||||||
export { default as NavGroup } from './components/NavGroup.svelte'
|
export { default as NavGroup } from './components/NavGroup.svelte'
|
||||||
export { default as Modal } from './components/Modal.svelte'
|
export { default as Modal } from './components/Modal.svelte'
|
||||||
@ -201,6 +202,7 @@ export { default as IconDescription } from './components/icons/Description.svelt
|
|||||||
export { default as IconSettings } from './components/icons/Settings.svelte'
|
export { default as IconSettings } from './components/icons/Settings.svelte'
|
||||||
export { default as IconSend } from './components/icons/Send.svelte'
|
export { default as IconSend } from './components/icons/Send.svelte'
|
||||||
export { default as IconSquareExpand } from './components/icons/SquareExpand.svelte'
|
export { default as IconSquareExpand } from './components/icons/SquareExpand.svelte'
|
||||||
|
export { default as IconTableOfContents } from './components/icons/TableOfContents.svelte'
|
||||||
|
|
||||||
export { default as PanelInstance } from './components/PanelInstance.svelte'
|
export { default as PanelInstance } from './components/PanelInstance.svelte'
|
||||||
export { default as Panel } from './components/Panel.svelte'
|
export { default as Panel } from './components/Panel.svelte'
|
||||||
|
@ -49,7 +49,16 @@
|
|||||||
"CreatingAttribute": "Creating an attribute",
|
"CreatingAttribute": "Creating an attribute",
|
||||||
"EditAttribute": "Edit attribute",
|
"EditAttribute": "Edit attribute",
|
||||||
"CreateEnum": "Create enum",
|
"CreateEnum": "Create enum",
|
||||||
|
"EditEnum": "Edit enum",
|
||||||
"Enums": "Enums",
|
"Enums": "Enums",
|
||||||
|
"EnumsSettingHint": "A set or category of things having some property or attribute in common from others by kind, type, or quality.",
|
||||||
|
"EnumTitle": "Enum title",
|
||||||
|
"EnumsCount": "{count, plural, =1 {# option} other {# options}}",
|
||||||
|
"ProjectTypesCount": "{count, plural, =0 {No project types} =1 {# project type} other {# project types}}",
|
||||||
|
"Options": "Options",
|
||||||
|
"EnterOptionTitle": "Enter option title",
|
||||||
|
"NewEnumDialogClose": "Do you want to close this dialog?",
|
||||||
|
"NewEnumDialogCloseNote": "All changes will be lost",
|
||||||
"NewValue": "New value",
|
"NewValue": "New value",
|
||||||
"Leave": "Leave workspace",
|
"Leave": "Leave workspace",
|
||||||
"LeaveDescr": "Are you sure you want to leave the workspace? This action cannot be undone.",
|
"LeaveDescr": "Are you sure you want to leave the workspace? This action cannot be undone.",
|
||||||
|
@ -49,7 +49,16 @@
|
|||||||
"CreatingAttribute": "Создание атрибута",
|
"CreatingAttribute": "Создание атрибута",
|
||||||
"EditAttribute": "Редактирование атрибута",
|
"EditAttribute": "Редактирование атрибута",
|
||||||
"CreateEnum": "Создать справочник",
|
"CreateEnum": "Создать справочник",
|
||||||
|
"EditEnum": "Редактировать справочник",
|
||||||
"Enums": "Справочники",
|
"Enums": "Справочники",
|
||||||
|
"EnumsSettingHint": "Набор или категория вещей, обладающих каким-либо свойством или атрибутом, отличающимся от других по виду, типу или качеству.",
|
||||||
|
"EnumTitle": "Заголовок справочника",
|
||||||
|
"EnumsCount": "{count, plural, one {# вариант} other {# вариантов}}",
|
||||||
|
"ProjectTypesCount": "{count, plural, =0 {Нет типов проектов} =1 {# тип проекта} few {# типа проектов} other {# типов проектов}}",
|
||||||
|
"Options": "Варианты",
|
||||||
|
"EnterOptionTitle": "Введите название варианта",
|
||||||
|
"NewEnumDialogClose": "Вы действительно хотите закрыть окно?",
|
||||||
|
"NewEnumDialogCloseNote": "Все внесенные изменения будут потеряны",
|
||||||
"NewValue": "Новое значение",
|
"NewValue": "Новое значение",
|
||||||
"Leave": "Покинуть рабочее пространство",
|
"Leave": "Покинуть рабочее пространство",
|
||||||
"LeaveDescr": "Вы действительно хотите покинуть рабочее пространство? Отменить это действие невозможно",
|
"LeaveDescr": "Вы действительно хотите покинуть рабочее пространство? Отменить это действие невозможно",
|
||||||
|
@ -26,7 +26,17 @@
|
|||||||
} from '@hcengineering/core'
|
} from '@hcengineering/core'
|
||||||
import { getEmbeddedLabel } from '@hcengineering/platform'
|
import { getEmbeddedLabel } from '@hcengineering/platform'
|
||||||
import presentation, { getClient } from '@hcengineering/presentation'
|
import presentation, { getClient } from '@hcengineering/presentation'
|
||||||
import { AnyComponent, Component, DropdownLabelsIntl, ModernEditbox, Label, Modal } from '@hcengineering/ui'
|
import {
|
||||||
|
AnyComponent,
|
||||||
|
Component,
|
||||||
|
DropdownLabelsIntl,
|
||||||
|
ModernEditbox,
|
||||||
|
Label,
|
||||||
|
Modal,
|
||||||
|
ButtonIcon,
|
||||||
|
IconDelete,
|
||||||
|
IconCopy
|
||||||
|
} from '@hcengineering/ui'
|
||||||
import { DropdownIntlItem } from '@hcengineering/ui/src/types'
|
import { DropdownIntlItem } from '@hcengineering/ui/src/types'
|
||||||
import setting from '../plugin'
|
import setting from '../plugin'
|
||||||
import view from '@hcengineering/view'
|
import view from '@hcengineering/view'
|
||||||
@ -108,6 +118,10 @@
|
|||||||
clearSettingsStore()
|
clearSettingsStore()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<svelte:fragment slot="actions">
|
||||||
|
<ButtonIcon icon={IconDelete} size={'small'} kind={'tertiary'} />
|
||||||
|
<ButtonIcon icon={IconCopy} size={'small'} kind={'tertiary'} />
|
||||||
|
</svelte:fragment>
|
||||||
<div class="hulyModal-content__titleGroup">
|
<div class="hulyModal-content__titleGroup">
|
||||||
<div class="hulyChip-item font-medium-12">
|
<div class="hulyChip-item font-medium-12">
|
||||||
<Label label={setting.string.Custom} />
|
<Label label={setting.string.Custom} />
|
||||||
|
@ -25,7 +25,10 @@
|
|||||||
ModernEditbox,
|
ModernEditbox,
|
||||||
Label,
|
Label,
|
||||||
themeStore,
|
themeStore,
|
||||||
Modal
|
Modal,
|
||||||
|
ButtonIcon,
|
||||||
|
IconDelete,
|
||||||
|
IconCopy
|
||||||
} from '@hcengineering/ui'
|
} from '@hcengineering/ui'
|
||||||
import view from '@hcengineering/view-resources/src/plugin'
|
import view from '@hcengineering/view-resources/src/plugin'
|
||||||
import { clearSettingsStore } from '../store'
|
import { clearSettingsStore } from '../store'
|
||||||
@ -111,6 +114,10 @@
|
|||||||
clearSettingsStore()
|
clearSettingsStore()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<svelte:fragment slot="actions">
|
||||||
|
<ButtonIcon icon={IconDelete} size={'small'} kind={'tertiary'} />
|
||||||
|
<ButtonIcon icon={IconCopy} size={'small'} kind={'tertiary'} />
|
||||||
|
</svelte:fragment>
|
||||||
<div class="hulyModal-content__titleGroup">
|
<div class="hulyModal-content__titleGroup">
|
||||||
{#if attribute.isCustom}
|
{#if attribute.isCustom}
|
||||||
<div class="hulyChip-item font-medium-12">
|
<div class="hulyChip-item font-medium-12">
|
||||||
|
@ -14,22 +14,37 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import core, { Enum } from '@hcengineering/core'
|
import core, { Enum } from '@hcengineering/core'
|
||||||
import presentation, { Card, getClient, MessageBox } from '@hcengineering/presentation'
|
import presentation, { getClient, MessageBox } from '@hcengineering/presentation'
|
||||||
import { ActionIcon, EditBox, IconAdd, IconAttachment, IconDelete, ListView, showPopup } from '@hcengineering/ui'
|
import {
|
||||||
import view from '@hcengineering/view-resources/src/plugin'
|
IconAdd,
|
||||||
|
IconAttachment,
|
||||||
|
IconDelete,
|
||||||
|
showPopup,
|
||||||
|
Modal,
|
||||||
|
ModernEditbox,
|
||||||
|
Label,
|
||||||
|
ButtonIcon,
|
||||||
|
IconMoreV,
|
||||||
|
IconMoreV2,
|
||||||
|
eventToHTMLElement,
|
||||||
|
ModernPopup
|
||||||
|
} from '@hcengineering/ui'
|
||||||
|
import type { DropdownIntlItem } from '@hcengineering/ui'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import setting from '../plugin'
|
import setting from '../plugin'
|
||||||
import EnumValuesList from './EnumValuesList.svelte'
|
import EnumValuesList from './EnumValuesList.svelte'
|
||||||
import Copy from './icons/Copy.svelte'
|
import IconBulletList from './icons/BulletList.svelte'
|
||||||
|
import Report from './icons/Report.svelte'
|
||||||
|
import { IntlString } from '@hcengineering/platform'
|
||||||
|
|
||||||
export let value: Enum | undefined
|
export let value: Enum | undefined
|
||||||
export let name: string = value?.name ?? ''
|
export let name: string = value?.name ?? ''
|
||||||
export let values: string[] = value?.enumValues ?? []
|
export let values: string[] = value?.enumValues ?? []
|
||||||
|
export let title: IntlString = setting.string.EditEnum
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
let list: ListView
|
|
||||||
|
|
||||||
async function save (): Promise<void> {
|
async function save (): Promise<void> {
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
await client.createDoc(core.class.Enum, core.space.Model, {
|
await client.createDoc(core.class.Enum, core.space.Model, {
|
||||||
@ -47,18 +62,29 @@
|
|||||||
|
|
||||||
function add () {
|
function add () {
|
||||||
newValue = newValue.trim()
|
newValue = newValue.trim()
|
||||||
if (newValue.length === 0) return
|
if (matched) return
|
||||||
if (values.includes(newValue)) return
|
if (values.includes(newValue)) return
|
||||||
values.push(newValue)
|
values.push(newValue)
|
||||||
values = values
|
values = values
|
||||||
newValue = ''
|
newValue = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
function remove (value: string) {
|
function remove (value: string) {
|
||||||
values = values.filter((p) => p !== value)
|
values = values.filter((p) => p !== value)
|
||||||
}
|
}
|
||||||
|
const handleKeydown = (evt: KeyboardEvent) => {
|
||||||
|
if (evt.key === 'Enter') {
|
||||||
|
add()
|
||||||
|
}
|
||||||
|
if (evt.key === 'Escape') {
|
||||||
|
newItem = false
|
||||||
|
newValue = ''
|
||||||
|
evt.stopPropagation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let newValue = ''
|
let newValue = ''
|
||||||
|
let newItem: boolean = false
|
||||||
|
let opened: boolean = false
|
||||||
let inputFile: HTMLInputElement
|
let inputFile: HTMLInputElement
|
||||||
|
|
||||||
function processText (text: string): void {
|
function processText (text: string): void {
|
||||||
@ -89,6 +115,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function fileDrop (e: DragEvent) {
|
function fileDrop (e: DragEvent) {
|
||||||
|
dragover = false
|
||||||
const list = e.dataTransfer?.files
|
const list = e.dataTransfer?.files
|
||||||
if (list === undefined || list.length === 0) return
|
if (list === undefined || list.length === 0) return
|
||||||
for (let index = 0; index < list.length; index++) {
|
for (let index = 0; index < list.length; index++) {
|
||||||
@ -114,40 +141,78 @@
|
|||||||
const text = await navigator.clipboard.readText()
|
const text = await navigator.clipboard.readText()
|
||||||
processText(text)
|
processText(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
let dragover = false
|
let dragover = false
|
||||||
const selection: number = 0
|
const selection: number = 0
|
||||||
|
|
||||||
function onKeydown (key: KeyboardEvent): void {
|
// $: filtered = newValue.length > 0 ? values.filter((it) => it.includes(newValue)) : values
|
||||||
if (key.code === 'ArrowUp') {
|
$: matched = values.includes(newValue.trim())
|
||||||
key.stopPropagation()
|
|
||||||
key.preventDefault()
|
// function onDelete () {
|
||||||
list.select(selection - 1)
|
// showPopup(
|
||||||
|
// MessageBox,
|
||||||
|
// {
|
||||||
|
// label: view.string.DeleteObject,
|
||||||
|
// message: view.string.DeleteObjectConfirm,
|
||||||
|
// params: { count: filtered.length }
|
||||||
|
// },
|
||||||
|
// 'top',
|
||||||
|
// (result?: boolean) => {
|
||||||
|
// if (result === true) {
|
||||||
|
// values = values.filter((it) => !filtered.includes(it))
|
||||||
|
// newValue = ''
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
|
||||||
|
const items: (DropdownIntlItem & { action: () => void })[] = [
|
||||||
|
{
|
||||||
|
id: 'import',
|
||||||
|
icon: IconAttachment,
|
||||||
|
label: setting.string.ImportEnum,
|
||||||
|
action: () => {
|
||||||
|
inputFile.click()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'paste',
|
||||||
|
icon: Report,
|
||||||
|
label: setting.string.ImportEnumCopy,
|
||||||
|
action: () => {
|
||||||
|
handleClipboard()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (key.code === 'ArrowDown') {
|
]
|
||||||
key.stopPropagation()
|
|
||||||
key.preventDefault()
|
const openPopup = (ev: MouseEvent): void => {
|
||||||
list.select(selection + 1)
|
if (!opened) {
|
||||||
|
opened = true
|
||||||
|
showPopup(ModernPopup, { items }, eventToHTMLElement(ev), (result) => {
|
||||||
|
if (result) items.find((it) => it.id === result)?.action()
|
||||||
|
opened = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$: filtered = newValue.length > 0 ? values.filter((it) => it.includes(newValue)) : values
|
async function showConfirmationDialog (): Promise<void> {
|
||||||
|
const isEnumEmpty = values.length === 0
|
||||||
|
|
||||||
function onDelete () {
|
if (isEnumEmpty) {
|
||||||
showPopup(
|
dispatch('close')
|
||||||
MessageBox,
|
} else {
|
||||||
{
|
showPopup(
|
||||||
label: view.string.DeleteObject,
|
MessageBox,
|
||||||
message: view.string.DeleteObjectConfirm,
|
{
|
||||||
params: { count: filtered.length }
|
label: setting.string.NewEnumDialogClose,
|
||||||
},
|
message: setting.string.NewEnumDialogCloseNote
|
||||||
'top',
|
},
|
||||||
(result?: boolean) => {
|
'top',
|
||||||
if (result === true) {
|
(result?: boolean) => {
|
||||||
values = values.filter((it) => !filtered.includes(it))
|
if (result === true) dispatch('close')
|
||||||
newValue = ''
|
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -163,57 +228,22 @@
|
|||||||
on:change={fileSelected}
|
on:change={fileSelected}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Card
|
<Modal
|
||||||
label={core.string.Enum}
|
label={title}
|
||||||
|
type={'type-popup'}
|
||||||
okLabel={presentation.string.Save}
|
okLabel={presentation.string.Save}
|
||||||
okAction={save}
|
okAction={save}
|
||||||
canSave={name.trim().length > 0 && values.length > 0}
|
canSave={name.trim().length > 0 && values.length > 0}
|
||||||
on:close={() => {
|
onCancel={() => {
|
||||||
dispatch('close')
|
showConfirmationDialog()
|
||||||
}}
|
}}
|
||||||
on:changeContent
|
|
||||||
>
|
>
|
||||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
<div class="flex-col">
|
||||||
<div class="flex-col" on:keydown={onKeydown}>
|
<ModernEditbox bind:value={name} label={setting.string.EnumTitle} kind={'ghost'} size={'large'} width={'100%'} />
|
||||||
<EditBox bind:value={name} placeholder={core.string.Name} kind={'large-style'} fullSize />
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||||
<div class="flex-between my-4">
|
|
||||||
<EditBox placeholder={presentation.string.Search} kind={'large-style'} bind:value={newValue} fullSize />
|
|
||||||
<div class="flex-row-center flex-no-shrink gap-2 ml-4">
|
|
||||||
<ActionIcon icon={IconAdd} label={presentation.string.Add} action={add} size={'small'} />
|
|
||||||
<ActionIcon
|
|
||||||
icon={Copy}
|
|
||||||
label={setting.string.ImportEnumCopy}
|
|
||||||
action={() => {
|
|
||||||
handleClipboard()
|
|
||||||
}}
|
|
||||||
size={'small'}
|
|
||||||
/>
|
|
||||||
<ActionIcon
|
|
||||||
icon={IconDelete}
|
|
||||||
label={setting.string.Delete}
|
|
||||||
action={() => {
|
|
||||||
onDelete()
|
|
||||||
}}
|
|
||||||
size={'small'}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="scroll" style:margin={'0 -.5rem'}>
|
|
||||||
<div class="box flex max-h-125">
|
|
||||||
<EnumValuesList
|
|
||||||
bind:values
|
|
||||||
bind:filtered
|
|
||||||
on:remove={(e) => {
|
|
||||||
remove(e.detail)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<svelte:fragment slot="footer">
|
|
||||||
<div
|
<div
|
||||||
class="resume flex-center"
|
class="hulyTableAttr-container mt-6"
|
||||||
class:solid={dragover}
|
class:dragDropZone={dragover}
|
||||||
on:dragover|preventDefault={() => {
|
on:dragover|preventDefault={() => {
|
||||||
dragover = true
|
dragover = true
|
||||||
}}
|
}}
|
||||||
@ -222,14 +252,81 @@
|
|||||||
}}
|
}}
|
||||||
on:drop|preventDefault|stopPropagation={fileDrop}
|
on:drop|preventDefault|stopPropagation={fileDrop}
|
||||||
>
|
>
|
||||||
<ActionIcon
|
<div class="hulyTableAttr-header font-medium-12">
|
||||||
icon={IconAttachment}
|
<IconBulletList size={'small'} />
|
||||||
label={setting.string.ImportEnum}
|
<span><Label label={setting.string.Options} /></span>
|
||||||
action={() => {
|
<div class="buttons-group tertiary-textColor">
|
||||||
inputFile.click()
|
<ButtonIcon
|
||||||
}}
|
kind={'tertiary'}
|
||||||
size={'small'}
|
icon={IconMoreV}
|
||||||
/>
|
size={'small'}
|
||||||
|
pressed={opened}
|
||||||
|
inheritColor
|
||||||
|
hasMenu
|
||||||
|
on:click={(ev) => {
|
||||||
|
openPopup(ev)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ButtonIcon
|
||||||
|
kind={'primary'}
|
||||||
|
icon={IconAdd}
|
||||||
|
size={'small'}
|
||||||
|
tooltip={{ label: setting.string.Add }}
|
||||||
|
on:click={() => {
|
||||||
|
newItem = true
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{#if values.length > 0 || newItem}
|
||||||
|
<div class="hulyTableAttr-content options">
|
||||||
|
<EnumValuesList
|
||||||
|
bind:values
|
||||||
|
disableMouseOver={newItem}
|
||||||
|
on:remove={(e) => {
|
||||||
|
remove(e.detail)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{#if newItem}
|
||||||
|
<div class="hulyTableAttr-content__row hovered">
|
||||||
|
<div class="hulyTableAttr-content__row-dragMenu">
|
||||||
|
<IconMoreV2 size={'small'} />
|
||||||
|
</div>
|
||||||
|
<div class="hulyTableAttr-content__row-label font-regular-14 accent grow">
|
||||||
|
<ModernEditbox
|
||||||
|
kind={'ghost'}
|
||||||
|
size={'small'}
|
||||||
|
label={setting.string.EnterOptionTitle}
|
||||||
|
on:keydown={handleKeydown}
|
||||||
|
bind:value={newValue}
|
||||||
|
width={'100%'}
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{#if matched}
|
||||||
|
<div class="hulyChip-item error font-medium-12">
|
||||||
|
<Label label={presentation.string.Match} />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
<ButtonIcon
|
||||||
|
kind={'tertiary'}
|
||||||
|
icon={IconDelete}
|
||||||
|
size={'small'}
|
||||||
|
on:click={() => {
|
||||||
|
newValue = ''
|
||||||
|
newItem = false
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</svelte:fragment>
|
</div>
|
||||||
</Card>
|
</Modal>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.dragDropZone {
|
||||||
|
border: 2px dashed var(--theme-popup-hover);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -15,10 +15,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import core, { Enum } from '@hcengineering/core'
|
import core, { Enum } from '@hcengineering/core'
|
||||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
import { createQuery } from '@hcengineering/presentation'
|
||||||
import {
|
import {
|
||||||
CircleButton,
|
|
||||||
EditBox,
|
|
||||||
eventToHTMLElement,
|
eventToHTMLElement,
|
||||||
IconAdd,
|
IconAdd,
|
||||||
IconMoreH,
|
IconMoreH,
|
||||||
@ -29,7 +27,10 @@
|
|||||||
defineSeparators,
|
defineSeparators,
|
||||||
settingsSeparators,
|
settingsSeparators,
|
||||||
Separator,
|
Separator,
|
||||||
Scroller
|
Scroller,
|
||||||
|
ButtonIcon,
|
||||||
|
IconTableOfContents,
|
||||||
|
ModernButton
|
||||||
} from '@hcengineering/ui'
|
} from '@hcengineering/ui'
|
||||||
import { ContextMenu } from '@hcengineering/view-resources'
|
import { ContextMenu } from '@hcengineering/view-resources'
|
||||||
import setting from '../plugin'
|
import setting from '../plugin'
|
||||||
@ -44,7 +45,6 @@
|
|||||||
let enums: Enum[] = []
|
let enums: Enum[] = []
|
||||||
let selected: Enum | undefined
|
let selected: Enum | undefined
|
||||||
let hovered: number | null = null
|
let hovered: number | null = null
|
||||||
const client = getClient()
|
|
||||||
|
|
||||||
query.query(core.class.Enum, {}, (res) => {
|
query.query(core.class.Enum, {}, (res) => {
|
||||||
enums = res
|
enums = res
|
||||||
@ -54,32 +54,38 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
function create () {
|
function create () {
|
||||||
showPopup(setting.component.EditEnum, {}, 'top')
|
showPopup(setting.component.EditEnum, { title: setting.string.CreateEnum }, 'top')
|
||||||
}
|
}
|
||||||
|
|
||||||
async function update (value: Enum): Promise<void> {
|
|
||||||
await client.update(value, {
|
|
||||||
name: value.name
|
|
||||||
})
|
|
||||||
}
|
|
||||||
defineSeparators('workspaceSettings', settingsSeparators)
|
defineSeparators('workspaceSettings', settingsSeparators)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="hulyComponent">
|
<div class="hulyComponent">
|
||||||
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
|
<Header minimize={!visibleNav} on:resize={(event) => dispatch('change', event.detail)}>
|
||||||
<Breadcrumb icon={setting.icon.Enums} label={setting.string.Enums} size={'large'} isCurrent />
|
<Breadcrumb icon={setting.icon.Enums} label={setting.string.Enums} size={'large'} isCurrent />
|
||||||
|
<svelte:fragment slot="actions">
|
||||||
|
<ModernButton
|
||||||
|
kind={'primary'}
|
||||||
|
icon={IconAdd}
|
||||||
|
label={setting.string.CreateEnum}
|
||||||
|
size={'small'}
|
||||||
|
on:click={create}
|
||||||
|
/>
|
||||||
|
</svelte:fragment>
|
||||||
</Header>
|
</Header>
|
||||||
<div class="hulyComponent-content__container columns">
|
<div class="hulyComponent-content__container columns">
|
||||||
<div class="hulyComponent-content__column">
|
<div class="hulyComponent-content__column">
|
||||||
<div class="flex-between trans-title m-3">
|
<div class="hulyComponent-content__navHeader">
|
||||||
<Label label={setting.string.Enums} />
|
<div class="hulyComponent-content__navHeader-menu">
|
||||||
<CircleButton icon={IconAdd} size="medium" on:click={create} />
|
<ButtonIcon kind={'tertiary'} icon={IconTableOfContents} size={'small'} inheritColor />
|
||||||
|
</div>
|
||||||
|
<div class="hulyComponent-content__navHeader-hint paragraph-regular-14">
|
||||||
|
<Label label={setting.string.EnumsSettingHint} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overflow-y-auto">
|
<Scroller>
|
||||||
{#each enums as value, i}
|
{#each enums as value, i}
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<button
|
||||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
||||||
<div
|
|
||||||
class="enum__list-item"
|
class="enum__list-item"
|
||||||
class:hovered={hovered === i}
|
class:hovered={hovered === i}
|
||||||
class:selected={selected === value}
|
class:selected={selected === value}
|
||||||
@ -87,21 +93,27 @@
|
|||||||
selected = value
|
selected = value
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<EditBox bind:value={value.name} on:change={() => update(value)} />
|
<div class="flex-col">
|
||||||
<div
|
<span class="font-regular-14 overflow-label">{value.name}</span>
|
||||||
class="hover-trans"
|
<span class="font-regular-12 secondary-textColor overflow-label">
|
||||||
on:click|stopPropagation={(ev) => {
|
<Label label={setting.string.EnumsCount} params={{ count: value.enumValues.length }} />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<ButtonIcon
|
||||||
|
kind={'tertiary'}
|
||||||
|
icon={IconMoreH}
|
||||||
|
size={'small'}
|
||||||
|
pressed={hovered === i}
|
||||||
|
on:click={(ev) => {
|
||||||
hovered = i
|
hovered = i
|
||||||
showPopup(ContextMenu, { object: value }, eventToHTMLElement(ev), () => {
|
showPopup(ContextMenu, { object: value }, eventToHTMLElement(ev), () => {
|
||||||
hovered = null
|
hovered = null
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
<IconMoreH size={'medium'} />
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</Scroller>
|
||||||
</div>
|
</div>
|
||||||
<Separator name={'workspaceSettings'} index={0} color={'var(--theme-divider-color)'} />
|
<Separator name={'workspaceSettings'} index={0} color={'var(--theme-divider-color)'} />
|
||||||
<div class="hulyComponent-content__column content">
|
<div class="hulyComponent-content__column content">
|
||||||
@ -121,21 +133,27 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-height: 2.5rem;
|
margin: 0 var(--spacing-1_5);
|
||||||
margin: 0 0.75rem;
|
padding: var(--spacing-1) var(--spacing-1_25);
|
||||||
padding: 0 1.25rem;
|
text-align: left;
|
||||||
border: 1px solid transparent;
|
border: none;
|
||||||
border-radius: 12px;
|
border-radius: var(--small-BorderRadius);
|
||||||
cursor: pointer;
|
outline: none;
|
||||||
|
|
||||||
|
& :global(button.type-button-icon) {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
&.hovered,
|
&.hovered,
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--theme-button-hovered);
|
background-color: var(--theme-button-hovered);
|
||||||
|
|
||||||
|
& :global(button.type-button-icon) {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&.selected {
|
&.selected {
|
||||||
background-color: var(--theme-button-default);
|
background-color: var(--theme-button-default);
|
||||||
border-color: var(--theme-button-border);
|
cursor: default;
|
||||||
cursor: auto;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -15,25 +15,43 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Enum } from '@hcengineering/core'
|
import { Enum } from '@hcengineering/core'
|
||||||
import presentation, { getClient, MessageBox } from '@hcengineering/presentation'
|
import presentation, { getClient, MessageBox } from '@hcengineering/presentation'
|
||||||
import { ActionIcon, EditBox, IconAdd, IconAttachment, IconDelete, showPopup } from '@hcengineering/ui'
|
import {
|
||||||
import view from '@hcengineering/view-resources/src/plugin'
|
ModernEditbox,
|
||||||
|
IconAdd,
|
||||||
|
IconAttachment,
|
||||||
|
IconDelete,
|
||||||
|
showPopup,
|
||||||
|
ModernButton,
|
||||||
|
Label,
|
||||||
|
ButtonIcon,
|
||||||
|
IconMoreV,
|
||||||
|
IconMoreV2,
|
||||||
|
ModernPopup,
|
||||||
|
eventToHTMLElement
|
||||||
|
} from '@hcengineering/ui'
|
||||||
|
import type { DropdownIntlItem } from '@hcengineering/ui'
|
||||||
import setting from '../plugin'
|
import setting from '../plugin'
|
||||||
import EnumValuesList from './EnumValuesList.svelte'
|
import EnumValuesList from './EnumValuesList.svelte'
|
||||||
import Copy from './icons/Copy.svelte'
|
import IconCrossedArrows from './icons/CrossedArrows.svelte'
|
||||||
|
import IconBulletList from './icons/BulletList.svelte'
|
||||||
|
import Report from './icons/Report.svelte'
|
||||||
|
|
||||||
export let value: Enum
|
export let value: Enum
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
|
|
||||||
let newValue = ''
|
let newValue: string = ''
|
||||||
|
let newItem: boolean = false
|
||||||
|
let opened: boolean = false
|
||||||
|
|
||||||
async function add () {
|
async function add () {
|
||||||
if (newValue.trim().length === 0) return
|
if (newValue.trim().length === 0) return
|
||||||
if (value.enumValues.includes(newValue.trim())) return
|
if (matched) return
|
||||||
await client.update(value, {
|
await client.update(value, {
|
||||||
$push: { enumValues: newValue }
|
$push: { enumValues: newValue }
|
||||||
})
|
})
|
||||||
newValue = ''
|
newValue = ''
|
||||||
|
newItem = false
|
||||||
}
|
}
|
||||||
|
|
||||||
async function remove (target: string) {
|
async function remove (target: string) {
|
||||||
@ -45,8 +63,13 @@
|
|||||||
if (evt.key === 'Enter') {
|
if (evt.key === 'Enter') {
|
||||||
add()
|
add()
|
||||||
}
|
}
|
||||||
|
if (evt.key === 'Escape') {
|
||||||
|
newItem = false
|
||||||
|
newValue = ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$: filtered = newValue.length > 0 ? value.enumValues.filter((it) => it.includes(newValue)) : value.enumValues
|
// $: filtered = newValue.length > 0 ? value.enumValues.filter((it) => it.includes(newValue)) : []
|
||||||
|
$: matched = value.enumValues.includes(newValue.trim())
|
||||||
|
|
||||||
async function handleClipboard (): Promise<void> {
|
async function handleClipboard (): Promise<void> {
|
||||||
const text = await navigator.clipboard.readText()
|
const text = await navigator.clipboard.readText()
|
||||||
@ -81,31 +104,84 @@
|
|||||||
}
|
}
|
||||||
inputFile.value = ''
|
inputFile.value = ''
|
||||||
}
|
}
|
||||||
function onDelete () {
|
// function onDelete () {
|
||||||
showPopup(
|
// showPopup(
|
||||||
MessageBox,
|
// MessageBox,
|
||||||
{
|
// {
|
||||||
label: view.string.DeleteObject,
|
// label: view.string.DeleteObject,
|
||||||
message: view.string.DeleteObjectConfirm,
|
// message: view.string.DeleteObjectConfirm,
|
||||||
params: { count: filtered.length }
|
// params: { count: filtered.length }
|
||||||
},
|
// },
|
||||||
undefined,
|
// undefined,
|
||||||
(result?: boolean) => {
|
// (result?: boolean) => {
|
||||||
if (result === true) {
|
// if (result === true) {
|
||||||
client.update(value, {
|
// client.update(value, {
|
||||||
$pull: { enumValues: { $in: filtered } }
|
// $pull: { enumValues: { $in: filtered } }
|
||||||
})
|
// })
|
||||||
newValue = ''
|
// newValue = ''
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
)
|
// )
|
||||||
|
// }
|
||||||
|
|
||||||
|
async function update (value: Enum): Promise<void> {
|
||||||
|
await client.update(value, {
|
||||||
|
name: value.name
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onDrop () {
|
async function onDrop () {
|
||||||
await client.update(value, { enumValues: value.enumValues })
|
await client.update(value, { enumValues: value.enumValues })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const items: (DropdownIntlItem & { action: () => void })[] = [
|
||||||
|
{
|
||||||
|
id: 'import',
|
||||||
|
icon: IconAttachment,
|
||||||
|
label: setting.string.ImportEnum,
|
||||||
|
action: () => {
|
||||||
|
inputFile.click()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'paste',
|
||||||
|
icon: Report,
|
||||||
|
label: setting.string.ImportEnumCopy,
|
||||||
|
action: () => {
|
||||||
|
handleClipboard()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const openPopup = (ev: MouseEvent): void => {
|
||||||
|
if (!opened) {
|
||||||
|
opened = true
|
||||||
|
showPopup(ModernPopup, { items }, eventToHTMLElement(ev), (result) => {
|
||||||
|
if (result) items.find((it) => it.id === result)?.action()
|
||||||
|
opened = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<div class="flex-between flex-gap-2">
|
||||||
|
<ModernEditbox
|
||||||
|
bind:value={value.name}
|
||||||
|
label={setting.string.EnumTitle}
|
||||||
|
kind={'ghost'}
|
||||||
|
size={'large'}
|
||||||
|
on:change={() => update(value)}
|
||||||
|
/>
|
||||||
|
<ModernButton
|
||||||
|
icon={IconCrossedArrows}
|
||||||
|
label={setting.string.ProjectTypesCount}
|
||||||
|
labelParams={{ count: 0 }}
|
||||||
|
disabled
|
||||||
|
kind={'tertiary'}
|
||||||
|
size={'medium'}
|
||||||
|
hasMenu
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<input
|
<input
|
||||||
bind:this={inputFile}
|
bind:this={inputFile}
|
||||||
multiple
|
multiple
|
||||||
@ -115,56 +191,74 @@
|
|||||||
style="display: none"
|
style="display: none"
|
||||||
on:change={fileSelected}
|
on:change={fileSelected}
|
||||||
/>
|
/>
|
||||||
<div class="flex-grow">
|
|
||||||
<div class="flex-between mb-4">
|
<div class="hulyTableAttr-container mt-6">
|
||||||
<EditBox
|
<div class="hulyTableAttr-header font-medium-12">
|
||||||
placeholder={presentation.string.Search}
|
<IconBulletList size={'small'} />
|
||||||
on:keydown={handleKeydown}
|
<span><Label label={setting.string.Options} /></span>
|
||||||
kind="large-style"
|
<div class="buttons-group tertiary-textColor">
|
||||||
bind:value={newValue}
|
<ButtonIcon
|
||||||
/>
|
kind={'tertiary'}
|
||||||
<div class="flex-row-center gap-2">
|
icon={IconMoreV}
|
||||||
<ActionIcon
|
size={'small'}
|
||||||
|
pressed={opened}
|
||||||
|
inheritColor
|
||||||
|
hasMenu
|
||||||
|
on:click={(ev) => {
|
||||||
|
openPopup(ev)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ButtonIcon
|
||||||
|
kind={'primary'}
|
||||||
icon={IconAdd}
|
icon={IconAdd}
|
||||||
label={setting.string.Add}
|
|
||||||
action={add}
|
|
||||||
size={'small'}
|
size={'small'}
|
||||||
disabled={value.enumValues.includes(newValue.trim())}
|
tooltip={{ label: setting.string.Add }}
|
||||||
/>
|
on:click={() => {
|
||||||
<ActionIcon
|
newItem = true
|
||||||
icon={IconAttachment}
|
|
||||||
label={setting.string.ImportEnum}
|
|
||||||
action={() => {
|
|
||||||
inputFile.click()
|
|
||||||
}}
|
}}
|
||||||
size={'small'}
|
|
||||||
/>
|
|
||||||
<ActionIcon
|
|
||||||
icon={Copy}
|
|
||||||
label={setting.string.ImportEnumCopy}
|
|
||||||
action={() => {
|
|
||||||
handleClipboard()
|
|
||||||
}}
|
|
||||||
size={'small'}
|
|
||||||
/>
|
|
||||||
<ActionIcon
|
|
||||||
icon={IconDelete}
|
|
||||||
label={setting.string.Delete}
|
|
||||||
action={() => {
|
|
||||||
onDelete()
|
|
||||||
}}
|
|
||||||
size={'small'}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="scroll">
|
{#if value.enumValues.length > 0 || newItem}
|
||||||
<div class="box">
|
<div class="hulyTableAttr-content options">
|
||||||
<EnumValuesList
|
<EnumValuesList
|
||||||
bind:values={value.enumValues}
|
bind:values={value.enumValues}
|
||||||
bind:filtered
|
disableMouseOver={newItem}
|
||||||
on:remove={(e) => remove(e.detail)}
|
on:remove={(e) => remove(e.detail)}
|
||||||
on:drop={onDrop}
|
on:drop={onDrop}
|
||||||
/>
|
/>
|
||||||
|
{#if newItem}
|
||||||
|
<div class="hulyTableAttr-content__row hovered">
|
||||||
|
<div class="hulyTableAttr-content__row-dragMenu">
|
||||||
|
<IconMoreV2 size={'small'} />
|
||||||
|
</div>
|
||||||
|
<div class="hulyTableAttr-content__row-label font-regular-14 accent grow">
|
||||||
|
<ModernEditbox
|
||||||
|
kind={'ghost'}
|
||||||
|
size={'small'}
|
||||||
|
label={setting.string.EnterOptionTitle}
|
||||||
|
on:keydown={handleKeydown}
|
||||||
|
bind:value={newValue}
|
||||||
|
width={'100%'}
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{#if matched}
|
||||||
|
<div class="hulyChip-item error font-medium-12">
|
||||||
|
<Label label={presentation.string.Match} />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
<ButtonIcon
|
||||||
|
kind={'tertiary'}
|
||||||
|
icon={IconDelete}
|
||||||
|
size={'small'}
|
||||||
|
on:click={() => {
|
||||||
|
newValue = ''
|
||||||
|
newItem = false
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,20 +13,29 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import presentation from '@hcengineering/presentation'
|
import {
|
||||||
import { ActionIcon, IconCircles, IconDelete, Label, Scroller } from '@hcengineering/ui'
|
ModernPopup,
|
||||||
|
IconDelete,
|
||||||
|
ButtonIcon,
|
||||||
|
IconMoreV,
|
||||||
|
IconMoreV2,
|
||||||
|
showPopup,
|
||||||
|
eventToHTMLElement
|
||||||
|
} from '@hcengineering/ui'
|
||||||
|
import type { DropdownIntlItem } from '@hcengineering/ui'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import setting from '../plugin'
|
import setting from '../plugin'
|
||||||
|
|
||||||
export let values: string[]
|
export let values: string[]
|
||||||
export let filtered: string[]
|
export let disableMouseOver: boolean = false
|
||||||
|
|
||||||
let selected: string | undefined
|
let selected: string | undefined
|
||||||
|
let opened: number | undefined = undefined
|
||||||
const elements: HTMLElement[] = []
|
const elements: HTMLElement[] = []
|
||||||
|
|
||||||
function dragswap (ev: MouseEvent, item: string): boolean {
|
function dragswap (ev: MouseEvent, item: string): boolean {
|
||||||
const s = filtered.findIndex((p) => p === selected)
|
const s = values.findIndex((p) => p === selected)
|
||||||
const i = filtered.findIndex((p) => p === item)
|
const i = values.findIndex((p) => p === item)
|
||||||
if (i < s) {
|
if (i < s) {
|
||||||
return ev.offsetY < elements[i].offsetHeight / 2
|
return ev.offsetY < elements[i].offsetHeight / 2
|
||||||
} else if (i > s) {
|
} else if (i > s) {
|
||||||
@ -52,45 +61,79 @@
|
|||||||
async function onDrop () {
|
async function onDrop () {
|
||||||
dispatch('drop')
|
dispatch('drop')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const items: (DropdownIntlItem & { action: () => void })[] = [
|
||||||
|
{
|
||||||
|
id: 'delete',
|
||||||
|
icon: IconDelete,
|
||||||
|
label: setting.string.Delete,
|
||||||
|
action: () => {
|
||||||
|
if (opened !== undefined) {
|
||||||
|
remove(values[opened])
|
||||||
|
opened = undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
function openPopup (ev: MouseEvent, n: number) {
|
||||||
|
if (opened === undefined) {
|
||||||
|
opened = n
|
||||||
|
showPopup(ModernPopup, { items }, eventToHTMLElement(ev), (result) => {
|
||||||
|
if (result) {
|
||||||
|
switch (result) {
|
||||||
|
case 'delete':
|
||||||
|
remove(values[n])
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
opened = undefined
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Scroller>
|
{#each values as item, i}
|
||||||
{#each filtered as item, i}
|
<button
|
||||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
bind:this={elements[i]}
|
||||||
<div
|
draggable={!disableMouseOver}
|
||||||
class="flex-between flex-nowrap item step-tb25"
|
class="hulyTableAttr-content__row"
|
||||||
draggable={true}
|
class:disableMouseOver
|
||||||
bind:this={elements[i]}
|
class:hovered={opened === i && !disableMouseOver}
|
||||||
on:dragover|preventDefault={(ev) => {
|
class:selected={selected === item}
|
||||||
dragover(ev, item)
|
on:dragover|preventDefault={(ev) => {
|
||||||
}}
|
dragover(ev, item)
|
||||||
on:drop|preventDefault={onDrop}
|
}}
|
||||||
on:dragstart={() => {
|
on:drop|preventDefault={onDrop}
|
||||||
selected = item
|
on:dragstart={() => {
|
||||||
}}
|
selected = item
|
||||||
on:dragend={() => {
|
}}
|
||||||
selected = undefined
|
on:dragend={() => {
|
||||||
}}
|
selected = undefined
|
||||||
>
|
}}
|
||||||
<div class="flex-row-center">
|
>
|
||||||
<div class="circles-mark"><IconCircles size={'small'} /></div>
|
<button class="hulyTableAttr-content__row-dragMenu" class:drag={!disableMouseOver}>
|
||||||
<span class="overflow-label mx-2">{item}</span>
|
<IconMoreV2 size={'small'} />
|
||||||
</div>
|
</button>
|
||||||
<ActionIcon
|
<div class="hulyTableAttr-content__row-label font-regular-14 accent">
|
||||||
icon={IconDelete}
|
{item}
|
||||||
label={setting.string.Delete}
|
|
||||||
action={() => {
|
|
||||||
remove(item)
|
|
||||||
}}
|
|
||||||
size={'small'}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
<div class="hulyTableAttr-content__row-label grow" />
|
||||||
{#if filtered.length}<div class="antiVSpacer x4" />{/if}
|
{#if !disableMouseOver}
|
||||||
</Scroller>
|
<ButtonIcon
|
||||||
{#if filtered.length === 0}
|
kind={'tertiary'}
|
||||||
<Label label={presentation.string.NoMatchesFound} />
|
icon={IconMoreV}
|
||||||
{/if}
|
iconProps={{ fill: 'var(--global-tertiary-TextColor)' }}
|
||||||
|
size={'small'}
|
||||||
|
pressed={opened === i}
|
||||||
|
hasMenu
|
||||||
|
on:click={(ev) => {
|
||||||
|
openPopup(ev, i)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
{/each}
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.item {
|
.item {
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2024 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">
|
||||||
|
export let size: 'small' | 'medium' | 'large'
|
||||||
|
const fill: string = 'currentColor'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg class="svg-{size}" {fill} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M4 9C5.10457 9 6 8.10457 6 7C6 5.89543 5.10457 5 4 5C2.89543 5 2 5.89543 2 7C2 8.10457 2.89543 9 4 9Z" />
|
||||||
|
<path
|
||||||
|
d="M9 7C9 6.44772 9.44772 6 10 6H29C29.5523 6 30 6.44772 30 7C30 7.55228 29.5523 8 29 8H10C9.44772 8 9 7.55228 9 7Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M9 16C9 15.4477 9.44772 15 10 15H29C29.5523 15 30 15.4477 30 16C30 16.5523 29.5523 17 29 17H10C9.44772 17 9 16.5523 9 16Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M10 24C9.44772 24 9 24.4477 9 25C9 25.5523 9.44772 26 10 26H29C29.5523 26 30 25.5523 30 25C30 24.4477 29.5523 24 29 24H10Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M6 16C6 17.1046 5.10457 18 4 18C2.89543 18 2 17.1046 2 16C2 14.8954 2.89543 14 4 14C5.10457 14 6 14.8954 6 16Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M4 27C5.10457 27 6 26.1046 6 25C6 23.8954 5.10457 23 4 23C2.89543 23 2 23.8954 2 25C2 26.1046 2.89543 27 4 27Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
@ -0,0 +1,24 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2024 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">
|
||||||
|
export let size: 'small' | 'medium' | 'large'
|
||||||
|
const fill: string = 'currentColor'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg class="svg-{size}" {fill} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M26.1696 9.00012L22.5898 12.5899L23.9998 13.9999L29.9998 7.99988L23.9998 1.99988L22.5898 3.40988L26.1698 6.99988L21.7712 7.00012C19.7025 7.00012 17.7797 8.06584 16.6832 9.82013L14 14.1133L11.3168 9.82013C10.2203 8.06584 8.2975 7.00012 6.22876 7.00012H3C2.44772 7.00012 2 7.44784 2 8.00012C2 8.55241 2.44772 9.00012 3 9.00012H6.22876C7.60792 9.00012 8.8898 9.7106 9.62075 10.8801L12.8208 16.0001L9.62075 21.1201C8.8898 22.2896 7.60792 23.0001 6.22876 23.0001H3C2.44772 23.0001 2 23.4478 2 24.0001C2 24.5524 2.44772 25.0001 3 25.0001H6.22876C8.2975 25.0001 10.2203 23.9344 11.3168 22.1801L14 17.8869L16.6832 22.1801C17.7797 23.9344 19.7025 25.0001 21.7712 25.0001H26.1696L22.5898 28.5899L23.9998 29.9999L29.9998 23.9999L23.9998 17.9999L22.5898 19.4099L26.1698 22.9999L21.7712 23.0001C20.3921 23.0001 19.1102 22.2896 18.3792 21.1201L15.1792 16.0001L18.3792 10.8801C19.1102 9.7106 20.3921 9.00012 21.7712 9.00012H26.1696Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
35
plugins/setting-resources/src/components/icons/Report.svelte
Normal file
35
plugins/setting-resources/src/components/icons/Report.svelte
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2024 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">
|
||||||
|
export let size: 'small' | 'medium' | 'large'
|
||||||
|
const fill: string = 'currentColor'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg class="svg-{size}" {fill} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M10 14.0005C9.44772 14.0005 9 14.4482 9 15.0005C9 15.5528 9.44772 16.0005 10 16.0005H22C22.5523 16.0005 23 15.5528 23 15.0005C23 14.4482 22.5523 14.0005 22 14.0005H10Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M9 19.0005C9 18.4482 9.44772 18.0005 10 18.0005H18C18.5523 18.0005 19 18.4482 19 19.0005C19 19.5528 18.5523 20.0005 18 20.0005H10C9.44772 20.0005 9 19.5528 9 19.0005Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M10 22.0005C9.44772 22.0005 9 22.4482 9 23.0005C9 23.5528 9.44772 24.0005 10 24.0005H16C16.5523 24.0005 17 23.5528 17 23.0005C17 22.4482 16.5523 22.0005 16 22.0005H10Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M19 2.00049C20.3062 2.00049 21.4175 2.8353 21.8293 4.00049H23C25.2091 4.00049 27 5.79135 27 8.00049V26.0005C27 28.2096 25.2091 30.0005 23 30.0005H9C6.79086 30.0005 5 28.2096 5 26.0005V8.00049C5 5.79135 6.79086 4.00049 9 4.00049H10.1707C10.5825 2.8353 11.6938 2.00049 13 2.00049H19ZM12 5.00049C12 4.4482 12.4477 4.00049 13 4.00049H19C19.5523 4.00049 20 4.4482 20 5.00049C20 5.55277 19.5523 6.00049 19 6.00049H13C12.4477 6.00049 12 5.55277 12 5.00049ZM19 8.00049C20.3062 8.00049 21.4175 7.16568 21.8293 6.00049H23C24.1046 6.00049 25 6.89592 25 8.00049V26.0005C25 27.1051 24.1046 28.0005 23 28.0005H9C7.89543 28.0005 7 27.1051 7 26.0005V8.00049C7 6.89592 7.89543 6.00049 9 6.00049H10.1707C10.5825 7.16568 11.6938 8.00049 13 8.00049H19Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
@ -44,7 +44,16 @@ export default mergeIds(settingId, setting, {
|
|||||||
CreatingAttribute: '' as IntlString,
|
CreatingAttribute: '' as IntlString,
|
||||||
EditAttribute: '' as IntlString,
|
EditAttribute: '' as IntlString,
|
||||||
CreateEnum: '' as IntlString,
|
CreateEnum: '' as IntlString,
|
||||||
|
EditEnum: '' as IntlString,
|
||||||
Enums: '' as IntlString,
|
Enums: '' as IntlString,
|
||||||
|
EnumsSettingHint: '' as IntlString,
|
||||||
|
EnumTitle: '' as IntlString,
|
||||||
|
EnumsCount: '' as IntlString,
|
||||||
|
ProjectTypesCount: '' as IntlString,
|
||||||
|
Options: '' as IntlString,
|
||||||
|
EnterOptionTitle: '' as IntlString,
|
||||||
|
NewEnumDialogClose: '' as IntlString,
|
||||||
|
NewEnumDialogCloseNote: '' as IntlString,
|
||||||
NewValue: '' as IntlString,
|
NewValue: '' as IntlString,
|
||||||
Leave: '' as IntlString,
|
Leave: '' as IntlString,
|
||||||
LeaveDescr: '' as IntlString,
|
LeaveDescr: '' as IntlString,
|
||||||
|
@ -27,7 +27,10 @@
|
|||||||
TextArea,
|
TextArea,
|
||||||
getPlatformColorDef,
|
getPlatformColorDef,
|
||||||
themeStore,
|
themeStore,
|
||||||
EmojiPopup
|
EmojiPopup,
|
||||||
|
ButtonIcon,
|
||||||
|
IconDelete,
|
||||||
|
IconCopy
|
||||||
} from '@hcengineering/ui'
|
} from '@hcengineering/ui'
|
||||||
import { statusStore, ColorsPopup } from '@hcengineering/view-resources'
|
import { statusStore, ColorsPopup } from '@hcengineering/view-resources'
|
||||||
import view from '@hcengineering/view-resources/src/plugin'
|
import view from '@hcengineering/view-resources/src/plugin'
|
||||||
@ -137,6 +140,10 @@
|
|||||||
clearSettingsStore()
|
clearSettingsStore()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<svelte:fragment slot="actions">
|
||||||
|
<ButtonIcon icon={IconDelete} size={'small'} kind={'tertiary'} />
|
||||||
|
<ButtonIcon icon={IconCopy} size={'small'} kind={'tertiary'} />
|
||||||
|
</svelte:fragment>
|
||||||
<div class="hulyModal-content__titleGroup">
|
<div class="hulyModal-content__titleGroup">
|
||||||
<ModernEditbox bind:value label={task.string.StatusName} size={'large'} kind={'ghost'} />
|
<ModernEditbox bind:value label={task.string.StatusName} size={'large'} kind={'ghost'} />
|
||||||
<TextArea
|
<TextArea
|
||||||
|
Loading…
Reference in New Issue
Block a user