Skip to content

Commit

Permalink
feat(025): Show SRS in UI (#17)
Browse files Browse the repository at this point in the history
* feat: update todo

* feat: update todo

* 0.9.0

* feat: close 025
  • Loading branch information
VladyslavKurmaz authored Nov 10, 2024
1 parent 4fb213b commit 5b8199d
Show file tree
Hide file tree
Showing 13 changed files with 304 additions and 56 deletions.
24 changes: 15 additions & 9 deletions .todo → .tpm
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ team:
name: Vladyslav Kurmaz
fte: 1
timeline:
- name: v0.10.0
date: 2024-11-15 17:00:00 GMT+0200
- name: v0.9.0
date: 2024-11-08 17:00:00 GMT+0200
date: 2024-11-10 23:00:00 GMT+0200
- name: v0.8.0
date: 2024-11-03 14:00:00 GMT+0200
- name: v0.7.0
Expand All @@ -25,26 +27,30 @@ timeline:
- name: v0.2.0
date: 2024-09-04 17:30:00 GMT+0200
tasks: |
[-:024:v0.8.0] Tweak task status based on child tasks @vlad.k
[+:023:v0.8.0] Implement project, team, srs section as classes @vlad.k
[-:028:v0.10.0] Tasks spill over batch mode @vlad.k
[-:027:v0.10.0] Implement team section as classes @vlad.k
[+:026:v0.9.0] Implement srs section as classes @vlad.k
[+:025:v0.9.0] Show SRS in UI @vlad.k
[-:024:v0.10.0] Tweak task status based on child tasks @vlad.k
[+:023:v0.9.0] Implement project, team, srs section as classes @vlad.k
[+:022:v0.7.0] Describe command - project @vlad.k
[+:021:v0.6.0] Add project description section @vlad.k
[+:020:v0.5.0] Add option to display tasks with different statuses: --backlog, --indev, --done @vlad.k
[+:019:v0.5.0] Add component as optional parameter for ls command @vlad.k
[-:018:v0.8.0] Generate snapshot @vlad.k
[-:018:v0.10.0] Generate snapshot @vlad.k
[+:017:v0.5.0] Add SRS section @vlad.k
[-:016:v0.8.0] Add describe command with resolved links @vlad.k
[-:016:v0.10.0] Add describe command with resolved links @vlad.k
[x:015:v0.5.0] Integrate .tpm folder at repository root level to store snapshots @vlad.k
[-:014:v0.8.0] Update README.md with Hello World section using <https://github.com/project-talan/tln-demo> repository @vlad.k
[-:014:v0.10.0] Update README.md with Hello World section using <https://github.com/project-talan/tln-demo> repository @vlad.k
[+:013:v0.6.0] Add search @vlad.k
[+:012:v0.6.0] Add CI/CD @vlad.k
[+:011:v0.6.0] Add unit test framework @vlad.k
[+:010:v0.6.0] Extract tags, timeline from task description @vlad.k
[+:009:v0.5.0] Add command to generate .todo template --team, --timeline, --tasks, --force @vlad.k
[+:008:v0.6.0] Merge multiple descriptions from one file @vlad.k
[-:007:v0.8.0] Server command: express server + fs watch @vlad.k
[-] Create API using express
[-] Implement web part: Dashboard
[-:007:v0.10.0] Server command: express server + fs watch @vlad.k
[+] Create API using express
[+] Implement web part: Dashboard
[-] Implement web part: Timeline
[-] Implement web part: Team
[-] Add --watch option to watch for changes in .todo file and refresh tpm internal state
Expand Down
1 change: 0 additions & 1 deletion .tpmrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{
"include": "**/.todo;**/.srs*;docs/srs/*",
"ignore": "**/node_modules/**;**/dist/**;.github/**"
}
2 changes: 1 addition & 1 deletion cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ yargs(hideBin(process.argv))
.config(configPath ? JSON.parse(fs.readFileSync(configPath)) : {})
.usage('Project management as Code\nUsage:\n $0 <command> [options]')
.option('verbose', { alias: 'v', count: true, default: 0 })
.option('include', { default: '**/.todo', type: 'string' })
.option('include', { default: '**/.tpm', type: 'string' })
.option('ignore', { default: '**/node_modules', type: 'string' })
.option('depth', { describe: 'Scan depth', default: 5, type: 'number' })
.option('g', { describe: 'Assignee(s), if not defined git user email will be used', alias: 'assignee', default: [], type: 'array' })
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tln-pm",
"version": "0.8.0",
"version": "0.9.0",
"description": "Project Management as Code",
"main": "cli.js",
"scripts": {
Expand Down
7 changes: 5 additions & 2 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ class App {
}

async load(include, ignore) {
this.rootComponent = componentFactory.create(this.logger, this.home, null);
this.rootComponent = componentFactory.create(this.logger, this.home, path.basename(this.home));
const entries = await fg(include, { cwd: this.home, dot: true, ignore });
this.logger.info('entries to scan:', entries.length);
for (const e of entries) {
await this.rootComponent.process(e);
}
Expand Down Expand Up @@ -96,7 +97,9 @@ class App {
if (c) {
if (what.project) {
result.projects = await c.describeProject();
// console.log(result.projects[0].summary.timeline);
}
if (what.srs) {
result.srs = await c.describeSrs();
}
}
return result;
Expand Down
19 changes: 17 additions & 2 deletions src/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class Component {
this.team = null;
this.timeline = [];
this.tasks = [];
this.srs = null;
this.srs = [];
this.components = [];
}

Expand Down Expand Up @@ -133,7 +133,9 @@ class Component {
}
}
if (data.srs) {
this.srs = assign({}, data.srs);
const srs = srsFactory.create(this.logger, source);
await srs.load(data.srs);
this.srs.push(srs);
result |= true;
}
if (data.components) {
Expand Down Expand Up @@ -240,6 +242,19 @@ class Component {
return projects;
}

async describeSrs(options) {
let srs = {};
(await Promise.all(this.srs.map(async c => c.getSummary()))).forEach( s => srs = assign(srs, s));
const components = (await Promise.all(this.components.map(async c => c.describeSrs()))).filter(c => !!c);
if (Object.keys(srs).length > 0 || components.length > 0) {
return {
id: this.id,
srs,
components
}
}
}

async getSummary(summary) {
for (const timeline of this.timeline) {
summary.timeline = summary.timeline.concat(await timeline.getSummary({features: 0}));
Expand Down
27 changes: 16 additions & 11 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,29 @@ class Server {
}
//
const ea = express();
ea.get('/', (req, res) => {
res.send(getLocalContent('index.html'));
})
ea.get('/styles.css', (req, res) => {
res.send(getLocalContent('styles.css'));
})
ea.get('/main.js', (req, res) => {
res.send(getLocalContent('main.js'));
})
ea.use(express.static(path.join(__dirname, '..', 'web')));

// ea.get('/', (req, res) => {
// res.send(getLocalContent('index.html'));
// })
// ea.get('/styles.css', (req, res) => {
// res.send(getLocalContent('styles.css'));
// })
// ea.get('/main.js', (req, res) => {
// res.send(getLocalContent('main.js'));
// })
// API
ea.get('/info', (req, res) => {
res.send(this.makeResponce({version}));
})
ea.get('/projects', async(req, res) => {
res.send(this.makeResponce( await app.describe({ what: { project: true } })));
})
ea.get('/teams', (req, res) => {
res.send(this.makeResponce(root.getTeam({}, true, true)));
})
ea.get('/projects', async(req, res) => {
res.send(this.makeResponce( await app.describe({ what: { project: true } })));
ea.get('/srs', async(req, res) => {
res.send(this.makeResponce( await app.describe({ what: { srs: true } })));
})

ea.get('/raw', (req, res) => {
Expand Down
4 changes: 4 additions & 0 deletions src/source.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ class Source {
this.file = file;
}

async getFolder() {
return path.dirname(this.file);
}

async flush(data) {
try {
fs.writeFileSync(this.file, `${(require('yaml')).stringify(data)}`);
Expand Down
41 changes: 34 additions & 7 deletions src/srs.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,44 @@
'use strict';

const path = require('path');
const fs = require('fs');

class SRS {

/*
*
* params:
*/
constructor(logger) {
constructor(logger, source) {
this.logger = logger;
this.source = source;
this.topics = {};
}

async load(data) {
const folder = await this.source.getFolder();
for( const t of Object.keys(data)) {
let file = null;
let md = data[t];
const lines = data[t].split('\n');
if (lines.length) {
file = path.join(folder, lines[0]);
if (fs.existsSync(file)) {
md = fs.readFileSync(file, {encoding: 'utf8'});
} else {
file = null;
}
}
this.topics[t] = {file, md};
}
}

async getSummary() {
let r = {};
for( const t of Object.keys(this.topics) ) {
r[t] = this.topics[t].md;
}
return r;
}

}

module.exports.create = (logger) => {
return new SRS(logger);
module.exports.create = (logger, source) => {
return new SRS(logger, source);
}
81 changes: 76 additions & 5 deletions web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.js" integrity="sha512-ZwR1/gSZM3ai6vCdI+LVF1zSq/5HznD3ZSTk7kajkaj4D292NLuduDCO1c/NT8Id+jE58KYLKT7hXnbtryGmMg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/markdown-it/13.0.2/markdown-it.min.js" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/markdown-it.min.js"></script>
<script>
import('https://cdn.jsdelivr.net/npm/[email protected]/fp/cdn.min.js').then((dateFns) => {
console.log(dateFns);
});
</script>
<link rel="stylesheet" href="styles.css">

<script src="https://www.gstatic.com/charts/loader.js"></script>
<script>
google.charts.load("current", { packages: ["gantt"] });
</script>

<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
Expand Down Expand Up @@ -65,7 +66,6 @@
</div>
</div>
</nav>

<div class="container pt-4">
<!-- Tabs -->
<div class="tab-content" id="myTabContent">
Expand Down Expand Up @@ -93,7 +93,7 @@
<th colspan="1" role="columnheader" title="Toggle SortBy" class="sortable" style="cursor: pointer;">Id</th>
<th colspan="1" role="columnheader" title="Toggle SortBy" class="sortable" style="cursor: pointer;">Name</th>
<th colspan="1" role="columnheader" title="Toggle SortBy" class="sortable" style="cursor: pointer;">FTE</th>
<th colspan="1" role="columnheader" title="Toggle SortBy" class="sortable" style="cursor: pointer;">inDev / Blocked / Backlog</th>
<th colspan="1" role="columnheader" title="Toggle SortBy" class="sortable" style="cursor: pointer;">Dev / Blocked / Backlog</th>
</tr>
</thead>
<tbody id="dashboard_team_list">
Expand All @@ -119,7 +119,77 @@
</div>
<!-- SRS -->
<div class="tab-pane fade" id="srs-tab-pane" role="tabpanel" aria-labelledby="srs-tab" tabindex="0">
<p>Comming soon...</p>
<div class="container">
<div class="row">
<div class="col-3 d-sm-none d-md-block border border-black border-0 border-top-0 border-bottom-0 border-start-0">

<aside class="bd-aside sticky-xl-top text-body-secondary align-self-start mb-3 mb-xl-5 px-2">
<nav class="small">
<ul class="list-unstyled" id="srs-toc">
<li class="my-2">
<ul class="list-unstyled ps-3 collapse show" id="forms-collapse1" style="">
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#overview">Overview</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#disabled-forms">Disabled forms</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#sizing">Sizing</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#input-group">Input group</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#floating-labels">Floating labels</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#validation">Validation</a></li>
</ul>
</li>
<li class="my-2">
<button type="button" class="btn d-inline-flex align-items-center border-0 collapsed" data-bs-toggle="collapse" aria-expanded="false" data-bs-target="#contents-collapse" aria-controls="contents-collapse">docs</button>
<ul class="list-unstyled ps-3 collapse" id="contents-collapse" style="">
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#typography">Typography</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#images">Images</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#tables">Tables</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#figures">Figures</a></li>
<li class="my-2">
<button type="button" class="btn d-inline-flex align-items-center border-0" data-bs-toggle="collapse" aria-expanded="true" data-bs-target="#forms-collapse" aria-controls="forms-collapse">srs</button>
<ul class="list-unstyled ps-3 collapse show" id="forms-collapse" style="">
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#overview">Overview</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#disabled-forms">Disabled forms</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#sizing">Sizing</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#input-group">Input group</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#floating-labels">Floating labels</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#validation">Validation</a></li>
</ul>
</li>

</ul>
</li>
<li class="my-2">
<button type="button" class="btn d-inline-flex align-items-center border-0 collapsed" data-bs-toggle="collapse" aria-expanded="false" data-bs-target="#components-collapse" aria-controls="components-collapse">backend</button>
<ul class="list-unstyled ps-3 collapse" id="components-collapse" style="">
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#accordion">Accordion</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#alerts">Alerts</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#badge">Badge</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#breadcrumb">Breadcrumb</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#buttons">Buttons</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#button-group">Button group</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#card">Card</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#carousel">Carousel</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#dropdowns">Dropdowns</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#list-group">List group</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#modal">Modal</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#navs">Navs</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#navbar">Navbar</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#pagination">Pagination</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#popovers">Popovers</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#progress">Progress</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#scrollspy">Scrollspy</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#spinners">Spinners</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#toasts">Toasts</a></li>
<li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#tooltips">Tooltips</a></li>
</ul>
</li>
</ul>
</nav>
</aside>
</div>
<div class="col-12 col-sm-9 p-4" id="srs-content">
</div>
</div>
</div>
</div>

</div>
Expand Down Expand Up @@ -149,6 +219,7 @@ <h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
</div-->

</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
<script src="main.js"></script>
</body>
Expand Down
Loading

0 comments on commit 5b8199d

Please sign in to comment.