Skip to content

Instantly share code, notes, and snippets.

@mattduffield
Forked from jdanyow/app.html
Last active July 18, 2017 23:08
Show Gist options
  • Select an option

  • Save mattduffield/e72047f61d7d9022763c986683403adf to your computer and use it in GitHub Desktop.

Select an option

Save mattduffield/e72047f61d7d9022763c986683403adf to your computer and use it in GitHub Desktop.
Aurelia TreeView with Blob Storage
<template>
<require from="tree-view"></require>
<h1>${message}</h1>
<!--<ul>-->
<!-- <li repeat.for="user of users">-->
<!-- ${user.login}-->
<!-- </li>-->
<!--</ul>-->
<tree-view items.bind="items"></tree-view>
</template>
import {inject} from 'aurelia-framework';
import {HttpClient} from 'aurelia-fetch-client';
import {AzureBlobStorageConnector} from './azure-blob-storage-connector';
@inject(HttpClient, AzureBlobStorageConnector)
export class App {
message = 'Hello World!';
users = null;
items = [];
constructor(http, blobConnector) {
this.http = http;
this.blobConnector = blobConnector;
http.fetch('https://api.github.com/users')
.then(response => response.json())
.then(users => this.users = users);
this.processBlobs();
}
processBlobs() {
let list = [];
let baseUrl = 'https://fec-functions.azurewebsites.net/api/';
let accountName = '58114358dcba0f01c12cf77a';
let accountKey = 'JlzT0skdhATwj8lAEE2paXlSu+de4Kp8ThCzhcgWYHibBEtiBbP7lnquHatZs+kI1p4LtE/X21Tsf/2ljgySBw==';
this.blobConnector.init(baseUrl, accountName, accountKey);
this.blobConnector.getContainers().then(containers => {
console.log('containers', containers);
if (containers) {
containers.forEach(c => {
let p = {};
p.isRoot = true;
p.id = c.name;
p.name = c.name;
p.title = c.name;
// p.icon = "sitemap";
p.href = "";
p.isOpen = false;
p.isReferenceOpen = false;
p.entityType = "screens";
p.items = [];
this.blobConnector.getBlobs(c.name).then(blobs => {
if (blobs) {
blobs.forEach(b => {
let nameArray = b.name.split('/');
this.processBlob(p, nameArray, b);
});
}
});
list.push(p);
});
this.items = list;
console.log('item', list);
}
});
}
findFolder(parent, name) {
if (parent.name == name) {
return parent;
}
let found = parent.items.find(p => this.findFolder(p, name));
return found;
}
processBlob(parent, nameArray, blob) {
let name = nameArray.shift();
if (nameArray.length === 0) {
let s = this.createBlob(parent, name, blob);
parent.items.push(s);
} else {
let folder = this.findFolder(parent, name);
if (!folder) {
let s = this.createBlob(parent, name, blob);
parent.items.push(s);
this.processBlob(s, nameArray, blob);
} else {
this.processBlob(folder, nameArray, blob);
}
}
}
createBlob(parent, name, blob) {
let s = {};
s.id = `${parent.name}_${name}`;
s.name = name;
s.href = `#/projects/screens/${s.id}`;
s.entityType = 'screens';
// s.selector = ((id) => this.projects.find(r => r.id === id));
s.tags = s.tags || [];
s.items = [];
return s;
}
}
import {HttpClient, json} from 'aurelia-fetch-client';
export class AzureBlobStorageConnector {
constructor() {
this.http = new HttpClient();
}
/**
* This method initializes the connector pasing in
* the baseUrl and apiKey.
* baseUrl: https://fec-functions.azurewebsites.net/api/
*/
init(baseUrl, accountName, accountKey) {
this.baseUrl = baseUrl;
this.accountName = accountName;
this.accountKey = accountKey;
this.configureFetch();
}
/**
* This method configures fetch.
*/
configureFetch() {
this.http.configure(config => {
config
.withBaseUrl(this.baseUrl)
.withDefaults({
headers: {
'Content-Type': 'application/json',
// 'X-Requested-With': 'Fetch'
}
})
.withInterceptor({
request(request) {
// console.log(`Requesting ${request.method} ${request.url}`);
return request; // you can return a modified Request, or you can short-circuit the request
},
response(response) {
// console.log(`Received ${response.status} ${response.url}`);
return response; // you can return a modified Response
}
});
});
}
/**
* The following appends a string to an existing
* blob.
*/
appendBlob(container, fileName, content) {
let data = {
accountName: this.accountName,
accountKey: this.accountKey,
container: container,
fileName: fileName,
content: content
};
return this.http.fetch('appendblob', {
method: 'post',
body: json(data)
})
.then(response => response.json())
.then(data => JSON.parse(data));
}
/**
* The following creates a new blob from a string.
*/
createBlob(container, fileName, content) {
let data = {
accountName: this.accountName,
accountKey: this.accountKey,
container: container,
fileName: fileName,
content: content
};
return this.http.fetch('createblob', {
method: 'post',
body: json(data)
})
.then(response => response.json())
.then(data => JSON.parse(data));
}
/**
* The following deletes a blob.
*/
deleteBlob(container, fileName) {
let data = {
accountName: this.accountName,
accountKey: this.accountKey,
container: container,
fileName: fileName
};
return this.http.fetch('deleteblob', {
method: 'post',
body: json(data)
})
.then(response => response.json())
.then(data => JSON.parse(data));
}
/**
* The following returns a blob as a string.
*/
getBlob(container, fileName) {
let data = {
accountName: this.accountName,
accountKey: this.accountKey,
container: container,
fileName: fileName
};
return this.http.fetch('getblob', {
method: 'post',
body: json(data)
})
.then(response => response.json())
.then(data => JSON.parse(data));
}
/**
* The following lists all blobs within a container.
*/
getBlobs(container) {
let data = {
accountName: this.accountName,
accountKey: this.accountKey,
container: container
};
return this.http.fetch('getblobs', {
method: 'post',
body: json(data)
})
.then(response => response.json())
.then(data => JSON.parse(data));
}
/**
* The following lists all containers for an account.
*/
getContainers() {
let data = {
accountName: this.accountName,
accountKey: this.accountKey
};
return this.http.fetch('getcontainers', {
method: 'post',
body: json(data)
})
.then(response => response.json())
.then(data => JSON.parse(data));
}
}
<!doctype html>
<html>
<head>
<title>Aurelia</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
</head>
<body aurelia-app>
<h1>Loading...</h1>
<script src="https://jdanyow.github.io/rjs-bundle/node_modules/requirejs/require.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/config.js"></script>
<script>
require.config({
paths: {
"aurelia-fetch-client": "https://jdanyow.github.io/rjs-bundle/node_modules/aurelia-fetch-client/dist/amd/aurelia-fetch-client"
}
})
</script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/aurelia.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/babel.js"></script>
<script>
require(['aurelia-bootstrapper']);
</script>
</body>
</html>
.user-select-none {
user-select: none;
}
.list-none {
list-style-type: none;
margin: 0;
padding: 0;
padding: 2px 0;
padding-left: 15px;
}
.no-events {
user-select: none;
pointer-events: none;
}
.tree-view input[type="checkbox"] {
position: absolute;
left: -9999px;
}
.tree-view input[type="checkbox"] ~ tree-view > ul {
height: 0;
transform: scaleY(0);
}
.tree-view input[type="checkbox"]:checked ~ tree-view > ul {
height: 100%;
transform-origin: top;
transition: transform .2 ease-out;
transform: scaleY(1);
}
.tree-view li {
position: relative;
}
.tree-view li:not(.is-folder):hover > label{
background-color: blue;
color: white;
cursor: pointer;
}
.tree-view li.is-folder,
.tree-view li.is-folder:hover > label {
cursor: pointer;
}
<template>
<require from="./tree-view.css"></require>
<ul class="list-none tree-view">
<li repeat.for="item of items"
class="${item.items.length > 0 ? 'is-folder' : ''}">
<label for="${item.id}">
<i if.bind="item.items.length > 0"
class="fa fa-${item.isOpen ? 'folder-open' : 'folder'}"></i>
${item.name}
</label>
<input if.bind="item.items.length > 0"
type="checkbox"
id="${item.id}"
checked.bind="item.isOpen">
<tree-view if.bind="item.items.length > 0"
items.bind="item.items">
</tree-view>
</li>
</ul>
</template>
import {bindable} from 'aurelia-framework';
export class TreeView {
@bindable items = [];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment