Skip to content

Commit ea09f2c

Browse files
committed
Add last synced information to integrations
1 parent 4fa3cc9 commit ea09f2c

File tree

1 file changed

+79
-39
lines changed

1 file changed

+79
-39
lines changed

frontend/src/modules/integration/components/integration-list-item.vue

Lines changed: 79 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,60 @@
22
<div class="s panel" :class="computedClass">
33
<div class="flex items-center justify-between">
44
<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>
4356
</div>
4457
</div>
58+
4559
<div>
4660
<div class="flex mb-2">
4761
<span class="block font-semibold">{{ integration.name }}</span>
@@ -101,11 +115,12 @@
101115

102116
<script setup>
103117
import { useStore } from 'vuex';
104-
import { defineProps, computed, ref } from 'vue';
118+
import { computed, onMounted, ref } from 'vue';
105119
import { FeatureFlag } from '@/featureFlag';
106120
import AppIntegrationConnect from '@/modules/integration/components/integration-connect.vue';
107121
import { isCurrentDateAfterGivenWorkingDays } from '@/utils/date';
108122
import { ERROR_BANNER_WORKING_DAYS_DISPLAY } from '@/modules/integration/integration-store';
123+
import moment from 'moment';
109124
110125
const store = useStore();
111126
const props = defineProps({
@@ -115,6 +130,21 @@ const props = defineProps({
115130
},
116131
});
117132
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+
118148
const computedClass = computed(() => ({
119149
'integration-custom': props.integration.platform === 'custom',
120150
}));
@@ -146,6 +176,16 @@ const isNeedsToBeReconnected = computed(
146176
() => props.integration.status === 'needs-reconnect',
147177
);
148178
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+
149189
const loadingDisconnect = ref(false);
150190
151191
const handleDisconnect = async () => {

0 commit comments

Comments
 (0)