@@ -3253,6 +3253,7 @@ sub app_html {
|
||
| 3253 | 3253 |
.host-alias-remove, .host-alias-add { min-height: 28px; padding: 3px 7px; font-size: 12px; }
|
| 3254 | 3254 |
.host-alias-remove { min-height: 0; padding: 0; border: 0; background: transparent; color: var(--bad); }
|
| 3255 | 3255 |
.host-alias-remove:hover { background: transparent; }
|
| 3256 |
+ .field-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
|
|
| 3256 | 3257 |
.host-cert-cell { min-width: 0; }
|
| 3257 | 3258 |
#page-vhosts .panel-head { align-items: center; padding-block: 10px; }
|
| 3258 | 3259 |
#page-vhosts .host-tools { flex-wrap: wrap; }
|
@@ -3383,6 +3384,7 @@ sub app_html {
|
||
| 3383 | 3384 |
<table> |
| 3384 | 3385 |
<thead> |
| 3385 | 3386 |
<tr> |
| 3387 |
+ <th style="width: 280px">Host</th> |
|
| 3386 | 3388 |
<th style="width: 140px">IP</th> |
| 3387 | 3389 |
<th>Aliases</th> |
| 3388 | 3390 |
<th style="width: 150px">Roles</th> |
@@ -3553,6 +3555,8 @@ sub app_html {
|
||
| 3553 | 3555 |
<div class="host-inline-editor-head"> |
| 3554 | 3556 |
<h2 id="host-form-title">New host</h2> |
| 3555 | 3557 |
<div class="host-inline-editor-tools"> |
| 3558 |
+ <button class="primary" type="submit" id="save-host" form="host-form">Save host</button> |
|
| 3559 |
+ <button class="danger" type="button" id="delete-host">Delete host</button> |
|
| 3556 | 3560 |
<button type="button" id="cancel-host-form">Close</button> |
| 3557 | 3561 |
</div> |
| 3558 | 3562 |
</div> |
@@ -3561,16 +3565,12 @@ sub app_html {
|
||
| 3561 | 3565 |
<label>FQDN<input name="fqdn" required></label> |
| 3562 | 3566 |
<label>Status<select name="status"><option>active</option><option>planned</option><option>retired</option></select></label> |
| 3563 | 3567 |
<label>IP<input name="ip" required></label> |
| 3564 |
- <label class="span2">Aliases<textarea name="aliases"></textarea></label> |
|
| 3568 |
+ <label class="span2"><span class="field-head"><span>Aliases</span><button type="button" id="host-add-alias-editor" class="host-alias-add" title="Add alias">+</button></span><textarea name="aliases"></textarea></label> |
|
| 3565 | 3569 |
<label>Roles<input name="roles"></label> |
| 3566 | 3570 |
<label>Sources<input name="sources"></label> |
| 3567 | 3571 |
<label>Monitoring<select name="monitoring"><option>pending</option><option>enabled</option><option>disabled</option></select></label> |
| 3568 | 3572 |
<label>Notes<input name="notes"></label> |
| 3569 | 3573 |
<div id="host-form-message" class="span2 form-message" aria-live="polite"></div> |
| 3570 |
- <div class="span2 form-actions"> |
|
| 3571 |
- <button class="primary" type="submit" id="save-host">Save host</button> |
|
| 3572 |
- <button class="danger" type="button" id="delete-host">Delete host</button> |
|
| 3573 |
- </div> |
|
| 3574 | 3574 |
</form>`; |
| 3575 | 3575 |
const hostForm = hostFormShell.querySelector('#host-form');
|
| 3576 | 3576 |
const hostFormTitle = hostFormShell.querySelector('#host-form-title');
|
@@ -3578,10 +3578,11 @@ sub app_html {
|
||
| 3578 | 3578 |
const saveHostButton = hostFormShell.querySelector('#save-host');
|
| 3579 | 3579 |
const deleteHostButton = hostFormShell.querySelector('#delete-host');
|
| 3580 | 3580 |
const cancelHostButton = hostFormShell.querySelector('#cancel-host-form');
|
| 3581 |
+ const hostAddAliasEditorButton = hostFormShell.querySelector('#host-add-alias-editor');
|
|
| 3581 | 3582 |
const hostEditorRow = document.createElement('tr');
|
| 3582 | 3583 |
hostEditorRow.className = 'host-inline-row'; |
| 3583 | 3584 |
const hostEditorCell = document.createElement('td');
|
| 3584 |
- hostEditorCell.colSpan = 7; |
|
| 3585 |
+ hostEditorCell.colSpan = 8; |
|
| 3585 | 3586 |
hostEditorRow.appendChild(hostEditorCell); |
| 3586 | 3587 |
hostEditorCell.appendChild(hostFormShell); |
| 3587 | 3588 |
const PAGE_PATHS = {
|
@@ -4042,6 +4043,7 @@ sub app_html {
|
||
| 4042 | 4043 |
const problems = state.problems.filter(p => p.host_id === h.id); |
| 4043 | 4044 |
const cls = problems.length ? 'warn' : 'ok'; |
| 4044 | 4045 |
return `<tr data-id="${escapeHtml(h.id)}" data-host-fqdn="${escapeHtml(h.fqdn || '')}">
|
| 4046 |
+ <td><span class="pill canonical" title="${escapeHtml(h.fqdn || '')}">${escapeHtml(h.fqdn || '')}</span></td>
|
|
| 4045 | 4047 |
<td>${escapeHtml(h.ip || '')}</td>
|
| 4046 | 4048 |
<td>${renderHostAliasCell(h)}</td>
|
| 4047 | 4049 |
<td>${(h.roles || []).map(n => `<span class="pill">${escapeHtml(n)}</span>`).join('')}</td>
|
@@ -4085,7 +4087,6 @@ sub app_html {
|
||
| 4085 | 4087 |
} |
| 4086 | 4088 |
|
| 4087 | 4089 |
function renderHostAliasCell(host) {
|
| 4088 |
- const canonical = host.fqdn ? `<span class="pill canonical host-alias-pill"><span class="host-alias-label">${escapeHtml(host.fqdn)}</span></span>` : '';
|
|
| 4089 | 4090 |
const aliases = (host.aliases || []).map(name => `<span class="pill host-alias-pill"> |
| 4090 | 4091 |
<span class="host-alias-label">${escapeHtml(name)}</span>
|
| 4091 | 4092 |
<button type="button" class="host-alias-remove" data-host-alias-remove="${escapeHtml(host.fqdn || '')}" data-host-alias-name="${escapeHtml(name)}" title="Delete ${escapeHtml(name)}">x</button>
|
@@ -4094,7 +4095,7 @@ sub app_html {
|
||
| 4094 | 4095 |
<span class="host-alias-label">${escapeHtml(name)}</span>
|
| 4095 | 4096 |
</span>`).join('');
|
| 4096 | 4097 |
return `<div class="host-alias-cell"> |
| 4097 |
- <div class="host-alias-list">${canonical}${aliases}${derivedAliases}<button type="button" class="host-alias-add" data-host-alias-add="${escapeHtml(host.fqdn || '')}" title="Add alias">+</button></div>
|
|
| 4098 |
+ <div class="host-alias-list">${aliases}${derivedAliases}</div>
|
|
| 4098 | 4099 |
</div>`; |
| 4099 | 4100 |
} |
| 4100 | 4101 |
|
@@ -4368,6 +4369,36 @@ sub app_html {
|
||
| 4368 | 4369 |
return payload; |
| 4369 | 4370 |
} |
| 4370 | 4371 |
|
| 4372 |
+ function aliasEditorValues() {
|
|
| 4373 |
+ return (hostField('aliases').value || '')
|
|
| 4374 |
+ .split(/[\s,]+/) |
|
| 4375 |
+ .map(value => String(value || '').trim().toLowerCase()) |
|
| 4376 |
+ .filter(Boolean); |
|
| 4377 |
+ } |
|
| 4378 |
+ |
|
| 4379 |
+ function appendAliasInEditor() {
|
|
| 4380 |
+ const fqdn = String(hostField('fqdn').value || '').trim().toLowerCase();
|
|
| 4381 |
+ const derived = shortAliasForFqdn(fqdn); |
|
| 4382 |
+ const alias = String(prompt(fqdn ? `Alias nou pentru ${fqdn}` : 'Alias nou', '') || '').trim().toLowerCase();
|
|
| 4383 |
+ if (!alias) return; |
|
| 4384 |
+ if (fqdn && alias === fqdn) {
|
|
| 4385 |
+ msg('fqdn-ul hostului este deja numele principal');
|
|
| 4386 |
+ return; |
|
| 4387 |
+ } |
|
| 4388 |
+ if (derived && alias === derived) {
|
|
| 4389 |
+ msg('aliasul derivat din fqdn se genereaza automat');
|
|
| 4390 |
+ return; |
|
| 4391 |
+ } |
|
| 4392 |
+ const aliases = aliasEditorValues(); |
|
| 4393 |
+ if (aliases.includes(alias)) {
|
|
| 4394 |
+ msg(`aliasul ${alias} este deja in editor`);
|
|
| 4395 |
+ return; |
|
| 4396 |
+ } |
|
| 4397 |
+ hostField('aliases').value = aliases.concat(alias).join('\n');
|
|
| 4398 |
+ hostField('aliases').dispatchEvent(new Event('input', { bubbles: true }));
|
|
| 4399 |
+ hostField('aliases').focus();
|
|
| 4400 |
+ } |
|
| 4401 |
+ |
|
| 4371 | 4402 |
async function addHostAlias(hostFqdn) {
|
| 4372 | 4403 |
if (!await ensureAuthenticated('Autentifica-te inainte de salvare.')) return;
|
| 4373 | 4404 |
const host = hostByFqdn(hostFqdn); |
@@ -4647,7 +4678,7 @@ sub app_html {
|
||
| 4647 | 4678 |
hostFormShell.hidden = true; |
| 4648 | 4679 |
return; |
| 4649 | 4680 |
} |
| 4650 |
- hostEditorCell.colSpan = 7; |
|
| 4681 |
+ hostEditorCell.colSpan = 8; |
|
| 4651 | 4682 |
const tbody = $('hosts');
|
| 4652 | 4683 |
if (!tbody) return; |
| 4653 | 4684 |
if (hostEditorTarget === '__new__') {
|
@@ -4682,6 +4713,7 @@ sub app_html {
|
||
| 4682 | 4713 |
saveHostButton.disabled = hostFormBusy; |
| 4683 | 4714 |
deleteHostButton.disabled = hostFormBusy || hostFormMode !== 'edit'; |
| 4684 | 4715 |
cancelHostButton.disabled = hostFormBusy; |
| 4716 |
+ hostAddAliasEditorButton.disabled = hostFormBusy; |
|
| 4685 | 4717 |
} |
| 4686 | 4718 |
|
| 4687 | 4719 |
function setHostFormMessage(text, isError = false) {
|
@@ -4896,6 +4928,7 @@ sub app_html {
|
||
| 4896 | 4928 |
$('debug-db-refresh').addEventListener('click', () => renderDebugDatabase().catch(e => {
|
| 4897 | 4929 |
if (!isAuthLost(e)) msg(e.message); |
| 4898 | 4930 |
})); |
| 4931 |
+ hostAddAliasEditorButton.addEventListener('click', appendAliasInEditor);
|
|
| 4899 | 4932 |
cancelHostButton.addEventListener('click', () => closeHostForm());
|
| 4900 | 4933 |
|
| 4901 | 4934 |
hostForm.addEventListener('submit', async (event) => {
|