Procházet zdrojové kódy

:recycle: passing group.is_paired from api | making pending list and pairs list | storing grouping.is_paired in currentProfile upon login

tags/0.0.1^2
j před 3 roky
rodič
revize
2445eaa5e7

+ 25
- 1
backend/lib/routes/membership/active.js Zobrazit soubor

@@ -34,6 +34,24 @@ const responseSchemas = {
34 34
     error: errorSchema.single,
35 35
 }
36 36
 
37
+const _activeGroupingIds = allMemberships => {
38
+    const active = {}
39
+    allMemberships.forEach(membership => {
40
+        if (!membership.is_active) return
41
+        if (!active[membership.grouping_id]) {
42
+            active[membership.grouping_id] = []
43
+        }
44
+        active[membership.grouping_id].push(membership)
45
+    })
46
+    const ids = []
47
+    Object.values(active).forEach(profileListInGrouping => {
48
+        if (profileListInGrouping.length == 2) {
49
+            ids.push(profileListInGrouping[0].grouping_id)
50
+        }
51
+    })
52
+    return ids
53
+}
54
+
37 55
 module.exports = {
38 56
     method: 'GET',
39 57
     path: '/{profile_id}',
@@ -53,7 +71,10 @@ module.exports = {
53 71
                 profileId,
54 72
                 membershipType,
55 73
             )
56
-            // console.log('groupings :>> ', groupings)
74
+            let memberships = await membershipService.findMemberships(
75
+                groupings.map(grouping => grouping.grouping_id),
76
+            )
77
+            // console.log('groupings :>> ', memberships)
57 78
 
58 79
             /**
59 80
              * Heavily process the result by storing just a profile_id
@@ -79,6 +100,9 @@ module.exports = {
79 100
                 completedProfiles.forEach(p => {
80 101
                     g.profile = g.profile == p.profile_id ? p : g.profile
81 102
                 })
103
+                g.is_paired = _activeGroupingIds(memberships).includes(
104
+                    g.grouping_id,
105
+                )
82 106
                 return g
83 107
             })
84 108
 

+ 6
- 2
backend/lib/schemas/groupings.js Zobrazit soubor

@@ -7,18 +7,22 @@ const singleGrouping = Joi.object({
7 7
     grouping_id: Joi.number(),
8 8
     grouping_name: Joi.string(),
9 9
     grouping_type: Joi.string(),
10
+    is_paired: Joi.boolean(),
10 11
 }).label('grouping_single')
11 12
 
12 13
 const singleWithProfile = Joi.object({
13 14
     grouping_id: Joi.number(),
14 15
     grouping_name: Joi.string(),
15 16
     grouping_type: Joi.string(),
16
-    profile: surveyProfileSchema.single
17
+    is_paired: Joi.boolean(),
18
+    profile: surveyProfileSchema.single,
17 19
 }).label('grouping_single_with_profile')
18 20
 
19 21
 module.exports = {
20 22
     single: singleGrouping,
21 23
     singleWithProfile,
22 24
     list: Joi.array().items(singleGrouping).label('grouping_list'),
23
-    listWithProfiles: Joi.array().items(singleWithProfile).label('grouping_list_with_profiles')
25
+    listWithProfiles: Joi.array()
26
+        .items(singleWithProfile)
27
+        .label('grouping_list_with_profiles'),
24 28
 }

+ 7
- 9
backend/lib/services/membership.js Zobrazit soubor

@@ -98,7 +98,11 @@ module.exports = class MembershipService extends Schmervice.Service {
98 98
                 .patch(patch)
99 99
         }
100 100
     }
101
-
101
+    async findMemberships(groupingIds) {
102
+        const { Membership } = this.server.models()
103
+        /** Grab all memberships associated with groupingIds */
104
+        return await Membership.query().whereIn('grouping_id', groupingIds)
105
+    }
102 106
     /**
103 107
      * Check for grouping membership then add membership record and set to active
104 108
      * or create a new grouping and add membership record for user and membership record for target
@@ -118,10 +122,7 @@ module.exports = class MembershipService extends Schmervice.Service {
118 122
         )
119 123
         if (matchingGroupingIds.length) {
120 124
             /** Grab all memberships associated with groupingIds */
121
-            let memberships = await Membership.query().whereIn(
122
-                'grouping_id',
123
-                matchingGroupingIds,
124
-            )
125
+            let memberships = await findMemberships(matchingGroupingIds)
125 126
 
126 127
             /** Set membership as active only if the user initiates it */
127 128
             await this._patchMembership(memberships, profileId, {
@@ -129,10 +130,7 @@ module.exports = class MembershipService extends Schmervice.Service {
129 130
             })
130 131
 
131 132
             /** Make a new query to get updated information */
132
-            memberships = await Membership.query().whereIn(
133
-                'grouping_id',
134
-                matchingGroupingIds,
135
-            )
133
+            memberships = await findMemberships(matchingGroupingIds)
136 134
             const groupings = await this._getGroupings(matchingGroupingIds, txn)
137 135
             return { memberships, groupings }
138 136
         } else {

+ 14
- 8
frontend/src/components/PairsList.vue Zobrazit soubor

@@ -1,15 +1,16 @@
1 1
 <template lang="pug">
2 2
 section.pairs-list
3
-    article(v-if="pairs.length")
4
-        .pair.w-flex.align-center.justify-space-around(
5
-            v-for="p in pairs"
6
-        )
3
+    article(v-if='pairs.length')
4
+        .pair.w-flex.align-center.justify-space-around(v-for='pair in pairs')
7 5
             .dot--icon
8 6
             .avatar
9 7
             .idCard
10
-                p S.R.
11
-                p Registered Nurse  
12
-    p(v-else) No results.    
8
+                p {{ pair.profile.name }}
9
+                p {{ pair.profile.pid }}
10
+                p since: {{ pair.grouping.createdAt }}
11
+                p updated: {{ pair.grouping.lastUpdatedAt }}
12
+                p paired: {{ pair.grouping.is_paired }}
13
+    p(v-else) No {{ tabName }} profiles.
13 14
 </template>
14 15
 
15 16
 <script setup>
@@ -18,8 +19,13 @@ const props = defineProps({
18 19
         type: [Object, Array],
19 20
         default: () => [{}],
20 21
     },
22
+    tabName: {
23
+        type: String,
24
+        default: 'paired',
25
+    },
21 26
 })
22 27
 </script>
28
+
23 29
 <style lang="sass">
24 30
 .pairs-list
25 31
     article
@@ -32,4 +38,4 @@ const props = defineProps({
32 38
             width:10vw
33 39
             height:10vw
34 40
             background-color:#D5D5D5
35
-</style>
41
+</style>

+ 17
- 1
frontend/src/components/ProfileCard.vue Zobrazit soubor

@@ -68,16 +68,32 @@ const props = defineProps({
68 68
     },
69 69
 })
70 70
 
71
+/**
72
+ * Attempt to pair with target profile
73
+ * Creates a grouping, and a membership
74
+ * for both profileId and targetId
75
+ */
71 76
 const onPair = async () => {
72 77
     const group = await postMembershipByProfileId({
73 78
         profileId: currentProfile.id.value,
74 79
         targetId: props.card.pid,
75 80
     })
76 81
     updateQueueByProfileId(currentProfile.id.value, props.card.pid, false)
82
+    currentProfile.getGroupings()
77 83
     console.warn('created grouping:', group)
78 84
     console.log('is grouping a match?:', group.membershipMatch.hasMatch)
79
-    router.push({ name: 'HomeView' })
85
+
86
+    let goToRoute = { name: 'HomeView' }
87
+    if (group.membershipMatch.hasMatch) {
88
+        goToRoute = { name: 'PairsView' }
89
+    }
90
+    router.push(goToRoute)
80 91
 }
92
+
93
+/**
94
+ * Send to the back of the matchQueue
95
+ * and forward back home
96
+ */
81 97
 const onPass = async () => {
82 98
     updateQueueByProfileId(currentProfile.id.value, props.card.pid, true)
83 99
     router.push({ name: 'HomeView' })

+ 2
- 1
frontend/src/entities/grouping/grouping.schema.js Zobrazit soubor

@@ -20,7 +20,8 @@ const groupingSchema = {
20 20
         grouping_id: Joi.number().required(),
21 21
         grouping_name: Joi.string(),
22 22
         grouping_type: Joi.string(),
23
-        profile: Joi.object()
23
+        is_paired: Joi.boolean(),
24
+        profile: Joi.object(),
24 25
     }),
25 26
     /** fields required before saving */
26 27
     required: ['grouping_id'],

+ 1
- 1
frontend/src/services/chat.service.js Zobrazit soubor

@@ -126,7 +126,7 @@ class Chatter {
126 126
     }
127 127
     stop() {
128 128
         this.subscriptions = [MAIN_CHANNEL]
129
-        console.warn('chatter stop no implemented')
129
+        console.warn('chatter stop not implemented')
130 130
     }
131 131
 }
132 132
 

+ 9
- 1
frontend/src/services/login.service.js Zobrazit soubor

@@ -56,7 +56,15 @@ class Login {
56 56
     get hasResponses() {
57 57
         return this.responses.length && this.responses.length > 0
58 58
     }
59
-
59
+    /**
60
+     * Groupings pending pair
61
+     */
62
+    get pendingGroupings() {
63
+        return this.groupings.filter(grouping => grouping.is_paired == false)
64
+    }
65
+    get pairedGroupings() {
66
+        return this.groupings.filter(grouping => grouping.is_paired == true)
67
+    }
60 68
     /**
61 69
      * Login a profile by id number
62 70
      * @param {number} profileId

+ 52
- 60
frontend/src/views/PairsView.vue Zobrazit soubor

@@ -1,103 +1,95 @@
1 1
 <template lang="pug">
2
-main.view--matches
3
-    article(v-if="!loading")
4
-
5
-        w-tabs(:items="tabs" fill-bar)
6
-            template(#item-title="{ item }")
7
-               span.green {{ item.title }}
2
+main.view--pairs
3
+    article(v-if='isLoggedIn')
4
+        w-tabs(:items='tabs' fill-bar)
5
+            template(#item-title='{ item }')
6
+                span.green {{ item.title }}
8 7
             //- pending tab
9
-            template(#item-content.1="{ item }")
10
-                PairsList(:pairs="pending")
8
+            template(#item-content.1='{ item }')
9
+                PairsList(:pairs='pending' tab-name='pending')
11 10
             //- paired tab 
12
-            template(#item-content.2="{ item }")
13
-                PairsList(:pairs="paired")
11
+            template(#item-content.2='{ item }')
12
+                PairsList(:pairs='paired' tab-name='paired')
14 13
 
15
-    w-spinner(v-else bounce)
14
+    w-spinner(bounce v-else)
16 15
     MainNav
17 16
 </template>
18 17
 
19 18
 <script>
20
-// import ProfileCardList from '../components/ProfileCardList.vue'
19
+import { Card } from '../entities'
21 20
 import PairsList from '../components/PairsList.vue'
22 21
 
23
-import { fetchMembershipsByProfileId, fetchQueueByProfileId } from '../services'
22
+import { currentProfile } from '../services'
24 23
 import { mixins } from '../utils'
25 24
 
26
-const convertToCard = profile => {
27
-    if (profile.type !== 'profile') {
28
-        console.error(`Cannot convert ${profile} to Card. Invalid entity.`)
29
-    }
30
-    if (!profile.isValid()) {
31
-        console.warn(`Profile ${profile.profile_id} is not a valid profile.`)
32
-    }
33
-    return new Card({
34
-        pid: profile.profile_id,
35
-        name: profile.user_name,
36
-        avatar: profile.profile_media[0],
37
-    })
38
-}
39
-
40
-const converGroupingToCard = grouping => {
25
+const convertGroupingToCard = grouping => {
41 26
     if (grouping.type !== 'grouping') {
42 27
         console.error(`Cannot convert ${grouping} to Card. Invalid entity.`)
43 28
     }
44 29
     if (!grouping.profile.isValid()) {
45 30
         console.warn(`Profile in ${grouping} is not a valid profile.`)
46 31
     }
47
-    return new Card({
48
-        pid: grouping.profile.profile_id,
49
-        name: grouping.profile.user_name,
50
-        avatar: grouping.profile.profile_media[0],
51
-    })
32
+    return {
33
+        profile: new Card({
34
+            pid: grouping.profile.profile_id,
35
+            name: grouping.profile.user_name,
36
+            avatar: grouping.profile.profile_media[0],
37
+        }),
38
+        grouping,
39
+    }
52 40
 }
53 41
 
54 42
 export default {
55 43
     name: 'PairsView',
56 44
     components: { PairsList },
57
-    mixins: [mixins.pidMixin, mixins.cardMixin],
58 45
     data: () => ({
59
-        tabs: [
60
-          { title: 'Pending',},
61
-          { title: 'Paired',},
62
-        ],
63
-        paired: ['x'],
64
-        pending: ['f'],
46
+        tabs: [{ title: 'Pending' }, { title: 'Paired' }],
65 47
     }),
48
+    computed: {
49
+        isLoggedIn() {
50
+            return currentProfile.isLoggedIn
51
+        },
52
+        pending() {
53
+            if (!this.isLoggedIn || !currentProfile.pendingGroupings) return []
54
+            return this._reformat(
55
+                currentProfile.pendingGroupings,
56
+                convertGroupingToCard,
57
+            )
58
+        },
59
+        paired() {
60
+            if (!this.isLoggedIn || !currentProfile.pairedGroupings) return []
61
+            return this._reformat(
62
+                currentProfile.pairedGroupings,
63
+                convertGroupingToCard,
64
+            )
65
+        },
66
+    },
66 67
     methods: {
67
-        /** Gets called from cardMixin */
68
-        async getCards() {
69
-            this.loading = true
70
-            try {
71
-                const pending = await fetchQueueByProfileId(this.pid)
72
-                this.pending = this._reformat(pending,converGroupingToCard)
73
-                const paired = await fetchMembershipsByProfileId(this.pid)
74
-                this.paired = this._reformat(paired,convertToCard)
75
-            } catch (err) {
76
-                console.error(err)
77
-            }
78
-            this.loading = false
68
+        _reformat(data, mapCb) {
69
+            return data.map(mapCb)
79 70
         },
80 71
     },
81 72
 }
82 73
 </script>
74
+
83 75
 <style>
84
-.select--matches{
76
+.select--matches {
85 77
     display: flex;
86 78
     justify-content: space-between;
87 79
     margin: 0 25px;
88 80
 }
89
-.select--matches > div{
81
+.select--matches > div {
90 82
     width: 100%;
91 83
     text-align: center;
92 84
     font-size: 16px;
93 85
     line-height: 40px;
94 86
 }
95
-.active{
96
-    border-bottom: 3px solid #F2CD5C;
97
-    color: #F2CD5C;
87
+.active {
88
+    border-bottom: 3px solid #f2cd5c;
89
+    color: #f2cd5c;
98 90
 }
99
-.idle{
100
-    color: #BCC5D3;
91
+.idle {
92
+    color: #bcc5d3;
101 93
 }
102
-
103 94
 </style>
95
+s

Načítá se…
Zrušit
Uložit