Commit 63d00739 by Tomáš Hübelbauer

Implement issue and wiki listing

parent cb3b55c1
......@@ -42,6 +42,35 @@ apiServer.post('/delete', jsonParser, async (request, response) => {
response.json({});
});
apiServer.get('/issues/:name', async (request, response) => {
const { name } = request.params;
const path = getPathForName(name) + '/todo';
await fs.ensureDir(path);
const issues = [];
for (const p of await fs.readdir(path)) {
const { atime, ctime } = await fs.stat(path + '/' + p);
console.log(atime, ctime);
issues.push({ accessed: atime, changed: ctime, name: p });
}
response.json({ name, issues });
});
// TODO: Make this a tree recursively.
apiServer.get('/wikis/:name', async (request, response) => {
const { name } = request.params;
const path = getPathForName(name) + '/wiki';
await fs.ensureDir(path);
const wikis = [];
for (const p of await fs.readdir(path)) {
const { atime, ctime } = await fs.stat(path + '/' + p);
console.log(atime, ctime);
wikis.push({ accessed: atime, changed: ctime, name: p });
}
response.json({ name, wikis });
});
const gitPort = 7000;
const gitServer = new GitServer('../../data', { autoCreate: false, authenticate: (type, repo, user, next) => next() });
......
......@@ -3,6 +3,8 @@ const gitPubUrl = 'http://localhost:4000';
type Params = { [name: string]: string; };
type Repo = { id: string; name: string; };
type Issue = { created: string, accessed: string, name: string; };
type Wiki = { created: string, accessed: string, name: string; };
function makeUrl(pathName: string, params?: Params) {
const url = new URL(gitPubUrl);
......@@ -40,14 +42,25 @@ window.addEventListener('load', async _ => {
let appNode = <div/>;
document.body.appendChild(mount(appNode));
// State:
let page: 'index' | 'repo' = 'index';
// -> Index page state:
let repos: Repo[] = [];
render();
// -> Repo page state:
let repo: Repo;
// Extend to include loading states.
let issues: Issue[];
let wikis: Wiki[];
renderPage();
await refresh();
async function refresh() {
const data = await get<{ repos: Repo[] }>('/repos');
repos = data.repos;
render();
renderPage();
}
async function onNewButtonClick() {
......@@ -60,6 +73,18 @@ window.addEventListener('load', async _ => {
await refresh();
}
async function onOpenAClick(event: Event) {
const id = (event.currentTarget as HTMLButtonElement).dataset['id'];
repo = repos.find(r => r.id === id);
page = 'repo';
issues = [];
wikis = [];
renderPage();
issues = (await get<{ name: string, issues: Issue[] }>('/issues/' + repo.id)).issues;
wikis = (await get<{ name: string, wikis: Wiki[] }>('/wikis/' + repo.id)).wikis;
renderPage();
}
async function onDeleteButtonClick(event: Event) {
const id = (event.currentTarget as HTMLButtonElement).dataset['id'];
const repo = repos.find(r => r.id === id);
......@@ -69,16 +94,64 @@ window.addEventListener('load', async _ => {
}
}
function render() {
const node = <div>
function onBackAClick() {
page = 'index';
renderPage();
}
function renderPage() {
switch (page) {
case 'index': return renderIndex();
case 'repo': return renderRepo();
default: return renderError();
}
}
function renderError() {
render(<div>
<span>Unknown page '{page}'.</span>
</div>);
}
function renderRepo() {
render(<div>
<a onclick={onBackAClick}>Back</a>
<h1>{repo.name}</h1>
<h2>Clone</h2>
<p>
<code>git clone http://localhost:7000/{repo.id}</code>
</p>
<h2>Issues</h2>
<button>New</button>
{issues.length === 0 ? 'No issues yet' : ''}
<ul>
{issues.map(i => <li>{i.name}</li>)}
</ul>
<h2>Wikis</h2>
<button>New</button>
{wikis.length === 0 ? 'No wikis yet' : ''}
<ul>
{wikis.map(w => <li>{w.name}</li>)}
</ul>
<h2>Branches</h2>
TODO: Load branches upon reaching this page (each branch is implicitly a PR/MR and has review UI)
</div>)
}
function renderIndex() {
render(<div>
<div>
<button onclick={onNewButtonClick}>New</button>
</div>
{repos.map(repo => <div>
{repo.name}
<a data-id={repo.id} href={'#repo/' + repo.id} onclick={onOpenAClick}>{repo.name}</a>
<button data-id={repo.id} onclick={onDeleteButtonClick}>Delete</button>
</div>)}
</div>;
</div>);
}
function render(node) {
patch(node, appNode);
appNode = node;
}
......
# Add detail view
This is going to be the repository detail where:
- New file can be created
- A file can be deleted or modified
- An issue can be created
- A wiki page can be created
- The clone URL is shown
- Etc…
# Fix problem with non-empty repos being cloned as empty
# Implement basic review stuff
Maybe using Git Appraise?
# Implement creating a new repository file
# Implement creating new issues
# Implement creating new wikis
# Implement listing repository files
# Implement squashing branch commits
Useful for when in the app, a user decided to contribute, so forks master, makes changes in the online editor for each file (a commit each time)
and then for review wants the changes to appears as one.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment