mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-09 19:27:44 +02:00
Load person names in docs table (#10361)
* Load person names in docs table Signed-off-by: Artem Savchenko <armisav@gmail.com> * Clean up Signed-off-by: Artem Savchenko <armisav@gmail.com> --------- Signed-off-by: Artem Savchenko <armisav@gmail.com>
This commit is contained in:
@@ -19,6 +19,7 @@ import core, {
|
||||
type Doc,
|
||||
type Hierarchy,
|
||||
type Ref,
|
||||
type PersonId,
|
||||
concatLink,
|
||||
getDisplayTime,
|
||||
getObjectValue
|
||||
@@ -28,14 +29,12 @@ import { addNotification, NotificationSeverity, locationToUrl } from '@hcenginee
|
||||
import { getCurrentLanguage } from '@hcengineering/theme'
|
||||
import viewPlugin, { type Viewlet, type AttributeModel, type BuildModelKey } from '@hcengineering/view'
|
||||
import presentation, { getClient } from '@hcengineering/presentation'
|
||||
import { getName, getPersonByPersonId } from '@hcengineering/contact'
|
||||
import { buildModel, buildConfigLookup, getObjectLinkFragment } from './utils'
|
||||
import view from './plugin'
|
||||
import SimpleNotification from './components/SimpleNotification.svelte'
|
||||
import { copyText } from './actionImpl'
|
||||
|
||||
/**
|
||||
* Standard document attribute keys
|
||||
*/
|
||||
enum DocumentAttributeKey {
|
||||
CreatedBy = 'createdBy',
|
||||
CreatedOn = 'createdOn',
|
||||
@@ -45,9 +44,6 @@ enum DocumentAttributeKey {
|
||||
Name = 'name'
|
||||
}
|
||||
|
||||
/**
|
||||
* Date format options for Intl.DateTimeFormat
|
||||
*/
|
||||
enum DateFormatOption {
|
||||
Numeric = 'numeric',
|
||||
Short = 'short'
|
||||
@@ -124,13 +120,43 @@ export function isIntlString (value: string): boolean {
|
||||
return parts.length >= 3 && parts.every((part) => part.length > 0)
|
||||
}
|
||||
|
||||
async function loadPersonName (
|
||||
personId: PersonId,
|
||||
hierarchy: Hierarchy,
|
||||
userCache?: Map<PersonId, string>
|
||||
): Promise<string> {
|
||||
if (userCache !== undefined) {
|
||||
const cachedName = userCache.get(personId)
|
||||
if (cachedName !== undefined) {
|
||||
return cachedName
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const client = getClient()
|
||||
const person = await getPersonByPersonId(client, personId)
|
||||
if (person !== null) {
|
||||
const name = getName(hierarchy, person)
|
||||
if (userCache !== undefined) {
|
||||
userCache.set(personId, name)
|
||||
}
|
||||
return name
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to lookup user name for PersonId:', personId, error)
|
||||
}
|
||||
|
||||
return personId
|
||||
}
|
||||
|
||||
async function formatValue (
|
||||
attr: AttributeModel,
|
||||
card: Doc,
|
||||
hierarchy: Hierarchy,
|
||||
_class: Ref<Class<Doc>>,
|
||||
language: string | undefined,
|
||||
isFirstColumn: boolean = false
|
||||
isFirstColumn: boolean = false,
|
||||
userCache?: Map<PersonId, string>
|
||||
): Promise<string> {
|
||||
let value: any
|
||||
if (attr.castRequest != null) {
|
||||
@@ -173,6 +199,9 @@ async function formatValue (
|
||||
if (isIntlString(value)) {
|
||||
return await translate(value as unknown as IntlString, {}, language)
|
||||
}
|
||||
if (attr.key === DocumentAttributeKey.CreatedBy || attr.key === DocumentAttributeKey.ModifiedBy) {
|
||||
return await loadPersonName(value as PersonId, hierarchy, userCache)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
@@ -310,6 +339,9 @@ export async function CopyAsMarkdownTable (
|
||||
|
||||
const language = getCurrentLanguage()
|
||||
|
||||
// Cache for user ID (PersonId) -> name mappings to reduce database calls
|
||||
const userCache = new Map<PersonId, string>()
|
||||
|
||||
const headers: string[] = []
|
||||
for (const attr of displayableModel) {
|
||||
let label: string
|
||||
@@ -329,7 +361,7 @@ export async function CopyAsMarkdownTable (
|
||||
for (let i = 0; i < displayableModel.length; i++) {
|
||||
const attr = displayableModel[i]
|
||||
const isFirstColumn = i === 0
|
||||
const value = await formatValue(attr, card, hierarchy, props.cardClass, language, isFirstColumn)
|
||||
const value = await formatValue(attr, card, hierarchy, props.cardClass, language, isFirstColumn, userCache)
|
||||
|
||||
// If this is the first column with empty key (title attribute), create a markdown link
|
||||
if (isFirstColumn && attr.key === '') {
|
||||
|
||||
Reference in New Issue
Block a user