Skip to content

Commit 2248673

Browse files
authored
Merge pull request #6035 from harshrajeevsingh/fix/missing-loading-state
fix: added missing loading state in AuditLogs
2 parents e0f5220 + 0b9549b commit 2248673

8 files changed

Lines changed: 109 additions & 64 deletions

File tree

frontend/src/components/audit-log/AuditLog.vue

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
<template>
22
<ff-loading v-if="loading" message="Loading Activity..." />
3-
<div v-if="hasNoEntries && !loading" class="ff-no-data ff-no-data-large">
4-
No Activity Found
5-
</div>
6-
<ff-accordion v-for="(logEntries, date, $index) in logEntriesByDate" :key="date" :label="date" :set-open="$index < 3" data-el="accordion" :disabled="disableAccordion">
7-
<template #meta>
8-
<span>{{ logEntries.length }} Event{{ logEntries.length === 1 ? '' : 's' }}</span>
9-
</template>
10-
<template #content>
11-
<div v-for="entry in logEntries" :key="entry.id">
12-
<AuditEntry :entry="entry" :association="getAssociation(entry)" :disableAssociations="disableAssociations" />
13-
</div>
14-
</template>
15-
</ff-accordion>
16-
<div v-if="!hasNoEntries && showLoadMore !== false && nextCursor" class="px-8 py-4">
17-
<a v-if="!loading" class="forge-button-inline" @click.stop="loadMore">Load more...</a>
18-
<div v-else class="text-gray-500">Loading...</div>
19-
</div>
3+
<template v-else>
4+
<div v-if="hasNoEntries && !loading" class="ff-no-data ff-no-data-large">
5+
No Activity Found
6+
</div>
7+
<ff-accordion v-for="(logEntries, date, $index) in logEntriesByDate" :key="date" :label="date" :set-open="$index < 3" data-el="accordion" :disabled="disableAccordion">
8+
<template #meta>
9+
<span>{{ logEntries.length }} Event{{ logEntries.length === 1 ? '' : 's' }}</span>
10+
</template>
11+
<template #content>
12+
<div v-for="entry in logEntries" :key="entry.id">
13+
<AuditEntry :entry="entry" :association="getAssociation(entry)" :disableAssociations="disableAssociations" />
14+
</div>
15+
</template>
16+
</ff-accordion>
17+
<div v-if="!hasNoEntries && showLoadMore !== false && nextCursor" class="px-8 py-4">
18+
<a v-if="!loading" class="forge-button-inline" @click.stop="loadMore">Load more...</a>
19+
<div v-else class="text-gray-500">Loading...</div>
20+
</div>
21+
</template>
2022
</template>
2123

2224
<script>
@@ -52,6 +54,10 @@ export default {
5254
// should the association be disabled?
5355
type: Boolean,
5456
default: false
57+
},
58+
loading: {
59+
type: Boolean,
60+
default: false
5561
}
5662
},
5763
emits: ['load-more'],
@@ -85,7 +91,6 @@ export default {
8591
},
8692
data () {
8793
return {
88-
loading: false,
8994
nextCursor: false // TODO: drive this properly through pagination
9095
}
9196
},

frontend/src/components/audit-log/AuditLogBrowser.vue

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<div class="ff-admin-audit">
33
<div data-el="audit-log">
44
<slot name="title" />
5-
<AuditLog :entries="logEntries" :associations="associations" />
5+
<AuditLog :entries="logEntries" :associations="associations" :loading="loading" />
66
</div>
77
<div>
88
<SectionTopMenu hero="Filters" />
@@ -56,6 +56,10 @@ export default {
5656
type: Array,
5757
required: true
5858
},
59+
loading: {
60+
type: Boolean,
61+
required: true
62+
},
5963
associations: {
6064
type: Object,
6165
default: () => {}
@@ -68,8 +72,6 @@ export default {
6872
emits: ['load-entries'],
6973
data () {
7074
return {
71-
loading: true,
72-
gettingEntries: false,
7375
auditFilters: {
7476
event: '',
7577
types: [],
@@ -99,29 +101,28 @@ export default {
99101
},
100102
watch: {
101103
'auditFilters.username': function () {
102-
if (this.loading || this.gettingEntries) {
104+
if (this.loading) {
103105
return // skip if we're already loading entries
104106
}
105107
this.loadEntries()
106108
},
107109
'auditFilters.event': function () {
108-
if (this.loading || this.gettingEntries) {
110+
if (this.loading) {
109111
return // skip if we're already loading entries
110112
}
111113
this.loadEntries()
112114
},
113115
users: function (users) {
114116
this.auditFilters.users = users
115117
}
118+
116119
},
117120
created () {
118-
this.loading = true
119121
this.auditFilters.scope = this.logType // init the scope to the logType set in the component's props
120122
this.auditFilters.logType = this.logType // init the scope to the logType
121123
this.auditFilters.users = this.users
122124
this.loadEventTypes()
123125
this.loadEntries()
124-
this.loading = false
125126
},
126127
methods: {
127128
/**
@@ -132,7 +133,6 @@ export default {
132133
* @param {string} [logType] The log type to load event type dropdown for
133134
*/
134135
loadEntries (scope, includeChildren, logType) {
135-
this.gettingEntries = true
136136
logType = logType || this.auditFilters.logType
137137
if (this.auditFilters.logType !== logType) {
138138
this.auditFilters.logType = logType // store the scope for later queries
@@ -153,7 +153,6 @@ export default {
153153
params.append('includeChildren', includeChildren)
154154
}
155155
this.$emit('load-entries', params)
156-
this.gettingEntries = false
157156
},
158157
loadEventTypes (scope) {
159158
scope = scope || this.auditFilters.scope

frontend/src/pages/admin/AuditLog.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
</template>
88
</ff-page-header>
99
</template>
10-
<AuditLogBrowser ref="AuditLog" :users="users" :logEntries="logEntries" logType="platform" @load-entries="loadEntries" />
10+
<AuditLogBrowser ref="AuditLog" :users="users" :logEntries="logEntries" logType="platform" :loading="loading" @load-entries="loadEntries" />
1111
</ff-page>
1212
</template>
1313

@@ -26,7 +26,8 @@ export default {
2626
data () {
2727
return {
2828
logEntries: [],
29-
users: []
29+
users: [],
30+
loading: true
3031
}
3132
},
3233
computed: {
@@ -46,6 +47,8 @@ export default {
4647
if (err.response?.status === 403) {
4748
this.$router.push('/')
4849
}
50+
} finally {
51+
this.loading = false
4952
}
5053
}
5154
}

frontend/src/pages/application/Activity.vue

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<AuditLogBrowser ref="AuditLog" :users="users" :logEntries="logEntries" :associations="associations" :logType="logScope" @load-entries="loadEntries">
2+
<AuditLogBrowser ref="AuditLog" :users="users" :logEntries="logEntries" :associations="associations" :logType="logScope" :loading="loading" @load-entries="loadEntries">
33
<template #title>
44
<SectionTopMenu hero="Audit Log" info="Recorded events that have taken place in within this application." />
55
</template>
@@ -61,6 +61,7 @@ export default {
6161
data () {
6262
return {
6363
logEntries: [],
64+
loading: true,
6465
associations: {}, // applications, instances, devices
6566
users: [],
6667
auditFilters: {
@@ -122,16 +123,22 @@ export default {
122123
}
123124
params.set('includeChildren', includeChildren)
124125
params.set('scope', paramScope)
125-
if (this.applicationId) {
126-
let log
127-
if (paramScope === 'application') {
128-
log = (await ApplicationApi.getApplicationAuditLog(this.applicationId, params, cursor, 200))
129-
} else {
130-
const instanceId = this.auditFilters.selectedEventScope
131-
log = (await InstanceApi.getInstanceAuditLog(instanceId, params, cursor, 200))
126+
try {
127+
if (this.applicationId) {
128+
let log
129+
if (paramScope === 'application') {
130+
log = (await ApplicationApi.getApplicationAuditLog(this.applicationId, params, cursor, 200))
131+
} else {
132+
const instanceId = this.auditFilters.selectedEventScope
133+
log = (await InstanceApi.getInstanceAuditLog(instanceId, params, cursor, 200))
134+
}
135+
this.logEntries = log.log
136+
this.associations = includeChildren ? log.associations : null
132137
}
133-
this.logEntries = log.log
134-
this.associations = includeChildren ? log.associations : null
138+
} catch (error) {
139+
console.error('Failed to load audit logs:', error)
140+
} finally {
141+
this.loading = false
135142
}
136143
}
137144
},

frontend/src/pages/device/AuditLog.vue

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<div class="mb-3">
33
<SectionTopMenu hero="Audit Log" info="" />
44
</div>
5-
<AuditLogBrowser ref="AuditLog" :users="users" :logEntries="logEntries" logType="device" @load-entries="loadEntries" />
5+
<AuditLogBrowser ref="AuditLog" :users="users" :logEntries="logEntries" logType="device" :loading="loading" @load-entries="loadEntries" />
66
</template>
77

88
<script>
@@ -29,7 +29,8 @@ export default {
2929
data () {
3030
return {
3131
logEntries: [],
32-
users: []
32+
users: [],
33+
loading: true
3334
}
3435
},
3536
computed: {
@@ -52,7 +53,13 @@ export default {
5253
},
5354
async loadEntries (params = new URLSearchParams(), cursor = undefined) {
5455
const deviceId = this.device.id
55-
this.logEntries = (await DeviceApi.getDeviceAuditLog(deviceId, params, cursor, 200)).log
56+
try {
57+
this.logEntries = (await DeviceApi.getDeviceAuditLog(deviceId, params, cursor, 200)).log
58+
} catch (error) {
59+
console.error('Failed to load audit logs:', error)
60+
} finally {
61+
this.loading = false
62+
}
5663
}
5764
}
5865
}

frontend/src/pages/instance/AuditLog.vue

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<AuditLogBrowser ref="AuditLog" :users="users" :logEntries="logEntries" :associations="associations" logType="project" @load-entries="loadEntries">
2+
<AuditLogBrowser ref="AuditLog" :users="users" :logEntries="logEntries" :associations="associations" logType="project" :loading="loading" @load-entries="loadEntries">
33
<template #title>
44
<SectionTopMenu hero="Audit Log" info="Recorded events that have taken place in within this instance." />
55
</template>
@@ -49,6 +49,7 @@ export default {
4949
data () {
5050
return {
5151
logEntries: [],
52+
loading: true,
5253
associations: {}, // devices
5354
users: [],
5455
auditFilters: {
@@ -92,18 +93,24 @@ export default {
9293
* @param cursor - cursor to use for pagination
9394
*/
9495
async loadEntries (params = new URLSearchParams(), cursor = undefined) {
95-
if (this.instance.id) {
96-
const auditLog = (await InstanceApi.getInstanceAuditLog(this.instance.id, params, cursor, 200))
97-
this.logEntries = auditLog.log
98-
// dont show associations if we are looking at "this" scope (project)"
99-
let showAssociations = false
100-
if (this.auditFilters.selectedEventScope === 'device') {
101-
showAssociations = true
96+
try {
97+
if (this.instance.id) {
98+
const auditLog = (await InstanceApi.getInstanceAuditLog(this.instance.id, params, cursor, 200))
99+
this.logEntries = auditLog.log
100+
// dont show associations if we are looking at "this" scope (project)"
101+
let showAssociations = false
102+
if (this.auditFilters.selectedEventScope === 'device') {
103+
showAssociations = true
104+
}
105+
if (this.auditFilters.selectedEventScope === 'project' && this.auditFilters.includeChildren) {
106+
showAssociations = true
107+
}
108+
this.associations = showAssociations ? auditLog.associations : null
102109
}
103-
if (this.auditFilters.selectedEventScope === 'project' && this.auditFilters.includeChildren) {
104-
showAssociations = true
105-
}
106-
this.associations = showAssociations ? auditLog.associations : null
110+
} catch (error) {
111+
console.error('Failed to load audit logs:', error)
112+
} finally {
113+
this.loading = false
107114
}
108115
},
109116
triggerLoad ({ users = false, events = true } = {}) {

frontend/src/pages/instance/Overview.vue

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@
107107
</div>
108108
<div class="ff-instance-info">
109109
<FormHeading><TrendingUpIcon />Recent Activity</FormHeading>
110-
<AuditLog :entries="auditLog" :showLoadMore="false" :disableAccordion="true" :disableAssociations="true" />
111-
<div class="pb-4 text-center">
110+
<AuditLog :entries="auditLog" :loading="loading" :showLoadMore="false" :disableAccordion="true" :disableAssociations="true" />
111+
<div v-if="!loading" class="pb-4 text-center">
112112
<router-link to="./audit-log" class="forge-button-inline">More...</router-link>
113113
</div>
114114
</div>
@@ -154,7 +154,8 @@ export default {
154154
},
155155
data () {
156156
return {
157-
auditLog: []
157+
auditLog: [],
158+
loading: true
158159
}
159160
},
160161
computed: {
@@ -185,9 +186,18 @@ export default {
185186
methods: {
186187
loadLogs () {
187188
if (this.instance && this.instance.id) {
188-
this.loadItems(this.instance.id).then((data) => {
189-
this.auditLog = data.log
190-
})
189+
this.loading = true
190+
this.loadItems(this.instance.id)
191+
.then((data) => {
192+
this.auditLog = data.log
193+
})
194+
.catch((error) => {
195+
console.error('Error loading logs:', error)
196+
this.auditLog = []
197+
})
198+
.finally(() => {
199+
this.loading = false
200+
})
191201
}
192202
},
193203
loadItems: async function (instanceId, cursor) {

frontend/src/pages/team/AuditLog.vue

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
</template>
88
</ff-page-header>
99
</template>
10-
<AuditLogBrowser ref="AuditLog" :users="users" :logEntries="logEntries" :associations="associations" logType="team" @load-entries="loadEntries">
10+
<AuditLogBrowser ref="AuditLog" :users="users" :logEntries="logEntries" :associations="associations" logType="team" :loading="loading" @load-entries="loadEntries">
1111
<template #title>
1212
<SectionTopMenu hero="Audit Log" info="Recorded events that have taken place in this Team." />
1313
</template>
@@ -64,6 +64,7 @@ export default {
6464
data () {
6565
return {
6666
logEntries: [],
67+
loading: true,
6768
associations: {}, // applications, instances, devices
6869
users: [],
6970
auditFilters: {
@@ -118,9 +119,15 @@ export default {
118119
}
119120
params.set('includeChildren', includeChildren)
120121
params.set('scope', paramScope)
121-
const auditLog = (await TeamAPI.getTeamAuditLog(teamId, params, cursor, 200))
122-
this.logEntries = auditLog.log
123-
this.associations = auditLog.associations
122+
try {
123+
const auditLog = (await TeamAPI.getTeamAuditLog(teamId, params, cursor, 200))
124+
this.logEntries = auditLog.log
125+
this.associations = auditLog.associations
126+
} catch (error) {
127+
console.error('Failed to load audit logs:', error)
128+
} finally {
129+
this.loading = false
130+
}
124131
}
125132
},
126133
triggerLoad ({ users = false, events = true } = {}) {

0 commit comments

Comments
 (0)