diff --git a/app/components/AddAccount.vue b/app/components/AddAccount.vue
new file mode 100644
index 000000000..c2c857729
--- /dev/null
+++ b/app/components/AddAccount.vue
@@ -0,0 +1,225 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/components/AppSettingsView.vue b/app/components/AppSettingsView.vue
index 4ebd4cf92..b3441f9a3 100644
--- a/app/components/AppSettingsView.vue
+++ b/app/components/AppSettingsView.vue
@@ -4,8 +4,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
@@ -26,7 +40,6 @@
import routes from "../routes";
import ScreenHeader from "./ScreenHeader";
import ScreenFooter from "./ScreenFooter";
-import { hexStringToByteWiseString } from "../utilities";
import { Build } from "../config";
export default {
@@ -34,8 +47,14 @@ export default {
return {
loggedIn: this.$portalInterface.isLoggedIn(),
versions: Build,
+ currentUser: this.$portalInterface._currentUser
};
},
+ computed: {
+ accounts() {
+ return this.$store.state.portal.accounts;
+ },
+ },
components: {
ScreenHeader,
ScreenFooter,
@@ -56,6 +75,10 @@ export default {
goToLogin() {
this.$navigateTo(routes.login);
},
+
+ addAccount() {
+ this.$navigateTo(routes.addAccount);
+ }
},
};
@@ -64,6 +87,8 @@ export default {
// Start custom common variables
@import "../app-variables";
// End custom common variables
-
+.v-middle {
+ vertical-align: middle;
+}
// Custom styles
diff --git a/app/i18n/en.js b/app/i18n/en.js
index 0e0f7dbd3..39db82eae 100644
--- a/app/i18n/en.js
+++ b/app/i18n/en.js
@@ -407,5 +407,8 @@ module.exports = {
daysHrsMin: "days hrs min",
hrsMinSec: "hrs min sec",
downloadFirmware: "Download Firmware",
- upgradeFirmware: "Upgrade Firmware"
+ upgradeFirmware: "Upgrade Firmware",
+ addAccount: "Add Account",
+ logOutAll: "Log Out All Accounts",
+ accounts: "Accounts"
};
diff --git a/app/i18n/es.js b/app/i18n/es.js
index 71a1ef516..d9b95c911 100644
--- a/app/i18n/es.js
+++ b/app/i18n/es.js
@@ -407,5 +407,8 @@ module.exports = {
daysHrsMin: "días hrs min",
hrsMinSec: "hrs min seg",
downloadFirmware: "Descargar Firmware",
- upgradeFirmware: "Actualización de Firmware"
+ upgradeFirmware: "Actualización de Firmware",
+ addAccount: "Add Account",
+ logOutAll: "Log Out All Accounts",
+ accounts: "Accounts"
};
diff --git a/app/migrations/20200731_093924_add_accounts_table.js b/app/migrations/20200731_093924_add_accounts_table.js
new file mode 100644
index 000000000..f382715a1
--- /dev/null
+++ b/app/migrations/20200731_093924_add_accounts_table.js
@@ -0,0 +1,15 @@
+import Migration from "./Migration";
+
+export class AddAccounts_20200731_093924 extends Migration {
+ up(db) {
+ return db.batch([
+ `CREATE TABLE IF NOT EXISTS accounts (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ name TEXT,
+ email TEXT,
+ portal_id TEXT,
+ token TEXT
+ )`,
+ ]);
+ }
+}
diff --git a/app/migrations/index.js b/app/migrations/index.js
index b5c1dc3d1..de60948d6 100644
--- a/app/migrations/index.js
+++ b/app/migrations/index.js
@@ -8,3 +8,4 @@ export * from "./20200624_193105_add_sensor_trend.js";
export * from "./20200708_162023_add_notes_table.js";
export * from "./20200715_075044_add_module_flags.js";
export * from "./20200723_093924_add_portal_updated_time.js";
+export * from "./20200731_093924_add_accounts_table.js";
diff --git a/app/routes/index.js b/app/routes/index.js
index c35b00606..bd04814f6 100644
--- a/app/routes/index.js
+++ b/app/routes/index.js
@@ -24,6 +24,7 @@ import DeployNotes from "../components/deploy/DeployNotesView";
import DeployReview from "../components/deploy/DeployReviewView";
import { Route, RouteState } from "./navigate";
+import AddAccount from "~/components/AddAccount";
const routes = {
appSettings: new Route(AppSettings, {}),
@@ -36,6 +37,7 @@ const routes = {
deployReview: new Route(DeployReview, {}),
developerMenu: new Route(DeveloperMenu, { developer: true }),
login: new Route(Login, { login: true }),
+ addAccount: new Route(AddAccount, {}),
module: new Route(Module, {}),
assembleStation: new Route(AssembleStation, {}),
stations: new Route(StationListView, { listing: true }),
diff --git a/app/services/db-interface.ts b/app/services/db-interface.ts
index 8c05d0690..56cfb879c 100644
--- a/app/services/db-interface.ts
+++ b/app/services/db-interface.ts
@@ -2,7 +2,7 @@ import _ from "lodash";
import Config from "../config";
import { sqliteToJs } from "../utilities";
import { Download, FileTypeUtils } from "../store/types";
-import { DownloadTableRow, NotesTableRow } from "../store/row-types";
+import {AccountsTableRow, DownloadTableRow, NotesTableRow} from "../store/row-types";
const log = Config.logger("DbInterface");
@@ -869,4 +869,34 @@ export default class DatabaseInterface {
)
.catch((err) => Promise.reject(new Error(`error fetching notes: ${err}`)));
}
+
+ public getAllAccounts(): Promise {
+ return this.getDatabase()
+ .then((db) => db.query("SELECT * FROM accounts"))
+ .then((rows) => sqliteToJs(rows))
+ .then((rows) => {
+ return rows;
+ })
+ .catch((err) => Promise.reject(new Error(`error fetching accounts: ${err}`)));
+ }
+
+ public addOrUpdateAccounts(account: any): Promise {
+ return this.getDatabase()
+ .then((db) =>
+ db.query(`SELECT id FROM accounts WHERE portal_id = ?`, [account.portalId]).then((maybeId) => {
+ console.log('maybeId', maybeId);
+ if (maybeId.length == 0) {
+ return db.execute(`INSERT INTO accounts (name, email, portal_id, token) VALUES (?, ?, ?, ?)`, [account.name, account.email, account.portalId, account.token]);
+ }
+ const values = [account.name, account.email, account.portalId, account.token, maybeId[0].id];
+ return db.execute(`UPDATE accounts SET name = ?, email = ?, portal_id = ?, token = ? WHERE id = ?`, values);
+ })
+ )
+ .catch((err) => Promise.reject(new Error(`error fetching accounts: ${err}`)));
+ }
+
+ public deleteAllAccounts(): Promise {
+ return this.getDatabase()
+ .then((db) => db.query("DELETE FROM accounts"))
+ }
}
diff --git a/app/services/portal-interface.ts b/app/services/portal-interface.ts
index 023d60da1..0139af618 100644
--- a/app/services/portal-interface.ts
+++ b/app/services/portal-interface.ts
@@ -4,6 +4,7 @@ import AppSettings from "../wrappers/app-settings";
import { Download, FileTypeUtils } from "../store/types";
import { AuthenticationError } from "../lib/errors";
import Config from "../config";
+import * as ActionTypes from "../store/actions";
type ProgressFunc = (total: number, copied: number, info: object) => void;
@@ -18,6 +19,7 @@ export default class PortalInterface {
_dbInterface: any;
_fs: any;
_conservify: any;
+ _store: any;
_currentUser: any;
_appSettings: any;
@@ -26,6 +28,7 @@ export default class PortalInterface {
this._dbInterface = services.Database();
this._fs = services.FileSystem();
this._conservify = services.Conservify();
+ this._store = services.Store();
this._currentUser = {};
this._appSettings = new AppSettings();
}
@@ -40,7 +43,7 @@ export default class PortalInterface {
});
}
- private storeCurrentUser(refreshed) {
+ private storeCurrentUser(refreshed, accessToken) {
return this.query({
refreshed: refreshed || false,
authenticated: true,
@@ -49,6 +52,10 @@ export default class PortalInterface {
}).then((data) => {
this._currentUser.name = data.name;
this._currentUser.portalId = data.id;
+ this._currentUser.email = data.email;
+ this._currentUser.token = accessToken;
+ this._store.dispatch(ActionTypes.UPDATE_ACCOUNT, {...this._currentUser});
+
return data;
});
}
@@ -88,6 +95,7 @@ export default class PortalInterface {
public logout() {
this._appSettings.remove("accessToken");
+ this._store.dispatch(ActionTypes.LOGOUT_ACCOUNTS);
return Promise.resolve(true);
}
@@ -241,7 +249,7 @@ export default class PortalInterface {
// Headers should always be lower case, bug otherwise.
const accessToken = response.headers.authorization;
this._appSettings.setString("accessToken", accessToken);
- return this.storeCurrentUser(true).then(() => {
+ return this.storeCurrentUser(true, accessToken).then(() => {
return {
token: accessToken,
};
diff --git a/app/store/actions.ts b/app/store/actions.ts
index 1f4f97572..d274e7400 100644
--- a/app/store/actions.ts
+++ b/app/store/actions.ts
@@ -57,3 +57,6 @@ export const SAVE_NOTES = "SAVE_NOTES";
// Portal
export const UPDATE_PORTAL = "UPDATE_PORTAL";
+export const LOAD_ACCOUNTS = "LOAD_ACCOUNTS";
+export const UPDATE_ACCOUNT = "UPDATE_ACCOUNT";
+export const LOGOUT_ACCOUNTS = "LOGOUT_ACCOUNTS";
diff --git a/app/store/modules/portal.ts b/app/store/modules/portal.ts
index a3b97aaae..5ab265ff1 100644
--- a/app/store/modules/portal.ts
+++ b/app/store/modules/portal.ts
@@ -1,12 +1,16 @@
import Vue from "../../wrappers/vue";
import * as ActionTypes from "../actions";
import * as MutationTypes from "../mutations";
+import {ServiceRef, Services} from "./utilities";
+import {AccountsTableRow} from "../row-types";
export class PortalState {
authenticated: boolean = false;
+ services: ServiceRef = new ServiceRef();
+ accounts: any;
}
-type ActionParameters = { commit: any };
+type ActionParameters = { commit: any; dispatch: any; state: any };
const getters = {};
@@ -14,21 +18,62 @@ const actions = {
[ActionTypes.INITIALIZE]: ({ commit }: ActionParameters) => {
//
},
+ [ActionTypes.LOAD]: ({ commit, dispatch, state }: ActionParameters) => {
+ //
+ dispatch(ActionTypes.LOAD_ACCOUNTS);
+ },
[ActionTypes.UPDATE_PORTAL]: ({ commit }: ActionParameters) => {
//
},
+ [ActionTypes.LOAD_ACCOUNTS]: ({ commit, dispatch, state }: ActionParameters) => {
+ return state.services
+ .db()
+ .getAllAccounts()
+ .then((accounts) => {
+ commit(MutationTypes.LOAD_ACCOUNTS, accounts)
+ })
+ .catch((e) => console.log('ActionTypes.LOAD_ACCOUNTS', e))
+ },
+ [ActionTypes.UPDATE_ACCOUNT]: ({ commit, dispatch, state }: ActionParameters, account) => {
+ return state.services
+ .db()
+ .addOrUpdateAccounts(account)
+ .then((all) => {
+ dispatch(ActionTypes.LOAD_ACCOUNTS);
+ })
+ .catch((e) => console.log('ActionTypes.UPDATE_ACCOUNT', e))
+ },
+ [ActionTypes.LOGOUT_ACCOUNTS]: ({ commit, dispatch, state }: ActionParameters) => {
+ return state.services
+ .db()
+ .deleteAllAccounts()
+ .then((all) => {
+ commit(MutationTypes.LOGOUT_ACCOUNTS);
+ dispatch(ActionTypes.LOAD_ACCOUNTS);
+ })
+ .catch((e) => console.log('ActionTypes.LOGOUT_ACCOUNTS', e))
+ },
};
const mutations = {
[MutationTypes.RESET]: (state: PortalState, error: string) => {
Object.assign(state, new PortalState());
},
+ [MutationTypes.SERVICES]: (state: PortalState, services: () => Services) => {
+ Vue.set(state, "services", new ServiceRef(services));
+ },
[MutationTypes.LOGIN]: (state: PortalState, token: string) => {
Vue.set(state, "authenticated", true);
},
[MutationTypes.LOGOUT]: (state: PortalState) => {
Vue.set(state, "authenticated", false);
},
+ [MutationTypes.LOGOUT_ACCOUNTS]: (state: PortalState) => {
+ Vue.set(state, "accounts", []);
+ },
+ [MutationTypes.LOAD_ACCOUNTS]: (state: PortalState, accounts: AccountsTableRow) => {
+ Vue.set(state, 'accounts', accounts);
+ },
};
const state = () => new PortalState();
diff --git a/app/store/mutations.ts b/app/store/mutations.ts
index 7fa0b54fa..c97867688 100644
--- a/app/store/mutations.ts
+++ b/app/store/mutations.ts
@@ -23,6 +23,9 @@ export const TRANSFER_CLOSE = "TRANSFER_CLOSE";
export const LOGIN = "LOGIN";
export const LOGOUT = "LOGOUT";
+export const LOAD_ACCOUNTS = "LOAD_ACCOUNTS";
+export const UPDATE_ACCOUNT = "UPDATE_ACCOUNT";
+export const LOGOUT_ACCOUNTS = "LOGOUT_ACCOUNTS";
export const STATION_QUERIED = "STATION_QUERIED";
export const STATION_ACTIVITY = "STATION_ACTIVITY";
diff --git a/app/store/row-types.ts b/app/store/row-types.ts
index b4ad93d42..35ffa3ccd 100644
--- a/app/store/row-types.ts
+++ b/app/store/row-types.ts
@@ -75,3 +75,11 @@ export interface NotesTableRow {
notes: string;
notesObject: object | null;
}
+
+export interface AccountsTableRow {
+ id: number;
+ name: string;
+ email: string;
+ portalId: string;
+ token: string;
+}