Files
Lauri Ojansivu 326d9bbf61 Board View / Version Control, issue files and synced issue details.
Version Control shows the board as a GitHub or Gitea issue tracker in the
board's own theme: cards are issues (open, or closed when archived, in a
Closed or Done list, or closed upstream), the board's labels are labels,
labels with a due date and the importers' milestone: labels are
milestones, comments are the conversation and attachments are the files.
The issue list takes GitHub's search words (is:open, label:, milestone:,
author:, assignee:@me, no:label, sort:). New issue, Close and Reopen write
through the ordinary collections, so the History tab - the board's
history table - shows them and Restore undoes them. Import links open the
GitHub, GitLab, Gitea and Forgejo importers, and each synced list has a
Sync now button.

The GitHub, GitLab, Gitea and Forgejo importers bring each issue's files:
user-attachments and user-images links, GitLab uploads, and Gitea and
Forgejo assets, downloaded through the import's SSRF guard and stored as
card attachments in Admin Panel / Attachments / Default Storage.

List sync has a new option, Comments, labels, state and files, off by
default: comments come from one paged repository-wide list (GitHub,
Gitea) or each issue's notes (GitLab), keyed by the tracker's ids, so a
second run writes only what changed, and nothing written in WeKan is
changed. Gitea issues are fetched without pull requests, and a rate
limited answer is waited out once or ends the run with the time to retry.

A public board's Show on / Default on Public Board settings are for the
public: visitors and non-members get them, read-only, and the board's own
members get the private side, so any view - Version Control, Email, Chat
and the rest - can be the read-only public view.

The card menu has a QR code of the card's link, drawn in the browser by
WeKan's own encoder, which the tests check module for module against
qrcode-svg.

The new strings are translated in every locale.

Thanks to xet7 !

Fixes #2015.
2026-10-14 12:09:34 +03:00

45 lines
1.8 KiB
JavaScript

'use strict';
import { copiedCardScrum } from './scrumCopy.js';
// #3185 "Template with subtasks and checklists". When a card is copied (e.g.
// generating a card from a template), each subtask was inserted as a BARE card
// document — its checklists (and their items) were never copied, so the new
// card's subtasks came out empty. The parent card's own checklists were copied,
// but the per-subtask copy skipped them.
//
// buildCopiedSubtaskFields() builds the card document for a copied subtask
// (re-homed under the new parent and onto the destination board), and
// subtaskCopyChildKinds() declares the child records a subtask copy must also
// reproduce — 'checklists' being the one that was missing in #3185. Meteor-free
// so the re-homing and the copy contract are unit tested; the caller then runs
// Checklist.copy() for each kind.
function buildCopiedSubtaskFields(subtask, { newParentId, boardId, swimlaneId, listId, planning = null } = {}) {
const fields = Object.assign({}, subtask);
delete fields._id;
delete fields.__id;
delete fields.syncExternalId;
delete fields.syncSourceType;
delete fields.syncLastSource;
delete fields.syncSourceKey;
delete fields.syncLabelIds;
delete fields.syncIssueState;
delete fields.scrum;
delete fields.scrumRevision;
// On another board, its sprint and release by name (scrumCopy.js).
Object.assign(fields, copiedCardScrum(subtask, boardId, { planning }));
fields.parentId = newParentId;
fields.boardId = boardId;
fields.swimlaneId = swimlaneId;
fields.listId = listId;
return fields;
}
// The child-record kinds a full subtask copy must reproduce. Guards #3185: a
// subtask copy that reproduces only the card (this list empty / missing
// 'checklists') is the regression.
function subtaskCopyChildKinds() {
return ['checklists'];
}
export { buildCopiedSubtaskFields, subtaskCopyChildKinds };