diff --git a/src/views/Project.vue b/src/views/Project.vue index 0d90f49..bb2770e 100644 --- a/src/views/Project.vue +++ b/src/views/Project.vue @@ -62,10 +62,11 @@ const tableHeaders = computed(() => { const fields = dataStore.projectFieldsMap.get(props.projectData.id); if (fields) { + // Сортируем поля, возможно не нужно const sortedFields = [...fields].sort((a, b) => a.order - b.order); sortedFields.forEach((field) => { headers.push({ - key: `attr_${field.id}`, + key: `attr_${field.id}`, // Ensure unique key for attributes label: field.name, isAttribute: true, attributeId: field.id, @@ -184,8 +185,10 @@ function getCellValue(userstory: Userstory, header: TableHeader): string | numbe if (value === null) return null; if (typeof value === "string" || typeof value === "number") return value; + // Если значение undefined, ?? "" превратит его в пустую строку. + // Если это объект (например, UserstoryStatusInfo) или boolean, его нужно преобразовать в строку. if (value === undefined) return ""; - return String(value); + return String(value); // Преобразует UserstoryStatusInfo, boolean и другие объекты в строку } else { if (header.attributeId === undefined) return "N/A (no attr ID)"; @@ -195,14 +198,15 @@ function getCellValue(userstory: Userstory, header: TableHeader): string | numbe if (attrValue === null) return null; if (typeof attrValue === "string" || typeof attrValue === "number") return attrValue; + // Аналогично для атрибутов if (attrValue === undefined) return ""; - return String(attrValue); + return String(attrValue); // Преобразует boolean, object в строку } if (isLoadingAttributesForAnyStory.value && !dataStore.userstoryAttributesMap.has(userstory.id)) { return "..."; } - return ""; + return ""; // Если атрибутов нет и не идет загрузка, вернуть пустую строку } } @@ -223,6 +227,6 @@ table thead tr th { font-weight: bold; } table thead tr th:hover { - background-color: var(--vt-c-black-soft); + background-color: #f2f2f2; }