1
1
<template >
2
- <v-container id =" messages" fluid class =" pa-0 ma-0" height =" 100%" >
3
- <v-row v-if =" loading" class =" ma-0" >
4
- <Spinner style =" width : 100% " ></Spinner >
5
- </v-row >
6
- <v-row fluid class =" mx-4" v-else >
7
- <v-row >
8
- <v-col id =" messages-summary" fluid class =" pa-0" :cols =" 4" >
9
- <v-card tile style =" border-right : 1px solid lightgrey " :height =" fitScreenHeight()" class =" pa-0 elevation-0" >
10
- <v-data-table
11
- :headers =" columns"
12
- :items =" messages"
13
- :mobile-breakpoint =" 960"
14
- :height =" fitScreenHeight()"
15
- fixed-header
16
- :item-value =" messageId"
17
- :items-per-page =" -1"
18
- hide-default-footer
19
- @click:row =" rowClickHandler"
20
- >
21
- <template #no-data >
22
- <v-alert :value =" true" type =" info" > No Data </v-alert >
23
- </template >
24
- <template #item .isRead =" { item } " >
25
- {{ item.isRead ? 'Read' : 'Unread' }}
26
- </template >
27
- <template #item .programYearValue =" { item } " >
28
- {{ formatFiscalYearName(item.programYearValue) }}
29
- </template >
30
- </v-data-table >
31
- </v-card >
32
- </v-col >
33
- <v-col v-if =" message.sender" id =" messages-content" fluid class =" pa-0" :cols =" 8" >
34
- <v-card class =" pa-4 overflow-auto elevation-0" fluid tile :height =" fitScreenHeight()" >
35
- <v-card-title class =" pa-0" >
36
- <v-row >
37
- <v-col :cols =" 8" >
38
- {{ message.sender }}
39
- </v-col >
40
- <v-col align =" right" :cols =" 4" >
41
- {{ message.dateReceived }}
42
- </v-col >
43
- </v-row >
44
- <v-row >
45
- <v-col >
46
- <strong >{{ message.subject }}</strong >
47
- </v-col >
48
- </v-row >
49
- </v-card-title >
50
- <v-divider />
51
- <v-card-text v-html =" message.messageContent" ></v-card-text >
52
- </v-card >
53
- </v-col >
54
- </v-row >
2
+ <v-container id =" messages" fluid class =" pa-0" >
3
+ <Spinner v-if =" loading" />
4
+ <v-row v-else no-gutters >
5
+ <v-col id =" messages-summary" cols =" 12" md =" 5" :class =" borderClass" >
6
+ <v-card tile elevation =" 0" >
7
+ <v-data-table
8
+ :headers =" columns"
9
+ :items =" messages"
10
+ :mobile =" null"
11
+ mobile-breakpoint =" lg"
12
+ :height =" screenHeight"
13
+ fixed-header
14
+ hover
15
+ item-key =" messageId"
16
+ item-value =" messageId"
17
+ :items-per-page =" -1"
18
+ hide-default-footer
19
+ :row-props =" getRowProps"
20
+ @click:row =" rowClickHandler"
21
+ >
22
+ <template #no-data >
23
+ <v-alert :value =" true" type =" info" > No Data </v-alert >
24
+ </template >
25
+ <template #item .isRead =" { item } " >
26
+ {{ item.isRead ? 'Read' : 'Unread' }}
27
+ </template >
28
+ <template #item .programYearValue =" { item } " >
29
+ {{ formatFiscalYearName(item.programYearValue) }}
30
+ </template >
31
+ </v-data-table >
32
+ </v-card >
33
+ </v-col >
34
+ <v-col v-if =" message.sender" id =" messages-content" cols =" 12" md =" 7" class =" mt-6 mt-md-0" >
35
+ <v-card class =" px-6 overflow-auto elevation-0" :height =" screenHeight" >
36
+ <div >
37
+ <v-row >
38
+ <v-col cols =" 12" sm =" 8" >
39
+ {{ message.sender }}
40
+ </v-col >
41
+ <v-col cols =" 12" sm =" 4" class =" text-right" >
42
+ {{ message.dateReceived }}
43
+ </v-col >
44
+ </v-row >
45
+ <div class =" pt-2" >
46
+ <strong >{{ message.subject }}</strong >
47
+ </div >
48
+ </div >
49
+ <v-divider class =" my-4" />
50
+ <div v-html =" message.messageContent" ></div >
51
+ </v-card >
52
+ </v-col >
55
53
</v-row >
56
54
<v-divider />
57
55
<v-row justify =" center" class =" pa-3" >
58
- <v-btn id =" back-button" color = " info " variant = " outlined " : size =" buttonSize " @click =" goToHomePage()" > Back </ v-btn >
56
+ <AppButton id =" back-button" :primary = " false " size =" x-large " @click =" goToHomePage()" >Back</ AppButton >
59
57
</v-row >
60
58
</v-container >
61
59
</template >
62
60
63
61
<script >
64
- import { useDisplay } from ' vuetify ' ;
62
+ import { mapState , mapActions } from ' pinia ' ;
65
63
66
64
import { useAuthStore } from ' @/store/auth.js' ;
67
65
import { useMessageStore } from ' @/store/message.js' ;
68
- import { mapState , mapActions } from ' pinia ' ;
66
+
69
67
import Spinner from ' @/components/common/Spinner.vue' ;
68
+ import AppButton from ' @/components/guiComponents/AppButton.vue' ;
69
+
70
70
import { PATHS } from ' @/utils/constants.js' ;
71
71
import { formatFiscalYearName } from ' @/utils/format' ;
72
72
73
73
export default {
74
74
name: ' MessagesPage' ,
75
75
components: {
76
76
Spinner,
77
+ AppButton,
77
78
},
78
79
data () {
79
80
return {
80
- selectedId: - 1 ,
81
81
columns: [
82
82
{ title: ' Read/Unread' , align: ' start' , key: ' isRead' },
83
83
{ title: ' Subject' , key: ' subject' },
@@ -91,8 +91,8 @@ export default {
91
91
dateReceived: ' ' ,
92
92
messageContent: ' ' ,
93
93
},
94
- displayName: ' ' ,
95
94
loading: false ,
95
+ selectedMessageId: undefined ,
96
96
};
97
97
},
98
98
computed: {
@@ -101,20 +101,28 @@ export default {
101
101
messages () {
102
102
return this .allMessages || [];
103
103
},
104
- buttonSize () {
105
- const sizeMap = {
106
- xs: ' large' ,
107
- sm: ' large' ,
108
- md: ' large' ,
109
- lg: ' x-large' ,
110
- xl: ' x-large' ,
111
- };
112
- return sizeMap[this .displayName ] || ' medium' ;
104
+ borderClass () {
105
+ return this .$vuetify .display .mdAndUp ? ' border-right' : ' border-bottom' ;
106
+ },
107
+ screenHeight () {
108
+ switch (this .$vuetify .display .name ) {
109
+ case ' xs' :
110
+ return ' 67vh' ;
111
+ case ' sm' :
112
+ return ' 82vh' ;
113
+ case ' md' :
114
+ return ' 75vh' ;
115
+ case ' lg' :
116
+ return ' 70vh' ;
117
+ case ' xl' :
118
+ return ' 78vh' ;
119
+ default :
120
+ return ' 70vh' ;
121
+ }
113
122
},
114
123
},
115
- mounted () {
116
- this .displayName = useDisplay ().name .value ;
117
- this .loadMessages ();
124
+ async created () {
125
+ await this .loadMessages ();
118
126
},
119
127
methods: {
120
128
... mapActions (useMessageStore, [' updateMessage' , ' getAllMessages' ]),
@@ -133,7 +141,8 @@ export default {
133
141
}
134
142
},
135
143
136
- rowClickHandler (event , { item }) {
144
+ rowClickHandler (_ , { item }) {
145
+ this .selectedMessageId = item? .messageId ;
137
146
this .message = {
138
147
subject: item .subject || ' No subject' ,
139
148
dateReceived: item .dateReceived || ' Unknown date' ,
@@ -148,52 +157,25 @@ export default {
148
157
console .error (' No messageId found in item' );
149
158
}
150
159
},
151
- getMessageStyle (message ) {
152
- return message .isRead ? ' read' : ' unread' ;
160
+ getRowProps (item ) {
161
+ const message = item? .item ;
162
+ let rowClass = ' ' ;
163
+ if (! message? .isRead ) rowClass += ' unread-message ' ;
164
+ if (this .selectedMessageId === message? .messageId ) rowClass += ' highlighted-row' ;
165
+ return { class: rowClass };
153
166
},
154
167
goToHomePage () {
155
168
this .$router .push (PATHS .ROOT .HOME );
156
169
},
157
- fitScreenHeight () {
158
- switch (this .displayName ) {
159
- case ' xs' :
160
- return ' 67vh' ;
161
- case ' sm' :
162
- return ' 82vh' ;
163
- case ' md' :
164
- return ' 75vh' ;
165
- case ' lg' :
166
- return ' 70vh' ;
167
- case ' xl' :
168
- return ' 78vh' ;
169
- default :
170
- return ' 70vh' ;
171
- }
172
- },
173
170
},
174
171
};
175
172
< / script>
176
-
177
173
< style scoped>
178
- :deep(html ) {
179
- overflow-y : auto ;
180
- }
181
- :deep(.read ) {
182
- font-weight : normal ;
183
- }
184
- :deep(.unread ) {
174
+ : deep (.unread - message ) {
185
175
font- weight: bold;
186
176
}
187
- :deep(tr :hover ) {
188
- cursor : pointer ;
189
- }
190
- :deep(tr .v-data-table__selected ) {
191
- background : #c2e0fa !important ;
192
- }
193
- :deep(.v-data-table-header th ) {
194
- white-space : nowrap ;
195
- }
196
- :deep(.v-data-table__wrapper ) {
197
- margin-bottom : 0px ;
177
+
178
+ : deep (.highlighted - row ) {
179
+ background: #c2e0fa;
198
180
}
199
181
< / style>
0 commit comments