145 lines
4.6 KiB
Markdown
145 lines
4.6 KiB
Markdown
```jsx
|
|
const {fandoms: fandomIcons, categories: categoryIcons} = await dc.require("root/views/cat-icons.md#category icons")
|
|
const PRE_REGEX = /^\d+\s-\s/m;
|
|
const tprogress = (t) => {
|
|
if(t.$completed) return 1;
|
|
let completed = t.$elements.filter(x => x.$completed).length;
|
|
let total = Math.max(t.$elements.length, 1);
|
|
let a = 0;
|
|
t.$elements.forEach(e => {
|
|
a += tprogress(e) / total;
|
|
})
|
|
return a;
|
|
}
|
|
const usePath = (path) => dc.useQuery(`childof (@block-list) and $parentLine < 0 and @task and path("${path}") and !#folder-note and !contains($file, "uni")`)
|
|
|
|
function TaskTable({rows}) {
|
|
//const uniq = dc.useMemo(() => q.map(x => x.$parent).filter((b, i, a) => i === a.findIndex(y => y.$file === b.$file)), [q]);
|
|
/*const groups = dc.useMemo(() => uniq
|
|
.map((p) => ({key: p, rows: q.filter(b => b.$parent.$id === p.$id)}))
|
|
.sort((a, b) => {
|
|
let aa = a.key.$file.split("/").toReversed()[0];
|
|
let bb = b.key.$file.split("/").toReversed()[0];
|
|
return aa > bb ? 1 : aa < bb ? -1 : 0;
|
|
}), [uniq, q]);*/
|
|
return dc.useMemo(() => {
|
|
|
|
const tprops = {
|
|
groupings: [
|
|
{
|
|
render: (k, r) => {
|
|
let kk = k.$file.split("/");
|
|
let block = kk.pop();
|
|
let name = kk[kk.length - 1];
|
|
name = name.substr(0, name.lastIndexOf("."));
|
|
let link = k.$parent.$link.withDisplay(k.$parent.$title)
|
|
return (<h4 style={{
|
|
"--link-color": "var(--h4-color)",
|
|
}}>
|
|
<dc.Link link={link} style={{color: "var(--h4-color) !important"}}/>
|
|
</h4>)
|
|
}
|
|
}
|
|
],
|
|
rows,
|
|
columns: [
|
|
{
|
|
id: "one",
|
|
title: "task",
|
|
value: (x) => x,
|
|
render: (v, o) => {
|
|
return <dc.TaskList
|
|
rows={[o]}
|
|
states={["/", "x", " "]} />
|
|
},
|
|
width: "maximum"
|
|
},
|
|
{
|
|
id: "progress",
|
|
title: "% done",
|
|
value: (x) => x,
|
|
render: (v, o) => <progress value={tprogress(o) * 100} min={0} max={100}/>,
|
|
width: "minimum"
|
|
}
|
|
],
|
|
|
|
paging: 7
|
|
}
|
|
return <dc.VanillaTable {...tprops}/>
|
|
}, [rows])
|
|
}
|
|
function Fandom({projects, name, path}) {
|
|
let realName = name.replace(PRE_REGEX, "")
|
|
let lastSegment = path.split("/").toReversed()[0]
|
|
const title = <span style={{"--link-color": "var(--callout-color)"}}><i className={`far ${fandomIcons[realName.toLocaleLowerCase()]}`}/> <dc.Link link={dc.fileLink(`${path}/${lastSegment}.md`).withDisplay(realName)}/></span>
|
|
return (
|
|
<>
|
|
<dc.Callout type="column|flex" title={title}>
|
|
{projects.map(p => (
|
|
<dc.Callout type="turquoise" title={<span style={{"--link-color": "var(--callout-color)"}}><dc.Link link={
|
|
dc.fileLink(p.key).withDisplay(p.key.split("/").toReversed()[0].replace(PRE_REGEX, "").replace(/\.md$/, ""))}/></span>} collapsible={false}>
|
|
<TaskTable rows={p.rows}/>
|
|
</dc.Callout>
|
|
))}
|
|
</dc.Callout>
|
|
</>
|
|
)
|
|
}
|
|
function Type({ fandoms, catName }) {
|
|
// console.log("tasks", tasks);
|
|
// console.log(arr)
|
|
let realName = catName.replace(PRE_REGEX, "")
|
|
return (<dc.Callout type="greybl" title={<h1><i className={`fal ${categoryIcons[realName.toLocaleLowerCase()]}`}/> {realName}</h1>}>
|
|
{fandoms.map(f => (
|
|
<Fandom path={f.key} projects={f.rows} name={f.key.split("/").toReversed()[0].replace(PRE_REGEX, "")} />))}
|
|
</dc.Callout>)
|
|
}
|
|
|
|
function Master({tasks}) {
|
|
return (<>
|
|
{tasks.map(x => <Type fandoms={x.rows} catName={x.key.split("/")[1].replace(PRE_REGEX, "")} />)}
|
|
</>)
|
|
}
|
|
|
|
function ProjectView({type, path}) {
|
|
let tmp = path.split("/").toReversed().slice(1).toReversed()
|
|
path = tmp.join("/").replace(/\.md$/m, "")
|
|
switch(type) {
|
|
case "master": {
|
|
const gf = o => {
|
|
let tmp = o.substring(o.indexOf("/"))
|
|
return tmp
|
|
}
|
|
const tasks = dc.array(usePath(path)).groupBy(o => o.$parent)
|
|
.groupBy(ok => ok.key.$file)
|
|
.groupBy(ok => {
|
|
let t = ok.key;
|
|
t = t.substring(0, t.lastIndexOf("/"))
|
|
return t
|
|
})
|
|
.groupBy((ok) => {
|
|
return ok.key.split("/").toReversed().slice(1).toReversed().join("/")
|
|
})
|
|
.array()
|
|
return <Master tasks={tasks}/>
|
|
}
|
|
case "category":
|
|
const tasks = usePath(path);
|
|
const fandoms = dc.array(tasks).groupBy(ok => ok.$parent)
|
|
.groupBy(ok => ok.key.$file)
|
|
.groupBy(ok => {
|
|
let tpo = ok.key.split("/").toReversed().slice(1).toReversed().join("/")
|
|
return tpo
|
|
}).array();
|
|
return <Type catName={path.substring(path.lastIndexOf("/") + 1)} fandoms={fandoms}/>
|
|
case "fandom":
|
|
default:
|
|
let projects = dc.array(usePath(path)).groupBy(ok => ok.$parent).groupBy(ok => ok.key.$file).array();
|
|
return <Fandom path={path} name={path.substring(path.lastIndexOf("/") + 1).replace(PRE_REGEX, "")} projects={projects}/>
|
|
}
|
|
}
|
|
return {TaskTable, Type, Fandom, ProjectView}
|
|
```
|
|
|
|
Dz1PGyklbj
|