UBERF-13430: Display date and space for cards in Home (#9759)

Signed-off-by: Artem Savchenko <armisav@gmail.com>
This commit is contained in:
Artyom Savchenko
2025-09-02 13:47:55 +07:00
committed by GitHub
parent 1b1bbe7053
commit 4046aefdff
4 changed files with 153 additions and 78 deletions
@@ -0,0 +1,85 @@
<!--
// Copyright © 2025 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 cardPlugin, { Card } from '@hcengineering/card'
import { WithLookup } from '@hcengineering/core'
import { Icon, tooltip } from '@hcengineering/ui'
import { getEmbeddedLabel } from '@hcengineering/platform'
import { IconForward } from '@hcengineering/presentation'
import { openCardInSidebar } from '../utils'
import CardIcon from './CardIcon.svelte'
export let card: WithLookup<Card>
export let displaySpace: boolean = true
</script>
<div class="flex-presenter flex-gap-0-5">
{#if displaySpace && card.$lookup?.space !== undefined}
<div class="card-presenter">
<Icon icon={cardPlugin.icon.Card} size="small" />
<span class="overflow-label max-w-40">
{card.$lookup?.space.name}
</span>
</div>
{/if}
{#if card.parent != null}
{#if displaySpace && card.$lookup?.space !== undefined}
<IconForward size={'small'} />
{/if}
{@const info = card.parentInfo?.find((it) => it._id === card.parent)}
{#if info}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
class="card-presenter"
use:tooltip={{ label: getEmbeddedLabel(info.title), textAlign: 'left' }}
on:click|stopPropagation|preventDefault={() => openCardInSidebar(info._id)}
>
<CardIcon size="x-small" _id={info._id} editable={false} />
<span class="overflow-label max-w-40">
{info.title}
</span>
</div>
{/if}
{/if}
</div>
<style lang="scss">
.card-presenter {
display: flex;
justify-content: center;
align-items: center;
padding: 0 0.5rem;
min-width: 2rem;
max-width: 25rem;
min-height: 1.5rem;
max-height: 1.5rem;
font-size: 0.75rem;
font-weight: 500;
border-radius: var(--extra-small-BorderRadius);
white-space: nowrap;
gap: 0.25rem;
background: var(--global-ui-hover-BackgroundColor);
border: var(--global-subtle-ui-BorderColor);
color: var(--global-secondary-TextColor);
cursor: pointer;
&:hover {
background: var(--global-ui-active-BackgroundColor);
}
}
</style>
@@ -0,0 +1,41 @@
<!--
// Copyright © 2025 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 { tooltip } from '@hcengineering/ui'
import { getDisplayTime, Timestamp } from '@hcengineering/core'
import { getEmbeddedLabel } from '@hcengineering/platform'
export let date: Timestamp
export let shortTime = false
$: fullDate = new Date(date).toLocaleString('default', {
minute: '2-digit',
hour: 'numeric',
day: '2-digit',
month: 'short',
year: 'numeric'
})
function getShortTime (date: Timestamp): string {
const options: Intl.DateTimeFormatOptions = { hour: 'numeric', minute: 'numeric' }
return new Date(date).toLocaleTimeString('default', options).split(' ')[0]
}
</script>
<span class="text-sm whitespace-nowrap" use:tooltip={{ label: getEmbeddedLabel(fullDate) }}>
{shortTime ? getShortTime(date) : getDisplayTime(date)}
</span>
@@ -13,7 +13,7 @@
<script lang="ts">
import { createQuery, getClient } from '@hcengineering/presentation'
import { Card } from '@hcengineering/card'
import { SortingOrder } from '@hcengineering/core'
import core, { SortingOrder } from '@hcengineering/core'
import ui, {
eventToHTMLElement,
IconSettings,
@@ -53,7 +53,10 @@
{
sort: { modifiedOn: SortingOrder.Descending },
limit,
total: true
total: true,
lookup: {
space: core.class.Space
}
}
)
@@ -13,8 +13,8 @@
<script lang="ts">
import cardPlugin, { Card } from '@hcengineering/card'
import { createMessagesQuery } from '@hcengineering/presentation'
import { PersonId, SortingOrder } from '@hcengineering/core'
import { createMessagesQuery, IconForward } from '@hcengineering/presentation'
import { PersonId, SortingOrder, WithLookup } from '@hcengineering/core'
import { CardID, Message, Label as CardLabel } from '@hcengineering/communication-types'
import { Avatar, getPersonByPersonIdStore, PersonPreviewProvider } from '@hcengineering/contact-resources'
import { Person } from '@hcengineering/contact'
@@ -26,9 +26,10 @@
import { isHomeSettingEnabled, compactSettingId, homeSettingsStore, comfortableSettingId2 } from '../home'
import { openCardInSidebar } from '../utils'
import CardTagsColored from './CardTagsColored.svelte'
import CardIcon from './CardIcon.svelte'
import CardPathPresenter from './CardPathPresenter.svelte'
import CardTimestamp from './CardTimestamp.svelte'
export let card: Card
export let card: WithLookup<Card>
const messagesQuery = createMessagesQuery()
@@ -75,10 +76,15 @@
<span class="card__title overflow-label" use:tooltip={{ label: getEmbeddedLabel(card.title), textAlign: 'left' }}>
{card.title}
</span>
<CardTimestamp date={card.modifiedOn} />
{#if !isComfortable2}
<span class="card__tags">
<CardTagsColored value={card} />
</span>
<div class="flex-presenter flex-gap-0-5">
<CardPathPresenter {card} />
<IconForward size={'small'} />
<div class="card__tags">
<CardTagsColored value={card} />
</div>
</div>
{/if}
</div>
<div class="card__message">
@@ -92,46 +98,17 @@
</div>
<div class="card__parent" class:wrap={isComfortable2}>
{#if isComfortable2}
<span class="card__tags mr-2">
<CardTagsColored value={card} />
</span>
{/if}
{#if card.parent != null && !isCompact}
{@const info = card.parentInfo?.find((it) => it._id === card.parent)}
{#if info}
<span
class="parent"
use:tooltip={{ label: getEmbeddedLabel(info.title), textAlign: 'left' }}
on:click|stopPropagation|preventDefault={() => openCardInSidebar(info._id)}
>
<CardIcon size="x-small" _id={info._id} editable={false} />
<span class="overflow-label max-w-100">
{info.title}
</span>
</span>
{/if}
<div class="flex-presenter flex-gap-0-5">
<CardPathPresenter {card} />
<IconForward size={'small'} />
<div class="card__tags mr-2">
<CardTagsColored value={card} />
</div>
</div>
{/if}
</div>
</div>
{#if card.parent && isCompact}
{@const info = card.parentInfo?.find((it) => it._id === card.parent)}
{#if info}
<div class="card__parent column">
<span
class="parent"
use:tooltip={{ label: getEmbeddedLabel(info.title), textAlign: 'left' }}
on:click|stopPropagation|preventDefault={() => openCardInSidebar(info._id)}
>
<CardIcon size="x-small" _id={info._id} editable={false} />
<span class="overflow-label max-w-40">
{info.title}
</span>
</span>
</div>
{/if}
{/if}
{#if !isCompact}
<div class="card__actions" class:opened={isActionsOpened}>
<Button
@@ -155,8 +132,7 @@
display: flex;
cursor: pointer;
border-radius: 0.5rem;
padding: 1rem;
padding-top: 0.375rem;
padding: 0.375rem 1rem;
gap: 0.75rem;
min-height: 4.75rem;
@@ -191,6 +167,7 @@
display: flex;
flex-direction: row;
height: 2rem;
min-width: 0;
}
&__title {
@@ -221,14 +198,6 @@
&.wrap {
flex-wrap: wrap;
}
&.column {
flex-direction: column;
align-items: center;
justify-content: center;
margin-left: auto;
padding-left: 0.5rem;
}
}
&__actions {
@@ -245,29 +214,6 @@
visibility: visible;
}
}
.parent {
display: flex;
justify-content: center;
align-items: center;
padding: 0 0.5rem;
min-width: 2rem;
max-width: 25rem;
min-height: 1.5rem;
max-height: 1.5rem;
font-size: 0.75rem;
font-weight: 500;
border-radius: 1rem;
white-space: nowrap;
gap: 0.25rem;
background: var(--global-ui-hover-BackgroundColor);
border: var(--global-subtle-ui-BorderColor);
color: var(--global-secondary-TextColor);
cursor: pointer;
&:hover {
background: var(--global-ui-active-BackgroundColor);
}
}
.notifyMarker {
display: flex;