mail4one/jsdev/index.html

353 lines
12 KiB
HTML
Raw Normal View History

2023-07-02 23:48:04 -04:00
<!doctype html>
<html>
<head>
2023-07-04 13:06:21 -04:00
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
2023-07-03 17:52:28 -04:00
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
2023-07-04 13:06:21 -04:00
<title>Mail4one Web config</title>
2023-07-02 23:48:04 -04:00
<script type="application/json" id="m41config">
{
"matches": [
{
"name": "mydomain",
"addr_rexs": [
".*@mydomain.com",
".*@m.mydomain.com"
]
},
{
"name": "personal",
"addrs": [
"first.last@mydomain.com",
"secret.name@mydomain.com"
]
}
],
"boxes": [
{
"name": "spam",
"rules": [
{
"match_name": "mydomain",
"negate": true,
"stop_check": true
}
]
},
{
"name": "important",
"rules": [
{
"match_name": "personal"
}
]
},
{
"name": "all",
"rules": [
{
"match_name": "default_match_all"
}
]
}
],
"users": [
{
"username": "mymobile",
"password_hash": "AFTY5EVN7AX47ZL7UMH3BETYWFBTAV3XHR73CEFAJBPN2NIHPWDZHV2UQSMSPHSQQ2A2BFQBNC77VL7F2UKATQNJZGYLCSU6C43UQDAQXWXSWNGAEPGIMG2F3QDKBXL3MRHY6K2BPID64ZR6LABLPVSF",
"mbox": "important"
},
{
"username": "mydesk",
"password_hash": "AFTY5EVN7AX47ZL7UMH3BETYWFBTAV3XHR73CEFAJBPN2NIHPWDZHV2UQSMSPHSQQ2A2BFQBNC77VL7F2UKATQNJZGYLCSU6C43UQDAQXWXSWNGAEPGIMG2F3QDKBXL3MRHY6K2BPID64ZR6LABLPVSF",
"mbox": "all"
}
]
}
</script>
2023-07-04 23:46:57 -04:00
<style>
2023-07-05 22:27:09 -04:00
.outer {
display: flex;
justify-content: center;
background: grey;
}
.inner {
border: 1px solid;
background: white;
padding: 5px;
// flex: 1 0 0;
// max-width: 700px;
}
2023-07-04 23:46:57 -04:00
.m41-box {
display: grid;
2023-07-05 22:27:09 -04:00
grid-template-columns: 1fr 3fr;
margin: 10px;
// background-color: lightblue;
2023-07-04 23:46:57 -04:00
}
#web-cfg-boxes {
2023-07-05 22:27:09 -04:00
// display: grid;
// grid-template-columns: 1fr ;
width: 100%;
2023-07-04 23:46:57 -04:00
//justify-content: space-around;
// justify-content: flex-start;
// background-color: blue;
}
2023-07-05 22:27:09 -04:00
.m41-box:nth-of-type(odd) {
background: lightblue;
}
.m41-box:nth-of-type(even) {
background: lightgrey;
}
2023-07-04 23:46:57 -04:00
.m41-box-info {
display: grid;
2023-07-05 22:27:09 -04:00
grid-template-columns: 4fr 2fr 5fr;
// align-items: stretch;
2023-07-04 23:46:57 -04:00
// justify-content: space-around;
2023-07-05 22:27:09 -04:00
// background-color: grey;
2023-07-04 23:46:57 -04:00
}
.button-group {
2023-07-05 22:27:09 -04:00
display: flex;
justify-content: center;
// grid-template-columns: 1fr 1fr 1fr;
// align-items: stretch;
2023-07-04 23:46:57 -04:00
// display: inline-flex;
}
.m41-box-rule:only-child div.button-group button{
2023-07-05 22:27:09 -04:00
// display: none;
visibility: hidden;
2023-07-04 23:46:57 -04:00
}
.m41-box:only-child div div.button-group button{
2023-07-05 22:27:09 -04:00
// display: none;
visibility: hidden;
2023-07-04 23:46:57 -04:00
}
.m41-box-rule {
2023-07-05 22:27:09 -04:00
display: flex;
// grid-template-columns: 1fr 3fr 1fr 1fr;
2023-07-04 23:46:57 -04:00
align-items: center;
justify-items: center;
2023-07-05 22:27:09 -04:00
// background-color: lightblue;
2023-07-04 23:46:57 -04:00
}
</style>
2023-07-02 23:48:04 -04:00
<script type="application/javascript">
2023-07-03 22:04:58 -04:00
"use strict"
2023-07-04 13:06:21 -04:00
2023-07-03 22:04:58 -04:00
// Globals
let matches_table
let match_row_template
let config
2023-07-04 19:44:25 -04:00
let boxes_ul
let box_template
let rule_template
2023-07-04 13:06:21 -04:00
function initGlobals() {
matches_table = document.getElementById("web-cfg-matches")
match_row_template = document.getElementById("web-cfg-matches-row")
config = JSON.parse(document.getElementById('m41config').text)
2023-07-04 19:44:25 -04:00
boxes_ul = document.getElementById("web-cfg-boxes")
box_template = document.getElementById("web-cfg-boxes-li")
rule_template = document.getElementById("web-cfg-boxes-rule-li")
2023-07-04 13:06:21 -04:00
}
2023-07-03 22:04:58 -04:00
function populate_match_table(matches_config) {
2023-07-04 13:06:21 -04:00
for (const { name: match_name, addrs, addr_rexs } of matches_config) {
2023-07-03 22:04:58 -04:00
const [match_type, match_values] = (() => {
2023-07-04 13:06:21 -04:00
2023-07-03 22:04:58 -04:00
if (addrs != undefined) {
return ["addrs", addrs]
} else {
return ["addr_rexs", addr_rexs]
}
2023-07-04 13:06:21 -04:00
})()
2023-07-02 23:48:04 -04:00
2023-07-03 17:52:28 -04:00
addMatchRow()
2023-07-04 13:06:21 -04:00
const last_row = matches_table.tBodies[0].lastElementChild
const [ ,name_cell, {firstElementChild: type_select}, value_cell ] = last_row.cells
2023-07-03 22:04:58 -04:00
name_cell.innerText = match_name
2023-07-04 13:06:21 -04:00
type_select.value = match_type
value_cell.innerText = match_values.join("\n")
2023-07-03 22:04:58 -04:00
}
}
function extract_match_table() {
2023-07-04 13:06:21 -04:00
2023-07-03 22:04:58 -04:00
let matches = []
for (let row of matches_table.tBodies[0].rows) {
2023-07-04 13:06:21 -04:00
const [ ,name_cell, {firstElementChild: type_select}, value_cell ] = row.cells
2023-07-03 22:04:58 -04:00
let m = {"name" : name_cell.innerText}
2023-07-04 13:06:21 -04:00
switch (type_select.value) {
case "addrs":
m["addrs"] = value_cell.innerText.split("\n")
break
case "addr_rexs":
m["addr_rexs"] = value_cell.innerText.split("\n")
break
2023-07-03 22:04:58 -04:00
}
matches.push(m)
2023-07-02 23:48:04 -04:00
}
2023-07-03 22:04:58 -04:00
return matches
2023-07-02 23:48:04 -04:00
}
2023-07-03 22:04:58 -04:00
2023-07-04 13:06:21 -04:00
function addMatchRow() {
let row_clone = match_row_template.content.cloneNode(true)
matches_table.tBodies[0].appendChild(row_clone)
}
2023-07-04 19:44:25 -04:00
function populate_boxes_list(boxes_config) {
for (const {name:box_name, rules} of boxes_config) {
addBox()
const box = boxes_ul.lastElementChild
2023-07-04 23:46:57 -04:00
const [{children: [,, header]}, rule_list ] = box.children
2023-07-04 19:44:25 -04:00
header.innerText = box_name
for (const {match_name, negate = false, stop_check = false} of rules ) {
addRule(rule_list)
const rule = rule_list.lastElementChild
const [,
{firstElementChild: match_select},
{firstElementChild: negateCheck},
{firstElementChild: stopCheck}
] = rule.children
negateCheck.checked = negate
stopCheck.checked = stop_check
}
}
}
function addBox() {
let box_clone = box_template.content.cloneNode(true)
boxes_ul.appendChild(box_clone)
}
function addRule(rules_list) {
let rule_clone = rule_template.content.cloneNode(true)
rules_list.appendChild(rule_clone)
}
function moveUp(button) {
2023-07-04 23:46:57 -04:00
const li = button.parentElement.parentElement.parentElement
2023-07-04 19:44:25 -04:00
if (li.previousElementSibling != null) {
li.parentNode.insertBefore(li, li.previousElementSibling)
}
}
function moveDown(button) {
2023-07-04 23:46:57 -04:00
const li = button.parentElement.parentElement.parentElement
2023-07-04 19:44:25 -04:00
if (li.nextElementSibling != null) {
li.parentNode.insertBefore(li.nextElementSibling, li)
}
}
2023-07-03 22:04:58 -04:00
function main() {
2023-07-04 13:06:21 -04:00
initGlobals()
2023-07-03 22:04:58 -04:00
populate_match_table(config["matches"])
save()
2023-07-04 13:06:21 -04:00
document.getElementById("before").innerText = JSON.stringify(config["matches"], null, 2)
2023-07-04 19:44:25 -04:00
populate_boxes_list(config["boxes"])
2023-07-03 22:04:58 -04:00
}
function save() {
2023-07-04 13:06:21 -04:00
const matches = extract_match_table()
document.getElementById("after").innerText = JSON.stringify(matches, null, 2)
2023-07-02 23:48:04 -04:00
}
2023-07-03 22:04:58 -04:00
2023-07-02 23:48:04 -04:00
</script>
</head>
<body onload="main()">
<template id="web-cfg-matches-row">
<tr>
2023-07-04 13:06:21 -04:00
<td><button onClick="this.parentElement.parentElement.remove()"></button></td>
<td contentEditable></td>
2023-07-03 17:52:28 -04:00
<td>
<select>
<option value="addrs">List of addresses</option>
<option value="addr_rexs">List of regexes for addresses</option>
</select>
</td>
2023-07-04 13:06:21 -04:00
<td contentEditable></td>
2023-07-02 23:48:04 -04:00
</tr>
</template>
2023-07-04 19:44:25 -04:00
<template id="web-cfg-boxes-rule-li">
2023-07-04 23:46:57 -04:00
<div class="m41-box-rule">
<div class="button-group">
2023-07-04 19:44:25 -04:00
<button onClick="this.parentElement.parentElement.remove()"></button>
2023-07-04 23:46:57 -04:00
<button onClick="moveUp(this)"></button>
<button onClick="moveDown(this)"></button>
2023-07-04 19:44:25 -04:00
</div>
<label>
Match Name
<select></select>
</label>
<label>
Negate
<input type=checkbox>
</label>
<label>
Stop check
<input type=checkbox>
</label>
2023-07-04 23:46:57 -04:00
</div>
2023-07-04 19:44:25 -04:00
</template>
<template id="web-cfg-boxes-li">
2023-07-04 23:46:57 -04:00
<div class="m41-box">
<div class="m41-box-info">
<div class="button-group">
<button onClick="this.parentElement.parentElement.parentElement.remove()"></button>
<button onClick="moveUp(this)"></button>
<button onClick="moveDown(this)"></button>
</div>
<button onClick="addRule(this.parentElement.nextElementSibling)">+</button>
<span></span>
</div>
<div class="m41-box-rules">
2023-07-04 19:44:25 -04:00
</div>
2023-07-04 23:46:57 -04:00
</div>
2023-07-04 19:44:25 -04:00
</template>
2023-07-05 22:27:09 -04:00
<div class="outer">
<div class="inner">
2023-07-02 23:48:04 -04:00
<h1>Mail4one Web config</h1>
2023-07-04 13:06:21 -04:00
<table border id="web-cfg-matches">
2023-07-02 23:48:04 -04:00
<thead>
2023-07-03 22:04:58 -04:00
<tr>
2023-07-04 13:06:21 -04:00
<th></th>
2023-07-03 22:04:58 -04:00
<th>Name</th>
<th>Type</th>
<th>Values</th>
</tr>
2023-07-02 23:48:04 -04:00
</thead>
<tbody>
</tbody>
</table>
2023-07-03 22:04:58 -04:00
<div>
2023-07-04 13:06:21 -04:00
<button onClick="addMatchRow()">Add Match</button>
<button onClick="save()">Save</button>
2023-07-03 22:04:58 -04:00
</div>
2023-07-04 23:46:57 -04:00
<h3>Boxes <button onClick="addBox()">+</button></h3>
<div id="web-cfg-boxes">
</div>
2023-07-04 13:06:21 -04:00
<hr>
<h3>Before</h3>
<pre id="before"></pre>
<hr>
<h3>After</h3>
<pre id="after"></pre>
<hr>
2023-07-05 22:27:09 -04:00
</div>
</div>
2023-07-02 23:48:04 -04:00
</body>
</html>