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
     error: errorSchema.single,
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
 module.exports = {
55
 module.exports = {
38
     method: 'GET',
56
     method: 'GET',
39
     path: '/{profile_id}',
57
     path: '/{profile_id}',
53
                 profileId,
71
                 profileId,
54
                 membershipType,
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
              * Heavily process the result by storing just a profile_id
80
              * Heavily process the result by storing just a profile_id
79
                 completedProfiles.forEach(p => {
100
                 completedProfiles.forEach(p => {
80
                     g.profile = g.profile == p.profile_id ? p : g.profile
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
                 return g
106
                 return g
83
             })
107
             })
84
 
108
 

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

7
     grouping_id: Joi.number(),
7
     grouping_id: Joi.number(),
8
     grouping_name: Joi.string(),
8
     grouping_name: Joi.string(),
9
     grouping_type: Joi.string(),
9
     grouping_type: Joi.string(),
10
+    is_paired: Joi.boolean(),
10
 }).label('grouping_single')
11
 }).label('grouping_single')
11
 
12
 
12
 const singleWithProfile = Joi.object({
13
 const singleWithProfile = Joi.object({
13
     grouping_id: Joi.number(),
14
     grouping_id: Joi.number(),
14
     grouping_name: Joi.string(),
15
     grouping_name: Joi.string(),
15
     grouping_type: Joi.string(),
16
     grouping_type: Joi.string(),
16
-    profile: surveyProfileSchema.single
17
+    is_paired: Joi.boolean(),
18
+    profile: surveyProfileSchema.single,
17
 }).label('grouping_single_with_profile')
19
 }).label('grouping_single_with_profile')
18
 
20
 
19
 module.exports = {
21
 module.exports = {
20
     single: singleGrouping,
22
     single: singleGrouping,
21
     singleWithProfile,
23
     singleWithProfile,
22
     list: Joi.array().items(singleGrouping).label('grouping_list'),
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
                 .patch(patch)
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
      * Check for grouping membership then add membership record and set to active
107
      * Check for grouping membership then add membership record and set to active
104
      * or create a new grouping and add membership record for user and membership record for target
108
      * or create a new grouping and add membership record for user and membership record for target
118
         )
122
         )
119
         if (matchingGroupingIds.length) {
123
         if (matchingGroupingIds.length) {
120
             /** Grab all memberships associated with groupingIds */
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
             /** Set membership as active only if the user initiates it */
127
             /** Set membership as active only if the user initiates it */
127
             await this._patchMembership(memberships, profileId, {
128
             await this._patchMembership(memberships, profileId, {
129
             })
130
             })
130
 
131
 
131
             /** Make a new query to get updated information */
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
             const groupings = await this._getGroupings(matchingGroupingIds, txn)
134
             const groupings = await this._getGroupings(matchingGroupingIds, txn)
137
             return { memberships, groupings }
135
             return { memberships, groupings }
138
         } else {
136
         } else {

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

1
 <template lang="pug">
1
 <template lang="pug">
2
 section.pairs-list
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
             .dot--icon
5
             .dot--icon
8
             .avatar
6
             .avatar
9
             .idCard
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
 </template>
14
 </template>
14
 
15
 
15
 <script setup>
16
 <script setup>
18
         type: [Object, Array],
19
         type: [Object, Array],
19
         default: () => [{}],
20
         default: () => [{}],
20
     },
21
     },
22
+    tabName: {
23
+        type: String,
24
+        default: 'paired',
25
+    },
21
 })
26
 })
22
 </script>
27
 </script>
28
+
23
 <style lang="sass">
29
 <style lang="sass">
24
 .pairs-list
30
 .pairs-list
25
     article
31
     article
32
             width:10vw
38
             width:10vw
33
             height:10vw
39
             height:10vw
34
             background-color:#D5D5D5
40
             background-color:#D5D5D5
35
-</style>
41
+</style>

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

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
 const onPair = async () => {
76
 const onPair = async () => {
72
     const group = await postMembershipByProfileId({
77
     const group = await postMembershipByProfileId({
73
         profileId: currentProfile.id.value,
78
         profileId: currentProfile.id.value,
74
         targetId: props.card.pid,
79
         targetId: props.card.pid,
75
     })
80
     })
76
     updateQueueByProfileId(currentProfile.id.value, props.card.pid, false)
81
     updateQueueByProfileId(currentProfile.id.value, props.card.pid, false)
82
+    currentProfile.getGroupings()
77
     console.warn('created grouping:', group)
83
     console.warn('created grouping:', group)
78
     console.log('is grouping a match?:', group.membershipMatch.hasMatch)
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
 const onPass = async () => {
97
 const onPass = async () => {
82
     updateQueueByProfileId(currentProfile.id.value, props.card.pid, true)
98
     updateQueueByProfileId(currentProfile.id.value, props.card.pid, true)
83
     router.push({ name: 'HomeView' })
99
     router.push({ name: 'HomeView' })

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

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

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

126
     }
126
     }
127
     stop() {
127
     stop() {
128
         this.subscriptions = [MAIN_CHANNEL]
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
     get hasResponses() {
56
     get hasResponses() {
57
         return this.responses.length && this.responses.length > 0
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
      * Login a profile by id number
69
      * Login a profile by id number
62
      * @param {number} profileId
70
      * @param {number} profileId

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

1
 <template lang="pug">
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
             //- pending tab
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
             //- paired tab 
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
     MainNav
15
     MainNav
17
 </template>
16
 </template>
18
 
17
 
19
 <script>
18
 <script>
20
-// import ProfileCardList from '../components/ProfileCardList.vue'
19
+import { Card } from '../entities'
21
 import PairsList from '../components/PairsList.vue'
20
 import PairsList from '../components/PairsList.vue'
22
 
21
 
23
-import { fetchMembershipsByProfileId, fetchQueueByProfileId } from '../services'
22
+import { currentProfile } from '../services'
24
 import { mixins } from '../utils'
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
     if (grouping.type !== 'grouping') {
26
     if (grouping.type !== 'grouping') {
42
         console.error(`Cannot convert ${grouping} to Card. Invalid entity.`)
27
         console.error(`Cannot convert ${grouping} to Card. Invalid entity.`)
43
     }
28
     }
44
     if (!grouping.profile.isValid()) {
29
     if (!grouping.profile.isValid()) {
45
         console.warn(`Profile in ${grouping} is not a valid profile.`)
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
 export default {
42
 export default {
55
     name: 'PairsView',
43
     name: 'PairsView',
56
     components: { PairsList },
44
     components: { PairsList },
57
-    mixins: [mixins.pidMixin, mixins.cardMixin],
58
     data: () => ({
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
     methods: {
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
 </script>
73
 </script>
74
+
83
 <style>
75
 <style>
84
-.select--matches{
76
+.select--matches {
85
     display: flex;
77
     display: flex;
86
     justify-content: space-between;
78
     justify-content: space-between;
87
     margin: 0 25px;
79
     margin: 0 25px;
88
 }
80
 }
89
-.select--matches > div{
81
+.select--matches > div {
90
     width: 100%;
82
     width: 100%;
91
     text-align: center;
83
     text-align: center;
92
     font-size: 16px;
84
     font-size: 16px;
93
     line-height: 40px;
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
 </style>
94
 </style>
95
+s

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