基于DataviewJS的Tasks查询每周的任务

PixPin_2024-12-22_15-45-38

基于DataviewJS的 Tasks 查询语法来查询和管理每周的任务,可以在 Obsidian 中轻松列出本周的任务,包括已完成的、尚未完成的以及计划中的任务。

任务状态类型

Tasks 插件定义的任务状态 (task.status.type),任务状态类型只有 4 种:TODO、DONE、IN_PROGRESS、CANCELLED。

状态符号 下一个状态符号 状态名称 状态类型
空格 x 待办 TODO
x 空格 已完成 DONE
/ x 进行中 IN_PROGRESS
- 空格 取消 CANCELLED

任务名称

可能这些状态对于任务管理的分类来说有点简单了,Tasks 插件还支持自定义的任务样式以及设置不同的任务状态名称 (task.status.name),你可以通过在 tasks 插件设置中进行添加自定义任务名称以及设置对应的任务类型。

示意

image

幸运的是,Tasks 插件支持一键导入个别主题定义的复选框样式,只需要点击你需要主题定义的样式既可。

示意

image

如果你不想专门为了一个复选框样式去更改主题,也可以使用如下的 Minimal 主题的复选框样式的片段:

导入后可以二次编辑,比如修改一些任务名称的任务类型,或者删除一些你需要的状态。

Tasks查询本周今日的任务并分组

列出本周今日的完成或未完成的任务 (包含今日日记为规划的任务),按任务状态名称
```tasks
{(done on today) OR (happens on today)} OR {(happens on or before today) AND (not done) AND (happens on this week)} \
OR {filter by function \
    const filename = task.file.filenameWithoutExtension; \
    const date1 = window.moment(filename).format('YYYY-MM-DD');\
    const date2 = window.moment().format('YYYY-MM-DD');\
    return date1 === date2;}
# show tree
# group by recurring reverse
group by status.name reverse
limit groups 4
short mode
```

基于 DataviewJS 的改造

```dataviewjs
// 获取当前日期
const today = window.moment();
let selectedDate = today.clone();
let currentWeekOffset = 0;

// showTree 状态
let showTree = true;
let showWeekTasks = false;

// 创建一个用于显示当前周次的标签
const weekControlsContainer = document.createElement("div");
weekControlsContainer.style.textAlign = "center";
weekControlsContainer.style.marginBottom = "10px";

// 创建 week input
const weekInput = document.createElement("input");
weekInput.type = "week";

// 为 week input 设置样式
Object.assign(weekInput.style, {
  fontSize: "1.2rem", 
  color: "var(--text-normal)",
  backgroundColor: "var(--background-primary)", 
  border: "1px solid var(--background-modifier-border)", 
  borderRadius: "4px", 
  padding: "0.2rem", 
  outline: "none"
});

// 设置初始值为当前周
function getFormattedWeekString(date) {
  const year = date.format("GGGG"); // 使用ISO年
  const week = date.format("WW");
  return `${year}-W${week}`;
}
weekInput.value = getFormattedWeekString(today);

// 设置 week input 的事件监听
weekInput.addEventListener("change", () => {
  const [year, week] = weekInput.value.split('-W').map(str => parseInt(str));
  const firstWeek = today.clone().year(year).startOf('year').week(1);
  const targetWeekStart = firstWeek.add(week - 1, 'weeks');
  currentWeekOffset = targetWeekStart.week() - today.week();
  dayButtonsContainer.children[0].click();
});

// 创建操作按钮
const leftButtonWeek = document.createElement("button");
const rightButtonWeek = document.createElement("button");
const toggleShowTreeButton = document.createElement("button");
const toggleShowWeekTasksButton = document.createElement("button");
const todayButton = document.createElement("button");

[leftButtonWeek, rightButtonWeek, todayButton, toggleShowTreeButton,toggleShowWeekTasksButton].forEach(button => {
  button.style.border = "none";
  button.style.margin = "0 5px";
  button.style.padding = "5px 10px";
  button.style.backgroundColor = "var(--interactive-accent)";
  button.style.fontSize = "large";
  button.style.color = "var(--text-on-accent)";
  button.style.cursor = "pointer";
});
leftButtonWeek.textContent = "←";
rightButtonWeek.textContent = "→";
toggleShowTreeButton.textContent = "↳";
toggleShowWeekTasksButton.textContent = "周报";
todayButton.textContent = "今日";

// 添加按钮逻辑
leftButtonWeek.addEventListener("click", () => {
  currentWeekOffset -= 1;
  updateWeekInput();
  dayButtonsContainer.children[0].click();
});

rightButtonWeek.addEventListener("click", () => {
  currentWeekOffset += 1;
  updateWeekInput();
  dayButtonsContainer.children[0].click();
});

todayButton.addEventListener("click", () => {
  currentWeekOffset = 0;
  updateWeekInput();
  const todayIndex = today.day() === 0 ? 6 : today.day() - 1;
  dayButtonsContainer.children[todayIndex].click();
});

// 初始化 可选按钮
function initButtonTheme(button, active) {
  if (active) {
    button.style.color = "var(--text-on-accent)";
    button.style.backgroundColor = "var(--interactive-accent)";
  } else {
    button.style.color = "var(--text-normal)";
    button.style.backgroundColor = "transparent";
  }
}

toggleShowTreeButton.addEventListener("click", () => {
  showTree = !showTree;
  initButtonTheme(toggleShowTreeButton, showTree);
  dayButtonsContainer.querySelector("button[style*='interactive-accent']").click();
});

toggleShowWeekTasksButton.addEventListener("click", () => {
  showWeekTasks = !showWeekTasks;
  initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);
  dayButtonsContainer.querySelector("button[style*='interactive-accent']").click();
});

// 初始化按钮主题色
initButtonTheme(toggleShowTreeButton, showTree);
initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);


// 更新周次选择框
function updateWeekInput() {
  const startDate = today.clone().startOf('week').add(currentWeekOffset, 'weeks');
  weekInput.value = getFormattedWeekString(startDate);
}

// 插入控件
weekControlsContainer.appendChild(toggleShowWeekTasksButton);
weekControlsContainer.appendChild(leftButtonWeek);
weekControlsContainer.appendChild(weekInput);
weekControlsContainer.appendChild(rightButtonWeek);
weekControlsContainer.appendChild(toggleShowTreeButton);
weekControlsContainer.appendChild(todayButton);
// 添加到页面中
document.body.appendChild(weekControlsContainer);
dv.container.appendChild(weekControlsContainer);

// 创建星期按钮
const daysOfWeek = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"];
const dayButtonsContainer = document.createElement("div");
dayButtonsContainer.style.display = "flex";
dayButtonsContainer.style.justifyContent = "center";
dayButtonsContainer.style.width = "100%";

// 存储当前选中的按钮
let selectedButton;
// 添加样式的默认值
const defaultButtonStyle = {
  border: "none",
  borderRadius: "0px",
  cursor: "pointer",
  fontSize: "large",
  flex: "1 1 auto",
  color: "var(--text-normal)",
  backgroundColor: "transparent",
};

daysOfWeek.forEach((day, index) => {
  const button = document.createElement("button");
  Object.assign(button.style, defaultButtonStyle);
  button.textContent = day;
  
  button.addEventListener("click", () => {
    // 设置选中的日期
    selectedDate = today.clone().startOf("week").add(currentWeekOffset, "weeks").add(index, "days");
    updateTasksView();

    // 更新先前选中按钮的样式
    if (selectedButton) {
      Object.assign(selectedButton.style, defaultButtonStyle);
    }

    // 更新选中按钮的样式
    button.style.backgroundColor = "var(--interactive-accent)";
    button.style.color = "var(--text-on-accent)";
    selectedButton = button;
  });

  dayButtonsContainer.appendChild(button);
});
// 插入星期按钮容器
dv.container.appendChild(dayButtonsContainer);

function updateTasksView() {
  dv.container.innerHTML = "";
  dv.container.appendChild(weekControlsContainer);
  dv.container.appendChild(dayButtonsContainer);

  const dateStr = selectedDate.format("YYYY-MM-DD");
  const weekStr = selectedDate.format("YYYY-[W]WW");
  const showTreeOption = showTree ? "show tree" : "";
  const queryDayOfWeek = `
    {(done on ${dateStr}) OR (happens on ${dateStr}) }\\
     OR {(happens before ${dateStr}) AND (not done) AND (happens on ${weekStr}) }\\
     OR {filter by function \\
        const filename = task.file.filenameWithoutExtension;\\
        const date1 = window.moment(filename).format('YYYY-MM-DD');\\
        return date1 === '${dateStr}';}
    ${showTreeOption}
    group by status.name reverse
    short mode
    is not recurring
    # limit groups 5
    `;
  const queryWeek = `
    group by function task.description.includes("http") ? "🌐阅读记录" : "📅任务记录"
    {(done on ${weekStr}) OR (happens on ${weekStr})}
    ${showTreeOption}
    is not recurring
    # group by status.name
    group by done reverse
    short mode
    limit 100
    `;
  const query = !showWeekTasks ? queryDayOfWeek : queryWeek;

  dv.paragraph("```tasks\n" + query + "\n```");
}

// 初始化:选择今天
todayButton.click()

// 监听今日按钮的双击事件
todayButton.addEventListener("dblclick", () => {
  app.commands.executeCommandById("daily-notes");
});

```

界面介绍

image

Tip:固定到侧边

可以将该查询笔记固定到侧边栏方便随时查看,可以用CSS隐藏固定按钮:

隐藏侧边栏的固定按钮.css
/* !在左右侧边栏中不显示固定按钮 */  
.workspace-split.mod-horizontal.mod-right-split,  
.workspace-split.mod-horizontal.mod-left-split {  
  .workspace-tab-header-status-container {  
    display: none;  
  }  
  /* 缩减底部空白 不然可能加载成空白页 */  
  .markdown-preview-section {  
    padding-bottom: 0px !important;  
    min-height: unset !important;  
  }  
  
  .embedded-backlinks {  
    display: none;  
  }  
}

Reference

5 个赞

强得了:+1::+1::+1:!!

太强大的脚本了, 能不能把没有截止时间的增加一个栏目:inbox

有意思,可以说说没有截止日期的任务,到底具体指什么类型的任务呢?这边也可以加上

优化下周报的Tasks查询:

  1. 分为:globe_with_meridians:阅读记录和:date:任务记录
  2. 简化分组,只按日期分组

效果如下:

请将下述查询语法赋值给queryWeek变量

group by function task.description.includes("http") ? "🌐阅读记录" : "📅任务记录"
{(done on ${weekStr}) OR (happens on ${weekStr})}
${showTreeOption}
# group by status.name
group by done reverse
short mode
完整代码

```dataviewjs
// 获取当前日期
const today = window.moment();
let selectedDate = today.clone();
let currentWeekOffset = 0;

// showTree 状态
let showTree = false;
let showWeekTasks = false;

// 创建一个用于显示当前周次的标签
const weekControlsContainer = document.createElement("div");
weekControlsContainer.style.textAlign = "center";
weekControlsContainer.style.marginBottom = "10px";

// 创建 week input
const weekInput = document.createElement("input");
weekInput.type = "week";

// 为 week input 设置样式
Object.assign(weekInput.style, {
  fontSize: "1.2rem", 
  color: "var(--text-normal)",
  backgroundColor: "var(--background-primary)", 
  border: "1px solid var(--background-modifier-border)", 
  borderRadius: "4px", 
  padding: "0.2rem", 
  outline: "none"
});

// 设置初始值为当前周
function getFormattedWeekString(date) {
  const year = date.format("YYYY");
  const week = date.format("WW");
  return `${year}-W${week}`;
}
weekInput.value = getFormattedWeekString(today);

// 设置 week input 的事件监听
weekInput.addEventListener("change", () => {
  const [year, week] = weekInput.value.split('-W').map(str => parseInt(str));
  const firstWeek = today.clone().year(year).startOf('year').week(1);
  const targetWeekStart = firstWeek.add(week - 1, 'weeks');
  currentWeekOffset = targetWeekStart.week() - today.week();
  dayButtonsContainer.children[0].click();
});

// 创建操作按钮
const leftButtonWeek = document.createElement("button");
const rightButtonWeek = document.createElement("button");
const toggleShowTreeButton = document.createElement("button");
const toggleShowWeekTasksButton = document.createElement("button");
const todayButton = document.createElement("button");

[leftButtonWeek, rightButtonWeek, todayButton, toggleShowTreeButton,toggleShowWeekTasksButton].forEach(button => {
  button.style.border = "none";
  button.style.margin = "0 5px";
  button.style.padding = "5px 10px";
  button.style.backgroundColor = "var(--interactive-accent)";
  button.style.fontSize = "large";
  button.style.color = "var(--text-on-accent)";
  button.style.cursor = "pointer";
});
leftButtonWeek.textContent = "←";
rightButtonWeek.textContent = "→";
toggleShowTreeButton.textContent = "↳";
toggleShowWeekTasksButton.textContent = "周报";
todayButton.textContent = "今日";

// 添加按钮逻辑
leftButtonWeek.addEventListener("click", () => {
  currentWeekOffset -= 1;
  updateWeekInput();
  dayButtonsContainer.children[0].click();
});

rightButtonWeek.addEventListener("click", () => {
  currentWeekOffset += 1;
  updateWeekInput();
  dayButtonsContainer.children[0].click();
});

todayButton.addEventListener("click", () => {
  currentWeekOffset = 0;
  updateWeekInput();
  const todayIndex = today.day() === 0 ? 6 : today.day() - 1;
  dayButtonsContainer.children[todayIndex].click();
});

// 初始化 可选按钮
function initButtonTheme(button, active) {
  if (active) {
    button.style.color = "var(--text-on-accent)";
    button.style.backgroundColor = "var(--interactive-accent)";
  } else {
    button.style.color = "var(--text-normal)";
    button.style.backgroundColor = "transparent";
  }
}

toggleShowTreeButton.addEventListener("click", () => {
  showTree = !showTree;
  initButtonTheme(toggleShowTreeButton, showTree);
  dayButtonsContainer.querySelector("button[style*='interactive-accent']").click();
});

toggleShowWeekTasksButton.addEventListener("click", () => {
  showWeekTasks = !showWeekTasks;
  initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);
  dayButtonsContainer.querySelector("button[style*='interactive-accent']").click();
});

// 初始化按钮主题色
initButtonTheme(toggleShowTreeButton, showTree);
initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);


// 更新周次选择框
function updateWeekInput() {
  const startDate = today.clone().startOf('week').add(currentWeekOffset, 'weeks');
  weekInput.value = getFormattedWeekString(startDate);
}

// 插入控件
weekControlsContainer.appendChild(toggleShowWeekTasksButton);
weekControlsContainer.appendChild(leftButtonWeek);
weekControlsContainer.appendChild(weekInput);
weekControlsContainer.appendChild(rightButtonWeek);
weekControlsContainer.appendChild(toggleShowTreeButton);
weekControlsContainer.appendChild(todayButton);
// 添加到页面中
document.body.appendChild(weekControlsContainer);
dv.container.appendChild(weekControlsContainer);

// 创建星期按钮
const daysOfWeek = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"];
const dayButtonsContainer = document.createElement("div");
dayButtonsContainer.style.display = "flex";
dayButtonsContainer.style.justifyContent = "center";
dayButtonsContainer.style.width = "100%";

// 存储当前选中的按钮
let selectedButton;
// 添加样式的默认值
const defaultButtonStyle = {
  border: "none",
  borderRadius: "0px",
  cursor: "pointer",
  fontSize: "large",
  flex: "1 1 auto",
  color: "var(--text-normal)",
  backgroundColor: "transparent",
};

daysOfWeek.forEach((day, index) => {
  const button = document.createElement("button");
  Object.assign(button.style, defaultButtonStyle);
  button.textContent = day;
  
  button.addEventListener("click", () => {
    // 设置选中的日期
    selectedDate = today.clone().startOf("week").add(currentWeekOffset, "weeks").add(index, "days");
    updateTasksView();

    // 更新先前选中按钮的样式
    if (selectedButton) {
      Object.assign(selectedButton.style, defaultButtonStyle);
    }

    // 更新选中按钮的样式
    button.style.backgroundColor = "var(--interactive-accent)";
    button.style.color = "var(--text-on-accent)";
    selectedButton = button;
  });

  dayButtonsContainer.appendChild(button);
});
// 插入星期按钮容器
dv.container.appendChild(dayButtonsContainer);

function updateTasksView() {
  dv.container.innerHTML = "";
  dv.container.appendChild(weekControlsContainer);
  dv.container.appendChild(dayButtonsContainer);

  const dateStr = selectedDate.format("YYYY-MM-DD");
  const weekStr = selectedDate.format("YYYY-[W]WW");
  const showTreeOption = showTree ? "show tree" : "";
  const queryDayOfWeek = `
    {(done on ${dateStr}) OR (happens on ${dateStr}) }\\
     OR {(happens before ${dateStr}) AND (not done) AND (happens on ${weekStr}) }\\
     OR {filter by function \\
        const filename = task.file.filenameWithoutExtension;\\
        const date1 = window.moment(filename).format('YYYY-MM-DD');\\
        return date1 === '${dateStr}';}
    ${showTreeOption}
    # group by recurring reverse
    group by status.name reverse
    short mode
    limit groups 5
    `;
  const queryWeek = `
    group by function task.description.includes("http") ? "🌐阅读记录" : "📅任务记录"
    {(done on ${weekStr}) OR (happens on ${weekStr})}
    ${showTreeOption}
    # group by status.name
    group by done reverse
    short mode
    `;
  const query = !showWeekTasks ? queryDayOfWeek : queryWeek;

  dv.paragraph("```tasks\n" + query + "\n```");
}

// 初始化:选择今天
todayButton.click()

// 监听今日按钮的双击事件
todayButton.addEventListener("dblclick", () => {
  app.commands.executeCommandById("daily-notes");
});
```
1 个赞

感谢分享 :pray:
在我的ubuntu里周一获得的日期是上一天的,也就是周日的,可能英文系统里周的第一天是周日的原因,不太懂js,搜了下moment可以配置

window.moment.updateLocale("en", {
    week: {
        // Set the First day of week to Monday
        dow: 1,
    },
});

日常都是用dataview操作下面这样的任务

Job A [created:: 2024-12-09] [scheduled:: 2024-12-09] [due:: 2024-12-15] [tid:: T0010cf] [completion:: 2024-12-11]

稍微改一下就可以用了 :clap:

  const weekStart = selectedDate.startOf('isoweek').format("YYYY-MM-DD")
  const weekEnd = selectedDate.endOf('isoweek').format("YYYY-MM-DD")  
  const showTreeOption = showTree ? "show tree" : "";
  const queryDayOfWeek = `
    TASK
    WHERE completion = date("${dateStr}") OR (!completion AND scheduled AND scheduled <= date("${dateStr}"))
    `;
  const queryWeek = `
    TASK
    WHERE completion >= date("${weekStart}") AND completion <= date("${weekEnd}")
    `;
  const query = !showWeekTasks ? queryDayOfWeek : queryWeek;

  dv.paragraph("```dataview\n" + query + "\n```");
1 个赞

年度最佳任务查询面板!!

1 个赞

好像出错了,
Tasks query:do not understand query
Problem line:"return datel ==date2;}

emmm 我排查了我发的2个代码,都正常运行,请直接点复制按钮以及关闭ob内的文本格式化插件,可能会导致粘贴文本出错。

简单加了一个inbox按钮,用的tasks语法是这样的:
image

not done
group by function task.due.category.groupText

# 不包含的路径
path does not include "700【模板】Template"
# 不包含看板文件的任务
filter by function !task.file.hasProperty('kanban-plugin')

short mode
hide tags
limit groups 10

其中group by function task.due.category.groupText分组任务的日期至5个广泛类别: Invalid dateOverdueTodayFutureUndated ,以该顺序显示。

dvjs
// 获取当前日期
const today = window.moment();
let selectedDate = today.clone();
let currentWeekOffset = 0;

// 初始状态
let showTree = true;
let showWeekTasks = false;
let showInbox = false;

// 创建一个用于显示当前周次的标签
const weekControlsContainer = document.createElement("div");
weekControlsContainer.style.textAlign = "center";
weekControlsContainer.style.marginBottom = "10px";

// 创建 week input
const weekInput = document.createElement("input");
weekInput.type = "week";

// 为 week input 设置样式
Object.assign(weekInput.style, {
  fontSize: "large", 
  color: "var(--text-normal)",
  backgroundColor: "var(--background-primary)", 
  border: "1px solid var(--background-modifier-border)", 
  borderRadius: "4px", 
  padding: "0.2rem", 
  outline: "none"
});

// 设置初始值为当前周
function getFormattedWeekString(date) {
  const year = date.format("GGGG"); // 使用ISO年
  const week = date.format("WW");
  return `${year}-W${week}`;
}
weekInput.value = getFormattedWeekString(today);

// 设置 week input 的事件监听
weekInput.addEventListener("change", () => {
  const [year, week] = weekInput.value.split('-W').map(str => parseInt(str));
  const firstWeek = today.clone().year(year).startOf('year').week(1);
  const targetWeekStart = firstWeek.add(week - 1, 'weeks');
  currentWeekOffset = targetWeekStart.week() - today.week();
  dayButtonsContainer.children[0].click();
});

// 创建操作按钮
const leftButtonWeek = document.createElement("button");
const rightButtonWeek = document.createElement("button");
const toggleShowTreeButton = document.createElement("button");
const toggleShowWeekTasksButton = document.createElement("button");
const toggleInboxTasksButton = document.createElement("button");
const todayButton = document.createElement("button");

[leftButtonWeek, rightButtonWeek, todayButton,toggleInboxTasksButton, toggleShowTreeButton,toggleShowWeekTasksButton].forEach(button => {
  button.style.border = "none";
  button.style.margin = "0 5px";
  button.style.padding = "5px 10px";
  button.style.backgroundColor = "var(--interactive-accent)";
  button.style.fontSize = "large";
  button.style.color = "var(--text-on-accent)";
  button.style.cursor = "pointer";
});
leftButtonWeek.textContent = "←";
rightButtonWeek.textContent = "→";
toggleShowTreeButton.textContent = "↳";
toggleShowWeekTasksButton.textContent = "周报";
todayButton.textContent = "今日";
toggleInboxTasksButton.textContent = "Inbox";

// 添加按钮逻辑
leftButtonWeek.addEventListener("click", () => {
  currentWeekOffset -= 1;
  updateWeekInput();
  dayButtonsContainer.children[0].click();
});

rightButtonWeek.addEventListener("click", () => {
  currentWeekOffset += 1;
  updateWeekInput();
  dayButtonsContainer.children[0].click();
});

todayButton.addEventListener("click", () => {
  currentWeekOffset = 0;
  updateWeekInput();
  const todayIndex = today.day() === 0 ? 6 : today.day() - 1;
  dayButtonsContainer.children[todayIndex].click();
});

// 初始化 可选按钮
function initButtonTheme(button, active) {
  if (active) {
    button.style.color = "var(--text-on-accent)";
    button.style.backgroundColor = "var(--interactive-accent)";
  } else {
    button.style.color = "var(--text-normal)";
    button.style.backgroundColor = "transparent";
  }
}

toggleShowTreeButton.addEventListener("click", () => {
  showTree = !showTree;
  initButtonTheme(toggleShowTreeButton, showTree);
  dayButtonsContainer.querySelector("button[style*='interactive-accent']").click();
});

toggleShowWeekTasksButton.addEventListener("click", () => {
  showWeekTasks = !showWeekTasks;
  initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);
  dayButtonsContainer.querySelector("button[style*='interactive-accent']").click();
});

toggleInboxTasksButton.addEventListener("click", () => {
  showInbox = !showInbox;
  initButtonTheme(toggleInboxTasksButton, showInbox);
  dayButtonsContainer.querySelector("button[style*='interactive-accent']").click();
});

// 初始化按钮主题色
initButtonTheme(toggleShowTreeButton, showTree);
initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);
initButtonTheme(toggleInboxTasksButton, showInbox);


// 更新周次选择框
function updateWeekInput() {
  const startDate = today.clone().startOf('week').add(currentWeekOffset, 'weeks');
  weekInput.value = getFormattedWeekString(startDate);
}

// 插入控件
weekControlsContainer.appendChild(toggleShowWeekTasksButton);
weekControlsContainer.appendChild(toggleInboxTasksButton);
weekControlsContainer.appendChild(leftButtonWeek);
weekControlsContainer.appendChild(weekInput);
weekControlsContainer.appendChild(rightButtonWeek);
weekControlsContainer.appendChild(toggleShowTreeButton);
weekControlsContainer.appendChild(todayButton);
// 添加到页面中
document.body.appendChild(weekControlsContainer);
dv.container.appendChild(weekControlsContainer);

// 创建星期按钮
const daysOfWeek = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"];
const dayButtonsContainer = document.createElement("div");
dayButtonsContainer.style.display = "flex";
dayButtonsContainer.style.justifyContent = "center";
dayButtonsContainer.style.width = "100%";

// 存储当前选中的按钮
let selectedButton;
// 添加样式的默认值
const defaultButtonStyle = {
  border: "none",
  borderRadius: "0px",
  cursor: "pointer",
  fontSize: "large",
  flex: "1 1 auto",
  color: "var(--text-normal)",
  backgroundColor: "transparent",
};

daysOfWeek.forEach((day, index) => {
  const button = document.createElement("button");
  Object.assign(button.style, defaultButtonStyle);
  button.textContent = day;
  
  button.addEventListener("click", () => {
    // 设置选中的日期
    selectedDate = today.clone().startOf("week").add(currentWeekOffset, "weeks").add(index, "days");
    updateTasksView();

    // 更新先前选中按钮的样式
    if (selectedButton) {
      Object.assign(selectedButton.style, defaultButtonStyle);
    }

    // 更新选中按钮的样式
    button.style.backgroundColor = "var(--interactive-accent)";
    button.style.color = "var(--text-on-accent)";
    selectedButton = button;
  });

  dayButtonsContainer.appendChild(button);
});
// 插入星期按钮容器
dv.container.appendChild(dayButtonsContainer);

function updateTasksView() {
  dv.container.innerHTML = "";
  dv.container.appendChild(weekControlsContainer);
  dv.container.appendChild(dayButtonsContainer);

  const dateStr = selectedDate.format("YYYY-MM-DD");
  const weekStr = selectedDate.format("YYYY-[W]WW");
  const showTreeOption = showTree ? "show tree" : "";
  let queryDayOfWeek = `
    {(done on ${dateStr}) OR (happens on ${dateStr}) }\\
     OR {(happens before ${dateStr}) AND (not done) AND (happens on ${weekStr}) }\\
     OR {filter by function \\
        const filename = task.file.filenameWithoutExtension;\\
        const date1 = window.moment(filename).format('YYYY-MM-DD');\\
        return date1 === '${dateStr}';}
    ${showTreeOption}
    group by status.name reverse
    short mode
    is not recurring
    # limit groups 5
    `;
  const queryWeek = `
    group by function task.description.includes("http") ? "🌐阅读记录" : "📅任务记录"
    {(done on ${weekStr}) OR (happens on ${weekStr})}
    ${showTreeOption}
    is not recurring
    # group by status.name
    group by done reverse
    short mode
    limit 100
    `;
  const queryInbox = `
    not done
    group by function task.due.category.groupText
    ${showTreeOption}
    # 不包含的路径
    path does not include "700【模板】Template"
    # 不包含看板文件的任务
    filter by function !task.file.hasProperty('kanban-plugin')

    short mode
    hide tags
    limit groups 10
    `;
  queryDayOfWeek = !showInbox ? queryDayOfWeek : queryInbox
  const query = !showWeekTasks ? queryDayOfWeek : queryWeek;


  dv.paragraph("```tasks\n" + query + "\n```");
}

// 初始化:选择今天
todayButton.click()

// 监听今日按钮的双击事件
todayButton.addEventListener("dblclick", () => {
  app.commands.executeCommandById("daily-notes");
});

修改选择的选项以及按钮状态保存至全局属性,防止dvjs刷新界面带来的界面重置。

dvjs
```dataviewjs
window.moment.updateLocale("en", {
    week: {
        dow: 1,
    },
});
// 获取当前日期
const today = window.moment();
let selectedDate = today.clone();
let currentWeekOffset = 0;

// 初始状态
let showTree = true;
let showWeekTasks = false;
let showInbox = false;

// 检查是否存在全局数据,如果不存在则初始化
if (!window.tasksQueryData) {
  window.tasksQueryData = {
    showTree: true,
    showWeekTasks: false,
    showInbox: false,
    currentWeekOffset: 0,
    selectedDate: today.format("YYYY-MM-DD")
  };
} else {
  // 恢复状态
  showTree = window.tasksQueryData.showTree;
  showWeekTasks = window.tasksQueryData.showWeekTasks;
  showInbox = window.tasksQueryData.showInbox;
  currentWeekOffset = window.tasksQueryData.currentWeekOffset;
  selectedDate = window.moment(window.tasksQueryData.selectedDate);
}

// 创建一个用于显示当前周次的标签
const weekControlsContainer = document.createElement("div");
weekControlsContainer.style.textAlign = "center";
weekControlsContainer.style.marginBottom = "10px";

// 创建 week input
const weekInput = document.createElement("input");
weekInput.type = "week";

// 为 week input 设置样式
Object.assign(weekInput.style, {
  fontSize: "larger", 
  color: "var(--text-normal)",
  backgroundColor: "var(--background-primary)", 
  border: "1px solid var(--background-modifier-border)", 
  borderRadius: "4px", 
  padding: "0.2rem", 
  outline: "none"
});

// 设置初始值为当前周
function getFormattedWeekString(date) {
  const year = date.format("GGGG"); // 使用ISO年
  const week = date.format("WW");
  return `${year}-W${week}`;
}
weekInput.value = getFormattedWeekString(selectedDate);

// 设置 week input 的事件监听
weekInput.addEventListener("change", () => {
  const [year, week] = weekInput.value.split('-W').map(str => parseInt(str));
  const firstWeek = today.clone().year(year).startOf('year').week(1);
  const targetWeekStart = firstWeek.add(week - 1, 'weeks');
  currentWeekOffset = targetWeekStart.week() - today.week();
  dayButtonsContainer.children[0].click();
  saveState();
});

// 创建操作按钮
const leftButtonWeek = document.createElement("button");
const rightButtonWeek = document.createElement("button");
const toggleShowTreeButton = document.createElement("button");
const toggleShowWeekTasksButton = document.createElement("button");
const toggleInboxTasksButton = document.createElement("button");
const todayButton = document.createElement("button");

[leftButtonWeek, rightButtonWeek, todayButton,toggleInboxTasksButton, toggleShowTreeButton,toggleShowWeekTasksButton].forEach(button => {
  button.style.border = "none";
  button.style.margin = "0 5px";
  button.style.padding = "5px 10px";
  button.style.backgroundColor = "var(--interactive-accent)";
  button.style.fontSize = "large";
  button.style.color = "var(--text-on-accent)";
  button.style.cursor = "pointer";
});
leftButtonWeek.textContent = "←";
rightButtonWeek.textContent = "→";
toggleShowTreeButton.textContent = "↳";
toggleShowWeekTasksButton.textContent = "周报";
todayButton.textContent = "今日";
toggleInboxTasksButton.textContent = "Inbox";

// 添加按钮逻辑
leftButtonWeek.addEventListener("click", () => {
  currentWeekOffset -= 1;
  updateWeekInput();
  dayButtonsContainer.children[0].click();
  saveState();
});

rightButtonWeek.addEventListener("click", () => {
  currentWeekOffset += 1;
  updateWeekInput();
  dayButtonsContainer.children[0].click();
  saveState();
});

todayButton.addEventListener("click", () => {
  currentWeekOffset = 0;
  updateWeekInput();
  const todayIndex = today.day() === 0 ? 6 : today.day() - 1;
  dayButtonsContainer.children[todayIndex].click();
  saveState();
});

// 初始化 可选按钮
function initButtonTheme(button, active) {
  if (active) {
    button.style.color = "var(--text-on-accent)";
    button.style.backgroundColor = "var(--interactive-accent)";
  } else {
    button.style.color = "var(--text-normal)";
    button.style.backgroundColor = "transparent";
  }
}

toggleShowTreeButton.addEventListener("click", () => {
  showTree = !showTree;
  initButtonTheme(toggleShowTreeButton, showTree);
  dayButtonsContainer.querySelector("button[style*='interactive-accent']").click();
  saveState();
});

toggleShowWeekTasksButton.addEventListener("click", () => {
  showWeekTasks = !showWeekTasks;
  initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);
  dayButtonsContainer.querySelector("button[style*='interactive-accent']").click();
  saveState();
});

toggleInboxTasksButton.addEventListener("click", () => {
  showInbox = !showInbox;
  initButtonTheme(toggleInboxTasksButton, showInbox);
  dayButtonsContainer.querySelector("button[style*='interactive-accent']").click();
  saveState();
});

// 初始化按钮主题色
initButtonTheme(toggleShowTreeButton, showTree);
initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);
initButtonTheme(toggleInboxTasksButton, showInbox);

// 更新周次选择框
function updateWeekInput() {
  const startDate = today.clone().startOf('week').add(currentWeekOffset, 'weeks');
  weekInput.value = getFormattedWeekString(startDate);
}

// 保存当前状态到全局属性
function saveState() {
  window.tasksQueryData = {
    showTree: showTree,
    showWeekTasks: showWeekTasks,
    showInbox: showInbox,
    currentWeekOffset: currentWeekOffset,
    selectedDate: selectedDate.format("YYYY-MM-DD")
  };
}

// 插入控件
weekControlsContainer.appendChild(toggleShowWeekTasksButton);
weekControlsContainer.appendChild(toggleInboxTasksButton);
weekControlsContainer.appendChild(leftButtonWeek);
weekControlsContainer.appendChild(weekInput);
weekControlsContainer.appendChild(rightButtonWeek);
weekControlsContainer.appendChild(toggleShowTreeButton);
weekControlsContainer.appendChild(todayButton);
// 添加到页面中
document.body.appendChild(weekControlsContainer);
dv.container.appendChild(weekControlsContainer);

// 创建星期按钮
const daysOfWeek = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"];
const dayButtonsContainer = document.createElement("div");
dayButtonsContainer.style.display = "flex";
dayButtonsContainer.style.justifyContent = "center";
dayButtonsContainer.style.width = "100%";

// 存储当前选中的按钮
let selectedButton;
// 添加样式的默认值
const defaultButtonStyle = {
  border: "none",
  borderRadius: "0px",
  cursor: "pointer",
  fontSize: "large",
  flex: "1 1 auto",
  color: "var(--text-normal)",
  backgroundColor: "transparent",
};

daysOfWeek.forEach((day, index) => {
  const button = document.createElement("button");
  Object.assign(button.style, defaultButtonStyle);
  button.textContent = day;
  
  button.addEventListener("click", () => {
    // 设置选中的日期
    selectedDate = today.clone().startOf("week").add(currentWeekOffset, "weeks").add(index, "days");
    updateTasksView();

    // 更新先前选中按钮的样式
    if (selectedButton) {
      Object.assign(selectedButton.style, defaultButtonStyle);
    }

    // 更新选中按钮的样式
    button.style.backgroundColor = "var(--interactive-accent)";
    button.style.color = "var(--text-on-accent)";
    selectedButton = button;
    saveState();
  });

  dayButtonsContainer.appendChild(button);
});
// 插入星期按钮容器
dv.container.appendChild(dayButtonsContainer);

function updateTasksView() {
  dv.container.innerHTML = "";
  dv.container.appendChild(weekControlsContainer);
  dv.container.appendChild(dayButtonsContainer);

  const dateStr = selectedDate.format("YYYY-MM-DD");
  const weekStr = selectedDate.format("YYYY-[W]WW");
  const showTreeOption = showTree ? "show tree" : "";
  let queryDayOfWeek = `
    {(done on ${dateStr}) OR (happens on ${dateStr}) }\\
     OR {(happens before ${dateStr}) AND (not done) AND (happens on ${weekStr}) }\\
     OR {filter by function \\
        const filename = task.file.filenameWithoutExtension;\\
        const date1 = window.moment(filename).format('YYYY-MM-DD');\\
        return date1 === '${dateStr}';}
    ${showTreeOption}
    group by status.name reverse
    short mode
    is not recurring
    # limit groups 5
    `;
  const queryWeek = `
    group by function task.description.includes("http") ? "🌐阅读记录" : "📅任务记录"
    {(done on ${weekStr}) OR (happens on ${weekStr})}
    ${showTreeOption}
    is not recurring
    # group by status.name
    group by done reverse
    short mode
    limit 100
    `;
  const queryInbox = `
    not done
    group by function task.due.category.groupText
    ${showTreeOption}
    # 不包含的路径
    path does not include "700【模板】Template"
    # 不包含看板文件的任务
    filter by function !task.file.hasProperty('kanban-plugin')

    short mode
    hide tags
    limit groups 10
    `;
  queryDayOfWeek = !showInbox ? queryDayOfWeek : queryInbox
  const query = !showWeekTasks ? queryDayOfWeek : queryWeek;


  dv.paragraph("```tasks\n" + query + "\n```");
}

// 初始化:选择今天
todayButton.click()

// 监听今日按钮的双击事件
todayButton.addEventListener("dblclick", () => {
  app.commands.executeCommandById("daily-notes");
});

```

将星期几改为周几并添加日历号,效果如下:
image

dataviewjs
window.moment.updateLocale("en", {
    week: {
        dow: 1,
    },
});

// 获取当前日期
const today = window.moment();
let selectedDate = today.clone();
let currentWeekOffset = 0;

// 初始状态
let showTree = false;
let showWeekTasks = false;
let showInbox = false;

// 检查是否存在全局数据,如果不存在则初始化
if (!window.tasksQueryData) {
    window.tasksQueryData = {
        showTree: true,
        showWeekTasks: false,
        showInbox: false,
        currentWeekOffset: 0,
        selectedDate: today.format("YYYY-MM-DD")
    };
} else {
    // 恢复状态
    showTree = window.tasksQueryData.showTree;
    showWeekTasks = window.tasksQueryData.showWeekTasks;
    showInbox = window.tasksQueryData.showInbox;
    currentWeekOffset = window.tasksQueryData.currentWeekOffset;
    selectedDate = window.moment(window.tasksQueryData.selectedDate);
}

// 创建一个用于显示当前周次的标签
const weekControlsContainer = document.createElement("div");
weekControlsContainer.style.textAlign = "center";
weekControlsContainer.style.marginBottom = "10px";

// 创建 week input
const weekInput = document.createElement("input");
weekInput.type = "week";

// 为 week input 设置样式
Object.assign(weekInput.style, {
    fontSize: "medium",
    color: "var(--text-normal)",
    backgroundColor: "var(--background-primary)",
    border: "1px solid var(--background-modifier-border)",
    borderRadius: "4px",
    padding: "0.2rem",
    outline: "none"
});

// 设置初始值为当前周
function getFormattedWeekString(date) {
    const year = date.format("GGGG"); // 使用ISO年
    const week = date.format("WW");
    return `${year}-W${week}`;
}
weekInput.value = getFormattedWeekString(selectedDate);

// 设置 week input 的事件监听
weekInput.addEventListener("change", () => {
    const [year, week] = weekInput.value.split('-W').map(str => parseInt(str));
    const firstWeek = today.clone().year(year).startOf('year').week(1);
    const targetWeekStart = firstWeek.add(week - 1, 'weeks');
    currentWeekOffset = targetWeekStart.week() - today.week();
    updateWeekButtons();  // 新增
    dayButtonsContainer.children[0].click();
    saveState();
});

// 创建操作按钮
const leftButtonWeek = document.createElement("button");
const rightButtonWeek = document.createElement("button");
const toggleShowTreeButton = document.createElement("button");
const toggleShowWeekTasksButton = document.createElement("button");
const toggleInboxTasksButton = document.createElement("button");
const todayButton = document.createElement("button");

[leftButtonWeek, rightButtonWeek, todayButton, toggleInboxTasksButton, toggleShowTreeButton, toggleShowWeekTasksButton].forEach(button => {
    button.style.border = "none";
    button.style.margin = "0 5px";
    button.style.padding = "5px 10px";
    button.style.backgroundColor = "var(--interactive-accent)";
    button.style.fontSize = "large";
    button.style.color = "var(--text-on-accent)";
    button.style.cursor = "pointer";
});
leftButtonWeek.textContent = "←";
rightButtonWeek.textContent = "→";
toggleShowTreeButton.textContent = "↳";
toggleShowWeekTasksButton.textContent = "周报";
todayButton.textContent = "今日";
toggleInboxTasksButton.textContent = "Inbox";

function updateWeekButtons() {
    daysOfWeek.forEach((day, index) => {
        const button = dayButtonsContainer.children[index];
        const date = today.clone().startOf("week").add(currentWeekOffset, "weeks").add(index, "days");
        button.textContent = `${day}(${date.format("DD")})`;
    });
}

// 在切换周次的地方调用更新函数
leftButtonWeek.addEventListener("click", () => {
    currentWeekOffset -= 1;
    updateWeekInput();
    updateWeekButtons();  // 新增
    dayButtonsContainer.children[0].click();
    saveState();
});

rightButtonWeek.addEventListener("click", () => {
    currentWeekOffset += 1;
    updateWeekInput();
    updateWeekButtons();  // 新增
    dayButtonsContainer.children[0].click();
    saveState();
});

todayButton.addEventListener("click", () => {
    currentWeekOffset = 0;
    updateWeekInput();
    updateWeekButtons();  // 新增
    const todayIndex = today.day() === 0 ? 6 : today.day() - 1;
    dayButtonsContainer.children[todayIndex].click();
    saveState();
});

// 初始化 可选按钮
function initButtonTheme(button, active) {
    if (active) {
        button.style.color = "var(--text-on-accent)";
        button.style.backgroundColor = "var(--interactive-accent)";
    } else {
        button.style.color = "var(--text-normal)";
        button.style.backgroundColor = "transparent";
    }
}

toggleShowTreeButton.addEventListener("click", () => {
    showTree = !showTree;
    initButtonTheme(toggleShowTreeButton, showTree);
    dayButtonsContainer.querySelector("button[style*='interactive-accent']").click();
    saveState();
});

toggleShowWeekTasksButton.addEventListener("click", () => {
    showWeekTasks = !showWeekTasks;
    initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);
    dayButtonsContainer.querySelector("button[style*='interactive-accent']").click();
    saveState();
});

toggleInboxTasksButton.addEventListener("click", () => {
    showInbox = !showInbox;
    initButtonTheme(toggleInboxTasksButton, showInbox);
    dayButtonsContainer.querySelector("button[style*='interactive-accent']").click();
    saveState();
});

// 初始化按钮主题色
initButtonTheme(toggleShowTreeButton, showTree);
initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);
initButtonTheme(toggleInboxTasksButton, showInbox);

// 更新周次选择框
function updateWeekInput() {
    const startDate = today.clone().startOf('week').add(currentWeekOffset, 'weeks');
    weekInput.value = getFormattedWeekString(startDate);
}

// 保存当前状态到全局属性
function saveState() {
    window.tasksQueryData = {
        showTree: showTree,
        showWeekTasks: showWeekTasks,
        showInbox: showInbox,
        currentWeekOffset: currentWeekOffset,
        selectedDate: selectedDate.format("YYYY-MM-DD")
    };
}

// 插入控件
weekControlsContainer.appendChild(toggleShowWeekTasksButton);
weekControlsContainer.appendChild(toggleInboxTasksButton);
weekControlsContainer.appendChild(leftButtonWeek);
weekControlsContainer.appendChild(weekInput);
weekControlsContainer.appendChild(rightButtonWeek);
weekControlsContainer.appendChild(toggleShowTreeButton);
weekControlsContainer.appendChild(todayButton);
// 添加到页面中
document.body.appendChild(weekControlsContainer);
dv.container.appendChild(weekControlsContainer);

// 创建星期按钮
const daysOfWeek = ["周一", "周二", "周三", "周四", "周五", "周六", "周天"];
const dayButtonsContainer = document.createElement("div");
dayButtonsContainer.style.display = "flex";
dayButtonsContainer.style.justifyContent = "center";
dayButtonsContainer.style.width = "100%";

// 存储当前选中的按钮
let selectedButton;
// 添加样式的默认值
const defaultButtonStyle = {
    border: "none",
    borderRadius: "0px",
    cursor: "pointer",
    fontSize: "medium",
    flex: "1 1 auto",
    color: "var(--text-normal)",
    backgroundColor: "transparent",
};


daysOfWeek.forEach((day, index) => {
    const button = document.createElement("button");
    Object.assign(button.style, defaultButtonStyle);
    // button.textContent = day;

    // 计算并显示日期
    const date = today.clone().startOf("week").add(currentWeekOffset, "weeks").add(index, "days");
    button.textContent = `${day}(${date.format("DD")})`;

    button.addEventListener("click", () => {
        // 设置选中的日期
        selectedDate = today.clone().startOf("week").add(currentWeekOffset, "weeks").add(index, "days");
        updateTasksView();

        // 更新先前选中按钮的样式
        if (selectedButton) {
            Object.assign(selectedButton.style, defaultButtonStyle);
        }

        // 更新选中按钮的样式
        button.style.backgroundColor = "var(--interactive-accent)";
        button.style.color = "var(--text-on-accent)";
        selectedButton = button;
        saveState();
    });

    dayButtonsContainer.appendChild(button);
});
// 插入星期按钮容器
dv.container.appendChild(dayButtonsContainer);

function updateTasksView() {
    dv.container.innerHTML = "";
    dv.container.appendChild(weekControlsContainer);
    dv.container.appendChild(dayButtonsContainer);

    const dateStr = selectedDate.format("YYYY-MM-DD");
    const weekStr = selectedDate.format("YYYY-[W]WW");
    const showTreeOption = showTree ? "show tree" : "";
    let queryDayOfWeek = `
    {(done on ${dateStr}) OR (happens on ${dateStr}) }\\
     OR {(happens before ${dateStr}) AND (not done) AND (happens on ${weekStr}) }\\
     OR {filter by function \\
        const filename = task.file.filenameWithoutExtension;\\
        const date1 = window.moment(filename).format('YYYY-MM-DD');\\
        return date1 === '${dateStr}';}
    ${showTreeOption}
    group by status.name reverse
    short mode
    is not recurring
    # limit groups 5
    `;
    const queryWeek = `
    group by function task.description.includes("http") ? "🌐阅读记录" : "📅任务记录"
    {(done on ${weekStr}) OR (happens on ${weekStr})}
    ${showTreeOption}
    is not recurring
    # group by status.name
    group by done reverse
    short mode
    limit 100
    `;
    const queryInbox = `
    not done
    group by function task.due.category.groupText
    ${showTreeOption}
    # 不包含的路径
    path does not include "700【模板】Template"
    # 不包含看板文件的任务
    filter by function !task.file.hasProperty('kanban-plugin')

    short mode
    hide tags
    limit groups 10
    `;
    queryDayOfWeek = !showInbox ? queryDayOfWeek : queryInbox;
    const query = !showWeekTasks ? queryDayOfWeek : queryWeek;

    dv.paragraph("```tasks\n" + query + "\n```");
}

// 初始化:选择今天
todayButton.click();

// 监听今日按钮的双击事件
todayButton.addEventListener("dblclick", () => {
    app.commands.executeCommandById("daily-notes");
});
``
1 个赞

真的太棒了,请问有没有办法在手机端也适配,现在在手机端盛不下。

1 个赞

可以看看 手机界面截图长啥样吗,因为我没用过手机端,如果要适配手机端的话,原来的js还得重新改下,我想尽量不修改js,而是直接通过css来处理一下。

手机端是这样的,好像自动换行了的样子。


因为无论是js还是css我都不太懂,也不知道怎么改,我现在用的有一个日程的代码适配的比较好,您看下,他需要指定到一个文件夹Taskido,是哔哩哔哩上一个up介绍的,地址是这里:Obsidian #5 日记周记模板修复改进,dataview增加tasks每日任务视图。_哔哩哔哩_bilibili


好的,Mark,看样子要改JS,我最近有点忙,可能不太有时间更改,不过后续我会看看的,目前我只能简单删除一些格式,让它看起来不太占位置,即:① 删除了周选择器;②删除了“星期”文字。如果你主要使用手机端的话,这个版本可能比较适合。

详细代码
window.moment.updateLocale("en", {
    week: {
        dow: 1,
    },
});

// 获取当前日期
const today = window.moment();
let selectedDate = today.clone();
let currentWeekOffset = 0;

// 初始状态
let showTree = true;
let showWeekTasks = false;
let showInbox = false;

// 检查是否存在全局数据,如果不存在则初始化
if (!window.tasksQueryData) {
  window.tasksQueryData = {
    showTree: true,
    showWeekTasks: false,
    showInbox: false,
    currentWeekOffset: 0,
    selectedDate: today.format("YYYY-MM-DD")
  };
} else {
  // 恢复状态
  showTree = window.tasksQueryData.showTree;
  showWeekTasks = window.tasksQueryData.showWeekTasks;
  showInbox = window.tasksQueryData.showInbox;
  currentWeekOffset = window.tasksQueryData.currentWeekOffset;
  selectedDate = window.moment(window.tasksQueryData.selectedDate);
}

// 创建一个用于显示当前周次的标签
const weekControlsContainer = document.createElement("div");
weekControlsContainer.style.textAlign = "center";
weekControlsContainer.style.marginBottom = "10px";

// 创建 week input
const weekInput = document.createElement("input");
weekInput.type = "week";

// 为 week input 设置样式
Object.assign(weekInput.style, {
  fontSize: "larger", 
  color: "var(--text-normal)",
  backgroundColor: "var(--background-primary)", 
  border: "1px solid var(--background-modifier-border)", 
  borderRadius: "4px", 
  padding: "0.2rem", 
  outline: "none"
});

// 设置初始值为当前周
function getFormattedWeekString(date) {
  const year = date.format("GGGG"); // 使用ISO年
  const week = date.format("WW");
  return `${year}-W${week}`;
}
weekInput.value = getFormattedWeekString(selectedDate);

// 设置 week input 的事件监听
weekInput.addEventListener("change", () => {
  const [year, week] = weekInput.value.split('-W').map(str => parseInt(str));
  const firstWeek = today.clone().year(year).startOf('year').week(1);
  const targetWeekStart = firstWeek.add(week - 1, 'weeks');
  currentWeekOffset = targetWeekStart.week() - today.week();
  dayButtonsContainer.children[0].click();
  saveState();
});

// 创建操作按钮
const leftButtonWeek = document.createElement("button");
const rightButtonWeek = document.createElement("button");
const toggleShowTreeButton = document.createElement("button");
const toggleShowWeekTasksButton = document.createElement("button");
const toggleInboxTasksButton = document.createElement("button");
const todayButton = document.createElement("button");

[leftButtonWeek, rightButtonWeek, todayButton,toggleInboxTasksButton, toggleShowTreeButton,toggleShowWeekTasksButton].forEach(button => {
  button.style.border = "none";
  button.style.margin = "0 5px";
  button.style.padding = "5px 10px";
  button.style.backgroundColor = "var(--interactive-accent)";
  button.style.fontSize = "large";
  button.style.color = "var(--text-on-accent)";
  button.style.cursor = "pointer";
});
leftButtonWeek.textContent = "←";
rightButtonWeek.textContent = "→";
toggleShowTreeButton.textContent = "↳";
toggleShowWeekTasksButton.textContent = "周报";
todayButton.textContent = "今日";
toggleInboxTasksButton.textContent = "Inbox";

// 添加按钮逻辑
leftButtonWeek.addEventListener("click", () => {
  currentWeekOffset -= 1;
  updateWeekInput();
  dayButtonsContainer.children[0].click();
  saveState();
});

rightButtonWeek.addEventListener("click", () => {
  currentWeekOffset += 1;
  updateWeekInput();
  dayButtonsContainer.children[0].click();
  saveState();
});

todayButton.addEventListener("click", () => {
  currentWeekOffset = 0;
  updateWeekInput();
  const todayIndex = today.day() === 0 ? 6 : today.day() - 1;
  dayButtonsContainer.children[todayIndex].click();
  saveState();
});

// 初始化 可选按钮
function initButtonTheme(button, active) {
  if (active) {
    button.style.color = "var(--text-on-accent)";
    button.style.backgroundColor = "var(--interactive-accent)";
  } else {
    button.style.color = "var(--text-normal)";
    button.style.backgroundColor = "transparent";
  }
}

toggleShowTreeButton.addEventListener("click", () => {
  showTree = !showTree;
  initButtonTheme(toggleShowTreeButton, showTree);
  dayButtonsContainer.querySelector("button[style*='interactive-accent']").click();
  saveState();
});

toggleShowWeekTasksButton.addEventListener("click", () => {
  showWeekTasks = !showWeekTasks;
  initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);
  dayButtonsContainer.querySelector("button[style*='interactive-accent']").click();
  saveState();
});

toggleInboxTasksButton.addEventListener("click", () => {
  showInbox = !showInbox;
  initButtonTheme(toggleInboxTasksButton, showInbox);
  dayButtonsContainer.querySelector("button[style*='interactive-accent']").click();
  saveState();
});

// 初始化按钮主题色
initButtonTheme(toggleShowTreeButton, showTree);
initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);
initButtonTheme(toggleInboxTasksButton, showInbox);

// 更新周次选择框
function updateWeekInput() {
  const startDate = today.clone().startOf('week').add(currentWeekOffset, 'weeks');
  weekInput.value = getFormattedWeekString(startDate);
}

// 保存当前状态到全局属性
function saveState() {
  window.tasksQueryData = {
    showTree: showTree,
    showWeekTasks: showWeekTasks,
    showInbox: showInbox,
    currentWeekOffset: currentWeekOffset,
    selectedDate: selectedDate.format("YYYY-MM-DD")
  };
}

// 插入控件
weekControlsContainer.appendChild(toggleShowWeekTasksButton);
weekControlsContainer.appendChild(toggleInboxTasksButton);
weekControlsContainer.appendChild(leftButtonWeek);
// weekControlsContainer.appendChild(weekInput);
weekControlsContainer.appendChild(rightButtonWeek);
weekControlsContainer.appendChild(toggleShowTreeButton);
weekControlsContainer.appendChild(todayButton);
// 添加到页面中
document.body.appendChild(weekControlsContainer);
dv.container.appendChild(weekControlsContainer);

// 创建星期按钮
const daysOfWeek = ["一", "二", "三", "四", "五", "六", "天"];
const dayButtonsContainer = document.createElement("div");
dayButtonsContainer.style.display = "flex";
dayButtonsContainer.style.justifyContent = "center";
dayButtonsContainer.style.width = "100%";

// 存储当前选中的按钮
let selectedButton;
// 添加样式的默认值
const defaultButtonStyle = {
  border: "none",
  borderRadius: "0px",
  cursor: "pointer",
  fontSize: "large",
  flex: "1 1 auto",
  color: "var(--text-normal)",
  backgroundColor: "transparent",
};

daysOfWeek.forEach((day, index) => {
  const button = document.createElement("button");
  Object.assign(button.style, defaultButtonStyle);
  button.textContent = day;
  
  button.addEventListener("click", () => {
    // 设置选中的日期
    selectedDate = today.clone().startOf("week").add(currentWeekOffset, "weeks").add(index, "days");
    updateTasksView();

    // 更新先前选中按钮的样式
    if (selectedButton) {
      Object.assign(selectedButton.style, defaultButtonStyle);
    }

    // 更新选中按钮的样式
    button.style.backgroundColor = "var(--interactive-accent)";
    button.style.color = "var(--text-on-accent)";
    selectedButton = button;
    saveState();
  });

  dayButtonsContainer.appendChild(button);
});
// 插入星期按钮容器
dv.container.appendChild(dayButtonsContainer);

function updateTasksView() {
  dv.container.innerHTML = "";
  dv.container.appendChild(weekControlsContainer);
  dv.container.appendChild(dayButtonsContainer);

  const dateStr = selectedDate.format("YYYY-MM-DD");
  const weekStr = selectedDate.format("YYYY-[W]WW");
  const showTreeOption = showTree ? "show tree" : "";
  let queryDayOfWeek = `
    {(done on ${dateStr}) OR (happens on ${dateStr}) }\\
     OR {(happens before ${dateStr}) AND (not done) AND (happens on ${weekStr}) }\\
     OR {filter by function \\
        const filename = task.file.filenameWithoutExtension;\\
        const date1 = window.moment(filename).format('YYYY-MM-DD');\\
        return date1 === '${dateStr}';}
    ${showTreeOption}
    group by status.name reverse
    short mode
    is not recurring
    # limit groups 5
    `;
  const queryWeek = `
    group by function task.description.includes("http") ? "🌐阅读记录" : "📅任务记录"
    {(done on ${weekStr}) OR (happens on ${weekStr})}
    ${showTreeOption}
    is not recurring
    # group by status.name
    group by done reverse
    short mode
    limit 100
    `;
  const queryInbox = `
    not done
    group by function task.due.category.groupText
    ${showTreeOption}
    # 不包含的路径
    path does not include "700【模板】Template"
    # 不包含看板文件的任务
    filter by function !task.file.hasProperty('kanban-plugin')

    short mode
    hide tags
    limit groups 10
    `;
  queryDayOfWeek = !showInbox ? queryDayOfWeek : queryInbox
  const query = !showWeekTasks ? queryDayOfWeek : queryWeek;

  dv.paragraph("```tasks\n" + query + "\n```");
}

// 初始化:选择今天
todayButton.click()

// 监听今日按钮的双击事件
todayButton.addEventListener("dblclick", () => {
  app.commands.executeCommandById("daily-notes");
});


非常感谢。 :revolving_hearts: :two_hearts:

参考了#15楼中的视频案例,添加快速添加今日任务按钮,借助的Tasks API。

由于不知道从哪里获取默认日记位置,目前需要配置Periodic Notes插件来获取日记位置。
如果日记不存在则从Periodic Notes插件获取template并创建。

PixPin_2025-03-10_12-06-33

Reference:

其他:

  • 优化了一点控件的布局以及添加类名,方便之后添加css。
  • 修复了周报和inbox按钮相互掩盖的问题
dataviewjs
window.moment.updateLocale("en", {
    week: {
        dow: 1,
    },
});

// 获取当前日期
const today = window.moment();
let selectedDate = today.clone();
let currentWeekOffset = 0;

// 初始状态
let showTree = false;
let showWeekTasks = false;
let showInbox = false;

// 检查是否存在全局数据,如果不存在则初始化
if (!window.tasksQueryData) {
    window.tasksQueryData = {
        showTree: true,
        showWeekTasks: false,
        showInbox: false,
        currentWeekOffset: 0,
        selectedDate: today.format("YYYY-MM-DD")
    };
} else {
    // 恢复状态
    showTree = window.tasksQueryData.showTree;
    showWeekTasks = window.tasksQueryData.showWeekTasks;
    showInbox = window.tasksQueryData.showInbox;
    currentWeekOffset = window.tasksQueryData.currentWeekOffset;
    selectedDate = window.moment(window.tasksQueryData.selectedDate);
}

// 创建一个用于显示当前周次的标签
const weekControlsContainer = document.createElement("div");
weekControlsContainer.style.textAlign = "center";
weekControlsContainer.style.marginBottom = "10px";

// 创建 week input
const weekInput = document.createElement("input");
weekInput.type = "week";

// 为 week input 设置样式
Object.assign(weekInput.style, {
    fontSize: "larger",
    color: "var(--text-normal)",
    backgroundColor: "var(--background-primary)",
    border: "1px solid var(--background-modifier-border)",
    borderRadius: "4px",
    padding: "0.2rem",
    outline: "none"
});

// 设置初始值为当前周
function getFormattedWeekString(date) {
    const year = date.format("GGGG"); // 使用ISO年
    const week = date.format("WW");
    return `${year}-W${week}`;
}
weekInput.value = getFormattedWeekString(selectedDate);

// 设置 week input 的事件监听
weekInput.addEventListener("change", () => {
    const [year, week] = weekInput.value.split('-W').map(str => parseInt(str));
    const firstWeek = today.clone().year(year).startOf('year').week(1);
    const targetWeekStart = firstWeek.add(week - 1, 'weeks');
    currentWeekOffset = targetWeekStart.week() - today.week();
    updateWeekButtons();
    weekSelectButtonsContainer.children[0].click();
    saveState();
});

// 创建操作按钮
const leftButtonWeek = document.createElement("button");
const rightButtonWeek = document.createElement("button");
const toggleShowTreeButton = document.createElement("button");
const toggleShowWeekTasksButton = document.createElement("button");
const toggleInboxTasksButton = document.createElement("button");
const todayButton = document.createElement("button");
const creatTasKButton = document.createElement("button");

// 设置样式
[toggleInboxTasksButton, toggleShowWeekTasksButton, leftButtonWeek, rightButtonWeek, todayButton, toggleShowTreeButton, creatTasKButton].forEach(button => {
    button.style.border = "none";
    button.style.margin = "0";
    button.style.fontSize = "large";
    button.style.color = "var(--text-on-accent)";
    button.style.cursor = "pointer";
    button.style.padding = "5px 10px";
    button.style.backgroundColor = "var(--interactive-accent)";
});


leftButtonWeek.textContent = "←";
rightButtonWeek.textContent = "→";
toggleShowTreeButton.textContent = "↳";
toggleShowWeekTasksButton.textContent = "周报";
todayButton.textContent = "今日";
toggleInboxTasksButton.textContent = "Inbox";
creatTasKButton.textContent = "✚";

function updateWeekButtons() {
    daysOfWeek.forEach((day, index) => {
        const button = weekSelectButtonsContainer.children[index];
        const date = today.clone().startOf("week").add(currentWeekOffset, "weeks").add(index, "days");
        button.textContent = `${day}(${date.format("DD")})`;
    });
}

// 在切换周次的地方调用更新函数
leftButtonWeek.addEventListener("click", () => {
    currentWeekOffset -= 1;
    updateWeekInput();
    updateWeekButtons();
    weekSelectButtonsContainer.children[0].click();
    saveState();
});

rightButtonWeek.addEventListener("click", () => {
    currentWeekOffset += 1;
    updateWeekInput();
    updateWeekButtons();
    weekSelectButtonsContainer.children[0].click();
    saveState();
});

todayButton.addEventListener("click", () => {
    currentWeekOffset = 0;
    updateWeekInput();
    updateWeekButtons();
    const todayIndex = today.day() === 0 ? 6 : today.day() - 1;
    weekSelectButtonsContainer.children[todayIndex].click();
    saveState();
});
creatTasKButton.addEventListener("click", async () => {
    const tasksApi = app.plugins.plugins['obsidian-tasks-plugin'].apiV1;

    // 创建一个 MutationObserver 来监听 DOM 变化
    const observer = new MutationObserver((mutationsList) => {
        for (const mutation of mutationsList) {
            if (mutation.type === 'childList') {
                // 检查是否添加了 section.tasks-modal-dependencies-section
                const sectionToRemove = document.querySelector('section.tasks-modal-dependencies-section');
                if (sectionToRemove) {
                    sectionToRemove.remove();
                    console.log('已删除 section.tasks-modal-dependencies-section');
                    observer.disconnect(); // 停止监听
                }
            }
        }
    });

    // 开始监听 document.body 的子元素变化
    observer.observe(document.body, { childList: true, subtree: true });

    // 等待任务创建
    let taskLine = await tasksApi.createTaskLineModal();
    if (!taskLine) return;
    console.log(taskLine);

    // 任务创建完成后,停止监听(如果还没有删除)
    observer.disconnect();

    // 将任务添加到每日日志文档中
    const dailySettings = await app.plugins.plugins["periodic-notes"].settings["daily"];
    const dailyFormat = dailySettings['format'];
    const path = `${dailySettings.folder}/${window.moment().format(dailyFormat)}.md`;
    const boolean = app.vault.getFileByPath(path);
    if (!boolean) {
        const templatePath = dailySettings['template'];
        let data = "";
        if (templatePath) {
            const templateFile = await app.vault.getFileByPath(templatePath + "\.md");
            data = await app.vault.read(templateFile);
            console.log("data:" + data);
        }
        await app.vault.create(path, data);
    }

    const file = await app.vault.getFileByPath(path);
    await app.vault.append(file, taskLine + '\n');
});

// 初始化 可选按钮
function initButtonTheme(button, active) {
    if (active) {
        button.style.color = "var(--text-on-accent)";
        button.style.backgroundColor = "var(--interactive-accent)";
    } else {
        button.style.color = "var(--text-normal)";
        button.style.backgroundColor = "transparent";
    }
}

toggleShowTreeButton.addEventListener("click", () => {
    showTree = !showTree;
    initButtonTheme(toggleShowTreeButton, showTree);
    weekSelectButtonsContainer.querySelector("button[style*='interactive-accent']").click();
    saveState();
});

// 
toggleShowWeekTasksButton.addEventListener("click", () => {
    showWeekTasks = !showWeekTasks;
    showInbox = false;
    initButtonTheme(toggleInboxTasksButton, showInbox);
    initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);
    weekSelectButtonsContainer.querySelector("button[style*='interactive-accent']").click();
    saveState();
});

toggleInboxTasksButton.addEventListener("click", () => {
    showInbox = !showInbox;
    showWeekTasks = false;
    initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);
    initButtonTheme(toggleInboxTasksButton, showInbox);
    weekSelectButtonsContainer.querySelector("button[style*='interactive-accent']").click();
    saveState();
});

// 初始化按钮主题色
initButtonTheme(toggleShowTreeButton, showTree);
initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);
initButtonTheme(toggleInboxTasksButton, showInbox);

// 更新周次选择框
function updateWeekInput() {
    const startDate = today.clone().startOf('week').add(currentWeekOffset, 'weeks');
    weekInput.value = getFormattedWeekString(startDate);
}

// 保存当前状态到全局属性
function saveState() {
    window.tasksQueryData = {
        showTree: showTree,
        showWeekTasks: showWeekTasks,
        showInbox: showInbox,
        currentWeekOffset: currentWeekOffset,
        selectedDate: selectedDate.format("YYYY-MM-DD")
    };
}

// !按顺序插入控件
const taskControlButtonContainer = document.createElement("div");
taskControlButtonContainer.className = "task-control-buttons-container";
taskControlButtonContainer.style.width = "100%";
taskControlButtonContainer.style.display = "flex";
taskControlButtonContainer.style.alignItems = "center";
taskControlButtonContainer.style.justifyContent = "center";
taskControlButtonContainer.style.gap = "5px";

[toggleInboxTasksButton, toggleShowWeekTasksButton, leftButtonWeek, weekInput, rightButtonWeek, toggleShowTreeButton, todayButton, creatTasKButton].forEach(button => {
    taskControlButtonContainer.appendChild(button);
});

weekControlsContainer.appendChild(taskControlButtonContainer);

// 添加到页面中
document.body.appendChild(weekControlsContainer);
dv.container.appendChild(weekControlsContainer);

// 创建星期按钮
const daysOfWeek = ["周一", "周二", "周三", "周四", "周五", "周六", "周天"];
const weekSelectButtonsContainer = document.createElement("div");
taskControlButtonContainer.className = "week-select-buttons-container";
weekSelectButtonsContainer.style.display = "flex";
weekSelectButtonsContainer.style.justifyContent = "center";
weekSelectButtonsContainer.style.width = "100%";

// 存储当前选中的按钮
let selectedButton;
// 添加样式的默认值
const defaultButtonStyle = {
    border: "none",
    borderRadius: "0px",
    cursor: "pointer",
    fontSize: "medium",
    flex: "1 1 auto",
    color: "var(--text-normal)",
    backgroundColor: "transparent",
};


daysOfWeek.forEach((day, index) => {
    const button = document.createElement("button");
    button.className = "week-day-button";

    Object.assign(button.style, defaultButtonStyle);
    // button.textContent = day;

    // 计算并显示日期
    const date = today.clone().startOf("week").add(currentWeekOffset, "weeks").add(index, "days");
    button.textContent = `${day}(${date.format("DD")})`;

    button.addEventListener("click", () => {
        // 设置选中的日期
        selectedDate = today.clone().startOf("week").add(currentWeekOffset, "weeks").add(index, "days");
        updateTasksView();

        // 更新先前选中按钮的样式
        if (selectedButton) {
            Object.assign(selectedButton.style, defaultButtonStyle);
        }

        // 更新选中按钮的样式
        button.style.backgroundColor = "var(--interactive-accent)";
        button.style.color = "var(--text-on-accent)";
        selectedButton = button;
        saveState();
    });

    weekSelectButtonsContainer.appendChild(button);
});
// 插入星期按钮容器
dv.container.appendChild(weekSelectButtonsContainer);

function updateTasksView() {
    dv.container.innerHTML = "";
    dv.container.appendChild(weekControlsContainer);
    dv.container.appendChild(weekSelectButtonsContainer);

    const dateStr = selectedDate.format("YYYY-MM-DD");
    const weekStr = selectedDate.format("YYYY-[W]WW");
    const showTreeOption = showTree ? "show tree" : "";
    let queryDayOfWeek = `
    {(done on ${dateStr}) OR (happens on ${dateStr}) }\\
    OR {(happens before ${dateStr}) AND (not done) AND (happens on ${weekStr}) }\\
    OR {filter by function \\
        const filename = task.file.filenameWithoutExtension;\\
        const date1 = window.moment(filename).format('YYYY-MM-DD');\\
        return date1 === '${dateStr}';}
    ${showTreeOption}
    group by status.name reverse
    short mode
    is not recurring
    # limit groups 5
    `;
    const queryWeek = `
    group by function task.description.includes("http") ? "🌐阅读记录" : "📅任务记录"
    {(done on ${weekStr}) OR (happens on ${weekStr})}
    ${showTreeOption}
    is not recurring
    # group by status.name
    group by done reverse
    short mode
    limit 100
    `;
    const queryInbox = `
    not done
    group by function task.due.category.groupText
    ${showTreeOption}
    # 不包含的路径
    path does not include "700【模板】Template"
    # 不包含看板文件的任务
    filter by function !task.file.hasProperty('kanban-plugin')

    short mode
    hide tags
    limit groups 10
    `;
    queryDayOfWeek = !showInbox ? queryDayOfWeek : queryInbox;
    const query = !showWeekTasks ? queryDayOfWeek : queryWeek;

    dv.paragraph("```tasks\n" + query + "\n```");
}

// 初始化:选择今天
todayButton.click();

// 监听今日按钮的双击事件
todayButton.addEventListener("dblclick", () => {
    app.commands.executeCommandById("daily-notes");
});

如果日记不存在则从Periodic Notes插件获取template并创建。
这个功能在我这里似乎有点问题,无法创建
image
原因是templatePath获取到的值已经是包含了.md后缀的,导致app.vault.getFileByPath(templatePath + "\.md")这一步实际结果是none
修改为app.vault.getFileByPath(templatePath)即可

这是我修改之后的版本,希望能有帮助:

window.moment.updateLocale("en", {
    week: {
        dow: 1,
    },
});

// 获取当前日期
const today = window.moment();
let selectedDate = today.clone();
let currentWeekOffset = 0;

// 初始状态
let showTree = false;
let showWeekTasks = false;
let showInbox = false;

// 检查是否存在全局数据,如果不存在则初始化
if (!window.tasksQueryData) {
    window.tasksQueryData = {
        showTree: true,
        showWeekTasks: false,
        showInbox: false,
        currentWeekOffset: 0,
        selectedDate: today.format("YYYY-MM-DD")
    };
} else {
    // 恢复状态
    showTree = window.tasksQueryData.showTree;
    showWeekTasks = window.tasksQueryData.showWeekTasks;
    showInbox = window.tasksQueryData.showInbox;
    currentWeekOffset = window.tasksQueryData.currentWeekOffset;
    selectedDate = window.moment(window.tasksQueryData.selectedDate);
}

// 创建一个用于显示当前周次的标签
const weekControlsContainer = document.createElement("div");
weekControlsContainer.style.textAlign = "center";
weekControlsContainer.style.marginBottom = "10px";

// 创建 week input
const weekInput = document.createElement("input");
weekInput.type = "week";

// 为 week input 设置样式
Object.assign(weekInput.style, {
    fontSize: "larger",
    color: "var(--text-normal)",
    backgroundColor: "var(--background-primary)",
    border: "1px solid var(--background-modifier-border)",
    borderRadius: "4px",
    padding: "0.2rem",
    outline: "none"
});

// 设置初始值为当前周
function getFormattedWeekString(date) {
    const year = date.format("GGGG"); // 使用ISO年
    const week = date.format("WW");
    return `${year}-W${week}`;
}
weekInput.value = getFormattedWeekString(selectedDate);

// 设置 week input 的事件监听
weekInput.addEventListener("change", () => {
    const [year, week] = weekInput.value.split('-W').map(str => parseInt(str));
    const firstWeek = today.clone().year(year).startOf('year').week(1);
    const targetWeekStart = firstWeek.add(week - 1, 'weeks');
    currentWeekOffset = targetWeekStart.week() - today.week();
    updateWeekButtons();
    weekSelectButtonsContainer.children[0].click();
    saveState();
});

// 创建操作按钮
const leftButtonWeek = document.createElement("button");
const rightButtonWeek = document.createElement("button");
const toggleShowTreeButton = document.createElement("button");
const toggleShowWeekTasksButton = document.createElement("button");
const toggleInboxTasksButton = document.createElement("button");
const todayButton = document.createElement("button");
const creatTasKButton = document.createElement("button");

// 设置样式
[toggleInboxTasksButton, toggleShowWeekTasksButton, leftButtonWeek, rightButtonWeek, todayButton, toggleShowTreeButton, creatTasKButton].forEach(button => {
    button.style.border = "none";
    button.style.margin = "0";
    button.style.fontSize = "large";
    button.style.color = "var(--text-on-accent)";
    button.style.cursor = "pointer";
    button.style.padding = "5px 10px";
    button.style.backgroundColor = "var(--interactive-accent)";
});


leftButtonWeek.textContent = "←";
rightButtonWeek.textContent = "→";
toggleShowTreeButton.textContent = "↳";
toggleShowWeekTasksButton.textContent = "周报";
todayButton.textContent = "今日";
toggleInboxTasksButton.textContent = "Inbox";
creatTasKButton.textContent = "✚";

function updateWeekButtons() {
    daysOfWeek.forEach((day, index) => {
        const button = weekSelectButtonsContainer.children[index];
        const date = today.clone().startOf("week").add(currentWeekOffset, "weeks").add(index, "days");
        button.textContent = `${day}(${date.format("DD")})`;
    });
}

// 在切换周次的地方调用更新函数
leftButtonWeek.addEventListener("click", () => {
    currentWeekOffset -= 1;
    updateWeekInput();
    updateWeekButtons();
    weekSelectButtonsContainer.children[0].click();
    saveState();
});

rightButtonWeek.addEventListener("click", () => {
    currentWeekOffset += 1;
    updateWeekInput();
    updateWeekButtons();
    weekSelectButtonsContainer.children[0].click();
    saveState();
});

todayButton.addEventListener("click", () => {
    currentWeekOffset = 0;
    updateWeekInput();
    updateWeekButtons();
    const todayIndex = today.day() === 0 ? 6 : today.day() - 1;
    weekSelectButtonsContainer.children[todayIndex].click();
    saveState();
});
creatTasKButton.addEventListener("click", async () => {
    const tasksApi = app.plugins.plugins['obsidian-tasks-plugin'].apiV1;

    // 创建一个 MutationObserver 来监听 DOM 变化
    const observer = new MutationObserver((mutationsList) => {
        for (const mutation of mutationsList) {
            if (mutation.type === 'childList') {
                // 检查是否添加了 section.tasks-modal-dependencies-section
                const sectionToRemove = document.querySelector('section.tasks-modal-dependencies-section');
                if (sectionToRemove) {
                    sectionToRemove.remove();
                    console.log('已删除 section.tasks-modal-dependencies-section');
                    observer.disconnect(); // 停止监听
                }
            }
        }
    });

    // 开始监听 document.body 的子元素变化
    observer.observe(document.body, { childList: true, subtree: true });

    // 等待任务创建
    let taskLine = await tasksApi.createTaskLineModal();
    if (!taskLine) return;
    console.log(taskLine);

    // 任务创建完成后,停止监听(如果还没有删除)
    observer.disconnect();

    // 将任务添加到每日日志文档中
    const dailySettings = await app.plugins.plugins["periodic-notes"].settings["daily"];
    const dailyFormat = dailySettings['format'];
    const path = `${dailySettings.folder}/${window.moment().format(dailyFormat)}.md`;
    const boolean = app.vault.getFileByPath(path);
    if (!boolean) {
        const templatePath = dailySettings['template'];
        let data = "";
        if (templatePath) {
            const templateFile = await app.vault.getFileByPath(templatePath);
            data = await app.vault.read(templateFile);
            console.log("data:" + data);
        }
        await app.vault.create(path, data);
    }

    const file = await app.vault.getFileByPath(path);
    await app.vault.append(file, taskLine + '\n');
});

// 初始化 可选按钮
function initButtonTheme(button, active) {
    if (active) {
        button.style.color = "var(--text-on-accent)";
        button.style.backgroundColor = "var(--interactive-accent)";
    } else {
        button.style.color = "var(--text-normal)";
        button.style.backgroundColor = "transparent";
    }
}

toggleShowTreeButton.addEventListener("click", () => {
    showTree = !showTree;
    initButtonTheme(toggleShowTreeButton, showTree);
    weekSelectButtonsContainer.querySelector("button[style*='interactive-accent']").click();
    saveState();
});

// 
toggleShowWeekTasksButton.addEventListener("click", () => {
    showWeekTasks = !showWeekTasks;
    showInbox = false;
    initButtonTheme(toggleInboxTasksButton, showInbox);
    initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);
    weekSelectButtonsContainer.querySelector("button[style*='interactive-accent']").click();
    saveState();
});

toggleInboxTasksButton.addEventListener("click", () => {
    showInbox = !showInbox;
    showWeekTasks = false;
    initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);
    initButtonTheme(toggleInboxTasksButton, showInbox);
    weekSelectButtonsContainer.querySelector("button[style*='interactive-accent']").click();
    saveState();
});

// 初始化按钮主题色
initButtonTheme(toggleShowTreeButton, showTree);
initButtonTheme(toggleShowWeekTasksButton, showWeekTasks);
initButtonTheme(toggleInboxTasksButton, showInbox);

// 更新周次选择框
function updateWeekInput() {
    const startDate = today.clone().startOf('week').add(currentWeekOffset, 'weeks');
    weekInput.value = getFormattedWeekString(startDate);
}

// 保存当前状态到全局属性
function saveState() {
    window.tasksQueryData = {
        showTree: showTree,
        showWeekTasks: showWeekTasks,
        showInbox: showInbox,
        currentWeekOffset: currentWeekOffset,
        selectedDate: selectedDate.format("YYYY-MM-DD")
    };
}

// !按顺序插入控件
const taskControlButtonContainer = document.createElement("div");
taskControlButtonContainer.className = "task-control-buttons-container";
taskControlButtonContainer.style.width = "100%";
taskControlButtonContainer.style.display = "flex";
taskControlButtonContainer.style.alignItems = "center";
taskControlButtonContainer.style.justifyContent = "center";
taskControlButtonContainer.style.gap = "5px";

[toggleInboxTasksButton, toggleShowWeekTasksButton, leftButtonWeek, weekInput, rightButtonWeek, toggleShowTreeButton, todayButton, creatTasKButton].forEach(button => {
    taskControlButtonContainer.appendChild(button);
});

weekControlsContainer.appendChild(taskControlButtonContainer);

// 添加到页面中
document.body.appendChild(weekControlsContainer);
dv.container.appendChild(weekControlsContainer);

// 创建星期按钮
const daysOfWeek = ["周一", "周二", "周三", "周四", "周五", "周六", "周天"];
const weekSelectButtonsContainer = document.createElement("div");
taskControlButtonContainer.className = "week-select-buttons-container";
weekSelectButtonsContainer.style.display = "flex";
weekSelectButtonsContainer.style.justifyContent = "center";
weekSelectButtonsContainer.style.width = "100%";

// 存储当前选中的按钮
let selectedButton;
// 添加样式的默认值
const defaultButtonStyle = {
    border: "none",
    borderRadius: "0px",
    cursor: "pointer",
    fontSize: "medium",
    flex: "1 1 auto",
    color: "var(--text-normal)",
    backgroundColor: "transparent",
};


daysOfWeek.forEach((day, index) => {
    const button = document.createElement("button");
    button.className = "week-day-button";

    Object.assign(button.style, defaultButtonStyle);
    // button.textContent = day;

    // 计算并显示日期
    const date = today.clone().startOf("week").add(currentWeekOffset, "weeks").add(index, "days");
    button.textContent = `${day}(${date.format("DD")})`;

    button.addEventListener("click", () => {
        // 设置选中的日期
        selectedDate = today.clone().startOf("week").add(currentWeekOffset, "weeks").add(index, "days");
        updateTasksView();

        // 更新先前选中按钮的样式
        if (selectedButton) {
            Object.assign(selectedButton.style, defaultButtonStyle);
        }

        // 更新选中按钮的样式
        button.style.backgroundColor = "var(--interactive-accent)";
        button.style.color = "var(--text-on-accent)";
        selectedButton = button;
        saveState();
    });

    weekSelectButtonsContainer.appendChild(button);
});
// 插入星期按钮容器
dv.container.appendChild(weekSelectButtonsContainer);

function updateTasksView() {
    dv.container.innerHTML = "";
    dv.container.appendChild(weekControlsContainer);
    dv.container.appendChild(weekSelectButtonsContainer);

    const dateStr = selectedDate.format("YYYY-MM-DD");
    const weekStr = selectedDate.format("YYYY-[W]WW");
    const showTreeOption = showTree ? "show tree" : "";
    let queryDayOfWeek = `
    {(done on ${dateStr}) OR (happens on ${dateStr}) }\\
    OR {(happens before ${dateStr}) AND (not done) AND (happens on ${weekStr}) }\\
    OR {filter by function \\
        const filename = task.file.filenameWithoutExtension;\\
        const date1 = window.moment(filename).format('YYYY-MM-DD');\\
        return date1 === '${dateStr}';}
    ${showTreeOption}
    group by status.name reverse
    short mode
    is not recurring
    # limit groups 5
    `;
    const queryWeek = `
    group by function task.description.includes("http") ? "🌐阅读记录" : "📅任务记录"
    {(done on ${weekStr}) OR (happens on ${weekStr})}
    ${showTreeOption}
    is not recurring
    # group by status.name
    group by done reverse
    short mode
    limit 100
    `;
    const queryInbox = `
    not done
    group by function task.due.category.groupText
    ${showTreeOption}
    # 不包含的路径
    path does not include "700【模板】Template"
    # 不包含看板文件的任务
    filter by function !task.file.hasProperty('kanban-plugin')

    short mode
    hide tags
    limit groups 10
    `;
    queryDayOfWeek = !showInbox ? queryDayOfWeek : queryInbox;
    const query = !showWeekTasks ? queryDayOfWeek : queryWeek;

    dv.paragraph("```tasks\n" + query + "\n```");
}

// 初始化:选择今天
todayButton.click();

// 监听今日按钮的双击事件
todayButton.addEventListener("dblclick", () => {
    app.commands.executeCommandById("daily-notes");
});
1 个赞