diff --git a/.babelrc b/.babelrc
index 9143cd8d1..a64b362c2 100644
--- a/.babelrc
+++ b/.babelrc
@@ -3,6 +3,6 @@
[ "env", {"modules": false} ],
"stage-2"
],
- "plugins": ["transform-runtime"],
+ "plugins": ["transform-runtime", "transform-decorators"],
"comments": false
}
diff --git a/.eslintignore b/.eslintignore
index 9b1c8b133..25aeecd2a 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1 +1,2 @@
/dist
+*.ts
diff --git a/package-lock.json b/package-lock.json
index da0a3a614..3e5e2a852 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2747,6 +2747,12 @@
"integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=",
"dev": true
},
+ "diff": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz",
+ "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==",
+ "dev": true
+ },
"diffie-hellman": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz",
@@ -10167,6 +10173,112 @@
"semver": "5.5.0"
}
},
+ "tslib": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz",
+ "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==",
+ "dev": true
+ },
+ "tslint": {
+ "version": "5.9.1",
+ "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.9.1.tgz",
+ "integrity": "sha1-ElX4ej/1frCw4fDmEKi0dIBGya4=",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "6.26.0",
+ "builtin-modules": "1.1.1",
+ "chalk": "2.3.1",
+ "commander": "2.14.1",
+ "diff": "3.4.0",
+ "glob": "7.1.2",
+ "js-yaml": "3.10.0",
+ "minimatch": "3.0.4",
+ "resolve": "1.5.0",
+ "semver": "5.5.0",
+ "tslib": "1.9.0",
+ "tsutils": "2.21.2"
+ }
+ },
+ "tslint-config-airbnb": {
+ "version": "5.7.0",
+ "resolved": "https://registry.npmjs.org/tslint-config-airbnb/-/tslint-config-airbnb-5.7.0.tgz",
+ "integrity": "sha1-Cf8EsN1Zl2X0S0QlAERY0I/LLEA=",
+ "dev": true,
+ "requires": {
+ "tslint-consistent-codestyle": "1.11.1",
+ "tslint-eslint-rules": "4.1.1",
+ "tslint-microsoft-contrib": "5.0.3"
+ }
+ },
+ "tslint-consistent-codestyle": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/tslint-consistent-codestyle/-/tslint-consistent-codestyle-1.11.1.tgz",
+ "integrity": "sha512-wLu+Ct8x4mBmVkuhEiNAnUBkxchMV2Le0ikBsST5HnKbGlm3K4RSpXCBSI1VtJDk748W2I5hDzgsInawLdnxwQ==",
+ "dev": true,
+ "requires": {
+ "tslib": "1.9.0",
+ "tsutils": "2.21.2"
+ }
+ },
+ "tslint-eslint-rules": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/tslint-eslint-rules/-/tslint-eslint-rules-4.1.1.tgz",
+ "integrity": "sha1-fDDniC8mvCdr/5HSOEl1xp2viLo=",
+ "dev": true,
+ "requires": {
+ "doctrine": "0.7.2",
+ "tslib": "1.9.0",
+ "tsutils": "1.9.1"
+ },
+ "dependencies": {
+ "doctrine": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz",
+ "integrity": "sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=",
+ "dev": true,
+ "requires": {
+ "esutils": "1.1.6",
+ "isarray": "0.0.1"
+ }
+ },
+ "esutils": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz",
+ "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=",
+ "dev": true
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
+ "tsutils": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-1.9.1.tgz",
+ "integrity": "sha1-ufmrROVa+WgYMdXyjQrur1x1DLA=",
+ "dev": true
+ }
+ }
+ },
+ "tslint-microsoft-contrib": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-5.0.3.tgz",
+ "integrity": "sha512-5AnfTGlfpUzpRHLmoojPBKFTTmbjnwgdaTHMdllausa4GBPya5u36i9ddrTX4PhetGZvd4JUYIpAmgHqVnsctg==",
+ "dev": true,
+ "requires": {
+ "tsutils": "2.21.2"
+ }
+ },
+ "tsutils": {
+ "version": "2.21.2",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.21.2.tgz",
+ "integrity": "sha512-iaIuyjIUeFLdD39MYdzqBuY7Zv6+uGxSwRH4mf+HuzsnznjFz0R2tGrAe0/JvtNh91WrN8UN/DZRFTZNDuVekA==",
+ "dev": true,
+ "requires": {
+ "tslib": "1.9.0"
+ }
+ },
"tty-browserify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
@@ -10711,6 +10823,11 @@
"integrity": "sha512-3D+lY7HTkKbtswDM4BBHgqyq+qo8IAEE8lz8va1dz3LLmttjgo0FxairO4r1iN2OBqk8o1FyL4hvzzTFEdQSEw==",
"dev": true
},
+ "vue-class-component": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/vue-class-component/-/vue-class-component-6.2.0.tgz",
+ "integrity": "sha512-U11yVeP5zjPSx4IU7Zas3MLC+Vy9dmufI+uLKLo8YuGQJGOihSYfh/fgNnbjMteN+hz5axjG6iC6ybMo6vGYnA=="
+ },
"vue-eslint-parser": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-2.0.2.tgz",
diff --git a/package.json b/package.json
index 123d2d521..6341e6902 100644
--- a/package.json
+++ b/package.json
@@ -7,16 +7,20 @@
"author": "BrewPi B.V.",
"private": true,
"scripts": {
- "lint": "eslint --ext .js,.vue,.ts src",
+ "eslint": "eslint --ext .js,.vue src",
+ "tslint": "tslint -c tslint.json 'src/**/*.ts'",
+ "lint": "npm run eslint && npm run tslint",
"test": "echo \"No test specified\" && exit 0"
},
"dependencies": {
+ "vue-class-component": "^6.2.0",
"vue-i18n": "^7.3.3",
"vuex-typescript": "^3.0.2"
},
"devDependencies": {
"@types/core-js": "^0.9.46",
"babel-eslint": "8.2.1",
+ "babel-plugin-transform-decorators": "^6.24.1",
"connect-api-mocker": "^1.3.6",
"eslint": "4.15.0",
"eslint-config-airbnb-base": "11.3.0",
@@ -27,6 +31,8 @@
"eslint-plugin-vue": "4.0.0",
"quasar-cli": "^0.15.0-beta.36",
"ts-loader": "^3.5.0",
+ "tslint": "^5.9.1",
+ "tslint-config-airbnb": "^5.7.0",
"typescript": "^2.7.1",
"typescript-eslint-parser": "^13.0.0"
},
diff --git a/quasar.conf.js b/quasar.conf.js
index 022dba303..c5b769fd3 100644
--- a/quasar.conf.js
+++ b/quasar.conf.js
@@ -36,17 +36,17 @@ module.exports = ctx => ({
// add custom loaders
cfg.module.rules.push({
- enforce: 'pre',
- test: /\.(js|vue)$/,
- loader: 'eslint-loader',
- exclude: /(node_modules|quasar)/,
- }, {
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
appendTsSuffixTo: [/\.vue$/],
},
+ }, {
+ enforce: 'pre',
+ test: /\.(js|vue)$/,
+ loader: 'eslint-loader',
+ exclude: /(node_modules|quasar)/,
});
},
},
diff --git a/src/components/blocks/OneWireTempSensor/OneWireTempSensor.ts b/src/components/blocks/OneWireTempSensor/OneWireTempSensor.ts
new file mode 100644
index 000000000..4e6c8ff1e
--- /dev/null
+++ b/src/components/blocks/OneWireTempSensor/OneWireTempSensor.ts
@@ -0,0 +1,26 @@
+import Vue from 'vue';
+import Component from 'vue-class-component';
+
+import { getById } from '../../../store/blocks/OneWireTempSensor/getters';
+
+@Component({
+ props: {
+ id: {
+ default: '',
+ type: String,
+ },
+ },
+})
+export default class OneWireTempSensor extends Vue {
+ get blockData() {
+ return getById(this.$props.id);
+ }
+
+ get settings() {
+ return this.blockData.settings;
+ }
+
+ get state() {
+ return this.blockData.state;
+ }
+}
diff --git a/src/components/blocks/OneWireTempSensor.vue b/src/components/blocks/OneWireTempSensor/default.vue
similarity index 72%
rename from src/components/blocks/OneWireTempSensor.vue
rename to src/components/blocks/OneWireTempSensor/default.vue
index e85ca8218..373209bd9 100644
--- a/src/components/blocks/OneWireTempSensor.vue
+++ b/src/components/blocks/OneWireTempSensor/default.vue
@@ -26,24 +26,7 @@
-
+
+
diff --git a/src/components/blocks/block.ts b/src/components/blocks/block.ts
deleted file mode 100644
index b6a920332..000000000
--- a/src/components/blocks/block.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import Vue from 'vue';
-
-import SetPointSimple from './SetPointSimple.vue';
-import OneWireTempSensor from './OneWireTempSensor.vue';
-
-export default Vue.extend({
- name: 'block',
- props: ['block-data'],
- render(createElement) {
- const { type } = this.$props.blockData;
- const options = {
- props: this.$props.blockData,
- };
-
- switch (type) {
- case 'OneWireTempSensor':
- return createElement(OneWireTempSensor, options);
- case 'SetPointSimple':
- return createElement(SetPointSimple, options);
- default:
- throw new Error(`'${type}' is not a valid block type`);
- }
- },
-});
diff --git a/src/components/blocks/block.vue b/src/components/blocks/block.vue
new file mode 100644
index 000000000..1ab09242e
--- /dev/null
+++ b/src/components/blocks/block.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
diff --git a/src/main.ts b/src/main.ts
index 59d692c5b..229a718bd 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -71,9 +71,9 @@ Vue.use(Quasar, {
});
const app = new Vue({
- el: '#q-app',
router,
store,
+ el: '#q-app',
render: h => h(App),
});
diff --git a/src/pages/blocks.vue b/src/pages/blocks.vue
index f76f3cf02..d10a5f7ff 100644
--- a/src/pages/blocks.vue
+++ b/src/pages/blocks.vue
@@ -10,8 +10,8 @@
@@ -25,13 +25,13 @@ import Vue from 'vue';
import Block from '../components/blocks/block';
-import { isFetching, allBlocks } from '../store/blocks/getters';
+import { isFetching, blockIds } from '../store/blocks/getters';
export default Vue.extend({
name: 'PageIndex',
components: { Block },
computed: {
- blocks: () => allBlocks(),
+ blocks: () => blockIds(),
fetching: () => isFetching(),
},
methods: {},
diff --git a/src/plugins/i18n.ts b/src/plugins/i18n.ts
index cffd90207..c75a9afee 100644
--- a/src/plugins/i18n.ts
+++ b/src/plugins/i18n.ts
@@ -7,8 +7,8 @@ export default ({ app, store, Vue }: PluginArguments) => {
// Set i18n instance on app
// This way we can use it in middleware and pages asyncData/fetch
app.i18n = new VueI18n({
+ messages,
locale: store.state.locale,
fallbackLocale: 'en',
- messages,
});
};
diff --git a/src/router/index.ts b/src/router/index.ts
index 4f18272ff..8a7433b3f 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -5,11 +5,11 @@ import routes from './routes';
Vue.use(VueRouter);
-const Router = new VueRouter({
+const router = new VueRouter({
+ routes,
// Leave as is and change from quasar.conf.js instead!
mode: process.env.VUE_ROUTER_MODE || 'history',
base: process.env.VUE_ROUTER_BASE || '',
- routes,
});
/*
@@ -23,4 +23,4 @@ Router.beforeEach((to, from, next) => {
})
*/
-export default Router;
+export default router;
diff --git a/src/store/blocks/OneWireTempSensor/OneWireTempSensor.d.ts b/src/store/blocks/OneWireTempSensor/OneWireTempSensor.d.ts
index db26f0870..d52b64016 100644
--- a/src/store/blocks/OneWireTempSensor/OneWireTempSensor.d.ts
+++ b/src/store/blocks/OneWireTempSensor/OneWireTempSensor.d.ts
@@ -4,11 +4,11 @@ export interface OneWireTempSensor extends BlockBase {
settings: {
address: string,
offset: number,
- },
+ };
state: {
value: number,
connected: boolean,
- },
+ };
}
export interface OneWireTempSensorBlock extends OneWireTempSensor {
diff --git a/src/store/blocks/OneWireTempSensor/getters.ts b/src/store/blocks/OneWireTempSensor/getters.ts
new file mode 100644
index 000000000..cc010d7a9
--- /dev/null
+++ b/src/store/blocks/OneWireTempSensor/getters.ts
@@ -0,0 +1,14 @@
+import { blockById } from '../getters';
+
+import { OneWireTempSensorBlock } from './OneWireTempSensor';
+
+export function getById(id: string): OneWireTempSensorBlock {
+ const block = blockById(id);
+
+ // force block type
+ if (block.type !== 'OneWireTempSensor') {
+ throw new Error('Block is not a valid OneWireTempSensor');
+ }
+
+ return block;
+}
diff --git a/src/store/blocks/SetPointSimple/SetPointSimple.d.ts b/src/store/blocks/SetPointSimple/SetPointSimple.d.ts
index 0137c25c3..2009036c1 100644
--- a/src/store/blocks/SetPointSimple/SetPointSimple.d.ts
+++ b/src/store/blocks/SetPointSimple/SetPointSimple.d.ts
@@ -3,7 +3,7 @@ import { BlockBase } from '../state';
export interface SetPointSimple extends BlockBase {
settings: {
value: number,
- },
+ };
}
export interface SetPointSimpleBlock extends SetPointSimple {
diff --git a/src/store/blocks/SetPointSimple/getters.ts b/src/store/blocks/SetPointSimple/getters.ts
new file mode 100644
index 000000000..14724b73a
--- /dev/null
+++ b/src/store/blocks/SetPointSimple/getters.ts
@@ -0,0 +1,14 @@
+import { blockById } from '../getters';
+
+import { SetPointSimpleBlock } from './SetPointSimple';
+
+export function getById(id: string): SetPointSimpleBlock {
+ const block = blockById(id);
+
+ // force block type
+ if (block.type !== 'SetPointSimple') {
+ throw new Error('Block is not a valid SetPointSimple');
+ }
+
+ return block;
+}
diff --git a/src/store/blocks/getters.ts b/src/store/blocks/getters.ts
index b1e042c60..e1578861b 100644
--- a/src/store/blocks/getters.ts
+++ b/src/store/blocks/getters.ts
@@ -7,6 +7,10 @@ import { State as RootState } from '../state';
const { read } = getStoreAccessors('blocks');
const getters = {
+ blocksById: (state: BlocksState): { [id: string]: Block } => state.byId,
+ blockIds(state: BlocksState): string[] {
+ return state.allIds;
+ },
allBlocks(state: BlocksState): Block[] {
return state.allIds.map(id => state.byId[id]);
},
@@ -17,8 +21,12 @@ const getters = {
const readIsFetching = read(getters.isFetching);
const readAllBlocks = read(getters.allBlocks);
+const readBlockIds = read(getters.blockIds);
+const readBlocksById = read(getters.blocksById);
export const allBlocks = () => readAllBlocks(store);
+export const blockIds = () => readBlockIds(store);
+export const blockById = (id: string) => readBlocksById(store)[id];
export const isFetching = () => readIsFetching(store);
export default getters;
diff --git a/src/store/blocks/index.ts b/src/store/blocks/index.ts
index dbaf894c2..a4e90507b 100644
--- a/src/store/blocks/index.ts
+++ b/src/store/blocks/index.ts
@@ -3,6 +3,9 @@ import getters from './getters';
import mutations from './mutations';
const blocks = {
+ getters,
+ actions,
+ mutations,
namespaced: true,
strict: true,
state: {
@@ -10,9 +13,6 @@ const blocks = {
byId: {},
fetching: false,
},
- getters,
- actions,
- mutations,
};
export default blocks;
diff --git a/src/store/blocks/state.ts b/src/store/blocks/state.ts
index 1743219ec..8ad5e3876 100644
--- a/src/store/blocks/state.ts
+++ b/src/store/blocks/state.ts
@@ -5,7 +5,7 @@ import { OneWireTempSensorBlock, OneWireTempSensor } from './OneWireTempSensor/O
import { State as RootState } from '../state';
export interface BlockBase {
- id: string,
+ id: string;
}
export type Block = SetPointSimpleBlock | OneWireTempSensorBlock;
diff --git a/src/vue-shims.d.ts b/src/vue-shims.d.ts
index 9bb374711..05ee2ac80 100644
--- a/src/vue-shims.d.ts
+++ b/src/vue-shims.d.ts
@@ -1,9 +1,9 @@
// standard declarations for *.vue files
declare module '*.vue' {
- import Vue from 'vue'; // eslint-disable-line
+ import Vue from 'vue';
export default Vue;
}
// Quasar specific declarations
declare module 'quasar';
-declare const __THEME: string; // eslint-disable-line
+declare const __THEME: string;
diff --git a/tsconfig.json b/tsconfig.json
index bb7d9b318..e4f991efe 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -4,6 +4,7 @@
"strict": true,
"lib": ["ESNext", "DOM"],
"moduleResolution": "node",
- "sourceMap": true
+ "sourceMap": true,
+ "experimentalDecorators": true
}
}
diff --git a/tslint.json b/tslint.json
new file mode 100644
index 000000000..740a3e241
--- /dev/null
+++ b/tslint.json
@@ -0,0 +1,12 @@
+{
+ "defaultSeverity": "error",
+ "extends": [
+ "tslint-config-airbnb"
+ ],
+ "jsRules": {},
+ "rules": {
+ "import-name": false,
+ "no-boolean-literal-compare": false
+ },
+ "rulesDirectory": []
+}