Skip to content

Commit

Permalink
Separate front-end components and add mock activities service. (kubef…
Browse files Browse the repository at this point in the history
…low#2626)

* Separate front-end components and add mock activities service.

- Adds deep-link routing behavior for all front-end pages.
  Iframed pages reflect a URL to the browser that makes them
  linkable but hides the internal page.
- Seperates the front-end into subcomponents, including an
  activities view.
- Fix iframe view behavior to have it cover the space voided
  by the layout header.
- Adds /api/activities endpoint to the Express server for
  activities to eventually be replaced with real data.
- Sets the _devMode flag to true based on the webpack build env.

* Address PR comments

* Merge changes from PR kubeflow#2651
  • Loading branch information
Kam D Kasravi committed Mar 8, 2019
1 parent b4f1973 commit 461697b
Show file tree
Hide file tree
Showing 12 changed files with 670 additions and 150 deletions.
3 changes: 2 additions & 1 deletion components/centraldashboard/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
},
"extends": ["eslint:recommended", "google"],
"globals": {
"VERSION": true,
"VERSION": "readonly",
"DEVMODE": "readonly",
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
Expand Down
35 changes: 34 additions & 1 deletion components/centraldashboard/app/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,45 @@ const {PORT, PORT_1} = process.env;
const port: number = Number(PORT) || Number(PORT_1) || 8082;
const frontEnd: string = resolve(__dirname, "public");

interface Activity {
time: Date;
event: string;
isError: boolean;
source: string;
}
const actvities = _generateActivities();
function _generateActivities(): Activity[] {
const activities: Activity[] = [];
const systems: string[] = [
"serving-system",
"gpu-system",
"training-system"
];
const now = Date.now();
for (let i = 0; i < 100; i++) {
activities.push({
time: new Date(now - (Math.random() * 86400000)),
event: `Event #${i}`,
isError: Math.random() * 10 <= 1, // 1/10 probability
source: systems[Math.floor(Math.random() * 3)]
});
}
return activities.sort((a, b) => b.time.getTime() - a.time.getTime());
}

app.use(express.json());
app.use(express.static(frontEnd));

app.get("/api", (req: express.Request, res: express.Response) => {
console.info(`Request ${req.url} received`);
res.send("Hello World");
});
app.get("/api/activities", (req: express.Request, res: express.Response) => {
res.send(actvities);
});
app.get("/*", (req: express.Request, res: express.Response) => {
res.sendFile(resolve(frontEnd, "index.html"));
});

app.listen(port,
() => console.info(`Server listening on port http://localhost:${port}`));
() => console.info(`Server listening on port http://localhost:${port}`));
40 changes: 36 additions & 4 deletions components/centraldashboard/package-lock.json

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

3 changes: 2 additions & 1 deletion components/centraldashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"@babel/polyfill": "^7.2.5",
"@polymer/app-layout": "^3.0.0",
"@polymer/app-route": "^3.0.0",
"@polymer/iron-ajax": "^3.0.1",
"@polymer/iron-collapse": "^3.0.1",
"@polymer/iron-flex-layout": "^3.0.0",
"@polymer/iron-icons": "^3.0.1",
Expand All @@ -43,11 +44,11 @@
"@polymer/paper-dropdown-menu": "^3.0.1",
"@polymer/paper-icon-button": "^3.0.0",
"@polymer/paper-item": "^3.0.1",
"@polymer/paper-progress": "^3.0.1",
"@polymer/paper-tabs": "^3.0.1",
"@polymer/polymer": "^3.1.0",
"@types/dotenv": "^6.1.0",
"@webcomponents/webcomponentsjs": "^2.0.0",
"body-parser": "^1.18.3",
"express": "^4.16.4",
"web-animations-js": "^2.3.1"
},
Expand Down
113 changes: 113 additions & 0 deletions components/centraldashboard/public/components/activity-view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import {PolymerElement, html} from '@polymer/polymer';

import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
import '@polymer/iron-ajax/iron-ajax.js';
import '@polymer/iron-icon/iron-icon.js';
import '@polymer/iron-icons/iron-icons.js';
import '@polymer/paper-progress/paper-progress.js';

export class ActivityView extends PolymerElement {
static get template() {
return html`
<style is="custom-style" include="iron-flex iron-flex-alignment">
</style>
<style>
:host {
@apply --layout-vertical;
background: #f1f3f4;
--accent-color: #007dfc;
--primary-background-color: #003c75;
--sidebar-default-color: #ffffff4f;
--border-color: #f4f4f6;
padding: 1em;
}
paper-progress {
width: 100%;
--paper-progress-active-color: var(--accent-color)
}
#list {
overflow-y: scroll;
}
.activity-row {
background: #fff;
border-top: 1px solid rgba(0,0,0,.12);
box-shadow: 0 3px 3px rgba(0,0,0,.12);
transition: margin .2s cubic-bezier(0.4, 0, 0.2, 1);
font-size: 13px;
padding: 5px;
}
.activity-row div {
padding: 0 5px;
}
.event {
flex-basis: 50%;
}
.event-icon {
height: 18px;
width: 18px;
padding: 0 10px;
}
.event-icon.build {
transform: scale(-1, 1);
color: rgb(28, 175, 199);
}
.event-icon.error {
color: rgb(218, 66, 54);
}
[hidden] {
display: none;
opacity: 0;
pointer-events: none
}
</style>
<iron-ajax auto url="/api/activities" handle-as="json"
loading="{{loading}}" on-response="_onResponse">
</iron-ajax>
<paper-progress indeterminate class="slow"
hidden$="[[!loading]]"></paper-progress>
<div id="list" role="listbox">
<template is="dom-repeat" items="[[activities]]">
<div class="activity-row layout horizontal">
<div class="flex">[[item.formattedTime]]</div>
<div class="flex flex-auto event">
<iron-icon class$="event-icon [[item.icon]]"
icon="[[item.icon]]">
</iron-icon>[[item.event]]
</div>
<div class="flex">[[item.source]]</div>
</div>
</template>
</div>
`;
}

/**
* Object describing property-related metadata used by Polymer features
*/
static get properties() {
return {
loading: Boolean,
activities: Array,
};
}

/**
* Handles the Activities response to set date format and icon.
* @param {Event} responseEvent
*/
_onResponse(responseEvent) {
const {status, response} = responseEvent.detail;
this.activities = [];
// TODO: Surface the error in some manner
if (status !== 200) return;
this.activities = response.map((a) => {
const activity = {
formattedTime: new Date(a.time).toLocaleString(),
icon: a.isError ? 'error' : 'build',
};
return Object.assign(activity, a);
});
}
}

window.customElements.define('activity-view', ActivityView);
89 changes: 89 additions & 0 deletions components/centraldashboard/public/components/dashboard-view.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
:host {
@apply --layout-vertical;
background: #f1f3f4;
--accent-color: #007dfc;
--primary-background-color: #003c75;
--sidebar-default-color: #ffffff4f;
--border-color: #f4f4f6;
}

article {
background: #f1f3f4;
padding: 1em;
grid-gap: 1em;
display: grid;
min-height: 0;
min-width: 0;
--primary-background-color: white;
}

article:after {
content: '';
grid-column: 1 span 3
}

article>paper-card {
border-radius: 5px;
grid-column: 1 / span 2;
max-width: 100%;
overflow: hidden;
min-width: 0;
--paper-card-header: {
font-family: "Google Sans"
}
}

article>paper-card.thin {
grid-column: 3;
min-width: 19em;
}

#Getting-Started paper-icon-item:not(:last-of-type) {
border-bottom: 1px solid var(--border-color);
}

#Getting-Started paper-icon-item iron-icon {
color: var(--accent-color)
}

#Getting-Started [secondary] {
word-break: break-word;
width: 100%;
white-space: normal;
font-size: .8em;
}

#Quick-Links {
grid-column: 3
}

#Quick-Links .link {
width: 80%;
margin: .5em auto;
border: 1px solid #eeeeef;
padding: .5em 1em;
border-radius: 5px;
@apply --layout-horizontal;
}

#Quick-Links .link.more-coming {
opacity: .4;
font-style: italic;
pointer-events: none
}

#Quick-Links .link .button {
color: var(--accent-color);
background: rgba(0, 125, 252, 0.25);
border-radius: 50%
}

a {
text-decoration: none;
color: initial;
}

.header:hover {
color: var(--paper-blue-700);
text-decoration: underline;
}
Loading

0 comments on commit 461697b

Please sign in to comment.