mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
update tabulator + bans page UI done
* add layout prop in order to define tabulator layout based on the number of cols ("fitData", "fitColums"...) to look good
* add actionsButtons props to tabulator in order to render buttons after filters and before table (stick left)
* enhance col width format by handling maxW < minW
* add i18n
* update tabulator and related components style
* add bans page component, related builder component, base builder done
This commit is contained in:
parent
2ed224d215
commit
590c776c4c
17 changed files with 1229 additions and 1741 deletions
384
src/ui/client/builder/pages/bans.py
Normal file
384
src/ui/client/builder/pages/bans.py
Normal file
|
|
@ -0,0 +1,384 @@
|
|||
from .utils.widgets import (
|
||||
button_widget,
|
||||
button_group_widget,
|
||||
title_widget,
|
||||
subtitle_widget,
|
||||
text_widget,
|
||||
tabulator_widget,
|
||||
unmatch_widget,
|
||||
datepicker_widget,
|
||||
checkbox_widget,
|
||||
)
|
||||
from .utils.table import add_column
|
||||
from .utils.format import get_fields_from_field
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def bans_tabs():
|
||||
return {
|
||||
"type": "tabs",
|
||||
"widgets": [
|
||||
button_group_widget(
|
||||
buttons=[
|
||||
button_widget(
|
||||
text="bans_tab_list",
|
||||
display=["main", 1],
|
||||
size="tab",
|
||||
color="info",
|
||||
iconColor="white",
|
||||
iconName="list",
|
||||
),
|
||||
button_widget(
|
||||
text="bans_tab_add",
|
||||
color="success",
|
||||
display=["main", 2],
|
||||
size="tab",
|
||||
iconColor="white",
|
||||
iconName="plus",
|
||||
),
|
||||
]
|
||||
)
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def ban_item(id: str, ip: str, reason: str, ban_start_date: int, ban_end_date: int, remain: str) -> dict:
|
||||
return {
|
||||
"check": get_fields_from_field(
|
||||
checkbox_widget(
|
||||
id=f"check-ban-{id}",
|
||||
name=f"check-ban-{id}",
|
||||
label="bans_ban_check", # keep it (a18n)
|
||||
hideLabel=True,
|
||||
value="no",
|
||||
columns={"pc": 12, "tablet": 12, "mobile": 12},
|
||||
)
|
||||
),
|
||||
"ip": text_widget(text=ip)["data"],
|
||||
"reason": text_widget(text=reason)["data"],
|
||||
"ban_start_date": get_fields_from_field(
|
||||
datepicker_widget(
|
||||
id=f"datepicker-ban-start-{id}",
|
||||
name=f"datepicker-ban-start-{id}",
|
||||
label="bans_ban_start_date", # keep it (a18n)
|
||||
hideLabel=True,
|
||||
value=ban_start_date,
|
||||
disabled=True, # Readonly
|
||||
columns={"pc": 12, "tablet": 12, "mobile": 12},
|
||||
)
|
||||
),
|
||||
"ban_end_date": get_fields_from_field(
|
||||
datepicker_widget(
|
||||
id=f"datepicker-ban-end-{id}",
|
||||
name=f"datepicker-ban-end-{id}",
|
||||
label="bans_ban_end_date", # keep it (a18n)
|
||||
hideLabel=True,
|
||||
value=ban_end_date,
|
||||
disabled=True, # Readonly
|
||||
)
|
||||
),
|
||||
"remain": text_widget(text=remain)["data"],
|
||||
}
|
||||
|
||||
|
||||
def bans_items(bans: Optional[list] = None) -> list:
|
||||
|
||||
if bans is None or len(bans) == 0:
|
||||
return []
|
||||
|
||||
items = []
|
||||
for index, item in enumerate(bans):
|
||||
items.append(
|
||||
ban_item(
|
||||
id=index,
|
||||
ip=item.get("ip"),
|
||||
reason=item.get("reason"),
|
||||
ban_start_date=item.get("ban_start_date"),
|
||||
ban_end_date=item.get("ban_end_date"),
|
||||
remain=item.get("remain"),
|
||||
)
|
||||
)
|
||||
|
||||
return items
|
||||
|
||||
|
||||
def bans_filters(reasons: Optional[list] = None, remains: Optional[list] = None) -> list:
|
||||
|
||||
filters = [
|
||||
{
|
||||
"type": "like",
|
||||
"fields": ["ip"],
|
||||
"setting": {
|
||||
"id": "input-search-ip",
|
||||
"name": "input-search-ip",
|
||||
"label": "bans_search_ip", # keep it (a18n)
|
||||
"value": "",
|
||||
"inpType": "input",
|
||||
"columns": {"pc": 3, "tablet": 4, "mobile": 12},
|
||||
"popovers": [
|
||||
{
|
||||
"iconName": "info",
|
||||
"text": "bans_search_ip_desc",
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
# Case "all" ans
|
||||
if reasons is not None and len(reasons) >= 2:
|
||||
filters.append(
|
||||
{
|
||||
"type": "=",
|
||||
"fields": ["reason"],
|
||||
"setting": {
|
||||
"id": "select-ban-reason",
|
||||
"name": "select-ban-reason",
|
||||
"label": "bans_select_reason", # keep it (a18n)
|
||||
"value": "all", # keep "all"
|
||||
"values": ["all"] + reasons, # keep "all" and add your reasons dynamically
|
||||
"inpType": "select",
|
||||
"onlyDown": True,
|
||||
"columns": {"pc": 3, "tablet": 4, "mobile": 12},
|
||||
"popovers": [
|
||||
{
|
||||
"iconName": "info",
|
||||
"text": "bans_select_reason_desc",
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
if remains is not None and len(remains) >= 2:
|
||||
filters.append(
|
||||
{
|
||||
"type": "=",
|
||||
"fields": ["remain"],
|
||||
"setting": {
|
||||
"id": "select-ban-remain",
|
||||
"name": "select-ban-remain",
|
||||
"label": "bans_select_remain", # keep it (a18n)
|
||||
"value": "all", # keep "all"
|
||||
"values": ["all"] + remains, # keep everything and format bans to fit in one remain category
|
||||
"inpType": "select",
|
||||
"onlyDown": True,
|
||||
"columns": {"pc": 3, "tablet": 4, "mobile": 12},
|
||||
"popovers": [
|
||||
{
|
||||
"iconName": "info",
|
||||
"text": "bans_select_remain_desc",
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
return filters
|
||||
|
||||
|
||||
def bans_list(bans: Optional[list] = None, reasons: Optional[list] = None, remains: Optional[list] = None) -> dict:
|
||||
if bans is None or len(bans) == 0:
|
||||
return {
|
||||
"type": "card",
|
||||
"gridLayoutClass": "transparent",
|
||||
"widgets": [
|
||||
unmatch_widget(text="bans_not_found"),
|
||||
],
|
||||
}
|
||||
|
||||
actions_table_list = [
|
||||
# Need to create a script on Page.vue level to add a row on click
|
||||
# + We need to retrieve from the first item a schema to add any new row
|
||||
button_widget(
|
||||
id="select-all-list",
|
||||
type="button",
|
||||
text="action_select_all", # keep it (a18n)
|
||||
color="success",
|
||||
iconColor="white",
|
||||
iconName="check",
|
||||
size="sm",
|
||||
attrs={"data-select-rows": ""}, # we will use this attrs to add a new row
|
||||
),
|
||||
button_widget(
|
||||
id="unselect-all-list",
|
||||
type="button",
|
||||
text="action_unselect_all", # keep it (a18n)
|
||||
color="delete",
|
||||
iconColor="white",
|
||||
iconName="uncheck",
|
||||
size="sm",
|
||||
attrs={"data-unselect-rows": ""}, # we will use this attrs to add a new row
|
||||
),
|
||||
]
|
||||
|
||||
bans_columns = [
|
||||
add_column(title="", field="check", formatter="fields", maxWidth=80),
|
||||
add_column(title="IP", field="ip", formatter="text"),
|
||||
add_column(title="Reason", field="reason", formatter="text"),
|
||||
add_column(title="Ban start date", field="ban_start_date", formatter="fields", minWidth=250),
|
||||
add_column(title="Ban end date", field="ban_end_date", formatter="fields", minWidth=250),
|
||||
add_column(title="Remain", field="remain", formatter="text"),
|
||||
]
|
||||
|
||||
return {
|
||||
"type": "card",
|
||||
"display": ["main", 1],
|
||||
"widgets": [
|
||||
title_widget("bans_list_title"), # keep it (a18n)
|
||||
subtitle_widget("bans_list_subtitle"), # keep it (a18n)
|
||||
tabulator_widget(
|
||||
id="table-bans-list",
|
||||
actionsButtons=actions_table_list,
|
||||
columns=bans_columns,
|
||||
items=bans_items(bans),
|
||||
filters=bans_filters(reasons=reasons, remains=remains),
|
||||
layout="fitColumns",
|
||||
),
|
||||
button_group_widget(
|
||||
buttons=[
|
||||
button_widget(
|
||||
id="unban-btn",
|
||||
type="button",
|
||||
text="action_unban", # keep it (a18n)
|
||||
color="success",
|
||||
size="normal",
|
||||
modal={
|
||||
"widgets": [
|
||||
title_widget(title="bans_unban_title"), # keep it (a18n)
|
||||
text_widget(text="bans_unban_subtitle"), # keep it (a18n)
|
||||
button_group_widget(
|
||||
buttons=[
|
||||
button_widget(
|
||||
id="close-unban-btn",
|
||||
text="action_close", # keep it (a18n)
|
||||
color="close",
|
||||
size="normal",
|
||||
attrs={"data-close-modal": ""}, # a11y
|
||||
),
|
||||
button_widget(
|
||||
id="unban-btn-confirm",
|
||||
text="action_unban", # keep it (a18n)
|
||||
color="success",
|
||||
size="normal",
|
||||
attrs={"data-unban": ""},
|
||||
),
|
||||
]
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
]
|
||||
),
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def bans_add() -> dict:
|
||||
|
||||
bans_add_table_actions = [
|
||||
# Need to create a script on Page.vue level to add a row on click
|
||||
# + We need to retrieve from the first item a schema to add any new row
|
||||
button_widget(
|
||||
id="add-bans-entry-btn",
|
||||
type="button",
|
||||
text="action_entry", # keep it (a18n)
|
||||
color="success",
|
||||
iconColor="white",
|
||||
iconName="plus",
|
||||
size="sm",
|
||||
attrs={"data-add-row": ""}, # we will use this attrs to add a new row
|
||||
),
|
||||
# Need to create a script on Page.vue level to delete all rows
|
||||
button_widget(
|
||||
id="add-bans-delete-all-btn",
|
||||
type="button",
|
||||
text="action_delete_all", # keep it (a18n)
|
||||
color="error",
|
||||
iconColor="white",
|
||||
iconName="trash",
|
||||
size="sm",
|
||||
attrs={"data-delete-all": ""}, # we will use this attrs to add a new row
|
||||
),
|
||||
]
|
||||
|
||||
bans_add_columns = [
|
||||
add_column(title="IP", field="ip", formatter="fields"),
|
||||
add_column(title="Ban end", field="ban_end", formatter="fields"),
|
||||
add_column(title="delete", field="delete", formatter="buttongroup", maxWidth=100),
|
||||
]
|
||||
|
||||
default_add_ban = [
|
||||
{
|
||||
"id": 1,
|
||||
"ip": get_fields_from_field(
|
||||
datepicker_widget(
|
||||
id="datepicker-add-ban-ip-1",
|
||||
name="datepicker-add-ban-ip-1",
|
||||
label="bans_add_ban_ip", # keep it (a18n)
|
||||
hideLabel=True,
|
||||
value="",
|
||||
columns={"pc": 12, "tablet": 12, "mobile": 12},
|
||||
)
|
||||
),
|
||||
"ban_end": get_fields_from_field(
|
||||
datepicker_widget(
|
||||
id="datepicker-add-ban-end-1",
|
||||
name="datepicker-add-ban-end-1",
|
||||
label="bans_add_end_date", # keep it (a18n)
|
||||
hideLabel=True,
|
||||
value="",
|
||||
)
|
||||
),
|
||||
# Need to create a script on Page.vue level to retrive table data and remove by id
|
||||
"delete": button_group_widget(
|
||||
buttons=[
|
||||
button_widget(
|
||||
id="delete-ban-1",
|
||||
type="button",
|
||||
text="action_delete", # keep it (a18n)
|
||||
hideText=True,
|
||||
iconName="trash",
|
||||
iconColor="white",
|
||||
color="error",
|
||||
size="normal",
|
||||
attrs={"data-delete-row": "1"}, # we will use this attrs to remove the row
|
||||
),
|
||||
]
|
||||
)["data"],
|
||||
}
|
||||
]
|
||||
|
||||
add_ban_action = button_group_widget(
|
||||
buttons=[
|
||||
button_widget(
|
||||
id="add-bans-btn",
|
||||
type="button",
|
||||
text="action_save", # keep it (a18n)
|
||||
color="success",
|
||||
size="normal",
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
return {
|
||||
"type": "card",
|
||||
"display": ["main", 2],
|
||||
"widgets": [
|
||||
title_widget("bans_add_title"), # keep it (a18n)
|
||||
subtitle_widget("bans_add_subtitle"), # keep it (a18n)
|
||||
tabulator_widget(
|
||||
id="table-register-plugins", columns=bans_add_columns, items=default_add_ban, layout="fitColumns", actionsButtons=bans_add_table_actions
|
||||
),
|
||||
add_ban_action,
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def bans_builder(bans: Optional[list] = None, reasons: Optional[list] = None, remains: Optional[list] = None) -> list:
|
||||
return [
|
||||
# Tabs is button group with display value and a size tab inside a tabs container
|
||||
bans_tabs(),
|
||||
bans_list(bans=bans, reasons=reasons, remains=remains),
|
||||
bans_add(),
|
||||
]
|
||||
|
|
@ -1,297 +0,0 @@
|
|||
from .utils.widgets import button_widget, button_group_widget, title_widget, text_widget, tabulator_widget, datepicker_widget
|
||||
from .utils.table import add_column
|
||||
from .utils.format import get_fields_from_field
|
||||
from typing import Optional
|
||||
|
||||
bans_columns = [
|
||||
add_column(title="IP", field="ip", formatter="text"),
|
||||
add_column(title="Reason", field="reason", formatter="text"),
|
||||
add_column(title="Ban start date", field="ban_start_date", formatter="fields"),
|
||||
add_column(title="Ban end date", field="ban_end_date", formatter="fields"),
|
||||
add_column(title="Remain", field="remain", formatter="text"),
|
||||
]
|
||||
|
||||
|
||||
def bans_filters(reasons: Optional[list] = None, remains: Optional[list] = None) -> list:
|
||||
|
||||
filters = [
|
||||
{
|
||||
"type": "like",
|
||||
"fields": ["ip"],
|
||||
"setting": {
|
||||
"id": "input-search-ip",
|
||||
"name": "input-search-ip",
|
||||
"label": "bans_search_ip", # keep it (a18n)
|
||||
"value": "",
|
||||
"inpType": "input",
|
||||
"columns": {"pc": 3, "tablet": 4, "mobile": 12},
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
# Case "all" ans
|
||||
if reasons is not None and len(reasons) >= 2:
|
||||
filters.append(
|
||||
{
|
||||
"type": "=",
|
||||
"fields": ["reason"],
|
||||
"setting": {
|
||||
"id": "select-ban-reason",
|
||||
"name": "select-ban-reason",
|
||||
"label": "bans_select_reason", # keep it (a18n)
|
||||
"value": "all", # keep "all"
|
||||
"values": ["all"] + reasons, # keep "all" and add your reasons dynamically
|
||||
"inpType": "select",
|
||||
"onlyDown": True,
|
||||
"columns": {"pc": 3, "tablet": 4, "mobile": 12},
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
if remains is not None and len(remains) >= 2:
|
||||
filters.append(
|
||||
{
|
||||
"type": "=",
|
||||
"fields": ["remain"],
|
||||
"setting": {
|
||||
"id": "select-ban-remain",
|
||||
"name": "select-ban-remain",
|
||||
"label": "bans_select_remain", # keep it (a18n)
|
||||
"value": "all", # keep "all"
|
||||
"values": ["all"] + remains, # keep everything and format bans to fit in one remain category
|
||||
"inpType": "select",
|
||||
"onlyDown": True,
|
||||
"columns": {"pc": 3, "tablet": 4, "mobile": 12},
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
return filters
|
||||
|
||||
|
||||
def ban_item(id: str, ip: str, reason: str, ban_start_date: int, ban_end_date: int, remain: str) -> dict:
|
||||
return (
|
||||
{
|
||||
"ip": text_widget(text=ip)["data"],
|
||||
"reason": text_widget(text=reason)["data"],
|
||||
"ban_start_date": get_fields_from_field(
|
||||
datepicker_widget(
|
||||
id=f"datepicker-ban-start-{id}",
|
||||
name=f"datepicker-ban-start-{id}",
|
||||
label="bans_ban_start_date", # keep it (a18n)
|
||||
hideLabel=True,
|
||||
value=ban_start_date,
|
||||
disabled=True, # Readonly
|
||||
columns={"pc": 12, "tablet": 12, "mobile": 12},
|
||||
)
|
||||
),
|
||||
"ban_end_date": get_fields_from_field(
|
||||
datepicker_widget(
|
||||
id=f"datepicker-ban-end-{id}",
|
||||
name=f"datepicker-ban-end-{id}",
|
||||
label="bans_ban_end_date", # keep it (a18n)
|
||||
hideLabel=True,
|
||||
value=ban_end_date,
|
||||
disabled=True, # Readonly
|
||||
)
|
||||
),
|
||||
"remain": text_widget(text=remain)["data"],
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def bans_items(items: list) -> list:
|
||||
items = []
|
||||
for index, item in enumerate(items):
|
||||
items.append(
|
||||
ban_item(
|
||||
id=index,
|
||||
ip=item.get("ip"),
|
||||
reason=item.get("reason"),
|
||||
ban_start_date=item.get("ban_start_date"),
|
||||
ban_end_date=item.get("ban_end_date"),
|
||||
remain=item.get("remain"),
|
||||
)
|
||||
)
|
||||
|
||||
return items
|
||||
|
||||
|
||||
bans_add_columns = [
|
||||
add_column(title="IP", field="ip", formatter="fields"),
|
||||
add_column(title="Ban end", field="ban_end", formatter="fields"),
|
||||
]
|
||||
|
||||
|
||||
default_add_ban = [
|
||||
{
|
||||
"id": 1,
|
||||
"ip": get_fields_from_field(
|
||||
datepicker_widget(
|
||||
id="datepicker-add-ban-ip-1",
|
||||
name="datepicker-add-ban-ip-1",
|
||||
label="bans_add_ban_ip", # keep it (a18n)
|
||||
hideLabel=True,
|
||||
value="",
|
||||
columns={"pc": 12, "tablet": 12, "mobile": 12},
|
||||
)
|
||||
),
|
||||
"ban_end": get_fields_from_field(
|
||||
datepicker_widget(
|
||||
id="datepicker-add-ban-end-1",
|
||||
name="datepicker-add-ban-end-1",
|
||||
label="bans_add_end_date", # keep it (a18n)
|
||||
hideLabel=True,
|
||||
value="",
|
||||
)
|
||||
),
|
||||
# Need to create a script on Page.vue level to retrive table data and remove by id
|
||||
"delete": button_group_widget(
|
||||
buttons=[
|
||||
button_widget(
|
||||
id="delete-ban-1",
|
||||
type="button",
|
||||
text="action_delete", # keep it (a18n)
|
||||
hideText=True,
|
||||
iconName="trash",
|
||||
iconColor="white",
|
||||
color="error",
|
||||
size="normal",
|
||||
attrs={"data-delete-row": "1"}, # we will use this attrs to remove the row
|
||||
),
|
||||
]
|
||||
),
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
bans_add_table_actions = button_group_widget(
|
||||
buttons=[
|
||||
# Need to create a script on Page.vue level to add a row on click
|
||||
# + We need to retrieve from the first item a schema to add any new row
|
||||
button_widget(
|
||||
id="add-bans-entry-btn",
|
||||
type="button",
|
||||
text="action_entry", # keep it (a18n)
|
||||
color="success",
|
||||
iconColor="white",
|
||||
iconName="plus",
|
||||
size="normal",
|
||||
attrs={"data-add-row": ""}, # we will use this attrs to add a new row
|
||||
),
|
||||
# Need to create a script on Page.vue level to delete all rows
|
||||
button_widget(
|
||||
id="add-bans-delete-all-btn",
|
||||
type="button",
|
||||
text="action_delete_all", # keep it (a18n)
|
||||
color="error",
|
||||
iconColor="white",
|
||||
iconName="trash",
|
||||
size="normal",
|
||||
attrs={"data-delete-all": ""}, # we will use this attrs to add a new row
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
# Need to create a script on Page.vue level to handle the unban form submission
|
||||
# Need to retrieve table data, format it to send to the server
|
||||
# We need to execute only when modal confirm is click (id="unban-btn-confirm")
|
||||
unban_action = (
|
||||
button_widget(
|
||||
id="unban-btn",
|
||||
type="button",
|
||||
text="action_unban", # keep it (a18n)
|
||||
color="success",
|
||||
size="normal",
|
||||
modal={
|
||||
"widgets": [
|
||||
title_widget(title="bans_unban_title"), # keep it (a18n)
|
||||
text_widget(text="bans_unban_subtitle"), # keep it (a18n)
|
||||
button_group_widget(
|
||||
buttons=[
|
||||
button_widget(
|
||||
id="close-unban-btn",
|
||||
text="action_close", # keep it (a18n)
|
||||
color="close",
|
||||
size="normal",
|
||||
attrs={"data-close-modal": ""}, # a11y
|
||||
)["data"],
|
||||
button_widget(
|
||||
id="unban-btn-confirm",
|
||||
text="action_unban", # keep it (a18n)
|
||||
color="success",
|
||||
size="normal",
|
||||
)["data"],
|
||||
]
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
# Need to create a script on Page.vue level to handle the form submission
|
||||
# Need to retrieve table data, format it to send to the serve
|
||||
add_ban_action = (
|
||||
button_widget(
|
||||
id="add-bans-btn",
|
||||
type="button",
|
||||
text="action_add_bans", # keep it (a18n)
|
||||
color="success",
|
||||
size="normal",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def bans_tabs():
|
||||
return [
|
||||
button_widget(
|
||||
text="bans_tab_list",
|
||||
display=["main", 1],
|
||||
size="tab",
|
||||
iconColor="white",
|
||||
iconName="list",
|
||||
),
|
||||
button_widget(
|
||||
text="bans_tab_add",
|
||||
display=["main", 2],
|
||||
size="tab",
|
||||
iconColor="white",
|
||||
iconName="plus",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def bans_builder(bans: list, reasons: list, remains: list) -> list:
|
||||
return [
|
||||
# Tabs is button group with display value and a size tab inside a tabs container
|
||||
{
|
||||
"type": "tabs",
|
||||
"widgets": [button_group_widget(buttons=bans_tabs())],
|
||||
},
|
||||
{
|
||||
"type": "card",
|
||||
"display": ["main", 1],
|
||||
"widgets": [
|
||||
tabulator_widget(
|
||||
id="table-bans-list",
|
||||
columns=bans_columns,
|
||||
items=bans_items(bans),
|
||||
filters=bans_filters(reasons=reasons, remains=remains),
|
||||
),
|
||||
unban_action,
|
||||
],
|
||||
},
|
||||
{
|
||||
"type": "card",
|
||||
"display": ["main", 2],
|
||||
"widgets": [
|
||||
bans_add_table_actions,
|
||||
tabulator_widget(
|
||||
id="table-register-plugins",
|
||||
columns=bans_add_columns,
|
||||
items=default_add_ban,
|
||||
),
|
||||
add_ban_action,
|
||||
],
|
||||
},
|
||||
]
|
||||
|
|
@ -168,7 +168,7 @@ def reports_builder(
|
|||
reports: list, reasons: Optional[list] = None, countries: Optional[list] = None, methods: Optional[list] = None, codes: Optional[list] = None
|
||||
) -> str:
|
||||
|
||||
if reasons is None or len(reasons) == 0:
|
||||
if reports is None or len(reports) == 0:
|
||||
return {
|
||||
"type": "card",
|
||||
"gridLayoutClass": "transparent",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
def add_column(title, field, formatter="", minWidth=None):
|
||||
def add_column(title, field, formatter="", minWidth=None, maxWidth=None, visible=None):
|
||||
|
||||
col = {"title": title, "field": field}
|
||||
|
||||
|
|
@ -8,4 +8,10 @@ def add_column(title, field, formatter="", minWidth=None):
|
|||
if minWidth:
|
||||
col["minWidth"] = minWidth
|
||||
|
||||
if maxWidth:
|
||||
col["maxWidth"] = maxWidth
|
||||
|
||||
if visible is not None:
|
||||
col["visible"] = visible
|
||||
|
||||
return col
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
from utils import save_builder
|
||||
from pages.bans2 import bans_builder
|
||||
from pages.bans import bans_builder
|
||||
|
||||
bans = [
|
||||
{
|
||||
|
|
@ -30,4 +30,4 @@ remains = ["all", "hour(s)", "day(s)"]
|
|||
|
||||
builder = bans_builder(bans, reasons, remains)
|
||||
|
||||
save_builder("bans2", builder)
|
||||
save_builder(page_name="bans", output=builder, script_name="bans")
|
||||
|
|
@ -2,10 +2,12 @@
|
|||
// Containers
|
||||
import Grid from "@components/Widget/Grid.vue";
|
||||
import GridLayout from "@components/Widget/GridLayout.vue";
|
||||
import Tabulator from "@components/Widget/Tabulator.vue";
|
||||
import Button from "@components/Widget/Button.vue";
|
||||
import ButtonGroup from "@components/Widget/ButtonGroup.vue";
|
||||
import Regular from "@components/Form/Regular.vue";
|
||||
import Title from "@components/Widget/Title.vue";
|
||||
import Subtitle from "@components/Widget/Subtitle.vue";
|
||||
import Table from "@components/Widget/Table.vue";
|
||||
import ListPairs from "@components/List/Pairs.vue";
|
||||
import MessageUnmatch from "@components/Message/Unmatch.vue";
|
||||
import { useEqualStr } from "@utils/global.js";
|
||||
|
||||
|
|
@ -53,18 +55,29 @@ const props = defineProps({
|
|||
<Grid>
|
||||
<!-- widget element -->
|
||||
<template v-for="(widget, index) in container.widgets" :key="index">
|
||||
<MessageUnmatch
|
||||
v-if="useEqualStr(widget.type, 'MessageUnmatch')"
|
||||
v-bind="widget.data"
|
||||
/>
|
||||
<Title v-if="useEqualStr(widget.type, 'Title')" v-bind="widget.data" />
|
||||
<Subtitle
|
||||
v-if="useEqualStr(widget.type, 'Subtitle')"
|
||||
v-bind="widget.data"
|
||||
/>
|
||||
<Table v-if="useEqualStr(widget.type, 'Table')" v-bind="widget.data" />
|
||||
<ListPairs
|
||||
v-if="useEqualStr(widget.type, 'ListPairs')"
|
||||
<MessageUnmatch
|
||||
v-if="useEqualStr(widget.type, 'MessageUnmatch')"
|
||||
v-bind="widget.data"
|
||||
/>
|
||||
<Tabulator
|
||||
v-if="useEqualStr(widget.type, 'Tabulator')"
|
||||
v-bind="widget.data"
|
||||
/>
|
||||
<Button
|
||||
v-if="useEqualStr(widget.type, 'Button')"
|
||||
v-bind="widget.data"
|
||||
/>
|
||||
<Regular
|
||||
v-if="useEqualStr(widget.type, 'Regular')"
|
||||
v-bind="widget.data"
|
||||
/>
|
||||
<ButtonGroup
|
||||
v-if="useEqualStr(widget.type, 'ButtonGroup')"
|
||||
v-bind="widget.data"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
|||
58
src/ui/client/dashboard/components/Icons/Uncheck.vue
Normal file
58
src/ui/client/dashboard/components/Icons/Uncheck.vue
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
<script setup>
|
||||
import { defineProps, reactive } from "vue";
|
||||
/**
|
||||
* @name Icons/Uncheck.vue
|
||||
* @description This component is a svg icon representing uncheck.
|
||||
* @example
|
||||
* {
|
||||
* color: 'info',
|
||||
* }
|
||||
* @param {String} [iconClass="icon-default"] - The class of the icon.
|
||||
* @param {Any} [value=""] - Attach a value to icon. Useful on some cases like table filtering using icons.
|
||||
* @param {String} [color="dark"] - The color of the icon between some tailwind css available colors (purple, green, red, orange, blue, yellow, gray, dark, amber, emerald, teal, indigo, cyan, sky, pink...). Darker colors are also available using the base color and adding '-darker' (e.g. 'red-darker').
|
||||
* @param {Boolean} [disabled=false] - If true, the icon will be disabled.
|
||||
*/
|
||||
|
||||
const props = defineProps({
|
||||
iconClass: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "icon-default",
|
||||
},
|
||||
value: {
|
||||
type: [String, Number],
|
||||
required: false,
|
||||
default: "",
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "dark",
|
||||
},
|
||||
disabled: { type: Boolean, required: false, default: false },
|
||||
});
|
||||
|
||||
const icon = reactive({
|
||||
color: props.color || "dark",
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<svg
|
||||
:data-color="icon.color"
|
||||
:data-value="props.value"
|
||||
:aria-disabled="props.disabled ? 'true' : 'false'"
|
||||
data-svg="uncheck"
|
||||
role="img"
|
||||
aria-hidden="true"
|
||||
:class="[props.iconClass, icon.color, 'fill dark:brightness-[125%]']"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25Zm3 10.5a.75.75 0 0 0 0-1.5H9a.75.75 0 0 0 0 1.5h6Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
|
@ -37,6 +37,7 @@ import Close from "@components/Icons/Close.vue";
|
|||
import Pen from "@components/Icons/Pen.vue";
|
||||
import Document from "@components/Icons/Document.vue";
|
||||
import Eye from "@components/Icons/Eye.vue";
|
||||
import Uncheck from "@components/Icons/Uncheck.vue";
|
||||
|
||||
/**
|
||||
* @name Widget/Icons.vue
|
||||
|
|
@ -110,6 +111,7 @@ onMounted(() => {
|
|||
v-bind="icon"
|
||||
/>
|
||||
<Box v-if="useEqualStr(props.iconName, 'box')" v-bind="icon" />
|
||||
<Uncheck v-if="useEqualStr(props.iconName, 'uncheck')" v-bind="icon" />
|
||||
<Carton v-if="useEqualStr(props.iconName, 'carton')" v-bind="icon" />
|
||||
<Core v-if="useEqualStr(props.iconName, 'core')" v-bind="icon" />
|
||||
<External v-if="useEqualStr(props.iconName, 'external')" v-bind="icon" />
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ const tableStore = useTableStore();
|
|||
* @param {array} [filters=[]] - List of filters to display
|
||||
* @param {array} columns - List of columns to display
|
||||
* @param {array} items - List of items to display
|
||||
* @param {array} [actionsButtons=[]] - Buttons group props to render buttons that will be after filters and before the table stick left.
|
||||
* @param {string} [layout="fitDataTable"] - Layout of the table. "fitDataTable" useful with wide columns, "fitColumns" useful with narrow columns.
|
||||
* @param {number} [rowHeight= 0] - Case value is 0, this will be ignored.
|
||||
* @param {number} [colMinWidth=150] - Minimum width for each col of a row
|
||||
* @param {number} [colMaxWidth=0] - Maximum width for each col of a row. Case value is 0, this will be ignored.
|
||||
|
|
@ -85,6 +87,16 @@ const props = defineProps({
|
|||
required: true,
|
||||
default: [],
|
||||
},
|
||||
actionsButtons: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: [],
|
||||
},
|
||||
layout: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "fitDataTable",
|
||||
},
|
||||
rowHeight: {
|
||||
type: Number,
|
||||
required: false,
|
||||
|
|
@ -138,7 +150,7 @@ const table = reactive({
|
|||
autoResize: true, // prevent auto resizing of table
|
||||
resizableRows: true, // this option takes a boolean value (default = false)
|
||||
resizableColumnFit: true, //maintain the fit of columns when resizing
|
||||
layout: "fitDataTable",
|
||||
layout: props.layout,
|
||||
placeholder: "No Data Available", //display message to user on empty table
|
||||
};
|
||||
|
||||
|
|
@ -253,41 +265,49 @@ onUnmounted(() => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<Container :containerClass="'layout-settings'">
|
||||
<template v-for="filter in props.filters">
|
||||
<Fields
|
||||
:setting="filter.setting"
|
||||
@inp="(value) => filterTable(filter, value)"
|
||||
/>
|
||||
<div data-is="table" class="layout-table">
|
||||
<Container
|
||||
v-if="props.filters.length"
|
||||
:containerClass="'layout-table-settings'"
|
||||
>
|
||||
<template v-for="filter in props.filters">
|
||||
<Fields
|
||||
:setting="filter.setting"
|
||||
@inp="(value) => filterTable(filter, value)"
|
||||
/>
|
||||
</template>
|
||||
</Container>
|
||||
<ButtonGroup
|
||||
v-if="props.actionsButtons.length"
|
||||
:buttons="props.actionsButtons"
|
||||
/>
|
||||
<div :class="[props.isStriped ? 'striped' : '']" ref="tableEl"></div>
|
||||
<template
|
||||
:key="table.customComponents"
|
||||
v-for="comp in table.customComponents"
|
||||
>
|
||||
<Teleport :to="comp.elDOM">
|
||||
<Icons
|
||||
v-if="useEqualStr(comp.type, 'Icons')"
|
||||
v-bind="{ ...comp.values }"
|
||||
/>
|
||||
<Text
|
||||
v-if="useEqualStr(comp.type, 'Text')"
|
||||
v-bind="{ ...comp.values }"
|
||||
/>
|
||||
<Fields
|
||||
v-if="useEqualStr(comp.type, 'Fields')"
|
||||
v-bind="{ ...comp.values }"
|
||||
/>
|
||||
<Button
|
||||
v-if="useEqualStr(comp.type, 'Button')"
|
||||
v-bind="{ ...comp.values }"
|
||||
/>
|
||||
<ButtonGroup
|
||||
v-if="useEqualStr(comp.type, 'ButtonGroup')"
|
||||
v-bind="{ ...comp.values }"
|
||||
/>
|
||||
</Teleport>
|
||||
</template>
|
||||
</Container>
|
||||
<div
|
||||
:class="[props.isStriped ? 'striped' : '']"
|
||||
data-is="table"
|
||||
ref="tableEl"
|
||||
></div>
|
||||
<template
|
||||
:key="table.customComponents"
|
||||
v-for="comp in table.customComponents"
|
||||
>
|
||||
<Teleport :to="comp.elDOM">
|
||||
<Icons
|
||||
v-if="useEqualStr(comp.type, 'Icons')"
|
||||
v-bind="{ ...comp.values }"
|
||||
/>
|
||||
<Text v-if="useEqualStr(comp.type, 'Text')" v-bind="{ ...comp.values }" />
|
||||
<Fields
|
||||
v-if="useEqualStr(comp.type, 'Fields')"
|
||||
v-bind="{ ...comp.values }"
|
||||
/>
|
||||
<Button
|
||||
v-if="useEqualStr(comp.type, 'Button')"
|
||||
v-bind="{ ...comp.values }"
|
||||
/>
|
||||
<ButtonGroup
|
||||
v-if="useEqualStr(comp.type, 'ButtonGroup')"
|
||||
v-bind="{ ...comp.values }"
|
||||
/>
|
||||
</Teleport>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -164,9 +164,13 @@
|
|||
"action_restart": "restart {name}",
|
||||
"action_upload": "upload {name}",
|
||||
"action_delete_all": "delete all {name}",
|
||||
"action_select_all": "select all {name}",
|
||||
"action_unselect_all": "unselect all {name}",
|
||||
"action_previous": "previous",
|
||||
"action_next": "next",
|
||||
"action_toggle": "toggle {name}",
|
||||
"action_unban": "unban {name}",
|
||||
"action_entry": "entry {name}",
|
||||
"home_version": "version",
|
||||
"home_all_features_available": "all features are available",
|
||||
"home_awaiting_compliance": "awaiting compliance",
|
||||
|
|
@ -256,21 +260,26 @@
|
|||
"reports_select_method_desc": "Method is the http method of the request.",
|
||||
"reports_select_code": "Select code",
|
||||
"reports_select_code_desc": "Code is the http status code returned by the request.",
|
||||
"bans_search": "Search bans",
|
||||
"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": "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",
|
||||
"bans_not_found": "No bans found",
|
||||
"bans_list_title": "Bans",
|
||||
"bans_list_subtitle": "List of bans catch by BunkerWeb.",
|
||||
"bans_unban_title": "Unban",
|
||||
"bans_unban_subtitle": "Are you sure to unban selected IP(s) ?",
|
||||
"bans_add_ban_ip": "Ip address to ban",
|
||||
"bans_add_end_date": "Define unban date",
|
||||
"bans_tab_list": "Bans",
|
||||
"bans_add_title": "Add ban",
|
||||
"bans_add_subtitle": "Manually add a ban.",
|
||||
"bans_tab_add": "Add ban",
|
||||
"bans_ban_check": "select ban",
|
||||
"bans_ban_start_date": "Ban date.",
|
||||
"bans_ban_end_date": "Unban date.",
|
||||
"bans_search_ip": "Search ip",
|
||||
"bans_search_ip_desc": "Search within ip address matching keyword.",
|
||||
"bans_select_reason": "Select reason",
|
||||
"bans_select_reason_desc": "Reason is the plugin that triggered the ban.",
|
||||
"bans_select_remain": "Select remain",
|
||||
"bans_select_remain_desc": "Scale of remaining time before unban.",
|
||||
"services_new": "new service",
|
||||
"services_title": "Services",
|
||||
"services_table_name": "Name",
|
||||
|
|
|
|||
|
|
@ -2,13 +2,17 @@
|
|||
import { reactive, onBeforeMount, onMounted } from "vue";
|
||||
import DashboardLayout from "@components/Dashboard/Layout.vue";
|
||||
import BuilderBans from "@components/Builder/Bans.vue";
|
||||
import { useGlobal } from "@utils/global";
|
||||
import { useGlobal } from "@utils/global.js";
|
||||
import { useDisplayStore } from "@store/global.js";
|
||||
|
||||
/**
|
||||
* @name Page/Bans.vue
|
||||
* @description This component is the ban page.
|
||||
This page displays global information about bans, and allow to delete or upload some bans.
|
||||
*/
|
||||
* @name Page/Bans.vue
|
||||
* @description This component is the bans page.
|
||||
*/
|
||||
|
||||
// Set default store
|
||||
const displayStore = useDisplayStore();
|
||||
displayStore.setDisplay("main", 1);
|
||||
|
||||
const bans = reactive({
|
||||
builder: "",
|
||||
|
|
@ -20,688 +24,19 @@ onBeforeMount(() => {
|
|||
const dataEl = document.querySelector(`[${dataAtt}]`);
|
||||
const data =
|
||||
dataEl && !dataEl.getAttribute(dataAtt).includes(dataAtt)
|
||||
? JSON.parse(dataEl.getAttribute(dataAtt))
|
||||
? JSON.parse(atob(dataEl.getAttribute(dataAtt)))
|
||||
: {};
|
||||
bans.builder = data;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
// Set the page title
|
||||
useGlobal();
|
||||
});
|
||||
|
||||
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>
|
||||
<DashboardLayout>
|
||||
<BuilderBans v-if="builder" :builder="builder" />
|
||||
<BuilderBans v-if="bans.builder" :builder="bans.builder" />
|
||||
</DashboardLayout>
|
||||
</template>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -20,7 +20,7 @@
|
|||
></div>
|
||||
<div
|
||||
class="hidden"
|
||||
data-server-builder='W3sidHlwZSI6ICJjYXJkIiwgIndpZGdldHMiOiBbeyJ0eXBlIjogIlRpdGxlIiwgImRhdGEiOiB7InRpdGxlIjogInJlcG9ydHNfdGl0bGUifX0sIHsidHlwZSI6ICJTdWJ0aXRsZSIsICJkYXRhIjogeyJzdWJ0aXRsZSI6ICJyZXBvcnRzX3N1YnRpdGxlIn19LCB7InR5cGUiOiAiVGFidWxhdG9yIiwgImRhdGEiOiB7ImlkIjogInRhYmxlLWNvcmUtcGx1Z2lucyIsICJjb2x1bW5zIjogW3sidGl0bGUiOiAiRGF0ZSIsICJmaWVsZCI6ICJkYXRlIiwgImZvcm1hdHRlciI6ICJmaWVsZHMiLCAibWluV2lkdGgiOiAyNTB9LCB7InRpdGxlIjogIklQIiwgImZpZWxkIjogImlwIiwgImZvcm1hdHRlciI6ICJ0ZXh0In0sIHsidGl0bGUiOiAiQ291bnRyeSIsICJmaWVsZCI6ICJjb3VudHJ5IiwgImZvcm1hdHRlciI6ICJ0ZXh0In0sIHsidGl0bGUiOiAiU2VydmVyIG5hbWUiLCAiZmllbGQiOiAic2VydmVyX25hbWUiLCAiZm9ybWF0dGVyIjogInRleHQifSwgeyJ0aXRsZSI6ICJNZXRob2QiLCAiZmllbGQiOiAibWV0aG9kIiwgImZvcm1hdHRlciI6ICJ0ZXh0In0sIHsidGl0bGUiOiAiVVJMIiwgImZpZWxkIjogInVybCIsICJmb3JtYXR0ZXIiOiAidGV4dCJ9LCB7InRpdGxlIjogIkNvZGUiLCAiZmllbGQiOiAiY29kZSIsICJmb3JtYXR0ZXIiOiAidGV4dCJ9LCB7InRpdGxlIjogIlVzZXIgYWdlbnQiLCAiZmllbGQiOiAidXNlcl9hZ2VudCIsICJmb3JtYXR0ZXIiOiAidGV4dCJ9LCB7InRpdGxlIjogIlJlYXNvbiIsICJmaWVsZCI6ICJyZWFzb24iLCAiZm9ybWF0dGVyIjogInRleHQifSwgeyJ0aXRsZSI6ICJEYXRhIiwgImZpZWxkIjogImRhdGEiLCAiZm9ybWF0dGVyIjogInRleHQifV0sICJpdGVtcyI6IFtdLCAiZmlsdGVycyI6IFt7InR5cGUiOiAibGlrZSIsICJmaWVsZHMiOiBbImlwIiwgInVybCIsICJ1c2VyX2FnZW50IiwgImRhdGEiXSwgInNldHRpbmciOiB7ImlkIjogImlucHV0LXNlYXJjaC1taXNjIiwgIm5hbWUiOiAiaW5wdXQtc2VhcmNoLW1pc2MiLCAibGFiZWwiOiAicmVwb3J0c19zZWFyY2hfbWlzYyIsICJ2YWx1ZSI6ICIiLCAiaW5wVHlwZSI6ICJpbnB1dCIsICJjb2x1bW5zIjogeyJwYyI6IDMsICJ0YWJsZXQiOiA0LCAibW9iaWxlIjogMTJ9LCAicG9wb3ZlcnMiOiBbeyJpY29uTmFtZSI6ICJpbmZvIiwgInRleHQiOiAicmVwb3J0c19zZWFyY2hfbWlzY19kZXNjIn1dfX0sIHsidHlwZSI6ICI9IiwgImZpZWxkcyI6IFsicmVhc29uIl0sICJzZXR0aW5nIjogeyJpZCI6ICJzZWxlY3QtcmVhc29uIiwgIm5hbWUiOiAic2VsZWN0LXJlYXNvbiIsICJsYWJlbCI6ICJyZXBvcnRzX3NlbGVjdF9yZWFzb24iLCAidmFsdWUiOiAiYWxsIiwgInZhbHVlcyI6IFsiYWxsIiwgImFudGlib3QiLCAidW5rbm93biJdLCAiaW5wVHlwZSI6ICJzZWxlY3QiLCAib25seURvd24iOiB0cnVlLCAiY29sdW1ucyI6IHsicGMiOiAzLCAidGFibGV0IjogNCwgIm1vYmlsZSI6IDEyfSwgInBvcG92ZXJzIjogW3siaWNvbk5hbWUiOiAiaW5mbyIsICJ0ZXh0IjogInJlcG9ydHNfc2VsZWN0X3JlYXNvbl9kZXNjIn1dfX0sIHsidHlwZSI6ICI9IiwgImZpZWxkcyI6IFsibWV0aG9kIl0sICJzZXR0aW5nIjogeyJpZCI6ICJzZWxlY3QtbWV0aG9kIiwgIm5hbWUiOiAic2VsZWN0LW1ldGhvZCIsICJsYWJlbCI6ICJyZXBvcnRzX3NlbGVjdF9tZXRob2QiLCAidmFsdWUiOiAiYWxsIiwgInZhbHVlcyI6IFsiYWxsIiwgIlBPU1QiLCAiR0VUIl0sICJpbnBUeXBlIjogInNlbGVjdCIsICJvbmx5RG93biI6IHRydWUsICJjb2x1bW5zIjogeyJwYyI6IDMsICJ0YWJsZXQiOiA0LCAibW9iaWxlIjogMTJ9LCAicG9wb3ZlcnMiOiBbeyJpY29uTmFtZSI6ICJpbmZvIiwgInRleHQiOiAicmVwb3J0c19zZWxlY3RfbWV0aG9kX2Rlc2MifV19fSwgeyJ0eXBlIjogIj0iLCAiZmllbGRzIjogWyJjb2RlIl0sICJzZXR0aW5nIjogeyJpZCI6ICJzZWxlY3QtY29kZSIsICJuYW1lIjogInNlbGVjdC1jb2RlIiwgImxhYmVsIjogInJlcG9ydHNfc2VsZWN0X2NvZGUiLCAidmFsdWUiOiAiYWxsIiwgInZhbHVlcyI6IFsiYWxsIiwgIjMwMCIsICI0MDAiXSwgImlucFR5cGUiOiAic2VsZWN0IiwgIm9ubHlEb3duIjogdHJ1ZSwgImNvbHVtbnMiOiB7InBjIjogMywgInRhYmxldCI6IDQsICJtb2JpbGUiOiAxMn0sICJwb3BvdmVycyI6IFt7Imljb25OYW1lIjogImluZm8iLCAidGV4dCI6ICJyZXBvcnRzX3NlbGVjdF9jb2RlX2Rlc2MifV19fV19fV19XQ=='
|
||||
data-server-builder='W3sidHlwZSI6ICJjYXJkIiwgIndpZGdldHMiOiBbeyJ0eXBlIjogIlRpdGxlIiwgImRhdGEiOiB7InRpdGxlIjogInJlcG9ydHNfdGl0bGUifX0sIHsidHlwZSI6ICJTdWJ0aXRsZSIsICJkYXRhIjogeyJzdWJ0aXRsZSI6ICJyZXBvcnRzX3N1YnRpdGxlIn19LCB7InR5cGUiOiAiVGFidWxhdG9yIiwgImRhdGEiOiB7ImlkIjogInRhYmxlLWNvcmUtcGx1Z2lucyIsICJjb2x1bW5zIjogW3sidGl0bGUiOiAiRGF0ZSIsICJmaWVsZCI6ICJkYXRlIiwgImZvcm1hdHRlciI6ICJmaWVsZHMiLCAibWluV2lkdGgiOiAyNTB9LCB7InRpdGxlIjogIklQIiwgImZpZWxkIjogImlwIiwgImZvcm1hdHRlciI6ICJ0ZXh0In0sIHsidGl0bGUiOiAiQ291bnRyeSIsICJmaWVsZCI6ICJjb3VudHJ5IiwgImZvcm1hdHRlciI6ICJ0ZXh0In0sIHsidGl0bGUiOiAiU2VydmVyIG5hbWUiLCAiZmllbGQiOiAic2VydmVyX25hbWUiLCAiZm9ybWF0dGVyIjogInRleHQifSwgeyJ0aXRsZSI6ICJNZXRob2QiLCAiZmllbGQiOiAibWV0aG9kIiwgImZvcm1hdHRlciI6ICJ0ZXh0In0sIHsidGl0bGUiOiAiVVJMIiwgImZpZWxkIjogInVybCIsICJmb3JtYXR0ZXIiOiAidGV4dCJ9LCB7InRpdGxlIjogIkNvZGUiLCAiZmllbGQiOiAiY29kZSIsICJmb3JtYXR0ZXIiOiAidGV4dCJ9LCB7InRpdGxlIjogIlVzZXIgYWdlbnQiLCAiZmllbGQiOiAidXNlcl9hZ2VudCIsICJmb3JtYXR0ZXIiOiAidGV4dCJ9LCB7InRpdGxlIjogIlJlYXNvbiIsICJmaWVsZCI6ICJyZWFzb24iLCAiZm9ybWF0dGVyIjogInRleHQifSwgeyJ0aXRsZSI6ICJEYXRhIiwgImZpZWxkIjogImRhdGEiLCAiZm9ybWF0dGVyIjogInRleHQifV0sICJpdGVtcyI6IFt7ImRhdGUiOiB7InNldHRpbmciOiB7ImxhYmVsIjogInJlcG9ydHNfZGF0ZSIsICJuYW1lIjogImRhdGVwaWNrZXItZGF0ZS0wIiwgImlkIjogImRhdGVwaWNrZXItZGF0ZS0wIiwgInZhbHVlIjogMTcyMzQ5MTczOTk1NCwgImhpZGVMYWJlbCI6IHRydWUsICJkaXNhYmxlZCI6IHRydWUsICJpbnBUeXBlIjogImRhdGVwaWNrZXIifX0sICJzZXJ2ZXJfbmFtZSI6IHsidGV4dCI6ICJsb2NhbGhvc3QifSwgImlwIjogeyJ0ZXh0IjogIjEyNy4wLjAuMSJ9LCAiY291bnRyeSI6IHsidGV4dCI6ICJFTiJ9LCAibWV0aG9kIjogeyJ0ZXh0IjogIlBPU1QifSwgInVybCI6IHsidGV4dCI6ICIvYWRtaW4ifSwgImNvZGUiOiB7InRleHQiOiAiNDAwIn0sICJ1c2VyX2FnZW50IjogeyJ0ZXh0IjogIk1vemlsbGEvNS4wIn0sICJyZWFzb24iOiB7InRleHQiOiAiYW50aWJvdCJ9LCAiZGF0YSI6IHsidGV4dCI6ICJsb3JlIGlwc3VtIGFkIHZpdGFtIGFldGVybmFtIn19LCB7ImRhdGUiOiB7InNldHRpbmciOiB7ImxhYmVsIjogInJlcG9ydHNfZGF0ZSIsICJuYW1lIjogImRhdGVwaWNrZXItZGF0ZS0xIiwgImlkIjogImRhdGVwaWNrZXItZGF0ZS0xIiwgInZhbHVlIjogMTcyMzQ5MTczODAwMCwgImhpZGVMYWJlbCI6IHRydWUsICJkaXNhYmxlZCI6IHRydWUsICJpbnBUeXBlIjogImRhdGVwaWNrZXIifX0sICJzZXJ2ZXJfbmFtZSI6IHsidGV4dCI6ICJsb2NhbGhvc3QifSwgImlwIjogeyJ0ZXh0IjogIjEyNy4wLjAuMiJ9LCAiY291bnRyeSI6IHsidGV4dCI6ICJFTiJ9LCAibWV0aG9kIjogeyJ0ZXh0IjogIkdFVCJ9LCAidXJsIjogeyJ0ZXh0IjogIi9ldGM/In0sICJjb2RlIjogeyJ0ZXh0IjogIjMwMCJ9LCAidXNlcl9hZ2VudCI6IHsidGV4dCI6ICJNb3ppbGxhLzAuMSJ9LCAicmVhc29uIjogeyJ0ZXh0IjogInVua25vd24ifSwgImRhdGEiOiB7InRleHQiOiAiIn19XSwgImZpbHRlcnMiOiBbeyJ0eXBlIjogImxpa2UiLCAiZmllbGRzIjogWyJpcCIsICJ1cmwiLCAidXNlcl9hZ2VudCIsICJkYXRhIl0sICJzZXR0aW5nIjogeyJpZCI6ICJpbnB1dC1zZWFyY2gtbWlzYyIsICJuYW1lIjogImlucHV0LXNlYXJjaC1taXNjIiwgImxhYmVsIjogInJlcG9ydHNfc2VhcmNoX21pc2MiLCAidmFsdWUiOiAiIiwgImlucFR5cGUiOiAiaW5wdXQiLCAiY29sdW1ucyI6IHsicGMiOiAzLCAidGFibGV0IjogNCwgIm1vYmlsZSI6IDEyfSwgInBvcG92ZXJzIjogW3siaWNvbk5hbWUiOiAiaW5mbyIsICJ0ZXh0IjogInJlcG9ydHNfc2VhcmNoX21pc2NfZGVzYyJ9XX19LCB7InR5cGUiOiAiPSIsICJmaWVsZHMiOiBbInJlYXNvbiJdLCAic2V0dGluZyI6IHsiaWQiOiAic2VsZWN0LXJlYXNvbiIsICJuYW1lIjogInNlbGVjdC1yZWFzb24iLCAibGFiZWwiOiAicmVwb3J0c19zZWxlY3RfcmVhc29uIiwgInZhbHVlIjogImFsbCIsICJ2YWx1ZXMiOiBbImFsbCIsICJ1bmtub3duIiwgImFudGlib3QiXSwgImlucFR5cGUiOiAic2VsZWN0IiwgIm9ubHlEb3duIjogdHJ1ZSwgImNvbHVtbnMiOiB7InBjIjogMywgInRhYmxldCI6IDQsICJtb2JpbGUiOiAxMn0sICJwb3BvdmVycyI6IFt7Imljb25OYW1lIjogImluZm8iLCAidGV4dCI6ICJyZXBvcnRzX3NlbGVjdF9yZWFzb25fZGVzYyJ9XX19LCB7InR5cGUiOiAiPSIsICJmaWVsZHMiOiBbIm1ldGhvZCJdLCAic2V0dGluZyI6IHsiaWQiOiAic2VsZWN0LW1ldGhvZCIsICJuYW1lIjogInNlbGVjdC1tZXRob2QiLCAibGFiZWwiOiAicmVwb3J0c19zZWxlY3RfbWV0aG9kIiwgInZhbHVlIjogImFsbCIsICJ2YWx1ZXMiOiBbImFsbCIsICJQT1NUIiwgIkdFVCJdLCAiaW5wVHlwZSI6ICJzZWxlY3QiLCAib25seURvd24iOiB0cnVlLCAiY29sdW1ucyI6IHsicGMiOiAzLCAidGFibGV0IjogNCwgIm1vYmlsZSI6IDEyfSwgInBvcG92ZXJzIjogW3siaWNvbk5hbWUiOiAiaW5mbyIsICJ0ZXh0IjogInJlcG9ydHNfc2VsZWN0X21ldGhvZF9kZXNjIn1dfX0sIHsidHlwZSI6ICI9IiwgImZpZWxkcyI6IFsiY29kZSJdLCAic2V0dGluZyI6IHsiaWQiOiAic2VsZWN0LWNvZGUiLCAibmFtZSI6ICJzZWxlY3QtY29kZSIsICJsYWJlbCI6ICJyZXBvcnRzX3NlbGVjdF9jb2RlIiwgInZhbHVlIjogImFsbCIsICJ2YWx1ZXMiOiBbImFsbCIsICI0MDAiLCAiMzAwIl0sICJpbnBUeXBlIjogInNlbGVjdCIsICJvbmx5RG93biI6IHRydWUsICJjb2x1bW5zIjogeyJwYyI6IDMsICJ0YWJsZXQiOiA0LCAibW9iaWxlIjogMTJ9LCAicG9wb3ZlcnMiOiBbeyJpY29uTmFtZSI6ICJpbmZvIiwgInRleHQiOiAicmVwb3J0c19zZWxlY3RfY29kZV9kZXNjIn1dfX1dfX1dfV0='
|
||||
></div>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="reports.js"></script>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,15 @@ function addColumnsWidth(column, colMinWidth = 0, colMaxWidth = 0) {
|
|||
column.minWidth = colMinWidth;
|
||||
if (+colMaxWidth > 0 && !("maxWidth" in column))
|
||||
column.maxWidth = colMaxWidth;
|
||||
|
||||
// Check that minWidth is less than maxWidth
|
||||
if (
|
||||
"minWidth" in column &&
|
||||
"maxWidth" in column &&
|
||||
column.minWidth > column.maxWidth
|
||||
) {
|
||||
column.minWidth = column.maxWidth;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -512,6 +512,14 @@ body {
|
|||
@apply col-span-12 grid grid-cols-12 w-full relative;
|
||||
}
|
||||
|
||||
.layout-table {
|
||||
@apply py-4 col-span-12 grid grid-cols-12 w-full relative;
|
||||
}
|
||||
|
||||
.layout-table-settings {
|
||||
@apply mb-4 sm:gap-x-8 gap-y-8 col-span-12 grid grid-cols-12 w-full relative;
|
||||
}
|
||||
|
||||
.layout-card {
|
||||
@apply px-6 py-4 grid grid-cols-12 w-full overflow-visible relative transition dark:brightness-110 shadow-md bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border transform duration-300 ease-in-out;
|
||||
}
|
||||
|
|
@ -1146,6 +1154,10 @@ body {
|
|||
|
||||
/* BTN GROUP */
|
||||
|
||||
.button-group-card {
|
||||
@apply col-span-12 flex justify-center items-center;
|
||||
}
|
||||
|
||||
.button-group-content {
|
||||
@apply flex justify-center items-center mx-4;
|
||||
}
|
||||
|
|
@ -1175,7 +1187,7 @@ body {
|
|||
}
|
||||
|
||||
.button-group-table {
|
||||
@apply col-span-12 flex justify-start items-center mx-0;
|
||||
@apply mb-4 col-span-12 flex justify-start items-center mx-0;
|
||||
}
|
||||
|
||||
/* LIST COMPONENT */
|
||||
|
|
@ -4415,7 +4427,6 @@ body.tabulator-print-fullscreen-hide > *:not(.tabulator-print-fullscreen) {
|
|||
|
||||
.tabulator {
|
||||
width: 100%;
|
||||
margin: 1em 0em;
|
||||
border: 1px solid rgba(34, 36, 38, 0.15);
|
||||
box-shadow: none;
|
||||
border-radius: 0.28571rem;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue