2
2
<div class =" s panel" :class =" computedClass" >
3
3
<div class =" flex items-center justify-between" >
4
4
<img :alt =" integration.name" :src =" integration.image" class =" h-6 mb-4" />
5
- <span v-if =" isDone" class =" badge badge--green" >Connected</span >
6
- <div v-else-if =" isError" class =" text-red-500 flex items-center text-sm" >
7
- <i class =" ri-error-warning-line mr-1" /> Failed to connect
8
- </div >
9
- <div v-else-if =" isNoData" class =" text-red-500 flex items-center text-sm" >
10
- <i class =" ri-error-warning-line mr-1" /> Not receiving activities
11
- </div >
12
- <div
13
- v-else-if =" isWaitingForAction"
14
- class =" text-yellow-600 flex items-center text-sm"
15
- >
16
- <i class =" ri-alert-line mr-1" /> Action required
17
- </div >
18
- <div
19
- v-else-if =" isWaitingApproval"
20
- class =" text-gray-500 flex items-center text-sm"
21
- >
22
- <i class =" ri-time-line mr-1" /> Waiting for approval
23
- </div >
24
- <div
25
- v-else-if =" isNeedsToBeReconnected"
26
- class =" text-yellow-600 flex items-center text-sm"
27
- >
28
- <i class =" ri-alert-line mr-1" /> Needs to be reconnected
29
- </div >
30
- <div v-else-if =" isConnected" class =" flex items-center" >
31
- <div
32
- v-loading =" true"
33
- class =" app-page-spinner !relative h-4 !w-4 mr-2 !min-h-fit"
34
- />
35
-
36
- <span class =" text-xs text-gray-900 mr-2" >In progress</span >
37
- <el-tooltip
38
- content =" Fetching first activities from an integration might take a few minutes"
39
- placement =" top"
40
- >
41
- <i class =" ri-question-line text-gray-400" />
42
- </el-tooltip >
5
+ <div >
6
+ <div class =" mb-1 flex justify-end" >
7
+ <span v-if =" isDone" class =" badge badge--green" >Connected</span >
8
+ <div v-else-if =" isError" class =" text-red-500 flex items-center text-sm" >
9
+ <i class =" ri-error-warning-line mr-1" /> Failed to connect
10
+ </div >
11
+ <div v-else-if =" isNoData" class =" text-red-500 flex items-center text-sm" >
12
+ <i class =" ri-error-warning-line mr-1" /> Not receiving activities
13
+ </div >
14
+ <div
15
+ v-else-if =" isWaitingForAction"
16
+ class =" text-yellow-600 flex items-center text-sm"
17
+ >
18
+ <i class =" ri-alert-line mr-1" /> Action required
19
+ </div >
20
+ <div
21
+ v-else-if =" isWaitingApproval"
22
+ class =" text-gray-500 flex items-center text-sm"
23
+ >
24
+ <i class =" ri-time-line mr-1" /> Waiting for approval
25
+ </div >
26
+ <div
27
+ v-else-if =" isNeedsToBeReconnected"
28
+ class =" text-yellow-600 flex items-center text-sm"
29
+ >
30
+ <i class =" ri-alert-line mr-1" /> Needs to be reconnected
31
+ </div >
32
+ <div v-else-if =" isConnected" class =" flex items-center" >
33
+ <div
34
+ v-loading =" true"
35
+ class =" app-page-spinner !relative h-4 !w-4 mr-2 !min-h-fit"
36
+ />
37
+
38
+ <span class =" text-xs text-gray-900 mr-2" >In progress</span >
39
+ <el-tooltip
40
+ content =" Fetching first activities from an integration might take a few minutes"
41
+ placement =" top"
42
+ >
43
+ <i class =" ri-question-line text-gray-400" />
44
+ </el-tooltip >
45
+ </div >
46
+ </div >
47
+ <div class =" h-5 leading-5 text-end" >
48
+ <el-tooltip
49
+ v-if =" includeTimestamp"
50
+ :content =" lastSynced.absolute"
51
+ placement =" top"
52
+ >
53
+ <span class =" text-3xs italic text-gray-500" >{{ lastSynced.relative }}</span >
54
+ </el-tooltip >
55
+ </div >
43
56
</div >
44
57
</div >
58
+
45
59
<div >
46
60
<div class =" flex mb-2" >
47
61
<span class =" block font-semibold" >{{ integration.name }}</span >
101
115
102
116
<script setup>
103
117
import { useStore } from ' vuex' ;
104
- import { defineProps , computed , ref } from ' vue' ;
118
+ import { computed , onMounted , ref } from ' vue' ;
105
119
import { FeatureFlag } from ' @/featureFlag' ;
106
120
import AppIntegrationConnect from ' @/modules/integration/components/integration-connect.vue' ;
107
121
import { isCurrentDateAfterGivenWorkingDays } from ' @/utils/date' ;
108
122
import { ERROR_BANNER_WORKING_DAYS_DISPLAY } from ' @/modules/integration/integration-store' ;
123
+ import moment from ' moment' ;
109
124
110
125
const store = useStore ();
111
126
const props = defineProps ({
@@ -115,6 +130,21 @@ const props = defineProps({
115
130
},
116
131
});
117
132
133
+ onMounted (() => {
134
+ moment .updateLocale (' en' , {
135
+ relativeTime: {
136
+ s: ' 1s' ,
137
+ ss: ' %ds' ,
138
+ m: ' 1min' ,
139
+ mm: ' %dmin' ,
140
+ h: ' 1h' ,
141
+ hh: ' %dh' ,
142
+ d: ' 1d' ,
143
+ dd: ' %dd' ,
144
+ },
145
+ });
146
+ });
147
+
118
148
const computedClass = computed (() => ({
119
149
' integration-custom' : props .integration .platform === ' custom' ,
120
150
}));
@@ -146,6 +176,16 @@ const isNeedsToBeReconnected = computed(
146
176
() => props .integration .status === ' needs-reconnect' ,
147
177
);
148
178
179
+ const includeTimestamp = computed (() => isConnected .value
180
+ || isDone .value || isError .value
181
+ || isNoData .value || isWaitingForAction .value
182
+ || isWaitingApproval .value || isNeedsToBeReconnected .value );
183
+
184
+ const lastSynced = computed (() => ({
185
+ absolute: moment .utc (props .integration .updatedAt ).format (' MMM DD, YYYY HH:mm' ),
186
+ relative: ` last synced ${ moment .utc (props .integration .updatedAt ).fromNow ()} ` ,
187
+ }));
188
+
149
189
const loadingDisconnect = ref (false );
150
190
151
191
const handleDisconnect = async () => {
0 commit comments