bans table/filter + uuid beforemount + fix popover

* format bans from data to create table with filters working
* fix popover behavior with overflow
* now uuid is set onbeforemount to avoid conflict with vanilla lib like datepicker or editor
* fix condition to add some reports and bans filters
This commit is contained in:
Jordan Blasenhauer 2024-06-26 15:34:53 +02:00
parent 9881fe11c6
commit 9a99bcdba4
32 changed files with 1647 additions and 152 deletions

View file

@ -1583,6 +1583,10 @@ body {
}
.xl.table {
@apply min-w-[1300px];
}
.xxl.table {
@apply min-w-[1400px];
}
@ -1607,7 +1611,7 @@ body {
}
.table-content-item-wrap {
@apply appearance-none pl-1 pr-2;
@apply appearance-none pl-0.5 pr-4.5;
}
/** MISC **/

File diff suppressed because one or more lines are too long

View file

@ -1,5 +1,5 @@
<script setup>
import { defineProps, onMounted, reactive } from "vue";
import { defineProps, onBeforeMount, reactive } from "vue";
import { contentIndex } from "@utils/tabindex.js";
import { useClipboard } from "@vueuse/core";
import { useUUID } from "@utils/global.js";
@ -57,7 +57,7 @@ const clip = reactive({
id: "",
});
onMounted(() => {
onBeforeMount(() => {
clip.id = useUUID(props.id);
});
</script>

View file

@ -1,5 +1,5 @@
<script setup>
import { reactive, defineProps, ref, onMounted } from "vue";
import { reactive, defineProps, ref, onMounted, onBeforeMount } from "vue";
import { contentIndex } from "@utils/tabindex.js";
import Container from "@components/Widget/Container.vue";
import Header from "@components/Forms/Header/Field.vue";
@ -132,9 +132,12 @@ function updateValue() {
return checkbox.value;
}
onBeforeMount(() => {
checkbox.id = useUUID(props.id);
});
onMounted(() => {
checkbox.isValid = checkboxEl.value.checkValidity();
checkbox.id = useUUID(props.id);
});
</script>

View file

@ -7,6 +7,7 @@ import {
defineEmits,
defineProps,
computed,
onBeforeMount,
} from "vue";
import { contentIndex } from "@utils/tabindex.js";
import Container from "@components/Widget/Container.vue";
@ -299,8 +300,11 @@ watch(select, () => {
}
});
onMounted(() => {
onBeforeMount(() => {
inp.id = useUUID(props.id);
});
onMounted(() => {
inp.isValid = inputEl.value.checkValidity();
selectWidth.value = `${selectBtn.value.clientWidth}px`;
window.addEventListener("resize", () => {

View file

@ -1,5 +1,11 @@
<script setup>
import { reactive, defineProps, onMounted, onUnmounted } from "vue";
import {
reactive,
defineProps,
onMounted,
onUnmounted,
onBeforeMount,
} from "vue";
import { contentIndex } from "@utils/tabindex.js";
import Container from "@components/Widget/Container.vue";
import Header from "@components/Forms/Header/Field.vue";
@ -573,18 +579,25 @@ function setIndex(calendarEl, tabindex) {
} catch (e) {}
}
onMounted(() => {
onBeforeMount(() => {
date.id = useUUID(props.id);
});
onMounted(() => {
datepicker = flatpickr(`#${date.id}`, {
locale: "en",
dateFormat: date.format,
defaultDate: +props.value,
defaultDate: isNaN(props.value) ? props.value : +props.value,
maxDate: +props.maxDate ? +props.maxDate : "",
minDate: +props.minDate ? +props.minDate : "",
enableTime: true,
enableSeconds: true,
time_24hr: true,
minuteIncrement: 1,
onReady(selectedDates, dateStr, instance) {
const currStamp = Date.parse(dateStr);
date.currStamp = currStamp;
},
onChange(selectedDates, dateStr, instance) {
if (!dateStr && props.required) return (date.isValid = false);
//Check if date is in interval
@ -637,7 +650,9 @@ onMounted(() => {
});
onUnmounted(() => {
datepicker.destroy();
try {
datepicker.destroy();
} catch (e) {}
});
</script>

View file

@ -6,6 +6,7 @@ import {
onMounted,
defineProps,
onUnmounted,
onBeforeMount,
} from "vue";
import { contentIndex } from "@utils/tabindex.js";
import Container from "@components/Widget/Container.vue";
@ -59,7 +60,7 @@ const props = defineProps({
id: {
type: String,
required: false,
default: uuidv4(),
default: "",
},
columns: {
type: [Object, Boolean],
@ -315,9 +316,12 @@ function setEditorAttrs() {
}
}
onBeforeMount(() => {
editor.id = useUUID(props.id);
});
// Use ace editor
onMounted(() => {
editor.id = useUUID(props.id);
setTimeout(() => {
// Default value
editorEl = new Editor();

View file

@ -1,5 +1,12 @@
<script setup>
import { reactive, ref, defineEmits, onMounted, defineProps } from "vue";
import {
reactive,
ref,
defineEmits,
onMounted,
onBeforeMount,
defineProps,
} from "vue";
import { contentIndex } from "@utils/tabindex.js";
import Container from "@components/Widget/Container.vue";
import Header from "@components/Forms/Header/Field.vue";
@ -159,8 +166,11 @@ const inp = reactive({
const emits = defineEmits(["inp"]);
onMounted(() => {
onBeforeMount(() => {
inp.id = useUUID(props.id);
});
onMounted(() => {
inp.isValid = inputEl.value.checkValidity();
// Clipboard not allowed on http

View file

@ -1,5 +1,13 @@
<script setup>
import { ref, reactive, watch, onMounted, defineEmits, defineProps } from "vue";
import {
ref,
reactive,
watch,
onMounted,
defineEmits,
defineProps,
onBeforeMount,
} from "vue";
import { contentIndex } from "@utils/tabindex.js";
import Container from "@components/Widget/Container.vue";
import Header from "@components/Forms/Header/Field.vue";
@ -273,8 +281,11 @@ watch(select, () => {
}
});
onMounted(() => {
onBeforeMount(() => {
select.id = useUUID(props.id);
});
onMounted(() => {
selectWidth.value = `${selectBtn.value.clientWidth}px`;
window.addEventListener("resize", () => {
try {

View file

@ -1,6 +1,6 @@
<script setup>
import { useUUID } from "@utils/global.js";
import { defineProps, reactive, onMounted } from "vue";
import { defineProps, reactive, onBeforeMount } from "vue";
/**
@name Icons/Check.vue
@description This component is a svg icon representing a check mark.
@ -32,7 +32,7 @@ const icon = reactive({
color: props.color || "success",
});
onMounted(() => {
onBeforeMount(() => {
icon.id = useUUID();
});
</script>

View file

@ -1,5 +1,5 @@
<script setup>
import { defineProps, reactive, onMounted } from "vue";
import { defineProps, reactive, onBeforeMount } from "vue";
import { useUUID } from "@utils/global.js";
/**
@name Icons/Close.vue
@ -32,7 +32,7 @@ const icon = reactive({
color: props.color || "dark",
});
onMounted(() => {
onBeforeMount(() => {
icon.id = useUUID();
});
</script>

View file

@ -1,5 +1,5 @@
<script setup>
import { defineProps, reactive, onMounted } from "vue";
import { defineProps, reactive, onBeforeMount } from "vue";
import { useUUID } from "@utils/global.js";
/**
@name Icons/Core.vue
@ -32,7 +32,7 @@ const icon = reactive({
color: props.color || "cyan-darker",
});
onMounted(() => {
onBeforeMount(() => {
icon.id = useUUID();
});
</script>

View file

@ -1,5 +1,5 @@
<script setup>
import { defineProps, reactive, onMounted } from "vue";
import { defineProps, reactive, onBeforeMount } from "vue";
import { useUUID } from "@utils/global.js";
/**
@name Icons/Cross.vue
@ -32,7 +32,7 @@ const icon = reactive({
color: props.color || "red",
});
onMounted(() => {
onBeforeMount(() => {
icon.id = useUUID();
});
</script>

View file

@ -1,5 +1,5 @@
<script setup>
import { defineProps, reactive, onMounted } from "vue";
import { defineProps, reactive, onBeforeMount } from "vue";
import { useUUID } from "@utils/global.js";
/**
@ -33,7 +33,7 @@ const icon = reactive({
color: props.color || "amber",
});
onMounted(() => {
onBeforeMount(() => {
icon.id = useUUID();
});
</script>

View file

@ -1,5 +1,5 @@
<script setup>
import { defineProps, reactive, onMounted } from "vue";
import { defineProps, reactive, onBeforeMount } from "vue";
import { useUUID } from "@utils/global.js";
/**
@name Icons/Discord.vue
@ -32,7 +32,7 @@ const icon = reactive({
color: props.color || "discord",
});
onMounted(() => {
onBeforeMount(() => {
icon.id = useUUID();
});
</script>

View file

@ -1,5 +1,5 @@
<script setup>
import { defineProps, reactive, onMounted } from "vue";
import { defineProps, reactive, onBeforeMount } from "vue";
import { useUUID } from "@utils/global.js";
/**
@name Icons/Core.vue
@ -32,7 +32,7 @@ const icon = reactive({
color: props.color || "blue",
});
onMounted(() => {
onBeforeMount(() => {
icon.id = useUUID();
});
</script>

View file

@ -1,5 +1,5 @@
<script setup>
import { defineProps, reactive, onMounted } from "vue";
import { defineProps, reactive, onBeforeMount } from "vue";
import { useUUID } from "@utils/global.js";
/**
@name Icons/Github.vue
@ -32,7 +32,7 @@ const icon = reactive({
color: props.color || "github",
});
onMounted(() => {
onBeforeMount(() => {
icon.id = useUUID();
});
</script>

View file

@ -1,5 +1,5 @@
<script setup>
import { defineProps, reactive, onMounted } from "vue";
import { defineProps, reactive, onBeforeMount } from "vue";
import { useUUID } from "@utils/global.js";
/**
@name Icons/Linkedin.vue
@ -32,7 +32,7 @@ const icon = reactive({
color: props.color || "linkedin",
});
onMounted(() => {
onBeforeMount(() => {
icon.id = useUUID();
});
</script>

View file

@ -1,5 +1,5 @@
<script setup>
import { defineProps, reactive, onMounted } from "vue";
import { defineProps, reactive, onBeforeMount } from "vue";
import { useUUID } from "@utils/global.js";
/**
@name Icons/Plus.vue
@ -32,7 +32,7 @@ const icon = reactive({
color: props.color || "success",
});
onMounted(() => {
onBeforeMount(() => {
icon.id = useUUID();
});
</script>

View file

@ -1,5 +1,5 @@
<script setup>
import { defineProps, reactive, onMounted } from "vue";
import { defineProps, reactive, onBeforeMount } from "vue";
import { useUUID } from "@utils/global.js";
/**
@name Icons/Trespass.vue
@ -32,7 +32,7 @@ const icon = reactive({
color: props.color || "error",
});
onMounted(() => {
onBeforeMount(() => {
icon.id = useUUID();
});
</script>

View file

@ -1,5 +1,5 @@
<script setup>
import { defineProps, reactive, onMounted } from "vue";
import { defineProps, reactive, onBeforeMount } from "vue";
import { useUUID } from "@utils/global.js";
/**
@name Icons/Twiiter.vue
@ -32,7 +32,7 @@ const icon = reactive({
color: props.color || "twitter",
});
onMounted(() => {
onBeforeMount(() => {
icon.id = useUUID();
});
</script>

View file

@ -1,6 +1,6 @@
<script setup>
import { onMounted } from "vue";
import { defineProps, defineEmits, reactive } from "vue";
import { defineProps, reactive, onMounted, onBeforeMount } from "vue";
import { useUUID } from "@utils/global.js";
/**
@name Forms/Error/Field.vue
@ -65,14 +65,16 @@ const alert = reactive({
id: "",
});
onBeforeMount(() => {
alert.id = useUUID();
});
onMounted(() => {
if (props.delayToClose > 0) {
setTimeout(() => {
alert.visible = false;
}, props.delayToClose);
}
alert.id = useUUID();
});
</script>

View file

@ -1,5 +1,5 @@
<script setup>
import { computed, ref, reactive, onMounted } from "vue";
import { computed, ref, reactive, onBeforeMount } from "vue";
import { contentIndex } from "@utils/tabindex.js";
import Container from "@components/Widget/Container.vue";
import Icons from "@components/Widget/Icons.vue";
@ -114,7 +114,7 @@ const buttonClass = computed(() => {
return `btn ${props.color} ${props.size}`;
});
onMounted(() => {
onBeforeMount(() => {
btn.id = useUUID(props.id);
});
</script>

View file

@ -1,5 +1,5 @@
<script setup>
import { computed, ref, onMounted, reactive } from "vue";
import { computed, ref, onMounted, reactive, onBeforeMount } from "vue";
import Button from "@components/Widget/Button.vue";
import { contentIndex } from "@utils/tabindex.js";
import { useUUID } from "@utils/global.js";
@ -84,8 +84,11 @@ const gridClass = computed(() => {
const flowEl = ref();
onMounted(() => {
onBeforeMount(() => {
container.id = useUUID(props.id);
});
onMounted(() => {
if (!props.link) return;
flowEl.value.setAttribute("href", props.link);
flowEl.value.setAttribute("rel", "noopener");

View file

@ -1,5 +1,12 @@
<script setup>
import { reactive, ref, watch, defineProps, onMounted } from "vue";
import {
reactive,
ref,
watch,
defineProps,
onMounted,
onBeforeMount,
} from "vue";
import { contentIndex } from "@utils/tabindex.js";
import { useUUID } from "@utils/global.js";
import Icons from "@components/Widget/Icons.vue";
@ -75,14 +82,17 @@ function showPopover() {
// Position popover relative to btn
const popoverBtnRect = popoverBtn.value.getBoundingClientRect();
popoverContainer.value.style.right = `${
window.innerWidth - popoverBtnRect.left - popoverBtnRect.width / 1.5
}px`;
// We need to take care of parent padding and margin that will affect dropdown position but aren't calculate in rect
const parents = [popoverBtn.value.parentElement];
const parents = [];
const firstParent = popoverBtn.value.parentElement;
const firstParentY = firstParent.getBoundingClientRect().y || 0;
let isParent = popoverBtn.value.parentElement ? true : false;
if (isParent) parents.push(firstParent);
while (isParent) {
parents.push(parents[parents.length - 1].parentElement);
isParent = parents[parents.length - 1].parentElement ? true : false;
@ -104,12 +114,11 @@ function showPopover() {
.replace("px", "");
} catch (e) {}
}
popoverContainer.value.style.top = `${
window.scrollY +
popoverBtnRect.top -
firstParentY +
window.scrollY -
noRectParentHeight -
popoverBtnRect.height * 1.5 -
popoverBtnRect.height -
80
}px`;
@ -133,8 +142,11 @@ watch(popover, () => {
}
});
onMounted(() => {
onBeforeMount(() => {
popover.id = useUUID();
});
onMounted(() => {
// Set props color or the default icon color
popover.color =
props.color || popoverBtn.value.querySelector("[data-svg]")

View file

@ -1,5 +1,5 @@
<script setup>
import { defineProps, computed, onMounted, reactive } from "vue";
import { defineProps, computed, onBeforeMount, reactive } from "vue";
import { useUUID } from "@utils/global.js";
/**
@ -45,7 +45,7 @@ const statusDesc = computed(() => {
if (props.status === "info") return "dashboard_status_info";
});
onMounted(() => {
onBeforeMount(() => {
status.id = useUUID(props.id);
});
</script>

View file

@ -247,6 +247,15 @@
"bans_search_desc" : "Search within ban ip, ban start / end date",
"bans_reason": "Reason",
"bans_reason_desc": "Reason is the method that triggered the ban.",
"bans_terms": "Interval",
"bans_terms_desc": "Order of magnitude before unban."
"bans_terms": "Term",
"bans_terms_desc": "Order of magnitude before unban.",
"bans_title" :"Bans",
"bans_table_title" :"Bans list with ip, start date, end date, reason and terms.",
"bans_table_ip" : "IP",
"bans_table_ban_start" : "Ban start",
"bans_table_ban_end" : "Ban end",
"bans_table_reason" : "Reason",
"bans_table_remain" : "Remain",
"bans_table_term" : "Term",
"bans_table_select" : "Select"
}

View file

@ -31,7 +31,675 @@ onMounted(() => {
useForm();
});
const builder = [];
const builder = [
{
type: "void",
widgets: [
{
type: "Button",
data: {
text: "bans_not_found",
},
},
],
},
{
type: "card",
containerColumns: {
pc: 12,
tablet: 12,
mobile: 12,
},
widgets: [
{
type: "Title",
data: {
title: "bans_title",
},
},
{
type: "Table",
data: {
title: "bans_table_title",
minWidth: "xl",
header: [
"bans_table_select",
"bans_table_ip",
"bans_table_reason",
"bans_table_ban_start",
"bans_table_ban_end",
"bans_table_remain",
"bans_table_term",
],
positions: [1, 1, 1, 3, 3, 2, 1],
items: [
[
{
select: false,
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: false,
value: "no",
inpType: "checkbox",
id: "select-ban-1",
name: "select-ban-1",
label: "select-ban-1",
hideLabel: true,
},
},
},
{
ip: "127.0.0.1",
type: "Text",
data: {
text: "127.0.0.1",
},
},
{
reason: "ui",
type: "Text",
data: {
text: "ui",
},
},
{
ban_start: "1719393920",
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: true,
value: 1719393920,
inpType: "datepicker",
id: "datepicker-ban-ban-start-1",
name: "datepicker-ban-ban-start-1",
label: "datepicker-ban-ban-start-1",
hideLabel: true,
},
},
},
{
ban_end: "1719393920",
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: true,
value: 1719393920,
inpType: "datepicker",
id: "datepicker-ban-ban-end-1",
name: "datepicker-ban-ban-end-1",
label: "datepicker-ban-ban-end-1",
hideLabel: true,
},
},
},
{
remain: "23 hours and 49 minutes",
type: "Text",
data: {
text: "23 hours and 49 minutes",
},
},
{
term: "hour(s)",
type: "Text",
data: {
text: "hour(s)",
},
},
],
[
{
select: false,
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: false,
value: "no",
inpType: "checkbox",
id: "select-ban-2",
name: "select-ban-2",
label: "select-ban-2",
hideLabel: true,
},
},
},
{
ip: "127.0.0.1",
type: "Text",
data: {
text: "127.0.0.1",
},
},
{
reason: "ui",
type: "Text",
data: {
text: "ui",
},
},
{
ban_start: "1719393920",
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: true,
value: 1719393920,
inpType: "datepicker",
id: "datepicker-ban-ban-start-2",
name: "datepicker-ban-ban-start-2",
label: "datepicker-ban-ban-start-2",
hideLabel: true,
},
},
},
{
ban_end: "1719393920",
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: true,
value: 1719393920,
inpType: "datepicker",
id: "datepicker-ban-ban-end-2",
name: "datepicker-ban-ban-end-2",
label: "datepicker-ban-ban-end-2",
hideLabel: true,
},
},
},
{
remain: "23 hours and 49 minutes",
type: "Text",
data: {
text: "23 hours and 49 minutes",
},
},
{
term: "day(s)",
type: "Text",
data: {
text: "day(s)",
},
},
],
[
{
select: false,
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: false,
value: "no",
inpType: "checkbox",
id: "select-ban-3",
name: "select-ban-3",
label: "select-ban-3",
hideLabel: true,
},
},
},
{
ip: "127.0.0.1",
type: "Text",
data: {
text: "127.0.0.1",
},
},
{
reason: "cor",
type: "Text",
data: {
text: "cor",
},
},
{
ban_start: "1719393920",
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: true,
value: 1719393920,
inpType: "datepicker",
id: "datepicker-ban-ban-start-3",
name: "datepicker-ban-ban-start-3",
label: "datepicker-ban-ban-start-3",
hideLabel: true,
},
},
},
{
ban_end: "1719393920",
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: true,
value: 1719393920,
inpType: "datepicker",
id: "datepicker-ban-ban-end-3",
name: "datepicker-ban-ban-end-3",
label: "datepicker-ban-ban-end-3",
hideLabel: true,
},
},
},
{
remain: "23 hours and 49 minutes",
type: "Text",
data: {
text: "23 hours and 49 minutes",
},
},
{
term: "hour(s)",
type: "Text",
data: {
text: "hour(s)",
},
},
],
[
{
select: false,
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: false,
value: "no",
inpType: "checkbox",
id: "select-ban-4",
name: "select-ban-4",
label: "select-ban-4",
hideLabel: true,
},
},
},
{
ip: "127.0.0.1",
type: "Text",
data: {
text: "127.0.0.1",
},
},
{
reason: "ui",
type: "Text",
data: {
text: "ui",
},
},
{
ban_start: "1719393920",
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: true,
value: 1719393920,
inpType: "datepicker",
id: "datepicker-ban-ban-start-4",
name: "datepicker-ban-ban-start-4",
label: "datepicker-ban-ban-start-4",
hideLabel: true,
},
},
},
{
ban_end: "1719393920",
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: true,
value: 1719393920,
inpType: "datepicker",
id: "datepicker-ban-ban-end-4",
name: "datepicker-ban-ban-end-4",
label: "datepicker-ban-ban-end-4",
hideLabel: true,
},
},
},
{
remain: "23 hours and 49 minutes",
type: "Text",
data: {
text: "23 hours and 49 minutes",
},
},
{
term: "hour(s)",
type: "Text",
data: {
text: "hour(s)",
},
},
],
[
{
select: false,
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: false,
value: "no",
inpType: "checkbox",
id: "select-ban-5",
name: "select-ban-5",
label: "select-ban-5",
hideLabel: true,
},
},
},
{
ip: "127.0.0.1",
type: "Text",
data: {
text: "127.0.0.1",
},
},
{
reason: "ui",
type: "Text",
data: {
text: "ui",
},
},
{
ban_start: "1719393920",
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: true,
value: 1719393920,
inpType: "datepicker",
id: "datepicker-ban-ban-start-5",
name: "datepicker-ban-ban-start-5",
label: "datepicker-ban-ban-start-5",
hideLabel: true,
},
},
},
{
ban_end: "1719393920",
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: true,
value: 1719393920,
inpType: "datepicker",
id: "datepicker-ban-ban-end-5",
name: "datepicker-ban-ban-end-5",
label: "datepicker-ban-ban-end-5",
hideLabel: true,
},
},
},
{
remain: "23 hours and 49 minutes",
type: "Text",
data: {
text: "23 hours and 49 minutes",
},
},
{
term: "hour(s)",
type: "Text",
data: {
text: "hour(s)",
},
},
],
[
{
select: false,
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: false,
value: "no",
inpType: "checkbox",
id: "select-ban-6",
name: "select-ban-6",
label: "select-ban-6",
hideLabel: true,
},
},
},
{
ip: "127.0.0.1",
type: "Text",
data: {
text: "127.0.0.1",
},
},
{
reason: "ui",
type: "Text",
data: {
text: "ui",
},
},
{
ban_start: "1719393920",
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: true,
value: 1719393920,
inpType: "datepicker",
id: "datepicker-ban-ban-start-6",
name: "datepicker-ban-ban-start-6",
label: "datepicker-ban-ban-start-6",
hideLabel: true,
},
},
},
{
ban_end: "1719393920",
type: "Fields",
data: {
setting: {
columns: {
pc: 12,
tablet: 12,
mobile: 12,
},
disabled: true,
value: 1719393920,
inpType: "datepicker",
id: "datepicker-ban-ban-end-6",
name: "datepicker-ban-ban-end-6",
label: "datepicker-ban-ban-end-6",
hideLabel: true,
},
},
},
{
remain: "23 hours and 49 minutes",
type: "Text",
data: {
text: "23 hours and 49 minutes",
},
},
{
term: "hour(s)",
type: "Text",
data: {
text: "hour(s)",
},
},
],
],
filters: [
{
filter: "table",
filterName: "keyword",
type: "keyword",
value: "",
keys: ["ip", "ban_start", "ban_end"],
field: {
id: "bans-keyword",
value: "",
type: "text",
name: "bans-keyword",
label: "bans_search",
placeholder: "inp_keyword",
isClipboard: false,
popovers: [
{
text: "bans_search_desc",
iconName: "info",
},
],
columns: {
pc: 3,
tablet: 4,
mobile: 12,
},
},
},
{
filter: "table",
filterName: "reason",
type: "select",
value: "all",
keys: ["reason"],
field: {
id: "bans-reason",
value: "all",
values: ["all", "ui", "cor"],
name: "bans-reason",
onlyDown: true,
label: "bans_reason",
popovers: [
{
text: "bans_reason_desc",
iconName: "info",
},
],
columns: {
pc: 3,
tablet: 4,
mobile: 12,
},
},
},
{
filter: "table",
filterName: "term",
type: "select",
value: "all",
keys: ["term"],
field: {
id: "bans-terms",
value: "all",
values: ["all", "hour(s)", "day(s)"],
name: "bans-terms",
onlyDown: true,
label: "bans_terms",
popovers: [
{
text: "bans_terms_desc",
iconName: "info",
},
],
columns: {
pc: 3,
tablet: 4,
mobile: 12,
},
},
},
],
},
},
],
},
];
</script>
<template>

693
vuejs/tests/bans.json Normal file
View file

@ -0,0 +1,693 @@
[
{
"type": "void",
"widgets": [
{
"type": "Button",
"data": {
"text": "bans_not_found"
}
}
]
},
{
"type": "card",
"containerColumns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"widgets": [
{
"type": "Title",
"data": {
"title": "bans_title"
}
},
{
"type": "Table",
"data": {
"title": "bans_table_title",
"minWidth": "xl",
"header": [
"bans_table_select",
"bans_table_ip",
"bans_table_reason",
"bans_table_ban_start",
"bans_table_ban_end",
"bans_table_remain",
"bans_table_term"
],
"positions": [
1,
1,
1,
3,
3,
2,
1
],
"items": [
[
{
"select": false,
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": false,
"value": "no",
"inpType": "checkbox",
"id": "select-ban-1",
"name": "select-ban-1",
"label": "select-ban-1",
"hideLabel": true
}
}
},
{
"ip": "127.0.0.1",
"type": "Text",
"data": {
"text": "127.0.0.1"
}
},
{
"reason": "ui",
"type": "Text",
"data": {
"text": "ui"
}
},
{
"ban_start": "1719393920",
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": true,
"value": 1719393920,
"inpType": "datepicker",
"id": "datepicker-ban-ban-start-1",
"name": "datepicker-ban-ban-start-1",
"label": "datepicker-ban-ban-start-1",
"hideLabel": true
}
}
},
{
"ban_end": "1719393920",
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": true,
"value": 1719393920,
"inpType": "datepicker",
"id": "datepicker-ban-ban-end-1",
"name": "datepicker-ban-ban-end-1",
"label": "datepicker-ban-ban-end-1",
"hideLabel": true
}
}
},
{
"remain": "23 hours and 49 minutes",
"type": "Text",
"data": {
"text": "23 hours and 49 minutes"
}
},
{
"term": "hour(s)",
"type": "Text",
"data": {
"text": "hour(s)"
}
}
],
[
{
"select": false,
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": false,
"value": "no",
"inpType": "checkbox",
"id": "select-ban-2",
"name": "select-ban-2",
"label": "select-ban-2",
"hideLabel": true
}
}
},
{
"ip": "127.0.0.1",
"type": "Text",
"data": {
"text": "127.0.0.1"
}
},
{
"reason": "ui",
"type": "Text",
"data": {
"text": "ui"
}
},
{
"ban_start": "1719393920",
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": true,
"value": 1719393920,
"inpType": "datepicker",
"id": "datepicker-ban-ban-start-2",
"name": "datepicker-ban-ban-start-2",
"label": "datepicker-ban-ban-start-2",
"hideLabel": true
}
}
},
{
"ban_end": "1719393920",
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": true,
"value": 1719393920,
"inpType": "datepicker",
"id": "datepicker-ban-ban-end-2",
"name": "datepicker-ban-ban-end-2",
"label": "datepicker-ban-ban-end-2",
"hideLabel": true
}
}
},
{
"remain": "23 hours and 49 minutes",
"type": "Text",
"data": {
"text": "23 hours and 49 minutes"
}
},
{
"term": "day(s)",
"type": "Text",
"data": {
"text": "day(s)"
}
}
],
[
{
"select": false,
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": false,
"value": "no",
"inpType": "checkbox",
"id": "select-ban-3",
"name": "select-ban-3",
"label": "select-ban-3",
"hideLabel": true
}
}
},
{
"ip": "127.0.0.1",
"type": "Text",
"data": {
"text": "127.0.0.1"
}
},
{
"reason": "cor",
"type": "Text",
"data": {
"text": "cor"
}
},
{
"ban_start": "1719393920",
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": true,
"value": 1719393920,
"inpType": "datepicker",
"id": "datepicker-ban-ban-start-3",
"name": "datepicker-ban-ban-start-3",
"label": "datepicker-ban-ban-start-3",
"hideLabel": true
}
}
},
{
"ban_end": "1719393920",
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": true,
"value": 1719393920,
"inpType": "datepicker",
"id": "datepicker-ban-ban-end-3",
"name": "datepicker-ban-ban-end-3",
"label": "datepicker-ban-ban-end-3",
"hideLabel": true
}
}
},
{
"remain": "23 hours and 49 minutes",
"type": "Text",
"data": {
"text": "23 hours and 49 minutes"
}
},
{
"term": "hour(s)",
"type": "Text",
"data": {
"text": "hour(s)"
}
}
],
[
{
"select": false,
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": false,
"value": "no",
"inpType": "checkbox",
"id": "select-ban-4",
"name": "select-ban-4",
"label": "select-ban-4",
"hideLabel": true
}
}
},
{
"ip": "127.0.0.1",
"type": "Text",
"data": {
"text": "127.0.0.1"
}
},
{
"reason": "ui",
"type": "Text",
"data": {
"text": "ui"
}
},
{
"ban_start": "1719393920",
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": true,
"value": 1719393920,
"inpType": "datepicker",
"id": "datepicker-ban-ban-start-4",
"name": "datepicker-ban-ban-start-4",
"label": "datepicker-ban-ban-start-4",
"hideLabel": true
}
}
},
{
"ban_end": "1719393920",
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": true,
"value": 1719393920,
"inpType": "datepicker",
"id": "datepicker-ban-ban-end-4",
"name": "datepicker-ban-ban-end-4",
"label": "datepicker-ban-ban-end-4",
"hideLabel": true
}
}
},
{
"remain": "23 hours and 49 minutes",
"type": "Text",
"data": {
"text": "23 hours and 49 minutes"
}
},
{
"term": "hour(s)",
"type": "Text",
"data": {
"text": "hour(s)"
}
}
],
[
{
"select": false,
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": false,
"value": "no",
"inpType": "checkbox",
"id": "select-ban-5",
"name": "select-ban-5",
"label": "select-ban-5",
"hideLabel": true
}
}
},
{
"ip": "127.0.0.1",
"type": "Text",
"data": {
"text": "127.0.0.1"
}
},
{
"reason": "ui",
"type": "Text",
"data": {
"text": "ui"
}
},
{
"ban_start": "1719393920",
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": true,
"value": 1719393920,
"inpType": "datepicker",
"id": "datepicker-ban-ban-start-5",
"name": "datepicker-ban-ban-start-5",
"label": "datepicker-ban-ban-start-5",
"hideLabel": true
}
}
},
{
"ban_end": "1719393920",
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": true,
"value": 1719393920,
"inpType": "datepicker",
"id": "datepicker-ban-ban-end-5",
"name": "datepicker-ban-ban-end-5",
"label": "datepicker-ban-ban-end-5",
"hideLabel": true
}
}
},
{
"remain": "23 hours and 49 minutes",
"type": "Text",
"data": {
"text": "23 hours and 49 minutes"
}
},
{
"term": "hour(s)",
"type": "Text",
"data": {
"text": "hour(s)"
}
}
],
[
{
"select": false,
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": false,
"value": "no",
"inpType": "checkbox",
"id": "select-ban-6",
"name": "select-ban-6",
"label": "select-ban-6",
"hideLabel": true
}
}
},
{
"ip": "127.0.0.1",
"type": "Text",
"data": {
"text": "127.0.0.1"
}
},
{
"reason": "ui",
"type": "Text",
"data": {
"text": "ui"
}
},
{
"ban_start": "1719393920",
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": true,
"value": 1719393920,
"inpType": "datepicker",
"id": "datepicker-ban-ban-start-6",
"name": "datepicker-ban-ban-start-6",
"label": "datepicker-ban-ban-start-6",
"hideLabel": true
}
}
},
{
"ban_end": "1719393920",
"type": "Fields",
"data": {
"setting": {
"columns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"disabled": true,
"value": 1719393920,
"inpType": "datepicker",
"id": "datepicker-ban-ban-end-6",
"name": "datepicker-ban-ban-end-6",
"label": "datepicker-ban-ban-end-6",
"hideLabel": true
}
}
},
{
"remain": "23 hours and 49 minutes",
"type": "Text",
"data": {
"text": "23 hours and 49 minutes"
}
},
{
"term": "hour(s)",
"type": "Text",
"data": {
"text": "hour(s)"
}
}
]
],
"filters": [
{
"filter": "table",
"filterName": "keyword",
"type": "keyword",
"value": "",
"keys": [
"ip",
"ban_start",
"ban_end"
],
"field": {
"id": "bans-keyword",
"value": "",
"type": "text",
"name": "bans-keyword",
"label": "bans_search",
"placeholder": "inp_keyword",
"isClipboard": false,
"popovers": [
{
"text": "bans_search_desc",
"iconName": "info"
}
],
"columns": {
"pc": 3,
"tablet": 4,
"mobile": 12
}
}
},
{
"filter": "table",
"filterName": "reason",
"type": "select",
"value": "all",
"keys": [
"reason"
],
"field": {
"id": "bans-reason",
"value": "all",
"values": [
"all",
"ui",
"cor"
],
"name": "bans-reason",
"onlyDown": true,
"label": "bans_reason",
"popovers": [
{
"text": "bans_reason_desc",
"iconName": "info"
}
],
"columns": {
"pc": 3,
"tablet": 4,
"mobile": 12
}
}
},
{
"filter": "table",
"filterName": "term",
"type": "select",
"value": "all",
"keys": [
"term"
],
"field": {
"id": "bans-terms",
"value": "all",
"values": [
"all",
"hour(s)",
"day(s)"
],
"name": "bans-terms",
"onlyDown": true,
"label": "bans_terms",
"popovers": [
{
"text": "bans_terms_desc",
"iconName": "info"
}
],
"columns": {
"pc": 3,
"tablet": 4,
"mobile": 12
}
}
}
]
}
}
]
}
]

View file

@ -10,8 +10,26 @@ bans = [
"ip": "127.0.0.1",
"remain": "23 hours and 49 minutes",
"term": "hour(s)",
"ban_start": "26/06/2024 09:25:20",
"ban_end": "27/06/2024 09:15:15",
"ban_start": 1719393920,
"ban_end": 1719393920,
},
{
"reason": "ui",
"date": 1719393920,
"ip": "127.0.0.1",
"remain": "23 hours and 49 minutes",
"term": "day(s)",
"ban_start": 1719393920,
"ban_end": 1719393920,
},
{
"reason": "core",
"date": 1719393920,
"ip": "127.0.0.1",
"remain": "23 hours and 49 minutes",
"term": "hour(s)",
"ban_start": 1719393920,
"ban_end": 1719393920,
},
{
"reason": "ui",
@ -19,12 +37,31 @@ bans = [
"ip": "127.0.0.1",
"remain": "23 hours and 49 minutes",
"term": "hour(s)",
"ban_start": "26/06/2024 09:25:20",
"ban_end": "27/06/2024 09:15:15",
"ban_start": 1719393920,
"ban_end": 1719393920,
},
{
"reason": "ui",
"date": 1719393920,
"ip": "127.0.0.1",
"remain": "23 hours and 49 minutes",
"term": "hour(s)",
"ban_start": 1719393920,
"ban_end": 1719393920,
},
{
"reason": "ui",
"date": 1719393920,
"ip": "127.0.0.1",
"remain": "23 hours and 49 minutes",
"term": "hour(s)",
"ban_start": 1719393920,
"ban_end": 1719393920,
},
]
# Reoder bans dict
for ban in bans:
ban.pop("date")
ban["ip"] = ban.pop("ip")
ban["reason"] = ban.pop("reason")
ban["ban_start"] = ban.pop("ban_start")
@ -76,7 +113,7 @@ def get_bans_filter(bans):
},
)
if len(total_reasons) > 1:
if len(total_reasons) > 2:
filters.append(
{
"filter": "table",
@ -102,40 +139,82 @@ def get_bans_filter(bans):
},
)
if len(total_terms) > 1:
filters.append(
{
"filter": "table",
"filterName": "term",
"type": "select",
if len(total_terms) > 2:
filters.append(
{
"filter": "table",
"filterName": "term",
"type": "select",
"value": "all",
"keys": ["term"],
"field": {
"id": "bans-terms",
"value": "all",
"keys": ["term"],
"field": {
"id": "bans-terms",
"value": "all",
"values": total_terms,
"name": "bans-terms",
"onlyDown": True,
"label": "bans_terms",
"popovers": [
{
"text": "bans_terms_desc",
"iconName": "info",
},
],
"columns": {"pc": 3, "tablet": 4, "mobile": 12},
},
"values": total_terms,
"name": "bans-terms",
"onlyDown": True,
"label": "bans_terms",
"popovers": [
{
"text": "bans_terms_desc",
"iconName": "info",
},
],
"columns": {"pc": 3, "tablet": 4, "mobile": 12},
},
)
},
)
return filters
def get_reports_list(reports):
def get_bans_list(bans):
data = []
# loop on each dict
for report in reports:
id = 0
for ban in bans:
id += 1
item = []
for k, v in report.items():
item.append(
{
"select": False,
"type": "Fields",
"data": {
"setting": {
"columns": {"pc": 12, "tablet": 12, "mobile": 12},
"disabled": False,
"value": "no",
"inpType": "checkbox",
"id": f"select-ban-{id}",
"name": f"select-ban-{id}",
"label": f"select-ban-{id}",
"hideLabel": True,
},
},
}
)
for k, v in ban.items():
if k in ("date", "ban_start", "ban_end"):
item.append(
{
k: json.dumps(v) if isinstance(v, dict) else str(v),
"type": "Fields",
"data": {
"setting": {
"columns": {"pc": 12, "tablet": 12, "mobile": 12},
"disabled": True,
"value": v,
"inpType": "datepicker",
"id": f"datepicker-ban-{k}-{id}".replace("_", "-"),
"name": f"datepicker-ban-{k}-{id}".replace("_", "-"),
"label": f"datepicker-ban-{k}-{id}".replace("_", "-"),
"hideLabel": True,
},
},
}
)
continue
item.append(
{
k: json.dumps(v) if isinstance(v, dict) else str(v),
@ -151,89 +230,67 @@ def get_reports_list(reports):
return data
def get_reports_details(details):
return {
"type": "card",
"containerColumns": {"pc": 4, "tablet": 6, "mobile": 12},
"widgets": [
{
"type": "Title",
"data": {"title": "dashboard_details"},
},
{
"type": "ListPairs",
"data": {
"pairs": [
{"key": "reports_total", "value": details.get("total_reports")},
{"key": "reports_top_status", "value": details.get("top_code")},
{
"key": "reports_top_reason",
"value": details.get("top_reason"),
},
],
},
},
],
}
def bans_builder(bans):
builder = [
{
"type": "void",
"widgets": [{"type": "Button", "data": {"text": "bans_not_found"}}],
},
]
def reports_builder(reports, details=None):
if not reports:
return [
if not bans:
builder.append(
{
"type": "void",
"widgets": [
{"type": "MessageUnmatch", "data": {"text": "reports_not_found"}}
{"type": "MessageUnmatch", "data": {"text": "bans_not_found"}}
],
},
]
}
)
return builder
details = get_reports_details(details)
filters = get_bans_filter(bans)
bans_list = get_bans_list(bans)
filters = get_bans_filter(reports)
reports_list = get_reports_list(reports)
reports_table = {
bans_table = {
"type": "card",
"containerColumns": {"pc": 12, "tablet": 12, "mobile": 12},
"widgets": [
{
"type": "Title",
"data": {"title": "reports_title"},
"data": {"title": "bans_title"},
},
{
"type": "Table",
"data": {
"title": "reports_table_title",
"title": "bans_table_title",
"minWidth": "xl",
"header": [
"reports_table_date",
"reports_table_ip",
"reports_table_country",
"reports_table_method",
"reports_table_url",
"reports_table_status_code",
"reports_table_cache_user_agent",
"reports_table_reason",
"reports_table_data",
"bans_table_select",
"bans_table_ip",
"bans_table_reason",
"bans_table_ban_start",
"bans_table_ban_end",
"bans_table_remain",
"bans_table_term",
],
"positions": [1, 1, 1, 1, 2, 1, 2, 1, 2],
"items": reports_list,
"positions": [1, 1, 1, 3, 3, 2, 1],
"items": bans_list,
"filters": filters,
},
},
],
}
builder = [details, reports_table]
builder.append(bans_table)
return builder
# output = reports_builder(reports)
output = reports_builder(no_bans)
output = bans_builder(bans)
# output = bans_builder(no_bans)
# store on a file
with open("reports.json", "w") as f:
with open("bans.json", "w") as f:
json.dump(output, f, indent=4)

View file

@ -16,7 +16,7 @@
{
"type": "ListPairs",
"data": {
"details": [
"pairs": [
{
"key": "reports_total",
"value": "200"

View file

@ -141,7 +141,7 @@ def get_reports_filter(reports):
},
)
if len(total_countries) > 1:
if len(total_countries) > 2:
filters.append(
{
"filter": "table",
@ -167,7 +167,7 @@ def get_reports_filter(reports):
},
)
if len(total_methods) > 1:
if len(total_methods) > 2:
filters.append(
{
"filter": "table",
@ -193,7 +193,7 @@ def get_reports_filter(reports):
},
)
if len(total_status) > 1:
if len(total_status) > 2:
filters.append(
{
"filter": "table",
@ -219,7 +219,7 @@ def get_reports_filter(reports):
},
)
if len(total_reasons) > 1:
if len(total_reasons) > 2:
filters.append(
{
"filter": "table",
@ -323,7 +323,7 @@ def reports_builder(reports, details=None):
"type": "Table",
"data": {
"title": "reports_table_title",
"minWidth": "xl",
"minWidth": "xxl",
"header": [
"reports_table_date",
"reports_table_ip",