Skip to content

Commit 6e26098

Browse files
committed
container
1 parent e0dd9f9 commit 6e26098

37 files changed

Lines changed: 319 additions & 53 deletions

dashboard/test.html

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
style="margin-top:3rem;height:calc( 100vh - 5rem )"
66
></sol-container>
77

8-
<!--
98
<sol-include type=markdown source="../drafts/notes.md"></sol-include>
109

1110
<sol-page
@@ -14,18 +13,24 @@
1413
template="container"
1514
></sol-page>
1615

17-
18-
-->
1916
<style>
2017
* { font-size:18px; }
2118
p,h2,h3,li,ul { margin:0; }
2219
h2,h3 { margin-top:0.5rem; }
2320
h2 { margin-left:1rem; }
2421
h3 { margin-left:2rem; }
2522
ul { margin-left:3rem; }
23+
textarea {
24+
max-width:100% !important;
25+
min-width:40rem !important;
26+
width:40rem;
27+
// display:table-cell !important;
28+
}
29+
2630
</style>
2731
<!-- <link href="../sol-core.css" rel="stylesheet" /> -->
28-
<script src="https://cdn.jsdelivr.net/npm/solid-ui@2.4.33-alpha/dist/solid-ui.min.js" type="module">
32+
33+
<script src="https://cdn.jsdelivr.net/npm/mashlib@1.8.10/dist/mashlib.min.js" type="module">
2934
</script>
3035
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.0.9/dist/purify.min.js" type="module">
3136
</script>

dashboard/themes/sidebar-left.html

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<div class="sol-header">
2+
<span class="sol-sidebarButton" style="font-weight:900;font-size:43px;cursor:pointer;"
3+
onclick="this.parentNode.parentNode.querySelector('.sol-main').classList.toggle('hidden')";
4+
>&equiv;</span>
5+
</div>
6+
<div class="sol-main">
7+
<div class="sol-sidebar"></div>
8+
<div class="sol-display"></div>
9+
</div>
10+
<div class="sol-footer"></div>
11+
12+
<style>
13+
/* COLORS */
14+
.sol-page { background:#111122;}
15+
.sol-display { padding:1rem; padding-top:0.75rem; }
16+
/* POSITIONING */
17+
body { margin:0; }
18+
.sol-page { margin:0; height:100%; display:grid; grid-template-rows: 3rem auto 2rem ; }
19+
.sol-main { display:grid;grid-template-columns:19rem auto; height:calc( 100% - 3rem ); }
20+
.sol-main.hidden { grid-template-columns:auto !important; }
21+
.sol-main.hidden .sol-sidebar { display:none !important; }
22+
.sol-main.hidden .sol-display { padding-left:1rem; }
23+
.sol-sidebarButton { margin-left:1rem; }
24+
.sol-sidebar { padding:0.75rem; }
25+
.sol-display { padding:1rem; padding-left:0; }
26+
.sol-footer { height:100%; padding:0.25rem; }
27+
/* OVERFLOW */
28+
body, .sol-page { overflow:hidden; }
29+
.sol-sidebar, .sol-display { overflow:auto; }
30+
31+
.formFieldName * {
32+
color: wheat !important;
33+
}
34+
</style>
35+

dashboard/themes/single-sidebar.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<div class="sol-header">
22
<span class="sol-sidebarButton" style="font-weight:900;font-size:43px;cursor:pointer;"
3-
onclick="this.closest('.sol-page').querySelector('.sol-main').classList.toggle('hidden')";
3+
onclick="this.parentNode.parentNode.querySelector('.sol-main').classList.toggle('hidden')";
44
>&equiv;</span>
55
</div>
66
<div class="sol-main">
@@ -15,10 +15,10 @@
1515
.sol-display { padding:1rem; padding-top:0.75rem; }
1616
/* POSITIONING */
1717
body { margin:0; }
18-
.sol-page { margin:0; height:100%; display:grid; grid-template-rows: 3rem auto 2rem ; }
18+
.sol-page { margin:0; height:100%; display:grid; grid-template-rows: 3rem auto 2rem ; }
1919
.sol-main { display:grid;grid-template-columns:19rem auto; height:calc( 100% - 3rem ); }
2020
.sol-main.hidden { grid-template-columns:auto !important; }
21-
.sol-main.hidden .sol-sidebar { display:none; }
21+
.sol-main.hidden .sol-sidebar { display:none !important; }
2222
.sol-main.hidden .sol-display { padding-left:1rem; }
2323
.sol-sidebarButton { margin-left:1rem; }
2424
.sol-sidebar { padding:0.75rem; }

icons

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
<img src='object camera photo picture film alt.svg'>
3+
<img src='object search search find magnify magnifying .svg'>
4+
<img src='object wrench.svg'>
5+
<img src='symbol audio sound volume music.svg'>
6+
<img src='symbol cross delete remove multiply.svg'>
7+
<img src='symbol external share link outside.svg'>
8+
<img src='symbol file document .txt text.svg'>
9+
<img src='symbol folder.svg'>
10+
<img src='symbol gear settings preferences.svg'>
11+
<img src='symbol hospital.svg'>
12+
<img src='symbol left chevron chevron left direction.svg'>
13+
<img src='symbol note music crotchet quaver quarter note.svg'>
14+
<img src='symbol plus add addition maths operators.svg'>
15+
<img src='symbol right chevron chevron right direction.svg'>
16+
<img src='symbol toggle adjust.svg'>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "solid-web-components",
3-
"version": "1.0.4",
3+
"version": "1.0.5",
44
"description": "access Solid & linked-data resources using no-code HTML components",
55
"type": "module",
66
"main": "sol-core.js",

sol-core.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
const host = "http://localhost:8444";
2+
window.SolidAppContext = {
3+
noAuth : host,
4+
webId : host + "/profile/card#me",
5+
app : host,
6+
webid : host + "/profile/card#me",
7+
scroll : 130 // for eyeFocus, should be height of top banner
8+
}
9+
window.$SolidTestEnvironment = {
10+
iconBase : "/common/icons/",
11+
originalIconBase : "/common/originalIcons/",
12+
}
13+
114
/*
215
all components use the same constructor & connectedCallback
316
see the processCustomElement in libs/controller.js

src/sol-container.js

Lines changed: 66 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,130 @@
1-
import {getDefaults} from './utils.js';
2-
import {isoDoc} from './isomorphic.js';
3-
import {bestLabel} from './model-rdf.js';
1+
import { getDefaults } from './utils.js';
2+
import { isoDoc } from './isomorphic.js';
3+
import { insertSolidosOutliner,solidosShow } from './view-solidos.js';
4+
import { makePage } from './sol-page.js';
5+
import { fetchNonRdfData } from './model.js';
6+
import { bestLabel } from './model-rdf.js';
47
import { registerView } from './controller.js';
5-
import {fetchNonRdfData} from './model.js';
8+
import { sidebarLeftTheme } from '../themes/sidebar-left.js';
69

710
registerView({
8-
actions: {containerClick}
11+
actions: {fileClick,folderClick,toggleHiddenClick}
912
});
1013

1114
export class SolContainer extends HTMLElement {
1215
constructor() {
1316
super();
1417
}
1518
async connectedCallback(){
16-
let element = await getDefaults(this)
17-
await container(element);
19+
await getDefaults(this)
20+
await prepContainerWrapper(this);
1821
}
1922
}
2023
customElements.define("sol-container",SolContainer);
2124

2225

23-
async function container(element){
24-
// let themeString = await fetchNonRdfData({source:'this.theme,type:'component'});
25-
let url = element.source;
26+
async function prepContainerWrapper(element){
27+
element.themeString = sidebarLeftTheme ;
28+
await makePage(element)
29+
let header = element.querySelector('.sol-header');
30+
header.innerHTML += `<a href="#" onclick="solrun(event,'toggleHiddenClick')" class="sol-icon">H</a>`;
31+
insertSolidosOutliner(element.querySelector('.sol-display'));
32+
await fillContainerWrapper(element);
33+
}
34+
async function fillContainerWrapper(element){
35+
let showHidden = element.classList.contains('showHidden');
36+
let url = element.source || element.getAttribute('source');
2637
let results = {
2738
files : "",
2839
folders : "",
2940
};
3041
const node = UI.rdf.sym(url);
42+
let parentDir = url.replace(/[^\/]+\/$/,'/').replace(/\/\/$/,'/');
43+
if( (parentDir.split('/').length)==3 ) parentDir=null;
3144
try {
3245
await UI.store.fetcher.load(node.doc(),{headers:{Accept:"text/turtle"}});
3346
}
3447
catch(e){console.log(e)}
35-
let resources = UI.store.match( node, UI.ns.ldp('contains') );
3648
let s = "display:block; text-decoration:none;height:1rem;"
49+
let resources = UI.store.match( node, UI.ns.ldp('contains') );
50+
let folderIcon = `<img src="./assets/folder.png" style="height:1rem;">`;
3751
for(let resource of resources){
38-
let label = bestLabel(resource.object);
3952
let link = resource.object.value;
53+
let label = bestLabel(resource.object);
54+
if( !showHidden ){
55+
if(label.startsWith('.')) continue;
56+
if(label.startsWith('#')) continue;
57+
if(label.endsWith('#')) continue;
58+
if(label.endsWith('~')) continue;
59+
if(label.endsWith('.part')) continue;
60+
}
4061
let isContainer = link.endsWith('/');
4162
if(isContainer) {
4263
label = label.replace(/^.*\//,'').replace(/\/$/,'');
43-
label = `<img src="./assets/folder.png" style="height:1rem;"> ${label}`
44-
results.folders += `<a href="${link}" onclick="solrun(event,'containerClick')" style="${s}">${label}</a>`;
64+
label = `${folderIcon} ${label}`
65+
results.folders += `<a href="${link}" onclick="solrun(event,'folderClick')" style="${s}">${label}</a>`;
4566

4667
}
4768
else{
4869
let types = UI.store.match(resource.subject,UI.ns.rdf('type'));
4970
let type=getMimeType(link);
50-
label = `<img src="./assets/document.png" style="height:1rem;"> ${label}`
51-
results.files += `<a href="${link}" onclick="solRun(event,'fileClick')" data-type="${type}" style="${s}">${label}</a>`;
71+
label = `<span style="white-space:nowrap" title="${label}"><img src="./assets/document.png" style="height:1rem;"> ${label}</span>`
72+
results.files += `<a href="${link}" onclick="solrun(event,'fileClick')" data-type="${type}" style="${s}">${label}</a>`;
5273
}
5374
}
5475
let headerArea = isoDoc.createElement('DIV');
5576
let folderArea = isoDoc.createElement('DIV');
5677
let fileArea = isoDoc.createElement('DIV');
5778
let displayArea = isoDoc.createElement('DIV');
58-
element.classList.add('sol-container');
59-
element.appendChild(headerArea);
60-
element.appendChild(folderArea);
61-
element.appendChild(fileArea);
79+
let sidebar = element.querySelector('.sol-sidebar') || element.closest('.sol-container').querySelector('.sol-sidebar');
80+
81+
if(parentDir) results.folders =`<a href="${parentDir}" onclick="solrun(event,'folderClick')" style="${s}">${folderIcon} ..</a>` + results.folders;
82+
6283
headerArea.innerHTML = element.source;
6384
folderArea.innerHTML = results.folders;
6485
fileArea.innerHTML = results.files;
65-
/* styles */
66-
element.style.width = "17rem";
86+
sidebar.innerHTML = "";
87+
sidebar.classList.add('sol-container-sidebar');
88+
sidebar.appendChild(headerArea);
89+
sidebar.appendChild(folderArea);
90+
sidebar.appendChild(fileArea);
91+
92+
sidebar.style.width = "17rem";
93+
sidebar.style.display = "block";
94+
sidebar.style['overflow-y']="hidden"
6795
folderArea.style['margin-bottom']="1rem"
6896
folderArea.style.height="30%"
69-
fileArea.style.height="calc( 70% - 3rem )"
97+
fileArea.style.height="calc( 70% - 2rem )"
7098
fileArea.style.overflow="auto"
7199
folderArea.style.overflow="auto"
72100
folderArea.style.backgroundColor="#eeeeee"
73101
fileArea.style.backgroundColor="#eeeeee"
74102
folderArea.style['border-radius']="0.3rem"
75103
fileArea.style['border-radius']="0.3rem"
76-
element.style.display = "block";
77104
}
78105

79-
async function containerClick(clickedElement){
106+
async function fileClick(clickedElement){
107+
const display = clickedElement.closest('.sol-container').querySelector('.sol-display');
108+
let source = clickedElement.href || clickedElement.parentNode.href;
109+
solidosShow(source,display);
110+
}
111+
async function folderClick(clickedElement){
112+
const element = clickedElement.closest('.sol-container');
113+
element.source = clickedElement.getAttribute('href');
114+
fillContainerWrapper(element);
115+
}
116+
async function toggleHiddenClick(clickedElement){
117+
const element = clickedElement.closest('.sol-container');
118+
element.classList.toggle('showHidden');
119+
fillContainerWrapper(element);
80120
}
81121

82122
function getMimeType(link){
83123
// TBD use mime library
84124
let ext = link.replace(/[^\.]+\./,'');
85125
if(ext=='ttl') return 'text/turtle';
86126
if(ext=='html') return 'text/html';
127+
if(ext=='txt') return 'text/plain';
87128
return ext;
88129
}
89130

src/sol-page.js

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,6 @@ import {rel2absIRI} from './utils.js';
22
import {fetchNonRdfData} from './model.js';
33
import { isoDoc,domFromContent } from "./isomorphic.js";
44

5-
export class SolPage extends HTMLElement {
6-
constructor() {
7-
super();
8-
}
9-
async connectedCallback(){
10-
await attrs2props(this);
11-
let themeString = await fetchNonRdfData({source:this.theme,type:'component'});
12-
let themeDom = await domFromContent(themeString);
13-
let components = themeDom.querySelectorAll('[class^="sol-"]')
14-
for(let component of components){
15-
let areaClass = component.getAttribute('class')
16-
let area = themeDom.querySelector('.'+areaClass);
17-
areaClass = component.getAttribute('class').replace(/^sol-/,'');
18-
if( area && this[areaClass] ){
19-
area.innerHTML = await fetchNonRdfData({ source:this[areaClass], type:'component' });
20-
}
21-
}
22-
this.innerHTML = themeDom.body.innerHTML;
23-
}
24-
}
255
/*
266
<sol-page
277
theme = "./themes/single-sidebar.html"
@@ -31,6 +11,31 @@ export class SolPage extends HTMLElement {
3111
footer = "./snippets/dashboard-footer.html"
3212
></sol-page>
3313
*/
14+
15+
export class SolPage extends HTMLElement {
16+
constructor() {
17+
super();
18+
}
19+
async connectedCallback(){
20+
await makePage(this);
21+
}
22+
}
23+
export async function makePage(element){
24+
await attrs2props(element);
25+
let themeString = element.themeString || await fetchNonRdfData({source:element.theme,type:'component'});
26+
let themeDom = await domFromContent(themeString);
27+
let components = themeDom.querySelectorAll('[class^="sol-"]')
28+
for(let component of components){
29+
let areaClass = component.getAttribute('class')
30+
let area = themeDom.querySelector('.'+areaClass);
31+
areaClass = component.getAttribute('class').replace(/^sol-/,'');
32+
if( area && element[areaClass] ){
33+
area.innerHTML = await fetchNonRdfData({ source:element[areaClass], type:'component' });
34+
}
35+
}
36+
element.innerHTML = themeDom.body.innerHTML;
37+
return element;
38+
}
3439
async function attrs2props(element){
3540
for (let attr of element.attributes) {
3641
element[attr.name] = await rel2absIRI(attr.value);

0 commit comments

Comments
 (0)