TeamMemberAdapter.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import { BehaviorSubject } from "rxjs"
  2. import gql from "graphql-tag"
  3. import cloneDeep from "lodash/cloneDeep"
  4. import * as Apollo from "@apollo/client/core"
  5. import { apolloClient } from "~/helpers/apollo"
  6. interface TeamsTeamMember {
  7. membershipID: string
  8. user: {
  9. uid: string
  10. email: string
  11. }
  12. role: "OWNER" | "EDITOR" | "VIEWER"
  13. }
  14. export default class TeamMemberAdapter {
  15. members$: BehaviorSubject<TeamsTeamMember[]>
  16. private teamMemberAdded$: ZenObservable.Subscription | null
  17. private teamMemberRemoved$: ZenObservable.Subscription | null
  18. private teamMemberUpdated$: ZenObservable.Subscription | null
  19. constructor(private teamID: string | null) {
  20. this.members$ = new BehaviorSubject<TeamsTeamMember[]>([])
  21. this.teamMemberAdded$ = null
  22. this.teamMemberUpdated$ = null
  23. this.teamMemberRemoved$ = null
  24. if (this.teamID) this.initialize()
  25. }
  26. changeTeamID(newTeamID: string | null) {
  27. this.members$.next([])
  28. this.teamID = newTeamID
  29. if (this.teamID) this.initialize()
  30. }
  31. unsubscribeSubscriptions() {
  32. this.teamMemberAdded$?.unsubscribe()
  33. this.teamMemberRemoved$?.unsubscribe()
  34. this.teamMemberUpdated$?.unsubscribe()
  35. }
  36. private async initialize() {
  37. await this.loadTeamMembers()
  38. this.registerSubscriptions()
  39. }
  40. private async loadTeamMembers(): Promise<void> {
  41. const result: TeamsTeamMember[] = []
  42. let cursor: string | null = null
  43. while (true) {
  44. const response: Apollo.ApolloQueryResult<any> = await apolloClient.query({
  45. query: gql`
  46. query GetTeamMembers($teamID: String!, $cursor: String) {
  47. team(teamID: $teamID) {
  48. members(cursor: $cursor) {
  49. membershipID
  50. user {
  51. uid
  52. email
  53. }
  54. role
  55. }
  56. }
  57. }
  58. `,
  59. variables: {
  60. teamID: this.teamID,
  61. cursor,
  62. },
  63. })
  64. result.push(...response.data.team.members)
  65. if ((response.data.team.members as any[]).length === 0) break
  66. else {
  67. cursor =
  68. response.data.team.members[response.data.team.members.length - 1]
  69. .membershipID
  70. }
  71. }
  72. this.members$.next(result)
  73. }
  74. private registerSubscriptions() {
  75. this.teamMemberAdded$ = apolloClient
  76. .subscribe({
  77. query: gql`
  78. subscription TeamMemberAdded($teamID: String!) {
  79. teamMemberAdded(teamID: $teamID) {
  80. user {
  81. uid
  82. email
  83. }
  84. role
  85. }
  86. }
  87. `,
  88. variables: {
  89. teamID: this.teamID,
  90. },
  91. })
  92. .subscribe(({ data }) => {
  93. this.members$.next([...this.members$.value, data.teamMemberAdded])
  94. })
  95. this.teamMemberRemoved$ = apolloClient
  96. .subscribe({
  97. query: gql`
  98. subscription TeamMemberRemoved($teamID: String!) {
  99. teamMemberRemoved(teamID: $teamID)
  100. }
  101. `,
  102. variables: {
  103. teamID: this.teamID,
  104. },
  105. })
  106. .subscribe(({ data }) => {
  107. this.members$.next(
  108. this.members$.value.filter(
  109. (el) => el.user.uid !== data.teamMemberRemoved
  110. )
  111. )
  112. })
  113. this.teamMemberUpdated$ = apolloClient
  114. .subscribe({
  115. query: gql`
  116. subscription TeamMemberUpdated($teamID: String!) {
  117. teamMemberUpdated(teamID: $teamID) {
  118. user {
  119. uid
  120. email
  121. }
  122. role
  123. }
  124. }
  125. `,
  126. variables: {
  127. teamID: this.teamID,
  128. },
  129. })
  130. .subscribe(({ data }) => {
  131. const list = cloneDeep(this.members$.value)
  132. const obj = list.find(
  133. (el) => el.user.uid === data.teamMemberUpdated.user.uid
  134. )
  135. if (!obj) return
  136. Object.assign(obj, data.teamMemberUpdated)
  137. })
  138. }
  139. }