fix indentation

This commit is contained in:
Hannaeko 2022-04-29 04:33:00 +02:00
parent c04090adaf
commit db82f8564c
7 changed files with 155 additions and 155 deletions

View file

@ -2,21 +2,21 @@ const baseUrl = '/api/v1';
function apiGet(url) { function apiGet(url) {
return fetch(`${baseUrl}/${url}`) return fetch(`${baseUrl}/${url}`)
.then(res => { .then(res => {
if (!res.ok) { if (!res.ok) {
// do something here // do something here
throw new Error('Not ok'); throw new Error('Not ok');
} }
return res.json(); return res.json();
}) })
} }
function getRecords(zone) { function getRecords(zone) {
return apiGet(`zones/${zone}/records`) return apiGet(`zones/${zone}/records`)
} }
export { export {
getRecords, getRecords,
}; };

View file

@ -2,99 +2,99 @@ import { html, Component, render, createContext, useState, useEffect } from 'htt
import { getRecords } from './api.js'; import { getRecords } from './api.js';
const rdataInputProperties = { const rdataInputProperties = {
Address: {label: 'adresse', type: 'text'}, Address: {label: 'adresse', type: 'text'},
Serial: {label: 'serial', type: 'number'}, Serial: {label: 'serial', type: 'number'},
Minimum: {label: 'minimum', type: 'number'}, Minimum: {label: 'minimum', type: 'number'},
Retry: {label: 'nouvelle tentative', type: 'number'}, Retry: {label: 'nouvelle tentative', type: 'number'},
Refresh: {label: 'actualisation', type: 'number'}, Refresh: {label: 'actualisation', type: 'number'},
MaintainerName: {label: 'contact', type: 'text'}, MaintainerName: {label: 'contact', type: 'text'},
MasterServerName: {label: 'serveur primaire', type: 'text'}, MasterServerName: {label: 'serveur primaire', type: 'text'},
Expire: {label: 'expiration', type: 'number'}, Expire: {label: 'expiration', type: 'number'},
Target: {label: 'cible', type: 'text'}, Target: {label: 'cible', type: 'text'},
} }
const Editable = createContext(false); const Editable = createContext(false);
function RDataInput({ name, value = '', index = 0 }) { function RDataInput({ name, value = '', index = 0 }) {
const {label, type} = rdataInputProperties[name] || {label: name, type: 'text'}; const {label, type} = rdataInputProperties[name] || {label: name, type: 'text'};
return html` return html`
<${Editable.Consumer}> <${Editable.Consumer}>
${ ${
(editable) => { (editable) => {
if (editable) { if (editable) {
return html` return html`
<div> <div>
<label for=record_${index}_${name}>${label}:</label> <label for=record_${index}_${name}>${label}:</label>
<input id=record_${index}_${name} type=${type} value=${value} /> <input id=record_${index}_${name} type=${type} value=${value} />
</div> </div>
`; `;
} else { } else {
return html` return html`
<div> <div>
<span class=label>${label}:</span> <span class=label>${label}:</span>
<span class=value>${value}</span> <span class=value>${value}</span>
</div> </div>
` `
} }
} }
} }
<//> <//>
`; `;
} }
function RData({ rdata, index }) { function RData({ rdata, index }) {
const { Address: address } = rdata; const { Address: address } = rdata;
return Object.entries(rdata).map(([name, value]) => html`<${RDataInput} name=${name} value=${value} index=${index} />`); return Object.entries(rdata).map(([name, value]) => html`<${RDataInput} name=${name} value=${value} index=${index} />`);
} }
function Record({name, ttl, type, rdata, index = 0}) { function Record({name, ttl, type, rdata, index = 0}) {
return html` return html`
<tr> <tr>
<td class=domain>${name}</div> <td class=domain>${name}</div>
<td class=type>${type}</div> <td class=type>${type}</div>
<td class=ttl>${ttl}</div> <td class=ttl>${ttl}</div>
<td class=rdata><${RData} rdata=${rdata} index=${index}/></div> <td class=rdata><${RData} rdata=${rdata} index=${index}/></div>
</tr> </tr>
`; `;
} }
function RecordList({ zone }) { function RecordList({ zone }) {
const [records, setRecords] = useState([]); const [records, setRecords] = useState([]);
const [editable, setEditable] = useState(false); const [editable, setEditable] = useState(false);
const toggleEdit = () => setEditable(!editable); const toggleEdit = () => setEditable(!editable);
useEffect(() => { useEffect(() => {
getRecords(zone) getRecords(zone)
.then((res) => setRecords(res)); .then((res) => setRecords(res));
}, []) }, [])
return html` return html`
<${Editable.Provider} value=${editable}> <${Editable.Provider} value=${editable}>
<button onclick=${toggleEdit}>${ editable ? 'Save' : 'Edit'}</button> <button onclick=${toggleEdit}>${ editable ? 'Save' : 'Edit'}</button>
<table class=record-list> <table class=record-list>
<thead> <thead>
<tr> <tr>
<th>Nom</th> <th>Nom</th>
<th>Type</th> <th>Type</th>
<th>TTL</th> <th>TTL</th>
<th>Données</th> <th>Données</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
${records.map( ${records.map(
({Name, Class, TTL, Type, ...rdata}, index) => { ({Name, Class, TTL, Type, ...rdata}, index) => {
return html`<${Record} name=${Name} ttl=${TTL} type=${Type} rdata=${rdata} index=${index}/>` return html`<${Record} name=${Name} ttl=${TTL} type=${Type} rdata=${rdata} index=${index}/>`
} }
)} )}
</tbody> </tbody>
</ul> </ul>
<//> <//>
`; `;
} }
export { RecordList }; export { RecordList };

View file

@ -1,41 +1,41 @@
body { body {
color: #2e2033; color: #2e2033;
} }
.record-list { .record-list {
border-collapse: collapse; border-collapse: collapse;
} }
.record-list .rdata { .record-list .rdata {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
} }
.record-list th, .record-list td { .record-list th, .record-list td {
font-weight: normal; font-weight: normal;
text-align: left; text-align: left;
vertical-align: top; vertical-align: top;
padding: 0.25rem; padding: 0.25rem;
} }
.record-list thead { .record-list thead {
background: #ccb9ff; background: #ccb9ff;
color: #39004d; color: #39004d;
} }
.record-list tbody tr:nth-child(even) td { .record-list tbody tr:nth-child(even) td {
background: #ccb9ff3d; background: #ccb9ff3d;
} }
.record-list tbody tr .rdata span.label, .record-list tbody tr .rdata span.label,
.record-list tbody tr .rdata label { .record-list tbody tr .rdata label {
display: inline-block; display: inline-block;
padding: 0.1em 0.5em; padding: 0.1em 0.5em;
background: #cecece; background: #cecece;
font-size: 0.7rem; font-size: 0.7rem;
border-radius: 0.5em; border-radius: 0.5em;
margin-right: 0.1rem; margin-right: 0.1rem;
} }
.record-list tbody tr .rdata > div { .record-list tbody tr .rdata > div {
margin: 0.1rem 0.5rem 0.1rem 0; margin: 0.1rem 0.5rem 0.1rem 0;
} }

View file

@ -10,48 +10,48 @@ use tera::{Tera, Context};
pub struct TemplateState { pub struct TemplateState {
tera: Tera, tera: Tera,
} }
impl TemplateState { impl TemplateState {
pub fn new(template_directory: &Path) -> Self { pub fn new(template_directory: &Path) -> Self {
let template_glob = template_directory.join("**").join("*"); let template_glob = template_directory.join("**").join("*");
match Tera::new(template_glob.to_str().expect("valid glob path string")) { match Tera::new(template_glob.to_str().expect("valid glob path string")) {
Ok(tera) => TemplateState { tera }, Ok(tera) => TemplateState { tera },
Err(e) => { Err(e) => {
println!("Loading templates failed: {}", e); println!("Loading templates failed: {}", e);
exit(1) exit(1)
} }
} }
} }
} }
pub struct Template<'t, S: Serialize> { pub struct Template<'t, S: Serialize> {
pub name: &'t str, pub name: &'t str,
pub context: S, pub context: S,
} }
impl<'r, S: Serialize> Template<'r, S> { impl<'r, S: Serialize> Template<'r, S> {
pub fn new(name: &'r str, context: S) -> Self { pub fn new(name: &'r str, context: S) -> Self {
Template { Template {
name, name,
context context
} }
} }
fn render(self, tera: &Tera) -> Result<(ContentType, String), Status> { fn render(self, tera: &Tera) -> Result<(ContentType, String), Status> {
let context = Context::from_serialize(self.context).map_err(|e| { let context = Context::from_serialize(self.context).map_err(|e| {
error!("Failed to serialize context: {}", e); error!("Failed to serialize context: {}", e);
Status::InternalServerError Status::InternalServerError
})?; })?;
let content = tera.render(self.name, &context).map_err(|e| { let content = tera.render(self.name, &context).map_err(|e| {
error!("Failed to render template `{}`: {}", self.name, e); error!("Failed to render template `{}`: {}", self.name, e);
Status::InternalServerError Status::InternalServerError
})?; })?;
Ok((ContentType::HTML, content)) Ok((ContentType::HTML, content))
} }
} }
impl<'r, 't, S: Serialize> Responder<'r, 'static> for Template<'t, S> { impl<'r, 't, S: Serialize> Responder<'r, 'static> for Template<'t, S> {

View file

@ -1,13 +1,13 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}{% endblock title %}Nomilo</title> <title>{% block title %}{% endblock title %}Nomilo</title>
<link rel="stylesheet" type="text/css" href="/styles/main.css"> <link rel="stylesheet" type="text/css" href="/styles/main.css">
</head> </head>
<body> <body>
{% block content %}{% endblock content %} {% block content %}{% endblock content %}
{% block scripts %}{% endblock scripts %} {% block scripts %}{% endblock scripts %}
</body> </body>
</html> </html>

View file

@ -3,16 +3,16 @@
{% block title %}Login ⋅ {% endblock title %} {% block title %}Login ⋅ {% endblock title %}
{% block content %} {% block content %}
<main> <main>
{% if error %} {% if error %}
<p> <p>
{{ error }} {{ error }}
</p> </p>
{% endif %} {% endif %}
<form method="POST" action="/login"> <form method="POST" action="/login">
<input type="text" name="username"> <input type="text" name="username">
<input type="password" name="password"> <input type="password" name="password">
<input type="submit" value="Se connecter"> <input type="submit" value="Se connecter">
</form> </form>
</main> </main>
{% endblock content %} {% endblock content %}

View file

@ -3,16 +3,16 @@
{% block title %}{{ zone }} ⋅ Records ⋅ {% endblock title %} {% block title %}{{ zone }} ⋅ Records ⋅ {% endblock title %}
{% block content %} {% block content %}
<main></main> <main></main>
{% endblock content %} {% endblock content %}
{% block scripts %} {% block scripts %}
<script type="module"> <script type="module">
const zoneName = "{{ zone }}"; const zoneName = "{{ zone }}";
import { RecordList } from '/scripts/records.js'; import { RecordList } from '/scripts/records.js';
import { html, render } from 'https://unpkg.com/htm/preact/standalone.mjs'; import { html, render } from 'https://unpkg.com/htm/preact/standalone.mjs';
render(html`<${RecordList} zone=${zoneName} />`, document.querySelector('main')); render(html`<${RecordList} zone=${zoneName} />`, document.querySelector('main'));
</script> </script>
{% endblock scripts %} {% endblock scripts %}