hacktoberfestdockerwebappuptime-monitoringuptimesocket-iosingle-page-appselfhostedself-hostedresponsivemonitoringwebsocket
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
244 lines
9.2 KiB
244 lines
9.2 KiB
<template>
|
|
<div class="monitor-check mb-4">
|
|
<div>
|
|
<div class="side-by-side">
|
|
<select id="invert-check" :value="invertedTypeOption" :class="{'form-select': true, 'mb-1': !!monitorCheck.type, 'me-1': true}"
|
|
@input="changeTypeInversion($event.target.value)" required>
|
|
<option value="SHOULD">{{ $t("MonitorCheckTypeShould") }}</option>
|
|
<option value="SHOULD_NOT">{{ $t("MonitorCheckTypeShouldNot") }}</option>
|
|
</select>
|
|
<select id="type" :value="monitorType" :class="{'form-select': true, 'mb-1': !!monitorCheck.type}"
|
|
@input="changeType($event.target.value)" required>
|
|
<option value="HTTP_STATUS_CODE_SHOULD_EQUAL">
|
|
{{ $t("MonitorCheckTypeHttpStatusCodeShouldEqual") }}
|
|
</option>
|
|
<option value="RESPONSE_SHOULD_CONTAIN_TEXT">
|
|
{{ $t("MonitorCheckTypeResponseShouldContainText") }}
|
|
</option>
|
|
<option value="RESPONSE_SHOULD_MATCH_REGEX">
|
|
{{ $t("MonitorCheckTypeResponseShouldMatchRegex") }}
|
|
</option>
|
|
<option value="RESPONSE_SELECTOR_SHOULD_EQUAL">
|
|
{{ $t("MonitorCheckTypeResponseSelectorShouldEqual") }}
|
|
</option>
|
|
<option value="RESPONSE_SELECTOR_SHOULD_MATCH_REGEX">
|
|
{{ $t("MonitorCheckTypeResponseSelectorShouldMatchRegex") }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
<div v-if="monitorType === 'HTTP_STATUS_CODE_SHOULD_EQUAL'">
|
|
<VueMultiselect
|
|
id="acceptedStatusCodes"
|
|
:options="acceptedStatusCodeOptions"
|
|
:multiple="true"
|
|
:close-on-select="false"
|
|
:clear-on-select="false"
|
|
:preserve-search="true"
|
|
placeholder="Pick Accepted Status Codes..."
|
|
:preselect-first="false"
|
|
:max-height="600"
|
|
:taggable="true"
|
|
:modelValue="monitorCheck.value"
|
|
@update:model-value="changeValue"
|
|
></VueMultiselect>
|
|
</div>
|
|
<div v-if="monitorType === 'RESPONSE_SHOULD_CONTAIN_TEXT'">
|
|
<input :value="monitorCheck.value" type="text" class="form-control" required :placeholder="$t('MonitorCheckValuePlaceholder')"
|
|
@input="changeValue($event.target.value)">
|
|
</div>
|
|
<div v-if="monitorType === 'RESPONSE_SHOULD_MATCH_REGEX'">
|
|
<input type="text" class="form-control" required :value="monitorCheck.value"
|
|
:placeholder="$t('Regexp, Example: [a-z0-9.]+@gmail\.com')" @input="changeValue($event.target.value)"
|
|
>
|
|
</div>
|
|
<div v-if="monitorType === 'RESPONSE_SELECTOR_SHOULD_EQUAL'">
|
|
<input :value="monitorCheck?.value?.selectorPath || ''" type="text" class="form-control mb-1" required
|
|
:placeholder="$t('Selector, Example: customer.address.street')"
|
|
@input="changeSelectorPath($event.target.value)"
|
|
>
|
|
<input :value="monitorCheck?.value?.selectorValue || ''" type="text" class="form-control" required
|
|
:placeholder="$t('Value, Example: First street')" @input="changeSelectorValue($event.target.value)">
|
|
</div>
|
|
<div v-if="monitorType === 'RESPONSE_SELECTOR_SHOULD_MATCH_REGEX'">
|
|
<input :value="monitorCheck?.value?.selectorPath || ''" type="text" class="form-control mb-1" required
|
|
:placeholder="$t('Selector, Example: customer.contactInfo.email')"
|
|
@input="changeSelectorPath($event.target.value)"
|
|
>
|
|
<input :value="monitorCheck?.value?.selectorValue || ''" type="text" class="form-control" required
|
|
:placeholder="$t('Regexp, Example: [a-z0-9.]+@gmail\.com')"
|
|
@input="changeSelectorValue($event.target.value)"
|
|
>
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-outline-danger" type="button" @click="deleteMonitorCheck">
|
|
<font-awesome-icon icon="times" />
|
|
</button>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import VueMultiselect from "vue-multiselect";
|
|
import {
|
|
MONITOR_CHECK_INVERTED_TYPES,
|
|
MONITOR_CHECK_SELECTOR_TYPES,
|
|
MONITOR_CHECK_STRING_TYPES,
|
|
MONITOR_CHECK_SHOULD,
|
|
MONITOR_CHECK_SHOULD_NOT,
|
|
MONITOR_CHECK_MAP_NORMAL_TO_INVERTED, MONITOR_CHECK_MAP_INVERTED_TO_NORMAL, MONITOR_CHECK_HTTP_CODE_TYPES,
|
|
} from "../util.ts";
|
|
|
|
export default {
|
|
components: {
|
|
VueMultiselect,
|
|
},
|
|
props: {
|
|
monitorCheck: {
|
|
type: Object,
|
|
default: () => ({
|
|
type: undefined,
|
|
value: undefined,
|
|
}),
|
|
},
|
|
},
|
|
emits: ["change", "delete"],
|
|
data() {
|
|
return {
|
|
acceptedStatusCodeOptions: [],
|
|
// Contains SHOULD or SHOULD_NOT
|
|
invertedTypeOption: MONITOR_CHECK_SHOULD,
|
|
// Always contains the normal type (never the NOT variant)
|
|
monitorType: undefined,
|
|
};
|
|
},
|
|
mounted() {
|
|
let acceptedStatusCodeOptions = [
|
|
"100-199",
|
|
"200-299",
|
|
"300-399",
|
|
"400-499",
|
|
"500-599",
|
|
];
|
|
|
|
for (let i = 100; i <= 999; i++) {
|
|
acceptedStatusCodeOptions.push(i.toString());
|
|
}
|
|
|
|
this.acceptedStatusCodeOptions = acceptedStatusCodeOptions;
|
|
|
|
if (this.monitorCheck.type) {
|
|
this.invertedTypeOption = MONITOR_CHECK_INVERTED_TYPES.includes(this.monitorCheck.type) ? MONITOR_CHECK_SHOULD_NOT : MONITOR_CHECK_SHOULD;
|
|
this.monitorType = MONITOR_CHECK_MAP_INVERTED_TO_NORMAL[this.monitorCheck.type] || this.monitorCheck.type;
|
|
}
|
|
},
|
|
methods: {
|
|
deleteMonitorCheck() {
|
|
this.$emit("delete");
|
|
},
|
|
changeTypeInversion(inversionType) {
|
|
this.invertedTypeOption = inversionType;
|
|
this.emitType();
|
|
},
|
|
changeType(type) {
|
|
this.monitorType = type;
|
|
this.emitType();
|
|
},
|
|
// Combine invertedTypeOption with monitorType to produce the combined this.monitorCheck.type
|
|
emitType() {
|
|
if (!this.monitorType) {
|
|
return;
|
|
}
|
|
const type = this.invertedTypeOption === MONITOR_CHECK_SHOULD ? this.monitorType : MONITOR_CHECK_MAP_NORMAL_TO_INVERTED[this.monitorType];
|
|
|
|
if (MONITOR_CHECK_HTTP_CODE_TYPES.includes(type) && MONITOR_CHECK_HTTP_CODE_TYPES.includes(this.monitorCheck.type) ||
|
|
MONITOR_CHECK_STRING_TYPES.includes(type) && MONITOR_CHECK_STRING_TYPES.includes(this.monitorCheck.type) ||
|
|
MONITOR_CHECK_SELECTOR_TYPES.includes(type) && MONITOR_CHECK_SELECTOR_TYPES.includes(this.monitorCheck.type)) {
|
|
// Check value stays same type (string => string or object => object)
|
|
this.$emit("change", {
|
|
...this.monitorCheck,
|
|
type,
|
|
});
|
|
} else {
|
|
// Check value switches (string => object or object => string)
|
|
this.$emit("change", {
|
|
type,
|
|
value: undefined,
|
|
});
|
|
}
|
|
},
|
|
changeValue(value) {
|
|
this.$emit("change", {
|
|
...this.monitorCheck,
|
|
value,
|
|
});
|
|
},
|
|
changeSelectorPath(selectorPath) {
|
|
this.$emit("change", {
|
|
...this.monitorCheck,
|
|
value: {
|
|
...(this.monitorCheck.value || {}),
|
|
selectorPath,
|
|
},
|
|
});
|
|
},
|
|
changeSelectorValue(selectorValue) {
|
|
this.$emit("change", {
|
|
...this.monitorCheck,
|
|
value: {
|
|
...(this.monitorCheck.value || {}),
|
|
selectorValue,
|
|
},
|
|
});
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
@import "../assets/vars.scss";
|
|
|
|
.monitor-check {
|
|
display: flex;
|
|
|
|
> div:first-child {
|
|
width: 100%;
|
|
}
|
|
|
|
.side-by-side {
|
|
display: flex;
|
|
|
|
> select:first-child {
|
|
width: 40%;
|
|
|
|
+ select {
|
|
border-radius: 0;
|
|
margin-left: -1px;
|
|
}
|
|
}
|
|
}
|
|
|
|
input,
|
|
select {
|
|
border-radius: 19px 0 0 19px;
|
|
|
|
&:focus {
|
|
z-index: 1;
|
|
}
|
|
}
|
|
|
|
button {
|
|
margin-left: 0.25rem;
|
|
padding-left: 15px;
|
|
padding-right: 15px;
|
|
border-radius: 0 19px 19px 0;
|
|
}
|
|
|
|
}
|
|
</style>
|
|
|
|
<style lang="scss">
|
|
.monitor-check {
|
|
.multiselect__tags {
|
|
border-radius: 19px 0 0 19px;
|
|
}
|
|
}
|
|
</style>
|
|
|