@rstoenescu Just came across this. Several of the most popular projects are there including vuejs
https://opencollective.com
you might want to add quasar and with 4.7K stars you are a project they want.
Personally I’d much rather give my financial credentials once and then support various projects. Although pateron does that this is more geared toward open source community.
Best posts made by dgk
-
RE: Give support to Quasar - share Patreon link on social media
-
await dialogs mixin
Just sharing my mixin that makes using ‘versions’ of dialog plugin a bit easier by return a promise reply that can be awaited just add mixin and go… See the comments for use and a dialogtest method
// to use this mixin // import and include it in mixins prop array of your component // copy this html button somewhere in your component template // <q-btn label="dialog test" color="secondary-1" text-color="secondary-1" @click="dialogtest()" /> // the button will call the dialogtest below export default { data: function () { return { } }, computed: { }, watch: { }, methods: { async dialogtest () { // (un)comment one or move of the tests below this.alert('Test Alert', 'All is good, no wait') console.log('confirmation', await this.confirm('Test Confirm', 'everything ok?', 'really?')) await this.alert('Test Alert', 'All is good, wait for dismiss') console.log('prompt', await this.prompt('Test Prompt', 'What is your favorite color')) }, async dialog (opts = {}) { return new Promise(resolve => { if (opts.prompt === true) opts.prompt = { model: '', type: 'text' } this.$q.dialog({ title: opts.title || '', message: opts.msg || '', cancel: opts.cancel == null ? false : opts.cancel, persistent: opts.persist == null ? false : opts.persist, prompt: opts.prompt, ok: { label: opts.ok || 'ok' } }) .onOk((res) => resolve(opts.confirm ? true : (res || ''))) .onCancel(() => resolve(false)) }) }, async confirm (title, msg, label) { return this.dialog({ title: title, msg: msg, confirm: true, cancel: true, persist: true, ok: label }) }, async alert (title, msg) { return this.dialog({ title: title, msg: msg }) }, async prompt (title, msg, prompt) { return this.dialog({ title: title, msg: msg, persist: true, prompt: prompt || true }) } }, created: function () { }, beforeMount: function () { }, mounted: function () { }, beforeDestory: function () { } } // export default
-
RE: Environment variables
ok I think I get it.
ctx.dev
istrue
forquasar dev
so this was my build:envenv: ctx.dev ? { // so on dev we'll have WSS: JSON.stringify(process.env.WSS) } : { // and on build (production): WSS: JSON.stringify(process.env.WSS) },
-
RE: Give support to Quasar - share Patreon link on social media
@rstoenescu I’ve been mocking up a frontend for a client and have definitedly decided on Quasar/Vue especially since @luc-claustres put together a tutorial of how to connect Qusar/Vue with a Feathers based backend api.
So…I was considering having my client (my brother) do a monthly contribution to Patreon while I work on his code.
Just wondering what your financial/time situatioin now is? I see you have about $500 a month coming from Patreon which isn’t enough for you to work on this project full time. So how much attention is $500 buying?
In particular is it enough for you to release the current “beta”. I just switched over to the beta and I much prefer it. It seems to be stable and mature. I know the beta has been around for awhile so wondering why you don’t release it as 1.0. Compared to many npm packages the beta seems very mature and really deserves a formal 1.0 release. It would be also easier to talk my client into substantially supporting Quasar if it wasn’t a “beta”. I know you are working on it at least monthly based on recent commits and it’s very much an active project. Still a 1.0 would make me feel more comfortable about commiting, ha ha, my project into the hands of Quasar.
@rstoenescu thx for all your time and effort. This project is making my project possible and does really deserve to be fully funded/backed. If not via Patreon then by other means.
-
manually adding quasar to an existing vuejs app
The quasar docs only assume you are going to start from scratch using a template and the quasar cli.
What are the steps need to be done or code added in order to add quasar to an existing vuejs app
-
RE: Patreon patrons get more attentative forum replies
@nothingismagick yea I know about discord although my experience of trying to use discord to get help with other projects is not that great. Depends on who is online and it’s not really great for sharing details of your issue. I prefer the async forum posts as long as I can get some help in a day or two and plus a forum post lives on in benefit to others.
-
RE: QForm - Form Fields Generator
@leon I can do that when it’s more tested plus a a little tutorial/docs on use. I can put the work in progress on github sooner though.
In the meantime I’ve added a q-collapse-form which wraps the form component, plus I have a quasar-feathers component so one can display all how set of configurable documents from a server.
Below is the latest, multi-schema would look. With these schemas quasar renders a three tab page with each tab allowing editing of that document/schemas fields. Shema now uses a
fieldprops
key so one can set the props for any quasar form component. Option-group options can be hard coded or are created at run time from other feathers services. Works slick although I am having this tab display issue. http://forum.quasar-framework.org/topic/920/formatting-generated-q-tabs-also-getting-a-explict-keys-warning/2const virtual = { name: { default: '', unique: true, fieldProps: { label: 'Name', tip: 'enter unique circuit name' } }, desc: { default: '', fieldProps: { label: 'Description', tip: 'Describe Services' } }, circuits: { default: [], fieldType: 'option-group', fieldProps: { label: 'Circuits', tip: 'Select circuits associated with this switch', inline: true, type: 'toggle', options: [] } } }; const physicalExtras = { mode: { default: 'toggle' , fieldType: 'select', fieldProps: { label: 'Switch Mode', tip: 'Select Switch Mode Type', options: [ {label: 'Toggle', value: 'toggle'}, {label: 'On/Off', value: 'onoff'}, {label: 'Momentary', value: 'momentary'}, ]} }, virtual: { default: true , fieldType: 'checkbox', fieldProps: { label: 'Virtual Switch', tip: 'Create a corresponding virtual switch', } }, // TODO make this another doc type so users can edit this list - for now disable location: { default: '1' , fieldType: 'hidden', fieldProps: { label: 'Location in Buidling', tip: 'Select building location', options: [ {label: 'First Floor', value: '1'}, {label: 'Second Floor', value: '2'}, {label: 'Outside', value: 'outside'} ]} }, bankid: { default: '', fieldType: 'select', fieldProps: { label: 'Bank/Board', tip: 'Select Bank/Board', options: [] } }, port: { default: 'A', fieldType: 'select', fieldProps: { label: 'Port', tip: 'Select a Port', options: [ {label: 'Port A', value: 'A'}, {label: 'Port B', value: 'B'} ]} }, pin: { default: 1, fieldProps: { label: 'Relay/Pin Number',min: 1, max: 8, step: 1 } //tip: 'Select a relay/pin number with the port ' } }; const physical = Object.assign({}, virtual); Object.assign(physical, physicalExtras); // views only for virtual switches virtual.views = { default: [], fieldType: 'option-group', fieldProps: { label: 'Views', tip: 'Put this switch in checked views', type: 'toggle', options: [] } } const view = { name: { default: '', unique: true, fieldProps: { label: 'view name', tip: 'enter unique view name' } } }; module.exports = { physical, virtual, view };
-
RE: Make own component from Quasar component
I am in need of making a pin pad component for easy entry of user pins. Seems like it would make use of a combination of existing Quasar components.
Maybe then some tutorial on using the mixins and/or making deriving “quasar” components from exiting ones.
I agree if with @spectrolite about the commmunity contributing compenents. As the library of Q components grows Quasar will gain more momentum and thus be able to attract more funding. It’s a win for @rstoenescu to show teach us how to fish.
-
Can we get props from quasar.config.js? (0.15)
Didn’t see anything in the docs but I assume there is a method (similar to express app) for getting any value of a property from within a .vue object?
http://quasar-framework.org/guide/app-quasar.conf.js.htmlI want to set some of my own custom properties/keys in quasar.config.js and then be able to grab them.
something like this I imagine
this.$q.configGet('propname')
Latest posts made by dgk
-
await dialogs mixin
Just sharing my mixin that makes using ‘versions’ of dialog plugin a bit easier by return a promise reply that can be awaited just add mixin and go… See the comments for use and a dialogtest method
// to use this mixin // import and include it in mixins prop array of your component // copy this html button somewhere in your component template // <q-btn label="dialog test" color="secondary-1" text-color="secondary-1" @click="dialogtest()" /> // the button will call the dialogtest below export default { data: function () { return { } }, computed: { }, watch: { }, methods: { async dialogtest () { // (un)comment one or move of the tests below this.alert('Test Alert', 'All is good, no wait') console.log('confirmation', await this.confirm('Test Confirm', 'everything ok?', 'really?')) await this.alert('Test Alert', 'All is good, wait for dismiss') console.log('prompt', await this.prompt('Test Prompt', 'What is your favorite color')) }, async dialog (opts = {}) { return new Promise(resolve => { if (opts.prompt === true) opts.prompt = { model: '', type: 'text' } this.$q.dialog({ title: opts.title || '', message: opts.msg || '', cancel: opts.cancel == null ? false : opts.cancel, persistent: opts.persist == null ? false : opts.persist, prompt: opts.prompt, ok: { label: opts.ok || 'ok' } }) .onOk((res) => resolve(opts.confirm ? true : (res || ''))) .onCancel(() => resolve(false)) }) }, async confirm (title, msg, label) { return this.dialog({ title: title, msg: msg, confirm: true, cancel: true, persist: true, ok: label }) }, async alert (title, msg) { return this.dialog({ title: title, msg: msg }) }, async prompt (title, msg, prompt) { return this.dialog({ title: title, msg: msg, persist: true, prompt: prompt || true }) } }, created: function () { }, beforeMount: function () { }, mounted: function () { }, beforeDestory: function () { } } // export default
-
RE: QForm - Form Fields Generator
My original post is quite old I have a much improved version of my form builder! as well as the app in general.
I did at one point try out vue-form-json-schema but it just didn’t fully meet my needs. One of the cool things my form builder is that it can use the values of one property in a schema instance as the option choices in another dynamically. Also I made it really easy to hide/show and have props of schema depend on the values of others. That you set in the schema. I really want to document and share this but just too preoccupied right now to do that. I have a major deployment coming up in the next week and after that I can put some attention to this if there is interest. In the meantime if you are savvy enough take a look at my repo of this project I am deploying that makes use of it. The component in question is Form.vue in the components subdirectory directory
https://git.kebler.net/Light2/frontend/src/branch/master/src/components
here are the schemas used. Notice they are in yaml format instead of json. This makes it WAY easier to comment stuff out and add comments. Of course they get read into a javascript object same as json.
https://git.kebler.net/Light2/database/src/branch/master/schemas
take a look at the config schema and page component. That is a simple single form implementation. The others are more complicated because they involved a collection of form instances.
-
RE: Browser refresh on spa build served by Caddy does not reload spa root route unlike dev server
The folks at Caddy helped me figure this out for Caddy V2 so I’ll share it as there is only an nginx example in quasar docs
https://lights.xxx.net { import r53 root * /opt/lights/web handle /socket.io/* { reverse_proxy http://lights.net:3030 } handle { try_files {path} {path}/ /index.html file_server } }
https://caddy.community/t/reload-rewrite-to-root-on-browser-refresh-v2/8276/11?u=dkebler
-
Browser refresh on spa build served by Caddy does not reload spa root route unlike dev server
I am finding a difference in behavior between when the user clicks browser refresh/reload (or enters via non root route) for a built spa (served by Caddy) vs the quasar dev server.
In the later the quasar dev server reloads the root route vue component (i.e. the q-layout) but in the former this does not happen thus breaking the site
I have to imagine this issue has come up for serving a built SPA with several routes so what is the solution? One ugly idea I had was to trap the refresh and redirect to the root route per this https://stegosource.com/prevent-browser-refresh-url-changes-route-navigation-vue/
Another is to bail on builds all together and use the dev server for production which will be the least painful.
I’ve tired to get the Caddy server to address this but that is not possible.
https://caddy.community/t/reload-rewrite-to-root-on-browser-refresh-v2I’m using the latest quasar/app framework (as of 5-19.20) although I’ve had this issue for going back awhile but now I have a “real” production situation coming up and I need a solution. I can’t have the user break the site by clicking refresh or entering on a non-root route.
-
RE: Best practices on how to globally scale down theme / layout
I have done battle with this issue with some success. @cmanique
In a nutshell I have avoided any styling within element attributes and worked toward a css files only solution.
Take a look at my css folder of the app I used to develop this approach
https://git.kebler.net/Light2/frontend/src/branch/master/src/cssStart by looking at https://git.kebler.net/Light2/frontend/src/branch/master/src/css/app.styl and follow the @imports to see how it’s all pulled together and in what order
For fonts sizes I have used rfs to do the overall font scaling https://github.com/twbs/rfs then used stylus variables with factors to relatively scale fonts in components. There is a post on this at this forum https://forum.quasar-framework.org/topic/3483/fluid-typography-solved/33
For brand colors I use palleton to get the four color set and then use variables to easily integrate them into to the overall theme. https://paletton.com/#uid=73j0c0kllllaFw0g0qFqFg0w0aF
Now when I change the that file of values https://git.kebler.net/Light2/frontend/src/branch/master/src/css/base-colors/brand.styl my site immediately has a brand color change. One can tweek those on a per component basis using stylus variables.I have set up files each targeting a quasar essential component like field, list, item that can be then overridden in a cascade like way using stylus variables.
Here is an example of how a “component” style file for q-field. It has a list of customizable variables at the top (which may be themselves variables and usually are) followed by the selectors and style affected by those variables.
https://git.kebler.net/Light2/frontend/src/branch/master/src/css/components/quasar/field.stylWith just a couple main variable changes (base font size, brand color page) I can change my whole color and font look.
@cmanique I’d just take my css folder and incorporate that into what you are evaluating.
https://git.kebler.net/Light2/frontend/src/branch/master/src/cssAs to a complex web app I think quasar is the answer. This app has a featherjs database backend, a nodejs app backend as well, and uses feather-vuex and my own reactive nested object store to react dynamically with the nodejs backend. I wrote a dynamic form component that one feeds in the collection schema and it generates the form. It’s designed to be the configuration and control interface to a system of 40+ switches and 40+ circuits with multiple process running on multiple machines. I couldn’t not have done it without quasar and vue especially since I am a one man show.
-
RE: q-drawer locked to q-page, i.e. not fixed
Arrrh…Just had a simple issue with the layout view
Had
<q-layout view="hHh lpR fFf">
needed
<q-layout view="hHh Lpr fFf">
lowercase l or r in middle three indicates locked to page container
nevermind
-
RE: q-drawer locked to q-page, i.e. not fixed
so moved the src/ folder over to clean starter build and the issue persists
I’ve apparently overridden some css?
if I comment out all my custom styling…still happens
-
q-drawer locked to q-page, i.e. not fixed
In my app the left drawer is not fixed like in the examples when content in the the page component is scrolled it scrolls with it.
I’ve check my html against the example for my layout page and that is all fine. The props for the drawer are just as in the example.
I see no special css in the codepen so I assume that a fixed drawer is the default
This project has come forward from pre 1.0 but I assumed any core css or css in the layout component was updated.
https://github.com/quasarframework/quasar/tree/dev/ui/src/css
so I scrubbed node_modules and reinstalled. Still there.I built a clean new app. Tossed in some content. Works fine
Just can’t put my finger on issue.
Any suggestions?
using
Pkg quasar… v1.9.8
Pkg @quasar/app… v1.6.0<template> <q-layout view="hHh lpR fFf"> <!-- Header/Toolbar --> <q-header elevated v-if="this.isAuthenticated"> <q-toolbar> <q-btn dense flat round icon="menu" @click="menuOpen = !menuOpen" /> <q-toolbar-title> {{ appName ? `${appName} -` : '' }} {{ pageName() }} <!-- <div slot="subtitle">{{subTitle}}></div> --> </q-toolbar-title> <q-btn icon="stop" small color="secondary" round @click="logout('admin')" v-show="isAdmin" > <q-tooltip anchor="bottom middle" self="top middle" :offset="[0, 20]"> Exit Administrator Configuration Mode </q-tooltip> </q-btn> <q-btn class="" icon="fas fa-key" small round @click="pinpad.admin=!pinpad.admin" v-show="isAuthenticated&&!isAdmin" > <q-tooltip anchor="bottom middle" self="top middle" :offset="[0, 20]"> Enter Configuration Mode - Requires Administrator Pin </q-tooltip> </q-btn> <q-btn icon="home" small round color="secondary-1" text-color="secondary-1" to="/home" > <q-tooltip anchor="bottom middle" self="top middle" :offset="[0, 20]"> Home - Dashboard </q-tooltip> </q-btn> </q-toolbar> </q-header> <!-- MENU --> <q-drawer v-if="this.isAuthenticated" show-if-above v-model="menuOpen" side="left" > <q-drawer-menu :menu="menu" :heading="isAdmin ? 'Configuration':'Control'" @active="(item) => active=item" :access="isAdmin ? 2 : 1" /> </q-drawer> <!-- main page --> <q-page-container> <router-view /> <!-- <router-view :key="$route.name" /> --> <q-page-scroller position="bottom-right" :scroll-offset="150" :offset="[18, 18]"> <q-btn fab icon="keyboard_arrow_up" /> </q-page-scroller> </q-page-container> <!-- modals --> <q-dialog v-model="pinpad.admin"> <q-pin-pad @validate="authenticate($event,'admin')" message="Enter Pin for Adminstator Access" title="Administrator Access" /> </q-dialog> <q-dialog v-model="pinpad.user" persistent> <q-pin-pad @validate="authenticate($event,'user')" message="Enter Pin for System Access" title="System Access" /> </q-dialog> <!-- footer toolbar --> <q-footer elevated v-if="this.isAuthenticated"> <q-toolbar> <div style="padding-right: 1em"> Status: </div> <q-spinner-hourglass v-if="get('footer.spinner')" /> <q-toolbar-title> {{ get('footer.message') || '' }} </q-toolbar-title> <q-btn glossy :class="cstatus('state')" > {{ cstatus('state') }} <q-tooltip anchor="bottom middle" self="top middle" :offset="[0, 20]" > System Controller Status </q-tooltip> </q-btn> <q-item class="etime"> {{ `uptime: ${cget('uptime') || '' }` }} </q-item> </q-toolbar> </q-footer> </q-layout> </template> <script> import idleTimeout from 'idle-timeout' import { openURL } from 'quasar' // ----------- INTERNAL DEPENDENCIES ------------ // assests import menu from 'assets/menu' // components import QDrawerMenu from 'src/components/DrawerMenu' import QPinPad from 'src/components/PinPad.vue' // MIXINS // general mixins import authenticate from 'src/mixins/authenticate' // maybe use an authentication api passed as a prop instead? // store mixins import state, { bindState } from 'src/mixins/state' // database mixins import docProp from 'src/mixins/doc-prop' import database from 'src/mixins/database' // controller websocket import controller from 'src/mixins/controller' // ----------- INTERNAL DEPENDENCIES ------------ export default { data () { return { menuOpen: false, menu: menu, pinpad: { user: false, admin: false }, active: {} // last/active sidebar item } }, components: { QDrawerMenu, QPinPad }, mixins: [database, controller, authenticate, state, docProp], props: [], // must pass service name as prop in either route call or calling template // warning: no computed values accessing the feathers-vuex store computed: { readonly () { return (!this.appDBLive || !this.appActive || !this.isAdmin || !this.isAuthenticated) }, appName: function () { return 'APP' // return this.getConfigDocProp('name') || 'UCI Application' } }, watch: { readonly: function (val) { console.log('setting global readonly', val) this.set('db.readonly', val) }, userState: async function (state) { // this.$router.push({ path: '/home' }) // this.connectController() // } else { // await this.removeControllerListeners() // await this.$socket.disonnect() // this.$q.notify({ color: 'negative', message: 'socket to controller has been closed' }) // console.log('unload the store here') // } } }, methods: { openURL, pageName () { const rname = this.$route.name || this.$route.params.name if (this.active ? this.active.name : false) { const a = this.active if (this.menu.items.find(item => item.name === rname)) return a.label ? a.label : a.name[0].toUpperCase() + a.name.slice(1) } return rname[0].toUpperCase() + rname.slice(1) } }, async beforeCreate () { }, created () { // set site load defaults this.set('appNameSpace', '_application') bindState(this, this.get('appNameSpace'), 'app') // for cget and cset this.set('db.locked', false) // unlock after authentication this.set('db.ready', false) // connected and all loaded this.cset('state', 'unavailable') // controller application state this.cset('db.live', true) // if controller application is listening for database changes // to logout the user on idle const idle = idleTimeout(this.logout, { element: document, timeout: 1000 * 60, loop: true }) idle.pause() }, async beforeMount () { }, async mounted () { await this.initDatabase() // will be pushed to database page if any issues await this.loadCollections() await this.connectController() console.log('authenticated?', this.isAuthenticated) if (!this.isAuthenticated) this.pinpad.user = true this.$router.push({ path: '/home' }) }, beforeDestroy () { } } </script> <style lang="stylus"> .etime background transparent </style>
-
For components provide a stylus alternative file that uses (more) variables
The components were developed with a bunch of styling in mind like the field component
<q-field color="purple-12" label="Label" stack-label> <template v-slot:prepend> <q-icon name="event" /> </template> <template v-slot:control> <div class="self-center full-width no-outline" tabindex="0">{{text}}</div> </template> </q-field>
Here the color prop is used to color the active/focused state. Which is great. One can even bind to it. But what one can’t do is bind to a stylus variable. Which means if you want to control the color outside of the script then you have to find the particular element/class in the field component that controls that element in the component. Then you can style it in stylus (i.e. theme it).
The time consuming activity for me has been to track down the tricky the classes. Especially painful are the ones that come and go. For example in the field component the label element has a
no-pointer-events
class added and removed as you click in the field. If you want to style that then you have to do this..q-field__label rfs($rfs-base-font-size * $field-font-factor) color $field-label-color padding-bottom .7em // needs to be dynamic based on font size &.no-pointer-events rfs($rfs-base-font-size * $field-font-factor * $field-label-font-factor) padding-bottom .5em // needs to be dynamic based on font size
So what then is the class that goes with that
color
prop. Good question. If you fire up the inspector and then click into the field you may or may not keep that focused so you can see that class that is added/removed.There be my point. I’m sure for static theming everyone is happy they can color things like some color in a component with a prop but to theme an entire front end requires knowing most of the classes.
so could you find out in the code? Sure
https://github.com/quasarframework/quasar/blob/dev/ui/src/components/field/QField.styl
so with a bit of investigating you can come up with the selector from the above file
.q-field--focused .q-field__control-container background red
BUT, that doesn’t help to set the color of that transition line at the bottom on the control container.
So I am suggesting that stylus sheets for quasar use more variables to allow users to theme without the pain of
discovering all the classes/selectors to make it so like I have done. Not everyone can be or wants to be a css guru.Those variables can have defaults just like what is more static coded now.
I’ve already done this for the critical ones (item, field, expansion, list) already that I now have pretty fine grain control using stylus variables. The effort is well worth it cause now with changing a couple stylus variables and/or my branding colors I can totally change the look.
for example here is my q-field stylus file
// QUASAR COMPONENT DEFAULT STYLING // ===================== Q FIELD COMPPONENT ============================ $field-font-factor = 1.5 // relative to base font size $field-label-font-factor = 1 // relative to field font size $field-label-color = $secondary-1 $field-text-color = white $field-color = $secondary-5 // Classes .q-field__native rfs($rfs-base-font-size * $field-font-factor) .q-checkbox__label color $field-text-color .q-field__label rfs($rfs-base-font-size * $field-font-factor) color $field-label-color padding-bottom .7em // needs to be dynamic based on font size &.no-pointer-events rfs($rfs-base-font-size * $field-font-factor * $field-label-font-factor) padding-bottom .5em // needs to be dynamic based on font size .q-field // margin .5em padding .2em 1em background $field-color &.checkbox padding 0 .q-field__control-container padding-top 0 .q-field--focused .q-field__control-container background red
here is how it looks.
-
RE: unable to load quasar.dev (weekend 10/9,10/10)
now at 9 pm PDT it is loading again @rstoenescu