diff --git a/models/tracker/src/index.ts b/models/tracker/src/index.ts index 6f491b14b5..5ba685000b 100644 --- a/models/tracker/src/index.ts +++ b/models/tracker/src/index.ts @@ -474,14 +474,19 @@ export function createModel (builder: Builder): void { props: {}, displayProps: { key: 'title' } }, - { key: 'comments', displayProps: { key: 'comments' } }, - { key: 'attachments', displayProps: { key: 'attachments' } }, - { key: '', label: tracker.string.SubIssues, presenter: tracker.component.SubIssuesSelector, props: {} }, + { + key: '', + label: tracker.string.SubIssues, + presenter: tracker.component.SubIssuesSelector, + props: {} + }, + { key: 'comments', displayProps: { key: 'comments', suffix: true } }, + { key: 'attachments', displayProps: { key: 'attachments', suffix: true } }, { key: '', displayProps: { grow: true } }, { key: 'labels', presenter: tags.component.LabelsPresenter, - displayProps: { optional: true, compression: true }, + displayProps: { optional: true }, props: { kind: 'list', full: false } }, { @@ -497,7 +502,6 @@ export function createModel (builder: Builder): void { displayProps: { key: 'milestone', excludeByKey: 'milestone', - compression: true, optional: true } }, @@ -514,7 +518,6 @@ export function createModel (builder: Builder): void { displayProps: { key: 'component', excludeByKey: 'component', - compression: true, optional: true } }, @@ -522,7 +525,7 @@ export function createModel (builder: Builder): void { key: '', label: tracker.string.DueDate, presenter: tracker.component.DueDatePresenter, - displayProps: { key: 'dueDate', optional: true, compression: true }, + displayProps: { key: 'dueDate', optional: true }, props: { kind: 'list' } }, { @@ -530,7 +533,7 @@ export function createModel (builder: Builder): void { label: tracker.string.Estimation, presenter: tracker.component.EstimationEditor, props: { kind: 'list', size: 'small' }, - displayProps: { key: 'estimation', fixed: 'left', compression: true, dividerBefore: true } + displayProps: { key: 'estimation', fixed: 'left', dividerBefore: true } }, { key: 'modifiedOn', @@ -697,7 +700,7 @@ export function createModel (builder: Builder): void { size: 'small', shouldShowPlaceholder: false }, - displayProps: { key: 'component', optional: true, compression: true } + displayProps: { key: 'component', optional: true } }, { key: '', @@ -708,7 +711,7 @@ export function createModel (builder: Builder): void { size: 'small', shouldShowPlaceholder: false }, - displayProps: { key: 'milestone', optional: true, compression: true } + displayProps: { key: 'milestone', optional: true } }, { key: '', @@ -718,7 +721,7 @@ export function createModel (builder: Builder): void { kind: 'list', size: 'small' }, - displayProps: { key: 'estimation', optional: true, compression: true } + displayProps: { key: 'estimation', optional: true } }, { key: '', displayProps: { grow: true } }, { diff --git a/packages/theme/styles/_layouts.scss b/packages/theme/styles/_layouts.scss index ddb209e65c..211cf9a0b1 100644 --- a/packages/theme/styles/_layouts.scss +++ b/packages/theme/styles/_layouts.scss @@ -453,6 +453,7 @@ input.search { width: 1.5rem; height: 1.5rem; } + &.halfcontent { color: var(--theme-halfcontent-color); } } &:hover .icon { color: var(--theme-caption-color); } } @@ -904,6 +905,7 @@ a.no-line { .content-trans-color { color: var(--theme-trans-color); } .content-darker-color { color: var(--theme-darker-color); } +.content-halfcontent-color { color: var(--theme-halfcontent-color); } .content-dark-color { color: var(--theme-dark-color); } .content-color { color: var(--theme-content-color); } .caption-color { color: var(--theme-caption-color); } diff --git a/packages/theme/styles/components.scss b/packages/theme/styles/components.scss index 895f01cdf2..721e755c5e 100644 --- a/packages/theme/styles/components.scss +++ b/packages/theme/styles/components.scss @@ -890,27 +890,28 @@ .optional-bar { overflow: hidden; display: flex; + justify-content: flex-end; align-items: center; - flex-shrink: 1; - min-width: 0; - border-radius: 0 1.49rem 1.49rem 0; - + flex-grow: 1; + border-radius: 1.625rem; + transition: flex-shrink 0.25s cubic-bezier(0.38, 0.01, 0.33, 1) 0s; + + &:hover { + flex-shrink: .5; + min-width: initial; + } .label-wrapper { display: flex; align-items: center; - flex-shrink: 10; width: auto; min-width: 0; } - & > *:not(:last-child) { - flex-shrink: 10; - width: min-content; - } & > *:last-child { flex-shrink: 0; width: max-content; } - & > * { margin-left: .375rem; } + & > *:not(:first-child) { margin-left: .25rem; } + & > * > * { min-width: fit-content; } } } // Labels on the ListView @@ -920,10 +921,13 @@ .list-container .antiButton.list:hover, .list-container .datetime-button, .list-container .datetime-button:hover { + padding-left: .5rem !important; + padding-right: .5rem !important; + font-size: 0.8125rem !important; background-color: var(--theme-list-button-color) !important; &:not(.only-icon) .btn-icon, - &:not(.only-icon) .icon { margin-right: .5rem !important; } + &:not(.only-icon) .icon { margin-right: .375rem !important; } .icon, .btn-icon { color: var(--theme-halfcontent-color) !important; } .label { font-size: 0.8125rem !important; diff --git a/packages/ui/src/components/internal/Root.svelte b/packages/ui/src/components/internal/Root.svelte index 7e4da932d6..5255e9eb74 100644 --- a/packages/ui/src/components/internal/Root.svelte +++ b/packages/ui/src/components/internal/Root.svelte @@ -1,7 +1,7 @@ diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index e7192a3de2..00b18b5ec7 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -220,6 +220,8 @@ export const deviceOptionsStore = writable({ isPortrait: false, isMobile: false, fontSize: 0, + size: null, + sizes: { xs: false, sm: false, md: false, lg: false, xl: false, xxl: false }, minWidth: false, twoRows: false }) diff --git a/packages/ui/src/types.ts b/packages/ui/src/types.ts index f2806ea574..fd5b20c2bc 100644 --- a/packages/ui/src/types.ts +++ b/packages/ui/src/types.ts @@ -295,12 +295,16 @@ export const tableHRscheduleY: FadeOptions = { multipler: { top: 5, bottom: 0 } export const issueSP: FadeOptions = { multipler: { top: 2.75, bottom: 0 } } export const emojiSP: FadeOptions = { multipler: { top: 1.5, bottom: 0 } } +export type WidthType = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' + export interface DeviceOptions { docWidth: number docHeight: number isPortrait: boolean isMobile: boolean fontSize: number + size: WidthType | null + sizes: Record minWidth: boolean twoRows: boolean theme?: any diff --git a/plugins/attachment-resources/src/components/AttachmentsPresenter.svelte b/plugins/attachment-resources/src/components/AttachmentsPresenter.svelte index b6282863d3..2382bfca50 100644 --- a/plugins/attachment-resources/src/components/AttachmentsPresenter.svelte +++ b/plugins/attachment-resources/src/components/AttachmentsPresenter.svelte @@ -23,29 +23,40 @@ export let object: Doc export let size: ButtonSize = 'small' export let kind: ButtonKind = 'link' - export let showCounter = true + export let showCounter: boolean = true + export let compactMode: boolean = false {#if value && value > 0} - + {#if kind === 'list'} -
- -
+
+ {#if showCounter}{value ?? 0}{/if} + + {:else} + + {/if} {:else}
{#if value && value > 0} - + {#if kind === 'list'} -
- -
+ {/if} {:else}
@@ -51,11 +53,23 @@ {#if kind === 'list' || kind === 'link'} - {#each items as value} -
- + {#if items.length > 4} +
+
- {/each} + {:else} + {#each items as value} +
+ +
+ {/each} + {/if} {:else}
-{#each values as v} - -{/each} +{#if kind === 'list'} +
+ {#each values as v} +
+ +
+ {/each} +
+{:else} + {#each values as v} + + {/each} +{/if} diff --git a/plugins/tags-resources/src/components/TagsReferencePresenter.svelte b/plugins/tags-resources/src/components/TagsReferencePresenter.svelte new file mode 100644 index 0000000000..939af70a5a --- /dev/null +++ b/plugins/tags-resources/src/components/TagsReferencePresenter.svelte @@ -0,0 +1,119 @@ + + + +{#if items} + {#if kind === 'link'} + + {:else if kind === 'list'} +
+ {#each colors as color} +
+ {/each} + + +
+ {/if} +{/if} + + diff --git a/plugins/tags-resources/src/plugin.ts b/plugins/tags-resources/src/plugin.ts index f7f885e3ac..2e09073c79 100644 --- a/plugins/tags-resources/src/plugin.ts +++ b/plugins/tags-resources/src/plugin.ts @@ -49,7 +49,8 @@ export default mergeIds(tagsId, tags, { Weight: '' as IntlString, Expert: '' as IntlString, Meaningfull: '' as IntlString, - Initial: '' as IntlString + Initial: '' as IntlString, + NumberLabels: '' as IntlString }, function: { FilterTagsInResult: '' as FilterFunction, diff --git a/plugins/tracker-resources/src/components/components/ComponentEditor.svelte b/plugins/tracker-resources/src/components/components/ComponentEditor.svelte index 0499db7392..df4c11f0d6 100644 --- a/plugins/tracker-resources/src/components/components/ComponentEditor.svelte +++ b/plugins/tracker-resources/src/components/components/ComponentEditor.svelte @@ -56,9 +56,8 @@ {#if (value.component && value.component !== $activeComponent && groupBy !== 'component') || shouldShowPlaceholder}
diff --git a/plugins/tracker-resources/src/components/issues/edit/SubIssuesSelector.svelte b/plugins/tracker-resources/src/components/issues/edit/SubIssuesSelector.svelte index 4dafdebc78..7998919aa3 100644 --- a/plugins/tracker-resources/src/components/issues/edit/SubIssuesSelector.svelte +++ b/plugins/tracker-resources/src/components/issues/edit/SubIssuesSelector.svelte @@ -39,6 +39,7 @@ export let size: ButtonSize = 'small' export let justify: 'left' | 'center' = 'left' export let width: string | undefined = 'min-contet' + export let compactMode: boolean = false let btn: HTMLElement @@ -150,9 +151,11 @@ {#if subIssues}
-
- -
+ {#if !compactMode} +
+ +
+ {/if} {countComplete}/{subIssues.length}
{/if} diff --git a/plugins/tracker-resources/src/components/milestones/MilestoneEditor.svelte b/plugins/tracker-resources/src/components/milestones/MilestoneEditor.svelte index d1a194cea8..8495a204cd 100644 --- a/plugins/tracker-resources/src/components/milestones/MilestoneEditor.svelte +++ b/plugins/tracker-resources/src/components/milestones/MilestoneEditor.svelte @@ -78,7 +78,7 @@ {#if kind === 'list'} {#if value.milestone} -
+
= {} export let selection: number | undefined = undefined + export let compactMode: boolean = false export let documents: Doc[] | undefined = undefined @@ -138,6 +139,7 @@ {disableHeader} {props} {listDiv} + {compactMode} bind:dragItem on:select={(evt) => { select(0, evt.detail) diff --git a/plugins/view-resources/src/components/list/ListCategories.svelte b/plugins/view-resources/src/components/list/ListCategories.svelte index 876afaab5a..2a9a14ec85 100644 --- a/plugins/view-resources/src/components/list/ListCategories.svelte +++ b/plugins/view-resources/src/components/list/ListCategories.svelte @@ -58,6 +58,7 @@ export let listDiv: HTMLDivElement export let selection: number | undefined = undefined export let groupPersistKey: string + export let compactMode: boolean = false $: groupByKey = viewOptions.groupBy[level] ?? noCategory let categories: CategoryType[] = [] @@ -310,6 +311,7 @@ {createItemDialogProps} {createItemLabel} {viewOptionsConfig} + {compactMode} on:check on:uncheckAll on:row-focus diff --git a/plugins/view-resources/src/components/list/ListCategory.svelte b/plugins/view-resources/src/components/list/ListCategory.svelte index c2e62ef976..97bf60cdcf 100644 --- a/plugins/view-resources/src/components/list/ListCategory.svelte +++ b/plugins/view-resources/src/components/list/ListCategory.svelte @@ -66,6 +66,7 @@ export let listDiv: HTMLDivElement export let index: number export let groupPersistKey: string + export let compactMode: boolean = false $: lastLevel = level + 1 >= viewOptions.groupBy.length @@ -448,6 +449,7 @@ on:mouseover={mouseAttractor(() => handleRowFocused(docObject))} on:mouseenter={mouseAttractor(() => handleRowFocused(docObject))} {props} + {compactMode} on:on-mount={() => { wasLoaded = true }} diff --git a/plugins/view-resources/src/components/list/ListItem.svelte b/plugins/view-resources/src/components/list/ListItem.svelte index fd08556306..f055fc9d77 100644 --- a/plugins/view-resources/src/components/list/ListItem.svelte +++ b/plugins/view-resources/src/components/list/ListItem.svelte @@ -16,7 +16,7 @@ import { AnyAttribute, Doc, getObjectValue } from '@hcengineering/core' import notification from '@hcengineering/notification' import { getClient, updateAttribute } from '@hcengineering/presentation' - import { CheckBox, Component, deviceOptionsStore as deviceInfo, IconCircles, tooltip } from '@hcengineering/ui' + import { CheckBox, Component, IconCircles, tooltip } from '@hcengineering/ui' import { AttributeModel } from '@hcengineering/view' import { createEventDispatcher, onMount } from 'svelte' import view from '../../plugin' @@ -31,6 +31,7 @@ export let last: boolean = false export let lastCat: boolean = false export let props: Record = {} + export let compactMode: boolean = false export function scroll () { elem?.scrollIntoView({ behavior: 'auto', block: 'nearest' }) @@ -48,8 +49,6 @@ return elem } - $: compactMode = $deviceInfo.twoRows - const client = getClient() function onChange (value: any, doc: Doc, key: string, attribute: AnyAttribute) { @@ -64,13 +63,6 @@ return (value: any) => onChange(value, docObject, attribute.key, attr) } - let noCompressed: number - $: if (model) { - noCompressed = -1 - model.forEach((m, i) => { - if (m.displayProps?.compression) noCompressed = i - }) - } onMount(() => { dispatch('on-mount') }) @@ -120,32 +112,55 @@ />
- {#each model.filter((p) => !(p.displayProps?.optional === true)) as attributeModel, i} + {#each model.filter((p) => !(p.displayProps?.optional === true || p.displayProps?.suffix === true)) as attributeModel, i} {@const displayProps = attributeModel.displayProps} {#if !groupByKey || displayProps?.excludeByKey !== groupByKey} {#if displayProps?.grow} - {#if !compactMode} - {#each model.filter((p) => p.displayProps?.optional === true) as attrModel, j} + {#each model.filter((p) => p.displayProps?.suffix === true) as attrModel} {/each} {/if} + + {#if !compactMode} +
+ {#each model.filter((p) => p.displayProps?.optional === true) as attrModel} + + {/each} +
+ {:else} + {#each model.filter((p) => p.displayProps?.suffix === true) as attrModel} + + {/each} + {/if} {:else} {/if} {/if} @@ -164,7 +179,7 @@
- {#each model.filter((m) => m.displayProps?.optional || m.displayProps?.compression) as attributeModel, j} + {#each model.filter((m) => m.displayProps?.optional) as attributeModel, j} {@const displayProps = attributeModel.displayProps} {@const value = getObjectValue(attributeModel.key, docObject)} {#if displayProps?.excludeByKey !== groupByKey && value !== undefined} diff --git a/plugins/view-resources/src/components/list/ListPresenter.svelte b/plugins/view-resources/src/components/list/ListPresenter.svelte index 5dc25c8da0..da73575dfb 100644 --- a/plugins/view-resources/src/components/list/ListPresenter.svelte +++ b/plugins/view-resources/src/components/list/ListPresenter.svelte @@ -25,6 +25,7 @@ export let props: Record export let compression: boolean = false export let hideDivider: boolean = false + export let compactMode: boolean = false $: dp = attributeModel?.displayProps @@ -47,6 +48,7 @@ {value} {onChange} kind={'list'} + {compactMode} {...joinProps(attributeModel, docObject, props)} /> @@ -56,7 +58,7 @@ {value} {onChange} kind={'list'} - compression={dp?.compression && compression} + {compactMode} {...joinProps(attributeModel, docObject, props)} /> {/if} diff --git a/plugins/view-resources/src/components/list/ListView.svelte b/plugins/view-resources/src/components/list/ListView.svelte index 8530955a54..ad054fe8ce 100644 --- a/plugins/view-resources/src/components/list/ListView.svelte +++ b/plugins/view-resources/src/components/list/ListView.svelte @@ -24,6 +24,7 @@ let list: List let scroll: Scroller let divScroll: HTMLDivElement + let listWidth: number const listProvider = new ListSelectionProvider((offset: 1 | -1 | 0, of?: Doc, dir?: SelectDirection) => { if (dir === 'vertical') { @@ -43,7 +44,7 @@ }} /> -
+