Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FE: NMS-17004: Update the login events item in Usage Stats, add link to download CSV file #7598

Merged
merged 3 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 38 additions & 3 deletions ui/src/components/UsageStatistics/UsageStatisticsTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
<td v-if="row.isLink">
<a href="#" @click.prevent="() => showFullValue(row)">See full value</a>
</td>
<td v-else-if="row.isFile">
<a href="#" @click.prevent="() => downloadFile(row)">Download CSV File</a>
</td>
<td v-else-if="shouldClipValue(row)">
{{ getClippedValue(row) }}
<a href="#" @click.prevent="() => showFullValue(row)">See full value</a>
Expand Down Expand Up @@ -80,16 +83,16 @@
</template>

<script setup lang="ts">
import { FeatherSortHeader, SORT } from '@featherds/table'
import { isNumber, isString } from '@/lib/utils'
import { useUsageStatisticsStore } from '@/stores/usageStatisticsStore'
import { FeatherSortObject } from '@/types'
import UsageStatisticsModal from './UsageStatisticsModal.vue'
import {
UsageStatisticsData,
UsageStatisticsMetadata,
UsageStatisticsMetadataItem
} from '@/types/usageStatistics'
import { FeatherSortHeader, SORT } from '@featherds/table'
import UsageStatisticsModal from './UsageStatisticsModal.vue'

interface StatisticsItem {
// this is just for sorting
Expand All @@ -98,6 +101,7 @@ interface StatisticsItem {
name: string
description: string
isLink: boolean
isFile: boolean
latestValue: string
}

Expand Down Expand Up @@ -145,13 +149,14 @@ const filteredData = computed<StatisticsItem[]>(() => {
const statsValue = statistics.value[key]
const metaItem = metadataMap.value.get(key)

const { isLink, latestValue } = getLatestValue(statsValue, metaItem)
const { isLink, isFile, latestValue } = getLatestValue(statsValue, metaItem)

const statsItem = {
key,
name: metaItem?.name || '',
description: metaItem?.description || '',
isLink,
isFile,
latestValue
} as StatisticsItem

Expand Down Expand Up @@ -186,6 +191,7 @@ const filteredData = computed<StatisticsItem[]>(() => {
const getLatestValue = (statsValue: any, metaItem: UsageStatisticsMetadataItem | undefined) => {
let latestValue = ''
let isLink = false
let isFile = false
const datatype = metaItem?.datatype || ''

// use hints from metadata if possible
Expand All @@ -198,6 +204,8 @@ const getLatestValue = (statsValue: any, metaItem: UsageStatisticsMetadataItem |
latestValue = new Intl.NumberFormat().format(statsValue as number)
} else if (datatype === 'object') {
isLink = true
} else if (datatype.startsWith('file')) {
isFile = true
}
} else {
// fallback if metadata entry not found
Expand All @@ -212,6 +220,7 @@ const getLatestValue = (statsValue: any, metaItem: UsageStatisticsMetadataItem |

return {
isLink,
isFile,
latestValue
}
}
Expand Down Expand Up @@ -248,6 +257,32 @@ const showFullValue = (item: StatisticsItem) => {
showValueModalVisible.value = true
}

const downloadFile = (item: StatisticsItem) => {
// Decode the Base64 string into a byte array
const byteCharacters = atob(statistics.value[item.key])
const byteNumbers = new Array(byteCharacters.length).fill(null).map((_, i) => byteCharacters.charCodeAt(i))
const byteArray = new Uint8Array(byteNumbers)

const fileType = metadata.value.metadata.find((meta) => meta.key === item.key)?.datatype.split('|').pop()?.toLowerCase()
const fileName = `Login events Past 60 days.${fileType}`
const contentType = fileType === 'csv' ? 'text/csv' : 'application/octet-stream'

// Create a Blob object for the CSV
const blob = new Blob([byteArray], { type: contentType})

// Create a temporary link element
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = fileName

// Trigger the download
link.click()

// Clean up
URL.revokeObjectURL(link.href)
document.body.removeChild(link)
}

onMounted(() => {
const wrap = document.getElementById('wrap')
const thead = document.querySelector('div.usage-stats-table table thead') as HTMLElement
Expand Down
6 changes: 3 additions & 3 deletions ui/src/containers/OpenAPI.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,14 @@ const setup = async () => {

if (protocol === https) {
const openApiSpecString = JSON.stringify(openApiSpec)
const modifiedOpenApiSpecString = openApiSpecString.includes(https)
const modifiedOpenApiSpecString = openApiSpecString.includes(https)
? openApiSpecString
: openApiSpecString.replaceAll(http, https);
: openApiSpecString.replaceAll(http, https)
modifiedOpenApiSpec = JSON.parse(modifiedOpenApiSpecString)
const openApiSpecStringV1 = JSON.stringify(openApiSpecV1)
const modifiedOpenApiSpecStringV1 = openApiSpecStringV1.includes(https)
? openApiSpecStringV1
: openApiSpecStringV1.replaceAll(http, https);
: openApiSpecStringV1.replaceAll(http, https)
modifiedOpenApiV1Spec = JSON.parse(modifiedOpenApiSpecStringV1)
}

Expand Down
Loading