What I’m trying to do
I have a folder structure like
Projects/
Project 1/
Project Note.md
Meeting Note 1.md
Project 2/
Project Note.md
....
I’m trying to create a list of lists such that the outer list will be the projects that have a status of open, and each list item has a list of open tasks.
I can get a list of all these folders.
I can get a list of all open tasks for these.
I just can’t figure out how to create a nested list of these.
So the result should look the same as if i had typed by hand
- Project 1
- [ ] Task 1
- [ ] Task 2
- Project 2
- [ ] Task 1
Am I trying to be too smart by using dataviewjs, and can this simply be done with inline dataview?
What I’ve tried
const folder = "Projects"; // Replace with your top-level folder
// Helper: Check if a folder contains a PoC file with 'active' status
function isFolderActive(folderPath) {
const pocFileName = `${folderPath.split("/").pop()} Projects`; // Construct the Project filename
const pocFile = dv.page(`${folderPath}/${pocFileName}`); // Get the Project file
return pocFile && pocFile.status === "active"; // Return true if status is 'active'
}
// Collect all valid tasks from eligible folders
let allTasks = [];
dv.pages(`"${folder}"`).forEach(page => {
const folderPath = page.file.path.split("/").slice(0, -1).join("/"); // Extract folder path
if (isFolderActive(folderPath)) {
page.file.tasks
.filter(t => !t.completed) // Filter open tasks
.forEach(t => allTasks.push({ ...t, path: page.file.path })); // Add task with path
}
});
// Group tasks by relevant subfolder (excluding 'Projects' and 'year')
const groupedTasks = allTasks.reduce((acc, task) => {
const pathParts = task.path.split("/"); // Split the path into parts
const relevantFolder = pathParts.slice(2, -1).join("/"); // Remove 'Projects' and 'year'
if (!acc[relevantFolder]) acc[relevantFolder] = [];
acc[relevantFolder].push(task);
return acc;
}, {});
dv.container.className = "el-ul"
// Render each group as a task list
const folders = [];
for (const [subfolder, tasks] of Object.entries(groupedTasks)) {
const displayFolder = subfolder || "Uncategorized"; // Handle case with no valid subfolder
folders.push(displayFolder);
dv.el('h1',`${displayFolder}`);
// stuck here!
}
Using this :
```dataview
TASK FROM "Projects"
WHERE !completed GROUP BY file.folder
Gives the correct results, but as a bunch of <h4>
tags per folder followed by a list.
I want those folder names as a list as well
Inside your for loop I think you need to nest another for loop to iterate through the tasks of each page and dv.el print them to ‘p’ type elements, below where you are stuck after printing the folder header. or something along those lines.
holroy
December 19, 2024, 9:03am
5
Why do you need the project names to be in a list, instead of headers?
Is it just for the visuals? Is it for folding purposes?
1 Like