Files
homelabdspbx/app/operator_panel/resources/css/operator_panel.css
T
frytimo afceedd4cf Add a select list for the dialpad (#7983)
The old basic operator panel had a select list that would popup if a name was typed in the dialpad input box. This adds the select list to the new operator panel to allow the same functionality. This feature does not use the websocket connection.
2026-05-22 19:56:21 +00:00

827 lines
20 KiB
CSS

/* Contact Autocomplete Dropdown */
.op-autocomplete-list {
position: fixed;
margin: 0;
padding: 0;
background: #fff;
border: 1px solid #d0d7de;
border-radius: 6px;
box-shadow: 0 8px 24px rgba(0,0,0,.15);
list-style: none;
z-index: 9995;
max-height: 300px;
overflow-y: auto;
display: none;
}
.op-autocomplete-item {
padding: 8px 12px;
cursor: pointer;
border-bottom: 1px solid #f0f0f0;
transition: background-color .15s;
}
.op-autocomplete-item:last-child {
border-bottom: none;
}
.op-autocomplete-item:hover {
background-color: #f6f8fa;
}
.op-autocomplete-item.op-autocomplete-selected {
background-color: #e7f1ff;
color: #0d6efd;
}
.op-autocomplete-label {
font-size: 13px;
color: #24292f;
word-break: break-word;
}
.op-autocomplete-item.op-autocomplete-selected .op-autocomplete-label {
color: #0d6efd;
font-weight: 500;
}
/* Active Operator Panel — extension blocks */
.op-ext-grid {
display: flex;
flex-wrap: wrap;
gap: 0;
padding: 4px 0 12px;
}
/* Status buttons */
.op-status-btn {
border: 2px solid transparent;
border-radius: 4px;
padding: 3px 10px;
font-size: 11px;
font-weight: 700;
color: #fff;
cursor: pointer;
text-transform: uppercase;
letter-spacing: .5px;
line-height: 1.4;
transition: opacity .15s, border-color .15s;
opacity: 0.55;
}
.op-status-btn:hover { opacity: 0.8; }
.op-status-btn.active { opacity: 1; border-color: rgba(0,0,0,.35); }
/* Filter bar */
.op-filter-bar {
display: flex;
align-items: center;
gap: 10px;
padding: 6px 0 10px;
flex-wrap: wrap;
}
.op-group-filters {
display: inline-flex;
gap: 4px;
flex-wrap: wrap;
}
.op-group-filter-btn {
border: none;
border-radius: 4px;
padding: 3px 10px;
font-size: 11px;
font-weight: 700;
color: #fff;
cursor: pointer;
text-transform: uppercase;
letter-spacing: .3px;
line-height: 1.4;
background-color: #4a8cdb;
transition: opacity .15s;
opacity: 0.55;
}
.op-group-filter-btn:hover { opacity: 0.8; }
.op-group-filter-btn.active { opacity: 1; background-color: #2a7fff; }
.op-text-filter {
border: 1px solid #ccc;
border-radius: 4px;
padding: 3px 8px;
font-size: 12px;
line-height: 1.4;
width: 130px;
outline: none;
}
.op-text-filter:focus { border-color: #80bdff; box-shadow: 0 0 0 2px rgba(0,123,255,.15); }
/* Edit mode button */
.op-edit-btn {
border: 1px solid #ccc;
border-radius: 4px;
background: #fff;
padding: 3px 8px;
font-size: 14px;
cursor: pointer;
color: #6c757d;
line-height: 1;
transition: background .15s, color .15s;
}
.op-edit-btn:hover { background: #e9ecef; }
.op-edit-btn.active { background: #0d6efd; color: #fff; border-color: #0d6efd; }
/* Transfer mode toggle */
.op-transfer-mode {
display: inline-flex;
align-items: center;
gap: 5px;
margin-left: auto;
font-size: 12px;
color: #555;
white-space: nowrap;
}
.op-transfer-mode-label {
font-weight: 600;
color: #444;
}
.op-transfer-mode-btn {
padding: 2px 10px;
border: 1px solid #ccc;
border-radius: 4px;
background: #fff;
font-size: 11px;
font-weight: 600;
cursor: pointer;
color: #555;
transition: background .15s, color .15s, border-color .15s;
}
.op-transfer-mode-btn:hover { background: #e9ecef; }
.op-transfer-mode-btn.active { background: #0d6efd; color: #fff; border-color: #0d6efd; }
/* Context menu */
.op-ctx-menu {
position: fixed;
z-index: 9990;
background: #fff;
border: 1px solid #d0d7de;
border-radius: 6px;
box-shadow: 0 8px 24px rgba(0,0,0,.18);
min-width: 165px;
padding: 4px 0;
display: none;
margin: 0;
}
.op-ctx-header {
font-size: 11px;
color: #888;
padding: 3px 14px 2px;
text-transform: uppercase;
letter-spacing: .5px;
font-weight: 600;
user-select: none;
}
.op-ctx-separator {
height: 1px;
background: #e0e0e0;
margin: 4px 0;
}
.op-ctx-item {
display: flex;
align-items: center;
gap: 8px;
padding: 7px 14px;
font-size: 13px;
cursor: pointer;
color: #24292f;
white-space: nowrap;
border: none;
background: none;
width: 100%;
text-align: left;
line-height: 1.3;
}
.op-ctx-item:hover { background: #f0f6ff; }
.op-ctx-item .op-ctx-icon { font-size: 12px; opacity: .7; flex-shrink: 0; }
.op-ctx-danger { color: #c9242d; }
.op-ctx-danger:hover { background: #fff1f0; }
/* Attended transfer consultation bar */
.op-att-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 9980;
display: flex;
align-items: center;
gap: 12px;
padding: 10px 20px;
background: #198754;
color: #fff;
font-size: 14px;
font-weight: 600;
box-shadow: 0 -2px 8px rgba(0,0,0,.2);
}
.op-att-icon { font-size: 18px; }
.op-att-label { flex: 1; }
.op-att-btn {
padding: 6px 16px;
border: none;
border-radius: 4px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
}
.op-att-complete {
background: #fff;
color: #198754;
}
.op-att-complete:hover { background: #e9ecef; }
.op-att-cancel {
background: rgba(255,255,255,.2);
color: #fff;
}
.op-att-cancel:hover { background: rgba(255,255,255,.35); }
.op-ext-block {
display: flex;
width: 235px;
margin: 0 8px 8px 0;
border-style: solid;
border-width: 1px 3px;
border-radius: 5px;
border-color: #b9c5d8;
background-color: #e5eaf5;
box-shadow: 0 0 3px #c8cdd9;
position: relative;
overflow: hidden;
user-select: none;
cursor: default;
}
.op-ext-icon {
display: flex;
align-items: center;
justify-content: center;
min-width: 47px;
width: 47px;
background-color: #e5eaf5;
border-radius: 4px 0 0 4px;
color: #7a8499;
font-size: 26px;
padding: 4px 0;
}
.op-ext-status-icon {
font-size: 28px;
line-height: 1;
color: inherit;
}
.op-ext-contact-photo {
width: 36px;
height: 36px;
border-radius: 50%;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.op-ext-info {
flex: 1;
padding: 5px 8px 5px 8px;
background: #fff;
border-radius: 0 3px 3px 0;
font-family: arial, sans-serif;
font-size: 10px;
min-width: 0;
position: relative;
min-height: 50px;
}
.op-ext-number { font-size: 12px; font-weight: bold; color: #3164AD; line-height: 1.4; }
.op-ext-name { font-size: 10px; color: #444; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.op-ext-state-info { font-size: 10px; color: #555; margin-top: 3px; }
.op-ext-info.op-has-live-call { padding-right: 18px; padding-bottom: 15px; box-sizing: border-box; }
.op-ext-info.op-has-live-call .op-ext-state-info {
padding-right: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.op-ext-mine-label { position: absolute; top: 2px; right: 4px; font-size: 9px; color: #0d6efd; font-weight: 600; }
.op-ext-dial-wrap { position: absolute; top: 22px; right: 3px; }
.op-ext-dial-toggle {
border: none;
background: transparent;
padding: 0;
margin: 0;
line-height: 0;
cursor: pointer;
}
.op-ext-dial-toggle img { display: block; }
.op-ext-dial-input {
position: absolute;
top: -1px;
right: 18px;
width: 100px;
min-width: 100px;
max-width: 100px;
height: 20px;
padding: 1px 6px;
font-size: 12px;
border: 1px solid #b9c5d8;
border-radius: 2px;
background-color: #fff;
text-align: center;
}
.op-ext-call-meta {
position: absolute;
top: 2px;
right: 20px;
display: flex;
align-items: center;
gap: 6px;
}
.op-ext-call-direction {
width: 12px;
height: 12px;
border: none;
}
.op-ext-call-duration {
font-size: 12px;
color: #4a4a4a;
line-height: 1;
}
.op-ext-call-actions {
position: absolute;
bottom: 2px;
right: 18px;
display: flex;
align-items: center;
gap: 5px;
}
.op-ext-action-icon {
width: 12px;
height: 12px;
border: none;
cursor: pointer;
}
body.op-dragging, body.op-dragging * {
cursor: none !important;
}
/* user status: available — green */
.op-ext-available { border-color: #28a745; background-color: #d4edda; }
.op-ext-available .op-ext-icon { background-color: #c3e6cb; }
.op-ext-available .op-ext-icon .op-ext-status-icon { color: #1e7e34; }
.op-ext-available .op-ext-info { background-color: #eaf6ec; }
/* user status: on break — gold */
.op-ext-on-break { border-color: #b8860b; background-color: #fdf3d7; }
.op-ext-on-break .op-ext-icon { background-color: #f5e6b8; }
.op-ext-on-break .op-ext-icon .op-ext-status-icon { color: #8a6508; }
.op-ext-on-break .op-ext-info { background-color: #fef9eb; }
/* user status: do not disturb — red */
.op-ext-dnd { border-color: #dc3545; background-color: #f8d7da; }
.op-ext-dnd .op-ext-icon { background-color: #f1b0b7; }
.op-ext-dnd .op-ext-icon .op-ext-status-icon { color: #a71d2a; }
.op-ext-dnd .op-ext-info { background-color: #fce4e7; }
/* registered (no explicit status / no user attached) — blue */
.op-ext-registered { border-color: #4a8cdb; background-color: #d6e9f8; }
.op-ext-registered .op-ext-icon { background-color: #c3ddf2; }
.op-ext-registered .op-ext-icon .op-ext-status-icon { color: #2b6cb0; }
.op-ext-registered .op-ext-info { background-color: #eaf3fc; }
/* user status: logged out — grey */
.op-ext-logged-out { border-color: #9da5ae; background-color: #e2e3e5; }
.op-ext-logged-out .op-ext-icon { background-color: #d6d8db; }
.op-ext-logged-out .op-ext-icon .op-ext-status-icon { color: #1e7e34; }
.op-ext-logged-out .op-ext-info { background-color: #f0f1f2; }
.op-ext-logged-out .op-ext-number { color: #888; }
.op-ext-logged-out .op-ext-name { color: #999; }
/* unregistered — grey with muted content */
.op-ext-unregistered { border-color: #9da5ae; background-color: #e2e3e5; cursor: not-allowed; }
.op-ext-unregistered .op-ext-icon { background-color: #d6d8db; }
.op-ext-unregistered .op-ext-icon .op-ext-status-icon { color: #6c757d; opacity: .4; filter: grayscale(100%); }
.op-ext-unregistered .op-ext-info { background-color: #f0f1f2; color: #999; }
.op-ext-unregistered .op-ext-number { color: #999; }
.op-ext-unregistered .op-ext-name { color: #aaa; }
/* call state: ringing — blue */
.op-ext-ringing { border-color: #41b9eb; background-color: #a8dbf0; }
.op-ext-ringing .op-ext-icon { background-color: #a8dbf0; }
.op-ext-ringing .op-ext-icon .op-ext-status-icon { color: #0e6882; }
.op-ext-ringing .op-ext-info { background-color: #d1f1ff; }
/* call state: active (on call) — bright green */
.op-ext-active { border-color: #77d779; background-color: #baf4bb; }
.op-ext-active .op-ext-icon { background-color: #baf4bb; }
.op-ext-active .op-ext-icon .op-ext-status-icon { color: #2a7a2b; }
.op-ext-active .op-ext-info { background-color: #e1ffe2; }
/* call state: held — teal */
.op-ext-held { border-color: #5bbfd1; background-color: #b3e5ee; }
.op-ext-held .op-ext-icon { background-color: #b3e5ee; }
.op-ext-held .op-ext-icon .op-ext-status-icon { color: #1a6c7a; }
.op-ext-held .op-ext-info { background-color: #ddf4f8; }
/* mine highlight */
.op-ext-mine { border-width: 2px 3px !important; border-color: #0d6efd !important; }
/* drop target */
.op-ext-drop-over { box-shadow: 0 0 0 3px #0d6efd; }
.op-ext-drop-over .op-ext-info { background-color: #cfe2ff !important; }
/* section labels */
.op-ext-section-label { font-weight: 600; font-size: .85em; color: #6c757d; margin: 8px 0 4px; width: 100%; }
/* My Extensions container — own line above other groups */
#my_extensions_container:not(:empty) {
margin-bottom: 14px;
padding-bottom: 10px;
}
/* call group cards */
.op-group-card {
border: 1px solid #d0d8e5;
border-radius: 5px;
background-color: #fff;
box-shadow: 0 1px 3px #d0d8e5;
margin-bottom: 14px;
overflow: hidden;
display: inline-flex;
vertical-align: top;
margin-right: 14px;
}
.op-group-card.op-hidden { display: none; }
/* Card frame orientation by label position */
.op-group-card[data-position="left"] { flex-direction: row; }
.op-group-card[data-position="right"] { flex-direction: row-reverse; }
.op-group-card[data-position="top"] { flex-direction: column; }
.op-group-card[data-position="bottom"] { flex-direction: column-reverse; }
.op-group-card[data-position="hidden"] { flex-direction: row; }
/* Edit mode: cards grid container */
#extensions_container {
transition: background .2s;
}
#extensions_container.op-edit-mode .op-group-card {
cursor: grab;
border: 2px dashed #80bdff;
}
#extensions_container.op-edit-mode .op-group-card.sortable-ghost {
opacity: .4;
}
/* In edit mode, force hidden headers visible so Sortable has a drag handle */
#extensions_container.op-edit-mode .op-group-card[data-position="hidden"] .op-group-card-header {
display: flex;
min-width: 18px;
padding: 4px 2px;
cursor: grab;
background: #d0d8e5;
writing-mode: vertical-rl;
text-orientation: mixed;
transform: rotate(180deg);
align-items: center;
justify-content: center;
font-size: 11px;
color: #888;
}
/* Card header - default/left side orientation with vertical text */
.op-group-card-header {
background-color: #e5e9f0;
padding: 8px 4px;
font-size: 12px;
font-weight: 600;
color: #444;
border-right: 1px solid #d0d8e5;
font-family: Calibri, Candara, Segoe, 'Segoe UI', Optima, Arial, sans-serif;
writing-mode: vertical-rl;
text-orientation: mixed;
transform: rotate(180deg);
letter-spacing: .6px;
text-transform: uppercase;
white-space: nowrap;
display: flex;
align-items: center;
justify-content: center;
min-width: 34px;
}
/* Top position - horizontal text, border at bottom */
.op-group-card[data-position="top"] .op-group-card-header {
writing-mode: horizontal-tb;
transform: none;
border-right: none;
border-bottom: 1px solid #d0d8e5;
min-width: auto;
padding: 6px 12px;
}
/* Right position - vertical text, border at left */
.op-group-card[data-position="right"] .op-group-card-header {
writing-mode: vertical-rl;
text-orientation: mixed;
transform: rotate(0deg);
border-right: none;
border-left: 1px solid #d0d8e5;
min-width: 34px;
}
/* Bottom position - horizontal text, border at top */
.op-group-card[data-position="bottom"] .op-group-card-header {
writing-mode: horizontal-tb;
transform: none;
border-right: none;
border-top: 1px solid #d0d8e5;
min-width: auto;
padding: 6px 12px;
}
/* Hidden position - no header visible */
.op-group-card[data-position="hidden"] .op-group-card-header {
display: none;
}
/* Tooltip on hover - show group name in title attribute */
.op-group-card:hover {
cursor: help;
}
/* Hide text for "My Extensions" but keep grey shading */
.op-group-card-header.op-hidden-text {
color: transparent;
text-shadow: none;
}
.op-group-card-body {
padding: 10px 8px 4px;
flex: 1;
}
/* Top row in Extensions tab: My Extensions + Parked */
.op-top-row {
display: flex;
align-items: stretch;
gap: 14px;
flex-wrap: wrap;
margin-bottom: 14px;
}
#my_extensions_container,
#parked_side_container {
flex: 1 1 420px;
min-width: 320px;
}
#my_extensions_container:not(:empty),
#parked_side_container:not(:empty) {
margin-bottom: 0;
padding-bottom: 0;
}
/* Parked side panel */
.op-parked-card {
border: 1px solid #d0d8e5;
border-radius: 5px;
background-color: #fff;
box-shadow: 0 1px 3px #d0d8e5;
overflow: hidden;
display: flex;
flex-direction: row;
}
.op-parked-header {
background-color: #e5e9f0;
padding: 8px 4px;
font-size: 12px;
font-weight: 600;
color: #444;
border-right: 1px solid #d0d8e5;
font-family: Calibri, Candara, Segoe, 'Segoe UI', Optima, Arial, sans-serif;
writing-mode: vertical-rl;
text-orientation: mixed;
transform: rotate(180deg);
letter-spacing: .6px;
text-transform: uppercase;
white-space: nowrap;
display: flex;
align-items: center;
justify-content: center;
min-width: 34px;
}
.op-parked-list {
padding: 8px;
max-height: 280px;
overflow: auto;
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.op-parked-item {
width: 235px;
min-height: 50px;
border-style: solid;
border-width: 1px 3px;
border-color: #77d779;
border-radius: 5px;
background: #baf4bb;
box-shadow: 0 0 3px #c8cdd9;
padding: 5px 8px;
cursor: grab;
user-select: none;
line-height: 1.2;
position: relative;
overflow: hidden;
}
.op-parked-item:hover { background: #c8f6c9; border-color: #4fc453; }
.op-parked-main {
font-size: 12px;
font-weight: 700;
color: #3164AD;
padding-right: 74px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.op-parked-sub {
font-size: 10px;
color: #444;
margin-top: 2px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.op-parked-duration {
position: absolute;
top: 6px;
right: 8px;
font-size: 12px;
color: #4a4a4a;
line-height: 1;
}
.op-parked-drop-over {
box-shadow: 0 0 0 3px #0d6efd;
border-color: #0d6efd;
}
.op-parked-empty {
padding: 10px;
font-size: 12px;
color: #6c757d;
font-style: italic;
}
/* Calls tab three-pane layout */
.op-calls-layout {
display: flex;
gap: 14px;
align-items: stretch;
min-height: 420px;
}
.op-calls-pane {
min-width: 0;
display: flex;
flex-direction: column;
}
.op-calls-pane-left {
flex: 1 1 50%;
}
.op-calls-pane-right {
flex: 1 1 50%;
display: flex;
flex-direction: column;
gap: 14px;
}
.op-calls-pane-half {
flex: 1 1 0;
min-height: 0;
}
.op-calls-card {
height: 100%;
margin-bottom: 0;
display: flex;
flex-direction: column;
}
.op-calls-card-title {
padding: 8px 12px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
font-size: 12px;
font-weight: 700;
letter-spacing: .4px;
text-transform: uppercase;
color: #495057;
border-bottom: 1px solid #d0d8e5;
background: #f8f9fb;
cursor: grab;
user-select: none;
}
.op-calls-card-title:active {
cursor: grabbing;
}
.op-calls-drag-hint {
font-size: 10px;
font-weight: 700;
letter-spacing: .3px;
color: #6c757d;
}
.op-calls-slot-over {
position: relative;
}
.op-calls-slot-over::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border: 2px dashed #0d6efd;
border-radius: 6px;
pointer-events: none;
z-index: 10;
}
.op-calls-card-dragging {
opacity: 0.72;
}
.op-calls-table-wrap {
flex: 1;
min-height: 0;
overflow: auto;
}
.op-calls-card .list {
margin-bottom: 0;
}
.op-calls-empty {
margin: 10px 12px;
font-size: 12px;
font-style: italic;
}
@media (max-width: 980px) {
#my_extensions_container,
#parked_side_container {
flex-basis: 100%;
min-width: 0;
}
.op-calls-layout {
flex-direction: column;
min-height: 0;
}
.op-calls-pane-left,
.op-calls-pane-right,
.op-calls-pane-half {
flex: 1 1 auto;
}
}
/* HTML5 dialog styles */
.op-dialog {
border: 1px solid #ccc;
border-radius: 8px;
padding: 0;
max-width: 400px;
width: 90%;
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
}
.op-dialog::backdrop {
background: rgba(0,0,0,0.4);
}
.op-dialog-sm {
max-width: 320px;
}
.op-dialog-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 16px;
border-bottom: 1px solid #ddd;
}
.op-dialog-header h5 {
margin: 0;
font-size: 1.1rem;
}
.op-dialog-close {
background: none;
border: none;
font-size: 1.4rem;
cursor: pointer;
line-height: 1;
padding: 0 4px;
opacity: 0.6;
}
.op-dialog-close:hover { opacity: 1; }
.op-dialog-body {
padding: 16px;
}
.op-dialog-footer {
display: flex;
justify-content: flex-end;
gap: 8px;
padding: 12px 16px;
border-top: 1px solid #ddd;
}
.op-dialog-input {
width: 100%;
padding: 6px 10px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 0.95rem;
box-sizing: border-box;
}
.op-dialog-input:focus {
outline: 2px solid #0d6efd;
outline-offset: -1px;
}
.op-dialog-actions {
display: flex;
flex-direction: column;
gap: 8px;
}
.op-dialog-btn {
display: block;
width: 100%;
padding: 8px 16px;
border: none;
border-radius: 4px;
font-size: 0.95rem;
cursor: pointer;
color: #fff;
}
.op-btn-primary { background: #0d6efd; }
.op-btn-primary:hover { background: #0b5ed7; }
.op-btn-success { background: #198754; }
.op-btn-success:hover { background: #157347; }
.op-btn-info { background: #0dcaf0; color: #000; }
.op-btn-info:hover { background: #31d2f2; }
.op-btn-secondary { background: #6c757d; }
.op-btn-secondary:hover { background: #5c636a; }