Skip to content

Commit

Permalink
Merge pull request #16 from coop-care/feat/team-collaboration-ui
Browse files Browse the repository at this point in the history
Feat/team collaboration UI
  • Loading branch information
michaelkamphausen committed Dec 23, 2020
2 parents c04dbe9 + 41aaef1 commit 273e9f8
Show file tree
Hide file tree
Showing 88 changed files with 6,448 additions and 3,760 deletions.
3,562 changes: 1,341 additions & 2,221 deletions package-lock.json

Large diffs are not rendered by default.

32 changes: 16 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,38 +18,38 @@
"test": "echo \"No test specified\" && exit 0"
},
"dependencies": {
"@quasar/extras": "^1.9.9",
"apexcharts": "^3.22.0",
"@quasar/extras": "^1.9.12",
"apexcharts": "^3.23.0",
"class-transformer": "^0.3.1",
"core-js": "^3.6.5",
"core-js": "^3.8.1",
"direct-vuex": "^0.12.0",
"luxon": "^1.25.0",
"mongodb-stitch-browser-sdk": "^4.8.0",
"quasar": "^1.14.1",
"quasar": "^1.14.7",
"reflect-metadata": "^0.1.13",
"rrule": "^2.6.6",
"timeago.js": "^4.0.2",
"vue-apexcharts": "^1.6.0",
"vue-class-component": "^7.2.6",
"vue-i18n": "^8.22.0",
"vue-property-decorator": "^9.0.2"
"vue-i18n": "^8.22.2",
"vue-property-decorator": "^9.1.2"
},
"devDependencies": {
"@quasar/app": "^2.1.1",
"@quasar/app": "^2.1.13",
"@quasar/quasar-app-extension-qenv": "^1.0.3",
"@quasar/quasar-app-extension-qmarkdown": "^1.0.34",
"@types/bson": "^4.0.2",
"@quasar/quasar-app-extension-qmarkdown": "^1.4.0",
"@types/bson": "^4.0.3",
"@types/luxon": "^1.25.0",
"@types/node": "^14.11.8",
"@typescript-eslint/eslint-plugin": "^4.4.1",
"@typescript-eslint/parser": "^4.4.1",
"@types/node": "^14.14.14",
"@typescript-eslint/eslint-plugin": "^4.11.0",
"@typescript-eslint/parser": "^4.11.0",
"babel-eslint": "^10.0.1",
"eslint": "^7.11.0",
"eslint-config-prettier": "^6.12.0",
"eslint": "^7.16.0",
"eslint-config-prettier": "^7.1.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-vue": "^7.0.1",
"workbox-webpack-plugin": "^5.1.4"
"eslint-plugin-vue": "^7.3.0",
"workbox-webpack-plugin": "^6.0.2"
},
"browserslist": [
"last 10 Chrome versions",
Expand Down
3 changes: 2 additions & 1 deletion quasar.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ module.exports = configure(function (ctx) {
// https://quasar.dev/quasar-cli/boot-files
boot: [
"i18n",
"quasar-lang-pack"
"quasar-lang-pack",
"fetchData"
],

// https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css
Expand Down
46 changes: 45 additions & 1 deletion src/api/apiProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import Vue from "vue";
import CoopCareApiInterface from "./coopCareApiInterface";
import DemoApi from "./demo";
import StitchApi from "./stitch";
import store from "../store";
import { User, TeamMember, Team, Client } from "../models";

declare module "vue/types/vue" {
interface Vue {
Expand All @@ -14,7 +16,49 @@ let ccApi: CoopCareApiInterface;
if (process.env.BACKEND == "demo") {
ccApi = new DemoApi();
} else {
ccApi = new StitchApi("openomaha-elgvq", "openomaha", "clients");
ccApi = new StitchApi("openomaha-elgvq", "openomaha");

ccApi.authListener = (changeType) => {
if (changeType == "sessionEnded") {
store.direct.dispatch.logout()
.then(() => location.reload())
.catch(error => console.error("error during logout", error));
}
};

ccApi.userListener = (changeType, data) => {
const isCurrentUser = data && store.state.currentUser?.equals(data)

if (data && (changeType == "replace" || changeType == "update")) {
let user = TeamMember.fromObject(data) as TeamMember
if (isCurrentUser) {
user = User.fromObject(data) as User;
store.direct.commit.setCurrentUser(user as User);
}
store.direct.commit.updateTeamMember(user);
} else {
if (isCurrentUser) {
void store.direct.dispatch.fetchUserFromDB({ locale: (data as User).locale });
}
void store.direct.dispatch.fetchTeamMembersFromDB();
}
};

ccApi.teamListener = (changeType, data) => {
if (data && (changeType == "replace" || changeType == "update")) {
store.direct.commit.setTeam(Team.fromObject(data) as Team);
} else {
void store.direct.dispatch.fetchTeamsFromDB();
}
};

ccApi.clientListener = (changeType, data) => {
if (data && (changeType == "replace" || changeType == "update")) {
store.direct.commit.updateClient(Client.fromObject(data) as Client);
} else {
void store.direct.dispatch.fetchClientsFromDB();
}
};
}

export { ccApi };
Expand Down
28 changes: 25 additions & 3 deletions src/api/coopCareApiInterface.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
import { Client, User } from "../models";
import { Client, User, Team, TeamMember } from "../models";

export type CoopCareApiListener<T> = (changeType: string, data: T | undefined) => void;

export default interface CoopCareApiInterface {
readonly isLoggedIn: boolean;
readonly user?: User;
readonly userId: string | undefined;
readonly userEmail: string | undefined;
authListener?: CoopCareApiListener<void>;
userListener?: CoopCareApiListener<TeamMember>;
teamListener?: CoopCareApiListener<Team>;
clientListener?: CoopCareApiListener<Client>;

login(username: string, password: string): Promise<void>;
logout(): Promise<void>;
registerUser(username: string, password: string): Promise<void>;
confirmUser(token: string, tokenId: string): Promise<void>;
resendConfirmationEmail(email: string): Promise<void>;
sendResetPasswordEmail(email: string): Promise<void>;
resetPassword(token: string, tokenId: string, password: string): Promise<void>;

getUser(): Promise<User | undefined>;
createUser(user: User): Promise<User>;
saveUser(user: User): Promise<User>;
deleteUser(): Promise<void>;
getTeamMembers(): Promise<TeamMember[]>;

getAllClients(): Promise<Client[]>;
getClients(clientIds: string[]): Promise<Client[]>;
createClient(client: Client): Promise<Client>;
saveClient(client: Client): Promise<Client>;
deleteClient(client: Client): Promise<void>;
deleteAllClients(): Promise<void>;
getClientsInAdditionalTeams(clientIds: string[], teamIds: string[]): Promise<string[]>

getMyTeams(): Promise<Team[]>;
createTeam(team: Team): Promise<Team>;
saveTeam(team: Team): Promise<Team>;
deleteTeam(team: Team): Promise<void>;
}
96 changes: 80 additions & 16 deletions src/api/demo.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
import CoopCareApiInterface from "./coopCareApiInterface";
import { Client, User } from "../models";
import { Client, User, Team } from "../models";
import { ObjectID } from "bson";
import sampleData from "../data/sample1.json";
import { importSamplesV2, sampleClientIds } from "../data/sampleImporter";

export default class DemoApi implements CoopCareApiInterface {
clients = (Client.fromObject(sampleData) as Client[]).map(client => {
client._id = new ObjectID();
return client;
});
private user = (() => {
const user = new User(this.userId, this.userEmail);
user._id = new ObjectID();
user.firstName = "Demo";
user.lastName = "Tester";
user.signature = "DT";
user.activeTeam = ""
return user;
})();
private clients: Client[] = [];
private teams = (() => {
const team = new Team("Team CoopCare", this.userId);
team._id = new ObjectID();
this.user.activeTeam = team._id.toHexString();
team.clients = sampleClientIds().map(id => id.toHexString());
return [team];
})();
private didImportSampleClients = false;

get isLoggedIn() {
return true;
}
get user() {
const user = new User("demo");
user.firstName = "Demo";
user.lastName = "Tester";
user.email = "demo@coopcare.de";
user.signature = window.localStorage.getItem("signature") || "DT";
return user;
get userId() {
return "demo";
}
get userEmail() {
return "demo@coopcare.de";
}
login() {
return Promise.resolve();
Expand All @@ -32,10 +44,31 @@ export default class DemoApi implements CoopCareApiInterface {
confirmUser() {
return Promise.resolve();
}
resendConfirmationEmail() {
return Promise.resolve();
}
sendResetPasswordEmail() {
return Promise.resolve();
}
resetPassword() {
return Promise.resolve();
}

getUser() {
return Promise.resolve(this.user);
}
createUser(user: User) {
return Promise.resolve(user);
}
saveUser(user: User) {
window.localStorage.setItem("signature", user.signature);
return Promise.resolve(user);
}
deleteUser() {
return Promise.resolve();
}
getTeamMembers() {
return Promise.resolve([this.user]);
}

createClient(client: Client) {
client._id = new ObjectID();
Expand All @@ -49,10 +82,41 @@ export default class DemoApi implements CoopCareApiInterface {
deleteAllClients() {
return Promise.reject();
}
getAllClients(): Promise<Client[]> {
return Promise.resolve(this.clients.slice());
getClients(clientIds: string[]): Promise<Client[]> {
if (!this.didImportSampleClients) {
this.clients = this.clients.concat(importSamplesV2());
this.clients.forEach((client, index) => client._id = new ObjectID(clientIds[index]))
this.didImportSampleClients = true;
}
return Promise.resolve(
this.clients.filter(client =>
clientIds.includes(client._id?.toHexString() || ""))
);
}
saveClient(client: Client) {
return Promise.resolve(client);
}
getClientsInAdditionalTeams(clientIds: string[], teamIds: string[]) {
return Promise.resolve(
this.teams
.flatMap(team => teamIds.indexOf(team._id?.toString() || "") < 0 ? team.clients : [])
.filter(clientId => clientIds.indexOf(clientId) >= 0)
);
}

getMyTeams() {
return Promise.resolve(this.teams.slice());
}
createTeam(team: Team) {
team._id = new ObjectID();
this.teams.push(team);
return Promise.resolve(team);
}
saveTeam(team: Team) {
return Promise.resolve(team);
}
deleteTeam(team: Team) {
this.teams = this.teams.filter(item => !item.equals(team));
return Promise.resolve();
}
}
Loading

0 comments on commit 273e9f8

Please sign in to comment.