Action

Archive

Posted by zigzagjeff, Last update about 2 hours ago - Unlisted

Archive Tasks — Heading-Aware + Timestamp

This action adds two functions to the “Archive Tasks” action.

  • Retains existing H2, H3, etc. groupings allowing you to maintain a log of the projects, areas, or outcomes the archived tasks were from.
  • Time stamps creation and completion date.

Steps

  • script

    // =====================================================
    // Archive Tasks — Heading-Aware + Timestamped
    //
    // Moves - [x] tasks to ## Archive, grouped under their
    // original H2/H3/H4 heading, with creation date (draft)
    // and completion datetime (system clock, to the minute).
    //
    // HOW TO INSTALL:
    //   1. In Drafts, create a new Action
    //   2. Add a single "Script" step
    //   3. Paste this entire file into that step
    //   4. Save. Run on any daily draft.
    // =====================================================
    
    (() => {
      const ARCHIVE_HDR  = '## Archive';
      const COMPLETED_RE = /^(\s*-\s\[x\]\s)/i;
      const HEADING_RE   = /^#{1,6}\s/;
      const pad = n => String(n).padStart(2, '0');
    
      // --- Timestamps ---
      const now = new Date();
      const completionStamp =
        `${now.getFullYear()}-${pad(now.getMonth()+1)}-${pad(now.getDate())}` +
        ` ${pad(now.getHours())}:${pad(now.getMinutes())}`;
    
      const cd = draft.createdAt;
      const creationStamp =
        `${cd.getFullYear()}-${pad(cd.getMonth()+1)}-${pad(cd.getDate())}`;
    
      // --- Split draft at archive boundary ---
      const text       = editor.getText();
      const lines      = text.split('\n');
      const archiveIdx = lines.findIndex(l => l.trim() === ARCHIVE_HDR);
    
      const activeLines   = archiveIdx >= 0 ? lines.slice(0, archiveIdx) : [...lines];
      const existingLines = archiveIdx >= 0 ? lines.slice(archiveIdx + 1) : [];
    
      // --- Walk active section ---
      // Track the most recent heading; collect completed tasks grouped by it.
      let currentHeading = null;
      const groups    = new Map();   // heading string → [stamped task lines]
      const remaining = [];
    
      for (const line of activeLines) {
        if (HEADING_RE.test(line)) {
          currentHeading = line.trim();
          remaining.push(line);
          continue;
        }
        if (COMPLETED_RE.test(line)) {
          const stamped = line.trimEnd() + ` ➕ ${creationStamp} ✅ ${completionStamp}`;
          if (!groups.has(currentHeading)) groups.set(currentHeading, []);
          groups.get(currentHeading).push(stamped);
        } else {
          remaining.push(line);
        }
      }
    
      // --- Nothing to archive ---
      if (groups.size === 0) {
        app.displayInfoMessage('No completed tasks found.');
        context.cancel('No completed tasks found.');
        return;
      }
    
      // --- Build new archive block ---
      // New tasks, grouped under their original headings, newest at top.
      const newBlock = [];
      for (const [heading, tasks] of groups) {
        if (heading) newBlock.push(heading);
        newBlock.push(...tasks);
        newBlock.push('');  // blank line between groups
      }
    
      // --- Tidy whitespace at seams ---
      while (remaining.length && remaining[remaining.length - 1].trim() === '') {
        remaining.pop();
      }
      while (existingLines.length && existingLines[0].trim() === '') {
        existingLines.shift();
      }
    
      // --- Reconstruct ---
      // Order: active content → ## Archive → new tasks → prior archived tasks
      const output = [
        remaining.join('\n'),
        '',
        ARCHIVE_HDR,
        '',
        ...newBlock,
        ...(existingLines.length ? existingLines : [])
      ].join('\n').trimEnd();
    
      editor.setText(output);
    })();

Options

  • After Success Nothing
    Notification Info
    Log Level Info
Items available in the Drafts Directory are uploaded by community members. Use appropriate caution reviewing downloaded items before use.