mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-06 00:09:22 +00:00
feat: dashboard havingCondition for aggregation fields (#6252)
This commit is contained in:
@@ -163,6 +163,14 @@ pub struct AxisItem {
|
||||
pub args: Option<Vec<AxisArg>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub is_derived: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub having_conditions: Option<Vec<HavingConditions>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Hash, Serialize, Deserialize, ToSchema)]
|
||||
pub struct HavingConditions {
|
||||
value: Option<OrdF64>,
|
||||
operator: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Hash, Serialize, Deserialize, ToSchema)]
|
||||
|
||||
@@ -413,6 +413,49 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"
|
||||
:rules="[(val: any) => val > 0 || 'Required']"
|
||||
/>
|
||||
<div style="width: 100%" class="tw-mb-2">
|
||||
<span class="tw-block tw-mb-1 tw-font-bold">Having</span>
|
||||
|
||||
<q-btn
|
||||
dense
|
||||
outline
|
||||
color="primary"
|
||||
icon="add"
|
||||
label="Add"
|
||||
@click="toggleHavingFilter"
|
||||
v-if="!isHavingFilterVisible()"
|
||||
/>
|
||||
|
||||
<div
|
||||
class="tw-flex tw-space-x-2 tw-mt-2 tw-items-center"
|
||||
v-if="isHavingFilterVisible()"
|
||||
>
|
||||
<q-select
|
||||
dense
|
||||
filled
|
||||
v-model="getHavingCondition().operator"
|
||||
:options="operators"
|
||||
style="width: 30%"
|
||||
>
|
||||
</q-select>
|
||||
|
||||
<q-input
|
||||
dense
|
||||
filled
|
||||
v-model.number="getHavingCondition().value"
|
||||
style="width: 50%"
|
||||
type="number"
|
||||
placeholder="Value"
|
||||
/>
|
||||
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
icon="close"
|
||||
@click="cancelHavingFilter"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="
|
||||
!dashboardPanelData.data.queries[
|
||||
@@ -467,7 +510,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, reactive, watch, computed } from "vue";
|
||||
import { defineComponent, ref, reactive, watch, computed, nextTick } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import useDashboardPanelData from "../../../composables/useDashboardPanel";
|
||||
import { getImageURL } from "../../../utils/zincutils";
|
||||
@@ -500,6 +543,7 @@ export default defineComponent({
|
||||
"dashboardPanelDataPageKey",
|
||||
"dashboard",
|
||||
);
|
||||
|
||||
const {
|
||||
dashboardPanelData,
|
||||
addLatitude,
|
||||
@@ -709,6 +753,53 @@ export default defineComponent({
|
||||
return commonBtnLabel(weightField);
|
||||
});
|
||||
|
||||
const operators = ["=", "<>", ">=", "<=", ">", "<"];
|
||||
|
||||
const isHavingFilterVisible = () => {
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
const currentField =
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields.weight;
|
||||
|
||||
const isVisible = !!currentField?.havingConditions?.length;
|
||||
return isVisible;
|
||||
};
|
||||
|
||||
const toggleHavingFilter = async () => {
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
const currentField =
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields.weight;
|
||||
|
||||
if (!currentField.havingConditions) {
|
||||
currentField.havingConditions = [];
|
||||
}
|
||||
|
||||
if (!currentField.havingConditions.length) {
|
||||
currentField.havingConditions.push({ operator: null, value: null });
|
||||
}
|
||||
|
||||
await nextTick();
|
||||
};
|
||||
|
||||
const cancelHavingFilter = async () => {
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
const currentField =
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields.weight;
|
||||
|
||||
currentField.havingConditions = [];
|
||||
|
||||
await nextTick();
|
||||
};
|
||||
|
||||
const getHavingCondition = () => {
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
const currentField =
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields.weight;
|
||||
|
||||
return (
|
||||
currentField.havingConditions?.[0] || { operator: null, value: null }
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
t,
|
||||
dashboardPanelData,
|
||||
@@ -733,6 +824,11 @@ export default defineComponent({
|
||||
promqlMode,
|
||||
weightLabel,
|
||||
onFieldDragStart,
|
||||
operators,
|
||||
isHavingFilterVisible,
|
||||
toggleHavingFilter,
|
||||
cancelHavingFilter,
|
||||
getHavingCondition,
|
||||
options: [
|
||||
"=",
|
||||
"<>",
|
||||
|
||||
@@ -278,6 +278,49 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"
|
||||
:rules="[(val: string) => !!val?.trim() || 'Required']"
|
||||
/>
|
||||
<div style="width: 100%" class="tw-mb-2">
|
||||
<span class="tw-block tw-mb-1 tw-font-bold">Having</span>
|
||||
|
||||
<q-btn
|
||||
dense
|
||||
outline
|
||||
color="primary"
|
||||
icon="add"
|
||||
label="Add"
|
||||
@click="toggleHavingFilter"
|
||||
v-if="!isHavingFilterVisible()"
|
||||
/>
|
||||
|
||||
<div
|
||||
class="tw-flex tw-space-x-2 tw-mt-2 tw-items-center"
|
||||
v-if="isHavingFilterVisible()"
|
||||
>
|
||||
<q-select
|
||||
dense
|
||||
filled
|
||||
v-model="getHavingCondition().operator"
|
||||
:options="operators"
|
||||
style="width: 30%"
|
||||
>
|
||||
</q-select>
|
||||
|
||||
<q-input
|
||||
dense
|
||||
filled
|
||||
v-model.number="getHavingCondition().value"
|
||||
style="width: 50%"
|
||||
type="number"
|
||||
placeholder="Value"
|
||||
/>
|
||||
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
icon="close"
|
||||
@click="cancelHavingFilter"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="
|
||||
!dashboardPanelData.data.queries[
|
||||
@@ -332,7 +375,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, reactive, watch, computed, inject } from "vue";
|
||||
import {
|
||||
defineComponent,
|
||||
ref,
|
||||
reactive,
|
||||
watch,
|
||||
computed,
|
||||
inject,
|
||||
nextTick,
|
||||
} from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import useDashboardPanelData from "../../../composables/useDashboardPanel";
|
||||
import { getImageURL } from "../../../utils/zincutils";
|
||||
@@ -364,7 +415,7 @@ export default defineComponent({
|
||||
"dashboardPanelDataPageKey",
|
||||
"dashboard",
|
||||
);
|
||||
|
||||
|
||||
const {
|
||||
dashboardPanelData,
|
||||
addMapName,
|
||||
@@ -559,6 +610,57 @@ export default defineComponent({
|
||||
return commonBtnLabel(valueField);
|
||||
});
|
||||
|
||||
const operators = ["=", "<>", ">=", "<=", ">", "<"];
|
||||
|
||||
const isHavingFilterVisible = () => {
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
const currentField =
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields
|
||||
.value_for_maps;
|
||||
|
||||
const isVisible = !!currentField?.havingConditions?.length;
|
||||
return isVisible;
|
||||
};
|
||||
|
||||
const toggleHavingFilter = async () => {
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
const currentField =
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields
|
||||
.value_for_maps;
|
||||
|
||||
if (!currentField.havingConditions) {
|
||||
currentField.havingConditions = [];
|
||||
}
|
||||
|
||||
if (!currentField.havingConditions.length) {
|
||||
currentField.havingConditions.push({ operator: null, value: null });
|
||||
}
|
||||
|
||||
await nextTick();
|
||||
};
|
||||
|
||||
const cancelHavingFilter = async () => {
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
const currentField =
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields
|
||||
.value_for_maps;
|
||||
|
||||
currentField.havingConditions = [];
|
||||
|
||||
await nextTick();
|
||||
};
|
||||
|
||||
const getHavingCondition = () => {
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
const currentField =
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields
|
||||
.value_for_maps;
|
||||
|
||||
return (
|
||||
currentField.havingConditions?.[0] || { operator: null, value: null }
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
t,
|
||||
dashboardPanelData,
|
||||
@@ -581,6 +683,11 @@ export default defineComponent({
|
||||
Hint,
|
||||
promqlMode,
|
||||
onFieldDragStart,
|
||||
operators,
|
||||
isHavingFilterVisible,
|
||||
toggleHavingFilter,
|
||||
cancelHavingFilter,
|
||||
getHavingCondition,
|
||||
options: [
|
||||
"=",
|
||||
"<>",
|
||||
|
||||
@@ -715,6 +715,52 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"
|
||||
:rules="[(val: any) => val.length > 0 || 'Required']"
|
||||
/>
|
||||
<div
|
||||
style="width: 100%"
|
||||
class="tw-mb-2"
|
||||
v-if="dashboardPanelData.data.type != 'heatmap'"
|
||||
>
|
||||
<span class="tw-block tw-mb-1 tw-font-bold">Having</span>
|
||||
|
||||
<q-btn
|
||||
dense
|
||||
outline
|
||||
color="primary"
|
||||
icon="add"
|
||||
label="Add"
|
||||
@click="toggleHavingFilter(index, 'y')"
|
||||
v-if="!isHavingFilterVisible(index, 'y')"
|
||||
/>
|
||||
|
||||
<div
|
||||
class="tw-flex tw-space-x-2 tw-mt-2 tw-items-center"
|
||||
v-if="isHavingFilterVisible(index, 'y')"
|
||||
>
|
||||
<q-select
|
||||
dense
|
||||
filled
|
||||
v-model="getHavingCondition(index, 'y').operator"
|
||||
:options="operators"
|
||||
style="width: 30%"
|
||||
/>
|
||||
|
||||
<q-input
|
||||
dense
|
||||
filled
|
||||
v-model.number="getHavingCondition(index, 'y').value"
|
||||
style="width: 50%"
|
||||
type="number"
|
||||
placeholder="Value"
|
||||
/>
|
||||
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
icon="close"
|
||||
@click="cancelHavingFilter(index, 'y')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="
|
||||
!dashboardPanelData.data.queries[
|
||||
@@ -910,6 +956,52 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"
|
||||
:rules="[(val: any) => val.length > 0 || 'Required']"
|
||||
/>
|
||||
<div style="width: 100%" class="tw-mb-2">
|
||||
<span class="tw-block tw-mb-1 tw-font-bold"
|
||||
>Having</span
|
||||
>
|
||||
|
||||
<q-btn
|
||||
dense
|
||||
outline
|
||||
color="primary"
|
||||
icon="add"
|
||||
label="Add"
|
||||
@click="toggleHavingFilter(index, 'z')"
|
||||
v-if="!isHavingFilterVisible(index, 'z')"
|
||||
/>
|
||||
|
||||
<div
|
||||
class="tw-flex tw-space-x-2 tw-mt-2 tw-items-center"
|
||||
v-if="isHavingFilterVisible(index, 'z')"
|
||||
>
|
||||
<q-select
|
||||
dense
|
||||
filled
|
||||
v-model="getHavingCondition(index, 'z').operator"
|
||||
:options="operators"
|
||||
style="width: 30%"
|
||||
/>
|
||||
|
||||
<q-input
|
||||
dense
|
||||
filled
|
||||
v-model.number="
|
||||
getHavingCondition(index, 'z').value
|
||||
"
|
||||
style="width: 50%"
|
||||
type="number"
|
||||
placeholder="Value"
|
||||
/>
|
||||
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
icon="close"
|
||||
@click="cancelHavingFilter(index, 'z')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="
|
||||
!dashboardPanelData.data.queries[
|
||||
@@ -974,7 +1066,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, reactive, watch, computed, inject } from "vue";
|
||||
import {
|
||||
defineComponent,
|
||||
ref,
|
||||
reactive,
|
||||
watch,
|
||||
computed,
|
||||
inject,
|
||||
nextTick,
|
||||
} from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import useDashboardPanelData from "../../../composables/useDashboardPanel";
|
||||
import { getImageURL } from "../../../utils/zincutils";
|
||||
@@ -1452,6 +1552,53 @@ export default defineComponent({
|
||||
return zFields.map(commonBtnLabel);
|
||||
});
|
||||
|
||||
const operators = ["=", "<>", ">=", "<=", ">", "<"];
|
||||
|
||||
const isHavingFilterVisible = (index: any, axis: any) => {
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
const currentField =
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields[axis][index];
|
||||
|
||||
const isVisible = !!currentField?.havingConditions?.length;
|
||||
return isVisible;
|
||||
};
|
||||
|
||||
const toggleHavingFilter = async (index: any, axis: any) => {
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
const currentField =
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields[axis][index];
|
||||
|
||||
if (!currentField.havingConditions) {
|
||||
currentField.havingConditions = [];
|
||||
}
|
||||
|
||||
if (!currentField.havingConditions.length) {
|
||||
currentField.havingConditions.push({ operator: null, value: null });
|
||||
}
|
||||
|
||||
await nextTick();
|
||||
};
|
||||
|
||||
const cancelHavingFilter = async (index: any, axis: any) => {
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
const currentField =
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields[axis][index];
|
||||
|
||||
currentField.havingConditions = [];
|
||||
|
||||
await nextTick();
|
||||
};
|
||||
|
||||
const getHavingCondition = (index: any, axis: any) => {
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
const currentField =
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields[axis][index];
|
||||
|
||||
return (
|
||||
currentField.havingConditions?.[0] || { operator: null, value: null }
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
showXAxis,
|
||||
t,
|
||||
@@ -1500,6 +1647,11 @@ export default defineComponent({
|
||||
onFieldDragStart,
|
||||
getHistoramIntervalField,
|
||||
onDragEnd,
|
||||
operators,
|
||||
isHavingFilterVisible,
|
||||
toggleHavingFilter,
|
||||
cancelHavingFilter,
|
||||
getHavingCondition,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -55,7 +55,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
].fields?.source.column,
|
||||
'source'
|
||||
'source',
|
||||
)
|
||||
"
|
||||
>
|
||||
@@ -191,7 +191,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
].fields?.target.column,
|
||||
'target'
|
||||
'target',
|
||||
)
|
||||
"
|
||||
>
|
||||
@@ -327,7 +327,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
].fields?.value.column,
|
||||
'value'
|
||||
'value',
|
||||
)
|
||||
"
|
||||
>
|
||||
@@ -413,6 +413,49 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"
|
||||
:rules="[(val: any) => val > 0 || 'Required']"
|
||||
/>
|
||||
<div style="width: 100%" class="tw-mb-2">
|
||||
<span class="tw-block tw-mb-1 tw-font-bold">Having</span>
|
||||
|
||||
<q-btn
|
||||
dense
|
||||
outline
|
||||
color="primary"
|
||||
icon="add"
|
||||
label="Add"
|
||||
@click="toggleHavingFilter"
|
||||
v-if="!isHavingFilterVisible()"
|
||||
/>
|
||||
|
||||
<div
|
||||
class="tw-flex tw-space-x-2 tw-mt-2 tw-items-center"
|
||||
v-if="isHavingFilterVisible()"
|
||||
>
|
||||
<q-select
|
||||
dense
|
||||
filled
|
||||
v-model="getHavingCondition().operator"
|
||||
:options="operators"
|
||||
style="width: 30%"
|
||||
>
|
||||
</q-select>
|
||||
|
||||
<q-input
|
||||
dense
|
||||
filled
|
||||
v-model.number="getHavingCondition().value"
|
||||
style="width: 50%"
|
||||
type="number"
|
||||
placeholder="Value"
|
||||
/>
|
||||
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
icon="close"
|
||||
@click="cancelHavingFilter"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="
|
||||
!dashboardPanelData.data.queries[
|
||||
@@ -467,7 +510,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, reactive, watch, computed, inject } from "vue";
|
||||
import {
|
||||
defineComponent,
|
||||
ref,
|
||||
reactive,
|
||||
watch,
|
||||
computed,
|
||||
inject,
|
||||
nextTick,
|
||||
} from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import useDashboardPanelData from "../../../composables/useDashboardPanel";
|
||||
import { getImageURL } from "../../../utils/zincutils";
|
||||
@@ -498,8 +549,9 @@ export default defineComponent({
|
||||
|
||||
const dashboardPanelDataPageKey = inject(
|
||||
"dashboardPanelDataPageKey",
|
||||
"dashboard"
|
||||
"dashboard",
|
||||
);
|
||||
|
||||
const {
|
||||
dashboardPanelData,
|
||||
addSource,
|
||||
@@ -547,7 +599,7 @@ export default defineComponent({
|
||||
expansionItems.value = true;
|
||||
expansionItems.filter = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const onDrop = (e: any, targetAxis: string) => {
|
||||
@@ -580,11 +632,11 @@ export default defineComponent({
|
||||
|
||||
const dragName =
|
||||
selectedStreamFieldsBasedOnUserDefinedSchema.value.find(
|
||||
(item: any) => item?.name === dragElement
|
||||
(item: any) => item?.name === dragElement,
|
||||
);
|
||||
const customDragName =
|
||||
dashboardPanelData.meta.stream.customQueryFields.find(
|
||||
(item: any) => item?.name === dragElement
|
||||
(item: any) => item?.name === dragElement,
|
||||
);
|
||||
|
||||
if (dragName || customDragName) {
|
||||
@@ -700,6 +752,53 @@ export default defineComponent({
|
||||
return commonBtnLabel(valueField);
|
||||
});
|
||||
|
||||
const operators = ["=", "<>", ">=", "<=", ">", "<"];
|
||||
|
||||
const isHavingFilterVisible = () => {
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
const currentField =
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields.value;
|
||||
|
||||
const isVisible = !!currentField?.havingConditions?.length;
|
||||
return isVisible;
|
||||
};
|
||||
|
||||
const toggleHavingFilter = async () => {
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
const currentField =
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields.value;
|
||||
|
||||
if (!currentField.havingConditions) {
|
||||
currentField.havingConditions = [];
|
||||
}
|
||||
|
||||
if (!currentField.havingConditions.length) {
|
||||
currentField.havingConditions.push({ operator: null, value: null });
|
||||
}
|
||||
|
||||
await nextTick();
|
||||
};
|
||||
|
||||
const cancelHavingFilter = async () => {
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
const currentField =
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields.value;
|
||||
|
||||
currentField.havingConditions = [];
|
||||
|
||||
await nextTick();
|
||||
};
|
||||
|
||||
const getHavingCondition = () => {
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
const currentField =
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields.value;
|
||||
|
||||
return (
|
||||
currentField.havingConditions?.[0] || { operator: null, value: null }
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
t,
|
||||
dashboardPanelData,
|
||||
@@ -723,6 +822,11 @@ export default defineComponent({
|
||||
promqlMode,
|
||||
valueLabel,
|
||||
onFieldDragStart,
|
||||
operators,
|
||||
isHavingFilterVisible,
|
||||
toggleHavingFilter,
|
||||
cancelHavingFilter,
|
||||
getHavingCondition,
|
||||
options: [
|
||||
"=",
|
||||
"<>",
|
||||
|
||||
@@ -197,8 +197,8 @@ const dashboardPanelDataObj: any = {
|
||||
|
||||
const getDefaultCustomChartText = () => {
|
||||
return `\ // To know more about ECharts , \n// visit: https://echarts.apache.org/examples/en/index.html \n// Example: https://echarts.apache.org/examples/en/editor.html?c=line-simple \n// Define your ECharts 'option' here. \n// 'data' variable is available for use and contains the response data from the search result and it is an array.\noption = { \n \n};
|
||||
`
|
||||
}
|
||||
`;
|
||||
};
|
||||
|
||||
const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
const store = useStore();
|
||||
@@ -468,6 +468,7 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
: "ASC"
|
||||
: null,
|
||||
isDerived,
|
||||
havingConditions: [],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -528,6 +529,7 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
: "ASC"
|
||||
: null,
|
||||
isDerived,
|
||||
havingConditions: [],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -581,6 +583,7 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
? null
|
||||
: "count",
|
||||
isDerived,
|
||||
havingConditions: [],
|
||||
});
|
||||
}
|
||||
updateArrayAlias();
|
||||
@@ -630,6 +633,7 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
color: getNewColorValue(),
|
||||
aggregationFunction: isDerived ? null : "count",
|
||||
isDerived,
|
||||
havingConditions: [],
|
||||
});
|
||||
}
|
||||
updateArrayAlias();
|
||||
@@ -651,6 +655,7 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
color: getNewColorValue(),
|
||||
aggregationFunction: null, // You can set the appropriate aggregation function here
|
||||
isDerived,
|
||||
havingConditions: [],
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -671,6 +676,7 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
color: getNewColorValue(),
|
||||
aggregationFunction: null, // You can set the appropriate aggregation function here
|
||||
isDerived,
|
||||
havingConditions: [],
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -691,6 +697,7 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
color: getNewColorValue(),
|
||||
aggregationFunction: isDerived ? null : "count", // You can set the appropriate aggregation function here
|
||||
isDerived,
|
||||
havingConditions: [],
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -709,6 +716,7 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
column: row.name,
|
||||
color: getNewColorValue(),
|
||||
aggregationFunction: null, // You can set the appropriate aggregation function here
|
||||
havingConditions: [],
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -727,6 +735,7 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
column: row.name,
|
||||
color: getNewColorValue(),
|
||||
aggregationFunction: "count", // You can set the appropriate aggregation function here
|
||||
havingConditions: [],
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -747,6 +756,7 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
color: getNewColorValue(),
|
||||
aggregationFunction: null, // You can set the appropriate aggregation function here
|
||||
isDerived,
|
||||
havingConditions: [],
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -767,6 +777,7 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
color: getNewColorValue(),
|
||||
aggregationFunction: null, // You can set the appropriate aggregation function here
|
||||
isDerived,
|
||||
havingConditions: [],
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -787,6 +798,7 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
color: getNewColorValue(),
|
||||
aggregationFunction: isDerived ? null : "sum", // You can set the appropriate aggregation function here
|
||||
isDerived,
|
||||
havingConditions: [],
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -831,7 +843,8 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
}
|
||||
dashboardPanelData.data.htmlContent = "";
|
||||
dashboardPanelData.data.markdownContent = "";
|
||||
dashboardPanelData.data.customChartContent = getDefaultCustomChartText();
|
||||
dashboardPanelData.data.customChartContent =
|
||||
getDefaultCustomChartText();
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
].config.time_shift = [];
|
||||
@@ -874,7 +887,8 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
}
|
||||
dashboardPanelData.data.htmlContent = "";
|
||||
dashboardPanelData.data.markdownContent = "";
|
||||
dashboardPanelData.data.customChartContent = getDefaultCustomChartText();
|
||||
dashboardPanelData.data.customChartContent =
|
||||
getDefaultCustomChartText();
|
||||
break;
|
||||
case "table":
|
||||
case "pie":
|
||||
@@ -913,7 +927,8 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
}
|
||||
dashboardPanelData.data.htmlContent = "";
|
||||
dashboardPanelData.data.markdownContent = "";
|
||||
dashboardPanelData.data.customChartContent = getDefaultCustomChartText();
|
||||
dashboardPanelData.data.customChartContent =
|
||||
getDefaultCustomChartText();
|
||||
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
@@ -938,7 +953,8 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
].fields.breakdown = [];
|
||||
dashboardPanelData.data.htmlContent = "";
|
||||
dashboardPanelData.data.markdownContent = "";
|
||||
dashboardPanelData.data.customChartContent = getDefaultCustomChartText();
|
||||
dashboardPanelData.data.customChartContent =
|
||||
getDefaultCustomChartText();
|
||||
|
||||
dashboardPanelData.data.queries?.forEach((query: any) => {
|
||||
query.fields.source = null;
|
||||
@@ -955,7 +971,8 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
case "html":
|
||||
dashboardPanelData.data.queries = getDefaultQueries();
|
||||
dashboardPanelData.data.markdownContent = "";
|
||||
dashboardPanelData.data.customChartContent = getDefaultCustomChartText();
|
||||
dashboardPanelData.data.customChartContent =
|
||||
getDefaultCustomChartText();
|
||||
dashboardPanelData.data.queryType = "";
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
@@ -964,7 +981,8 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
case "markdown":
|
||||
dashboardPanelData.data.queries = getDefaultQueries();
|
||||
dashboardPanelData.data.htmlContent = "";
|
||||
dashboardPanelData.data.customChartContent = getDefaultCustomChartText();
|
||||
dashboardPanelData.data.customChartContent =
|
||||
getDefaultCustomChartText();
|
||||
|
||||
dashboardPanelData.data.queryType = "";
|
||||
dashboardPanelData.data.queries[
|
||||
@@ -1024,7 +1042,8 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
};
|
||||
dashboardPanelData.data.htmlContent = "";
|
||||
dashboardPanelData.data.markdownContent = "";
|
||||
dashboardPanelData.data.customChartContent = getDefaultCustomChartText();
|
||||
dashboardPanelData.data.customChartContent =
|
||||
getDefaultCustomChartText();
|
||||
dashboardPanelData.data.queries?.forEach((query: any) => {
|
||||
query.fields.latitude = null;
|
||||
query.fields.longitude = null;
|
||||
@@ -2242,6 +2261,56 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
}
|
||||
}
|
||||
|
||||
// Add HAVING clause if y-axis or z-axis has operator and value
|
||||
const yAxisFields =
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
].fields.y;
|
||||
|
||||
const zAxisFields =
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
].fields?.z || [];
|
||||
|
||||
const havingClauses: any = [];
|
||||
|
||||
// Only add having clauses for non-heatmap charts from y-axis
|
||||
if (dashboardPanelData.data.type !== "heatmap") {
|
||||
// Process y-axis having conditions
|
||||
yAxisFields.forEach((field: any) => {
|
||||
if (
|
||||
field?.havingConditions?.[0]?.operator &&
|
||||
field?.havingConditions?.[0]?.value !== undefined &&
|
||||
field?.havingConditions?.[0]?.value !== null &&
|
||||
field?.havingConditions?.[0]?.value !== ""
|
||||
) {
|
||||
const columnName = field.alias;
|
||||
havingClauses.push(
|
||||
`${columnName} ${field.havingConditions[0].operator} ${field.havingConditions[0].value}`,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Process z-axis having conditions
|
||||
zAxisFields.forEach((field: any) => {
|
||||
if (
|
||||
field?.havingConditions?.[0]?.operator &&
|
||||
field?.havingConditions?.[0]?.value !== undefined &&
|
||||
field?.havingConditions?.[0]?.value !== null &&
|
||||
field?.havingConditions?.[0]?.value !== ""
|
||||
) {
|
||||
const columnName = field.alias;
|
||||
havingClauses.push(
|
||||
`${columnName} ${field.havingConditions[0].operator} ${field.havingConditions[0].value}`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
if (havingClauses.length > 0) {
|
||||
query += " HAVING " + havingClauses.join(" AND ");
|
||||
}
|
||||
|
||||
// array of sorting fields with followed by asc or desc
|
||||
const orderByArr: string[] = [];
|
||||
|
||||
@@ -2332,6 +2401,30 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
}
|
||||
}
|
||||
|
||||
// Add HAVING clause if y-axis has operator and value
|
||||
const valueForMapsFields =
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
].fields.value_for_maps;
|
||||
|
||||
const havingClauses: any = [];
|
||||
|
||||
if (
|
||||
valueForMapsFields?.havingConditions?.[0]?.operator &&
|
||||
valueForMapsFields?.havingConditions?.[0]?.value !== undefined &&
|
||||
valueForMapsFields?.havingConditions?.[0]?.value !== null &&
|
||||
valueForMapsFields?.havingConditions?.[0]?.value !== ""
|
||||
) {
|
||||
const columnName = valueForMapsFields.alias;
|
||||
havingClauses.push(
|
||||
`${columnName} ${valueForMapsFields.havingConditions[0].operator} ${valueForMapsFields.havingConditions[0].value}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (havingClauses.length > 0) {
|
||||
query += " HAVING " + havingClauses.join(" AND ");
|
||||
}
|
||||
|
||||
// array of sorting fields with followed by asc or desc
|
||||
const orderByArr: string[] = [];
|
||||
|
||||
@@ -2427,6 +2520,30 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
query += `GROUP BY ${aliases}`;
|
||||
}
|
||||
|
||||
// Add HAVING clause if y-axis has operator and value
|
||||
const weightFields =
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
].fields.weight;
|
||||
|
||||
const havingClauses: any = [];
|
||||
|
||||
if (
|
||||
weightFields?.havingConditions?.[0]?.operator &&
|
||||
weightFields?.havingConditions?.[0]?.value !== undefined &&
|
||||
weightFields?.havingConditions?.[0]?.value !== null &&
|
||||
weightFields?.havingConditions?.[0]?.value !== ""
|
||||
) {
|
||||
const columnName = weightFields.alias;
|
||||
havingClauses.push(
|
||||
`${columnName} ${weightFields.havingConditions[0].operator} ${weightFields.havingConditions[0].value}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (havingClauses.length > 0) {
|
||||
query += " HAVING " + havingClauses.join(" AND ");
|
||||
}
|
||||
|
||||
// array of sorting fields with followed by asc or desc
|
||||
const orderByArr: string[] = [];
|
||||
|
||||
@@ -2531,6 +2648,30 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
query += `GROUP BY ${aliases}`;
|
||||
}
|
||||
|
||||
// Add HAVING clause if y-axis has operator and value
|
||||
const valueFields =
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
].fields.value;
|
||||
|
||||
const havingClauses: any = [];
|
||||
|
||||
if (
|
||||
valueFields?.havingConditions?.[0]?.operator &&
|
||||
valueFields?.havingConditions?.[0]?.value !== undefined &&
|
||||
valueFields?.havingConditions?.[0]?.value !== null &&
|
||||
valueFields?.havingConditions?.[0]?.value !== ""
|
||||
) {
|
||||
const columnName = valueFields.alias;
|
||||
havingClauses.push(
|
||||
`${columnName} ${valueFields.havingConditions[0].operator} ${valueFields.havingConditions[0].value}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (havingClauses.length > 0) {
|
||||
query += " HAVING " + havingClauses.join(" AND ");
|
||||
}
|
||||
|
||||
// Adding sorting
|
||||
const orderByArr: string[] = [];
|
||||
[source, target, value]
|
||||
|
||||
Reference in New Issue
Block a user