Skip to content

Commit 7dfbb41

Browse files
committed
added terminal in page to inspect and load data
1 parent 04a3624 commit 7dfbb41

File tree

6 files changed

+419
-3
lines changed

6 files changed

+419
-3
lines changed

_includes/dataset/terminal-button.html

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
<button class="button is-primary modal-button" style="position: fixed;bottom: 0;right: 0;" data-target="#myModal" aria-haspopup="true">Launch Terminal</button>
1+
<button class="button is-primary modal-button" style="position: fixed;bottom: 0;right: 0;" data-target="#myModal" aria-haspopup="true">
2+
<i class="fas fa-terminal"></i>
3+
</button>
24

35
<div class="modal" id="myModal">
46
<div class="modal-background"></div>
5-
<div class="modal-content">
6-
<div class="box">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean efficitur sit amet massa fringilla egestas. Nullam condimentum luctus turpis. </div>
7+
<div class="modal-content" style="width:100%;">
8+
{% include dataset/terminal-content.html %}
79
</div>
810
<button class="modal-close is-large" aria-label="close"></button>
911
</div>
+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
<section class="hero is-fullheight">
2+
<div class="hero-body" style="padding: 0;">
3+
<div class="container">
4+
<div class="columns">
5+
<div class="column is-flex">
6+
<div class="column-child terminal shadow">
7+
<div class="terminal-bar">
8+
<div class="icon-btn close"></div>
9+
<div class="icon-btn min"></div>
10+
<div class="icon-btn max"></div>
11+
<div class="terminal-bar-text is-hidden-mobile dark-mode-text">explorer@dataherb: ~</div>
12+
</div>
13+
<div class="terminal-window primary-bg" onclick="document.getElementById('dummyKeyboard').focus();">
14+
<div class="terminal-output" id="terminalOutput">
15+
<div class="terminal-line">
16+
<span class="help-msg">The DataHerb Terminal — Type <span class="code">help</span>.</span>
17+
</div>
18+
</div>
19+
<div class="terminal-line">
20+
<span class="success"></span> <span class="directory">~</span> <span class="user-input"
21+
id="userInput"></span>
22+
<input type="text" id="dummyKeyboard" class="dummy-keyboard">
23+
</div>
24+
</div>
25+
</div>
26+
</div>
27+
</div>
28+
</div>
29+
</div>
30+
</section>
31+
32+
<script>
33+
var dataset = {}
34+
const BLACKLISTED_KEY_CODES = [ 38 ];
35+
const COMMANDS = {
36+
help:
37+
`DataHerb Terminal Help:
38+
<span class="code">about</span>,
39+
<span class="code">dataset</span>.`,
40+
about:
41+
"DataHerb terminal is developed for more advanced data explorations on DataHerb.",
42+
dataset:
43+
`Dataset name: <span class="code">{{page.name}}</span><br>
44+
GitHub Repository: <span class="code"><a href="https://github.com/{{ page.repository }}">{{ page.repository }}</a></span><br>
45+
{% if page.data %}
46+
{% for data in page.data %}
47+
{% assign data_path_base_url = 'https://raw.githubusercontent.com/' %}
48+
{% assign data_path_branch = '/master/' %}
49+
{% assign data_path = data_path_base_url | append: page.repository | append: data_path_branch | append: data.path %}
50+
<div class="is-divider" style="border-top:.05rem dashed #dbdbdb !important; margin: 0!important;"></div>
51+
{% if data.name %}Name: <span class="code">{{ data.name }}</span> <br>{% endif %}
52+
File: <span class="code">{{data.path}}</span><br>
53+
{% endfor %}
54+
{% endif %}`,
55+
"load": `Load dataset into console in the developer tool. <span class="code">load(file_path_in_dataset)</span>`,
56+
{% if page.data %}
57+
{% for data in page.data %}
58+
{% assign data_path_base_url = 'https://raw.githubusercontent.com/' %}
59+
{% assign data_path_branch = '/master/' %}
60+
{% assign data_path = data_path_base_url | append: page.repository | append: data_path_branch | append: data.path %}
61+
"load({{data.path}})": `Load {{data.path}} into console.`{% unless forloop.last %},{% endunless %}
62+
{% endfor %}
63+
{% endif %}
64+
};
65+
let userInput, terminalOutput;
66+
67+
const app = () => {
68+
userInput = document.getElementById("userInput");
69+
terminalOutput = document.getElementById("terminalOutput");
70+
document.getElementById("dummyKeyboard").focus();
71+
console.log("Application loaded");
72+
};
73+
74+
const execute = function executeCommand(input) {
75+
let output;
76+
input = input.toLowerCase();
77+
if (input.length === 0) {
78+
return;
79+
}
80+
output = `<div class="terminal-line"><span class="success">➜</span> <span class="directory">~</span> ${input}</div>`;
81+
if (!COMMANDS.hasOwnProperty(input)) {
82+
output += `<div class="terminal-line">no such command: ${input}</div>`;
83+
console.log("Oops! no such command");
84+
} else if (input === "load") {
85+
{% if page.data %}
86+
{% for data in page.data %}
87+
{% assign data_path_base_url = 'https://raw.githubusercontent.com/' %}
88+
{% assign data_path_branch = '/master/' %}
89+
{% assign data_path = data_path_base_url | append: page.repository | append: data_path_branch | append: data.path %}
90+
d3.csv("{{data_path}}").then(function(data) { dataset["{{data.path}}"] = data })
91+
{% endfor %}
92+
{% endif %}
93+
94+
}
95+
else {
96+
output += COMMANDS[input];
97+
}
98+
99+
terminalOutput.innerHTML = `${
100+
terminalOutput.innerHTML
101+
}<div class="terminal-line">${output}</div>`;
102+
terminalOutput.scrollTop = terminalOutput.scrollHeight;
103+
};
104+
105+
const key = function keyEvent(e) {
106+
const input = userInput.innerHTML;
107+
108+
if (BLACKLISTED_KEY_CODES.includes(e.keyCode)) {
109+
return;
110+
}
111+
112+
if (e.key === "Enter") {
113+
execute(input);
114+
userInput.innerHTML = "";
115+
return;
116+
}
117+
118+
userInput.innerHTML = input + e.key;
119+
};
120+
121+
const backspace = function backSpaceKeyEvent(e) {
122+
if (e.keyCode !== 8 && e.keyCode !== 46) {
123+
return;
124+
}
125+
userInput.innerHTML = userInput.innerHTML.slice(
126+
0,
127+
userInput.innerHTML.length - 1
128+
);
129+
};
130+
131+
document.addEventListener("keydown", backspace);
132+
document.addEventListener("keypress", key);
133+
document.addEventListener("DOMContentLoaded", app);
134+
135+
</script>

_layouts/dataherb.html

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
layout: default
33
---
44

5+
<link rel="stylesheet" href="{{ site.base_url }}/assets/data/terminal.css">
56
<script src="https://d3js.org/d3.v5.min.js"></script>
67
<script src="{{site.base_url}}/assets/data/dataherb.js"></script>
78
<script src="{{site.base_url}}/assets/js/filesize.min.js"></script>

assets/data/dataherb.js

+1
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,4 @@ function get_filesize(url, callback) {
6767
};
6868
xhr.send();
6969
}
70+

assets/data/terminal.css

+205
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
a {
2+
color: inherit;
3+
}
4+
5+
a:hover {
6+
text-decoration: none;
7+
color: inherit;
8+
}
9+
10+
p {
11+
color: rgb(136, 146, 176);
12+
}
13+
14+
.title {
15+
color: rgba(139, 180, 216, 0.94);
16+
}
17+
18+
.sidebar {
19+
background-color: rgb(23, 42, 69);
20+
display: flex;
21+
align-items: center;
22+
flex-direction: column;
23+
border-radius: 5px;
24+
color: rgb(136, 146, 176);
25+
opacity: 1;
26+
}
27+
28+
29+
.image-overlay {
30+
background: url('https://i.imgur.com/SsVBVWk.png') 20%;
31+
opacity: 0.5;
32+
}
33+
34+
.sidebar-image {
35+
width: 150px;
36+
border-radius: 100%;
37+
margin-top: 1rem;
38+
text-shadow: 2px 2px 4px #000000;
39+
}
40+
41+
.sidebar-link {
42+
font-size: 0.8rem;
43+
text-transform: uppercase;
44+
color: rgba(139, 180, 216, 0.94);
45+
}
46+
47+
.sidebar-link:hover {
48+
color: rgb(230, 241, 255);
49+
50+
}
51+
.header-name {
52+
font-weight: 600;
53+
color: rgb(230, 241, 255);
54+
}
55+
56+
.column-header {
57+
border-bottom: 2px rgb(45, 57, 82) solid;
58+
margin-bottom: 1rem;
59+
}
60+
61+
.column-header > h1 {
62+
font-family: 'Lato', sans-serif;
63+
font-weight: 100;
64+
color: white;
65+
}
66+
67+
.icon, .sidebar-link {
68+
transition-duration: 250ms;
69+
}
70+
71+
.icon:hover {
72+
color: white;
73+
}
74+
75+
.terminal-bar {
76+
background-color: #eae8e9;
77+
border-top-left-radius: 5px;
78+
border-top-right-radius: 5px;
79+
display: flex;
80+
position: relative;
81+
}
82+
83+
.dark-mode {
84+
background-image: linear-gradient(180deg, #464248 0%, #3b383d 100%);
85+
border-bottom: 1px solid rgba(66, 66, 66, 0.5);
86+
}
87+
88+
.dark-mode-text {
89+
color: #bdb9bf !important;
90+
}
91+
92+
.icon-btn {
93+
border-radius: 50%;
94+
margin-top: 7px;
95+
height: 15px;
96+
width: 15px;
97+
margin-bottom: 0.5rem;
98+
}
99+
100+
.terminal-bar > div.icon-btn:first-child {
101+
margin-left: 0.6rem;
102+
}
103+
104+
.terminal-bar > div.icon-btn:not(:first-child) {
105+
margin-left: 0.5rem;
106+
}
107+
108+
.terminal-bar > div.icon-btn:last-child {
109+
margin-right: 0.6rem;
110+
}
111+
112+
.close {
113+
background-color: #fa615c;
114+
}
115+
116+
.max {
117+
background-color: #3fc950;
118+
}
119+
120+
.min {
121+
background-color: #ffbd48;
122+
}
123+
124+
.terminal-window {
125+
border-bottom-right-radius: 5px;
126+
border-bottom-left-radius: 5px;
127+
height: 254px;
128+
min-height: 80vh;
129+
padding: .5rem 0rem 0rem .5rem;
130+
display: flex;
131+
flex-direction: column;
132+
}
133+
134+
.primary-bg {
135+
background-color: rgb(23, 42, 69);
136+
}
137+
138+
.shadow {
139+
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.55);
140+
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.55);
141+
box-shadow: 0px 3px 15px rgba(0, 0, 0, 0.2);
142+
}
143+
144+
.terminal-bar-text {
145+
position: absolute;
146+
margin-top: 3px;
147+
color: #383838;
148+
width: 100%;
149+
text-align: center;
150+
font-weight: 500;
151+
}
152+
153+
.has-equal-height {
154+
height: 100%;
155+
display: flex;
156+
flex-direction: column;
157+
}
158+
159+
.terminal-output {
160+
overflow-y: hidden;
161+
overflow: auto;
162+
}
163+
164+
.column-child {
165+
flex: 1;
166+
}
167+
168+
.terminal-line {
169+
position: relative;
170+
font-family: 'Anonymous Pro', monospace;
171+
font-size: .9rem;
172+
color: #b7c5d2;
173+
}
174+
175+
.directory {
176+
color: #75e1e7;
177+
font-weight: 500;
178+
}
179+
180+
.success {
181+
color: #8dd39e;
182+
}
183+
184+
.code, .error, .fa-heart {
185+
color: #ffd14e
186+
}
187+
188+
.fa-heart {
189+
padding-top: 0.5rem;
190+
}
191+
192+
.dummy-keyboard {
193+
opacity:0;
194+
filter:alpha(opacity=0);
195+
}
196+
197+
::-webkit-scrollbar {
198+
display: none;
199+
}
200+
201+
@media screen and (max-width: 768px) {
202+
.resume {
203+
padding-bottom: 0.5rem;
204+
}
205+
}

0 commit comments

Comments
 (0)