Skip to content

Commit d961175

Browse files
authored
Improve Quick Install App password input (hestiacp#3530)
* Rename JS entry point * Import helper in charts JS * Stop setting window.Hestia * Improve charts data fetching * Fix spacing under form title
1 parent e70df5d commit d961175

File tree

6 files changed

+95
-93
lines changed

6 files changed

+95
-93
lines changed

.eslintrc.cjs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ module.exports = {
1919
es2021: true,
2020
},
2121
globals: {
22-
Hestia: 'readonly',
2322
Alpine: 'readonly',
2423
},
2524
rules: {

build.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const externalPackages = ['chart.js/auto', 'alpinejs/dist/cdn.min.js'];
1313

1414
// Build main bundle
1515
async function buildJS() {
16-
const inputPath = './web/js/src/main.js';
16+
const inputPath = './web/js/src/index.js';
1717
try {
1818
await esbuild.build({
1919
entryPoints: [inputPath],

web/js/src/helpers.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,25 @@ export function parseAndSortIpLists(ipListsData) {
4343
return ipLists.sort((a, b) => a.name.localeCompare(b.name));
4444
}
4545

46+
// Posts data to the given URL and returns the response
47+
export async function post(url, data, headers = {}) {
48+
const requestOptions = {
49+
method: 'POST',
50+
headers: {
51+
'Content-Type': 'application/json',
52+
...headers,
53+
},
54+
body: JSON.stringify(data),
55+
};
56+
57+
const response = await fetch(url, requestOptions);
58+
if (!response.ok) {
59+
throw new Error(`HTTP error ${response.status}: ${response.statusText}`);
60+
}
61+
62+
return response.json();
63+
}
64+
4665
// Creates a confirmation <dialog> on the fly
4766
export function createConfirmationDialog({
4867
title,
Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ import handleTabPanels from './tabPanels';
2525
import handleToggleAdvanced from './toggleAdvanced';
2626
import handleUnlimitedInput from './unlimitedInput';
2727
import initRrdCharts from './rrdCharts';
28-
import * as helpers from './helpers';
29-
30-
window.Hestia = { helpers };
3128

3229
initListeners();
3330
focusFirstInput();

web/js/src/rrdCharts.js

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { post, getCssVariable } from './helpers';
2+
13
// Create Chart.js charts from in-page data on Task Monitor page
24
export default async function initRrdCharts() {
35
const chartCanvases = document.querySelectorAll('.js-rrd-chart');
@@ -11,7 +13,7 @@ export default async function initRrdCharts() {
1113
for (const chartCanvas of chartCanvases) {
1214
const service = chartCanvas.dataset.service;
1315
const period = chartCanvas.dataset.period;
14-
const rrdData = await fetchRrdData(service, period);
16+
const rrdData = await post('/list/rrd/ajax.php', { service, period });
1517
const chartData = prepareChartData(rrdData, period);
1618
const chartOptions = getChartOptions(rrdData.unit);
1719

@@ -31,16 +33,6 @@ async function loadChartJs() {
3133
return chartJsModule.Chart;
3234
}
3335

34-
async function fetchRrdData(service, period) {
35-
const response = await fetch('/list/rrd/ajax.php', {
36-
method: 'POST',
37-
headers: { 'Content-Type': 'application/json' },
38-
body: JSON.stringify({ service, period }),
39-
});
40-
41-
return response.json();
42-
}
43-
4436
function prepareChartData(rrdData, period) {
4537
return {
4638
labels: rrdData.data.map((_, index) => {
@@ -49,7 +41,7 @@ function prepareChartData(rrdData, period) {
4941
return formatLabel(date, period);
5042
}),
5143
datasets: rrdData.meta.legend.map((legend, legendIndex) => {
52-
const lineColor = Hestia.helpers.getCssVariable(`--chart-line-${legendIndex + 1}-color`);
44+
const lineColor = getCssVariable(`--chart-line-${legendIndex + 1}-color`);
5345

5446
return {
5547
label: legend,
@@ -75,8 +67,8 @@ function formatLabel(date, period) {
7567
}
7668

7769
function getChartOptions(unit) {
78-
const labelColor = Hestia.helpers.getCssVariable('--chart-label-color');
79-
const gridColor = Hestia.helpers.getCssVariable('--chart-grid-color');
70+
const labelColor = getCssVariable('--chart-label-color');
71+
const gridColor = getCssVariable('--chart-grid-color');
8072

8173
return {
8274
plugins: {

web/templates/pages/setup_webapp.php

Lines changed: 69 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -36,94 +36,89 @@
3636
</div>
3737
</div>
3838
<?php } ?>
39-
<div class="u-mt20">
40-
<?php
41-
foreach ($WebappInstaller->getOptions() as $form_name => $form_control) {
42-
$field_name = $WebappInstaller->formNs() . "_" . $form_name;
43-
$field_type = $form_control;
44-
$field_value = "";
45-
$field_label =
46-
isset($form_control["label"])
47-
? htmlentities($form_control["label"])
48-
: ucwords(str_replace([".","_"], " ", $form_name));
49-
$field_placeholder = "";
50-
if (is_array($form_control)) {
51-
$field_type = !empty($form_control["type"]) ? $form_control["type"] : "text";
52-
$field_value = !empty($form_control["value"]) ? $form_control["value"] : "";
53-
$field_placeholder = !empty($form_control["placeholder"]) ? $form_control["placeholder"] : "";
54-
}
55-
$field_value = htmlentities($field_value);
56-
$field_label = htmlentities($field_label);
57-
$field_name = htmlentities($field_name);
58-
$field_placeholder = htmlentities($field_placeholder);
59-
?>
60-
<div
61-
x-data="{
62-
value: '<?= !empty($field_value) ? $field_value : "" ?>'
63-
}"
64-
class="u-mb10"
65-
>
66-
<?php if ($field_type != "boolean"): ?>
67-
<label for="<?= $field_name ?>" class="form-label">
68-
<?= $field_label ?>
69-
<?php if ($field_type == "password") { ?>
70-
/
71-
<button
72-
x-on:click="value = Hestia.helpers.randomPassword()"
73-
class="form-link"
74-
type="button"
75-
>
76-
<?= _("Generate") ?>
39+
<?php
40+
foreach ($WebappInstaller->getOptions() as $form_name => $form_control) {
41+
$field_name = $WebappInstaller->formNs() . "_" . $form_name;
42+
$field_type = $form_control;
43+
$field_value = "";
44+
$field_label =
45+
isset($form_control["label"])
46+
? htmlentities($form_control["label"])
47+
: ucwords(str_replace([".","_"], " ", $form_name));
48+
$field_placeholder = "";
49+
if (is_array($form_control)) {
50+
$field_type = !empty($form_control["type"]) ? $form_control["type"] : "text";
51+
$field_value = !empty($form_control["value"]) ? $form_control["value"] : "";
52+
$field_placeholder = !empty($form_control["placeholder"]) ? $form_control["placeholder"] : "";
53+
}
54+
$field_value = htmlentities($field_value);
55+
$field_label = htmlentities($field_label);
56+
$field_name = htmlentities($field_name);
57+
$field_placeholder = htmlentities($field_placeholder);
58+
?>
59+
<div class="u-mb10">
60+
<?php if ($field_type != "boolean"): ?>
61+
<label for="<?= $field_name ?>" class="form-label">
62+
<?= $field_label ?>
63+
<?php if ($field_type == "password"): ?>
64+
<button type="button" title="<?= _("Generate") ?>" class="u-unstyled-button u-ml5 js-generate-password">
65+
<i class="fas fa-arrows-rotate icon-green"></i>
7766
</button>
78-
<?php } ?>
79-
</label>
80-
<?php endif; ?>
67+
<?php endif; ?>
68+
</label>
69+
<?php endif; ?>
8170

82-
<?php if ($field_type == 'select' && count($form_control['options'])) { ?>
83-
<select class="form-select" name="<?= $field_name ?>" id="<?= $field_name ?>">
84-
<?php
85-
foreach ($form_control['options'] as $key => $option) {
86-
$key = !is_numeric($key) ? $key : $option;
87-
$selected = !empty($form_control['value'] && $key == $form_control['value']) ? 'selected' : '';
88-
?>
89-
<option
90-
value="<?= $key ?>"
91-
<?= $selected ?>
92-
>
93-
<?= htmlentities($option) ?>
94-
</option>
95-
<?php } ?>
96-
</select>
97-
<?php
98-
} elseif ($field_type == "boolean") {
99-
$checked = !empty($field_value) ? "checked" : "";
100-
?>
101-
<div class="form-check">
71+
<?php if ($field_type == 'select' && count($form_control['options'])): ?>
72+
<select class="form-select" name="<?= $field_name ?>" id="<?= $field_name ?>">
73+
<?php foreach ($form_control['options'] as $key => $option):
74+
$key = !is_numeric($key) ? $key : $option;
75+
$selected = !empty($form_control['value'] && $key == $form_control['value']) ? 'selected' : ''; ?>
76+
<option value="<?= $key ?>" <?= $selected ?>>
77+
<?= htmlentities($option) ?>
78+
</option>
79+
<?php endforeach; ?>
80+
</select>
81+
<?php elseif ($field_type == "boolean"):
82+
$checked = !empty($field_value) ? "checked" : ""; ?>
83+
<div class="form-check">
84+
<input
85+
class="form-check-input"
86+
type="checkbox"
87+
name="<?= $field_name ?>"
88+
id="<?= $field_name ?>"
89+
value="true"
90+
<?= $checked ?>
91+
>
92+
<label for="<?= $field_name ?>">
93+
<?= $field_label ?>
94+
</label>
95+
</div>
96+
<?php else: ?>
97+
<?php if ($field_type == "password"): ?>
98+
<div class="u-pos-relative">
10299
<input
103-
class="form-check-input"
104-
type="checkbox"
100+
type="text"
101+
class="form-control js-password-input"
105102
name="<?= $field_name ?>"
106103
id="<?= $field_name ?>"
107-
value="true"
108-
<?= $checked ?>
104+
placeholder="<?= $field_placeholder ?>"
109105
>
110-
<label for="<?= $field_name ?>">
111-
<?= $field_label ?>
112-
</label>
106+
<div class="password-meter">
107+
<meter max="4" class="password-meter-input js-password-meter"></meter>
108+
</div>
113109
</div>
114-
<?php } else { ?>
110+
<?php else: ?>
115111
<input
116-
x-model="value"
117112
type="text"
118113
class="form-control"
119114
name="<?= $field_name ?>"
120115
id="<?= $field_name ?>"
121116
placeholder="<?= $field_placeholder ?>"
122117
>
123-
<?php } ?>
124-
</div>
125-
<?php } ?>
126-
</div>
118+
<?php endif; ?>
119+
<?php endif; ?>
120+
</div>
121+
<?php } ?>
127122
</div>
128123
</form>
129124
<?php } ?>

0 commit comments

Comments
 (0)