let projects = dv.pages('"Projects"').where( p => ( [ 'todo', 'today', 'now', 'important' ].indexOf(p.status) > -1 ) );
let order = 'asc';
// SORT
projects = projects.sort( function(project) {
if ( project.notes && Object.keys(project.notes).length ) {
var date = moment( Object.keys(project.notes)[0] );
} else {
var date = moment();
}
let sortValue = date.unix();
return sortValue;
}, order);
// RENDER
let html = `<section class="project-cards">`;
for (let i = 0; i < projects.length; i++) {
const project = projects[i];
// Jump ahead to get the most relevant date.
let now = moment();
if ( project.notes && Object.keys(project.notes).length ) {
projectTimestamp = Object.keys(project.notes)[0];
let projectDate = moment( projectTimestamp );
if ( projectDate.format('YYYY MM DD') == now.format('YYYY MM DD') ) {
project.status = 'today';
}
}
html += `<article class="project-card">`;
// ICON
if ( project.status ) html += `<span class="project-card-status" data-status="${project.status}"> </span>`;
// TITLE
let title = project.title || project.file.name;
html += `<h1 class="project-card-title"><a href="${project.file.name}" data-href="${project.file.name}" class="internal-link">${title}</a></h1>`;
// CODE
html += `<div class="project-card-meta">`;
if ( project.code ) html += `<span class="project-card-code">${project.code}</span>`;
html += '</div>';
// NOTES
if ( project.notes && Object.keys(project.notes).length ) { for (let l = 0; l < Object.keys(project.notes).length; l++) {
const noteTimestamp = Object.keys(project.notes)[l];
const noteText = project.notes[ noteTimestamp ];
let noteDate = moment( noteTimestamp );
let noteHasTime = ( noteTimestamp.split(' ').length > 1 );
let sameYear = ( now.format('YYYY') == noteDate.format('YYYY') );
let displayDate = noteDate.calendar(null, {
sameDay: '[Today]',
nextDay: '[Tomorrow]',
nextWeek: 'dddd',
lastDay: '[Yesterday]',
lastWeek: '[Last] dddd',
sameElse: ( sameYear ? 'D MMMM' : 'D MMMM YYYY' ),
});
if ( noteHasTime ) {
displayDate += ' <span class="project-card-sep">•</span> ' + noteDate.format( 'h:mm a' );
}
html += `<div class="project-card-note">
<span class="project-card-note-date" title="${noteDate}">${displayDate}</span>
<span class="project-card-note-text" title="${noteDate}">${noteText}</span>
</div>`;
}}
// LINKS
html += `<div class="project-card-meta">`;
if ( project.links && Object.keys(project.links).length ) { for (let l = 0; l < Object.keys(project.links).length; l++) {
let linkText = Object.keys(project.links)[l];
let linkURL = project.links[ linkText ];
html += `<a class="project-card-link" href="${linkURL}">${linkText}</a>`;
}}
html += '</div>';
html += '</div>';
html += '</article>';
}
html += `</section>`;
dv.paragraph( html );
Last active
April 9, 2022 04:22
-
-
Save kaelri/f7427fef75a375a453faa7e9c030e254 to your computer and use it in GitHub Desktop.
Obsidian Project List
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.project-cards { | |
margin: 2em 0; | |
} | |
.project-card { | |
margin: .5em 0; | |
/* border: 1px solid #444; */ | |
background: hsla(0, 0%, 0%, .1); | |
padding: .5em .5em .5em 2em; | |
position: relative; | |
/* max-width: 40em; */ | |
} | |
/* Display priority tags as colored circle badges instead of text. */ | |
.project-card-status { | |
display: block; | |
position: absolute; | |
top: .75em; | |
left: .5em; | |
color: transparent; | |
content: ''; | |
width: 1em; | |
height: 1em; | |
border-radius: 50%; | |
margin-right: .25em; | |
} | |
.project-card-status[data-status="today"] { | |
background: #d9534f; | |
} | |
.project-card-status[data-status="todo"] { | |
background: #0275d8; | |
} | |
.project-card-status[data-status="done"] { | |
background: #5cb85c; | |
} | |
.project-card-status[data-status="cont"] { | |
background: #5bc0de; | |
} | |
.project-card-status[data-status="future"], | |
.project-card-status[data-status="wait"] { | |
background: #444; | |
} | |
.project-card-status[data-status="important"], | |
.project-card-status[data-status="now"] { | |
background: #ffd946; | |
} | |
.project-card .project-card-title { | |
margin: 0; | |
font-size: 1rem; | |
} | |
.project-card-title a { | |
color: inherit; | |
} | |
.project-card-meta, | |
.project-card-note { | |
font-size: smaller; | |
color: #999; | |
line-height: 1.5; | |
margin-top: .25em; | |
} | |
.project-card-link { | |
display: inline-block; | |
color: inherit; | |
line-height: 1; | |
padding: 4px; | |
margin-right: .5em; | |
border: 1px solid #444; | |
/* text-decoration: underline; */ | |
} | |
.project-card-note-date { | |
margin-right: .5em; | |
color: white; | |
} | |
.project-card-note-text { | |
color: #999; | |
} | |
.project-card-sep { | |
color: #666; | |
} |
@confluencepoint Hey there — yes, this lists notes in a top-level folder called "Projects." That can be changed to any other query that the Dataview plugin allows. For example, if your notes have the tag
#project
, you could list them by changing the initial query todv.pages('"#project"')
.
Thanks. I think I need your help again.
I have a top-level folder called "Projects" an two files in there:
PROJECT-0001 Some Neat Project.md
---
title: "Some Neat Project"
status: "todo"
code: "PROJECT-0001"
notes:
"2021-06-17 14:00": "In Progress"
links:
"Thread": "https://www.google.com"
"Google Docs": "https://www.google.com"
---
I'm a project!
PROJECT-0002 Some Extra Neat Project.md
---
title: "Some extra Neat Project"
status: "todo"
code: "PROJECT-0002"
notes:
"2021-06-17 15:00": "In Progress"
links:
"Thread": "https://www.google.com"
"Google Docs": "https://www.google.com"
---
I'm a project!
- The file
obsidian-dataview-project-cards.md
produces this error:
Evaluation Error: ReferenceError: projectTimestamp is not defined
at eval (eval at <anonymous> (eval at <anonymous> (app://obsidian.md/app.js:1:1210430)), <anonymous>:30:26)
at DataviewInlineApi.eval (eval at <anonymous> (app://obsidian.md/app.js:1:1210430), <anonymous>:11833:33)
at evalInContext (eval at <anonymous> (app://obsidian.md/app.js:1:1210430), <anonymous>:11833:49)
at DataviewJSRenderer.eval (eval at <anonymous> (app://obsidian.md/app.js:1:1210430), <anonymous>:12221:17)
at Generator.next (<anonymous>)
at eval (eval at <anonymous> (app://obsidian.md/app.js:1:1210430), <anonymous>:26:71)
at new Promise (<anonymous>)
at __awaiter (eval at <anonymous> (app://obsidian.md/app.js:1:1210430), <anonymous>:22:12)
at DataviewJSRenderer.render (eval at <anonymous> (app://obsidian.md/app.js:1:1210430), <anonymous>:12218:16)
at DataviewJSRenderer.eval (eval at <anonymous> (app://obsidian.md/app.js:1:1210430), <anonymous>:12210:24)
The file obsidian-dataview-project-cards.css
is in the snippets folder and enabled.
@confluencepoint Changing projectTimestamp = Object.keys(project.notes)[0];
to let projectTimestamp = Object.keys(project.notes)[0];
fixed the issue for me.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@confluencepoint Hey there — yes, this lists notes in a top-level folder called "Projects." That can be changed to any other query that the Dataview plugin allows. For example, if your notes have the tag
#project
, you could list them by changing the initial query todv.pages('"#project"')
.