Showing 1 changed files with 42 additions and 9 deletions
+42 -9
scripts/host_manager.pl
@@ -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) => {