Files
wekan/models/lib/attachmentMeta.js
T
Lauri Ojansivu 973c2ad901 Fix #3453 #3199; linked-card custom field crash; pin #3843.
- #3453: publish the FULL subtask ancestor chain, not only direct
  parents - the cross-board full-path label vanished after refresh.
- #3748 (defect half): skip unresolvable custom-field definitions on
  linked cards - phantom empty rows and a template TypeError on every
  card details render. The mirroring itself is by design: linked cards
  are pointers; label/custom-field ids are board-scoped; name-based
  inheritance is the copy feature, not the link feature.
- #3199: group each archived card with its own Restore/Delete links and
  add a clear separator below the group (RTL-safe, theme-neutral).
- #3843: comment-editor uploads and the attachments popup now share one
  null-safe meta builder, and tests pin that comment attachments list in
  the card's Attachments section.

Closes #3748: mirroring is by design (see above); the only actionable
defect is fixed in this commit.
Closes #3378: already fixed - notification_cleanup moved off SyncedCron
to a guarded Meteor.setInterval singleton, and quave:synced-cron 2.4.0
handles the E11000 history collision that percolate 1.5.x missed.
Closes #3276: already fixed by d3625db75 - the spent-time badge helpers
now read the live Cards document reactively, so the overtime color flips
immediately; verified behaviorally against the real component.
Closes #3843: behavior verified present and now regression-locked.

Thanks to MPeti1, peterbecich, fxkr, jghaanstra and xet7.
2026-07-17 03:21:02 +03:00

51 lines
2.1 KiB
JavaScript

'use strict';
// Pure helper: build the `meta` object stored on every card attachment
// (Attachments FilesCollection, ostrio:files). Kept side-effect free so it can
// be unit tested without a database or the Meteor client environment.
//
// This single builder is shared by ALL card attachment upload paths:
// - the card Attachments popup and clipboard upload
// (client/components/cards/attachments.js), and
// - images uploaded inside card COMMENTS / the card description through the
// rich text editor (client/components/main/editor.js, summernote
// onImageUpload), via Utils.getCommonAttachmentMetaFrom().
//
// Because comment uploads carry the exact same `meta.cardId` as direct card
// uploads, they are listed in the card's Attachments section, whose queries
// all key on `meta.cardId` (Template.attachmentGallery in
// client/components/cards/attachments.js and Cards.helpers.attachments in
// models/cards.js) with no `meta.source` filtering. That is the behaviour
// requested in https://github.com/wekan/wekan/issues/3843 — an attachment
// added in a card comment must stay linked to (and visible in) the card's
// global attachment list.
//
// For a linked card the attachment is attached to the REAL card (linkedId),
// so it shows up on the original card and on every linked copy.
//
// `getCardById` resolves the real card of a linked card (the client passes
// ReactiveCache.getCard). A missing/null card yields an empty meta rather
// than throwing, so a failed lookup cannot crash an upload handler.
function buildCardAttachmentMeta(card, getCardById) {
const meta = {};
if (!card) {
return meta;
}
if (typeof card.isLinkedCard === 'function' && card.isLinkedCard()) {
const realCard =
typeof getCardById === 'function' ? getCardById(card.linkedId) : null;
if (realCard) {
meta.boardId = realCard.boardId;
}
meta.cardId = card.linkedId;
} else {
meta.boardId = card.boardId;
meta.swimlaneId = card.swimlaneId;
meta.listId = card.listId;
meta.cardId = card._id;
}
return meta;
}
module.exports = { buildCardAttachmentMeta };