mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-06 00:09:22 +00:00
feat: dashboard table chart download as csv file (#2428)
- download table chart as a csv file
This commit is contained in:
@@ -17,8 +17,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
<template>
|
||||
<div
|
||||
class="panelcontainer"
|
||||
@mouseover="() => (showFullScreenBtn = true)"
|
||||
@mouseleave="() => (showFullScreenBtn = false)"
|
||||
@mouseover="() => (isCurrentlyHoveredPanel = true)"
|
||||
@mouseleave="() => (isCurrentlyHoveredPanel = false)"
|
||||
data-test="dashboard-panel-container"
|
||||
>
|
||||
<div class="drag-allow">
|
||||
<q-bar
|
||||
@@ -28,23 +29,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
style="border-top-left-radius: 3px; border-top-right-radius: 3px"
|
||||
data-test="dashboard-panel-bar"
|
||||
>
|
||||
<q-icon v-if="!viewOnly" name="drag_indicator" data-test="dashboard-panel-drag"/>
|
||||
<q-icon
|
||||
v-if="!viewOnly"
|
||||
name="drag_indicator"
|
||||
data-test="dashboard-panel-drag"
|
||||
/>
|
||||
<div :title="props.data.title" class="panelHeader">
|
||||
{{ props.data.title }}
|
||||
</div>
|
||||
<q-space />
|
||||
<q-icon
|
||||
v-if="!viewOnly && showFullScreenBtn && props.data.description != ''"
|
||||
v-if="
|
||||
!viewOnly && isCurrentlyHoveredPanel && props.data.description != ''
|
||||
"
|
||||
name="info_outline"
|
||||
style="cursor: pointer"
|
||||
data-test="dashboard-panel-description-info"
|
||||
>
|
||||
<q-tooltip anchor="bottom right" self="top right" max-width="220px">
|
||||
<div style="white-space: pre-wrap;">{{ props.data.description }}</div>
|
||||
<div style="white-space: pre-wrap">
|
||||
{{ props.data.description }}
|
||||
</div>
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
<q-btn
|
||||
v-if="!viewOnly && showFullScreenBtn"
|
||||
v-if="!viewOnly && isCurrentlyHoveredPanel"
|
||||
icon="fullscreen"
|
||||
flat
|
||||
size="sm"
|
||||
@@ -53,6 +62,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
title="Full screen"
|
||||
data-test="dashboard-panel-fullscreen-btn"
|
||||
/>
|
||||
<!-- if table chart then download button as a csv file -->
|
||||
<q-btn
|
||||
v-if="
|
||||
!viewOnly && isCurrentlyHoveredPanel && props.data.type == 'table'
|
||||
"
|
||||
icon="download"
|
||||
flat
|
||||
size="sm"
|
||||
padding="1px"
|
||||
@click="
|
||||
PanleSchemaRendererRef?.tableRendererRef?.downloadTableAsCSV(
|
||||
props.data.title
|
||||
)
|
||||
"
|
||||
title="Download as a CSV"
|
||||
data-test="dashboard-panel-table-download-as-csv-btn"
|
||||
/>
|
||||
<q-btn
|
||||
v-if="dependentAdHocVariable"
|
||||
:icon="outlinedWarning"
|
||||
@@ -138,6 +164,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
:variablesData="props.variablesData"
|
||||
@metadata-update="metaDataValue"
|
||||
@updated:data-zoom="$emit('updated:data-zoom', $event)"
|
||||
ref="PanleSchemaRendererRef"
|
||||
></PanelSchemaRenderer>
|
||||
<q-dialog v-model="showViewPanel">
|
||||
<QueryInspector :metaData="metaData" :data="props.data"></QueryInspector>
|
||||
@@ -195,6 +222,9 @@ export default defineComponent({
|
||||
};
|
||||
const showText = ref(false);
|
||||
|
||||
// need PanleSchemaRendererRef for table download as a csv
|
||||
const PanleSchemaRendererRef: any = ref(null);
|
||||
|
||||
//check if dependent adhoc variable exists
|
||||
const dependentAdHocVariable = computed(() => {
|
||||
if (!metaData.value) return false;
|
||||
@@ -215,7 +245,7 @@ export default defineComponent({
|
||||
});
|
||||
|
||||
// for full screen button
|
||||
const showFullScreenBtn: any = ref(false);
|
||||
const isCurrentlyHoveredPanel: any = ref(false);
|
||||
|
||||
//for edit panel
|
||||
const onEditPanel = (data: any) => {
|
||||
@@ -291,7 +321,7 @@ export default defineComponent({
|
||||
onEditPanel,
|
||||
onDuplicatePanel,
|
||||
deletePanelDialog,
|
||||
showFullScreenBtn,
|
||||
isCurrentlyHoveredPanel,
|
||||
outlinedWarning,
|
||||
store,
|
||||
metaDataValue,
|
||||
@@ -299,7 +329,8 @@ export default defineComponent({
|
||||
showViewPanel,
|
||||
dependentAdHocVariable,
|
||||
confirmDeletePanelDialog,
|
||||
showText
|
||||
showText,
|
||||
PanleSchemaRendererRef,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -19,11 +19,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
<div v-show="!errorDetail" style="height: 100%; width: 100%">
|
||||
<GeoMapRenderer
|
||||
v-if="panelSchema.type == 'geomap'"
|
||||
:data="panelData.chartType == 'geomap' ? panelData : { options: {backgroundColor: 'transparent'} }"
|
||||
:data="
|
||||
panelData.chartType == 'geomap'
|
||||
? panelData
|
||||
: { options: { backgroundColor: 'transparent' } }
|
||||
"
|
||||
/>
|
||||
<TableRenderer
|
||||
v-else-if="panelSchema.type == 'table'"
|
||||
:data="panelData.chartType == 'table' ? panelData : { options: {backgroundColor: 'transparent'} }"
|
||||
:data="
|
||||
panelData.chartType == 'table'
|
||||
? panelData
|
||||
: { options: { backgroundColor: 'transparent' } }
|
||||
"
|
||||
ref="tableRendererRef"
|
||||
/>
|
||||
<ChartRenderer
|
||||
v-else
|
||||
@@ -34,7 +43,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
panelData.chartType != 'geomap' &&
|
||||
panelData.chartType != 'table')
|
||||
? panelData
|
||||
: { options: {backgroundColor: 'transparent'} }
|
||||
: { options: { backgroundColor: 'transparent' } }
|
||||
"
|
||||
@updated:data-zoom="$emit('updated:data-zoom', $event)"
|
||||
/>
|
||||
@@ -115,6 +124,9 @@ export default defineComponent({
|
||||
chartPanelRef
|
||||
);
|
||||
|
||||
// need tableRendererRef to access downloadTableAsCSV method
|
||||
const tableRendererRef = ref(null);
|
||||
|
||||
// hovered series state
|
||||
// used to show tooltip axis for all charts
|
||||
const hoveredSeriesState: any = inject("hoveredSeriesState", null);
|
||||
@@ -253,6 +265,7 @@ export default defineComponent({
|
||||
panelData,
|
||||
noData,
|
||||
metadata,
|
||||
tableRendererRef,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -25,11 +25,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
:rows="data.rows || []"
|
||||
:columns="data.columns"
|
||||
row-key="id"
|
||||
ref="tableRef"
|
||||
data-test="dashboard-panel-table"
|
||||
>
|
||||
</q-table>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { exportFile, useQuasar } from "quasar";
|
||||
import { defineComponent, ref, onMounted, watch } from "vue";
|
||||
|
||||
export default defineComponent({
|
||||
@@ -42,10 +45,74 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
setup(props: any) {
|
||||
const $q = useQuasar();
|
||||
const tableRef: any = ref(null);
|
||||
|
||||
function wrapCsvValue(val: any, formatFn?: any, row?: any) {
|
||||
let formatted = formatFn !== void 0 ? formatFn(val, row) : val;
|
||||
|
||||
formatted =
|
||||
formatted === void 0 || formatted === null ? "" : String(formatted);
|
||||
|
||||
formatted = formatted.split('"').join('""');
|
||||
/**
|
||||
* Excel accepts \n and \r in strings, but some other CSV parsers do not
|
||||
* Uncomment the next two lines to escape new lines
|
||||
*/
|
||||
// .split('\n').join('\\n')
|
||||
// .split('\r').join('\\r')
|
||||
|
||||
return `"${formatted}"`;
|
||||
}
|
||||
|
||||
const downloadTableAsCSV = (title?: any) => {
|
||||
// naive encoding to csv format
|
||||
const content = [
|
||||
props?.data?.columns?.map((col: any) => wrapCsvValue(col.label)),
|
||||
]
|
||||
.concat(
|
||||
tableRef?.value?.filteredSortedRows?.map((row: any) =>
|
||||
props?.data?.columns
|
||||
?.map((col: any) =>
|
||||
wrapCsvValue(
|
||||
typeof col.field === "function"
|
||||
? col.field(row)
|
||||
: row[col.field === void 0 ? col.name : col.field],
|
||||
col.format,
|
||||
row
|
||||
)
|
||||
)
|
||||
.join(",")
|
||||
)
|
||||
)
|
||||
.join("\r\n");
|
||||
|
||||
const status = exportFile(
|
||||
(title ?? "table-export") + ".csv",
|
||||
content,
|
||||
"text/csv"
|
||||
);
|
||||
|
||||
if (status === true) {
|
||||
$q.notify({
|
||||
message: "Table downloaded as a CSV file",
|
||||
color: "positive",
|
||||
timeout: 2000,
|
||||
});
|
||||
} else {
|
||||
$q.notify({
|
||||
message: "Browser denied file download...",
|
||||
color: "negative",
|
||||
icon: "warning",
|
||||
});
|
||||
}
|
||||
};
|
||||
return {
|
||||
pagination: ref({
|
||||
rowsPerPage: 0,
|
||||
}),
|
||||
downloadTableAsCSV,
|
||||
tableRef,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user