mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-22 11:42:30 +03:00
UBER-64,-231,-229: updated CreateProject and SelectAvatar layouts, fixed bugs (#3253)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
parent
0298ff1c8d
commit
ea6612cdb7
@ -127,7 +127,7 @@ export class TTypeMilestoneStatus extends TType {}
|
||||
@Model(tracker.class.Project, core.class.Space, DOMAIN_SPACE)
|
||||
@UX(tracker.string.Project, tracker.icon.Issues, 'Project', 'name')
|
||||
export class TProject extends TSpace implements Project {
|
||||
@Prop(TypeString(), tracker.string.Identifier)
|
||||
@Prop(TypeString(), tracker.string.ProjectIdentifier)
|
||||
@Index(IndexKind.FullText)
|
||||
identifier!: IntlString
|
||||
|
||||
|
@ -30,7 +30,9 @@
|
||||
export let fullSize: boolean = false
|
||||
export let hideAttachments: boolean = false
|
||||
export let hideSubheader: boolean = false
|
||||
export let accentHeader: boolean = false
|
||||
export let gap: string | undefined = undefined
|
||||
export let width: 'large' | 'medium' | 'small' | 'x-small' = 'large'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@ -39,7 +41,7 @@
|
||||
|
||||
<form
|
||||
id={label}
|
||||
class="antiCard {$deviceInfo.isMobile ? 'mobile' : 'dialog'}"
|
||||
class="antiCard {$deviceInfo.isMobile ? 'mobile' : 'dialog'} {width}"
|
||||
class:full={fullSize}
|
||||
on:submit|preventDefault={() => {}}
|
||||
use:resizeObserver={() => {
|
||||
@ -52,7 +54,7 @@
|
||||
<slot name="header" />
|
||||
<span class="antiCard-header__divider"><IconForward size={'small'} /></span>
|
||||
{/if}
|
||||
<span class="antiCard-header__title">
|
||||
<span class="antiCard-header__title" class:accentHeader>
|
||||
{#if $$slots.title}
|
||||
<slot name="title" {label} labelProps={labelProps ?? {}} />
|
||||
{:else}
|
||||
|
@ -36,6 +36,7 @@
|
||||
export let enableFormatting = false
|
||||
export let autofocus = false
|
||||
export let enableBackReferences: boolean = false
|
||||
export let isScrollable: boolean = true
|
||||
|
||||
const Mode = {
|
||||
View: 1,
|
||||
@ -159,6 +160,7 @@
|
||||
{focusable}
|
||||
{enableFormatting}
|
||||
{autofocus}
|
||||
{isScrollable}
|
||||
extensions={enableBackReferences ? [completionPlugin] : []}
|
||||
bind:content={rawValue}
|
||||
bind:this={textEditor}
|
||||
|
@ -646,13 +646,19 @@
|
||||
// max-height: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
&:not(.showScroll)::-webkit-scrollbar-thumb {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
&.scrollable {
|
||||
overflow: auto;
|
||||
max-height: var(--texteditor-maxheight);
|
||||
|
||||
&.showScroll {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
&:not(.showScroll) {
|
||||
overflow-y: hidden;
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@
|
||||
--primary-button-hovered: #1A53AF;
|
||||
--primary-button-pressed: #144CA8;
|
||||
--primary-button-focused: #144CA8;
|
||||
--primary-button-disabled: #6E9FED;
|
||||
--primary-button-disabled: #484662;
|
||||
--primary-button-focused-border: #6E9FED;
|
||||
--primary-button-border: rgba(255, 255, 255, .09);
|
||||
--primary-button-outline: rgba(87, 132, 255, .3); // OLD
|
||||
@ -142,6 +142,13 @@
|
||||
--theme-calendar-holiday-bgcolor: rgba(235, 87, 87, .1);
|
||||
--theme-calendar-weekend-bgcolor: rgba(242, 153, 74, .05);
|
||||
|
||||
--theme-toggle-sw-color: #fff;
|
||||
--theme-toggle-on-sw-color: #fff;
|
||||
--theme-toggle-bg-color: rgba(120, 120, 128, 0.32);
|
||||
--theme-toggle-bg-hover: rgba(120, 120, 128, 0.64);
|
||||
--theme-toggle-on-bg-color: #205dc2;
|
||||
--theme-toggle-on-bg-hover: #1A53AF;
|
||||
|
||||
--theme-error-color: #eb5757;
|
||||
--theme-urgent-color: #F5694A;
|
||||
--theme-warning-color: #f2994a;
|
||||
@ -208,13 +215,6 @@
|
||||
--dangerous-bg-hover: #ff6464;
|
||||
--dangerous-shadow: var(--dangerous-bg-color) 0px 0px 12px -1px;
|
||||
|
||||
--toggle-sw-color: #27282b;
|
||||
--toggle-on-sw-color: #fff;
|
||||
--toggle-bg-color: #3c3f44;
|
||||
--toggle-bg-hover: #45484e;
|
||||
--toggle-on-bg-color: #5e6ad2;
|
||||
--toggle-on-bg-hover: #828fff;
|
||||
|
||||
--incoming-msg: rgba(67, 67, 72, .3);
|
||||
--outcoming-msg: rgba(67, 67, 72, .6);
|
||||
|
||||
@ -226,12 +226,12 @@
|
||||
/* Light Theme */
|
||||
.theme-light {
|
||||
--primary-button-color: #fff;
|
||||
--primary-button-enabled: rgb(43, 82, 144);
|
||||
--primary-button-transparent: rgba(43, 82, 144, 0.2);
|
||||
--primary-button-hovered: #1A53AF; // DARK
|
||||
--primary-button-pressed: #144CA8; // DARK
|
||||
--primary-button-focused: #144CA8; // DARK
|
||||
--primary-button-disabled: #6E9FED; // DARK
|
||||
--primary-button-enabled: #205DC2;
|
||||
--primary-button-transparent: rgba(32, 93, 194, 0.2);
|
||||
--primary-button-hovered: #1A53AF;
|
||||
--primary-button-pressed: #144CA8;
|
||||
--primary-button-focused: #144CA8;
|
||||
--primary-button-disabled: #EBEBEB;
|
||||
--primary-button-focused-border: #6E9FED; // DARK
|
||||
--primary-button-border: rgba(255, 255, 255, .09);
|
||||
--primary-button-outline: rgba(87, 132, 255, .3); // OLD
|
||||
@ -313,6 +313,12 @@
|
||||
--theme-calendar-today-bgcolor: rgba(43, 81, 144, .1);
|
||||
--theme-calendar-holiday-bgcolor: rgba(235, 87, 87, .1);
|
||||
--theme-calendar-weekend-bgcolor: rgba(242, 153, 74, .1);
|
||||
--theme-toggle-sw-color: #fff;
|
||||
--theme-toggle-on-sw-color: #fff;
|
||||
--theme-toggle-bg-color: rgba(120, 120, 128, 0.32);
|
||||
--theme-toggle-bg-hover: rgba(120, 120, 128, 0.64);
|
||||
--theme-toggle-on-bg-color: #205dc2;
|
||||
--theme-toggle-on-bg-hover: #1A53AF;
|
||||
|
||||
--theme-error-color: #eb5757; // Dark
|
||||
--theme-urgent-color: #F5694A;
|
||||
@ -380,13 +386,6 @@
|
||||
--dangerous-bg-hover: #d44e4e;
|
||||
--dangerous-shadow: var(--dangerous-bg-color) 0px 0px 12px -1px;
|
||||
|
||||
--toggle-sw-color: #fff;
|
||||
--toggle-on-sw-color: #fff;
|
||||
--toggle-bg-color: #dfe1e4;
|
||||
--toggle-bg-hover: #c9cbcd;
|
||||
--toggle-on-bg-color: #6e79d6;
|
||||
--toggle-on-bg-hover: #535db3;
|
||||
|
||||
--incoming-msg: rgba(67, 67, 72, .1);
|
||||
--outcoming-msg: rgba(67, 67, 72, .2);
|
||||
|
||||
|
@ -413,6 +413,8 @@ input.search {
|
||||
&.reverse > *:not(:last-child) { margin-right: 1rem; }
|
||||
}
|
||||
.gapV-4 > *:not(:last-child) { margin-bottom: 1rem; }
|
||||
.gapV-6 > *:not(:last-child) { margin-bottom: 1.5rem; }
|
||||
.gapV-8 > *:not(:last-child) { margin-bottom: 2rem; }
|
||||
.gap-around-2 > * { margin: .25rem; }
|
||||
.gap-around-4 > * { margin: .5rem; }
|
||||
|
||||
|
@ -256,6 +256,49 @@
|
||||
padding: .5rem 0 1.25rem;
|
||||
}
|
||||
|
||||
/* Basic */
|
||||
.antiGrid {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
|
||||
&-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
|
||||
&__header {
|
||||
width: 15rem;
|
||||
padding-right: 1rem;
|
||||
color: var(--theme-caption-color);
|
||||
|
||||
&.withDesciption {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
|
||||
span {
|
||||
font-size: .75rem;
|
||||
color: var(--theme-halfcontent-color);
|
||||
}
|
||||
}
|
||||
&.topAlign {
|
||||
align-self: flex-start;
|
||||
margin-top: .75rem;
|
||||
}
|
||||
}
|
||||
.padding {
|
||||
flex-grow: 1;
|
||||
padding: .75rem 0;
|
||||
}
|
||||
&:not(:last-child) { margin-bottom: .5rem; }
|
||||
& > *:not(.padding, .topAlign) { margin: .25rem 0; }
|
||||
}
|
||||
}
|
||||
|
||||
/* Basic */
|
||||
.antiTitle {
|
||||
.icon-wrapper, &.icon-wrapper,
|
||||
|
@ -58,6 +58,8 @@
|
||||
min-width: 0;
|
||||
line-height: 150%;
|
||||
color: var(--theme-caption-color);
|
||||
|
||||
&.accentHeader { font-size: 1rem; }
|
||||
}
|
||||
&__divider { color: var(--theme-dark-color); }
|
||||
&__error {
|
||||
@ -190,10 +192,25 @@
|
||||
}
|
||||
|
||||
&.dialog {
|
||||
width: 45rem;
|
||||
height: auto;
|
||||
max-width: 60rem;
|
||||
max-height: inherit;
|
||||
|
||||
&.large {
|
||||
width: 45rem;
|
||||
max-width: 60rem;
|
||||
}
|
||||
&.medium {
|
||||
width: 37.5rem;
|
||||
max-width: 37.5rem;
|
||||
}
|
||||
&.small {
|
||||
width: 30rem;
|
||||
max-width: 30rem;
|
||||
}
|
||||
&.x-small {
|
||||
width: 25rem;
|
||||
max-width: 25rem;
|
||||
}
|
||||
&.full {
|
||||
width: max-content;
|
||||
// max-width: 100%;
|
||||
|
@ -37,8 +37,9 @@
|
||||
export let select: boolean = false
|
||||
export let focusable: boolean = false
|
||||
export let disabled: boolean = false
|
||||
export let fullSize = false
|
||||
export let required = false
|
||||
export let fullSize: boolean = false
|
||||
export let required: boolean = false
|
||||
export let uppercase: boolean = false
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@ -134,6 +135,7 @@
|
||||
class="editbox-container"
|
||||
class:flex-grow={fullSize}
|
||||
class:w-full={focusable || fullSize}
|
||||
class:uppercase
|
||||
on:click={() => {
|
||||
input.focus()
|
||||
}}
|
||||
@ -210,8 +212,8 @@
|
||||
align-items: flex-start;
|
||||
|
||||
.large-style {
|
||||
font-weight: 500;
|
||||
font-size: 1.125rem;
|
||||
font-weight: 400;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
.small-style {
|
||||
font-weight: 400;
|
||||
@ -271,5 +273,9 @@
|
||||
input[type='number'] {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
&.uppercase .hidden-text,
|
||||
&.uppercase input {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -22,7 +22,7 @@
|
||||
export let selected: string | string[] = ''
|
||||
export let multiselect: boolean = false
|
||||
export let items: TabItem[]
|
||||
export let kind: 'normal' | 'secondary' | 'plain' | 'separated' = 'normal'
|
||||
export let kind: 'normal' | 'secondary' | 'plain' | 'separated' | 'separated-free' = 'normal'
|
||||
export let onlyIcons: boolean = false
|
||||
export let size: 'small' | 'medium' = 'medium'
|
||||
|
||||
@ -50,7 +50,8 @@
|
||||
<div
|
||||
bind:this={tabs[i]}
|
||||
class={kind === 'normal' || kind === 'secondary' ? 'button' : 'plain'}
|
||||
class:separated={kind === 'separated'}
|
||||
class:separated={kind === 'separated' || kind === 'separated-free'}
|
||||
class:free={kind === 'separated-free'}
|
||||
class:onlyIcons
|
||||
class:selected={getSelected(item.id, selected)}
|
||||
data-view={item.tooltip}
|
||||
@ -234,6 +235,9 @@
|
||||
background-color: var(--theme-tablist-plain-divider);
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
&.free:first-child::before {
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,9 +37,9 @@
|
||||
<style lang="scss">
|
||||
.toggle {
|
||||
display: inline-block;
|
||||
width: 2rem;
|
||||
min-width: 2rem;
|
||||
height: 1.5rem;
|
||||
width: 2.25rem;
|
||||
min-width: 2.25rem;
|
||||
height: 1.25rem;
|
||||
// line-height: 1.75rem;
|
||||
vertical-align: middle;
|
||||
font-size: inherit;
|
||||
@ -55,13 +55,13 @@
|
||||
overflow: hidden;
|
||||
|
||||
&:checked + .toggle-switch {
|
||||
background-color: var(--toggle-on-bg-color);
|
||||
background-color: var(--theme-toggle-on-bg-color);
|
||||
&:hover {
|
||||
background-color: var(--toggle-on-bg-hover);
|
||||
background-color: var(--theme-toggle-on-bg-hover);
|
||||
}
|
||||
&:before {
|
||||
left: 0.75rem;
|
||||
background: var(--toggle-on-sw-color);
|
||||
left: 1.125rem;
|
||||
background: var(--theme-toggle-on-sw-color);
|
||||
}
|
||||
}
|
||||
&:not(:disabled) + .toggle-switch {
|
||||
@ -79,26 +79,26 @@
|
||||
.toggle-switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 2rem;
|
||||
height: 1.5rem;
|
||||
border-radius: 4.5rem;
|
||||
background-color: var(--toggle-bg-color);
|
||||
width: 2.25rem;
|
||||
height: 1.25rem;
|
||||
border-radius: 1.25rem;
|
||||
background-color: var(--theme-toggle-bg-color);
|
||||
transition: left 0.2s, background-color 0.2s;
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0.25rem;
|
||||
left: 0.25rem;
|
||||
top: 0.125rem;
|
||||
left: 0.125rem;
|
||||
display: inline-block;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
border-radius: 50%;
|
||||
background: var(--toggle-sw-color);
|
||||
box-shadow: 1px 2px 7px rgba(119, 129, 142, 0.1);
|
||||
background: var(--theme-toggle-sw-color);
|
||||
box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.15), 0px 3px 1px rgba(0, 0, 0, 0.06);
|
||||
transition: 0.15s;
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--toggle-bg-hover);
|
||||
background-color: var(--theme-toggle-bg-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,7 @@
|
||||
class:dateTimeButtonNoLabel={!shouldShowLabel}
|
||||
class:text-xs={size === 'x-small'}
|
||||
class:noDate={!value}
|
||||
class:withIcon={showIcon}
|
||||
style:width
|
||||
on:click={(e) => {
|
||||
if (editable && !opened) {
|
||||
@ -292,12 +293,17 @@
|
||||
}
|
||||
}
|
||||
&.secondary {
|
||||
padding: 0 0.625rem;
|
||||
color: var(--theme-caption-color);
|
||||
background-color: var(--theme-button-enabled);
|
||||
border-color: var(--theme-button-border);
|
||||
border-radius: 0.25rem;
|
||||
|
||||
&.withIcon {
|
||||
padding: 0 1rem 0 0.75rem;
|
||||
}
|
||||
&:not(.withIcon) {
|
||||
padding: 0 0.75rem;
|
||||
}
|
||||
.btn-icon {
|
||||
color: var(--theme-content-color);
|
||||
}
|
||||
|
@ -185,6 +185,7 @@ export type IconSize =
|
||||
| 'medium'
|
||||
| 'large'
|
||||
| 'x-large'
|
||||
| '2x-large'
|
||||
| 'full'
|
||||
|
||||
export interface DateOrShift {
|
||||
|
@ -94,25 +94,28 @@
|
||||
{trimFilename(value.name)}
|
||||
</a>
|
||||
</div>
|
||||
<div class="info-content">
|
||||
{filesize(value.size, { spacer: '' })} •
|
||||
<a class="no-line colorInherit" href={getFileUrl(value.file)} download={value.name} bind:this={download}>
|
||||
<Label label={presentation.string.Download} />
|
||||
</a>
|
||||
{#if removable}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
•
|
||||
<span
|
||||
class="remove-link"
|
||||
on:click={(ev) => {
|
||||
ev.stopPropagation()
|
||||
ev.preventDefault()
|
||||
dispatch('remove', value)
|
||||
}}
|
||||
>
|
||||
<Label label={presentation.string.Delete} />
|
||||
</span>
|
||||
{/if}
|
||||
<div class="info-content flex-row-center">
|
||||
{filesize(value.size, { spacer: '' })}
|
||||
<span class="actions inline-flex clear-mins ml-1 gap-1">
|
||||
<span>•</span>
|
||||
<a class="no-line colorInherit" href={getFileUrl(value.file)} download={value.name} bind:this={download}>
|
||||
<Label label={presentation.string.Download} />
|
||||
</a>
|
||||
{#if removable}
|
||||
<span>•</span>
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<span
|
||||
class="remove-link"
|
||||
on:click={(ev) => {
|
||||
ev.stopPropagation()
|
||||
ev.preventDefault()
|
||||
dispatch('remove', value)
|
||||
}}
|
||||
>
|
||||
<Label label={presentation.string.Delete} />
|
||||
</span>
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -124,7 +127,6 @@
|
||||
height: 3rem;
|
||||
min-width: 14rem;
|
||||
max-width: 19rem;
|
||||
background-color: var(--theme-button-hovered);
|
||||
border-radius: 0.25rem;
|
||||
|
||||
.icon {
|
||||
@ -152,20 +154,41 @@
|
||||
padding: 0.5rem 0.75rem;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--theme-button-enabled);
|
||||
border: 1px solid var(--theme-button-border);
|
||||
border-left: none;
|
||||
border-radius: 0 0.25rem 0.25rem 0;
|
||||
}
|
||||
.no-line:hover ~ .info-container,
|
||||
.info-container:hover {
|
||||
background-color: var(--theme-button-hovered);
|
||||
|
||||
.actions {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.name {
|
||||
white-space: nowrap;
|
||||
font-size: 0.8125rem;
|
||||
color: var(--theme-caption-color);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover ~ .info-content .actions {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.info-content {
|
||||
white-space: nowrap;
|
||||
font-size: 0.6875rem;
|
||||
color: var(--theme-darker-color);
|
||||
|
||||
.actions {
|
||||
opacity: 0;
|
||||
transition: opacity 0.1s var(--timing-main);
|
||||
}
|
||||
&:hover .actions {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.remove-link {
|
||||
color: var(--theme-error-color);
|
||||
|
@ -339,7 +339,7 @@
|
||||
on:dragleave={() => {}}
|
||||
on:drop|preventDefault|stopPropagation={(ev) => {
|
||||
if (fakeAttach === 'fake') dispatch('attach', { action: 'drop', event: ev })
|
||||
else if (fakeAttach === 'normal') fileDrop(ev)
|
||||
else fileDrop(ev)
|
||||
}}
|
||||
>
|
||||
<div class="expand-collapse">
|
||||
|
@ -84,7 +84,8 @@
|
||||
"DisplayName": "Display name",
|
||||
"SelectAvatar": "Select avatar",
|
||||
"AvatarProvider": "Avatar provider",
|
||||
"GravatarsManaged": "Gravatars are managed through",
|
||||
"GravatarsManaged": "Gravatars are managed",
|
||||
"Through": "through",
|
||||
"CategoryProjectMembers": "Project members",
|
||||
"AddMembersHeader": "Add members to {value}:",
|
||||
"Assigned": "Assigned",
|
||||
|
@ -84,7 +84,8 @@
|
||||
"MergeEmployeeTo": "В сотрудника",
|
||||
"DisplayName": "Отображаемое имя",
|
||||
"SelectAvatar": "Выбрать аватар",
|
||||
"GravatarsManaged": "Граватары управляются через",
|
||||
"GravatarsManaged": "Граватары управляются",
|
||||
"Through": "через",
|
||||
"AddMembersHeader": "Добавить пользователей в {value}:",
|
||||
"NumberMembers": "{count, plural, =0 {нет участников} =1 {1 участник} =2 {2 участника} =3 {3 участника} =4 {4 участника} other {# участников}}",
|
||||
"Assigned": "Назначен",
|
||||
|
@ -156,7 +156,7 @@
|
||||
<div class="flex-presenter not-selected">
|
||||
{#if icon}
|
||||
<div class="icon w-4 flex-no-shrink" class:small-gap={size === 'inline' || size === 'small'}>
|
||||
<Icon {icon} size={avatarSize} />
|
||||
<Icon {icon} size={'small'} />
|
||||
</div>
|
||||
{/if}
|
||||
<div class="label no-underline">
|
||||
|
@ -73,7 +73,7 @@
|
||||
|
||||
<div class="ava-{size} flex-center avatar-container" class:no-img={!url}>
|
||||
{#if url}
|
||||
{#if size === 'large' || size === 'x-large'}
|
||||
{#if size === 'large' || size === 'x-large' || size === '2x-large'}
|
||||
<img class="ava-{size} ava-blur" src={url} alt={''} bind:this={imageElement} />
|
||||
{/if}
|
||||
<img class="ava-{size} ava-mask" src={url} alt={''} bind:this={imageElement} />
|
||||
@ -138,6 +138,10 @@
|
||||
width: 7.5rem; // 120
|
||||
height: 7.5rem;
|
||||
}
|
||||
.ava-2x-large {
|
||||
width: 10rem; // 120
|
||||
height: 10rem;
|
||||
}
|
||||
|
||||
.ava-blur {
|
||||
position: absolute;
|
||||
@ -148,6 +152,11 @@
|
||||
border: 1px solid var(--avatar-border-color);
|
||||
border-radius: 50%;
|
||||
}
|
||||
.ava-large .ava-mask,
|
||||
.ava-x-large .ava-mask,
|
||||
.ava-2x-large .ava-mask {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.ava-inline .ava-mask,
|
||||
.ava-inline.no-img,
|
||||
|
@ -60,21 +60,17 @@
|
||||
dispatch('close')
|
||||
}}
|
||||
/>
|
||||
<div class="root">
|
||||
<div class="editavatar-container">
|
||||
{#await CropperP then Cropper}
|
||||
<div class="cropper">
|
||||
<Cropper bind:this={cropper} image={file} />
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div>
|
||||
<Button label={presentation.string.Save} kind={'primary'} on:click={onCrop} />
|
||||
</div>
|
||||
<div class="ml-4 mr-4">
|
||||
<Button label={presentation.string.Change} on:click={selectAnother} />
|
||||
</div>
|
||||
<div>
|
||||
<Button label={presentation.string.Remove} on:click={remove} />
|
||||
<Button label={presentation.string.Save} kind={'primary'} size={'large'} on:click={onCrop} />
|
||||
<div class="mx-3 clear-mins">
|
||||
<Button label={presentation.string.Change} size={'large'} on:click={selectAnother} />
|
||||
</div>
|
||||
<Button label={presentation.string.Remove} size={'large'} on:click={remove} />
|
||||
</div>
|
||||
{/await}
|
||||
</div>
|
||||
@ -87,11 +83,11 @@
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
|
||||
background: var(--card-overlay-color);
|
||||
background: var(--theme-overlay-color);
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.root {
|
||||
.editavatar-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
@ -105,21 +101,20 @@
|
||||
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
background: var(--popup-bg-color);
|
||||
background: var(--theme-popup-color);
|
||||
border-radius: 1.25rem;
|
||||
box-shadow: 0px 44px 154px rgba(0, 0, 0, 0.75);
|
||||
box-shadow: var(--theme-popup-shadow);
|
||||
|
||||
display: grid;
|
||||
grid-template-rows: minmax(min-content, 1fr) auto;
|
||||
}
|
||||
|
||||
.cropper {
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
padding: 1rem 1.5rem;
|
||||
.cropper {
|
||||
width: inherit;
|
||||
}
|
||||
.footer {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
padding: 1rem 1.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { AvatarType, buildGravatarId, checkHasGravatar, getAvatarColorForId } from '@hcengineering/contact'
|
||||
import { Asset } from '@hcengineering/platform'
|
||||
import { AnySvelteComponent, DropdownLabelsIntl, Label, showPopup } from '@hcengineering/ui'
|
||||
import { AnySvelteComponent, Label, showPopup, TabList } from '@hcengineering/ui'
|
||||
|
||||
import presentation, { Card, getFileUrl } from '@hcengineering/presentation'
|
||||
import contact from '../plugin'
|
||||
@ -29,7 +29,7 @@
|
||||
export let email: string | undefined
|
||||
export let id: string
|
||||
export let file: Blob | undefined
|
||||
export let icon: Asset | AnySvelteComponent | undefined
|
||||
export let icon: Asset | AnySvelteComponent | undefined = undefined
|
||||
export let onSubmit: (avatarType?: AvatarType, avatar?: string, file?: Blob) => void
|
||||
|
||||
const [schema, uri] = avatar?.split('://') || []
|
||||
@ -151,6 +151,8 @@
|
||||
<Card
|
||||
label={contact.string.SelectAvatar}
|
||||
okLabel={presentation.string.Save}
|
||||
width={'x-small'}
|
||||
accentHeader
|
||||
canSave={selectedAvatarType !== initialSelectedType ||
|
||||
selectedAvatar !== initialSelectedAvatar ||
|
||||
selectedFile !== file ||
|
||||
@ -161,36 +163,39 @@
|
||||
}}
|
||||
on:changeContent
|
||||
>
|
||||
<div class="flex-row-center">
|
||||
<Label label={contact.string.AvatarProvider} />
|
||||
<DropdownLabelsIntl
|
||||
kind={'link-bordered'}
|
||||
<div class="flex-col-center gapV-4 mx-6">
|
||||
{#if selectedAvatarType === AvatarType.IMAGE}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div class="cursor-pointer" on:click|self={handleImageAvatarClick}>
|
||||
<AvatarComponent avatar={selectedAvatar} direct={selectedFile} size={'2x-large'} {icon} />
|
||||
</div>
|
||||
{:else}
|
||||
<AvatarComponent avatar={`${selectedAvatarType}://${selectedAvatar}`} size={'2x-large'} {icon} />
|
||||
{/if}
|
||||
<TabList
|
||||
items={getAvatarTypeDropdownItems(hasGravatar)}
|
||||
label={contact.string.SelectAvatar}
|
||||
kind={'separated-free'}
|
||||
bind:selected={selectedAvatarType}
|
||||
on:selected={handleDropdownSelection}
|
||||
on:select={handleDropdownSelection}
|
||||
/>
|
||||
</div>
|
||||
{#if selectedAvatarType === AvatarType.IMAGE}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div class="cursor-pointer" on:click|self={handleImageAvatarClick}>
|
||||
<AvatarComponent avatar={selectedAvatar} direct={selectedFile} size={'x-large'} {icon} />
|
||||
</div>
|
||||
{:else}
|
||||
<AvatarComponent avatar={`${selectedAvatarType}://${selectedAvatar}`} size={'x-large'} {icon} />
|
||||
{/if}
|
||||
{#if selectedAvatarType === AvatarType.GRAVATAR}
|
||||
<span>
|
||||
<Label label={contact.string.GravatarsManaged} />
|
||||
<a target="”_blank”" href="//gravatar.com">Gravatar.com</a>
|
||||
</span>
|
||||
{/if}
|
||||
<input
|
||||
style="display: none;"
|
||||
type="file"
|
||||
bind:this={inputRef}
|
||||
on:change={onSelectFile}
|
||||
on:click={() => (document.body.onfocus = handleFileSelectionCancel)}
|
||||
accept={targetMimes.join(',')}
|
||||
/>
|
||||
<svelte:fragment slot="footer">
|
||||
{#if selectedAvatarType === AvatarType.GRAVATAR}
|
||||
<div class="flex-col">
|
||||
<Label label={contact.string.GravatarsManaged} />
|
||||
<span class="inline-flex clear-mins">
|
||||
<Label label={contact.string.Through} />
|
||||
<a target="”_blank”" class="ml-1" href="//gravatar.com">Gravatar.com</a>
|
||||
</span>
|
||||
</div>
|
||||
{/if}
|
||||
<input
|
||||
style="display: none;"
|
||||
type="file"
|
||||
bind:this={inputRef}
|
||||
on:change={onSelectFile}
|
||||
on:click={() => (document.body.onfocus = handleFileSelectionCancel)}
|
||||
accept={targetMimes.join(',')}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
</Card>
|
||||
|
@ -85,9 +85,9 @@
|
||||
{#if persons.length > 0}
|
||||
<div class="flex-row-center flex-nowrap pointer-events-none">
|
||||
{#if persons.length === 1}
|
||||
<UserInfo value={persons[0]} size={'inline'} />
|
||||
<UserInfo value={persons[0]} size={'card'} />
|
||||
{:else}
|
||||
<CombineAvatars {_class} bind:items size={'inline'} hideLimit />
|
||||
<CombineAvatars {_class} bind:items size={'card'} hideLimit />
|
||||
<span class="overflow-label ml-1-5">
|
||||
<Label label={plugin.string.NumberMembers} params={{ count: persons.length }} />
|
||||
</span>
|
||||
|
@ -21,7 +21,7 @@
|
||||
export let fill: string = 'var(--caption-color)'
|
||||
</script>
|
||||
|
||||
<svg class="svg-avatar {size}" {fill} viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg class="svg-avatar avaicon-{size}" {fill} viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle class="op" cx="20" cy="13.6" r="6.4" />
|
||||
<path
|
||||
d="M33.1,33.3c-0.8-2.2-2.5-4.2-4.9-5.5c-2.3-1.3-5.2-2.1-8.2-2.1s-5.8,0.7-8.2,2.1c-2.4,1.4-4.1,3.3-4.9,5.5 c-0.1,0.4,0.1,0.8,0.5,1c0.4,0.1,0.8-0.1,1-0.5c0.7-1.9,2.2-3.5,4.2-4.7c2.1-1.2,4.7-1.9,7.4-1.9c2.7,0,5.3,0.7,7.4,1.9 c2.1,1.2,3.6,2.9,4.2,4.7c0.1,0.3,0.4,0.5,0.7,0.5c0.1,0,0.2,0,0.3,0C33,34.1,33.2,33.7,33.1,33.3z"
|
||||
@ -37,38 +37,42 @@
|
||||
opacity: 0.05;
|
||||
}
|
||||
}
|
||||
.inline {
|
||||
.avaicon-inline {
|
||||
width: 0.75rem;
|
||||
height: 0.75rem;
|
||||
}
|
||||
|
||||
.tiny {
|
||||
.avaicon-tiny {
|
||||
width: 0.875rem;
|
||||
height: 0.875rem;
|
||||
}
|
||||
|
||||
.x-small {
|
||||
.avaicon-x-small {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
.smaller {
|
||||
.avaicon-smaller {
|
||||
width: 1.125rem;
|
||||
height: 1.125rem;
|
||||
}
|
||||
.small {
|
||||
.avaicon-small {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
}
|
||||
.medium {
|
||||
.avaicon-medium {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
}
|
||||
.large {
|
||||
.avaicon-large {
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
}
|
||||
.x-large {
|
||||
.avaicon-x-large {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
}
|
||||
.avaicon-2x-large {
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
}
|
||||
</style>
|
||||
|
@ -66,6 +66,7 @@ export default mergeIds(contactId, contact, {
|
||||
MergeEmployeeTo: '' as IntlString,
|
||||
SelectAvatar: '' as IntlString,
|
||||
GravatarsManaged: '' as IntlString,
|
||||
Through: '' as IntlString,
|
||||
AvatarProvider: '' as IntlString,
|
||||
|
||||
CategoryProjectMembers: '' as IntlString,
|
||||
|
@ -30,13 +30,7 @@ import {
|
||||
import { Client, Doc, getCurrentAccount, IdMap, ObjQueryType, Ref, Timestamp, toIdMap } from '@hcengineering/core'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { TemplateDataProvider } from '@hcengineering/templates'
|
||||
import {
|
||||
DropdownIntlItem,
|
||||
getCurrentResolvedLocation,
|
||||
getPanelURI,
|
||||
Location,
|
||||
ResolvedLocation
|
||||
} from '@hcengineering/ui'
|
||||
import { TabItem, getCurrentResolvedLocation, getPanelURI, Location, ResolvedLocation } from '@hcengineering/ui'
|
||||
import view, { Filter } from '@hcengineering/view'
|
||||
import { FilterQuery } from '@hcengineering/view-resources'
|
||||
import { get, writable } from 'svelte/store'
|
||||
@ -269,21 +263,21 @@ function fillStores (): void {
|
||||
|
||||
fillStores()
|
||||
|
||||
export function getAvatarTypeDropdownItems (hasGravatar: boolean): DropdownIntlItem[] {
|
||||
export function getAvatarTypeDropdownItems (hasGravatar: boolean): TabItem[] {
|
||||
return [
|
||||
{
|
||||
id: AvatarType.COLOR,
|
||||
label: contact.string.UseColor
|
||||
labelIntl: contact.string.UseColor
|
||||
},
|
||||
{
|
||||
id: AvatarType.IMAGE,
|
||||
label: contact.string.UseImage
|
||||
labelIntl: contact.string.UseImage
|
||||
},
|
||||
...(hasGravatar
|
||||
? [
|
||||
{
|
||||
id: AvatarType.GRAVATAR,
|
||||
label: contact.string.UseGravatar
|
||||
labelIntl: contact.string.UseGravatar
|
||||
}
|
||||
]
|
||||
: [])
|
||||
|
@ -40,10 +40,13 @@
|
||||
"Canceled": "Canceled",
|
||||
"CreateProject": "Create project",
|
||||
"NewProject": "New project",
|
||||
"ProjectTitlePlaceholder": "Project title",
|
||||
"Identifier": "Project Identifier",
|
||||
"ProjectTitle": "Project title",
|
||||
"ProjectTitlePlaceholder": "New project",
|
||||
"UsedInIssueIDs": "Used in issue IDs",
|
||||
"Identifier": "Identifier",
|
||||
"ProjectIdentifier": "Project Identifier",
|
||||
"IdentifierExists": "Project identifier already exists",
|
||||
"ProjectIdentifierPlaceholder": "Project Identifier",
|
||||
"ProjectIdentifierPlaceholder": "PRJCT",
|
||||
"ChooseIcon": "Choose icon",
|
||||
"AddIssue": "Add Issue",
|
||||
"NewIssue": "New issue",
|
||||
@ -78,7 +81,7 @@
|
||||
"AssignTo": "Assign to...",
|
||||
"AssignedTo": "Assigned to {value}",
|
||||
"Parent": "Parent issue",
|
||||
"SetParent": "Set parent issue",
|
||||
"SetParent": "Set parent issue\u2026",
|
||||
"ChangeParent": "Change parent issue\u2026",
|
||||
"RemoveParent": "Remove parent issue",
|
||||
"OpenParent": "Open parent issue",
|
||||
@ -93,7 +96,6 @@
|
||||
"Labels": "Labels",
|
||||
"Component": "Component",
|
||||
"Space": "",
|
||||
"NoDueDate": "No due date",
|
||||
"SetDueDate": "Set due date\u2026",
|
||||
"ChangeDueDate": "Change due date\u2026",
|
||||
"ModificationDate": "Updated {value}",
|
||||
@ -106,7 +108,7 @@
|
||||
"TypeIssuePriority": "Issue priority",
|
||||
"IssueTitlePlaceholder": "Issue title",
|
||||
"SubIssueTitlePlaceholder": "Sub-issue title",
|
||||
"IssueDescriptionPlaceholder": "Add description",
|
||||
"IssueDescriptionPlaceholder": "Add description\u2026",
|
||||
"SubIssueDescriptionPlaceholder": "Add sub-issue description",
|
||||
"AddIssueTooltip": "Add issue...",
|
||||
"NewIssueDialogClose": "Do you want to close this dialog?",
|
||||
@ -264,7 +266,7 @@
|
||||
"CurrentWorkDay": "Current Working Day",
|
||||
"PreviousWorkDay": "Previous Working Day",
|
||||
"TimeReportDayTypeLabel": "Select time report day type",
|
||||
"DefaultAssignee": "Select default assignee for issues",
|
||||
"DefaultAssignee": "Default assignee for issues",
|
||||
|
||||
"SevenHoursLength": "Seven Hours",
|
||||
"EightHoursLength": "Eight Hours",
|
||||
|
@ -40,10 +40,13 @@
|
||||
"Canceled": "Отменено",
|
||||
"CreateProject": "Создать проект",
|
||||
"NewProject": "Новый проект",
|
||||
"ProjectTitlePlaceholder": "Название проекта",
|
||||
"Identifier": "Идентификатор проекта",
|
||||
"ProjectTitle": "Название проекта",
|
||||
"ProjectTitlePlaceholder": "Новый проект",
|
||||
"UsedInIssueIDs": "Используется в идентификаторах задач",
|
||||
"Identifier": "Идентификатор",
|
||||
"ProjectIdentifier": "Идентификатор проекта",
|
||||
"IdentifierExists": "Идентификатор уже существует проекта",
|
||||
"ProjectIdentifierPlaceholder": "Идентификатор проекта",
|
||||
"ProjectIdentifierPlaceholder": "ПКТ",
|
||||
"ChooseIcon": "Выбрать иконку",
|
||||
"AddIssue": "Добавить задачу",
|
||||
"NewIssue": "Новая задача",
|
||||
@ -78,7 +81,7 @@
|
||||
"AssignTo": "Назначить...",
|
||||
"AssignedTo": "Назначен на {value}",
|
||||
"Parent": "Родительская задача",
|
||||
"SetParent": "Задать родительскую задачу",
|
||||
"SetParent": "Задать родительскую задачу\u2026",
|
||||
"ChangeParent": "Изменить родительскую задачу\u2026",
|
||||
"RemoveParent": "Удалить родительскую задачу",
|
||||
"OpenParent": "Открыть родительскую задачу",
|
||||
@ -93,7 +96,6 @@
|
||||
"Labels": "Метки",
|
||||
"Component": "Компонент",
|
||||
"Space": "",
|
||||
"NoDueDate": "Нет срока выполнения",
|
||||
"SetDueDate": "Указать срок выполнения\u2026",
|
||||
"ChangeDueDate": "Изменить срок выполнения\u2026",
|
||||
"ModificationDate": "Изменено {value}",
|
||||
@ -106,7 +108,7 @@
|
||||
"TypeIssuePriority": "Приоритет задачи",
|
||||
"IssueTitlePlaceholder": "Имя задачи",
|
||||
"SubIssueTitlePlaceholder": "Имя подзадачи",
|
||||
"IssueDescriptionPlaceholder": "Описание задачи",
|
||||
"IssueDescriptionPlaceholder": "Добавить описание\u2026",
|
||||
"SubIssueDescriptionPlaceholder": "Описание подзадачи",
|
||||
"AddIssueTooltip": "Добавить задачу\u2026",
|
||||
"NewIssueDialogClose": "Вы действительно хотите закрыть окно?",
|
||||
@ -264,7 +266,7 @@
|
||||
"CurrentWorkDay": "Текущий Рабочий День",
|
||||
"PreviousWorkDay": "Предыдущий Рабочий День",
|
||||
"TimeReportDayTypeLabel": "Выберите тип дня для временного отчета",
|
||||
"DefaultAssignee": "Выберите исполнителя по умолчанию",
|
||||
"DefaultAssignee": "Исполнитель задачи по умолчанию",
|
||||
|
||||
"SevenHoursLength": "Семь Часов",
|
||||
"EightHoursLength": "Восемь Часов",
|
||||
|
@ -587,7 +587,6 @@
|
||||
alwaysEdit
|
||||
showButtons={false}
|
||||
kind={'indented'}
|
||||
fakeAttach={'hidden'}
|
||||
enableBackReferences={true}
|
||||
bind:content={object.description}
|
||||
placeholder={tracker.string.IssueDescriptionPlaceholder}
|
||||
@ -708,8 +707,7 @@
|
||||
<div id="duedate-editor" class="new-line">
|
||||
<DatePresenter
|
||||
bind:value={object.dueDate}
|
||||
labelNull={tracker.string.NoDueDate}
|
||||
icon={tracker.icon.DueDate}
|
||||
labelNull={tracker.string.DueDate}
|
||||
kind={'secondary'}
|
||||
size={'large'}
|
||||
editable
|
||||
|
@ -59,7 +59,7 @@
|
||||
|
||||
$: handleSelectedMilestoneIdUpdated(value, rawMilestones)
|
||||
|
||||
$: translate(tracker.string.NoMilestone, {}).then((result) => (defaultMilestoneLabel = result))
|
||||
$: translate(tracker.string.Milestone, {}).then((result) => (defaultMilestoneLabel = result))
|
||||
const milestoneIcon = tracker.icon.Milestone
|
||||
$: milestoneText = shouldShowLabel ? selectedMilestone?.label ?? defaultMilestoneLabel : undefined
|
||||
|
||||
@ -81,7 +81,7 @@
|
||||
{
|
||||
id: null,
|
||||
icon: tracker.icon.Milestone,
|
||||
label: tracker.string.NoMilestone,
|
||||
label: tracker.string.Milestone,
|
||||
isSelected: sp === undefined
|
||||
},
|
||||
...rawMilestones.map((p) => ({
|
||||
|
@ -25,7 +25,7 @@
|
||||
</script>
|
||||
|
||||
<Card
|
||||
label={projects.has(identifier) ? tracker.string.IdentifierExists : tracker.string.Identifier}
|
||||
label={projects.has(identifier) ? tracker.string.IdentifierExists : tracker.string.ProjectIdentifier}
|
||||
okLabel={presentation.string.Save}
|
||||
okAction={save}
|
||||
canSave={identifier !== project.identifier && !projects.has(identifier)}
|
||||
|
@ -26,7 +26,7 @@
|
||||
IconEdit,
|
||||
IconWithEmojii,
|
||||
Label,
|
||||
ToggleWithLabel,
|
||||
Toggle,
|
||||
eventToHTMLElement,
|
||||
getColorNumberByText,
|
||||
getPlatformColorDef,
|
||||
@ -184,92 +184,124 @@
|
||||
okLabel={isNew ? presentation.string.Create : presentation.string.Save}
|
||||
okAction={handleSave}
|
||||
canSave={name.length > 0 && !(members.length === 0 && isPrivate)}
|
||||
gap={'gapV-4'}
|
||||
accentHeader
|
||||
width={'medium'}
|
||||
gap={'gapV-6'}
|
||||
on:close={() => {
|
||||
dispatch('close')
|
||||
}}
|
||||
on:changeContent
|
||||
>
|
||||
<div class="flex-row-center flex-between">
|
||||
<EditBox
|
||||
bind:value={name}
|
||||
placeholder={tracker.string.ProjectTitlePlaceholder}
|
||||
kind={'large-style'}
|
||||
focus
|
||||
on:input={() => {
|
||||
if (isNew) {
|
||||
identifier = name.toLocaleUpperCase().replaceAll(' ', '_').substring(0, 5)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<div class="flex-row-center">
|
||||
<EditBox
|
||||
bind:value={identifier}
|
||||
disabled={!isNew}
|
||||
placeholder={tracker.string.ProjectIdentifierPlaceholder}
|
||||
kind={'large-style'}
|
||||
/>
|
||||
{#if !isNew}
|
||||
<Button size={'small'} icon={IconEdit} on:click={changeIdentity} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<StyledTextBox
|
||||
alwaysEdit
|
||||
showButtons={false}
|
||||
bind:content={description}
|
||||
placeholder={tracker.string.IssueDescriptionPlaceholder}
|
||||
/>
|
||||
<ToggleWithLabel
|
||||
label={presentation.string.MakePrivate}
|
||||
description={presentation.string.MakePrivateDescription}
|
||||
bind:on={isPrivate}
|
||||
disabled={!isPrivate && members.length === 0}
|
||||
/>
|
||||
<div class="flex-between">
|
||||
<div class="caption">
|
||||
<Label label={tracker.string.ChooseIcon} />
|
||||
</div>
|
||||
<Button
|
||||
icon={icon === tracker.component.IconWithEmojii ? IconWithEmojii : icon ?? tracker.icon.Home}
|
||||
iconProps={icon === tracker.component.IconWithEmojii
|
||||
? { icon: color }
|
||||
: {
|
||||
fill:
|
||||
color !== undefined
|
||||
? getPlatformColorDef(color, $themeStore.dark).icon
|
||||
: getPlatformColorForTextDef(name, $themeStore.dark).icon
|
||||
<div class="antiGrid">
|
||||
<div class="antiGrid-row">
|
||||
<div class="antiGrid-row__header">
|
||||
<Label label={tracker.string.ProjectTitle} />
|
||||
</div>
|
||||
<div class="padding">
|
||||
<EditBox
|
||||
bind:value={name}
|
||||
placeholder={tracker.string.ProjectTitlePlaceholder}
|
||||
kind={'large-style'}
|
||||
focus
|
||||
on:input={() => {
|
||||
if (isNew) {
|
||||
identifier = name.toLocaleUpperCase().replaceAll(' ', '_').substring(0, 5)
|
||||
}
|
||||
}}
|
||||
kind="no-border"
|
||||
size="medium"
|
||||
on:click={chooseIcon}
|
||||
/>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="antiGrid-row">
|
||||
<div class="antiGrid-row__header withDesciption">
|
||||
<Label label={tracker.string.Identifier} />
|
||||
<span><Label label={tracker.string.UsedInIssueIDs} /></span>
|
||||
</div>
|
||||
<div class="padding flex-row-center">
|
||||
<EditBox
|
||||
bind:value={identifier}
|
||||
disabled={!isNew}
|
||||
placeholder={tracker.string.ProjectIdentifierPlaceholder}
|
||||
kind={'large-style'}
|
||||
uppercase
|
||||
/>
|
||||
{#if !isNew}
|
||||
<Button size={'small'} icon={IconEdit} on:click={changeIdentity} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="antiGrid-row">
|
||||
<div class="antiGrid-row__header topAlign">
|
||||
<Label label={tracker.string.Description} />
|
||||
</div>
|
||||
<div class="padding clear-mins">
|
||||
<StyledTextBox
|
||||
alwaysEdit
|
||||
showButtons={false}
|
||||
bind:content={description}
|
||||
placeholder={tracker.string.IssueDescriptionPlaceholder}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-between">
|
||||
<div class="caption">
|
||||
<Label label={tracker.string.Members} />
|
||||
<div class="antiGrid">
|
||||
<div class="antiGrid-row">
|
||||
<div class="antiGrid-row__header">
|
||||
<Label label={tracker.string.ChooseIcon} />
|
||||
</div>
|
||||
<Button
|
||||
icon={icon === tracker.component.IconWithEmojii ? IconWithEmojii : icon ?? tracker.icon.Home}
|
||||
iconProps={icon === tracker.component.IconWithEmojii
|
||||
? { icon: color }
|
||||
: {
|
||||
fill:
|
||||
color !== undefined
|
||||
? getPlatformColorDef(color, $themeStore.dark).icon
|
||||
: getPlatformColorForTextDef(name, $themeStore.dark).icon
|
||||
}}
|
||||
size={'large'}
|
||||
on:click={chooseIcon}
|
||||
/>
|
||||
</div>
|
||||
<AccountArrayEditor
|
||||
value={members}
|
||||
label={tracker.string.Members}
|
||||
onChange={(refs) => (members = refs)}
|
||||
kind="link-bordered"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex-between">
|
||||
<div class="caption">
|
||||
<Label label={tracker.string.DefaultAssignee} />
|
||||
<div class="antiGrid-row">
|
||||
<div class="antiGrid-row__header withDesciption">
|
||||
<Label label={presentation.string.MakePrivate} />
|
||||
<span><Label label={presentation.string.MakePrivateDescription} /></span>
|
||||
</div>
|
||||
<Toggle bind:on={isPrivate} disabled={!isPrivate && members.length === 0} />
|
||||
</div>
|
||||
|
||||
<div class="antiGrid-row">
|
||||
<div class="antiGrid-row__header">
|
||||
<Label label={tracker.string.Members} />
|
||||
</div>
|
||||
<AccountArrayEditor
|
||||
value={members}
|
||||
label={tracker.string.Members}
|
||||
onChange={(refs) => (members = refs)}
|
||||
kind={'secondary'}
|
||||
size={'large'}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="antiGrid-row">
|
||||
<div class="antiGrid-row__header">
|
||||
<Label label={tracker.string.DefaultAssignee} />
|
||||
</div>
|
||||
<AssigneeBox
|
||||
label={tracker.string.Assignee}
|
||||
placeholder={tracker.string.Assignee}
|
||||
kind={'secondary'}
|
||||
size={'large'}
|
||||
avatarSize={'card'}
|
||||
bind:value={defaultAssignee}
|
||||
titleDeselect={tracker.string.Unassigned}
|
||||
showNavigate={false}
|
||||
showTooltip={{ label: tracker.string.DefaultAssignee }}
|
||||
/>
|
||||
</div>
|
||||
<AssigneeBox
|
||||
label={tracker.string.Assignee}
|
||||
placeholder={tracker.string.Assignee}
|
||||
kind="link-bordered"
|
||||
bind:value={defaultAssignee}
|
||||
titleDeselect={tracker.string.Unassigned}
|
||||
showNavigate={false}
|
||||
showTooltip={{ label: tracker.string.DefaultAssignee }}
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
|
@ -66,6 +66,7 @@ export default mergeIds(trackerId, tracker, {
|
||||
Canceled: '' as IntlString,
|
||||
CreateProject: '' as IntlString,
|
||||
NewProject: '' as IntlString,
|
||||
ProjectTitle: '' as IntlString,
|
||||
ProjectTitlePlaceholder: '' as IntlString,
|
||||
ProjectIdentifierPlaceholder: '' as IntlString,
|
||||
ChooseIcon: '' as IntlString,
|
||||
@ -88,7 +89,9 @@ export default mergeIds(trackerId, tracker, {
|
||||
Medium: '' as IntlString,
|
||||
Low: '' as IntlString,
|
||||
Title: '' as IntlString,
|
||||
UsedInIssueIDs: '' as IntlString,
|
||||
Identifier: '' as IntlString,
|
||||
ProjectIdentifier: '' as IntlString,
|
||||
IdentifierExists: '' as IntlString,
|
||||
Description: '' as IntlString,
|
||||
Status: '' as IntlString,
|
||||
@ -131,7 +134,6 @@ export default mergeIds(trackerId, tracker, {
|
||||
Attachments: '' as IntlString,
|
||||
Labels: '' as IntlString,
|
||||
Space: '' as IntlString,
|
||||
NoDueDate: '' as IntlString,
|
||||
SetDueDate: '' as IntlString,
|
||||
ChangeDueDate: '' as IntlString,
|
||||
ModificationDate: '' as IntlString,
|
||||
|
@ -140,10 +140,15 @@ test('report-time-from-issue-card', async ({ page }) => {
|
||||
const random = Math.floor(Math.random() * values.length)
|
||||
const time = values[random]
|
||||
const name = getIssueName()
|
||||
await createIssue(page, { name, assignee, status })
|
||||
await page.waitForSelector(`text="${name}"`)
|
||||
await page.waitForSelector('text="View issue"')
|
||||
await page.click('text="View issue"')
|
||||
try {
|
||||
await page.evaluate(() => localStorage.setItem('#platform.notification.timeout', '5000'))
|
||||
await createIssue(page, { name, assignee, status })
|
||||
await page.waitForSelector(`text="${name}"`)
|
||||
await page.waitForSelector('text="View issue"')
|
||||
await page.click('text="View issue"')
|
||||
} finally {
|
||||
await page.evaluate(() => localStorage.setItem('#platform.notification.timeout', '1'))
|
||||
}
|
||||
|
||||
await page.click('#ReportedTimeEditor')
|
||||
await page.waitForSelector('text="Time spend reports"')
|
||||
@ -246,7 +251,7 @@ test('create-issue-draft', async ({ page }) => {
|
||||
await page.locator('.ml-2 > .antiButton').click()
|
||||
|
||||
// Click button:has-text("No due date")
|
||||
await page.locator('button:has-text("No due date")').click()
|
||||
await page.locator('button:has-text("Due date")').click()
|
||||
// Click text=24 >> nth=0
|
||||
await page.locator('.date-popup-container >> text=24').first().click()
|
||||
|
||||
|
@ -83,7 +83,7 @@ export async function fillIssueForm (page: Page, props: IssueProps): Promise<voi
|
||||
await page.click(`.selectPopup button:has-text("${component}")`)
|
||||
}
|
||||
if (milestone !== undefined) {
|
||||
await page.click(af + '.antiButton:has-text("No Milestone")')
|
||||
await page.click(af + '.antiButton:has-text("Milestone")')
|
||||
await page.click(`.selectPopup button:has-text("${milestone}")`)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user