fix: teams edit modal + race conditions on currentUser
This commit is contained in:
@@ -33,7 +33,7 @@
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul v-for="(member, index) in teamMembers" :key="`new-${index}`">
|
||||
<ul v-for="(member, index) in members" :key="`new-${index}`">
|
||||
<li>
|
||||
<input
|
||||
:placeholder="$t('email')"
|
||||
@@ -84,7 +84,7 @@
|
||||
</li>
|
||||
</div>
|
||||
</ul>
|
||||
<ul v-for="(member, index) in members" :key="index">
|
||||
<ul v-for="(member, index) in newMembers" :key="index">
|
||||
<li>
|
||||
<input
|
||||
:placeholder="$t('email')"
|
||||
@@ -164,122 +164,9 @@
|
||||
|
||||
<script>
|
||||
import * as team_utils from "~/helpers/teams/utils"
|
||||
import gql from "graphql-tag"
|
||||
import cloneDeep from "lodash/cloneDeep"
|
||||
|
||||
export default {
|
||||
apollo: {
|
||||
teamMembers: {
|
||||
query: gql`
|
||||
query GetMyTeams {
|
||||
myTeams {
|
||||
id
|
||||
members {
|
||||
user {
|
||||
displayName
|
||||
email
|
||||
uid
|
||||
}
|
||||
role
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
subscribeToMore: [
|
||||
{
|
||||
document: gql`
|
||||
subscription teamMemberAdded($teamID: String!) {
|
||||
teamMemberAdded(teamID: $teamID) {
|
||||
role
|
||||
user {
|
||||
displayName
|
||||
email
|
||||
uid
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables() {
|
||||
return { teamID: this.$props.editingteamID }
|
||||
},
|
||||
skip() {
|
||||
return this.$props.editingteamID === ""
|
||||
},
|
||||
updateQuery(previousResult, { subscriptionData }) {
|
||||
const teamIdx = previousResult.myTeams.findIndex(
|
||||
(x) => x.id === this.$props.editingteamID
|
||||
)
|
||||
previousResult.myTeams[teamIdx].members.push(subscriptionData.data.teamMemberAdded)
|
||||
return previousResult
|
||||
},
|
||||
},
|
||||
{
|
||||
document: gql`
|
||||
subscription teamMemberUpdated($teamID: String!) {
|
||||
teamMemberUpdated(teamID: $teamID) {
|
||||
role
|
||||
user {
|
||||
displayName
|
||||
email
|
||||
uid
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables() {
|
||||
return { teamID: this.$props.editingteamID }
|
||||
},
|
||||
skip() {
|
||||
return this.$props.editingteamID === ""
|
||||
},
|
||||
updateQuery(previousResult, { subscriptionData }) {
|
||||
const teamIdx = previousResult.myTeams.findIndex(
|
||||
(x) => x.id === this.$props.editingteamID
|
||||
)
|
||||
const memberIdx = previousResult.myTeams[teamIdx].members.findIndex(
|
||||
(x) => x.user.uid === subscriptionData.data.teamMemberUpdated.user.uid
|
||||
)
|
||||
previousResult.myTeams[teamIdx].members[memberIdx].user =
|
||||
subscriptionData.data.teamMemberUpdated.user
|
||||
previousResult.myTeams[teamIdx].members[memberIdx].role =
|
||||
subscriptionData.data.teamMemberUpdated.role
|
||||
|
||||
return previousResult
|
||||
},
|
||||
},
|
||||
{
|
||||
document: gql`
|
||||
subscription teamMemberRemoved($teamID: String!) {
|
||||
teamMemberRemoved(teamID: $teamID)
|
||||
}
|
||||
`,
|
||||
variables() {
|
||||
return { teamID: this.$props.editingteamID }
|
||||
},
|
||||
skip() {
|
||||
return this.$props.editingteamID === ""
|
||||
},
|
||||
updateQuery(previousResult, { subscriptionData }) {
|
||||
const teamIdx = previousResult.myTeams.findIndex(
|
||||
(x) => x.id === this.$props.editingteamID
|
||||
)
|
||||
const memberIdx = previousResult.myTeams[teamIdx].members.findIndex(
|
||||
(x) => x.user.id === subscriptionData.data.teamMemberRemoved.id
|
||||
)
|
||||
if (memberIdx !== -1) previousResult.myTeams[teamIdx].members.splice(memberIdx, 1)
|
||||
|
||||
return previousResult
|
||||
},
|
||||
},
|
||||
],
|
||||
update(response) {
|
||||
const teamIdx = response.myTeams.findIndex((x) => x.id === this.$props.editingteamID)
|
||||
return response.myTeams[teamIdx].members
|
||||
},
|
||||
skip() {
|
||||
return this.$props.editingteamID === ""
|
||||
},
|
||||
},
|
||||
},
|
||||
props: {
|
||||
show: Boolean,
|
||||
editingTeam: Object,
|
||||
@@ -292,6 +179,7 @@ export default {
|
||||
members: [],
|
||||
membersSubject: null,
|
||||
membersSubscription: null,
|
||||
newMembers: [],
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -301,7 +189,7 @@ export default {
|
||||
|
||||
this.membersSubscription = this.membersSubject.subscribe((memberList) => {
|
||||
console.log(memberList)
|
||||
this.members = memberList
|
||||
this.members = cloneDeep(memberList)
|
||||
})
|
||||
})
|
||||
},
|
||||
@@ -321,11 +209,12 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
updateRole(id, role) {
|
||||
this.teamMembers[id].role = role
|
||||
console.log(this.members, id)
|
||||
this.members[id].role = role
|
||||
},
|
||||
addTeamMember() {
|
||||
let value = { key: "", value: "" }
|
||||
this.members.push(value)
|
||||
this.newMembers.push(value)
|
||||
console.log("addTeamMember")
|
||||
},
|
||||
removeExistingTeamMember(userID) {
|
||||
@@ -347,7 +236,7 @@ export default {
|
||||
})
|
||||
},
|
||||
removeTeamMember(index) {
|
||||
this.members.splice(index, 1)
|
||||
this.newMembers.splice(index, 1)
|
||||
console.log("removeTeamMember")
|
||||
},
|
||||
validateEmail(emailID) {
|
||||
@@ -364,8 +253,7 @@ export default {
|
||||
console.log("String length less than 6")
|
||||
return
|
||||
}
|
||||
console.log("saveTeam", this.members)
|
||||
this.$data.members.forEach((element) => {
|
||||
this.$data.newMembers.forEach((element) => {
|
||||
if (!this.validateEmail(element.key)) {
|
||||
this.$toast.error(this.$t("invalid_emailID_format"), {
|
||||
icon: "error",
|
||||
@@ -374,7 +262,7 @@ export default {
|
||||
return
|
||||
}
|
||||
})
|
||||
this.$data.members.forEach((element) => {
|
||||
this.$data.newMembers.forEach((element) => {
|
||||
// Call to the graphql mutation
|
||||
team_utils
|
||||
.addTeamMemberByEmail(this.$apollo, element.value, element.key, this.editingteamID)
|
||||
@@ -394,7 +282,7 @@ export default {
|
||||
})
|
||||
})
|
||||
let messageShown = true
|
||||
this.teamMembers.forEach((element) => {
|
||||
this.members.forEach((element) => {
|
||||
team_utils
|
||||
.updateTeamMemberRole(this.$apollo, element.user.uid, element.role, this.editingteamID)
|
||||
.then((data) => {
|
||||
@@ -444,7 +332,7 @@ export default {
|
||||
})
|
||||
}
|
||||
this.hideModal()
|
||||
this.members = []
|
||||
this.newMembers = []
|
||||
},
|
||||
hideModal() {
|
||||
this.$emit("hide-modal")
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<button
|
||||
class="icon"
|
||||
@click="team.myRole === 'OWNER' ? $emit('edit-team') : ''"
|
||||
v-tooltip.right="$t('edit')"
|
||||
v-tooltip.right="team.myRole === 'OWNER' ? $t('edit') : ''"
|
||||
>
|
||||
<i class="material-icons">group</i>
|
||||
<span>{{ team.name }}</span>
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
<template>
|
||||
<AppSection class="green" icon="history" :label="$t('teams')" ref="teams" no-legend>
|
||||
<!-- debug start -->
|
||||
<pre>me: {{ me }}</pre>
|
||||
<pre>myTeams: {{ myTeams }}</pre>
|
||||
<!-- debug end -->
|
||||
<TeamsAdd :show="showModalAdd" @hide-modal="displayModalAdd(false)" />
|
||||
<TeamsEdit
|
||||
:team="myTeams[0]"
|
||||
@@ -12,11 +8,11 @@
|
||||
:editingteamID="editingteamID"
|
||||
@hide-modal="displayModalEdit(false)"
|
||||
/>
|
||||
<TeamsImportExport
|
||||
<!-- <TeamsImportExport
|
||||
:show="showModalImportExport"
|
||||
:teams="myTeams"
|
||||
@hide-modal="displayModalImportExport(false)"
|
||||
/>
|
||||
/> -->
|
||||
<div class="row-wrapper">
|
||||
<div>
|
||||
<button class="icon" @click="displayModalAdd(true)">
|
||||
@@ -24,11 +20,11 @@
|
||||
<span>{{ $t("new") }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<!-- <div>
|
||||
<button class="icon" @click="displayModalImportExport(true)">
|
||||
{{ $t("import_export") }}
|
||||
</button>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<p v-if="$apollo.queries.myTeams.loading" class="info">{{ $t("loading") }}</p>
|
||||
<p v-if="myTeams.length === 0" class="info">
|
||||
@@ -76,6 +72,7 @@ export default {
|
||||
query GetMe {
|
||||
me {
|
||||
uid
|
||||
eaInvited
|
||||
}
|
||||
}
|
||||
`,
|
||||
|
||||
@@ -4,15 +4,27 @@ import { setContext } from "@apollo/client/link/context"
|
||||
import { fb } from "./fb"
|
||||
import { getMainDefinition } from "@apollo/client/utilities"
|
||||
|
||||
let authToken: String | null = null
|
||||
|
||||
export function registerApolloAuthUpdate() {
|
||||
fb.idToken$.subscribe((token: String | null) => {
|
||||
console.log(token, "from sub")
|
||||
|
||||
authToken = token
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects auth token if available
|
||||
*/
|
||||
const authLink = setContext((_, { headers }) => {
|
||||
if (fb.idToken) {
|
||||
console.log(authToken)
|
||||
|
||||
if (authToken) {
|
||||
return {
|
||||
headers: {
|
||||
...headers,
|
||||
authorization: `Bearer ${fb.idToken}`,
|
||||
authorization: `Bearer ${authToken}`,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
@@ -38,11 +50,11 @@ const wsLink = new WebSocketLink({
|
||||
reconnect: true,
|
||||
lazy: true,
|
||||
connectionParams: () => {
|
||||
if (fb.idToken) {
|
||||
if (authToken) {
|
||||
return {}
|
||||
} else {
|
||||
return {
|
||||
authorization: `Bearer ${fb.idToken}`,
|
||||
authorization: `Bearer ${authToken}`,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -42,12 +42,14 @@ export const currentUserInfo$ = new BehaviorSubject<UserInfo | null>(null)
|
||||
/**
|
||||
* Initializes the currenUserInfo$ view and sets up its update mechanism
|
||||
*/
|
||||
export function initUserInfo() {
|
||||
updateUserInfo()
|
||||
export async function initUserInfo() {
|
||||
await updateUserInfo()
|
||||
console.log("updated")
|
||||
|
||||
fb.idToken$.subscribe(token => {
|
||||
fb.idToken$.subscribe((token) => {
|
||||
if (token) {
|
||||
updateUserInfo()
|
||||
console.log(token, "updateUserInfo")
|
||||
} else {
|
||||
currentUserInfo$.next(null)
|
||||
}
|
||||
@@ -63,22 +65,24 @@ async function updateUserInfo() {
|
||||
query: gql`
|
||||
query GetUserInfo {
|
||||
me {
|
||||
uid,
|
||||
displayName,
|
||||
email,
|
||||
photoURL,
|
||||
uid
|
||||
displayName
|
||||
email
|
||||
photoURL
|
||||
eaInvited
|
||||
}
|
||||
}
|
||||
`
|
||||
`,
|
||||
})
|
||||
|
||||
|
||||
console.log(data)
|
||||
|
||||
currentUserInfo$.next({
|
||||
uid: data.me.uid,
|
||||
displayName: data.me.displayName,
|
||||
email: data.me.email,
|
||||
photoURL : data.me.photoURL,
|
||||
eaInvited: data.me.eaInvited
|
||||
photoURL: data.me.photoURL,
|
||||
eaInvited: data.me.eaInvited,
|
||||
})
|
||||
} catch (e) {
|
||||
currentUserInfo$.next(null)
|
||||
|
||||
@@ -32,7 +32,6 @@ export async function getLiveTeamMembersList(apollo, teamID) {
|
||||
},
|
||||
})
|
||||
|
||||
debugger
|
||||
subject.next(data.team.members)
|
||||
|
||||
const addedSub = apollo
|
||||
@@ -53,6 +52,7 @@ export async function getLiveTeamMembersList(apollo, teamID) {
|
||||
},
|
||||
})
|
||||
.subscribe(({ data }) => {
|
||||
console.log(data)
|
||||
subject.next([...subject.value, data.teamMemberAdded])
|
||||
})
|
||||
|
||||
|
||||
@@ -17,9 +17,12 @@
|
||||
import { setupLocalPersistence } from "~/newstore/localpersistence"
|
||||
import { performMigrations } from "~/helpers/migrations"
|
||||
import { initUserInfo } from "~/helpers/teams/BackendUserInfo"
|
||||
import { registerApolloAuthUpdate } from "~/helpers/apollo"
|
||||
|
||||
export default {
|
||||
beforeMount() {
|
||||
registerApolloAuthUpdate()
|
||||
|
||||
let color = localStorage.getItem("THEME_COLOR") || "green"
|
||||
document.documentElement.setAttribute("data-accent", color)
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div v-if="fb.currentUser">
|
||||
<div v-if="currentUser && currentUser.eaInvited">
|
||||
<Teams />
|
||||
</div>
|
||||
|
||||
@@ -202,6 +202,7 @@ import {
|
||||
defaultSettings,
|
||||
} from "~/newstore/settings"
|
||||
import type { KeysMatching } from "~/types/ts-utils"
|
||||
import { currentUserInfo$ } from "~/helpers/teams/BackendUserInfo"
|
||||
|
||||
import Vue from "vue"
|
||||
|
||||
@@ -243,6 +244,9 @@ export default Vue.extend({
|
||||
SYNC_COLLECTIONS: getSettingSubject("syncCollections"),
|
||||
SYNC_ENVIRONMENTS: getSettingSubject("syncEnvironments"),
|
||||
SYNC_HISTORY: getSettingSubject("syncHistory"),
|
||||
|
||||
// Teams feature flag
|
||||
currentUser: currentUserInfo$,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
Reference in New Issue
Block a user