forked from root/public
lee
4 years ago
5 changed files with 102 additions and 492 deletions
@ -1,119 +1,37 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<title>Graphql Doc</title> |
||||
<meta charset="utf-8"> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> |
||||
<style> |
||||
|
||||
:root { |
||||
--color: hsl(0, 0%, 65%); |
||||
} |
||||
|
||||
* { |
||||
box-sizing: border-box; |
||||
} |
||||
|
||||
body { |
||||
background: hsl(0, 0%, 16%); |
||||
font-family: sans-serif; |
||||
letter-spacing: 1.5px; |
||||
display: flex; |
||||
flex-wrap: wrap; |
||||
justify-content: center; |
||||
align-content: center; |
||||
width: inherit; |
||||
height: inherit; |
||||
padding: 5rem; |
||||
font-size: 12px; |
||||
} |
||||
|
||||
input { |
||||
border: none; |
||||
position: absolute; |
||||
margin: 6px 24px 8px 15px; |
||||
background: rgba(255, 255, 255, 0); |
||||
border-bottom: 1px solid var(--color); |
||||
outline: none; |
||||
} |
||||
|
||||
.docExplorerWrap { |
||||
position: inherit; |
||||
width: 80%; |
||||
height: 100%; |
||||
top: 50%; |
||||
left: 50%; |
||||
background-color: hsl(0, 1%, 35%); |
||||
} |
||||
|
||||
.doc-title, .doc-explore-content { |
||||
padding: 10px; |
||||
margin: 10px; |
||||
align-content: center; |
||||
border-bottom: 1px solid var(--color); |
||||
} |
||||
|
||||
.doc-title { |
||||
display: flex; |
||||
} |
||||
|
||||
.back { |
||||
width: 50px; |
||||
height: 50px; |
||||
} |
||||
|
||||
h3, h4, li { |
||||
font-weight: 300; |
||||
width: 100%; |
||||
margin: 15px; |
||||
} |
||||
|
||||
h3 { |
||||
font-size: 1.25rem; |
||||
} |
||||
|
||||
h4 { |
||||
font-size: 0.8rem; |
||||
white-space: pre; |
||||
} |
||||
|
||||
b { |
||||
padding: 4px; |
||||
border-bottom: 1px solid var(--color); |
||||
} |
||||
|
||||
a { |
||||
color:lightcoral; |
||||
} |
||||
|
||||
a:hover { |
||||
text-decoration: underline; |
||||
cursor: pointer; |
||||
} |
||||
|
||||
img { |
||||
cursor: pointer; |
||||
width: 30px; |
||||
height: 30px; |
||||
} |
||||
|
||||
</style> |
||||
</head> |
||||
<body> |
||||
<script type="module" src="./lib/schema.js"></script> |
||||
<div class="docExplorerWrap"> |
||||
<div class="doc-title"><h3 class="title">Schema Documentation</h3></div> |
||||
<div class="doc-explore-content"> |
||||
<label class="search-box"> |
||||
<img src="https://cdn1.iconfinder.com/data/icons/thin-ui-1/100/Noun_Project_100Icon_1px_grid_thin_ic_cookie-512.png"> |
||||
<input class="search" type="text" placeholder="Search Schema..."> |
||||
</label> |
||||
<div class="doc-type-description"> <h4 class="comment">A Graphql schema provides a root type for each kind of operation</h4><!-- description of... --></div> |
||||
<br> |
||||
<div class="doc-category"><h4><b class="doc-type">ROOT TYPES</b></h4></div> |
||||
<br> |
||||
<div class="display-doc"></h4></div> |
||||
</div> |
||||
</div> |
||||
</body> |
||||
</html> |
||||
<head> |
||||
<title>Simple GraphiQL Example</title> |
||||
<link href="https://unpkg.com/graphiql/graphiql.min.css" rel="stylesheet" /> |
||||
</head> |
||||
<body style="margin: 0;"> |
||||
<div id="graphiql" style="height: 100vh;"></div> |
||||
|
||||
<script |
||||
crossorigin |
||||
src="https://unpkg.com/react/umd/react.production.min.js" |
||||
></script> |
||||
<script |
||||
crossorigin |
||||
src="https://unpkg.com/react-dom/umd/react-dom.production.min.js" |
||||
></script> |
||||
<script |
||||
crossorigin |
||||
src="https://unpkg.com/graphiql/graphiql.min.js" |
||||
></script> |
||||
|
||||
<script> |
||||
const graphQLFetcher = graphQLParams => |
||||
fetch(`https://${location.hostname}/api/graphql-engine/v1/graphql`, { |
||||
method: 'post', |
||||
headers: { 'Content-Type': 'application/json' }, |
||||
body: JSON.stringify(graphQLParams), |
||||
}) |
||||
.then(response => response.json()) |
||||
.catch(() => response.text()); |
||||
ReactDOM.render( |
||||
React.createElement(GraphiQL, { fetcher: graphQLFetcher }), |
||||
document.getElementById('graphiql'), |
||||
); |
||||
</script> |
||||
</body> |
||||
</html> |
@ -1,163 +0,0 @@
|
||||
const backImg = |
||||
'https://cdn1.iconfinder.com/data/icons/thin-ui-1/100/Noun_Project_100Icon_1px_grid_thin_ic_arrow_left_simple-512.png' |
||||
const body = document.body |
||||
const docDisplay = document.querySelector('.display-doc') |
||||
const exist = () => document.querySelector('.back') |
||||
const removeComments = (obj) => |
||||
Object.fromEntries(obj.filter((v) => v[0] !== 'comment')) |
||||
|
||||
const getData = async (pathToFile) => { |
||||
const data = await fetch(pathToFile) |
||||
.then((data) => data.json()) |
||||
.catch(console.log) |
||||
return data |
||||
} |
||||
|
||||
const generateLinks = (k, v) => { |
||||
const h4 = document.createElement('h4') |
||||
const a = document.createElement('a') |
||||
a.innerText = v |
||||
h4.innerHTML = k |
||||
h4.appendChild(a) |
||||
docDisplay.appendChild(h4) |
||||
return a |
||||
} |
||||
|
||||
const generateAllQueries = (data) => { |
||||
const docTitle = document.querySelector('.doc-title') |
||||
docDisplay.innerHTML = '' |
||||
const back = backArrow() |
||||
docTitle.appendChild(back) |
||||
for (let obj of data.types) { |
||||
for (const [k, _] of Object.entries(removeComments(Object.entries(obj)))) { |
||||
generateContent(k, obj) |
||||
} |
||||
} |
||||
} |
||||
|
||||
const loadRootTypes = async () => { |
||||
const data = await getData('./lib/schema.json') |
||||
for (let v of data.root_types) { |
||||
const h4 = document.createElement('h4') |
||||
const a = document.createElement('a') |
||||
a.addEventListener('click', (event) => changeContent(event, data)) |
||||
|
||||
for (const [k, value] of Object.entries(v)) { |
||||
a.innerText = value |
||||
h4.innerHTML = `${k}: ` |
||||
h4.appendChild(a) |
||||
docDisplay.appendChild(h4) |
||||
} |
||||
} |
||||
const a = generateLinks('all: ', 'all_available_queries') |
||||
a.addEventListener('click', () => generateAllQueries(data)) |
||||
} |
||||
|
||||
const generateContent = (t, data) => { |
||||
docDisplay.innerHTML += `type ${t.toUpperCase()} {` |
||||
for (const [k, v] of Object.entries(data[t])) { |
||||
generateLinks(` ${k}: `, v) |
||||
} |
||||
docDisplay.innerHTML += `}<br><br>` |
||||
if (t === 'query') { |
||||
for (let v of document.getElementsByTagName('a')) { |
||||
v.addEventListener('click', (e) => changeContent(e, data)) |
||||
} |
||||
} |
||||
} |
||||
|
||||
const backArrow = () => { |
||||
const title = document.querySelector('.title') |
||||
const typeDescription = document.querySelector('.comment') |
||||
const contType = document.querySelector('.doc-type') |
||||
const origType = contType.innerText |
||||
const origTitle = title.innerText |
||||
const origTypeDescription = typeDescription.innerText |
||||
const back = document.createElement('img') |
||||
back.className = 'back' |
||||
back.src = backImg |
||||
|
||||
back.addEventListener('click', () => { |
||||
back.remove() |
||||
docDisplay.innerHTML = '' |
||||
title.innerText = origTitle |
||||
contType.innerText = origType |
||||
typeDescription.innerText = origTypeDescription |
||||
loadRootTypes() |
||||
}) |
||||
return back |
||||
} |
||||
|
||||
const allArgs = (data) => { |
||||
for (const [k, v] of Object.entries(data.arguments)) { |
||||
docDisplay.innerHTML += `<hr><h4><b>${k}</b>: <a>(${v.description})</a> // ${v.comment}</h4>Expressions:<br>` |
||||
for (const exp of v.expressions) { |
||||
docDisplay.innerHTML += `<h4>${exp}</h4>` |
||||
} |
||||
docDisplay.innerHTML += `<a>Example: </a><h4>${v.example}</h4><br><br>` |
||||
} |
||||
} |
||||
|
||||
const changeContent = ({ target }, data) => { |
||||
const title = document.querySelector('.title') |
||||
const typeDescription = document.querySelector('.comment') |
||||
const contType = document.querySelector('.doc-type') |
||||
const docTitle = document.querySelector('.doc-title') |
||||
|
||||
const t = target.innerText |
||||
const back = backArrow() |
||||
|
||||
title.innerText = t.toUpperCase() |
||||
contType.innerText = `${t.toUpperCase()} fields` |
||||
docDisplay.innerHTML = '' |
||||
if (/\[\w*\!\]\!/g.test(t)) { |
||||
const b = t.replace(/\[|\]|\!/g, '') |
||||
const obj = data.types.filter((v) => v[b])[0] |
||||
typeDescription.innerText = obj.comment |
||||
generateContent(b, obj) |
||||
} else if (t === 'arguments') { |
||||
allArgs(data) |
||||
!exist() && docTitle.appendChild(back) |
||||
} else { |
||||
generateContent(t, data) |
||||
!exist() && docTitle.appendChild(back) |
||||
} |
||||
} |
||||
|
||||
loadRootTypes() |
||||
|
||||
/* search */ |
||||
const updateResult = (dataToSearch, { target }) => { |
||||
docDisplay.innerHTML = '' |
||||
|
||||
dataToSearch.search.map((type) => |
||||
target.value.split(' ').map((w) => { |
||||
if (type.toLowerCase().indexOf(w.toLowerCase()) !== -1) { |
||||
docDisplay.innerHTML += `<li><a class="query-result">${type}</a></li>` |
||||
document |
||||
.querySelectorAll('.query-result') |
||||
.forEach((ele) => |
||||
ele.addEventListener('click', (e) => changeContent(e, dataToSearch)) |
||||
) |
||||
} |
||||
}) |
||||
) |
||||
} |
||||
|
||||
const initSearch = async () => { |
||||
const data = await getData('./lib/schema.json') |
||||
const input = document.querySelector('.search') |
||||
|
||||
input.addEventListener('focus', () => { |
||||
const bg = document.querySelector('.back') |
||||
if (!bg) { |
||||
const back = backArrow() |
||||
document.querySelector('.doc-title').appendChild(back) |
||||
} |
||||
docDisplay.innerHTML = '' |
||||
}) |
||||
input.oninput = (e) => updateResult(data, e) |
||||
} |
||||
|
||||
initSearch() |
||||
/*--------------*/ |
@ -1,136 +0,0 @@
|
||||
{ |
||||
"search": [ |
||||
"[user!]!", |
||||
"[object!]!", |
||||
"[transaction!]!", |
||||
"[progress_view!]!", |
||||
"[result!]!", |
||||
"query", |
||||
"arguments" |
||||
], |
||||
"root_types": [{ "query": "query" }, { "arguments": "arguments" }], |
||||
"query": { |
||||
"user": "[user!]!", |
||||
"object": "[object!]!", |
||||
"transaction": "[transaction!]!", |
||||
"progress_view": "[progress_view!]!", |
||||
"result": "[result!]!" |
||||
}, |
||||
"types": [ |
||||
{ |
||||
"user": { |
||||
"id": "ID!", |
||||
"attrs": "Jsonb!", |
||||
"createdAt": "String!", |
||||
"discordDMChannelId": "String!", |
||||
"discordId": "String!", |
||||
"discordLogin": "String!", |
||||
"githubId": "String!", |
||||
"githubLogin": "String!", |
||||
"profile": "Jsonb!", |
||||
"updatedAt": "String!" |
||||
}, |
||||
"comment": "Fetch data from the table: \"user\"\nThis table will have information about the user" |
||||
}, |
||||
{ |
||||
"object": { |
||||
"id": "ID!", |
||||
"attrs": "Jsonb!", |
||||
"authorId": "String!", |
||||
"childrenAttrs": "String!", |
||||
"createdAt": "String!", |
||||
"externalRelationUrl": "String!", |
||||
"name": "String!", |
||||
"type": "String!", |
||||
"status": "String!", |
||||
"updatedAt": "String!" |
||||
}, |
||||
"comment": "Fetch data from the table: \"object\"\nThis table will give you information about all objects (exercises/projects)" |
||||
}, |
||||
{ |
||||
"transaction": { |
||||
"id": "ID!", |
||||
"attrs": "Jsonb!", |
||||
"amount": "Int!", |
||||
"createdAt": "String!", |
||||
"type": "String!", |
||||
"userId": "Int!" |
||||
}, |
||||
"comment": "Fetch data from the table: \"transaction\"\nThis table will give you access to XP and audits ratio" |
||||
}, |
||||
{ |
||||
"progress_view": { |
||||
"id": "ID!", |
||||
"attrs": "Jsonb!", |
||||
"bestResultId": "Int!", |
||||
"createdAt": "String!", |
||||
"eventId": "Int!", |
||||
"groupId": "Int!", |
||||
"objectId": "Int!", |
||||
"updatedAt": "String!", |
||||
"userId": "Int!" |
||||
}, |
||||
"comment": "Fetch data from the table: \"progress\"\nBoth progress and result table will give you the student progression" |
||||
}, |
||||
{ |
||||
"result": { |
||||
"id": "ID!", |
||||
"progressId": "Int!", |
||||
"attrs": "Jsonb!", |
||||
"createdAt": "String!", |
||||
"grade": "Int!", |
||||
"updatedAt": "String!" |
||||
}, |
||||
"comment": "Fetch data from the table: \"result\"\nBoth progress and result table will give you the student progression" |
||||
} |
||||
], |
||||
"arguments": { |
||||
"where": { |
||||
"description": "bool_exp", |
||||
"expressions": [ |
||||
"_eq (equal)", |
||||
"_gt (grater then)", |
||||
"_gte (grater then equal)", |
||||
"_in (in)", |
||||
"_is_null (boolean)", |
||||
"_lt (lower then)", |
||||
"_lte (lower then equal)", |
||||
"_neq (not equal)", |
||||
"_nin (not in)" |
||||
], |
||||
"example": "user(where: {id: { _eq: x } }){\n id \n}", |
||||
"comment": "filter the rows returned" |
||||
}, |
||||
"order_by": { |
||||
"description": "[order_by!]", |
||||
"expressions": [ |
||||
"asc (ascending)", |
||||
"asc_nulls_first", |
||||
"asc_nulls_last", |
||||
"desc (descending)", |
||||
"desc_nulls_first", |
||||
"asc_nulls_last" |
||||
], |
||||
"example": "user(order_by: {id: desc }){\n id \n}", |
||||
"comment": "sort the rows by one or more columns" |
||||
}, |
||||
"limit": { |
||||
"description": "Int", |
||||
"expressions": ["Int"], |
||||
"example": "user(limit: 1 ){\n id \n}", |
||||
"comment": "limit the number of rows returned" |
||||
}, |
||||
"distinct_on": { |
||||
"description": "column name", |
||||
"expressions": ["column name"], |
||||
"example": "object(distinct_on: name, where: { name:{ _eq:\"forum\" } }){\n name \n}", |
||||
"comment": "distinct select on columns" |
||||
}, |
||||
"offset": { |
||||
"description": "int", |
||||
"expressions": ["Int"], |
||||
"example": "object(distinct_on: name, where: { name:{ _eq:\"forum\" } }){\n name\n }", |
||||
"comment": "skip the first n rows by one or more columns" |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue