Skip to content

[BUG] dataview not rendering #108

@Huasushis

Description

@Huasushis

I use dataviewjs to renderr a table, it works well in obsidian, but when I open the publication center, an alert popped says "Unable to render dataview query. Please update the dataview plugin to the latest version."

However, my plugins are all up to date.

Quartz Syncer: 1.9.2
Dataview: 0.5.68

code in md:

```dataviewjs
dv.view("task");
```

the task.js at the root of the vault:

//task.js
const onlyProjectFolder = true;

const targetFolder = onlyProjectFolder ? "Project" : "";

// ⭐ 新增:定义你的日期格式
const dateFormat = "yyyy-MM-dd HH:mm:ss";

// ⭐ 新增:解析日期的函数
function parseDate(dateStr) {
    if (!dateStr) return null;
    // 强制按指定格式解析
    const parsed = dv.luxon.DateTime.fromFormat(dateStr, dateFormat);
    return parsed.isValid ? parsed : null;
}

let projects = dv.pages( `"${targetFolder}"` )
    .filter(p => {
        return p.PARA == "Project" && p.status != "Cancelled" && p.status != "No Status"
    })
    // ⭐ 新增排序逻辑:时间晚的(新的)排在前面
    // 注意:这里使用减法,b - a 表示 b 时间晚就排前面
    .sort((a, b) => {
        // 尝试获取 date 字段的时间戳
        const dateA = parseDate(a.date);
        const dateB = parseDate(b.date);
        
        // 如果双方都有有效日期,按时间倒序
        if (dateA && dateB) {
            return dateB - dateA; 
        }
        // 如果只有 B 有日期,B 排前面
        if (!dateA && dateB) return 1;
        // 如果只有 A 有日期,A 排前面
        if (dateA && !dateB) return -1;
        // 都没有则保持原顺序
        return 0;
    });

// 定义状态显示顺序和对应的 Emoji
const statusConfig = {
  "Focus": { emoji: "🔍" },
  "Drafting": { emoji: "✏️" },
  "In Progress": { emoji: "🚀" },
  "To Do": { emoji: "📝" },
  "Idea": { emoji: "💡" },
  "Pending": { emoji: "⏳" },
  "On Hold": { emoji: "⏸️" },
  "Completed": { emoji: "✅" }
};

// 获取状态列表(按定义顺序)
const statusOrder = Object.keys(statusConfig);

// 获取状态对应的显示文本(带 Emoji)
function getStatusDisplay(status) {
  if (statusConfig[status]) {
    return `${statusConfig[status].emoji} ${status}`;
  }
  return status; // 如果没有配置,保持原样
}

// 按状态分组
let groupedProjects = {};
projects.forEach(project => {
  if (!groupedProjects[project.status]) {
    groupedProjects[project.status] = [];
  }
  groupedProjects[project.status].push(project);
});

// 创建表格数据
let tableData = [];

// 获取当前日期
const today = new Date();
today.setHours(0, 0, 0, 0);

// 处理日期和倒计时的函数
function processDeadline(deadline) {
  // 检查是否为时间戳格式(数字)
  if (deadline && !isNaN(deadline)) {
    // 如果是数字(时间戳),转换为日期对象
    let deadlineDate = new Date(Number(deadline));
    
    // 格式化为 YYYY.MM.DD 格式
    let year = deadlineDate.getFullYear();
    let month = String(deadlineDate.getMonth() + 1).padStart(2, '0');
    let day = String(deadlineDate.getDate()).padStart(2, '0');
    let formattedDate = `${year}.${month}.${day}`;
    
    // 计算剩余天数
    const timeDiff = deadlineDate.getTime() - today.getTime();
    const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
    
    return formattedDate + getCountdownText(daysDiff);
  }
  
  // 保留原始日期显示
  let deadlineDisplay = deadline || "";
  
  if (deadline) {
    // 解析截止日期
    try {
      // 尝试解析日期
      let deadlineDate = new Date(deadline);
      
      // 检查日期是否有效
      if (!isNaN(deadlineDate.getTime())) {
        // 计算剩余天数
        deadlineDate.setHours(0, 0, 0, 0);
        const timeDiff = deadlineDate.getTime() - today.getTime();
        const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
        
        return deadlineDisplay + getCountdownText(daysDiff);
      }
    } catch (e) {
      // 解析失败,不添加倒计时信息
    }
  }
  
  return deadlineDisplay;
}

// 获取倒计时文本
function getCountdownText(daysDiff) {
  if (daysDiff > 0) {
    return `<br>还有 ${daysDiff} 天`;
  } else if (daysDiff === 0) {
    return `<br>就是今天`;
  } else {
    return `<br>💀 已过期!`;
  }
}

// 按照预定义顺序添加状态组
for (let status of statusOrder) {
  // 如果没有该状态的项目,跳过
  if (!groupedProjects[status] || groupedProjects[status].length === 0) {
    continue;
  }

  let count = groupedProjects[status].length;
  
  // 添加状态行
  tableData.push([
    `<span class="proj-status">${getStatusDisplay(status)} (${count})</span>`,
    "", "", "", ""
  ]);
  
  // 添加该状态下的项目
  groupedProjects[status].forEach(project => {
    tableData.push([
      project.file.link,
      project.passion=="Intense"?"🔥On Fire!":project.passion,
      project.type,
      `<progress value="${project.progress}" max="${project.target ? project.target : 100}"></progress><br>进度:${Math.round((project.progress / (project.target?project.target:100)) * 100)}%`,
      processDeadline(project.deadline)
    ]);
  });
}

// 处理未在预定义顺序中的状态
let otherStatuses = Object.keys(groupedProjects).filter(status => !statusOrder.includes(status));
for (let status of otherStatuses) {
  // 添加状态行
  let count = groupedProjects[status].length;
  tableData.push([
    `<span class="proj-status">${getStatusDisplay(status)} (${count})</span>`,
    "", "", "", ""
  ]);
  
  // 添加该状态下的项目
  groupedProjects[status].forEach(project => {
    tableData.push([
      project.file.link,
      project.passion,
      project.type,
      `<progress value="${project.progress}" max="${project.target ? project.target : 100}"></progress><br>进度:${Math.round((project.progress / (project.target?project.target:100)) * 100)}%`,
      processDeadline(project.deadline)
    ]);
  });
}

// 创建单个表格
dv.table(["项目", "兴致", "类型", "进度", "死线"], tableData);

// 添加样式类
dv.container.classList.add("cards-align-top");

// 添加交错行样式 - 使用 Dataview 的方式
const styleElement = dv.container.createEl('style', {
  text: `
    .dataview.table-view-table tr:nth-child(even):not(:first-child) {
      background-color: rgba(0, 0, 0, 0.05);
    }
  `
});

I think it can be stably reproduced.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions