start services page

This commit is contained in:
Jordan Blasenhauer 2024-07-29 15:42:12 +02:00
parent 312cc5a078
commit 784c231198
9 changed files with 1043 additions and 26378 deletions

View file

@ -0,0 +1,322 @@
<script setup>
// Containers
import Grid from "@components/Widget/Grid.vue";
import GridLayout from "@components/Widget/GridLayout.vue";
import Table from "@components/Widget/Table.vue";
import Title from "@components/Widget/Title.vue";
/**
@name Builder/Services.vue
@description This component is lightweight builder containing only the necessary components to create the services page.
@example
[
{
"type": "card",
"containerColumns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"widgets": [
{
"type": "Title",
"data": {
"title": "services_title"
}
},
{
"type": "Table",
"data": {
"title": "services_table_title",
"minWidth": "lg",
"header": [
"services_table_name",
"services_table_method",
"services_table_settings",
"services_table_manage",
"services_table_is_draft",
"services_table_delete"
],
"positions": [
2,
2,
2,
2,
2,
2
],
"items": [
[
{
"name": "app1.example.com",
"type": "Text",
"data": {
"text": "app1.example.com"
}
},
{
"method": "scheduler",
"type": "Text",
"data": {
"text": "scheduler"
}
},
{
"type": "Button",
"data": {
"id": "open-modal-settings-0",
"text": "settings",
"hideText": false,
" color": "info",
"size": "normal",
"iconName": "settings"
}
},
{
"type": "Button",
"data": {
"attrs": {
"data-server-name": "app1.example.com"
},
"id": "open-modal-manage-0",
"text": "manage",
"hideText": false,
" color": "green",
"size": "normal",
"iconName": "manage"
}
},
{
"type": "Button",
"data": {
"attrs": {
"data-server-name": "app1.example.com",
"data-is-draft": "no"
},
"id": "open-modal-draft-0",
"text": "online",
"hideText": false,
" color": "cyan",
"size": "normal",
"iconName": "online"
}
},
{
"type": "Button",
"data": {
"attrs": {
"data-server-name": "app1.example.com"
},
"id": "open-modal-delete-0",
"text": "delete",
"disabled": true,
"hideText": false,
" color": "red",
"size": "normal",
"iconName": "trash"
}
}
],
[
{
"name": "www.example.com",
"type": "Text",
"data": {
"text": "www.example.com"
}
},
{
"method": "scheduler",
"type": "Text",
"data": {
"text": "scheduler"
}
},
{
"type": "Button",
"data": {
"id": "open-modal-settings-1",
"text": "settings",
"hideText": false,
" color": "info",
"size": "normal",
"iconName": "settings"
}
},
{
"type": "Button",
"data": {
"attrs": {
"data-server-name": "www.example.com"
},
"id": "open-modal-manage-1",
"text": "manage",
"hideText": false,
" color": "green",
"size": "normal",
"iconName": "manage"
}
},
{
"type": "Button",
"data": {
"attrs": {
"data-server-name": "www.example.com",
"data-is-draft": "no"
},
"id": "open-modal-draft-1",
"text": "online",
"hideText": false,
" color": "cyan",
"size": "normal",
"iconName": "online"
}
},
{
"type": "Button",
"data": {
"attrs": {
"data-server-name": "www.example.com"
},
"id": "open-modal-delete-1",
"text": "delete",
"disabled": true,
"hideText": false,
" color": "red",
"size": "normal",
"iconName": "trash"
}
}
]
],
"filters": [
{
"filter": "table",
"filterName": "keyword",
"type": "keyword",
"value": "",
"keys": [
"name"
],
"field": {
"id": "services-keyword",
"value": "",
"type": "text",
"name": "services-keyword",
"label": "services_search",
"placeholder": "inp_keyword",
"isClipboard": false,
"popovers": [
{
"text": "services_search_desc",
"iconName": "info"
}
],
"columns": {
"pc": 3,
"tablet": 4,
"mobile": 12
}
}
},
{
"filter": "table",
"filterName": "method",
"type": "select",
"value": "all",
"keys": [
"method"
],
"field": {
"id": "services-methods",
"value": "all",
"values": [
"scheduler"
],
"name": "services-methods",
"onlyDown": true,
"label": "services_methods",
"popovers": [
{
"text": "services_methods_desc",
"iconName": "info"
}
],
"columns": {
"pc": 3,
"tablet": 4,
"mobile": 12
}
}
},
{
"filter": "table",
"filterName": "draft",
"type": "select",
"value": "all",
"keys": [
"draft"
],
"field": {
"id": "services-draft",
"value": "all",
"values": [
"all",
"online",
"draft"
],
"name": "services-draft",
"onlyDown": true,
"label": "services_draft",
"popovers": [
{
"text": "services_draft_desc",
"iconName": "info"
}
],
"columns": {
"pc": 3,
"tablet": 4,
"mobile": 12
}
}
}
]
}
}
]
}
]
@param {array} builder - Array of containers and widgets
*/
const props = defineProps({
builder: {
type: Array,
required: true,
},
});
</script>
<template>
<!-- top level grid (layout) -->
<GridLayout
v-for="(container, index) in props.builder"
:key="index"
:gridLayoutClass="container.containerClass"
:type="container.type"
:title="container.title"
:link="container.link"
:columns="container.containerColumns"
:id="container.id"
>
<!-- widget grid -->
<Grid>
<!-- widget element -->
<template v-for="(widget, index) in container.widgets" :key="index">
<Table v-if="widget.type === 'Table'" v-bind="widget.data" />
<Title v-if="widget.type === 'Title'" v-bind="widget.data" />
</template>
</Grid>
</GridLayout>
</template>

View file

@ -262,5 +262,18 @@
"bans_table_reason": "Reason",
"bans_table_remain": "Remain",
"bans_table_term": "Term",
"bans_table_select": "Select"
"bans_table_select": "Select",
"services_title": "Services",
"services_table_name": "Name",
"services_table_method": "Method",
"services_table_settings": "Settings",
"services_table_manage": "Manage",
"services_table_is_draft": "Draft status",
"services_table_delete": "Delete",
"services_search": "Search services",
"services_search_desc": "Search within service name",
"services_methods": "Methods",
"services_methods_desc": "Only show services of the chosen method",
"services_draft": "Draft status",
"services_draft_desc": "Only show services of the chosen draft status"
}

View file

@ -10,12 +10,14 @@
</head>
<body>
<div class="hidden" data-server-global='{"username" : "admin"}'></div>
<div class="hidden"
data-server-flash='[{"type" : "success", "title" : "title", "message" : "Success feedback"}, {"type" : "error", "title" : "title", "message" : "Error feedback"}, {"type" : "warning", "title" : "title", "message" : "Warning feedback"}, {"type" : "info", "title" : "title", "message" : "Info feedback"}]'>
</div>
<div class="hidden"
data-server-builder='[{"type":"card","containerColumns":{"pc":6,"tablet":6,"mobile":12},"widgets":[{"type":"Instance","data":{"details":[{"key":"instances_hostname","value":"bunkerweb"},{"key":"instances_type","value":"manual"},{"key":"instances_status","value":"instances_active"}],"status":"success","title":"bunkerweb","buttons":[{"attrs":{"data-form-INSTANCE_ID":"bunkerweb","data-form-operation":"reload","data-submit-form":"true"},"text":"action_reload","color":"warning","size":"normal"},{"attrs":{"data-form-INSTANCE_ID":"bunkerweb","data-form-operation":"stop","data-submit-form":"true"},"text":"action_stop","color":"error","size":"normal"}]}}]}]'>
</div>
<div
class="hidden"
data-server-flash='[{"type" : "success", "title" : "title", "message" : "Success feedback"}, {"type" : "error", "title" : "title", "message" : "Error feedback"}, {"type" : "warning", "title" : "title", "message" : "Warning feedback"}, {"type" : "info", "title" : "title", "message" : "Info feedback"}]'
></div>
<div
class="hidden"
data-server-builder="W3sidHlwZSI6ICJjYXJkIiwgImNvbnRhaW5lckNvbHVtbnMiOiB7InBjIjogMTIsICJ0YWJsZXQiOiAxMiwgIm1vYmlsZSI6IDEyfSwgIndpZGdldHMiOiBbeyJ0eXBlIjogIlRpdGxlIiwgImRhdGEiOiB7InRpdGxlIjogInNlcnZpY2VzX3RpdGxlIn19LCB7InR5cGUiOiAiVGFibGUiLCAiZGF0YSI6IHsidGl0bGUiOiAic2VydmljZXNfdGFibGVfdGl0bGUiLCAibWluV2lkdGgiOiAibGciLCAiaGVhZGVyIjogWyJzZXJ2aWNlc190YWJsZV9uYW1lIiwgInNlcnZpY2VzX3RhYmxlX21ldGhvZCIsICJzZXJ2aWNlc190YWJsZV9zZXR0aW5ncyIsICJzZXJ2aWNlc190YWJsZV9tYW5hZ2UiLCAic2VydmljZXNfdGFibGVfaXNfZHJhZnQiLCAic2VydmljZXNfdGFibGVfZGVsZXRlIl0sICJwb3NpdGlvbnMiOiBbMiwgMiwgMiwgMiwgMiwgMl0sICJpdGVtcyI6IFtbeyJuYW1lIjogImFwcDEuZXhhbXBsZS5jb20iLCAidHlwZSI6ICJUZXh0IiwgImRhdGEiOiB7InRleHQiOiAiYXBwMS5leGFtcGxlLmNvbSJ9fSwgeyJtZXRob2QiOiAic2NoZWR1bGVyIiwgInR5cGUiOiAiVGV4dCIsICJkYXRhIjogeyJ0ZXh0IjogInNjaGVkdWxlciJ9fSwgeyJ0eXBlIjogIkJ1dHRvbiIsICJkYXRhIjogeyJpZCI6ICJvcGVuLW1vZGFsLXNldHRpbmdzLTAiLCAidGV4dCI6ICJzZXR0aW5ncyIsICJoaWRlVGV4dCI6IGZhbHNlLCAiIGNvbG9yIjogImluZm8iLCAic2l6ZSI6ICJub3JtYWwiLCAiaWNvbk5hbWUiOiAic2V0dGluZ3MifX0sIHsidHlwZSI6ICJCdXR0b24iLCAiZGF0YSI6IHsiYXR0cnMiOiB7ImRhdGEtc2VydmVyLW5hbWUiOiAiYXBwMS5leGFtcGxlLmNvbSJ9LCAiaWQiOiAib3Blbi1tb2RhbC1tYW5hZ2UtMCIsICJ0ZXh0IjogIm1hbmFnZSIsICJoaWRlVGV4dCI6IGZhbHNlLCAiIGNvbG9yIjogImdyZWVuIiwgInNpemUiOiAibm9ybWFsIiwgImljb25OYW1lIjogIm1hbmFnZSJ9fSwgeyJ0eXBlIjogIkJ1dHRvbiIsICJkYXRhIjogeyJhdHRycyI6IHsiZGF0YS1zZXJ2ZXItbmFtZSI6ICJhcHAxLmV4YW1wbGUuY29tIiwgImRhdGEtaXMtZHJhZnQiOiAibm8ifSwgImlkIjogIm9wZW4tbW9kYWwtZHJhZnQtMCIsICJ0ZXh0IjogIm9ubGluZSIsICJoaWRlVGV4dCI6IGZhbHNlLCAiIGNvbG9yIjogImN5YW4iLCAic2l6ZSI6ICJub3JtYWwiLCAiaWNvbk5hbWUiOiAib25saW5lIn19LCB7InR5cGUiOiAiQnV0dG9uIiwgImRhdGEiOiB7ImF0dHJzIjogeyJkYXRhLXNlcnZlci1uYW1lIjogImFwcDEuZXhhbXBsZS5jb20ifSwgImlkIjogIm9wZW4tbW9kYWwtZGVsZXRlLTAiLCAidGV4dCI6ICJkZWxldGUiLCAiZGlzYWJsZWQiOiB0cnVlLCAiaGlkZVRleHQiOiBmYWxzZSwgIiBjb2xvciI6ICJyZWQiLCAic2l6ZSI6ICJub3JtYWwiLCAiaWNvbk5hbWUiOiAidHJhc2gifX1dLCBbeyJuYW1lIjogInd3dy5leGFtcGxlLmNvbSIsICJ0eXBlIjogIlRleHQiLCAiZGF0YSI6IHsidGV4dCI6ICJ3d3cuZXhhbXBsZS5jb20ifX0sIHsibWV0aG9kIjogInNjaGVkdWxlciIsICJ0eXBlIjogIlRleHQiLCAiZGF0YSI6IHsidGV4dCI6ICJzY2hlZHVsZXIifX0sIHsidHlwZSI6ICJCdXR0b24iLCAiZGF0YSI6IHsiaWQiOiAib3Blbi1tb2RhbC1zZXR0aW5ncy0xIiwgInRleHQiOiAic2V0dGluZ3MiLCAiaGlkZVRleHQiOiBmYWxzZSwgIiBjb2xvciI6ICJpbmZvIiwgInNpemUiOiAibm9ybWFsIiwgImljb25OYW1lIjogInNldHRpbmdzIn19LCB7InR5cGUiOiAiQnV0dG9uIiwgImRhdGEiOiB7ImF0dHJzIjogeyJkYXRhLXNlcnZlci1uYW1lIjogInd3dy5leGFtcGxlLmNvbSJ9LCAiaWQiOiAib3Blbi1tb2RhbC1tYW5hZ2UtMSIsICJ0ZXh0IjogIm1hbmFnZSIsICJoaWRlVGV4dCI6IGZhbHNlLCAiIGNvbG9yIjogImdyZWVuIiwgInNpemUiOiAibm9ybWFsIiwgImljb25OYW1lIjogIm1hbmFnZSJ9fSwgeyJ0eXBlIjogIkJ1dHRvbiIsICJkYXRhIjogeyJhdHRycyI6IHsiZGF0YS1zZXJ2ZXItbmFtZSI6ICJ3d3cuZXhhbXBsZS5jb20iLCAiZGF0YS1pcy1kcmFmdCI6ICJubyJ9LCAiaWQiOiAib3Blbi1tb2RhbC1kcmFmdC0xIiwgInRleHQiOiAib25saW5lIiwgImhpZGVUZXh0IjogZmFsc2UsICIgY29sb3IiOiAiY3lhbiIsICJzaXplIjogIm5vcm1hbCIsICJpY29uTmFtZSI6ICJvbmxpbmUifX0sIHsidHlwZSI6ICJCdXR0b24iLCAiZGF0YSI6IHsiYXR0cnMiOiB7ImRhdGEtc2VydmVyLW5hbWUiOiAid3d3LmV4YW1wbGUuY29tIn0sICJpZCI6ICJvcGVuLW1vZGFsLWRlbGV0ZS0xIiwgInRleHQiOiAiZGVsZXRlIiwgImRpc2FibGVkIjogdHJ1ZSwgImhpZGVUZXh0IjogZmFsc2UsICIgY29sb3IiOiAicmVkIiwgInNpemUiOiAibm9ybWFsIiwgImljb25OYW1lIjogInRyYXNoIn19XV0sICJmaWx0ZXJzIjogW3siZmlsdGVyIjogInRhYmxlIiwgImZpbHRlck5hbWUiOiAia2V5d29yZCIsICJ0eXBlIjogImtleXdvcmQiLCAidmFsdWUiOiAiIiwgImtleXMiOiBbIm5hbWUiXSwgImZpZWxkIjogeyJpZCI6ICJzZXJ2aWNlcy1rZXl3b3JkIiwgInZhbHVlIjogIiIsICJ0eXBlIjogInRleHQiLCAibmFtZSI6ICJzZXJ2aWNlcy1rZXl3b3JkIiwgImxhYmVsIjogInNlcnZpY2VzX3NlYXJjaCIsICJwbGFjZWhvbGRlciI6ICJpbnBfa2V5d29yZCIsICJpc0NsaXBib2FyZCI6IGZhbHNlLCAicG9wb3ZlcnMiOiBbeyJ0ZXh0IjogInNlcnZpY2VzX3NlYXJjaF9kZXNjIiwgImljb25OYW1lIjogImluZm8ifV0sICJjb2x1bW5zIjogeyJwYyI6IDMsICJ0YWJsZXQiOiA0LCAibW9iaWxlIjogMTJ9fX0sIHsiZmlsdGVyIjogInRhYmxlIiwgImZpbHRlck5hbWUiOiAibWV0aG9kIiwgInR5cGUiOiAic2VsZWN0IiwgInZhbHVlIjogImFsbCIsICJrZXlzIjogWyJtZXRob2QiXSwgImZpZWxkIjogeyJpZCI6ICJzZXJ2aWNlcy1tZXRob2RzIiwgInZhbHVlIjogImFsbCIsICJ2YWx1ZXMiOiBbInNjaGVkdWxlciJdLCAibmFtZSI6ICJzZXJ2aWNlcy1tZXRob2RzIiwgIm9ubHlEb3duIjogdHJ1ZSwgImxhYmVsIjogInNlcnZpY2VzX21ldGhvZHMiLCAicG9wb3ZlcnMiOiBbeyJ0ZXh0IjogInNlcnZpY2VzX21ldGhvZHNfZGVzYyIsICJpY29uTmFtZSI6ICJpbmZvIn1dLCAiY29sdW1ucyI6IHsicGMiOiAzLCAidGFibGV0IjogNCwgIm1vYmlsZSI6IDEyfX19LCB7ImZpbHRlciI6ICJ0YWJsZSIsICJmaWx0ZXJOYW1lIjogImRyYWZ0IiwgInR5cGUiOiAic2VsZWN0IiwgInZhbHVlIjogImFsbCIsICJrZXlzIjogWyJkcmFmdCJdLCAiZmllbGQiOiB7ImlkIjogInNlcnZpY2VzLWRyYWZ0IiwgInZhbHVlIjogImFsbCIsICJ2YWx1ZXMiOiBbImFsbCIsICJvbmxpbmUiLCAiZHJhZnQiXSwgIm5hbWUiOiAic2VydmljZXMtZHJhZnQiLCAib25seURvd24iOiB0cnVlLCAibGFiZWwiOiAic2VydmljZXNfZHJhZnQiLCAicG9wb3ZlcnMiOiBbeyJ0ZXh0IjogInNlcnZpY2VzX2RyYWZ0X2Rlc2MiLCAiaWNvbk5hbWUiOiAiaW5mbyJ9XSwgImNvbHVtbnMiOiB7InBjIjogMywgInRhYmxldCI6IDQsICJtb2JpbGUiOiAxMn19fV19fV19XQ"
></div>
<div id="app"></div>
<script type="module" src="services.js"></script>
</body>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,278 @@
[
{
"type": "card",
"containerColumns": {
"pc": 12,
"tablet": 12,
"mobile": 12
},
"widgets": [
{
"type": "Title",
"data": {
"title": "services_title"
}
},
{
"type": "Table",
"data": {
"title": "services_table_title",
"minWidth": "lg",
"header": [
"services_table_name",
"services_table_method",
"services_table_settings",
"services_table_manage",
"services_table_is_draft",
"services_table_delete"
],
"positions": [
2,
2,
2,
2,
2,
2
],
"items": [
[
{
"name": "app1.example.com",
"type": "Text",
"data": {
"text": "app1.example.com"
}
},
{
"method": "scheduler",
"type": "Text",
"data": {
"text": "scheduler"
}
},
{
"type": "Button",
"data": {
"id": "open-modal-settings-0",
"text": "settings",
"hideText": false,
" color": "info",
"size": "normal",
"iconName": "settings"
}
},
{
"type": "Button",
"data": {
"attrs": {
"data-server-name": "app1.example.com"
},
"id": "open-modal-manage-0",
"text": "manage",
"hideText": false,
" color": "green",
"size": "normal",
"iconName": "manage"
}
},
{
"type": "Button",
"data": {
"attrs": {
"data-server-name": "app1.example.com",
"data-is-draft": "no"
},
"id": "open-modal-draft-0",
"text": "online",
"hideText": false,
" color": "cyan",
"size": "normal",
"iconName": "online"
}
},
{
"type": "Button",
"data": {
"attrs": {
"data-server-name": "app1.example.com"
},
"id": "open-modal-delete-0",
"text": "delete",
"disabled": true,
"hideText": false,
" color": "red",
"size": "normal",
"iconName": "trash"
}
}
],
[
{
"name": "www.example.com",
"type": "Text",
"data": {
"text": "www.example.com"
}
},
{
"method": "scheduler",
"type": "Text",
"data": {
"text": "scheduler"
}
},
{
"type": "Button",
"data": {
"id": "open-modal-settings-1",
"text": "settings",
"hideText": false,
" color": "info",
"size": "normal",
"iconName": "settings"
}
},
{
"type": "Button",
"data": {
"attrs": {
"data-server-name": "www.example.com"
},
"id": "open-modal-manage-1",
"text": "manage",
"hideText": false,
" color": "green",
"size": "normal",
"iconName": "manage"
}
},
{
"type": "Button",
"data": {
"attrs": {
"data-server-name": "www.example.com",
"data-is-draft": "no"
},
"id": "open-modal-draft-1",
"text": "online",
"hideText": false,
" color": "cyan",
"size": "normal",
"iconName": "online"
}
},
{
"type": "Button",
"data": {
"attrs": {
"data-server-name": "www.example.com"
},
"id": "open-modal-delete-1",
"text": "delete",
"disabled": true,
"hideText": false,
" color": "red",
"size": "normal",
"iconName": "trash"
}
}
]
],
"filters": [
{
"filter": "table",
"filterName": "keyword",
"type": "keyword",
"value": "",
"keys": [
"name"
],
"field": {
"id": "services-keyword",
"value": "",
"type": "text",
"name": "services-keyword",
"label": "services_search",
"placeholder": "inp_keyword",
"isClipboard": false,
"popovers": [
{
"text": "services_search_desc",
"iconName": "info"
}
],
"columns": {
"pc": 3,
"tablet": 4,
"mobile": 12
}
}
},
{
"filter": "table",
"filterName": "method",
"type": "select",
"value": "all",
"keys": [
"method"
],
"field": {
"id": "services-methods",
"value": "all",
"values": [
"scheduler"
],
"name": "services-methods",
"onlyDown": true,
"label": "services_methods",
"popovers": [
{
"text": "services_methods_desc",
"iconName": "info"
}
],
"columns": {
"pc": 3,
"tablet": 4,
"mobile": 12
}
}
},
{
"filter": "table",
"filterName": "draft",
"type": "select",
"value": "all",
"keys": [
"draft"
],
"field": {
"id": "services-draft",
"value": "all",
"values": [
"all",
"online",
"draft"
],
"name": "services-draft",
"onlyDown": true,
"label": "services_draft",
"popovers": [
{
"text": "services_draft_desc",
"iconName": "info"
}
],
"columns": {
"pc": 3,
"tablet": 4,
"mobile": 12
}
}
}
]
}
}
]
}
]

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
W3sidHlwZSI6ICJjYXJkIiwgImNvbnRhaW5lckNvbHVtbnMiOiB7InBjIjogMTIsICJ0YWJsZXQiOiAxMiwgIm1vYmlsZSI6IDEyfSwgIndpZGdldHMiOiBbeyJ0eXBlIjogIlRpdGxlIiwgImRhdGEiOiB7InRpdGxlIjogInNlcnZpY2VzX3RpdGxlIn19LCB7InR5cGUiOiAiVGFibGUiLCAiZGF0YSI6IHsidGl0bGUiOiAic2VydmljZXNfdGFibGVfdGl0bGUiLCAibWluV2lkdGgiOiAibGciLCAiaGVhZGVyIjogWyJzZXJ2aWNlc190YWJsZV9uYW1lIiwgInNlcnZpY2VzX3RhYmxlX21ldGhvZCIsICJzZXJ2aWNlc190YWJsZV9zZXR0aW5ncyIsICJzZXJ2aWNlc190YWJsZV9tYW5hZ2UiLCAic2VydmljZXNfdGFibGVfaXNfZHJhZnQiLCAic2VydmljZXNfdGFibGVfZGVsZXRlIl0sICJwb3NpdGlvbnMiOiBbMiwgMiwgMiwgMiwgMiwgMl0sICJpdGVtcyI6IFtbeyJuYW1lIjogImFwcDEuZXhhbXBsZS5jb20iLCAidHlwZSI6ICJUZXh0IiwgImRhdGEiOiB7InRleHQiOiAiYXBwMS5leGFtcGxlLmNvbSJ9fSwgeyJtZXRob2QiOiAic2NoZWR1bGVyIiwgInR5cGUiOiAiVGV4dCIsICJkYXRhIjogeyJ0ZXh0IjogInNjaGVkdWxlciJ9fSwgeyJ0eXBlIjogIkJ1dHRvbiIsICJkYXRhIjogeyJpZCI6ICJvcGVuLW1vZGFsLXNldHRpbmdzLTAiLCAidGV4dCI6ICJzZXR0aW5ncyIsICJoaWRlVGV4dCI6IGZhbHNlLCAiIGNvbG9yIjogImluZm8iLCAic2l6ZSI6ICJub3JtYWwiLCAiaWNvbk5hbWUiOiAic2V0dGluZ3MifX0sIHsidHlwZSI6ICJCdXR0b24iLCAiZGF0YSI6IHsiYXR0cnMiOiB7ImRhdGEtc2VydmVyLW5hbWUiOiAiYXBwMS5leGFtcGxlLmNvbSJ9LCAiaWQiOiAib3Blbi1tb2RhbC1tYW5hZ2UtMCIsICJ0ZXh0IjogIm1hbmFnZSIsICJoaWRlVGV4dCI6IGZhbHNlLCAiIGNvbG9yIjogImdyZWVuIiwgInNpemUiOiAibm9ybWFsIiwgImljb25OYW1lIjogIm1hbmFnZSJ9fSwgeyJ0eXBlIjogIkJ1dHRvbiIsICJkYXRhIjogeyJhdHRycyI6IHsiZGF0YS1zZXJ2ZXItbmFtZSI6ICJhcHAxLmV4YW1wbGUuY29tIiwgImRhdGEtaXMtZHJhZnQiOiAibm8ifSwgImlkIjogIm9wZW4tbW9kYWwtZHJhZnQtMCIsICJ0ZXh0IjogIm9ubGluZSIsICJoaWRlVGV4dCI6IGZhbHNlLCAiIGNvbG9yIjogImN5YW4iLCAic2l6ZSI6ICJub3JtYWwiLCAiaWNvbk5hbWUiOiAib25saW5lIn19LCB7InR5cGUiOiAiQnV0dG9uIiwgImRhdGEiOiB7ImF0dHJzIjogeyJkYXRhLXNlcnZlci1uYW1lIjogImFwcDEuZXhhbXBsZS5jb20ifSwgImlkIjogIm9wZW4tbW9kYWwtZGVsZXRlLTAiLCAidGV4dCI6ICJkZWxldGUiLCAiZGlzYWJsZWQiOiB0cnVlLCAiaGlkZVRleHQiOiBmYWxzZSwgIiBjb2xvciI6ICJyZWQiLCAic2l6ZSI6ICJub3JtYWwiLCAiaWNvbk5hbWUiOiAidHJhc2gifX1dLCBbeyJuYW1lIjogInd3dy5leGFtcGxlLmNvbSIsICJ0eXBlIjogIlRleHQiLCAiZGF0YSI6IHsidGV4dCI6ICJ3d3cuZXhhbXBsZS5jb20ifX0sIHsibWV0aG9kIjogInNjaGVkdWxlciIsICJ0eXBlIjogIlRleHQiLCAiZGF0YSI6IHsidGV4dCI6ICJzY2hlZHVsZXIifX0sIHsidHlwZSI6ICJCdXR0b24iLCAiZGF0YSI6IHsiaWQiOiAib3Blbi1tb2RhbC1zZXR0aW5ncy0xIiwgInRleHQiOiAic2V0dGluZ3MiLCAiaGlkZVRleHQiOiBmYWxzZSwgIiBjb2xvciI6ICJpbmZvIiwgInNpemUiOiAibm9ybWFsIiwgImljb25OYW1lIjogInNldHRpbmdzIn19LCB7InR5cGUiOiAiQnV0dG9uIiwgImRhdGEiOiB7ImF0dHJzIjogeyJkYXRhLXNlcnZlci1uYW1lIjogInd3dy5leGFtcGxlLmNvbSJ9LCAiaWQiOiAib3Blbi1tb2RhbC1tYW5hZ2UtMSIsICJ0ZXh0IjogIm1hbmFnZSIsICJoaWRlVGV4dCI6IGZhbHNlLCAiIGNvbG9yIjogImdyZWVuIiwgInNpemUiOiAibm9ybWFsIiwgImljb25OYW1lIjogIm1hbmFnZSJ9fSwgeyJ0eXBlIjogIkJ1dHRvbiIsICJkYXRhIjogeyJhdHRycyI6IHsiZGF0YS1zZXJ2ZXItbmFtZSI6ICJ3d3cuZXhhbXBsZS5jb20iLCAiZGF0YS1pcy1kcmFmdCI6ICJubyJ9LCAiaWQiOiAib3Blbi1tb2RhbC1kcmFmdC0xIiwgInRleHQiOiAib25saW5lIiwgImhpZGVUZXh0IjogZmFsc2UsICIgY29sb3IiOiAiY3lhbiIsICJzaXplIjogIm5vcm1hbCIsICJpY29uTmFtZSI6ICJvbmxpbmUifX0sIHsidHlwZSI6ICJCdXR0b24iLCAiZGF0YSI6IHsiYXR0cnMiOiB7ImRhdGEtc2VydmVyLW5hbWUiOiAid3d3LmV4YW1wbGUuY29tIn0sICJpZCI6ICJvcGVuLW1vZGFsLWRlbGV0ZS0xIiwgInRleHQiOiAiZGVsZXRlIiwgImRpc2FibGVkIjogdHJ1ZSwgImhpZGVUZXh0IjogZmFsc2UsICIgY29sb3IiOiAicmVkIiwgInNpemUiOiAibm9ybWFsIiwgImljb25OYW1lIjogInRyYXNoIn19XV0sICJmaWx0ZXJzIjogW3siZmlsdGVyIjogInRhYmxlIiwgImZpbHRlck5hbWUiOiAia2V5d29yZCIsICJ0eXBlIjogImtleXdvcmQiLCAidmFsdWUiOiAiIiwgImtleXMiOiBbIm5hbWUiXSwgImZpZWxkIjogeyJpZCI6ICJzZXJ2aWNlcy1rZXl3b3JkIiwgInZhbHVlIjogIiIsICJ0eXBlIjogInRleHQiLCAibmFtZSI6ICJzZXJ2aWNlcy1rZXl3b3JkIiwgImxhYmVsIjogInNlcnZpY2VzX3NlYXJjaCIsICJwbGFjZWhvbGRlciI6ICJpbnBfa2V5d29yZCIsICJpc0NsaXBib2FyZCI6IGZhbHNlLCAicG9wb3ZlcnMiOiBbeyJ0ZXh0IjogInNlcnZpY2VzX3NlYXJjaF9kZXNjIiwgImljb25OYW1lIjogImluZm8ifV0sICJjb2x1bW5zIjogeyJwYyI6IDMsICJ0YWJsZXQiOiA0LCAibW9iaWxlIjogMTJ9fX0sIHsiZmlsdGVyIjogInRhYmxlIiwgImZpbHRlck5hbWUiOiAibWV0aG9kIiwgInR5cGUiOiAic2VsZWN0IiwgInZhbHVlIjogImFsbCIsICJrZXlzIjogWyJtZXRob2QiXSwgImZpZWxkIjogeyJpZCI6ICJzZXJ2aWNlcy1tZXRob2RzIiwgInZhbHVlIjogImFsbCIsICJ2YWx1ZXMiOiBbInNjaGVkdWxlciJdLCAibmFtZSI6ICJzZXJ2aWNlcy1tZXRob2RzIiwgIm9ubHlEb3duIjogdHJ1ZSwgImxhYmVsIjogInNlcnZpY2VzX21ldGhvZHMiLCAicG9wb3ZlcnMiOiBbeyJ0ZXh0IjogInNlcnZpY2VzX21ldGhvZHNfZGVzYyIsICJpY29uTmFtZSI6ICJpbmZvIn1dLCAiY29sdW1ucyI6IHsicGMiOiAzLCAidGFibGV0IjogNCwgIm1vYmlsZSI6IDEyfX19LCB7ImZpbHRlciI6ICJ0YWJsZSIsICJmaWx0ZXJOYW1lIjogImRyYWZ0IiwgInR5cGUiOiAic2VsZWN0IiwgInZhbHVlIjogImFsbCIsICJrZXlzIjogWyJkcmFmdCJdLCAiZmllbGQiOiB7ImlkIjogInNlcnZpY2VzLWRyYWZ0IiwgInZhbHVlIjogImFsbCIsICJ2YWx1ZXMiOiBbImFsbCIsICJvbmxpbmUiLCAiZHJhZnQiXSwgIm5hbWUiOiAic2VydmljZXMtZHJhZnQiLCAib25seURvd24iOiB0cnVlLCAibGFiZWwiOiAic2VydmljZXNfZHJhZnQiLCAicG9wb3ZlcnMiOiBbeyJ0ZXh0IjogInNlcnZpY2VzX2RyYWZ0X2Rlc2MiLCAiaWNvbk5hbWUiOiAiaW5mbyJ9XSwgImNvbHVtbnMiOiB7InBjIjogMywgInRhYmxldCI6IDQsICJtb2JpbGUiOiAxMn19fV19fV19XQ==

View file

@ -0,0 +1,94 @@
import json
import base64
services = [
{
"USE_REVERSE_PROXY": {"value": "yes", "method": "scheduler", "global": False},
"IS_DRAFT": {"value": "no", "method": "default", "global": False},
"SERVE_FILES": {"value": "no", "method": "scheduler", "global": True},
"REMOTE_PHP": {"value": "", "method": "default", "global": True},
"AUTO_LETS_ENCRYPT": {"value": "no", "method": "default", "global": True},
"USE_CUSTOM_SSL": {"value": "no", "method": "default", "global": True},
"USE_MODSECURITY": {"value": "yes", "method": "default", "global": True},
"USE_BAD_BEHAVIOR": {"value": "yes", "method": "default", "global": True},
"USE_LIMIT_REQ": {"value": "yes", "method": "default", "global": True},
"USE_DNSBL": {"value": "yes", "method": "default", "global": True},
"SERVER_NAME": {"value": "app1.example.com", "method": "scheduler", "global": False},
},
{
"USE_REVERSE_PROXY": {"value": "yes", "method": "scheduler", "global": False},
"IS_DRAFT": {"value": "no", "method": "default", "global": False},
"SERVE_FILES": {"value": "no", "method": "scheduler", "global": True},
"REMOTE_PHP": {"value": "", "method": "default", "global": True},
"AUTO_LETS_ENCRYPT": {"value": "no", "method": "default", "global": True},
"USE_CUSTOM_SSL": {"value": "no", "method": "default", "global": True},
"USE_MODSECURITY": {"value": "yes", "method": "default", "global": True},
"USE_BAD_BEHAVIOR": {"value": "yes", "method": "default", "global": True},
"USE_LIMIT_REQ": {"value": "yes", "method": "default", "global": True},
"USE_DNSBL": {"value": "yes", "method": "default", "global": True},
"SERVER_NAME": {"value": "www.example.com", "method": "scheduler", "global": False},
},
]
data = []
for index, service in enumerate(services):
server_name = service["SERVER_NAME"]["value"]
server_method = service["SERVER_NAME"]["method"]
is_draft = True if service["IS_DRAFT"]["value"] == "yes" else False
is_deletable = False if server_method in ("autoconf", "scheduler") else True
item = []
# Get name
item.append({"name": server_name, "type": "Text", "data": {"text": server_name}})
item.append({"method": server_method, "type": "Text", "data": {"text": server_method}})
item.append(
{
"type": "Button",
"data": {"id": f"open-modal-settings-{index}", "text": "settings", "hideText": False, " color": "info", "size": "normal", "iconName": "settings"},
}
)
item.append(
{
"type": "Button",
"data": {
"attrs": {"data-server-name": server_name},
"id": f"open-modal-manage-{index}",
"text": "manage",
"hideText": False,
" color": "green",
"size": "normal",
"iconName": "manage",
},
}
)
item.append(
{
"type": "Button",
"data": {
"attrs": {"data-server-name": server_name, "data-is-draft": "yes" if is_draft else "no"},
"id": f"open-modal-draft-{index}",
"text": "draft" if is_draft else "online",
"hideText": False,
" color": "cyan",
"size": "normal",
"iconName": "draft" if is_draft else "online",
},
}
)
item.append(
{
"type": "Button",
"data": {
"attrs": {"data-server-name": server_name},
"id": f"open-modal-delete-{index}",
"text": "delete",
"disabled": not is_deletable,
"hideText": False,
" color": "red",
"size": "normal",
"iconName": "trash",
},
}
)
data.append(item)

View file

@ -1056,6 +1056,124 @@ def get_service_data():
return config, variables, format_configs, server_name, old_server_name, operation, is_draft, was_draft, is_draft_unchanged
# @app.route("/services", methods=["GET", "POST"])
# @login_required
# def services():
# if request.method == "POST":
# if app.config["DB"].readonly:
# return handle_error("Database is in read-only mode", "services")
# verify_data_in_form(
# data={"operation": ("edit", "new", "delete")},
# err_message="Invalid operation parameter on /services.",
# redirect_url="services",
# )
# config, variables, format_configs, server_name, old_server_name, operation, is_draft, was_draft, is_draft_unchanged = get_service_data()
# if request.form["operation"] == "edit":
# if is_draft_unchanged and len(variables) == 1 and "SERVER_NAME" in variables and server_name == old_server_name:
# return handle_error("The service was not edited because no values were changed.", "services", True)
# if request.form["operation"] == "new" and not variables:
# return handle_error("The service was not created because all values had the default value.", "services", True)
# # Delete
# if request.form["operation"] == "delete":
# is_service = app.config["CONFIG"].check_variables({"SERVER_NAME": request.form["SERVER_NAME"]}, config)
# if not is_service:
# error_message(f"Error while deleting the service {request.form['SERVER_NAME']}")
# if config.get(f"{request.form['SERVER_NAME'].split(' ')[0]}_SERVER_NAME", {"method": "scheduler"})["method"] != "ui":
# return handle_error("The service cannot be deleted because it has not been created with the UI.", "services", True)
# db_metadata = app.config["DB"].get_metadata()
# def update_services(threaded: bool = False):
# wait_applying()
# manage_bunkerweb(
# "services",
# variables,
# old_server_name,
# variables.get("SERVER_NAME", ""),
# operation=operation,
# is_draft=is_draft,
# was_draft=was_draft,
# threaded=threaded,
# )
# ui_data = get_ui_data()
# if any(
# v
# for k, v in db_metadata.items()
# if k in ("custom_configs_changed", "external_plugins_changed", "pro_plugins_changed", "plugins_config_changed", "instances_changed")
# ):
# ui_data["RELOADING"] = True
# ui_data["LAST_RELOAD"] = time()
# Thread(target=update_services, args=(True,)).start()
# else:
# update_services()
# ui_data["CONFIG_CHANGED"] = True
# with LOCK:
# TMP_DATA_FILE.write_text(dumps(ui_data), encoding="utf-8")
# message = ""
# if request.form["operation"] == "new":
# message = f"Creating {'draft ' if is_draft else ''}service {variables.get('SERVER_NAME', '').split(' ')[0]}"
# elif request.form["operation"] == "edit":
# message = f"Saving configuration for {'draft ' if is_draft else ''}service {old_server_name.split(' ')[0]}"
# elif request.form["operation"] == "delete":
# message = f"Deleting {'draft ' if was_draft and is_draft else ''}service {request.form.get('SERVER_NAME', '').split(' ')[0]}"
# return redirect(url_for("loading", next=url_for("services"), message=message))
# # Display services
# services = []
# tmp_config = app.config["DB"].get_config(methods=True, with_drafts=True).copy()
# service_names = tmp_config["SERVER_NAME"]["value"].split(" ")
# table_settings = (
# "USE_REVERSE_PROXY",
# "IS_DRAFT",
# "SERVE_FILES",
# "REMOTE_PHP",
# "AUTO_LETS_ENCRYPT",
# "USE_CUSTOM_SSL",
# "USE_MODSECURITY",
# "USE_BAD_BEHAVIOR",
# "USE_LIMIT_REQ",
# "USE_DNSBL",
# "SERVER_NAME",
# )
# for service in service_names:
# service_settings = {}
# # For each needed setting, get the service value if one, else the global (value), else defautl value
# for setting in table_settings:
# value = tmp_config.get(f"{service}_{setting}", tmp_config.get(setting, {"value": None}))["value"]
# method = tmp_config.get(f"{service}_{setting}", tmp_config.get(setting, {"method": None}))["method"]
# is_global = tmp_config.get(f"{service}_{setting}", tmp_config.get(setting, {"global": None}))["global"]
# service_settings[setting] = {"value": value, "method": method, "global": is_global}
# services.append(service_settings)
# services.sort(key=lambda x: x["SERVER_NAME"]["value"])
# return render_template(
# "services.html",
# services=services,
# global_config=global_config,
# )
@app.route("/services", methods=["GET", "POST"])
@login_required
def services():