Skip to content
Open
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
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"vue-class-component": "^7.0.2",
"vue-click-outside": "^1.1.0",
"vue-clipboard2": "^0.3.1",
"vue-grid-layout": "2.4.0",
"vue-i18n": "^8.11.2",
"vue-json-tree-view": "^2.1.6",
"vue-markdown": "^2.2.4",
Expand Down Expand Up @@ -131,6 +132,7 @@
"raw-loader": "^4.0.2",
"sass": "~1.32.13",
"sass-loader": "^8.0.2",
"ts-node": "10.9.2",
"typeorm-uml": "^1.6.4",
"typescript": "^4.9.5",
"vue-cli-plugin-electron-builder": "^2.1.1",
Expand Down
133 changes: 133 additions & 0 deletions src/components/ThresholdEditor.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<template>
<div class="key-value-editor">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this new component created because the built-in key value editor couldn't satisfy the needs?

<div class="editor-header">
<div class="header-left">
<span class="editor-title"> {{ title }} </span>
<el-select
v-model="localThresholdsType"
size="mini"
placeholder="Select type"
style="margin-left: 10px"
@change="emitThresholdsTypeChange"
>
<el-option label="Absolute" value="Absolute" />
<el-option label="Percentage" value="Percentage" />
</el-select>
<el-button
icon="el-icon-plus"
class="btn-props-plus"
type="text"
@click="addThreshold"
style="margin-left: 10px"
></el-button>
</div>
</div>
<div class="editor-row">
<el-row v-for="(threshold, index) in localThresholds" :key="index" :gutter="10" class="editor-row">
<el-col :span="10">
<el-input
type="number"
v-model.number="threshold.value"
size="mini"
placeholder="Value"
@input="onThresholdChange"
/>
</el-col>
<el-col :span="4">
<el-color-picker v-model="threshold.color" size="mini" color-format="hex" @change="onThresholdChange" />
</el-col>
<el-col :span="4">
<el-button icon="el-icon-delete" class="btn-delete" type="text" @click="removeThreshold(index)" />
</el-col>
</el-row>
</div>
</div>
</template>

<script lang="ts">
import { Component, Vue, Prop, Watch } from 'vue-property-decorator'

@Component
export default class ThresholdEditor extends Vue {
@Prop({ type: String, default: 'Thresholds' }) readonly title!: string
@Prop({ type: Array, default: () => [] }) readonly value!: Array<{ value: number; color: string }>
@Prop({ type: String, default: 'Absolute' }) readonly thresholdsType!: 'Absolute' | 'Percentage'

private localThresholds: Array<{ value: number; color: string }> = []
private localThresholdsType: 'Absolute' | 'Percentage' = 'Absolute'

mounted() {
this.initializeLocalData()
}

@Watch('value', { deep: true, immediate: true })
onValueChange(newValue: Array<{ value: number; color: string }>) {
if (JSON.stringify(this.localThresholds) !== JSON.stringify(newValue)) {
this.localThresholds = [...(newValue || [])]
}
}

@Watch('thresholdsType', { immediate: true })
onThresholdsTypeChange(newType: 'Absolute' | 'Percentage') {
this.localThresholdsType = newType
}

private initializeLocalData() {
this.localThresholds = [...(this.value || [])]
this.localThresholdsType = this.thresholdsType
}

private addThreshold() {
this.localThresholds.push({ value: 0, color: '#FF0000' })
this.emitChange()
}

private removeThreshold(index: number) {
this.localThresholds.splice(index, 1)
this.emitChange()
}

private onThresholdChange() {
this.emitChange()
}

private emitThresholdsTypeChange() {
this.$emit('update:thresholdsType', this.localThresholdsType)
}

private emitChange() {
this.$emit('input', [...this.localThresholds])
}
}
</script>

<style lang="scss" scoped>
.key-value-editor {
.editor-header {
display: flex;
justify-content: space-between;
align-items: center;
.header-left {
display: flex;
align-items: center;
}
.editor-title {
font-weight: 600;
color: var(--color-text-default);
}
}
.editor-row {
margin-top: 10px;
.el-col {
display: flex;
align-items: center;
}
}
.btn-props-plus {
font-size: 12px;
}
.btn-delete {
color: var(--color-text-light);
}
}
</style>
66 changes: 60 additions & 6 deletions src/components/TimeRangeSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
:end-placeholder="$t('common.endTime')"
:picker-options="pickerOptions"
value-format="yyyy-MM-dd HH:mm:ss:SSS"
size="small"
:size="size"
popper-class="time-range-picker-popper"
>
</el-date-picker>
Expand All @@ -18,18 +18,61 @@ import { Component, Vue, Prop, Watch } from 'vue-property-decorator'
@Component
export default class TimeRangeSelect extends Vue {
@Prop({ required: true }) public value!: [string, string]
@Prop({ default: 'small' }) public size!: string
@Prop({ default: false }) public showLiveMode!: boolean
@Prop({ default: 'static' }) public timeRangeType!: 'live' | 'static'
@Prop({ default: 24 * 60 }) public duration!: number

private modelValue = this.value
private currentDuration: number | null = null
private isLiveMode: boolean = false
private isFromShortcut: boolean = false
private shortcutLiveMode: boolean = false
private shortcutDuration: number | null = null

// Initialize with props
private mounted() {
this.isLiveMode = this.timeRangeType === 'live'
this.currentDuration = this.duration * 60 * 1000 // Convert minutes to milliseconds
}

@Watch('value')
private onValueChange(newVal: [string, string]) {
this.modelValue = newVal
}

@Watch('timeRangeType')
private onTimeRangeTypeChange() {
this.isLiveMode = this.timeRangeType === 'live'
}

@Watch('duration')
private onDurationChange() {
this.currentDuration = this.duration * 60 * 1000 // Convert minutes to milliseconds
}

@Watch('modelValue')
private onModelValueChange(newVal: [string, string] | null) {
this.$emit('input', newVal)
this.$emit('change', newVal)

// Only emit range-relative for shortcuts, not for external changes (like dashboard switches)
if (this.isFromShortcut) {
// Use shortcut-specific values
const finalIsLive = this.shortcutLiveMode
const finalDuration = this.shortcutDuration

this.$emit('range-relative', {
timeRange: newVal,
duration: finalDuration || 24 * 60 * 60 * 1000, // Default to 24 hours in milliseconds
isLive: finalIsLive,
})

// Reset shortcut flags after emitting
this.isFromShortcut = false
this.shortcutLiveMode = false
this.shortcutDuration = null
}
}

private pickerOptions = {
Expand All @@ -39,7 +82,8 @@ export default class TimeRangeSelect extends Vue {
shortcuts: [
{
text: this.$t('common.last5Minutes'),
onClick(picker: any) {
onClick: (picker: any) => {
this.setShortcutValues(true, 5 * 60 * 1000)
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 5 * 60 * 1000)
Expand All @@ -48,7 +92,8 @@ export default class TimeRangeSelect extends Vue {
},
{
text: this.$t('common.last30Minutes'),
onClick(picker: any) {
onClick: (picker: any) => {
this.setShortcutValues(true, 30 * 60 * 1000)
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 30 * 60 * 1000)
Expand All @@ -57,7 +102,8 @@ export default class TimeRangeSelect extends Vue {
},
{
text: this.$t('common.lastHour'),
onClick(picker: any) {
onClick: (picker: any) => {
this.setShortcutValues(true, 60 * 60 * 1000)
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 60 * 60 * 1000)
Expand All @@ -66,7 +112,8 @@ export default class TimeRangeSelect extends Vue {
},
{
text: this.$t('common.lastDay'),
onClick(picker: any) {
onClick: (picker: any) => {
this.setShortcutValues(true, 24 * 60 * 60 * 1000)
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 24 * 60 * 60 * 1000)
Expand All @@ -75,7 +122,8 @@ export default class TimeRangeSelect extends Vue {
},
{
text: this.$t('common.lastWeek'),
onClick(picker: any) {
onClick: (picker: any) => {
this.setShortcutValues(true, 7 * 24 * 60 * 60 * 1000)
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 7 * 24 * 60 * 60 * 1000)
Expand All @@ -84,6 +132,12 @@ export default class TimeRangeSelect extends Vue {
},
],
}

private setShortcutValues(isLive: boolean, duration: number) {
this.isFromShortcut = true
this.shortcutLiveMode = isLive
this.shortcutDuration = duration
}
}
</script>

Expand Down
Loading