start on table maker ui
This commit is contained in:
@@ -16,6 +16,7 @@ import type {
|
||||
UploadAssetsResponse,
|
||||
RunReportPreviewRequest,
|
||||
RunReportRequest,
|
||||
VariableAnalysis,
|
||||
} from "../types/reporting";
|
||||
import type { QTreeFileNode } from "@/types/filebrowser";
|
||||
import { notifySuccess } from "@/utils/notify";
|
||||
@@ -49,8 +50,7 @@ export interface useReportingTemplates {
|
||||
) => void;
|
||||
exportReport: (id: number) => void;
|
||||
importReport: (payload: string) => void;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
variableAnalysis: Ref<any>;
|
||||
variableAnalysis: Ref<VariableAnalysis>;
|
||||
getAllowedValues: (payload: {
|
||||
variables: string;
|
||||
dependencies?: ReportDependencies;
|
||||
@@ -65,8 +65,7 @@ export function useReportTemplates(): useReportingTemplates {
|
||||
const renderedPreview = ref("");
|
||||
const renderedVariables = ref("");
|
||||
const reportData = ref("");
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const variableAnalysis = ref<any>({});
|
||||
const variableAnalysis = ref<VariableAnalysis>({});
|
||||
|
||||
const getReportTemplates = (dependsOn?: string[]) => {
|
||||
isLoading.value = true;
|
||||
@@ -232,8 +231,7 @@ export function useReportTemplates(): useReportingTemplates {
|
||||
isError.value = false;
|
||||
axios
|
||||
.post(`${baseUrl}/templates/preview/analysis/`, payload)
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
.then(({ data }: { data: any }) => {
|
||||
.then(({ data }: { data: VariableAnalysis }) => {
|
||||
variableAnalysis.value = data;
|
||||
})
|
||||
.catch(() => (isError.value = true))
|
||||
|
||||
@@ -258,7 +258,7 @@ For details, see: https://license.tacticalrmm.com/ee
|
||||
dense
|
||||
:ripple="false"
|
||||
icon="mdi-table-large-plus"
|
||||
@click="insertTable"
|
||||
@click="openTableMaker"
|
||||
>
|
||||
<q-tooltip :delay="500">Table</q-tooltip>
|
||||
</q-btn>
|
||||
@@ -283,6 +283,7 @@ import ReportDataQueryForm from "./ReportDataQueryForm.vue";
|
||||
import DataQuerySelect from "./DataQuerySelect.vue";
|
||||
import ReportAssetSelect from "./ReportAssetSelect.vue";
|
||||
import ReportChartSelect from "./ReportChartSelect.vue";
|
||||
import ReportTableMaker from "./ReportTableMaker.vue";
|
||||
|
||||
// utils
|
||||
import { convertCamelCase } from "@/utils/format";
|
||||
@@ -449,26 +450,13 @@ function insertHr() {
|
||||
_editor.focus();
|
||||
}
|
||||
|
||||
function insertTable() {
|
||||
const table = `<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Column1 Name</th>
|
||||
<th>Column2 Name</th>
|
||||
<th>Column3 Name</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for agents in datasources.agentsQuery %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>`;
|
||||
insert(table, true);
|
||||
function openTableMaker() {
|
||||
$q.dialog({
|
||||
component: ReportTableMaker,
|
||||
}).onOk((table) => {
|
||||
insert(table, true);
|
||||
_editor.focus();
|
||||
});
|
||||
_editor.focus();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,3 +3,134 @@ Copyright (c) 2023-present Amidaware Inc.
|
||||
This file is subject to the EE License Agreement.
|
||||
For details, see: https://license.tacticalrmm.com/ee
|
||||
-->
|
||||
|
||||
<template>
|
||||
<q-dialog ref="dialogRef" @hide="onDialogHide">
|
||||
<q-card style="width: 600px">
|
||||
<q-bar>
|
||||
Insert Table
|
||||
<q-space />
|
||||
<q-btn v-close-popup dense flat icon="close">
|
||||
<q-tooltip class="bg-white text-primary">Close</q-tooltip>
|
||||
</q-btn>
|
||||
</q-bar>
|
||||
<q-card-section>
|
||||
<q-option-group
|
||||
v-model="tableType"
|
||||
:options="tableTypeOptions"
|
||||
dense
|
||||
inline
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section v-if="tableType === 'variables'">
|
||||
<q-select
|
||||
v-model="source"
|
||||
:options="arrayOptions"
|
||||
outlined
|
||||
dense
|
||||
label="Data Source"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-input v-model="output" filled type="textarea" lines="20" />
|
||||
</q-card-section>
|
||||
<q-card-actions align="right">
|
||||
<q-btn v-close-popup dense flat label="Cancel" />
|
||||
<q-btn dense flat label="Insert" color="primary" @click="insert" />
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { useDialogPluginComponent } from "quasar";
|
||||
import { useSharedReportTemplates } from "../api/reporting";
|
||||
|
||||
const { variableAnalysis } = useSharedReportTemplates;
|
||||
|
||||
// quasar dialog setup
|
||||
const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent();
|
||||
|
||||
const tableTypeOptions = [
|
||||
{ value: "blank", label: "Blank" },
|
||||
{ value: "variables", label: "From Variables" },
|
||||
];
|
||||
|
||||
const blankOutput = `<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>`;
|
||||
|
||||
const tableType = ref<"blank" | "variables">("blank");
|
||||
const source = ref("");
|
||||
const output = ref(blankOutput);
|
||||
|
||||
// watch for source change and get list of columns
|
||||
watch(source, (newSource) => {
|
||||
let columns = [] as string[];
|
||||
for (let key in variableAnalysis.value)
|
||||
if (key.startsWith(newSource + "[0]"))
|
||||
columns.push(key.replace(newSource + "[0].", ""));
|
||||
|
||||
generateTable(columns);
|
||||
});
|
||||
|
||||
watch(tableType, (newValue) => {
|
||||
if (newValue === "blank") output.value = blankOutput;
|
||||
});
|
||||
|
||||
// compute the arrayOptions
|
||||
const arrayOptions = computed(() => {
|
||||
let options = [];
|
||||
for (let key in variableAnalysis.value)
|
||||
if (variableAnalysis.value[key].toLowerCase().startsWith("array"))
|
||||
options.push(key);
|
||||
return options;
|
||||
});
|
||||
|
||||
function generateTable(columns: string[]) {
|
||||
let headers = "";
|
||||
let cells = "";
|
||||
columns.forEach((column) => {
|
||||
headers += `\t<th>${column}</th>\n`;
|
||||
cells += `\t<td>{{ item.${column} }}</td>\n`;
|
||||
});
|
||||
|
||||
if (!headers) {
|
||||
headers = "\t<th>Column Name</th>";
|
||||
}
|
||||
|
||||
if (!cells) {
|
||||
cells = "\t<td>{{ item }}</td>";
|
||||
}
|
||||
|
||||
output.value = `<table>
|
||||
<thead>
|
||||
<tr>
|
||||
${headers}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in ${source.value} %}
|
||||
<tr>
|
||||
${cells}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
}
|
||||
|
||||
function insert() {
|
||||
onDialogOK(output.value);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -15,6 +15,10 @@ export interface ReportDependencies {
|
||||
[x: string]: string | number;
|
||||
}
|
||||
|
||||
export interface VariableAnalysis {
|
||||
[x: string]: string;
|
||||
}
|
||||
|
||||
export interface ReportTemplate {
|
||||
id: number;
|
||||
name: string;
|
||||
|
||||
Reference in New Issue
Block a user