Added tabs
5
lnbits/extensions/example/crud.py
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
# crud.py is for communication with your extensions database
|
||||||
|
|
||||||
|
# add your dependencies here
|
||||||
|
|
||||||
|
# add your fnctions here
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
# migrations.py is for building your database
|
||||||
|
|
||||||
# async def m001_initial(db):
|
# async def m001_initial(db):
|
||||||
# await db.execute(
|
# await db.execute(
|
||||||
# f"""
|
# f"""
|
||||||
|
|
|
||||||
BIN
lnbits/extensions/example/static/fastapi-framework.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
lnbits/extensions/example/static/fastapilogo.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
lnbits/extensions/example/static/quasar-example.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
lnbits/extensions/example/static/quasar-framework.png
Normal file
|
After Width: | Height: | Size: 2 KiB |
BIN
lnbits/extensions/example/static/quasarlogo.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
lnbits/extensions/example/static/script-example.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
lnbits/extensions/example/static/vif-example.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
lnbits/extensions/example/static/vuejs-framework.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
lnbits/extensions/example/static/vuejslogo.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
|
|
@ -1,58 +1,212 @@
|
||||||
{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
|
{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
|
||||||
%} {% block page %}
|
%} {% block page %}
|
||||||
<q-card>
|
|
||||||
|
<q-dialog v-model="thingDialog.show" position="top">
|
||||||
|
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
||||||
|
<q-form @submit="sendThingDialog" class="q-gutter-md">
|
||||||
|
<q-input filled dense v-model.trim="thingDialog.data.name" type="text" label="Name *"></q-input>
|
||||||
|
<q-input filled dense v-model.trim="thingDialog.data.email" type="email" label="Name *"></q-input>
|
||||||
|
<q-select filled dense emit-value v-model="thingDialog.data.wallet" :options="g.user.walletOptions" label="Wallet *"></q-select>
|
||||||
|
<div class="row q-mt-lg">
|
||||||
|
<q-btn v-if="thingDialog.data.id" unelevated color="primary" type="submit">Update thing</q-btn>
|
||||||
|
<q-btn v-else unelevated color="primary" :disable="thingDialog.data.name == null" type="submit">Create thing</q-btn>
|
||||||
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Cancel</q-btn>
|
||||||
|
</div>
|
||||||
|
</q-form>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
|
|
||||||
|
<q-card flat>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<h5 class="text-subtitle1 q-mt-none q-mb-md">
|
<div class="text-h5 q-mb-md">
|
||||||
Frameworks used by {{SITE_TITLE}}
|
{{SITE_TITLE}} Extension Development Guide
|
||||||
</h5>
|
</div>
|
||||||
<q-list>
|
|
||||||
<q-item
|
<q-card unelevated flat>
|
||||||
v-for="tool in tools"
|
<q-tabs
|
||||||
:key="tool.name"
|
v-model="tab"
|
||||||
tag="a"
|
dense
|
||||||
:href="tool.url"
|
class="text-grey"
|
||||||
target="_blank"
|
active-color="primary"
|
||||||
|
indicator-color="primary"
|
||||||
|
align="justify"
|
||||||
|
narrow-indicator
|
||||||
>
|
>
|
||||||
{% raw %}
|
<q-tab name="frameworks" label="Frameworks" ></q-tab>
|
||||||
<!-- with raw Flask won't try to interpret the Vue moustaches -->
|
<q-tab name="tools" label="Useful Tools" ></q-tab>
|
||||||
<q-item-section>
|
<q-tab name="structure" label="File Structure" ></q-tab>
|
||||||
<q-item-label>{{ tool.name }}</q-item-label>
|
<q-tab name="enviroment" label="Dev Enviroment" ></q-tab>
|
||||||
<q-item-label caption>{{ tool.language }}</q-item-label>
|
</q-tabs>
|
||||||
</q-item-section>
|
|
||||||
{% endraw %}
|
<q-separator></q-separator>
|
||||||
</q-item>
|
|
||||||
</q-list>
|
<q-tab-panels v-model="tab">
|
||||||
<q-separator class="q-my-lg"></q-separator>
|
<q-tab-panel name="frameworks">
|
||||||
|
<div class="text-h6">Frameworks</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<q-splitter
|
||||||
|
v-model="splitterModel"
|
||||||
|
>
|
||||||
|
|
||||||
|
<template v-slot:before>
|
||||||
|
<q-tabs
|
||||||
|
v-model="framworktab"
|
||||||
|
vertical
|
||||||
|
>
|
||||||
|
<q-tab name="fastapi"><img src="./static/fastapi-framework.png">FASTAPI</q-tab>
|
||||||
|
<q-tab name="quasar"><img src="./static/quasar-framework.png">QUASAR</q-tab>
|
||||||
|
<q-tab name="vuejs"><img src="./static/vuejs-framework.png">VUE-JS</q-tab>
|
||||||
|
</q-tabs>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-slot:after>
|
||||||
|
<q-tab-panels
|
||||||
|
v-model="framworktab"
|
||||||
|
>
|
||||||
|
<q-tab-panel name="fastapi" class="text-body1">
|
||||||
|
<img src="./static/fastapilogo.png">
|
||||||
|
<p>LNbits API is built using FastAPI, a high-performance, easy to code API framework.<br/><br/>
|
||||||
|
FastAPI auto-generates swagger UI docs for testing endpoints <a class="text-primary" href="../docs">/docs</a></p>
|
||||||
|
|
||||||
|
</q-tab-panel>
|
||||||
|
|
||||||
|
<q-tab-panel name="quasar" class="text-body1">
|
||||||
|
<img src="./static/quasarlogo.png">
|
||||||
|
<p>LNbits uses Quasar for frontend deisgn elements. Quasar Framework is an open-source Vue.js based framework for building apps.</p>
|
||||||
|
|
||||||
|
<p class="text-weight-bold">TIP: Look through <code>/template</code> files in other extensions for examples.</p>
|
||||||
|
|
||||||
|
<p>In the below example we make a dialogue popup box (box can be triggered <q-btn size="sm" color="primary" @click="thingDialog.show = true">here</q-btn>):
|
||||||
|
<q-tooltip>Exmple of a tooltip!</q-tooltip></p>
|
||||||
|
<img src="./static/quasar-example.png"><br/><br/>
|
||||||
|
<div class="text-h6">Useful links:</div>
|
||||||
|
<q-btn color="primary" type="a" href="https://quasar.dev/style/">Style (typography, spacing, etc)</q-btn>
|
||||||
|
<q-btn color="primary" type="a" href="https://quasar.dev/vue-components/">Genral components (cards, buttons, popup dialogs, etc)</q-btn>
|
||||||
|
<q-btn color="primary" type="a" href="https://quasar.dev/layout/grid">Layouts (rows/columns, flexbox)</q-btn>
|
||||||
|
|
||||||
|
</q-tab-panel>
|
||||||
|
|
||||||
|
<q-tab-panel v-if="someBool == true" name="vuejs" class="text-body1">
|
||||||
|
<img src="./static/vuejslogo.png">
|
||||||
|
<p>Quasar is built on Vue-JS, so LNbits uses Vue-JS for rendering page elements, organising JS functions and declaring modles and elements.</p>
|
||||||
|
<p><code>v-if</code> can be used to render elements:</p>
|
||||||
|
<img src="./static/vif-example.png" style="max-width:800px">
|
||||||
|
<p>Typical example of a frontend page JS:</p>
|
||||||
|
<img src="./static/script-example.png" style="max-width:800px">
|
||||||
|
</q-tab-panel>
|
||||||
|
</q-tab-panels>
|
||||||
|
</template>
|
||||||
|
</q-splitter>
|
||||||
|
</div>
|
||||||
|
</q-tab-panel>
|
||||||
|
|
||||||
|
<!--FILE STRUCTURE-->
|
||||||
|
|
||||||
|
<q-tab-panel name="structure">
|
||||||
|
<div class="text-h6">File Structure</div>
|
||||||
|
Coming soon...
|
||||||
|
</q-tab-panel>
|
||||||
|
|
||||||
|
<q-tab-panel name="enviroment">
|
||||||
|
<div class="text-h6">Dev Enviroment</div>
|
||||||
|
Coming soon...
|
||||||
|
</q-tab-panel>
|
||||||
|
|
||||||
|
<q-tab-panel name="tools">
|
||||||
|
<div class="text-h6">Useful Tools</div>
|
||||||
|
<div>
|
||||||
|
<q-splitter
|
||||||
|
v-model="splitterModel"
|
||||||
|
>
|
||||||
|
|
||||||
|
<template v-slot:before>
|
||||||
|
<q-tabs
|
||||||
|
v-model="usefultab"
|
||||||
|
vertical
|
||||||
|
>
|
||||||
|
<q-tab name="magicalg">MAGICAL G</q-tab>
|
||||||
|
<q-tab name="conversion">CONVERSION</q-tab>
|
||||||
|
</q-tabs>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-slot:after>
|
||||||
|
<q-tab-panels
|
||||||
|
v-model="usefultab"
|
||||||
|
>
|
||||||
|
<q-tab-panel name="magicalg" class="text-body1">
|
||||||
|
<div class="text-h5 q-mb-md">Magical G</div>
|
||||||
<p>
|
<p>
|
||||||
A magical "g" is always available, with info about the user, wallets and
|
A magical "g" (ie <code>this.g.user.wallets[0].inkey</code>) is always available, with info about the user, wallets and
|
||||||
extensions:
|
extensions:
|
||||||
</p>
|
</p>
|
||||||
<code class="text-caption">{% raw %}{{ g }}{% endraw %}</code>
|
<code class="text-caption">{% raw %}{{ g }}{% endraw %}</code>
|
||||||
|
</q-tab-panel>
|
||||||
|
</q-tab-panels>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</q-splitter>
|
||||||
|
</div>
|
||||||
|
</q-tab-panel>
|
||||||
|
</q-tab-panels>
|
||||||
|
</q-card>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
{% endblock %} {% block scripts %} {{ window_vars(user) }}
|
{% endblock %} {% block scripts %} {{ window_vars(user) }}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
var someMapObject = obj => {
|
||||||
|
obj._data = _.clone(obj)
|
||||||
|
obj.date = Quasar.utils.date.formatDate(
|
||||||
|
new Date(obj.time * 1000),
|
||||||
|
'YYYY-MM-DD HH:mm'
|
||||||
|
)
|
||||||
|
// here you can do something with the mapped data
|
||||||
|
return obj
|
||||||
|
}
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#vue',
|
el: '#vue',
|
||||||
mixins: [windowMixin],
|
mixins: [windowMixin],
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
tools: []
|
///// Declare models/variables /////
|
||||||
|
thingDialog:{
|
||||||
|
show: false,
|
||||||
|
data: {}
|
||||||
|
},
|
||||||
|
someBool: true,
|
||||||
|
splitterModel: 20,
|
||||||
|
exampleData: [],
|
||||||
|
tab: "frameworks",
|
||||||
|
framworktab: "fastapi",
|
||||||
|
usefultab: "magicalg"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: function () {
|
///// Where functions live /////
|
||||||
var self = this
|
methods: {
|
||||||
|
exampleFunction(data){
|
||||||
// axios is available for making requests
|
var theData = data
|
||||||
axios({
|
LNbits.api
|
||||||
method: 'GET',
|
.request(
|
||||||
url: '/example/api/v1/tools',
|
'GET', // Type of request
|
||||||
headers: {
|
'/example/api/v1/test/'+ theData, // URL of the endpoint
|
||||||
'X-example-header': 'not-used'
|
this.g.user.wallets[0].inkey // Often endpoints require a key
|
||||||
}
|
)
|
||||||
}).then(function (response) {
|
.then(response => {
|
||||||
self.tools = response.data
|
this.exampleData = response.data.map(someMapObject) // Often whats returned is mapped onto some model
|
||||||
})
|
})
|
||||||
|
.catch(error => {
|
||||||
|
LNbits.utils.notifyApiError(error) // Error will be passed to the frontend
|
||||||
|
})
|
||||||
|
},
|
||||||
|
sendThingDialog(){
|
||||||
|
console.log(this.thingDialog)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
///// To run on startup /////
|
||||||
|
created: function () {
|
||||||
|
self = this // Often used to run a real object, rather than the event (all a bit confusing really)
|
||||||
|
self.exampleFunction("lorum")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -2,34 +2,11 @@
|
||||||
|
|
||||||
# add your dependencies here
|
# add your dependencies here
|
||||||
|
|
||||||
# import httpx
|
|
||||||
# (use httpx just like requests, except instead of response.ok there's only the
|
|
||||||
# response.is_error that is its inverse)
|
|
||||||
|
|
||||||
from . import example_ext
|
from . import example_ext
|
||||||
|
|
||||||
# add your endpoints here
|
# add your endpoints here
|
||||||
|
|
||||||
|
@example_ext.get("/api/v1/test/{test_data}")
|
||||||
@example_ext.get("/api/v1/tools")
|
async def api_example(test_data):
|
||||||
async def api_example():
|
# Do some python things and return the data
|
||||||
"""Try to add descriptions for others."""
|
return test_data
|
||||||
tools = [
|
|
||||||
{
|
|
||||||
"name": "fastAPI",
|
|
||||||
"url": "https://fastapi.tiangolo.com/",
|
|
||||||
"language": "Python",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Vue.js",
|
|
||||||
"url": "https://vuejs.org/",
|
|
||||||
"language": "JavaScript",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Quasar Framework",
|
|
||||||
"url": "https://quasar.dev/",
|
|
||||||
"language": "JavaScript",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
return tools
|
|
||||||
|
|
|
||||||