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 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
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
PROJECT-0002 Some Extra Neat Project.md
obsidian-dataview-project-cards.md
produces this error:The file
obsidian-dataview-project-cards.css
is in the snippets folder and enabled.