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

feat(analytics-chart): move actions into kebab menu [MA-3301] #1741

Merged
merged 7 commits into from
Oct 31, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@
:chart-data="(exploreResult)"
:chart-options="analyticsChartOptions"
chart-title="Request count by Status Code"
:go-to-explore="(exploreLink)"
:legend-position="legendPosition"
:show-annotations="showAnnotationsToggle"
:show-legend-values="showLegendValuesToggle"
Expand Down Expand Up @@ -330,6 +331,8 @@ const exportCsv = () => {
setModalVisibility(true)
}

const exploreLink: string = 'https://cloud.konghq.tech/us/analytics/explorer'

const exploreResultText = ref('')
const hasError = computed(() => !isValidJson(exploreResultText.value))
const isValid = computed(() => exploreResultText.value !== undefined &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ function mouseMove(x1: number, y1: number, x2: number, y2: number, duration: num
describe('<AnalyticsChart />', () => {
beforeEach(() => {
cy.viewport(1280, 800)
cy.stub(composables, 'useEvaluateFeatureFlag').returns({
evaluateFeatureFlag: () => true,
})
})

it('Renders a line chart for total requests count with status code dimension', () => {
Expand Down Expand Up @@ -251,21 +254,52 @@ describe('<AnalyticsChart />', () => {
chartTitle: 'Requests',
},
})
cy.getTestId('csv-export-button').should('not.exist')

cy.getTestId('chart-action-menu').should('not.exist')
})

it('does not render an "Export" button if chart data is present but prop is set to `false`', () => {
it('renders the kebab menu with only the "Jump to Explore" link if no data is provided', () => {
cy.mount(AnalyticsChart, {
props: {
allowCsvExport: true,
goToExplore: 'https://cloud.konghq.tech/us/analytics/explorer',
chartData: emptyExploreResult,
chartOptions: {
type: 'timeseries_line',
},
chartTitle: 'Requests',
},
})

cy.getTestId('chart-action-menu').should('exist')

// eslint-disable-next-line cypress/unsafe-to-chain-command
cy.getTestId('chart-action-menu').click().then(() => {
cy.getTestId('chart-jump-to-explore').should('exist')
cy.getTestId('csv-export-button').should('not.exist')
})
})

it('does not render an "Export" link in the kebab actions if chart data is present but prop is set to `false`', () => {
cy.mount(AnalyticsChart, {
props: {
allowCsvExport: false,
goToExplore: 'https://cloud.konghq.tech/us/analytics/explorer',
chartData: exploreResult,
chartOptions: {
type: 'timeseries_line',
},
chartTitle: 'Requests',
},
})
cy.getTestId('csv-export-button').should('not.exist')

cy.getTestId('chart-action-menu').should('exist')

// eslint-disable-next-line cypress/unsafe-to-chain-command
cy.getTestId('chart-action-menu').click().then(() => {
cy.getTestId('chart-jump-to-explore').should('exist')
cy.getTestId('csv-export-modal').should('not.exist')
})
})

it('Renders an "Export" button, and tabulated data in the modal preview', () => {
Expand All @@ -280,10 +314,13 @@ describe('<AnalyticsChart />', () => {
},
})

cy.getTestId('csv-export-button').should('exist')
cy.getTestId('chart-action-menu').should('exist')

// eslint-disable-next-line cypress/unsafe-to-chain-command
cy.getTestId('csv-export-button').click().then(() => {
cy.getTestId('chart-action-menu').click().then(() => {
cy.getTestId('chart-jump-to-explore').should('not.exist')

cy.getTestId('csv-export-button').click()
cy.getTestId('csv-export-modal').should('exist')
cy.get('.modal-content .vitals-table').should('exist')
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,55 @@
</KTooltip>
</div>
<div
v-if="allowCsvExport && hasValidChartData"
v-if="allowCsvExport && hasValidChartData && !hasKebabMenuAccess"
class="chart-export-button"
>
<CsvExportButton
:data="rawChartData"
:filename-prefix="filenamePrefix"
/>
</div>
<!-- More actions menu -->
<KDropdown
v-if="hasKebabMenuAccess && hasMenuOptions"
class="dropdown"
data-testid="chart-action-menu"
>
<MoreIcon
:color="KUI_COLOR_TEXT_NEUTRAL"
:size="KUI_ICON_SIZE_40"
/>
<template #items>
<KDropdownItem
v-if="!!goToExplore"
data-testid="chart-jump-to-explore"
>
<a :href="goToExplore">
{{ i18n.t('jumpToExplore') }}
</a>
</KDropdownItem>
<KDropdownItem
v-if="allowCsvExport && hasValidChartData"
class="chart-export-button"
data-testid="chart-csv-export"
>
<span
class="chart-export-trigger"
data-testid="csv-export-button"
@click="exportCsv()"
>
{{ i18n.t('csvExport.exportButton') }}
</span>
</KDropdownItem>
</template>
</KDropdown>
<!-- Keep outside of dropdown, so we can independently affect its visibility -->
<CsvExportModal
v-if="exportModalVisible"
:chart-data="rawChartData"
:filename="csvFilename"
@toggle-modal="setExportModalVisibility"
/>
</div>
<KEmptyState
v-if="!hasValidChartData"
Expand Down Expand Up @@ -110,13 +151,14 @@ import { ChartLegendPosition } from '../enums'
import StackedBarChart from './chart-types/StackedBarChart.vue'
import DoughnutChart from './chart-types/DoughnutChart.vue'
import type { PropType } from 'vue'
import { computed, provide, toRef } from 'vue'
import { computed, provide, toRef, ref } from 'vue'
import { msToGranularity } from '@kong-ui-public/analytics-utilities'
import type { AbsoluteTimeRangeV4, ExploreAggregations, ExploreResultV4, GranularityValues } from '@kong-ui-public/analytics-utilities'
import { hasMillisecondTimestamps, defaultStatusCodeColors } from '../utils'
import TimeSeriesChart from './chart-types/TimeSeriesChart.vue'
import { KUI_COLOR_TEXT_WARNING, KUI_ICON_SIZE_40 } from '@kong/design-tokens'
import { WarningIcon } from '@kong/icons'
import { KUI_COLOR_TEXT_NEUTRAL, KUI_COLOR_TEXT_WARNING, KUI_ICON_SIZE_40 } from '@kong/design-tokens'
import { MoreIcon, WarningIcon } from '@kong/icons'
import CsvExportModal from './CsvExportModal.vue'
import CsvExportButton from './CsvExportButton.vue'

const props = defineProps({
Expand All @@ -125,6 +167,11 @@ const props = defineProps({
required: false,
default: false,
},
goToExplore: {
type: String,
required: false,
default: '',
},
chartData: {
type: Object as PropType<ExploreResultV4>,
required: true,
Expand Down Expand Up @@ -190,6 +237,9 @@ const emit = defineEmits<{
}>()

const { i18n } = composables.useI18n()
const { evaluateFeatureFlag } = composables.useEvaluateFeatureFlag()

const hasKebabMenuAccess = evaluateFeatureFlag('ma-3043-analytics-chart-kebab-menu', false)

const rawChartData = toRef(props, 'chartData')

Expand All @@ -211,6 +261,15 @@ const computedChartData = computed(() => {
).value
})

const exportModalVisible = ref(false)
const setExportModalVisibility = (val: boolean) => {
exportModalVisible.value = val
}
const csvFilename = computed<string>(() => props.filenamePrefix || i18n.t('csvExport.defaultFilename'))
const exportCsv = () => {
setExportModalVisibility(true)
}

const timeRangeMs = computed<number | undefined>(() => {
if (!props.chartData?.meta) {
return 0
Expand Down Expand Up @@ -302,6 +361,8 @@ const showChartHeader = computed(() => {
return (hasValidChartData.value && resultSetTruncated.value && maxEntitiesShown.value) || props.chartTitle || (props.allowCsvExport && hasValidChartData.value)
})

const hasMenuOptions = computed(() => (props.allowCsvExport && hasValidChartData.value) || !!props.goToExplore)

const timeSeriesGranularity = computed<GranularityValues>(() => {

if (!props.chartData.meta.granularity_ms) {
Expand Down Expand Up @@ -413,6 +474,31 @@ provide('legendPosition', toRef(props, 'legendPosition'))
margin-left: var(--kui-space-50, $kui-space-50);
margin-top: var(--kui-space-10, $kui-space-10);
}

// Action menu
.dropdown {
display: flex;
margin-left: var(--kui-space-auto, $kui-space-auto);
margin-right: var(--kui-space-0, $kui-space-0);

li.k-dropdown-item {
a {
text-decoration: none;
}
}
a {
color: $kui-color-text;

&:hover {
color: $kui-color-text;
text-decoration: none;
}
}

&:hover {
cursor: pointer;
}
}
}

</style>
2 changes: 2 additions & 0 deletions packages/analytics/analytics-chart/src/composables/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import useExploreResultToDatasets from './useExploreResultToDatasets'
import useExploreResultToTimeDataset from './useExploreResultToTimeDatasets'
import useReportChartDataForSynthetics from './useReportChartDataForSynthetics'
import useTranslatedUnits from './useTranslatedUnits'
import useEvaluateFeatureFlag from './useEvauluateFeatureFlag'

// All composables must be exported as part of the default object for Cypress test stubs
export default {
Expand All @@ -23,4 +24,5 @@ export default {
useI18n,
useReportChartDataForSynthetics,
useTranslatedUnits,
useEvaluateFeatureFlag,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { AnalyticsBridge } from '@kong-ui-public/analytics-utilities'
import { inject } from 'vue'
import { INJECT_QUERY_PROVIDER } from '../constants'

export default function useEvaluateFeatureFlag() {

const queryBridge: AnalyticsBridge | undefined = inject(INJECT_QUERY_PROVIDER)

const evaluateFeatureFlag = (key: string, defaultValue: boolean) => {
if (!queryBridge) {
return defaultValue
}
return queryBridge.evaluateFeatureFlagFn(key, defaultValue)
}

return {
evaluateFeatureFlag,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const INJECT_QUERY_PROVIDER = 'analytics-query-provider'
1 change: 1 addition & 0 deletions packages/analytics/analytics-chart/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"entityNoName": "no-name",
"debug": "debug",
"total": "Total",
"jumpToExplore": "Jump to Explore",
"chartUnits": {
"ms": "ms",
"bytes": "Byte{plural}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export interface LegendValueEntry {
*/
export interface EnhancedLegendItem extends LegendItem {
value: LegendValueEntry
text: string
}

/**
Expand Down
Loading