Skip to content
This repository has been archived by the owner on Jul 6, 2023. It is now read-only.

Commit

Permalink
feat: setup workflow, local db handler, add groups
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmadalfy committed Jan 18, 2020
1 parent c036b0a commit 5b05e4a
Show file tree
Hide file tree
Showing 28 changed files with 8,640 additions and 0 deletions.
31 changes: 31 additions & 0 deletions images/group.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 51 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Gitlab Statistics</title>
<link rel="stylesheet" href="styles/main.css" />
</head>
<body>
<div id="app" class="layout-container">
<div class="panel">
<div class="panel__head">
<h1 class="panel__title">Groups</h1>
<div class="panel__actions"><button id="load-groups">Load Groups</button></div>
</div>
<div class="panel__content">
<div id="groups-content"></div>
</div>
<div class="panel__footer">
<p>Total count: <span id="groups-count">loading</span></p>
<p>Last update: <span id="groups-update">loading</span></p>
</div>
</div>
<div class="panel">
<div class="panel__head">
<h1 class="panel__title">Projects</h1>
<div class="panel__actions"><button id="load-projects">Load Projects</button></div>
</div>
<div class="panel__content">
<div id="projects-content"></div>
</div>
<div class="panel__footer">
<p>Total count: <span id="projects-count"></span></p>
<p>Last update: <span id="projects-update"></span></p>
</div>
</div>
<div class="panel members-area">
<div class="panel__head">
<h1 class="panel__title">Members</h1>
<div class="panel__actions"><button id="load-members">Load Members</button></div>
</div>
<div class="panel__content">
<div id="members-content"></div>
</div>
<div class="panel__footer">
<p>Total count: <span id="members-count"></span></p>
<p>Last update: <span id="members-update"></span></p>
</div>
</div>
</div>
<script type="module" src="scripts/app.js"></script>
</body>
</html>
28 changes: 28 additions & 0 deletions package-lock.json

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

14 changes: 14 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,26 @@
"description": "",
"main": "index.js",
"scripts": {
"snowpack": "snowpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"dexie": "^2.0.4",
"dexie-relationships": "^1.2.11",
"javascript-time-ago": "^2.0.6",
"lit-html": "^1.1.2",
"snowpack": "^1.0.5"
},
"snowpack": {
"webDependencies": [
"dexie",
"dexie-relationships",
"javascript-time-ago",
"javascript-time-ago/locale/en/index.js",
"lit-html"
]
}
}
19 changes: 19 additions & 0 deletions scripts/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { html, render } from '../web_modules/lit-html.js';
import TimeAgo from '../web_modules/javascript-time-ago.js'
import en from '../web_modules/javascript-time-ago/locale/en/index.js';
import Groups from './groups.js'
import db from './db.js'

class App {
constructor() {
this.registerRelativeTime();
this.groups = new Groups();
}

registerRelativeTime() {
TimeAgo.addLocale(en)
window.timeAgo = new TimeAgo('en');
}
}

new App();
42 changes: 42 additions & 0 deletions scripts/base-component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import Utilities from './utilities.js';
import routes from './routes.js'
import DataSource from './data-handler.js';
import db from './db.js';

class Base {
constructor(component) {
this.component = component;
this.checkData();
this.bindEvents();
}

bindEvents() {
document.querySelector(`#load-${this.component}`).addEventListener('click', this.fetchItems.bind(this));
}

fetchItems() {
this.data = new DataSource();
const fetcher = `fetch${this.component.charAt(0).toUpperCase()}${this.component.substring(1)}`
this.data[fetcher]().then(data => {
this.drawListing(data);
});
}

drawListing(content) {}

checkData() {
db[this.component].toArray().then(content => {
this.drawListing(content);
// can get count using count()
document.querySelector(`#${this.component}-count`).innerHTML = content.length;
});
}

updateLastModified() {
const lastModified = localStorage.getItem(this.component);
console.log(lastModified);
document.querySelector(`#${this.component}-update`).innerHTML = lastModified ? timeAgo.format(JSON.parse(lastModified)) : 'Not available';
}
}

export default Base;
58 changes: 58 additions & 0 deletions scripts/data-handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Utilities from './utilities.js';
import Groups from './groups.js';
import Projects from './projects.js';
import Members from './members.js';
import routes from './routes.js'
import db from './db.js'

class DataSource {

static instance;

constructor() {
if(DataSource.instance){
return DataSource.instance;
}
this.data = { members: [], groups: []};
DataSource.instance = this;
}

fetchGroups() {
return Groups.load().then(groups => {
this.data.groups = groups;
db.groups.bulkPut(groups);
localStorage.setItem('groups', Date.now());
return groups;
})
}

fetchData() {
Groups.load().then(groups => {
data.groups = groups;
db.groups.bulkPut(groups);
const projects = Promise.all(groups.map(group => Groups.loadGroupProjects(group.id)));
projects.then(projects => {
db.projects.bulkPut(projects.flat());
});
return Promise.all(groups.map(group => Groups.loadGroupMembers(group.id)))
})
.then(groupMembers => groupMembers.flat())
.then(members => {
const key = 'id';
const uniqueMembers = [...new Map(members.map(item =>[item[key], item])).values()];
data.members = uniqueMembers;
db.members.bulkPut(uniqueMembers);
const events = Promise.all(uniqueMembers.map(member => Members.loadMemberEvents(member.id)));
events.then(events => {
db.events.bulkPut(events.flat());
});
})
.then(events => {
data.members.forEach((member, i) => {
data.members[i].events = events[i];
});
});
}
}

export default DataSource;
12 changes: 12 additions & 0 deletions scripts/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Dexie from '../web_modules/dexie.js';
import relationships from '../web_modules/dexie-relationships.js';

const db = new Dexie('gitlab', {addons: [relationships]});
db.version(1).stores({
groups: 'id, name',
members: 'id, name, &username',
projects: 'id, name',
events: 'created_at, project_id -> projects.id',
});

export default db;
81 changes: 81 additions & 0 deletions scripts/groups.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { html, render } from '../web_modules/lit-html.js';
import Utilities from './utilities.js';
import routes from './routes.js'
import DataSource from './data-handler.js';
import Base from './base-component.js';
import db from './db.js';

class Groups extends Base {
constructor() {
super('groups');
}

static load() {
return Utilities.req(routes.groups);
}

// static loadGroupMembers(groupId) {
// return Utilities.req(`${routes.groups}/${groupId}/${routes.members}`);
// }

// static loadGroupProjects(groupId) {
// return Utilities.req(`${routes.groups}/${groupId}/${routes.projects}`);
// }

// bindEvents() {
// document.querySelector('#load-groups').addEventListener('click', this.fetchGroups.bind(this));
// }

// fetchGroups() {
// this.data = new DataSource();
// this.data.fetchGroups().then(groups => {
// this.drawGroups(groups);
// });
// }

drawListing(groups) {
const groupsTemplates = [];
for (const group of groups) {
groupsTemplates.push(html`
<tr>
<td class="listing__avatar"><img src="${group.avatar_url || './images/group.svg'}" alt="${group.name}" /></td>
<td>${group.name}</td>
<td>
<a @click=${()=> {this.showProjects(group.id)}}>Projects</a>
<a @click=${()=> {this.showMembers(group.id)}}>Members</a>
</td>
</tr>
`);
}
const nodes = html`
<table class="listing">
<thead>
<tr>
<th colspan="2">Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
${groupsTemplates}
</tbody>
</table>
`;
render(nodes, document.querySelector('#groups-content'));
this.updateLastModified();
}

// checkData() {
// db.groups.toArray().then(groups => {
// this.drawGroups(groups);
// // can get count using count()
// document.querySelector('#groups-count').innerHTML = groups.length;
// });
// }

// updateLastModified() {
// const lastModified = localStorage.getItem('groups');
// document.querySelector('#groups-update').innerHTML = lastModified ? timeAgo.format(JSON.parse(lastModified)) : 'Not available';
// }
}

export default Groups;
14 changes: 14 additions & 0 deletions scripts/members.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Utilities from './utilities.js';
import routes from './routes.js'

class Members {
static load() {
return Utilities.req(routes.members);
}

static loadMemberEvents(userId) {
return Utilities.req(`${routes.users}/${userId}/${routes.events}`);
}
}

export default Members;
Loading

0 comments on commit 5b05e4a

Please sign in to comment.