Skip to content
This repository was archived by the owner on Mar 29, 2025. It is now read-only.

Commit 096cad7

Browse files
GabeStahdanielmai
authored andcommitted
Adds RunnableUrl (editable Dgraph Alpha URLs). (#59)
All Runnable dialogs throughout site can optionally provide users the ability to customize the Dgraph URL posted to during a transaction request. * Added RunnableUrl module. * Moved RunnableUrl initialization to beginning of Runnable to suit module style. * Added customized error message and clickable button highlight animation. * Added `Load Defaults` button which resets all URLs to default values. Modified Hugo params configuration. Added `RunnableUrl.displayCustomEndpoint` param which determines if custom endpoint paths are displayed in UI. Fixed README typo. * Updated `runnable.js` to use module export.
1 parent e1dd0c7 commit 096cad7

File tree

14 files changed

+1199
-155
lines changed

14 files changed

+1199
-155
lines changed

config.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@ theme="hugo-tutorials"
3434
identifier = "search"
3535
weight = 6
3636

37-
3837
[params]
38+
[params.RunnableUrl]
39+
enabled = true
40+
displayCustomEndpoint = true
41+
3942
[params.menudesc]
4043
intro = "In this lesson you'll learn how to set up and run Dgraph for the tutorial and learn about graph databases"
4144
basic = "Here you'll learn the basics of how to query graph data from Dgraph and how to use and interpret the results."

themes/hugo-tutorials/README.md

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# Hugo Tutorials Theme
2+
3+
## Customizing Runnable URLs
4+
5+
All `Runnable` dialogs throughout site can **optionally** provide users the ability to customize the Dgraph URL posted to during a transaction request.
6+
7+
![RunnableUrl Demo](./static/images/runnable-url-demo.gif)
8+
9+
### Configuration
10+
11+
To enable editable URLs edit the Hugo configuration (`config.toml`) and set the `RunnableUrl.enabled` param to `true`.
12+
13+
```toml
14+
[params.RunnableUrl]
15+
enabled = true
16+
```
17+
18+
Any other value (or a missing entry) will disable editable URLs and use the default behavior.
19+
20+
To adjust whether the endpoint button displays the user-defined path or the default endpoint path set the `RunnableUrl.displayCustomEndpoint` to `true` or `false`.
21+
22+
```toml
23+
[params.RunnableUrl]
24+
displayCustomEndpoint = true
25+
```
26+
27+
A default value of `true` will display whatever custom path the user inputs for a matching endpoint type. For example, if the user sets the path of a query to `/q` the endpoint button will display `/q`. However, if `displayCustomEndpoint` is set to `false`, the query URL will still use the custom `/q` path value, but the UI button will display the default path of `/query`.
28+
29+
## RunnableUrl
30+
31+
The [`RunnableUrl`](./static/js/runnable-url/index.js) class represents a robust Runnable URL object. It has the following fields and default values.
32+
33+
```js
34+
class RunnableUrl {
35+
hash: '',
36+
hostName: '127.0.0.1',
37+
port: '8080',
38+
pathName: '/query',
39+
pathType: 'query',
40+
protocol: 'http:',
41+
search: '',
42+
searchParams: {},
43+
statics: {
44+
searchParams: {
45+
latency: true
46+
}
47+
}
48+
}
49+
```
50+
51+
Each field has a named getter/setter so values can be easily changed or retrieved. A `RunnableUrl` instance is then used to generate the full Dgraph Runnable URL using the `RunnableUrl.url` getter or the `RunnableUrl.toString()` method.
52+
53+
```js
54+
const default = new RunnableUrl();
55+
console.log(default.url);
56+
// http://127.0.0.1:8080/query
57+
```
58+
59+
## Defining Static Properties
60+
61+
The `RunnableUrl` class also has a field called `statics` that is an `Object` collection of property values that should be associated with and included in _every_ `RunnableUrl` instance. However, any properties of the `statics` property object **are not** visible to (or editable by) the user. For example, if every request should include a `latency=true` search parameter, in addition to whatever other user-modifications are made, the `statics` object might look like the following example.
62+
63+
```js
64+
const instance = new RunnableUrl({
65+
searchParams: {
66+
foo: 'bar'
67+
},
68+
statics: {
69+
searchParams: {
70+
latency: true
71+
}
72+
}
73+
});
74+
75+
console.log(instance.url);
76+
// returns 'http://127.0.0.1:8080?foo=bar'
77+
// UI shows above URL and allows editing of that URL, without exposing statics.
78+
79+
console.log(RunnableUrl.factory(instance, instance.statics).url);
80+
// returns 'http://127.0.0.1:8080?foo=bar&latency=true'
81+
// Passing statics to temp factory instance allows inclusion of hidden static properties.
82+
```
83+
84+
## Handling Endpoint-Specific User Settings
85+
86+
In many situations the user may need to override a small selection of properties that make up the overall Alpha URL. RunnableUrl intelligently parses and extracts all components of a valid URL and overrides default properties with any matching user-specified properties. However, it is necessary to differentiate between URLs and settings for each of the potential Alpha endpoints (e.g. `/query`, `/mutate`, `/alter`, etc).
87+
88+
RunnableUrl handles this by tracking each Alpha endpoint as a separate instance, each of which is uniquely editable by the user. Therefore, while the default URL for a `query` transaction will post to the `http://127.0.0.1:8080/query` URL, the user can override every component of the `query` URL, including the endpoint/pathname. For example, even if the user updates the `query` URL to `https://example.com:5432/runQuery?name=Alice` RunnableUrl will remember that this URL is associated with `query` transactions and will use this URL for all runnable requests that default to a `/query` endpoint type.
89+
90+
RunnableUrl determines the transaction type of a runnable instance through the Hugo front matter `endpoint` (or `pathName`) property. If the Hugo `endpoint` property is not specified then RunnableUrl assumes and defaults to a `/query` transaction type.
91+
92+
## Retaining User Data via RunnableStorage
93+
94+
The [`RunnableStorage`](./static/js/runnable-url/storage.js) class provides a RunnableUrl instance with helper methods to save and load its data via the browser's [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage).
95+
96+
For example, the `RunnableUrl.save()` method serializes its data to JSON then uses `RunnableStorage` to save it to disk.
97+
98+
```js
99+
// ...
100+
save() {
101+
RunnableStorage.set(
102+
`${this.constructor.name}-${this.pathType}`,
103+
JSON.stringify(this.toJSON())
104+
);
105+
}
106+
// ...
107+
toJSON() {
108+
return {
109+
hash: this.hash,
110+
hostname: this.hostname,
111+
port: this.port,
112+
pathname: this.pathname,
113+
protocol: this.protocol,
114+
search: this.search,
115+
searchParams: this.searchParams,
116+
statics: this.statics
117+
};
118+
}
119+
```
120+
121+
The `static` `RunnableUrl.load()` method retrieves any existing saved data and deserializes it to create a `RunnableUrl` instance from that data.
122+
123+
```js
124+
static load(overrides = {}) {
125+
return new this(
126+
JSON.parse(RunnableStorage.get(this.prototype.constructor.name)),
127+
overrides
128+
);
129+
}
130+
```
131+
132+
This retains state information for all user-defined fields between page loads across the app.
133+
134+
## Interface
135+
136+
The [`runnable.html`](./layouts/partials/runnable.html) partial checks if the `RunnableUrlEnabled` flag is set to `true` in the site config. If so, it includes the [`runnable-url.html`](./layouts/partials/runnable-url.html) partial, otherwise everything is left as default.
137+
138+
```html
139+
{{ if .RunnableUrlEnabled }} {{ partial "runnable-url.html" . }} {{ else }}
140+
<span class="pane-title">
141+
Endpoint: {{ $endpoint }}
142+
</span>
143+
{{ end }}
144+
```
145+
146+
## (Optional) Front Matter Variables
147+
148+
Each individual post or page that uses a Runnable element can also specify optional front matter params to alter the _initial_ properties of the generated Dgraph URL. The following is the list of possible front matter variables that `RunnableUrl` will look for and use.
149+
150+
- `protocol`
151+
- `hostName`
152+
- `port`
153+
- `endpoint` - Retained for backwards compatibility. `endpoint` and `pathName` are interchangeable, so only one must be specified to alter the pathname of the URL.
154+
- `pathName`
155+
- `search`
156+
- `hash`
157+
158+
**Note: User-specified values will always override front matter values.**
159+
160+
For example, here are the default front matter variables for the [https://tour.dgraph.io/intro/3/](https://tour.dgraph.io/intro/3/) page.
161+
162+
```md
163+
+++
164+
date = "2017-04-26T22:28:55+10:00"
165+
next = "/intro/4"
166+
prev = "/intro/2"
167+
title = "Load Schema"
168+
weight = 3
169+
endpoint = "/alter"
170+
+++
171+
```
172+
173+
RunnableUrl will generate the following URL for the `alter` endpoint transaction: `http://127.0.0.1:8080/alter?latency=true`. However, the `static` property includes `searchParams: { latency: true }` by default, which means the URL displayed to the user in the view is: `http://127.0.0.1:8080/alter`.
174+
175+
## Error Handling
176+
177+
While RunnableUrl is enabled a message is appended to the error message indicating to the user that the URL is editable. The RunnableUrl endpoint button is also highlighted via an animation, as seen below.
178+
179+
![RunnableUrl Error Demo](./static/images/runnable-url-error-demo.gif)

themes/hugo-tutorials/layouts/_default/single.html

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,28 +21,30 @@ <h1 class="lesson-heading">{{ .Title }}</h1>
2121

2222
<div class="page-nav">
2323
{{ with .Params.prev }}
24-
<a href="{{ . | relURL }}" data-action="go-prev" class="btn btn-secondary btn-sm page-nav-link"><i class="fa fa-chevron-left"></i></a>
24+
<a href="{{ . | relURL }}" data-action="go-prev" class="btn btn-secondary btn-sm page-nav-link"><i
25+
class="fa fa-chevron-left"></i></a>
2526
{{ end }}
2627
<div class="nav-index">
2728
{{ .File.BaseFileName }} / {{ $numContents }}
2829
</div>
2930
{{ with .Params.next }}
30-
<a href="{{ . | relURL }}" data-action="go-next" class="btn btn-secondary btn-sm page-nav-link"><i class="fa fa-chevron-right"></i></a>
31+
<a href="{{ . | relURL }}" data-action="go-next" class="btn btn-secondary btn-sm page-nav-link"><i
32+
class="fa fa-chevron-right"></i></a>
3133
{{ end }}
3234
</div>
3335
</div>
3436
</div>
3537

3638
<div class="col-12 col-sm-12 col-md-12 col-lg-6 vertical-stretch">
3739
{{ if not (eq $codeContent "")}}
38-
{{ partial "runnable" (dict "Content" . "Code" $codeContent) }}
40+
{{ partial "runnable" (dict "Content" . "Code" $codeContent "RunnableUrlConfig" .Site.Params.RunnableUrl) }}
3941
{{ else }}
40-
<div class="panel empty">
41-
<img src="{{ .Site.BaseURL }}/images/dgraph-black.png" alt="dgraph-icon" class="dgraph-icon" />
42-
</div>
42+
<div class="panel empty">
43+
<img src="{{ .Site.BaseURL }}/images/dgraph-black.png" alt="dgraph-icon" class="dgraph-icon" />
44+
</div>
4345
{{ end }}
4446
</div>
4547
</div>
4648
</div>
4749

48-
{{ partial "footer.html" . }}
50+
{{ partial "footer.html" . }}

themes/hugo-tutorials/layouts/partials/footer.html

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
<script src="{{ .Site.BaseURL }}/js/clipboard.min.js"></script>
44
<script src="{{ .Site.BaseURL }}/js/dgraph.js?{{ now }}"></script>
5-
<script src="{{ .Site.BaseURL }}/js/runnable.js?{{ now }}"></script>
5+
<script type="module" src="{{ .Site.BaseURL }}/js/runnable.js?{{ now }}"></script>
66
<script>
77
hljs.initHighlightingOnLoad();
88
</script>
9-
</body>
10-
</html>
9+
</body>
10+
11+
</html>

0 commit comments

Comments
 (0)