mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-22 16:27:22 +00:00
Adaptation of IssuesList, IssuesListItem added (#2322)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
parent
47f577a0aa
commit
cfe5972a11
@ -459,7 +459,7 @@ export function createModel (builder: Builder): void {
|
|||||||
presenter: tracker.component.PriorityEditor,
|
presenter: tracker.component.PriorityEditor,
|
||||||
props: { type: 'priority', kind: 'list', size: 'small' }
|
props: { type: 'priority', kind: 'list', size: 'small' }
|
||||||
},
|
},
|
||||||
{ key: '', presenter: tracker.component.IssuePresenter, props: { type: 'issue' } },
|
{ key: '', presenter: tracker.component.IssuePresenter, props: { type: 'issue', fixed: 'left' } },
|
||||||
{
|
{
|
||||||
key: '',
|
key: '',
|
||||||
presenter: tracker.component.StatusEditor,
|
presenter: tracker.component.StatusEditor,
|
||||||
|
@ -87,7 +87,7 @@
|
|||||||
"Space": "",
|
"Space": "",
|
||||||
"SetDueDate": "Указать срок выполнения\u2026",
|
"SetDueDate": "Указать срок выполнения\u2026",
|
||||||
"ChangeDueDate": "Изменить срок выполнения\u2026",
|
"ChangeDueDate": "Изменить срок выполнения\u2026",
|
||||||
"ModificationDate": "Изменино {value}",
|
"ModificationDate": "Изменено {value}",
|
||||||
"Team": "",
|
"Team": "",
|
||||||
"Issue": "Задача",
|
"Issue": "Задача",
|
||||||
"Document": "",
|
"Document": "",
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import contact, { Employee } from '@hcengineering/contact'
|
import contact, { Employee } from '@hcengineering/contact'
|
||||||
import { Class, Doc, FindOptions, getObjectValue, Ref, WithLookup } from '@hcengineering/core'
|
import { Class, Doc, FindOptions, Ref, WithLookup } from '@hcengineering/core'
|
||||||
import notification from '@hcengineering/notification'
|
|
||||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||||
import { Issue, IssueStatus, Team } from '@hcengineering/tracker'
|
import { Issue, IssueStatus, Team } from '@hcengineering/tracker'
|
||||||
import ui, {
|
import ui, {
|
||||||
@ -29,17 +28,15 @@
|
|||||||
IconAdd,
|
IconAdd,
|
||||||
IconMoreH,
|
IconMoreH,
|
||||||
showPopup,
|
showPopup,
|
||||||
Spinner,
|
Spinner
|
||||||
tooltip,
|
|
||||||
deviceOptionsStore as deviceInfo
|
|
||||||
} from '@hcengineering/ui'
|
} from '@hcengineering/ui'
|
||||||
import { AttributeModel, BuildModelKey } from '@hcengineering/view'
|
import { AttributeModel, BuildModelKey } from '@hcengineering/view'
|
||||||
import { buildModel, FixedColumn, getObjectPresenter, LoadingProps, Menu } from '@hcengineering/view-resources'
|
import { buildModel, getObjectPresenter, LoadingProps, Menu } from '@hcengineering/view-resources'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import tracker from '../../plugin'
|
import tracker from '../../plugin'
|
||||||
import { IssuesGroupByKeys, issuesGroupEditorMap, IssuesOrderByKeys, issuesSortOrderMap } from '../../utils'
|
import { IssuesGroupByKeys, issuesGroupEditorMap, IssuesOrderByKeys, issuesSortOrderMap } from '../../utils'
|
||||||
import CreateIssue from '../CreateIssue.svelte'
|
import CreateIssue from '../CreateIssue.svelte'
|
||||||
import Circles from '../icons/Circles.svelte'
|
import IssuesListItem from './IssuesListItem.svelte'
|
||||||
|
|
||||||
export let _class: Ref<Class<Doc>>
|
export let _class: Ref<Class<Doc>>
|
||||||
export let currentSpace: Ref<Team> | undefined = undefined
|
export let currentSpace: Ref<Team> | undefined = undefined
|
||||||
@ -108,6 +105,7 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
const handleMenuOpened = async (event: MouseEvent, object: Doc, rowIndex: number) => {
|
const handleMenuOpened = async (event: MouseEvent, object: Doc, rowIndex: number) => {
|
||||||
|
event.preventDefault()
|
||||||
selectedRowIndex = rowIndex
|
selectedRowIndex = rowIndex
|
||||||
|
|
||||||
if (!selectedObjectIdsSet.has(object._id)) {
|
if (!selectedObjectIdsSet.has(object._id)) {
|
||||||
@ -186,16 +184,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
let varsStyle: string = ''
|
let varsStyle: string = ''
|
||||||
const propsWidth: Record<string, number> = { issue: 0 }
|
let propsWidth: Record<string, number> = {}
|
||||||
let itemModels: AttributeModel[]
|
let itemModels: AttributeModel[]
|
||||||
$: buildModel({ client, _class, keys: itemsConfig, lookup: options.lookup }).then((res) => (itemModels = res))
|
$: buildModel({ client, _class, keys: itemsConfig, lookup: options.lookup }).then((res) => (itemModels = res))
|
||||||
|
$: if (itemModels) {
|
||||||
|
for (const item of itemModels) if (item.props?.fixed !== undefined) propsWidth[item.key] = 0
|
||||||
|
}
|
||||||
$: if (propsWidth) {
|
$: if (propsWidth) {
|
||||||
varsStyle = ''
|
varsStyle = ''
|
||||||
for (const key in propsWidth) varsStyle += `--fixed-${key}: ${propsWidth[key]}px;`
|
for (const key in propsWidth) varsStyle += `--fixed-${key}: ${propsWidth[key]}px;`
|
||||||
}
|
}
|
||||||
const checkWidth = (key: string, result: CustomEvent): void => {
|
|
||||||
if (result !== undefined) propsWidth[key] = result.detail
|
|
||||||
}
|
|
||||||
function limitGroup (
|
function limitGroup (
|
||||||
category: any,
|
category: any,
|
||||||
groupes: { [key: string | number | symbol]: Issue[] },
|
groupes: { [key: string | number | symbol]: Issue[] },
|
||||||
@ -276,13 +274,21 @@
|
|||||||
{#if itemModels}
|
{#if itemModels}
|
||||||
{#if groupedIssues[category]}
|
{#if groupedIssues[category]}
|
||||||
{#each limited as docObject (docObject._id)}
|
{#each limited as docObject (docObject._id)}
|
||||||
<div
|
<IssuesListItem
|
||||||
bind:this={objectRefs[combinedGroupedIssues.findIndex((x) => x === docObject)]}
|
bind:use={objectRefs[combinedGroupedIssues.findIndex((x) => x === docObject)]}
|
||||||
class="listGrid antiList__row row gap-2 flex-grow"
|
{docObject}
|
||||||
class:checking={selectedObjectIdsSet.has(docObject._id)}
|
model={itemModels}
|
||||||
class:mListGridFixed={selectedRowIndex === combinedGroupedIssues.findIndex((x) => x === docObject)}
|
{groupByKey}
|
||||||
class:mListGridSelected={selectedRowIndex === combinedGroupedIssues.findIndex((x) => x === docObject)}
|
selected={selectedRowIndex === combinedGroupedIssues.findIndex((x) => x === docObject)}
|
||||||
on:contextmenu|preventDefault={(event) =>
|
checked={selectedObjectIdsSet.has(docObject._id)}
|
||||||
|
{statuses}
|
||||||
|
{currentTeam}
|
||||||
|
{propsWidth}
|
||||||
|
on:fitting={(ev) => {
|
||||||
|
if (ev.detail !== undefined) propsWidth = ev.detail
|
||||||
|
}}
|
||||||
|
on:check={(ev) => dispatch('check', { docs: ev.detail.docs, value: ev.detail.value })}
|
||||||
|
on:contextmenu={(event) =>
|
||||||
handleMenuOpened(
|
handleMenuOpened(
|
||||||
event,
|
event,
|
||||||
docObject,
|
docObject,
|
||||||
@ -290,124 +296,7 @@
|
|||||||
)}
|
)}
|
||||||
on:focus={() => {}}
|
on:focus={() => {}}
|
||||||
on:mouseover={() => handleRowFocused(docObject)}
|
on:mouseover={() => handleRowFocused(docObject)}
|
||||||
>
|
/>
|
||||||
<div
|
|
||||||
class="flex-center relative"
|
|
||||||
use:tooltip={{ label: tracker.string.SelectIssue, direction: 'bottom' }}
|
|
||||||
>
|
|
||||||
<div class="antiList-cells__notifyCell">
|
|
||||||
<div class="antiList-cells__checkCell">
|
|
||||||
<CheckBox
|
|
||||||
checked={selectedObjectIdsSet.has(docObject._id)}
|
|
||||||
on:value={(event) => {
|
|
||||||
onObjectChecked([docObject], event.detail)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<Component
|
|
||||||
is={notification.component.NotificationPresenter}
|
|
||||||
showLoading={false}
|
|
||||||
props={{ value: docObject, kind: 'table' }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{#each itemModels as attributeModel}
|
|
||||||
{#if attributeModel.props?.type === 'priority'}
|
|
||||||
<div class="priorityPresenter">
|
|
||||||
<svelte:component
|
|
||||||
this={attributeModel.presenter}
|
|
||||||
value={getObjectValue(attributeModel.key, docObject) ?? ''}
|
|
||||||
groupBy={groupByKey}
|
|
||||||
{...attributeModel.props}
|
|
||||||
{statuses}
|
|
||||||
{currentTeam}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{:else if attributeModel.props?.type === 'issue'}
|
|
||||||
<div class="issuePresenter">
|
|
||||||
<FixedColumn
|
|
||||||
width={propsWidth.issue}
|
|
||||||
key={'issue'}
|
|
||||||
justify={'left'}
|
|
||||||
on:update={(result) => checkWidth('issue', result)}
|
|
||||||
>
|
|
||||||
<svelte:component
|
|
||||||
this={attributeModel.presenter}
|
|
||||||
value={getObjectValue(attributeModel.key, docObject) ?? ''}
|
|
||||||
groupBy={groupByKey}
|
|
||||||
{...attributeModel.props}
|
|
||||||
{statuses}
|
|
||||||
{currentTeam}
|
|
||||||
/>
|
|
||||||
</FixedColumn>
|
|
||||||
</div>
|
|
||||||
{:else if attributeModel.props?.type === 'grow'}
|
|
||||||
<svelte:component
|
|
||||||
this={attributeModel.presenter}
|
|
||||||
value={getObjectValue(attributeModel.key, docObject) ?? ''}
|
|
||||||
groupBy={groupByKey}
|
|
||||||
{...attributeModel.props}
|
|
||||||
/>
|
|
||||||
{:else if attributeModel.props?.fixed}
|
|
||||||
{#if !(attributeModel.props?.optional && $deviceInfo.minWidth)}
|
|
||||||
<FixedColumn
|
|
||||||
width={propsWidth[attributeModel.key]}
|
|
||||||
key={attributeModel.key}
|
|
||||||
justify={attributeModel.props.fixed}
|
|
||||||
on:update={(result) => checkWidth(attributeModel.key, result)}
|
|
||||||
>
|
|
||||||
<svelte:component
|
|
||||||
this={attributeModel.presenter}
|
|
||||||
value={getObjectValue(attributeModel.key, docObject) ?? ''}
|
|
||||||
groupBy={groupByKey}
|
|
||||||
{...attributeModel.props}
|
|
||||||
{statuses}
|
|
||||||
{currentTeam}
|
|
||||||
/>
|
|
||||||
</FixedColumn>
|
|
||||||
{/if}
|
|
||||||
{:else if attributeModel.props?.excludeByKey !== groupByKey}
|
|
||||||
{#if !(attributeModel.props?.optional && $deviceInfo.minWidth)}
|
|
||||||
<svelte:component
|
|
||||||
this={attributeModel.presenter}
|
|
||||||
value={getObjectValue(attributeModel.key, docObject) ?? ''}
|
|
||||||
issueId={docObject._id}
|
|
||||||
groupBy={groupByKey}
|
|
||||||
{...attributeModel.props}
|
|
||||||
{statuses}
|
|
||||||
{currentTeam}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
{/if}
|
|
||||||
{/each}
|
|
||||||
{#if $deviceInfo.minWidth}
|
|
||||||
<div class="panel-trigger" tabindex="-1">
|
|
||||||
<Circles />
|
|
||||||
<div class="space" />
|
|
||||||
<Circles />
|
|
||||||
</div>
|
|
||||||
<div class="hidden-panel gap-2" tabindex="-1">
|
|
||||||
<div class="header">
|
|
||||||
<Circles />
|
|
||||||
<div class="space" />
|
|
||||||
<Circles />
|
|
||||||
</div>
|
|
||||||
{#each itemModels as attributeModel}
|
|
||||||
{#if attributeModel.props?.optional && attributeModel.props?.excludeByKey !== groupByKey}
|
|
||||||
<svelte:component
|
|
||||||
this={attributeModel.presenter}
|
|
||||||
value={getObjectValue(attributeModel.key, docObject) ?? ''}
|
|
||||||
issueId={docObject._id}
|
|
||||||
groupBy={groupByKey}
|
|
||||||
{...attributeModel.props}
|
|
||||||
{statuses}
|
|
||||||
{currentTeam}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{/each}
|
{/each}
|
||||||
{:else if loadingProps !== undefined}
|
{:else if loadingProps !== undefined}
|
||||||
{#each Array(getLoadingElementsLength(loadingProps, options)) as _, rowIndex}
|
{#each Array(getLoadingElementsLength(loadingProps, options)) as _, rowIndex}
|
||||||
@ -470,97 +359,4 @@
|
|||||||
border: 1px solid var(--divider-color);
|
border: 1px solid var(--divider-color);
|
||||||
border-radius: 1rem;
|
border-radius: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.listGrid {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 0.75rem 0 0.875rem;
|
|
||||||
width: 100%;
|
|
||||||
height: 2.75rem;
|
|
||||||
min-height: 2.75rem;
|
|
||||||
color: var(--theme-caption-color);
|
|
||||||
|
|
||||||
&.checking {
|
|
||||||
background-color: var(--highlight-select);
|
|
||||||
border-bottom-color: var(--highlight-select);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--highlight-select-hover);
|
|
||||||
border-bottom-color: var(--highlight-select-hover);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.mListGridSelected {
|
|
||||||
background-color: var(--highlight-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hidden-panel,
|
|
||||||
.panel-trigger {
|
|
||||||
position: absolute;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.hidden-panel {
|
|
||||||
overflow: hidden;
|
|
||||||
right: 0;
|
|
||||||
width: 80%;
|
|
||||||
background-color: var(--accent-bg-color);
|
|
||||||
opacity: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
z-index: 2;
|
|
||||||
transition-property: opacity, width;
|
|
||||||
transition-duration: 0.15s;
|
|
||||||
transition-timing-function: var(--timing-main);
|
|
||||||
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
margin: 0 0.25rem;
|
|
||||||
width: 0.375rem;
|
|
||||||
min-width: 0.375rem;
|
|
||||||
height: 100%;
|
|
||||||
opacity: 0.25;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.panel-trigger {
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 0 0.125rem;
|
|
||||||
right: 2.5rem;
|
|
||||||
width: 0.75rem;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
opacity: 0.1;
|
|
||||||
z-index: 1;
|
|
||||||
transition: opacity 0.15s var(--timing-main);
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
border-color: var(--primary-edit-border-color);
|
|
||||||
opacity: 0.25;
|
|
||||||
}
|
|
||||||
& > * {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.hidden-panel:focus-within,
|
|
||||||
.panel-trigger:focus + .hidden-panel {
|
|
||||||
width: 100%;
|
|
||||||
opacity: 1;
|
|
||||||
pointer-events: all;
|
|
||||||
}
|
|
||||||
.space {
|
|
||||||
min-height: 0.1075rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.priorityPresenter,
|
|
||||||
.issuePresenter {
|
|
||||||
// min-width: 0;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -0,0 +1,245 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2022 Hardcore Engineering Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License. You may
|
||||||
|
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
//
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
-->
|
||||||
|
<script lang="ts">
|
||||||
|
import { createEventDispatcher } from 'svelte'
|
||||||
|
import { getObjectValue, WithLookup } from '@hcengineering/core'
|
||||||
|
import { Issue, IssueStatus, Team } from '@hcengineering/tracker'
|
||||||
|
import notification from '@hcengineering/notification'
|
||||||
|
import { tooltip, CheckBox, Component, deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
|
||||||
|
import { AttributeModel } from '@hcengineering/view'
|
||||||
|
import tracker from '../../plugin'
|
||||||
|
import { IssuesGroupByKeys } from '../../utils'
|
||||||
|
import { FixedColumn } from '@hcengineering/view-resources'
|
||||||
|
import Circles from '../icons/Circles.svelte'
|
||||||
|
|
||||||
|
export let use: HTMLElement
|
||||||
|
export let docObject: Issue
|
||||||
|
export let model: AttributeModel[]
|
||||||
|
export let groupByKey: IssuesGroupByKeys | undefined
|
||||||
|
export let checked: boolean
|
||||||
|
export let selected: boolean
|
||||||
|
export let statuses: WithLookup<IssueStatus>[]
|
||||||
|
export let currentTeam: Team | undefined
|
||||||
|
export let propsWidth: Record<string, number>
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
const checkWidth = (key: string, result: CustomEvent): void => {
|
||||||
|
if (result !== undefined) {
|
||||||
|
propsWidth[key] = result.detail
|
||||||
|
dispatch('fitting', propsWidth)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$: compactMode = $deviceInfo.twoRows
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
bind:this={use}
|
||||||
|
class="listGrid antiList__row row gap-2 flex-grow"
|
||||||
|
class:checking={checked}
|
||||||
|
class:mListGridFixed={selected}
|
||||||
|
class:mListGridSelected={selected}
|
||||||
|
on:contextmenu
|
||||||
|
on:focus
|
||||||
|
on:mouseover
|
||||||
|
>
|
||||||
|
<div class="flex-center relative" use:tooltip={{ label: tracker.string.SelectIssue, direction: 'bottom' }}>
|
||||||
|
<div class="antiList-cells__notifyCell">
|
||||||
|
<div class="antiList-cells__checkCell">
|
||||||
|
<CheckBox
|
||||||
|
{checked}
|
||||||
|
on:value={(event) => {
|
||||||
|
dispatch('check', { docs: [docObject], value: event.detail })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Component
|
||||||
|
is={notification.component.NotificationPresenter}
|
||||||
|
showLoading={false}
|
||||||
|
props={{ value: docObject, kind: 'table' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{#each model as attributeModel}
|
||||||
|
{#if attributeModel.props?.type === 'grow'}
|
||||||
|
<svelte:component this={attributeModel.presenter} />
|
||||||
|
{:else if attributeModel.props?.excludeByKey !== groupByKey && !(attributeModel.props?.optional && compactMode)}
|
||||||
|
{#if attributeModel.props?.fixed}
|
||||||
|
<FixedColumn
|
||||||
|
width={propsWidth[attributeModel.key]}
|
||||||
|
key={attributeModel.key}
|
||||||
|
justify={attributeModel.props.fixed}
|
||||||
|
on:update={(result) => checkWidth(attributeModel.key, result)}
|
||||||
|
>
|
||||||
|
<svelte:component
|
||||||
|
this={attributeModel.presenter}
|
||||||
|
value={getObjectValue(attributeModel.key, docObject) ?? ''}
|
||||||
|
groupBy={groupByKey}
|
||||||
|
{...attributeModel.props}
|
||||||
|
{statuses}
|
||||||
|
{currentTeam}
|
||||||
|
/>
|
||||||
|
</FixedColumn>
|
||||||
|
{:else}
|
||||||
|
<svelte:component
|
||||||
|
this={attributeModel.presenter}
|
||||||
|
value={getObjectValue(attributeModel.key, docObject) ?? ''}
|
||||||
|
issueId={docObject._id}
|
||||||
|
groupBy={groupByKey}
|
||||||
|
{...attributeModel.props}
|
||||||
|
{statuses}
|
||||||
|
{currentTeam}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
{#if compactMode}
|
||||||
|
<div class="panel-trigger" tabindex="-1">
|
||||||
|
<Circles />
|
||||||
|
<div class="space" />
|
||||||
|
<Circles />
|
||||||
|
</div>
|
||||||
|
<div class="hidden-panel" tabindex="-1">
|
||||||
|
<div class="header">
|
||||||
|
<Circles />
|
||||||
|
<div class="space" />
|
||||||
|
<Circles />
|
||||||
|
</div>
|
||||||
|
<div class="scroll-box gap-2">
|
||||||
|
{#each model as attributeModel}
|
||||||
|
{@const value = getObjectValue(attributeModel.key, docObject)}
|
||||||
|
{#if attributeModel.props?.optional && attributeModel.props?.excludeByKey !== groupByKey && value !== undefined}
|
||||||
|
<svelte:component
|
||||||
|
this={attributeModel.presenter}
|
||||||
|
value={value ?? ''}
|
||||||
|
issueId={docObject._id}
|
||||||
|
groupBy={groupByKey}
|
||||||
|
{...attributeModel.props}
|
||||||
|
{statuses}
|
||||||
|
{currentTeam}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.row:not(:last-child) {
|
||||||
|
border-bottom: 1px solid var(--accent-bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.listGrid {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 0.75rem 0 0.875rem;
|
||||||
|
width: 100%;
|
||||||
|
height: 2.75rem;
|
||||||
|
min-height: 2.75rem;
|
||||||
|
color: var(--theme-caption-color);
|
||||||
|
|
||||||
|
&.checking {
|
||||||
|
background-color: var(--highlight-select);
|
||||||
|
border-bottom-color: var(--highlight-select);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--highlight-select-hover);
|
||||||
|
border-bottom-color: var(--highlight-select-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.mListGridSelected {
|
||||||
|
background-color: var(--highlight-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden-panel,
|
||||||
|
.panel-trigger {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.hidden-panel {
|
||||||
|
overflow: hidden;
|
||||||
|
right: 0;
|
||||||
|
width: 80%;
|
||||||
|
background-color: var(--accent-bg-color);
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 2;
|
||||||
|
transition-property: opacity, width;
|
||||||
|
transition-duration: 0.15s;
|
||||||
|
transition-timing-function: var(--timing-main);
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 0.25rem;
|
||||||
|
width: 0.375rem;
|
||||||
|
min-width: 0.375rem;
|
||||||
|
height: 100%;
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
||||||
|
.scroll-box {
|
||||||
|
overflow: auto visible;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0.125rem 0.25rem 0;
|
||||||
|
padding: 0.25rem 0.25rem;
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar:horizontal {
|
||||||
|
height: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.panel-trigger {
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0 0.125rem;
|
||||||
|
right: 2.5rem;
|
||||||
|
width: 0.75rem;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
opacity: 0.1;
|
||||||
|
z-index: 1;
|
||||||
|
transition: opacity 0.15s var(--timing-main);
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: var(--primary-edit-border-color);
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
||||||
|
& > * {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.hidden-panel:focus-within,
|
||||||
|
.hidden-panel:focus,
|
||||||
|
.panel-trigger:focus + .hidden-panel {
|
||||||
|
width: 100%;
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
.space {
|
||||||
|
min-height: 0.1075rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -41,6 +41,7 @@
|
|||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.modificationDateLabel {
|
.modificationDateLabel {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
min-width: min-content;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
|
@ -49,7 +49,6 @@
|
|||||||
|
|
||||||
{#if (value.project && value.project !== $activeProject && groupBy !== 'project') || shouldShowPlaceholder}
|
{#if (value.project && value.project !== $activeProject && groupBy !== 'project') || shouldShowPlaceholder}
|
||||||
<div
|
<div
|
||||||
class="min-w-8"
|
|
||||||
class:minus-margin={kind === 'list-header'}
|
class:minus-margin={kind === 'list-header'}
|
||||||
use:tooltip={{ label: value.project ? tracker.string.MoveToProject : tracker.string.AddToProject }}
|
use:tooltip={{ label: value.project ? tracker.string.MoveToProject : tracker.string.AddToProject }}
|
||||||
>
|
>
|
||||||
|
@ -125,7 +125,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="flex flex-wrap min-w-8"
|
class="flex flex-wrap"
|
||||||
class:minus-margin={kind === 'list-header'}
|
class:minus-margin={kind === 'list-header'}
|
||||||
style:flex-direction={twoRows ? 'column' : 'row'}
|
style:flex-direction={twoRows ? 'column' : 'row'}
|
||||||
>
|
>
|
||||||
|
Loading…
Reference in New Issue
Block a user