├── .github
└── FUNDING.yml
├── .gitignore
├── .prettierrc
├── LICENSE
├── README.md
├── app-extension
├── .npmignore
├── README.md
├── package.json
└── src
│ ├── boot
│ └── register.js
│ └── index.js
└── ui
├── .npmignore
├── README.md
├── build
├── config.js
├── entry
│ ├── index.common.js
│ ├── index.esm.js
│ └── index.umd.js
├── index.js
├── script.app-ext.js
├── script.clean.js
├── script.css.js
├── script.javascript.js
├── script.open-umd.js
└── utils.js
├── dev
├── .editorconfig
├── .firebase
│ └── hosting.ZGlzdC9zcGE.cache
├── .firebaserc
├── .gitignore
├── .postcssrc.js
├── README.md
├── babel.config.js
├── firebase.json
├── package-lock.json
├── package.json
├── quasar.conf.js
├── quasar.extensions.json
└── src
│ ├── App.vue
│ ├── assets
│ └── .gitkeep
│ ├── boot
│ ├── register.js
│ └── vueComponents.js
│ ├── components
│ ├── .gitkeep
│ ├── DialogWrapper.vue
│ ├── InfoBoxWrapper.vue
│ ├── MarkdownCode.vue
│ ├── QDialogMethods.js
│ ├── Template.vue
│ └── showMoreWrapper.vue
│ ├── css
│ └── app.sass
│ ├── helpers
│ ├── conversion.js
│ ├── parseCodeForPrint.js
│ └── schemaBuilders.js
│ ├── index.template.html
│ ├── layouts
│ └── MyLayout.vue
│ ├── pages
│ ├── EasyTableDemo.vue
│ ├── Index.vue
│ └── SlotsDemo.vue
│ ├── router
│ ├── index.js
│ └── routes.js
│ ├── schemas
│ ├── examples
│ │ ├── basics.js
│ │ ├── computedFields.js
│ │ ├── editing.js
│ │ ├── editing2.js
│ │ ├── index.js
│ │ ├── selection.js
│ │ └── slots.js
│ └── pages
│ │ ├── basics.js
│ │ ├── computedFields.js
│ │ ├── editing.js
│ │ ├── index.js
│ │ ├── selection.js
│ │ └── slots.js
│ └── statics
│ ├── app-logo-128x128.png
│ └── icons
│ ├── apple-icon-120x120.png
│ ├── apple-icon-152x152.png
│ ├── apple-icon-167x167.png
│ ├── apple-icon-180x180.png
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon-96x96.png
│ ├── favicon.ico
│ ├── icon-128x128.png
│ ├── icon-192x192.png
│ ├── icon-256x256.png
│ ├── icon-384x384.png
│ ├── icon-512x512.png
│ ├── ms-icon-144x144.png
│ └── safari-pinned-tab.svg
├── package-lock.json
├── package.json
├── src
├── components
│ ├── EasyCell.vue
│ ├── EasyRow.vue
│ └── EasyTable.vue
├── helpers
│ ├── dateHelpers.js
│ ├── flattenPerSchema.js
│ └── schemaToQTableColumns.js
├── index.js
├── index.sass
├── margin-padding.sass
├── meta
│ ├── dependencyMap.js
│ ├── lang.js
│ └── quasarPropsJson.js
└── mixins
│ └── .gitkeep
└── umd-test.html
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: mesqueeb
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .thumbs.db
3 | node_modules
4 | dist
5 | yarn.lock
6 | npm-debug.log*
7 | yarn-debug.log*
8 | yarn-error.log*
9 |
10 | # Editor directories and files
11 | .idea
12 | .vscode
13 | *.suo
14 | *.ntvs*
15 | *.njsproj
16 | *.sln
17 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 100,
3 | "tabWidth": 2,
4 | "singleQuote": true,
5 | "trailingComma": "es5",
6 | "semi": false,
7 | "bracketSpacing": true
8 | }
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Luca Ban - Mesqueeb
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Quasar Easy Tables 🪑 (ノಠ益ಠ)ノ彡┻━┻
2 |
3 | New version:
4 |
5 | # Blitzar released! 🎉
6 |
7 | Quasar Easy Forms & Tables was upgraded to become much more powerful!
8 |
9 | The new version is called **Blitzar**
10 |
11 | - see blog post here: https://lucaban.medium.com/better-faster-vue-forms-with-blitzar-a0d71258a3bb
12 | - see documentation here: https://blitzar.cycraft.co
13 | - see the upgrade guide here: https://github.com/CyCraft/blitzar/releases/tag/v0.0.14
14 |
15 | # Support
16 |
17 | If this helped you in any way, you can contribute to the package's long term survival by supporting me:
18 |
19 | ### [💜 Support my open-source work on GitHub](https://github.com/sponsors/mesqueeb)
20 |
21 | Be sure to check out my sponsor page, I have a lot of open-source packages that might help you!
22 |
23 | (GitHub currently **doubles your support**! So if you support me with $10/mo, I will $20 instead! They're alchemists 🦾😉)
24 |
25 | Thank you so much!!!
26 |
27 | # License
28 | MIT (c) Luca Ban - Mesqueeb
29 |
--------------------------------------------------------------------------------
/app-extension/.npmignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .thumbs.db
3 | yarn.lock
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Editor directories and files
9 | .idea
10 | .vscode
11 | *.suo
12 | *.ntvs*
13 | *.njsproj
14 | *.sln
15 | .editorconfig
16 | .eslintignore
17 | .eslintrc.js
18 |
--------------------------------------------------------------------------------
/app-extension/README.md:
--------------------------------------------------------------------------------
1 | Quasar Easy Tables 🪑 (ノಠ益ಠ)ノ彡┻━┻
2 |
3 | New version:
4 |
5 | # Blitzar released! 🎉
6 |
7 | Quasar Easy Forms & Tables was upgraded to become much more powerful!
8 |
9 | The new version is called **Blitzar**
10 |
11 | - see blog post here: https://lucaban.medium.com/better-faster-vue-forms-with-blitzar-a0d71258a3bb
12 | - see documentation here: https://blitzar.cycraft.co
13 | - see the upgrade guide here: https://github.com/CyCraft/blitzar/releases/tag/v0.0.14
14 |
15 | # Support
16 |
17 | If this helped you in any way, you can contribute to the package's long term survival by supporting me:
18 |
19 | ### [💜 Support my open-source work on GitHub](https://github.com/sponsors/mesqueeb)
20 |
21 | Be sure to check out my sponsor page, I have a lot of open-source packages that might help you!
22 |
23 | (GitHub currently **doubles your support**! So if you support me with $10/mo, I will $20 instead! They're alchemists 🦾😉)
24 |
25 | Thank you so much!!!
26 |
27 | # License
28 | MIT (c) Luca Ban - Mesqueeb
29 |
--------------------------------------------------------------------------------
/app-extension/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "quasar-app-extension-easy-tables",
3 | "version": "0.8.6",
4 | "description": "Easily generate tables by only defining a \"schema\" object.",
5 | "author": "Luca Ban - Mesqueeb",
6 | "license": "MIT",
7 | "main": "src/index.js",
8 | "repository": {
9 | "type": "git",
10 | "url": "https://github.com/mesqueeb/quasar-ui-easy-tables"
11 | },
12 | "bugs": "https://github.com/mesqueeb/quasar-ui-easy-tables/issues",
13 | "homepage": "https://quasar-easy-tables.web.app",
14 | "dependencies": {
15 | "quasar-ui-easy-tables": "^0.8.5"
16 | },
17 | "engines": {
18 | "node": ">= 8.9.0",
19 | "npm": ">= 5.6.0",
20 | "yarn": ">= 1.6.0"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app-extension/src/boot/register.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VuePlugin from 'quasar-ui-easy-tables'
3 |
4 | Vue.use(VuePlugin)
5 |
--------------------------------------------------------------------------------
/app-extension/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Quasar App Extension index/runner script
3 | * (runs on each dev/build)
4 | *
5 | * Docs: https://quasar.dev/app-extensions/development-guide/index-api
6 | * API: https://github.com/quasarframework/quasar/blob/master/app/lib/app-extension/IndexAPI.js
7 | */
8 |
9 | function extendConf (conf) {
10 | // register our boot file
11 | conf.boot.push('~quasar-app-extension-easy-tables/src/boot/register.js')
12 |
13 | // make sure app extension files & ui package gets transpiled
14 | conf.build.transpileDependencies.push(/quasar-app-extension-easy-tables[\\/]src/)
15 | }
16 |
17 | module.exports = function (api) {
18 | // Quasar compatibility check; you may need
19 | // hard dependencies, as in a minimum version of the "quasar"
20 | // package or a minimum version of "@quasar/app" CLI
21 | api.compatibleWith('quasar', '^1.1.1')
22 | api.compatibleWith('@quasar/app', '^1.1.0')
23 |
24 | // Uncomment the line below if you provide a JSON API for your component
25 | // api.registerDescribeApi('EasyTable', '~quasar-ui-easy-tables/src/components/EasyTable.json')
26 |
27 | // We extend /quasar.conf.js
28 | api.extendQuasarConf(extendConf)
29 | }
30 |
--------------------------------------------------------------------------------
/ui/.npmignore:
--------------------------------------------------------------------------------
1 | /build
2 | /dev
3 | umd-test.html
4 |
5 | .DS_Store
6 | .thumbs.db
7 | yarn.lock
8 | npm-debug.log*
9 | yarn-debug.log*
10 | yarn-error.log*
11 |
12 | # Editor directories and files
13 | .idea
14 | .vscode
15 | *.suo
16 | *.ntvs*
17 | *.njsproj
18 | *.sln
19 | .editorconfig
20 | .eslintignore
21 | .eslintrc.js
22 |
--------------------------------------------------------------------------------
/ui/README.md:
--------------------------------------------------------------------------------
1 | Quasar Easy Tables 🪑 (ノಠ益ಠ)ノ彡┻━┻
2 |
3 | New version:
4 |
5 | # Blitzar released! 🎉
6 |
7 | Quasar Easy Forms & Tables was upgraded to become much more powerful!
8 |
9 | The new version is called **Blitzar**
10 |
11 | - see blog post here: https://lucaban.medium.com/better-faster-vue-forms-with-blitzar-a0d71258a3bb
12 | - see documentation here: https://blitzar.cycraft.co
13 | - see the upgrade guide here: https://github.com/CyCraft/blitzar/releases/tag/v0.0.14
14 |
15 | # Support
16 |
17 | If this helped you in any way, you can contribute to the package's long term survival by supporting me:
18 |
19 | ### [💜 Support my open-source work on GitHub](https://github.com/sponsors/mesqueeb)
20 |
21 | Be sure to check out my sponsor page, I have a lot of open-source packages that might help you!
22 |
23 | (GitHub currently **doubles your support**! So if you support me with $10/mo, I will $20 instead! They're alchemists 🦾😉)
24 |
25 | Thank you so much!!!
26 |
27 | # License
28 | MIT (c) Luca Ban - Mesqueeb
29 |
--------------------------------------------------------------------------------
/ui/build/config.js:
--------------------------------------------------------------------------------
1 | const { name, author, version } = require('../package.json')
2 | const year = (new Date()).getFullYear()
3 |
4 | module.exports = {
5 | name,
6 | version,
7 | banner:
8 | '/*!\n' +
9 | ' * ' + name + ' v' + version + '\n' +
10 | ' * (c) ' + year + ' ' + author + '\n' +
11 | ' * Released under the MIT License.\n' +
12 | ' */\n'
13 | }
14 |
--------------------------------------------------------------------------------
/ui/build/entry/index.common.js:
--------------------------------------------------------------------------------
1 | import Plugin from '../../src/index'
2 |
3 | export default Plugin
4 |
--------------------------------------------------------------------------------
/ui/build/entry/index.esm.js:
--------------------------------------------------------------------------------
1 | import Plugin from '../../src/index'
2 |
3 | export default Plugin
4 | export * from '../../src/index'
5 |
--------------------------------------------------------------------------------
/ui/build/entry/index.umd.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Plugin from '../../src/index'
3 |
4 | Vue.use(Plugin)
5 |
6 | export * from '../../src/index'
7 |
--------------------------------------------------------------------------------
/ui/build/index.js:
--------------------------------------------------------------------------------
1 | process.env.NODE_ENV = 'production'
2 |
3 | const { join } = require('path')
4 | const { createFolder } = require('./utils')
5 | const { green, blue } = require('chalk')
6 |
7 | console.log()
8 |
9 | require('./script.app-ext.js').syncAppExt()
10 | require('./script.clean.js')
11 |
12 | console.log(` 📦 Building ${green('v' + require('../package.json').version)}...\n`)
13 |
14 | createFolder('dist')
15 |
16 | require(join(__dirname, './script.javascript.js'))
17 |
--------------------------------------------------------------------------------
/ui/build/script.app-ext.js:
--------------------------------------------------------------------------------
1 | const
2 | fs = require('fs'),
3 | path = require('path'),
4 | root = path.resolve(__dirname, '../..'),
5 | resolvePath = file => path.resolve(root, file),
6 | { blue } = require('chalk')
7 |
8 | const writeJson = function (file, json) {
9 | return fs.writeFileSync(file, JSON.stringify(json, null, 2) + '\n', 'utf-8')
10 | }
11 |
12 | module.exports.syncAppExt = function (both = true) {
13 | // make sure this project has an app-extension project
14 | const appExtDir = resolvePath('app-extension')
15 | if (!fs.existsSync(appExtDir)) {
16 | return
17 | }
18 |
19 | // make sure this project has an ui project
20 | const uiDir = resolvePath('ui')
21 | if (!fs.existsSync(uiDir)) {
22 | return
23 | }
24 |
25 | // get version and name from ui package.json
26 | const { name, version } = require(resolvePath(resolvePath('ui/package.json')))
27 |
28 | // read app-ext package.json
29 | const appExtFile = resolvePath('app-extension/package.json')
30 | let appExtJson = require(appExtFile),
31 | finished = false
32 |
33 | // sync version numbers
34 | if (both === true) {
35 | appExtJson.version = version
36 | }
37 |
38 | // check dependencies
39 | if (appExtJson.dependencies !== void 0) {
40 | if (appExtJson.dependencies[name] !== void 0) {
41 | appExtJson.dependencies[name] = '^' + version
42 | finished = true
43 | }
44 | }
45 | // check devDependencies, if not finished
46 | if (finished === false && appExtJson.devDependencies !== void 0) {
47 | if (appExtJson.devDependencies[name] !== void 0) {
48 | appExtJson.devDependencies[name] = '^' + version
49 | finished = true
50 | }
51 | }
52 |
53 | if (finished === true) {
54 | writeJson(appExtFile, appExtJson)
55 | console.log(` ⭐️ App Extension version ${blue(appExtJson.name)} synced.\n`)
56 | return
57 | }
58 |
59 | console.error(` App Extension version and dependency NOT synced.\n`)
60 | }
--------------------------------------------------------------------------------
/ui/build/script.clean.js:
--------------------------------------------------------------------------------
1 | var
2 | rimraf = require('rimraf'),
3 | path = require('path')
4 |
5 | rimraf.sync(path.resolve(__dirname, '../dist/*'))
6 | console.log(` 💥 Cleaned build artifacts.\n`)
7 |
--------------------------------------------------------------------------------
/ui/build/script.css.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const sass = require('node-sass')
3 | const postcss = require('postcss')
4 | const cssnano = require('cssnano')
5 | const rtl = require('postcss-rtl')
6 | const autoprefixer = require('autoprefixer')
7 |
8 | const buildConf = require('./config')
9 | const buildUtils = require('./utils')
10 |
11 | const postCssCompiler = postcss([ autoprefixer ])
12 | const postCssRtlCompiler = postcss([ rtl({}) ])
13 |
14 | const nano = postcss([
15 | cssnano({
16 | preset: ['default', {
17 | mergeLonghand: false,
18 | convertValues: false,
19 | cssDeclarationSorter: false,
20 | reduceTransforms: false
21 | }]
22 | })
23 | ])
24 |
25 | Promise
26 | .all([
27 | generate('src/index.sass', `dist/index`)
28 | ])
29 | .catch(e => {
30 | console.error(e)
31 | process.exit(1)
32 | })
33 |
34 | /**
35 | * Helpers
36 | */
37 |
38 | function resolve (_path) {
39 | return path.resolve(__dirname, '..', _path)
40 | }
41 |
42 | function generate (src, dest) {
43 | src = resolve(src)
44 | dest = resolve(dest)
45 |
46 | return new Promise((resolve, reject) => {
47 | sass.render({ file: src, includePaths: ['node_modules'] }, (err, result) => {
48 | if (err) {
49 | reject(err)
50 | return
51 | }
52 |
53 | resolve(result.css)
54 | })
55 | })
56 | .then(code => buildConf.banner + code)
57 | .then(code => postCssCompiler.process(code, { from: void 0 }))
58 | .then(code => {
59 | code.warnings().forEach(warn => {
60 | console.warn(warn.toString())
61 | })
62 | return code.css
63 | })
64 | .then(code => Promise.all([
65 | generateUMD(dest, code),
66 | postCssRtlCompiler.process(code, { from: void 0 })
67 | .then(code => generateUMD(dest, code.css, '.rtl'))
68 | ]))
69 | }
70 |
71 | function generateUMD (dest, code, ext = '') {
72 | return buildUtils.writeFile(`${dest}${ext}.css`, code, true)
73 | .then(code => nano.process(code, { from: void 0 }))
74 | .then(code => buildUtils.writeFile(`${dest}${ext}.min.css`, code.css, true))
75 | }
76 |
--------------------------------------------------------------------------------
/ui/build/script.javascript.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const fs = require('fs')
3 | const fse = require('fs-extra')
4 | const rollup = require('rollup')
5 | const uglify = require('uglify-es')
6 | const buble = require('@rollup/plugin-buble')
7 | const json = require('@rollup/plugin-json')
8 | const nodeResolve = require('@rollup/plugin-node-resolve')
9 | const VuePlugin = require('rollup-plugin-vue')
10 | const commonjs = require('@rollup/plugin-commonjs')
11 |
12 | const buildConf = require('./config')
13 | const buildUtils = require('./utils')
14 |
15 | const rollupPlugins = [
16 | commonjs(),
17 | nodeResolve({
18 | extensions: ['.js'],
19 | preferBuiltins: false,
20 | }),
21 | VuePlugin(),
22 | json(),
23 | buble({
24 | objectAssign: 'Object.assign',
25 | }),
26 | ]
27 |
28 | const builds = [
29 | {
30 | rollup: {
31 | input: {
32 | input: resolve(`entry/index.esm.js`),
33 | },
34 | output: {
35 | file: resolve(`../dist/index.esm.js`),
36 | format: 'es',
37 | },
38 | },
39 | build: {
40 | unminified: true,
41 | // minified: true,
42 | },
43 | },
44 | {
45 | rollup: {
46 | input: {
47 | input: resolve(`entry/index.common.js`),
48 | },
49 | output: {
50 | file: resolve(`../dist/index.common.js`),
51 | format: 'cjs',
52 | },
53 | },
54 | build: {
55 | unminified: true,
56 | // minified: true,
57 | },
58 | },
59 | {
60 | rollup: {
61 | input: {
62 | input: resolve(`entry/index.umd.js`),
63 | },
64 | output: {
65 | name: 'easyTables',
66 | file: resolve(`../dist/index.umd.js`),
67 | format: 'umd',
68 | },
69 | },
70 | build: {
71 | unminified: true,
72 | minified: true,
73 | minExt: true,
74 | },
75 | },
76 | ]
77 |
78 | // Add your asset folders here
79 | // addAssets(builds, 'icon-set', 'iconSet')
80 | // addAssets(builds, 'lang', 'lang')
81 |
82 | build(builds)
83 |
84 | /**
85 | * Helpers
86 | */
87 |
88 | function resolve (_path) {
89 | return path.resolve(__dirname, _path)
90 | }
91 |
92 | function addAssets (builds, type, injectName) {
93 | const files = fs.readdirSync(resolve('../../ui/src/components/' + type)),
94 | plugins = [buble(bubleConfig)],
95 | outputDir = resolve(`../dist/${type}`)
96 |
97 | fse.mkdirp(outputDir)
98 |
99 | files
100 | .filter(file => file.endsWith('.js'))
101 | .forEach(file => {
102 | const name = file.substr(0, file.length - 3).replace(/-([a-z])/g, g => g[1].toUpperCase())
103 | builds.push({
104 | rollup: {
105 | input: {
106 | input: resolve(`../src/components/${type}/${file}`),
107 | plugins,
108 | },
109 | output: {
110 | file: addExtension(resolve(`../dist/${type}/${file}`), 'umd'),
111 | format: 'umd',
112 | name: `easyTables.${injectName}.${name}`,
113 | },
114 | },
115 | build: {
116 | minified: true,
117 | },
118 | })
119 | })
120 | }
121 |
122 | function build (builds) {
123 | return Promise.all(builds.map(genConfig).map(buildEntry)).catch(buildUtils.logError)
124 | }
125 |
126 | function genConfig (opts) {
127 | Object.assign(opts.rollup.input, {
128 | plugins: rollupPlugins,
129 | external: ['vue', 'quasar', 'quasar-ui-easy-forms'],
130 | })
131 |
132 | Object.assign(opts.rollup.output, {
133 | banner: buildConf.banner,
134 | globals: { vue: 'Vue', quasar: 'Quasar', 'quasar-ui-easy-forms': 'EasyForms' },
135 | })
136 |
137 | return opts
138 | }
139 |
140 | function addExtension (filename, ext = 'min') {
141 | const insertionPoint = filename.lastIndexOf('.')
142 | return `${filename.slice(0, insertionPoint)}.${ext}${filename.slice(insertionPoint)}`
143 | }
144 |
145 | function buildEntry (config) {
146 | return rollup
147 | .rollup(config.rollup.input)
148 | .then(bundle => bundle.generate(config.rollup.output))
149 | .then(({ output }) => {
150 | const code =
151 | config.rollup.output.format === 'umd'
152 | ? injectVueRequirement(output[0].code)
153 | : output[0].code
154 |
155 | return config.build.unminified ? buildUtils.writeFile(config.rollup.output.file, code) : code
156 | })
157 | .then(code => {
158 | if (!config.build.minified) {
159 | return code
160 | }
161 |
162 | const minified = uglify.minify(code, {
163 | compress: {
164 | pure_funcs: ['makeMap'],
165 | },
166 | })
167 |
168 | if (minified.error) {
169 | return Promise.reject(minified.error)
170 | }
171 |
172 | return buildUtils.writeFile(
173 | config.build.minExt === true
174 | ? addExtension(config.rollup.output.file)
175 | : config.rollup.output.file,
176 | buildConf.banner + minified.code,
177 | true
178 | )
179 | })
180 | .catch(err => {
181 | console.error(err)
182 | process.exit(1)
183 | })
184 | }
185 |
186 | function injectVueRequirement (code) {
187 | const index = code.indexOf(`Vue = Vue && Vue.hasOwnProperty('default') ? Vue['default'] : Vue`)
188 |
189 | if (index === -1) {
190 | return code
191 | }
192 |
193 | const checkMe = ` if (Vue === void 0) {
194 | console.error('[ Quasar ] Vue is required to run. Please add a script tag for it before loading Quasar.')
195 | return
196 | }
197 | `
198 |
199 | return code.substring(0, index - 1) + checkMe + code.substring(index)
200 | }
201 |
--------------------------------------------------------------------------------
/ui/build/script.open-umd.js:
--------------------------------------------------------------------------------
1 | const { resolve } = require('path')
2 | const open = require('open')
3 |
4 | open(
5 | resolve(__dirname, '../umd-test.html')
6 | )
7 |
--------------------------------------------------------------------------------
/ui/build/utils.js:
--------------------------------------------------------------------------------
1 | const
2 | fs = require('fs'),
3 | path = require('path'),
4 | zlib = require('zlib'),
5 | { green, blue, red, cyan } = require('chalk'),
6 | kebabRegex = /[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g
7 |
8 | function getSize (code) {
9 | return (code.length / 1024).toFixed(2) + 'kb'
10 | }
11 |
12 | module.exports.createFolder = function (folder) {
13 | const dir = path.join(__dirname, '..', folder)
14 | if (!fs.existsSync(dir)) {
15 | fs.mkdirSync(dir)
16 | }
17 | }
18 |
19 | module.exports.writeFile = function (dest, code, zip) {
20 | const banner = dest.indexOf('.json') > -1
21 | ? red('[json]')
22 | : dest.indexOf('.js') > -1
23 | ? green('[js] ')
24 | : dest.indexOf('.ts') > -1
25 | ? cyan('[ts] ')
26 | : blue('[css] ')
27 |
28 | return new Promise((resolve, reject) => {
29 | function report (extra) {
30 | console.log(`${banner} ${path.relative(process.cwd(), dest).padEnd(41)} ${getSize(code).padStart(8)}${extra || ''}`)
31 | resolve(code)
32 | }
33 |
34 | fs.writeFile(dest, code, err => {
35 | if (err) return reject(err)
36 | if (zip) {
37 | zlib.gzip(code, (err, zipped) => {
38 | if (err) return reject(err)
39 | report(` (gzipped: ${getSize(zipped).padStart(8)})`)
40 | })
41 | }
42 | else {
43 | report()
44 | }
45 | })
46 | })
47 | }
48 |
49 | module.exports.readFile = function (file) {
50 | return fs.readFileSync(file, 'utf-8')
51 | }
52 |
53 | module.exports.logError = function (err) {
54 | console.error('\n' + red('[Error]'), err)
55 | console.log()
56 | }
57 |
--------------------------------------------------------------------------------
/ui/dev/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/ui/dev/.firebase/hosting.ZGlzdC9zcGE.cache:
--------------------------------------------------------------------------------
1 | index.html,1590727263243,311618c8b3a9586de6bc09d414e68cc4b310f4ff4c9cfe12fb2039601ca0d53b
2 | css/4.e7b6832b.css,1590727263239,200b654d00881441b5795196795d761120a37c31fe9de48938931e47d2d295a8
3 | css/5.6f0819b1.css,1590727263241,998dd72ad2d6276a0f2721ab55d6b7ae532339a237406682dde88663de09a1ee
4 | css/6.0eb74e2f.css,1590727263242,9d4d8891f30b5b77abc0a4a65dd3757c0b984c879414ec6bda869999d23544b6
5 | css/chunk-common.e5ca51ca.css,1590727263237,c59e728bddee043a5585323eefcb0148533e24e0e2ad33638255ab25f536ee7d
6 | js/4.be7f69f1.js,1590727263241,e6dab5ad27d27c847d4c53e31830ecd1ad9fe4529e75ae38f5b9f2c147fa948c
7 | js/5.6a16ff69.js,1590727263241,672acc4040d243d9f8ee9de386dee531cc9621c00de3a660f7102925e40917f4
8 | js/6.8caa064d.js,1590727263242,ecfb1a90a76c4cd599bf46bd67e9e27bae43bbdfa18f0c591d28be75831c4d5b
9 | js/7.b4b11c5e.js,1590727263242,a4f0d9595a8189eb2b39521908e57e476687a8d887b154de9f1419962194d79a
10 | js/runtime.13d7c7fb.js,1590727263238,24a35c01489a3217478694f7d743186cb3235197d9c802758bfaa27a8a456d42
11 | statics/app-logo-128x128.png,1590727263241,3ba36b6fe48820fa565c588c7057d5b20de3777c1ac01299e7a9f090a558f175
12 | statics/icons/apple-icon-120x120.png,1590727263241,9e147671e0051a9fe6042d4a0797037f077100fcb121d4206f4543838ddf87eb
13 | js/app.fd3dd48d.js,1590727263238,5a6292207bf94643b33e74fedaee2cfa2804be26aa40cd7d14216506bbdd4ae1
14 | statics/icons/apple-icon-152x152.png,1590727263242,6dc20f0fb7da357654cb1a9312a74702e1e97ceb3056d67b5ad0a066e96c0ed8
15 | statics/icons/favicon-16x16.png,1590727263242,9a9519211345ba591ae9ecd63082d20cdec901bd22da4ff5fa1c0c0aa45fdbee
16 | statics/icons/favicon-32x32.png,1590727263242,6b423caf88b215fc7f52e76642141dd78522862cc989114233eb50c77deb16d8
17 | statics/icons/apple-icon-180x180.png,1590727263242,43f646dadecb2dbabbe53a3e888aa3c377594f843167dd54001fa3a34a4cabaa
18 | js/chunk-common.bfe2648e.js,1590727263239,a3b9bfdfb78d1d026f38fbd342a2369fc3ce1ff2862d442229f3b7f842a8d8a5
19 | statics/icons/favicon-96x96.png,1590727263242,aea2f51632b5e5a4d9bbb3fd010b438940bb568838f6cb186a4b9e33eb85e562
20 | statics/icons/icon-128x128.png,1590727263244,3ba36b6fe48820fa565c588c7057d5b20de3777c1ac01299e7a9f090a558f175
21 | statics/icons/icon-192x192.png,1590727263244,efe6efc75397aab84684918e7c45e24aadc2f8612789d6c91a6e7432d47724c2
22 | statics/icons/ms-icon-144x144.png,1590727263244,a1bee2aec520eea50583e3ace8461eb229b8bd5679c573cabd6c54a37b2286da
23 | statics/icons/safari-pinned-tab.svg,1590727263244,3356180d03fd5493efc6f27816d1d4e5f908ac300f5efb9f8044d9ef8823c4d1
24 | fonts/KFOkCnqEu92Fr1MmgVxIIzQ.a45108d3.woff,1590727263238,0cc82ea4e2383c3b0d0f46b32471cee5e920f87d2a151d302635cb2ca8cb6e43
25 | fonts/KFOlCnqEu92Fr1MmEU9fBBc-.cea99d3e.woff,1590727263238,42c7afdcff7aea098db26a417a9bb7929eed6df8823461b05cea5e6185216248
26 | fonts/KFOlCnqEu92Fr1MmSU5fBBc-.865f928c.woff,1590727263236,92689fd58bd8ba23da284d871afeb0e05fce981a9a28464b0acbad2051f6545a
27 | fonts/KFOlCnqEu92Fr1MmYUtfBBc-.bac8362e.woff,1590727263238,f225f153b48f4208f17a7fcc4595d2832b5b29916c357c8f7979ba64831b9ad0
28 | fonts/KFOlCnqEu92Fr1MmWUlfBBc-.2267169e.woff,1590727263238,de91d90d88d21edee1be62c920126d606e0beac61e6ee2243c417490b107279e
29 | statics/icons/favicon.ico,1590727263242,f4066f8f9d3212c5156547c3e2e2f607d1b17f1887f96d3a0bf59221e6eb519e
30 | fonts/KFOmCnqEu92Fr1Mu4mxM.49ae34d4.woff,1590727263238,68fb4aa339f56ddb03b15f12cae4f82cd06640dca3dcfe230b802593f36312e4
31 | statics/icons/apple-icon-167x167.png,1590727263243,89d93abc376213db7d1663adc8bd595d76daccd4e2890e29f19152e33d2ee4d8
32 | statics/icons/icon-256x256.png,1590727263244,fef8007201e545ef561f5fa50a12fa654c0fa9f03e9d998b6199727de8238c25
33 | statics/icons/icon-384x384.png,1590727263244,4e90fdacc7e781857ab93ece4b8e816b65ed69319f3abbe18367df2f47111049
34 | statics/icons/icon-512x512.png,1590727263244,83cb2337e81081fd5a948805b4fb550c68daa81346add2e8ea86f43d13f6ce9d
35 | fonts/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.12a47ed5.woff2,1590727263238,a99652277b6479b04b3231319123ca269fe04f85cddac90b8dcbc142d4625d4d
36 | fonts/flUhRq6tzZclQEJ-Vdg-IuiaDsNa.f2a09334.woff,1590727263238,64fc5686c655301234b304dfb176d6ca1d6fd56f9434abf380b3549ce0058b69
37 | css/app.22b18900.css,1590727263238,5d890761d95f5c280ca49b8ed79577ec691de04777cb78373278aacff5fdb4e3
38 | js/vendor.61eed14f.js,1590727263237,490a6535de6f513e5bfa20b7794efdc9c7920b95fec0d3710eddc19ac031a7f0
39 |
--------------------------------------------------------------------------------
/ui/dev/.firebaserc:
--------------------------------------------------------------------------------
1 | {
2 | "projects": {
3 | "default": "quasar-easy-tables"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/ui/dev/.gitignore:
--------------------------------------------------------------------------------
1 | .quasar
2 | .DS_Store
3 | .thumbs.db
4 | node_modules
5 | /dist
6 | /src-cordova/node_modules
7 | /src-cordova/platforms
8 | /src-cordova/plugins
9 | /src-cordova/www
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 |
--------------------------------------------------------------------------------
/ui/dev/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | plugins: [
5 | // to edit target browsers: use "browserslist" field in package.json
6 | require('autoprefixer')
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/ui/dev/README.md:
--------------------------------------------------------------------------------
1 | # Dev app (playground)
2 |
3 | Adding .vue files to src/pages/ will auto-add them to the Index page list.
4 |
--------------------------------------------------------------------------------
/ui/dev/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@quasar/babel-preset-app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/ui/dev/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "hosting": {
3 | "public": "dist/spa",
4 | "ignore": [
5 | "firebase.json",
6 | "**/.*",
7 | "**/node_modules/**"
8 | ],
9 | "rewrites": [
10 | {
11 | "source": "**",
12 | "destination": "/index.html"
13 | }
14 | ]
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ui/dev/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dev",
3 | "version": "1.0.0",
4 | "description": "A Quasar Framework app",
5 | "productName": "Quasar App",
6 | "cordovaId": "org.cordova.quasar.app",
7 | "private": true,
8 | "scripts": {
9 | "build": "quasar build",
10 | "deploy": "quasar build && firebase deploy",
11 | "dev": "quasar dev",
12 | "dev:ssr": "quasar dev -m ssr",
13 | "dev:ios": "quasar dev -m ios",
14 | "dev:android": "quasar dev -m android",
15 | "dev:electron": "quasar dev -m electron"
16 | },
17 | "dependencies": {
18 | "@quasar/extras": "^1.8.1",
19 | "case-anything": "^0.3.1",
20 | "copy-anything": "^1.6.0",
21 | "filter-anything": "^1.1.5",
22 | "is-what": "^3.11.3",
23 | "merge-anything": "^2.4.4",
24 | "quasar-ui-component-info-card": "0.0.7",
25 | "quasar-ui-easy-forms": "^1.2.7",
26 | "raw-loader": "^4.0.1",
27 | "sort-anything": "^0.1.0"
28 | },
29 | "devDependencies": {
30 | "@quasar/app": "^1.9.1",
31 | "@quasar/quasar-app-extension-qmarkdown": "^1.0.27"
32 | },
33 | "engines": {
34 | "node": ">= 8.9.0",
35 | "npm": ">= 5.6.0",
36 | "yarn": ">= 1.6.0"
37 | },
38 | "browserslist": [
39 | "last 1 version, not dead, ie >= 11"
40 | ]
41 | }
42 |
--------------------------------------------------------------------------------
/ui/dev/quasar.conf.js:
--------------------------------------------------------------------------------
1 | // Configuration for your app
2 | // https://quasar.dev/quasar-cli/quasar-conf-js
3 |
4 | const path = require('path')
5 |
6 | module.exports = function (ctx) {
7 | return {
8 | // app boot file (/src/boot)
9 | // --> boot files are part of "main.js"
10 | boot: ['vueComponents.js', 'register.js'],
11 |
12 | css: [],
13 |
14 | extras: [
15 | // 'ionicons-v4',
16 | // 'mdi-v4',
17 | // 'fontawesome-v5',
18 | // 'eva-icons',
19 | // 'themify',
20 | // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!
21 |
22 | 'roboto-font', // optional, you are not bound to it
23 | 'material-icons', // optional, you are not bound to it
24 | ],
25 |
26 | framework: {
27 | // iconSet: 'ionicons-v4', // Quasar icon set
28 | // lang: 'de', // Quasar language pack
29 |
30 | // Possible values for "all":
31 | // * 'auto' - Auto-import needed Quasar components & directives
32 | // (slightly higher compile time; next to minimum bundle size; most convenient)
33 | // * false - Manually specify what to import
34 | // (fastest compile time; minimum bundle size; most tedious)
35 | // * true - Import everything from Quasar
36 | // (not treeshaking Quasar; biggest bundle size; convenient)
37 | all: 'auto',
38 |
39 | components: ['QInput', 'QImg', 'QToggle', 'QSelect', 'QBtnToggle', 'QIcon'],
40 | directives: [],
41 |
42 | // Quasar plugins
43 | plugins: ['Dialog'],
44 | },
45 |
46 | supportIE: false,
47 |
48 | // animations: 'all', // --- includes all animations
49 | animations: [],
50 |
51 | build: {
52 | vueRouterMode: 'history',
53 |
54 | chainWebpack (chain) {
55 | chain.resolve.alias.merge({
56 | ui: path.resolve(__dirname, '../src/index.js'),
57 | })
58 | },
59 | },
60 |
61 | devServer: {
62 | // port: 8080,
63 | open: true, // opens browser window automatically
64 | },
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/ui/dev/quasar.extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "@quasar/qmarkdown": {
3 | "import_md": false,
4 | "import_vmd": false
5 | }
6 | }
--------------------------------------------------------------------------------
/ui/dev/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
--------------------------------------------------------------------------------
/ui/dev/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/assets/.gitkeep
--------------------------------------------------------------------------------
/ui/dev/src/boot/register.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import EasyForms from 'quasar-ui-easy-forms'
3 | import VuePlugin from 'ui' // "ui" is aliased in quasar.conf.js
4 |
5 | Vue.use(EasyForms)
6 | Vue.use(VuePlugin)
7 |
--------------------------------------------------------------------------------
/ui/dev/src/boot/vueComponents.js:
--------------------------------------------------------------------------------
1 | import { InfoCard } from 'quasar-ui-component-info-card'
2 | import InfoBoxWrapper from '../components/InfoBoxWrapper'
3 |
4 | export default ({ Vue }) => {
5 | Vue.component(InfoCard.name, InfoCard)
6 | Vue.component(InfoBoxWrapper.name, InfoBoxWrapper)
7 | }
8 |
--------------------------------------------------------------------------------
/ui/dev/src/components/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/components/.gitkeep
--------------------------------------------------------------------------------
/ui/dev/src/components/DialogWrapper.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
14 |
15 |
16 |
17 |
18 |
30 |
31 |
77 |
--------------------------------------------------------------------------------
/ui/dev/src/components/InfoBoxWrapper.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ label }}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
30 |
31 |
52 |
--------------------------------------------------------------------------------
/ui/dev/src/components/MarkdownCode.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
50 |
--------------------------------------------------------------------------------
/ui/dev/src/components/QDialogMethods.js:
--------------------------------------------------------------------------------
1 |
2 | export default {
3 | methods: {
4 | // following method is REQUIRED
5 | // (don't change its name --> "show")
6 | show () {
7 | if (!this.$refs.dialog) return
8 | this.$refs.dialog.show()
9 | },
10 |
11 | // following method is REQUIRED
12 | // (don't change its name --> "hide")
13 | hide () {
14 | if (!this.$refs.dialog) return
15 | this.$refs.dialog.hide()
16 | },
17 |
18 | onDialogHide (val) {
19 | if (val !== undefined) {
20 | return this.Ok(val)
21 | }
22 | // required to be emitted
23 | // when QDialog emits "hide" event
24 | this.$emit('hide')
25 | },
26 |
27 | Ok (val) {
28 | // on Ok, it is REQUIRED to
29 | // emit "ok" event (with optional payload)
30 | // before hiding the QDialog
31 | this.$emit('ok', val)
32 | // or with payload: this.$emit('ok', { ... })
33 |
34 | // then hiding dialog
35 | this.hide()
36 | },
37 |
38 | onCancelClick () {
39 | // we just need to hide dialog
40 | this.hide()
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/ui/dev/src/components/Template.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
12 |
13 |
22 |
--------------------------------------------------------------------------------
/ui/dev/src/components/showMoreWrapper.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
24 | {{ showingMore ? showLess : showMore }}
25 |
26 |
27 |
28 |
29 |
63 |
64 |
94 |
--------------------------------------------------------------------------------
/ui/dev/src/css/app.sass:
--------------------------------------------------------------------------------
1 | // app global css in Sass form
2 | .text-wrap-all
3 | white-space: pre-line
4 | word-break: break-word
5 |
--------------------------------------------------------------------------------
/ui/dev/src/helpers/conversion.js:
--------------------------------------------------------------------------------
1 | import { isFullString } from 'is-what'
2 |
3 | export function stringToJs (string) {
4 | if (!isFullString(string)) return undefined
5 | const jsonString = string.replace(/([a-zA-Z0-9]+?):/g, '"$1":').replace(/'/g, '"')
6 | let parsed
7 | try {
8 | parsed = JSON.parse(jsonString)
9 | } catch (e) {
10 | return string
11 | }
12 | return parsed
13 | }
14 |
--------------------------------------------------------------------------------
/ui/dev/src/helpers/parseCodeForPrint.js:
--------------------------------------------------------------------------------
1 | import { isFunction } from 'is-what'
2 |
3 | export default function parseCodeForPrint (code) {
4 | // return early on 0, undefined, null, etc.
5 | if (!code) return code
6 | const stringifiedFns = []
7 | function replacer (key, value) {
8 | if (isFunction(value) && value.prototype.stringifiedFn) {
9 | const fnString = value.prototype.stringifiedFn
10 | stringifiedFns.push(fnString)
11 | return fnString
12 | }
13 | return value
14 | }
15 | const string = JSON.stringify(code, replacer, 2)
16 | const cleanedString = string.replace(/'/g, `\\'`).replace(/"/g, `'`)
17 | const parsedString = stringifiedFns.reduce((str, fnString) => {
18 | const fnStringRegex = `'${fnString.replace(/'/g, `\\'`).replace(/"/g, `'`)}'`
19 | return str.replace(fnStringRegex, fnString)
20 | }, cleanedString)
21 | return parsedString
22 | }
23 |
--------------------------------------------------------------------------------
/ui/dev/src/helpers/schemaBuilders.js:
--------------------------------------------------------------------------------
1 | import { isArray, isUndefined, isFunction } from 'is-what'
2 | import copy from 'copy-anything'
3 | import merge from 'merge-anything'
4 | import { stringToJs } from './conversion'
5 |
6 | export function propToPropSchema (propKey, propInfo) {
7 | const { desc, type, inheritedProp, examples, default: df, values, category } = propInfo
8 | // make the raw prop info from the components into an EasyForm:
9 | // whatever the prop is, default to an 'input' EasyField
10 | const events = {}
11 | let component = 'QInput'
12 | let subLabel = desc
13 | let options,
14 | outlined,
15 | standout,
16 | disable,
17 | parseInput,
18 | parseValue,
19 | autogrow,
20 | debounce,
21 | span,
22 | emitValue
23 | let fieldClasses = []
24 | let _default = df === true || undefined
25 | // If it has a default, write it in the description
26 | if (!isUndefined(df)) subLabel += `\n\nDefault: \`${isFunction(df) ? JSON.stringify(df()) : df}\``
27 | // if the prop is a Boolean, show this as a 'toggle' EasyField
28 | if (type === Boolean || (isArray(type) && type.includes(Boolean))) {
29 | component = 'QToggle'
30 | _default = df === true
31 | }
32 | // if the prop has a fixed set of possible values, show this as an 'option' EasyField
33 | const propHasValues = isArray(values) && values.length
34 | if (propHasValues) {
35 | component = 'QSelect'
36 | emitValue = true
37 | options = values.map(v => ({ label: v, value: v }))
38 | }
39 | // Create a special input for defining arrays and/or objects
40 | if (
41 | type === Array ||
42 | type === Object ||
43 | type === Function ||
44 | (isArray(type) && [Array, Object].some(t => type.includes(t)) && type.length === 2)
45 | ) {
46 | // events.blur = (e, val) => console.log(stringToJs(val))
47 | outlined = false
48 | standout = true
49 | debounce = 500
50 | parseInput = stringToJs
51 | parseValue = JSON.stringify
52 | autogrow = true
53 | if (isArray(examples)) subLabel += `\nExamples: \`${examples.join('` | `')}\``
54 | }
55 | // Don't allow editing props that accept functions.
56 | if (type === Function) disable = true
57 | // If it's the prop called 'schema', span the entire form, add extra info and don't return any input field
58 | if (propKey === 'schema') {
59 | component = ''
60 | span = true
61 | subLabel +=
62 | '\n\n> 👀 Check「Source tab」→「Schema」to see the following code in color and with indentation.'
63 | }
64 | // Create the EasyField schema for the prop
65 | return {
66 | id: propKey,
67 | component,
68 | type: type === Number ? 'number' : undefined,
69 | // schema,
70 | label: propKey,
71 | subLabel,
72 | placeholder: !isArray(examples) ? '' : examples.join(', '),
73 | inheritedProp,
74 | options,
75 | outlined,
76 | standout,
77 | disable,
78 | parseInput,
79 | parseValue,
80 | autogrow,
81 | category,
82 | fieldClasses,
83 | debounce,
84 | events,
85 | span,
86 | emitValue,
87 | // if the prop is `true` by default, set to true
88 | default: _default,
89 | // defaults
90 | hasMarkdown: true,
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/ui/dev/src/index.template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= htmlWebpackPlugin.options.productName %>
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ui/dev/src/layouts/MyLayout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | quasar-ui-easy-tables v{{ version }}
8 |
9 | Quasar v{{ $q.version }}
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
32 |
--------------------------------------------------------------------------------
/ui/dev/src/pages/EasyTableDemo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
14 |
20 |
21 |
22 |
23 |
24 |
37 |
38 |
102 |
--------------------------------------------------------------------------------
/ui/dev/src/pages/Index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | < EasyTable />
5 | Generate an entire table via just a "schema" object
6 |
7 |
8 |
9 |
10 |
11 | {{ page.title }}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Essential Links
20 |
21 |
27 |
28 |
43 |
44 |
45 | Github
46 | mesqueeb/quasar-ui-easy-tables
47 |
48 |
49 |
50 |
51 |
52 |
57 |
58 |
59 | Twitter
60 | @mesqueeb
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | Quasar Framework
70 | quasar.dev
71 |
72 |
73 |
74 |
75 |
76 |
77 |
95 |
96 |
102 |
--------------------------------------------------------------------------------
/ui/dev/src/pages/SlotsDemo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
14 |
24 |
32 |
33 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
54 |
55 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
76 |
77 |
78 | < template v-slot:above-nav-row>< /template>
79 |
80 |
81 |
82 |
83 | < template v-slot:top-left>< /template>
84 |
85 |
86 |
87 |
88 | < template v-slot:top-right>< /template>
89 |
90 |
91 |
92 |
93 | < template v-slot:above-table>< /template>
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
117 |
118 |
184 |
--------------------------------------------------------------------------------
/ui/dev/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 |
4 | import routes from './routes'
5 |
6 | Vue.use(VueRouter)
7 |
8 | /*
9 | * If not building with SSR mode, you can
10 | * directly export the Router instantiation
11 | */
12 |
13 | export default function (/* { store, ssrContext } */) {
14 | const Router = new VueRouter({
15 | scrollBehavior: () => ({ x: 0, y: 0 }),
16 | routes,
17 |
18 | // Leave these as is and change from quasar.conf.js instead!
19 | // quasar.conf.js -> build -> vueRouterMode
20 | // quasar.conf.js -> build -> publicPath
21 | mode: process.env.VUE_ROUTER_MODE,
22 | base: process.env.VUE_ROUTER_BASE
23 | })
24 |
25 | // we get each page from server first!
26 | if (process.env.MODE === 'ssr' && process.env.CLIENT) {
27 | console.log('!!!!')
28 | console.log('On route change we deliberately load page from server -- in order to test hydration errors')
29 | console.log('!!!!')
30 |
31 | let reload = false
32 | Router.beforeEach((to, _, next) => {
33 | if (reload) {
34 | window.location.href = to.fullPath
35 | return
36 | }
37 | reload = true
38 | next()
39 | })
40 | }
41 |
42 | return Router
43 | }
44 |
--------------------------------------------------------------------------------
/ui/dev/src/router/routes.js:
--------------------------------------------------------------------------------
1 | const routes = [
2 | {
3 | path: '/',
4 | component: () => import('layouts/MyLayout.vue'),
5 | children: [
6 | { path: '', component: () => import('pages/Index.vue') },
7 | { path: '/slots', component: () => import('pages/SlotsDemo.vue') },
8 | { path: '/:schemaId', component: () => import('pages/EasyTableDemo.vue'), props: true },
9 | ],
10 | },
11 | ]
12 |
13 | export default routes
14 |
--------------------------------------------------------------------------------
/ui/dev/src/schemas/examples/basics.js:
--------------------------------------------------------------------------------
1 | const rows = [
2 | {
3 | title: 'Mathematica',
4 | topic: 'curriculum',
5 | subject: 'We will look at the curriculum of the Mathematica √/%^×-+÷',
6 | img:
7 | 'https://images.unsplash.com/photo-1509228468518-180dd4864904?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=160',
8 | grade: 90000,
9 | passing: true,
10 | created: new Date(),
11 | classes: [{ label: 'One', value: '1' }],
12 | },
13 | {
14 | title: 'Films',
15 | topic: 'split',
16 | subject: 'We will look at the split of the Films √/%^×-+÷',
17 | img:
18 | 'https://images.unsplash.com/photo-1509228468518-180dd4864904?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=160',
19 | grade: 80000,
20 | passing: false,
21 | created: new Date('2020/01/01'),
22 | classes: [{ label: 'One', value: '1' }],
23 | },
24 | {
25 | title: 'Winds',
26 | topic: 'north',
27 | subject: 'We will look at the north of the Winds √/%^×-+÷',
28 | img:
29 | 'https://images.unsplash.com/photo-1509228468518-180dd4864904?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=160',
30 | grade: 120000,
31 | passing: false,
32 | created: new Date(),
33 | classes: [{ label: 'Two', value: '2' }],
34 | },
35 | {
36 | title: 'Apps',
37 | topic: 'hotdog',
38 | subject: 'We will look at the hotdog of the Apps √/%^×-+÷',
39 | img:
40 | 'https://images.unsplash.com/photo-1509228468518-180dd4864904?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=160',
41 | grade: 25,
42 | passing: true,
43 | created: new Date('1990-01-01'),
44 | classes: [
45 | { label: 'One', value: '1' },
46 | { label: 'Two', value: '2' },
47 | ],
48 | },
49 | {
50 | title: 'Computers',
51 | topic: 'hardware',
52 | subject: 'We will look at the hardware of the Computers √/%^×-+÷',
53 | img:
54 | 'https://images.unsplash.com/photo-1509228468518-180dd4864904?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=160',
55 | grade: 0,
56 | passing: false,
57 | created: new Date(),
58 | classes: [{ label: 'One', value: '1' }],
59 | },
60 | ]
61 |
62 | export default {
63 | title: 'My Lessons',
64 | rows,
65 | schemaColumns: [
66 | {
67 | id: 'title',
68 | label: 'Lesson Title',
69 | component: 'QInput',
70 | },
71 | {
72 | id: 'topic',
73 | label: 'Topic',
74 | component: 'QInput',
75 | },
76 | {
77 | id: 'subject',
78 | label: 'Subject',
79 | component: 'QInput',
80 | },
81 | {
82 | id: 'img',
83 | label: 'Image',
84 | component: 'QImg',
85 | mode: 'view',
86 | evaluatedProps: ['src'],
87 | internalErrors: true,
88 | // component props:
89 | src: val => val,
90 | },
91 | {
92 | id: 'grade',
93 | label: 'Grade',
94 | component: 'QInput',
95 | // component props:
96 | type: 'number',
97 | },
98 | {
99 | id: 'passing',
100 | label: 'Passing',
101 | component: 'QToggle',
102 | default: false,
103 | },
104 | {
105 | id: 'created',
106 | label: 'Created at',
107 | component: 'QInput',
108 | parseInput: val => new Date(val),
109 | dateFormat: 'YYYY/MM/DD',
110 | valueType: 'date',
111 | // component props:
112 | mask: '####/##/##',
113 | placeholder: 'YYYY/MM/DD',
114 | },
115 | {
116 | id: 'classes',
117 | label: 'Classes',
118 | component: 'QSelect',
119 | // component props:
120 | multiple: true,
121 | options: [
122 | { label: 'One', value: '1' },
123 | { label: 'Two', value: '2' },
124 | { label: 'Three', value: '3' },
125 | ],
126 | },
127 | ],
128 | get schemaGrid () {
129 | return this.schemaColumns
130 | },
131 | }
132 |
--------------------------------------------------------------------------------
/ui/dev/src/schemas/examples/computedFields.js:
--------------------------------------------------------------------------------
1 | import { isFunction } from 'is-what'
2 |
3 | const rows = [
4 | { firstName: 'Taylor', lastName: 'Roach' },
5 | { firstName: 'Corey', lastName: 'Carson' },
6 | { firstName: 'Alden', lastName: 'Cantrell' },
7 | { firstName: 'Ezequiel', lastName: 'Davenport' },
8 | { firstName: 'Kendrick', lastName: 'Schultz' },
9 | { firstName: 'Bradyn', lastName: 'Arroyo' },
10 | { firstName: 'Kade', lastName: 'Craig' },
11 | { firstName: 'Carissa', lastName: 'Atkinson' },
12 | { firstName: 'Zaire', lastName: 'Lambert' },
13 | { firstName: 'Alec', lastName: 'Villanueva' },
14 | { firstName: 'Sheldon', lastName: 'Rogers' },
15 | { firstName: 'Celeste', lastName: 'Trujillo' },
16 | ]
17 |
18 | export default {
19 | title: 'My Lessons',
20 | rows,
21 | schemaColumns: [
22 | {
23 | id: 'fullName',
24 | label: 'Full name',
25 | component: 'QInput',
26 | parseValue: (val, { formData, fieldInput }) => {
27 | const value = `${formData.firstName || ''} ${formData.lastName || ''}`.trim()
28 | fieldInput({ id: 'fullName', value })
29 | return value
30 | },
31 | },
32 | ],
33 | get schemaGrid () {
34 | return this.schemaColumns
35 | },
36 | }
37 |
--------------------------------------------------------------------------------
/ui/dev/src/schemas/examples/editing.js:
--------------------------------------------------------------------------------
1 | import { Dialog } from 'quasar'
2 | import DialogWrapper from '../../components/DialogWrapper.vue'
3 | // For more info on this DialogWrapper see:
4 | // https://github.com/mesqueeb/quasar-ui-easy-tables/blob/master/ui/dev/src/components/DialogWrapper.vue
5 |
6 | const schemaColumns = [
7 | {
8 | id: 'name',
9 | label: 'Name',
10 | component: 'QInput',
11 | },
12 | {
13 | id: 'img',
14 | label: 'Profile picture',
15 | component: 'QImg',
16 | mode: 'view',
17 | evaluatedProps: ['src'],
18 | internalErrors: true,
19 | // component props:
20 | src: val => val,
21 | },
22 | {
23 | id: 'level',
24 | label: 'Level',
25 | component: 'QInput',
26 | // component props:
27 | type: 'number',
28 | },
29 | {
30 | id: 'darkSide',
31 | label: 'Dark side',
32 | component: 'QToggle',
33 | default: false,
34 | },
35 | {
36 | id: 'birthdate',
37 | label: 'Created at',
38 | component: 'QInput',
39 | parseInput: val => new Date(val),
40 | valueType: 'date',
41 | // component props:
42 | mask: '####/##/##',
43 | placeholder: 'YYYY/MM/DD',
44 | dateFormat: 'YYYY/MM/DD',
45 | },
46 | {
47 | id: 'trialsCompleted',
48 | label: 'Trials completed',
49 | component: 'QSelect',
50 | // component props:
51 | multiple: true,
52 | options: [
53 | { label: 'One', value: '1' },
54 | { label: 'Two', value: '2' },
55 | { label: 'Three', value: '3' },
56 | ],
57 | },
58 | ]
59 | const rows = [
60 | {
61 | id: 'abc123',
62 | name: 'Luke',
63 | img:
64 | 'https://images.unsplash.com/photo-1509228468518-180dd4864904?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=160',
65 | level: 90000,
66 | darkSide: true,
67 | birthdate: new Date(),
68 | trialsCompleted: [{ label: 'One', value: '1' }],
69 | },
70 | {
71 | id: 'def456',
72 | name: 'Leia',
73 | img:
74 | 'https://images.unsplash.com/photo-1509228468518-180dd4864904?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=160',
75 | level: 80000,
76 | darkSide: false,
77 | birthdate: new Date('1990-01-01'),
78 | trialsCompleted: [{ label: 'Two', value: '2' }],
79 | },
80 | ]
81 |
82 | export default {
83 | rows,
84 | schemaColumns,
85 | schemaGrid: schemaColumns,
86 | events: {
87 | 'row-click': (event, rowData) => {
88 | Dialog.create({
89 | // tell Quasar's Dialog plugin to use DialogWrapper.vue
90 | component: DialogWrapper,
91 | parent: this,
92 | // tell DialogWrapper.vue to use an EasyForm
93 | slotComponent: 'EasyForm',
94 | // props bound to EasyForm via v-bind="slotProps"
95 | slotProps: {
96 | actionButtons: ['edit', 'cancel', 'save'],
97 | value: rowData,
98 | schema: schemaColumns,
99 | class: 'q-pa-lg',
100 | mode: 'edit',
101 | },
102 | // events bound to EasyForm via v-on="slotEvents"
103 | slotEvents: ({ hide }) => ({
104 | cancel: hide,
105 | save: ({ newData }) => {
106 | const { id: rowId } = rowData
107 | const rowToUpdate = rows.find(r => r.id === rowId)
108 | Object.entries(newData).forEach(([fieldId, value]) => {
109 | rowToUpdate[fieldId] = value
110 | })
111 | hide()
112 | },
113 | }),
114 | })
115 | },
116 | },
117 | }
118 |
--------------------------------------------------------------------------------
/ui/dev/src/schemas/examples/editing2.js:
--------------------------------------------------------------------------------
1 | import { Dialog } from 'quasar'
2 | import DialogWrapper from '../../components/DialogWrapper.vue'
3 | // For more info on this DialogWrapper see:
4 | // https://github.com/mesqueeb/quasar-ui-easy-tables/blob/master/ui/dev/src/components/DialogWrapper.vue
5 |
6 | const schemaColumns = [
7 | {
8 | id: 'name',
9 | label: 'Name',
10 | component: 'QInput',
11 | },
12 | {
13 | id: 'img',
14 | label: 'Profile picture',
15 | component: 'QImg',
16 | mode: 'view',
17 | evaluatedProps: ['src'],
18 | internalErrors: true,
19 | // component props:
20 | src: val => val,
21 | },
22 | {
23 | id: 'level',
24 | label: 'Level',
25 | component: 'QInput',
26 | // component props:
27 | type: 'number',
28 | },
29 | {
30 | id: 'darkSide',
31 | label: 'Dark side',
32 | component: 'QToggle',
33 | default: false,
34 | },
35 | {
36 | id: 'birthdate',
37 | label: 'Created at',
38 | component: 'QInput',
39 | parseInput: val => new Date(val),
40 | valueType: 'date',
41 | // component props:
42 | mask: '####/##/##',
43 | placeholder: 'YYYY/MM/DD',
44 | dateFormat: 'YYYY/MM/DD',
45 | },
46 | {
47 | id: 'trialsCompleted',
48 | label: 'Trials completed',
49 | component: 'QSelect',
50 | // component props:
51 | multiple: true,
52 | options: [
53 | { label: 'One', value: '1' },
54 | { label: 'Two', value: '2' },
55 | { label: 'Three', value: '3' },
56 | ],
57 | },
58 | ]
59 | const rows = [
60 | {
61 | id: 'abc123',
62 | name: 'Luke',
63 | img:
64 | 'https://images.unsplash.com/photo-1509228468518-180dd4864904?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=160',
65 | level: 90000,
66 | darkSide: true,
67 | birthdate: new Date(),
68 | trialsCompleted: [{ label: 'One', value: '1' }],
69 | },
70 | {
71 | id: 'def456',
72 | name: 'Leia',
73 | img:
74 | 'https://images.unsplash.com/photo-1509228468518-180dd4864904?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=160',
75 | level: 80000,
76 | darkSide: false,
77 | birthdate: new Date('1990-01-01'),
78 | trialsCompleted: [{ label: 'Two', value: '2' }],
79 | },
80 | ]
81 |
82 | export default {
83 | rows,
84 | schemaColumns: [
85 | {
86 | id: 'edit-btn',
87 | component: 'EfBtn',
88 | btnLabel: 'Edit',
89 | mode: 'edit',
90 | unelevated: true,
91 | size: 'sm',
92 | dense: true,
93 | hideBottomSpace: true,
94 | events: {
95 | click: (event, { formData }) => {
96 | Dialog.create({
97 | // tell Quasar's Dialog plugin to use DialogWrapper.vue
98 | component: DialogWrapper,
99 | parent: this,
100 | // tell DialogWrapper.vue to use an EasyForm
101 | slotComponent: 'EasyForm',
102 | // props bound to EasyForm via v-bind="slotProps"
103 | slotProps: {
104 | actionButtons: ['edit', 'cancel', 'save'],
105 | value: formData,
106 | schema: schemaColumns,
107 | class: 'q-pa-lg',
108 | mode: 'edit',
109 | },
110 | // events bound to EasyForm via v-on="slotEvents"
111 | slotEvents: ({ hide }) => ({
112 | cancel: hide,
113 | save: ({ newData }) => {
114 | const { id: rowId } = formData
115 | const rowToUpdate = rows.find(r => r.id === rowId)
116 | Object.entries(newData).forEach(([fieldId, value]) => {
117 | rowToUpdate[fieldId] = value
118 | })
119 | hide()
120 | },
121 | }),
122 | })
123 | },
124 | },
125 | },
126 | ].concat(schemaColumns),
127 | }
128 |
--------------------------------------------------------------------------------
/ui/dev/src/schemas/examples/index.js:
--------------------------------------------------------------------------------
1 | export const basics = {
2 | code: [require('./basics').default],
3 | string: [require('!!raw-loader!./basics').default],
4 | }
5 | export const editing = {
6 | code: [require('./editing').default, require('./editing2').default],
7 | string: [require('!!raw-loader!./editing').default, require('!!raw-loader!./editing2').default],
8 | }
9 | export const slots = {
10 | code: [require('./slots').default],
11 | string: [require('!!raw-loader!./slots').default],
12 | }
13 | export const computedFields = {
14 | code: [require('./computedFields').default],
15 | string: [require('!!raw-loader!./computedFields').default],
16 | }
17 | export const selection = {
18 | code: [require('./selection').default],
19 | string: [require('!!raw-loader!./selection').default],
20 | }
21 |
--------------------------------------------------------------------------------
/ui/dev/src/schemas/examples/selection.js:
--------------------------------------------------------------------------------
1 | import { isFunction } from 'is-what'
2 |
3 | const rows = [
4 | { fullName: 'Taylor Roach', id: 'taylor-roach' },
5 | { fullName: 'Corey Carson', id: 'corey-carson' },
6 | { fullName: 'Alden Cantrell', id: 'alden-cantrell' },
7 | { fullName: 'Ezequiel Davenport', id: 'ezequiel-davenport' },
8 | { fullName: 'Kendrick Schultz', id: 'kendrick-schultz' },
9 | { fullName: 'Bradyn Arroyo', id: 'bradyn-arroyo' },
10 | { fullName: 'Kade Craig', id: 'kade-craig' },
11 | { fullName: 'Carissa Atkinson', id: 'carissa-atkinson' },
12 | { fullName: 'Zaire Lambert', id: 'zaire-lambert' },
13 | { fullName: 'Alec Villanueva', id: 'alec-villanueva' },
14 | { fullName: 'Sheldon Rogers', id: 'sheldon-rogers' },
15 | { fullName: 'Celeste Trujillo', id: 'celeste-trujillo' },
16 | ]
17 |
18 | const table = {
19 | selection: 'multiple',
20 | title: 'My Lessons',
21 | rows,
22 | schemaColumns: [
23 | {
24 | id: 'fullName',
25 | label: 'Full name',
26 | component: 'QInput',
27 | },
28 | ],
29 | get schemaGrid () {
30 | return this.schemaColumns
31 | },
32 | selected: [],
33 | events: {
34 | 'update:selected': selection => {
35 | table.selected = selection
36 | },
37 | },
38 | }
39 | export default table
40 |
--------------------------------------------------------------------------------
/ui/dev/src/schemas/examples/slots.js:
--------------------------------------------------------------------------------
1 | const rows = [
2 | {
3 | title: 'Mathematica',
4 | topic: 'curriculum',
5 | subject: 'We will look at the Mathematica of the Maths √/%^×-+÷',
6 | img:
7 | 'https://images.unsplash.com/photo-1509228468518-180dd4864904?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=160',
8 | grade: 90000,
9 | passing: true,
10 | created: new Date(),
11 | classes: [{ label: 'One', value: '1' }],
12 | },
13 | {
14 | title: 'Mathematica',
15 | topic: 'split',
16 | subject: 'We will look at the Mathematica of the Maths √/%^×-+÷',
17 | img:
18 | 'https://images.unsplash.com/photo-1509228468518-180dd4864904?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=160',
19 | grade: 90000,
20 | passing: false,
21 | created: new Date(),
22 | classes: [{ label: 'One', value: '1' }],
23 | },
24 | {
25 | title: 'Mathematica',
26 | topic: 'north',
27 | subject: 'We will look at the Mathematica of the Maths √/%^×-+÷',
28 | img:
29 | 'https://images.unsplash.com/photo-1509228468518-180dd4864904?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=160',
30 | grade: 90000,
31 | passing: true,
32 | created: new Date(),
33 | classes: [{ label: 'One', value: '1' }],
34 | },
35 | {
36 | title: 'Mathematica',
37 | topic: 'hotdog',
38 | subject: 'We will look at the Mathematica of the Maths √/%^×-+÷',
39 | img:
40 | 'https://images.unsplash.com/photo-1509228468518-180dd4864904?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=160',
41 | grade: 90000,
42 | passing: true,
43 | created: new Date(),
44 | classes: [{ label: 'One', value: '1' }],
45 | },
46 | {
47 | title: 'Mathematica',
48 | topic: 'hardware',
49 | subject: 'We will look at the Mathematica of the Maths √/%^×-+÷',
50 | img:
51 | 'https://images.unsplash.com/photo-1509228468518-180dd4864904?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=160',
52 | grade: 90000,
53 | passing: true,
54 | created: new Date(),
55 | classes: [{ label: 'One', value: '1' }],
56 | },
57 | ]
58 |
59 | export default {
60 | title: 'My Lessons',
61 | rows,
62 | schemaColumns: [
63 | {
64 | id: 'title',
65 | label: 'Lesson Title',
66 | component: 'QInput',
67 | },
68 | {
69 | id: 'topic',
70 | label: 'Topic',
71 | component: 'QInput',
72 | },
73 | {
74 | id: 'subject',
75 | label: 'Subject',
76 | component: 'QInput',
77 | },
78 | {
79 | id: 'img',
80 | label: 'Image',
81 | component: 'QImg',
82 | mode: 'view',
83 | evaluatedProps: ['src'],
84 | internalErrors: true,
85 | // component props:
86 | src: val => val,
87 | },
88 | {
89 | id: 'grade',
90 | label: 'Grade',
91 | component: 'QInput',
92 | // component props:
93 | type: 'number',
94 | },
95 | {
96 | id: 'passing',
97 | label: 'Passing',
98 | component: 'QToggle',
99 | default: false,
100 | },
101 | {
102 | id: 'created',
103 | label: 'Created at',
104 | component: 'QInput',
105 | parseInput: val => new Date(val),
106 | dateFormat: 'YYYY/MM/DD',
107 | valueType: 'date',
108 | // component props:
109 | mask: '####/##/##',
110 | placeholder: 'YYYY/MM/DD',
111 | },
112 | {
113 | id: 'classes',
114 | label: 'Classes',
115 | component: 'QSelect',
116 | // component props:
117 | multiple: true,
118 | options: [
119 | { label: 'One', value: '1' },
120 | { label: 'Two', value: '2' },
121 | { label: 'Three', value: '3' },
122 | ],
123 | },
124 | ],
125 | get schemaGrid () {
126 | return this.schemaColumns
127 | },
128 | }
129 |
--------------------------------------------------------------------------------
/ui/dev/src/schemas/pages/basics.js:
--------------------------------------------------------------------------------
1 | const description = `\`\` is Quasar's QTable but with the allows you to define columns & grid-cards via the schema syntax of [EasyForms](https://quasar-easy-forms.web.app).
2 |
3 | A single schema object describing the fields in your data can be used for:
4 | - defining the columns of an EasyTable
5 | - defining the fields to show on each card for the grid-view of the EasyTable
6 | - an EasyForm to be show in a pop-up on eg. clicking a row
7 |
8 | Of course you can also use all of Quasar's QTable props on and they will be passed to .
9 |
10 | See below the interactive demo. You can check the source code, as well as _edit_ any prop and see its effect immidiately!`
11 |
12 | export default {
13 | mode: 'edit',
14 | actionButtons: [],
15 | schema: [
16 | {
17 | component: 'QMarkdown',
18 | src: description,
19 | noContainer: true,
20 | noLineNumbers: true,
21 | },
22 | ],
23 | }
24 |
--------------------------------------------------------------------------------
/ui/dev/src/schemas/pages/computedFields.js:
--------------------------------------------------------------------------------
1 | const description = `This is an example of a table with [Computed Fields](https://quasar-easy-forms.web.app/computedFields).
2 |
3 | For this example we used a Computed Field that's not yet saved to the database and is computed on the fly when showing the table.
4 |
5 | `
6 |
7 | export default {
8 | mode: 'edit',
9 | actionButtons: [],
10 | schema: [
11 | {
12 | component: 'QMarkdown',
13 | src: description,
14 | noContainer: true,
15 | noLineNumbers: true,
16 | },
17 | ],
18 | }
19 |
--------------------------------------------------------------------------------
/ui/dev/src/schemas/pages/editing.js:
--------------------------------------------------------------------------------
1 | const description = `Since an \`\` is based on the [EasyForms](https://quasar-easy-forms.web.app) schema system, it's possible to easily implement stuff like inline editing; popup editing; or show an editable form on a row click.`
2 |
3 | export default {
4 | mode: 'edit',
5 | actionButtons: [],
6 | schema: Object.values({
7 | _1: {
8 | component: 'QMarkdown',
9 | src: description,
10 | noContainer: true,
11 | noLineNumbers: true,
12 | },
13 | get _2 () {
14 | return {
15 | id: 'chosenExample',
16 | component: 'QBtnToggle',
17 | spread: true,
18 | noCaps: true,
19 | options: [this._3, this._4].map((field, index) => {
20 | return { label: field.label, value: index }
21 | }),
22 | }
23 | },
24 | _3: {
25 | showCondition: (value, { formData }) => formData.chosenExample === 0,
26 | label: 'Editable form on row click',
27 | span: true,
28 | evaluatedProps: ['showCondition'],
29 | },
30 | _4: {
31 | showCondition: (value, { formData }) => formData.chosenExample === 1,
32 | label: 'Editable form on button click',
33 | span: true,
34 | evaluatedProps: ['showCondition'],
35 | },
36 | }),
37 | }
38 |
--------------------------------------------------------------------------------
/ui/dev/src/schemas/pages/index.js:
--------------------------------------------------------------------------------
1 | export { default as basics } from './basics'
2 | export { default as editing } from './editing'
3 | export { default as slots } from './slots'
4 | export { default as computedFields } from './computedFields'
5 | export { default as selection } from './selection'
6 |
--------------------------------------------------------------------------------
/ui/dev/src/schemas/pages/selection.js:
--------------------------------------------------------------------------------
1 | const description = `By default selection is implemented for both table and grid view, however, every row NEEDS an 'id' prop in order for it to work.
2 |
3 | CSS can be overwritten with these classes:
4 | - \`.easy-table__grid-item.selected\`
5 |
6 | - \`.easy-table__row.selected\`
7 | `
8 |
9 | export default {
10 | mode: 'edit',
11 | actionButtons: [],
12 | schema: [
13 | {
14 | component: 'QMarkdown',
15 | src: description,
16 | noContainer: true,
17 | noLineNumbers: true,
18 | },
19 | ],
20 | }
21 |
--------------------------------------------------------------------------------
/ui/dev/src/schemas/pages/slots.js:
--------------------------------------------------------------------------------
1 | const description = `You can use slots with EasyTable.
2 |
3 | ### EasyTable specific slots:
4 | - above-nav-row
5 | - above-table
6 |
7 | ### Quasar's QTable slots:
8 | You can use all Quasar slots "around" the table. However, EasyTable uses these slots to generate its content: \`body\` for the rows, \`item\` for the cards in grid mode.
9 |
10 | If you find yourself in a spot where you also want to use slots for the rows or items, you are probably better off using a regular QTable, perhaps in combination with quasar-easy-forms. Feel free to look at my source code for how I built the EasyTable component. 😉
11 |
12 | > Please note that while the examples below show slot usage in the preview, they don't correctly show the use of the slots in the source code > template yet. I still have to improve this example. 😂
13 | `
14 |
15 | export default {
16 | mode: 'edit',
17 | actionButtons: [],
18 | schema: [
19 | {
20 | component: 'QMarkdown',
21 | src: description,
22 | noContainer: true,
23 | noLineNumbers: true,
24 | },
25 | ],
26 | }
27 |
--------------------------------------------------------------------------------
/ui/dev/src/statics/app-logo-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/statics/app-logo-128x128.png
--------------------------------------------------------------------------------
/ui/dev/src/statics/icons/apple-icon-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/statics/icons/apple-icon-120x120.png
--------------------------------------------------------------------------------
/ui/dev/src/statics/icons/apple-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/statics/icons/apple-icon-152x152.png
--------------------------------------------------------------------------------
/ui/dev/src/statics/icons/apple-icon-167x167.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/statics/icons/apple-icon-167x167.png
--------------------------------------------------------------------------------
/ui/dev/src/statics/icons/apple-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/statics/icons/apple-icon-180x180.png
--------------------------------------------------------------------------------
/ui/dev/src/statics/icons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/statics/icons/favicon-16x16.png
--------------------------------------------------------------------------------
/ui/dev/src/statics/icons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/statics/icons/favicon-32x32.png
--------------------------------------------------------------------------------
/ui/dev/src/statics/icons/favicon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/statics/icons/favicon-96x96.png
--------------------------------------------------------------------------------
/ui/dev/src/statics/icons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/statics/icons/favicon.ico
--------------------------------------------------------------------------------
/ui/dev/src/statics/icons/icon-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/statics/icons/icon-128x128.png
--------------------------------------------------------------------------------
/ui/dev/src/statics/icons/icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/statics/icons/icon-192x192.png
--------------------------------------------------------------------------------
/ui/dev/src/statics/icons/icon-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/statics/icons/icon-256x256.png
--------------------------------------------------------------------------------
/ui/dev/src/statics/icons/icon-384x384.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/statics/icons/icon-384x384.png
--------------------------------------------------------------------------------
/ui/dev/src/statics/icons/icon-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/statics/icons/icon-512x512.png
--------------------------------------------------------------------------------
/ui/dev/src/statics/icons/ms-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/dev/src/statics/icons/ms-icon-144x144.png
--------------------------------------------------------------------------------
/ui/dev/src/statics/icons/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ui/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "quasar-ui-easy-tables",
3 | "version": "0.8.6",
4 | "author": "Luca Ban - Mesqueeb",
5 | "description": "A Vue plugin (that uses Quasar components) to easily generate tables by only defining a \"schema\" object.",
6 | "license": "MIT",
7 | "module": "dist/index.esm.js",
8 | "main": "dist/index.common.js",
9 | "scripts": {
10 | "deploy": "npm run build && cd dev && npm run deploy && cd .. && npm publish && cd ../app-extension && npm publish",
11 | "dev": "cd dev && yarn dev && cd ..",
12 | "dev:umd": "yarn build && node build/script.open-umd.js",
13 | "dev:ssr": "cd dev && yarn 'dev:ssr' && cd ..",
14 | "dev:ios": "cd dev && yarn 'dev:ios' && cd ..",
15 | "dev:android": "cd dev && yarn 'dev:android' && cd ..",
16 | "dev:electron": "cd dev && yarn 'dev:electron' && cd ..",
17 | "build": "node build/index.js",
18 | "build:js": "node build/script.javascript.js"
19 | },
20 | "repository": {
21 | "type": "git",
22 | "url": "https://github.com/mesqueeb/quasar-ui-easy-tables"
23 | },
24 | "bugs": "https://github.com/mesqueeb/quasar-ui-easy-tables/issues",
25 | "homepage": "https://quasar-easy-tables.web.app",
26 | "peerDependencies": {
27 | "quasar-ui-easy-forms": "^2.3.4"
28 | },
29 | "devDependencies": {
30 | "@rollup/plugin-buble": "^0.21.3",
31 | "@rollup/plugin-json": "^4.0.3",
32 | "chalk": "^2.4.2",
33 | "fs-extra": "^8.1.0",
34 | "open": "^6.4.0",
35 | "quasar": "^1.12.0",
36 | "quasar-ui-easy-forms": "^2.3.4",
37 | "rimraf": "^3.0.2",
38 | "rollup": "^1.32.1",
39 | "rollup-plugin-vue": "^5.1.9",
40 | "ts-toolbelt": "^6.9.4",
41 | "uglify-es": "^3.3.10",
42 | "vue-template-compiler": "^2.6.11",
43 | "zlib": "^1.0.5"
44 | },
45 | "browserslist": ["last 1 version, not dead, ie >= 11"],
46 | "dependencies": {
47 | "@rollup/plugin-commonjs": "^11.1.0",
48 | "@rollup/plugin-node-resolve": "^6.1.0",
49 | "commafy-anything": "^1.1.3",
50 | "copy-anything": "^1.6.0",
51 | "flatten-anything": "^1.4.1",
52 | "is-what": "^3.11.3",
53 | "merge-anything": "^2.4.4",
54 | "nestify-anything": "0.0.1",
55 | "path-to-prop": "0.0.3"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/ui/src/components/EasyCell.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
12 |
13 |
101 |
--------------------------------------------------------------------------------
/ui/src/components/EasyRow.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
17 |
18 |
105 |
--------------------------------------------------------------------------------
/ui/src/components/EasyTable.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 | {{ title }}
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
25 |
27 |
28 |
36 |
37 |
43 | onInputCell(rowId, fieldId, value, origin)
53 | "
54 | v-slot="EasyFormSimulatedContext"
55 | >
56 |
57 |
58 |
59 |
60 |
61 | onRowClick(e, rowProps.row)"
66 | >
67 |
68 | onInputCell(rowProps.row.id, blueprint.id, val, origin)"
72 | />
73 |
74 |
75 |
76 |
77 |
78 | onRowClick(e, gridItemProps.row, 'grid', gridItemProps)"
88 | >
89 |
96 | onInputCell(gridItemProps.row.id, fieldId, value, origin)
97 | "
98 | />
99 |
100 |
101 |
102 |
103 |
104 |
136 |
137 |
420 |
--------------------------------------------------------------------------------
/ui/src/helpers/dateHelpers.js:
--------------------------------------------------------------------------------
1 | import { isString, isDate } from 'is-what'
2 | import { date } from 'quasar'
3 | const { formatDate, adjustDate } = date
4 |
5 | export function dateStamp (date, format) {
6 | if (isString(date)) date = new Date(date)
7 | if (!isDate(date)) return 'null'
8 | if (format === 'short') return formatDate(date, 'YYYY/MM/DD')
9 | if (isString(format)) return formatDate(date, format)
10 | return formatDate(date, 'YYYY年MM月DD日')
11 | }
12 |
13 | export function timeStamp (date) {
14 | if (isString(date)) date = new Date(date)
15 | if (!isDate(date)) return '00:00'
16 | return formatDate(date, 'HH:mm')
17 | }
18 |
19 | export function dateTimeStamp (date) {
20 | return dateStamp(date) + ' ' + timeStamp(date)
21 | }
22 |
23 | /**
24 | * Create a new date object from a dateStamp and timeStamp
25 | *
26 | * @export
27 | * @param {(string|date)} dateStamp eg. 2019-12-31 - a date string or date object
28 | * @param {string} timeStamp eg. 23:59 time in the 24h format
29 | * @returns {date}
30 | */
31 | export function makeDateFromStamps (dateStamp, timeStamp) {
32 | let date = dateStamp
33 | if (isString(date)) date = new Date(date)
34 | if (!isDate(date)) throw new Error('invalid date parameter')
35 | if (!isString(timeStamp)) return date
36 | const hours = Number(timeStamp.split(':')[0])
37 | const minutes = Number(timeStamp.split(':')[1])
38 | return adjustDate(date, { hours, minutes })
39 | }
40 |
41 | export function numberToHourTimestamp (number) {
42 | if (number < 0) {
43 | number = 24 + number
44 | }
45 | const numberAsString = number < 10 ? `0${String(number)}` : String(number)
46 | return `${numberAsString}:00`
47 | }
48 |
--------------------------------------------------------------------------------
/ui/src/helpers/flattenPerSchema.js:
--------------------------------------------------------------------------------
1 | import { flattenObjectProps } from 'flatten-anything'
2 | import { isArray } from 'is-what'
3 |
4 | /**
5 | * Flattens an object to be in line with a schema.
6 | *
7 | * @export
8 | * @param {Object} target the target object
9 | * @param {(Object|Object[])} schema
10 | * @returns {Object}
11 | */
12 | export default function flattenPerSchema (target, schema) {
13 | const schemaArray = isArray(schema) ? schema : Object.values(schema)
14 | const schemaNestedIds = schemaArray
15 | .map(blueprint => blueprint.id)
16 | .filter(id => id && id.includes('.'))
17 | return flattenObjectProps(target, schemaNestedIds)
18 | }
19 |
--------------------------------------------------------------------------------
/ui/src/helpers/schemaToQTableColumns.js:
--------------------------------------------------------------------------------
1 | import { isArray, isUndefined, isFunction, isFullString, isBoolean, isPlainObject } from 'is-what'
2 | import pathToProp from 'path-to-prop'
3 |
4 | export default function schemaToQTableColumns (schema) {
5 | const schemaArray = !isArray(schema) ? [schema] : schema
6 | return schemaArray.map(blueprint => {
7 | const {
8 | id,
9 | valueType,
10 | type,
11 | label,
12 | align,
13 | default: df,
14 | sortable,
15 | parseValue,
16 | sort,
17 | format,
18 | headerClasses,
19 | headerStyle,
20 | } = blueprint
21 | const field = row => {
22 | const value = pathToProp(row, id)
23 | // todo: can I retrieve the EasyField context? should I?
24 | const easyFieldContext = { formData: row, fieldInput: () => {} }
25 | // fieldInput has a chance to be triggered on `parseValue`, and thus needs to be added as fn to make sure it exists on the context but does nothing. We don't want to trigger fieldInput on sorting, therefore it must be an empty fn.
26 | const valueOrDefaultValue = !isUndefined(value)
27 | ? value
28 | : isFunction(df)
29 | ? df(row, easyFieldContext)
30 | : df
31 | if (isFunction(parseValue)) return parseValue(valueOrDefaultValue, easyFieldContext)
32 | return valueOrDefaultValue
33 | }
34 | const quasarColumnConfig = {
35 | name: id,
36 | field,
37 | label,
38 | align: ['left', 'right', 'center'].includes(align)
39 | ? align
40 | : [valueType, type].includes('number')
41 | ? 'right'
42 | : 'left',
43 | sortable: isBoolean(sortable) ? sortable : id !== 'id',
44 | sort: isFunction(sort) ? sort : undefined,
45 | format: isFunction(format) ? format : undefined,
46 | headerClasses: [isArray, isPlainObject, isFullString].some(fn => fn(headerClasses))
47 | ? headerClasses
48 | : undefined,
49 | headerStyle: [isArray, isPlainObject, isFullString].some(fn => fn(headerStyle))
50 | ? headerStyle
51 | : undefined,
52 | // not sure why i'd want to set these:
53 | // required,
54 | // style,
55 | // classes,
56 | }
57 | return quasarColumnConfig
58 | })
59 | }
60 |
--------------------------------------------------------------------------------
/ui/src/index.js:
--------------------------------------------------------------------------------
1 | import { version } from '../package.json'
2 |
3 | import EasyTable from './components/EasyTable.vue'
4 |
5 | import schemaToQTableColumns from './helpers/schemaToQTableColumns.js'
6 |
7 | import dependencyMap from './meta/dependencyMap'
8 |
9 | export { version, EasyTable, schemaToQTableColumns, dependencyMap }
10 |
11 | export default {
12 | version,
13 |
14 | EasyTable,
15 |
16 | schemaToQTableColumns,
17 |
18 | dependencyMap,
19 |
20 | install (Vue) {
21 | Vue.component(EasyTable.name, EasyTable)
22 | },
23 | }
24 |
--------------------------------------------------------------------------------
/ui/src/index.sass:
--------------------------------------------------------------------------------
1 | // when installed as package needs to be:
2 | // @ import 'quasar/src/css/variables.sass'
3 | // when using npm run dev in `dev` folder it needs to be:
4 | // @ import '../node_modules/quasar/src/css/variables.sass'
5 |
6 | @import 'margin-padding.sass'
7 |
8 | .text-wrap-all
9 | white-space: pre-line
10 | word-break: break-word
11 |
--------------------------------------------------------------------------------
/ui/src/margin-padding.sass:
--------------------------------------------------------------------------------
1 |
2 | $_space-base: 16px
3 |
4 | $xxs: ($_space-base * .1)
5 | $xs: ($_space-base * .25)
6 | $sm: ($_space-base * .5)
7 | $md: $_space-base
8 | $lg: ($_space-base * 1.5)
9 | $xl: ($_space-base * 2.3)
10 | $xxl: ($_space-base * 3)
11 | $xxxl: ($_space-base * 5)
12 |
--------------------------------------------------------------------------------
/ui/src/meta/dependencyMap.js:
--------------------------------------------------------------------------------
1 | import merge from 'merge-anything'
2 | import { QTable } from './quasarPropsJson'
3 |
4 | export const dependencyMap = {
5 | EasyTable: {
6 | QTable,
7 | },
8 | }
9 |
10 | export function getPassedProps (tagName) {
11 | const inheritedComponents = dependencyMap[tagName] || {}
12 | return merge(...Object.values(inheritedComponents))
13 | }
14 |
15 | export default { ...dependencyMap, getPassedProps }
16 |
--------------------------------------------------------------------------------
/ui/src/meta/lang.js:
--------------------------------------------------------------------------------
1 | const defaultLang = {
2 | add: 'Add new',
3 | duplicate: 'Duplicate',
4 | }
5 |
6 | export default defaultLang
7 |
--------------------------------------------------------------------------------
/ui/src/meta/quasarPropsJson.js:
--------------------------------------------------------------------------------
1 | import copy from 'copy-anything'
2 | import { camelCase } from 'case-anything'
3 | import { isArray } from 'is-what'
4 | import QTableJson from 'quasar/dist/api/QTable.json'
5 |
6 | const stringToTypeFnDictionary = {
7 | Object: Object,
8 | Function: Function,
9 | Array: Array,
10 | String: String,
11 | Number: Number,
12 | Boolean: Boolean,
13 | RegExp: RegExp,
14 | Date: Date,
15 | Symbol: Symbol,
16 | }
17 | const stringToTypeFn = string => stringToTypeFnDictionary[string]
18 |
19 | function jsonToPropFormat ({ props }) {
20 | if (!props) return {}
21 | return Object.entries(props).reduce((carry, [key, value]) => {
22 | value = copy(value)
23 | value.inheritedProp = true
24 | value.type = isArray(value.type) ? value.type.map(stringToTypeFn) : stringToTypeFn(value.type)
25 | carry[camelCase(key)] = value
26 | return carry
27 | }, {})
28 | }
29 |
30 | export const QTable = jsonToPropFormat(QTableJson)
31 |
32 | export default {
33 | QTable,
34 | }
35 |
--------------------------------------------------------------------------------
/ui/src/mixins/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mesqueeb/quasar-ui-easy-tables/c8611d97513dc3bdab7ed1d0108a8444239e1270/ui/src/mixins/.gitkeep
--------------------------------------------------------------------------------
/ui/umd-test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | UMD test
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | quasar-ui-easy-tables v{{ version }}
21 |
22 |
23 | Quasar v{{ $q.version }}
24 |
25 |
26 |
27 |
28 |
29 |
30 | - In /ui, run: "yarn build"
31 | - You need to build & refresh page on each change manually.
32 | - Use self-closing tags only!
33 | - Example: <my-component></my-component>
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
56 |
57 |
58 |
--------------------------------------------------------------------------------