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 );
-
-
Save kaelri/f7427fef75a375a453faa7e9c030e254 to your computer and use it in GitHub Desktop.
.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 to dv.pages('"#project"')
.
@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.
I found your post on Discord.
Is there a special path for your project file?
For me, only the heading "Project Cards" is displayed.