From: Alexander Moisseev Date: Thu, 2 Jul 2026 10:35:46 +0000 (+0300) Subject: [Rework] WebUI: remove FooTable X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dcc7c54ea54baeabaad22d0f1b5bfd6c8903f804;p=thirdparty%2Frspamd.git [Rework] WebUI: remove FooTable FooTable was superseded by Tabulator across all tables (Phases 0-3). Remove the vendored library/CSS, the footable-fontawesome icon module, and every remaining reference: - index.html: drop the two tags - main.js: drop the requirejs path and shim - rspamd.js: drop the app/footable-fontawesome require; stickyTabs runs directly (declared module dependency) - common.js: delete dead appendButtonsToFtFilterDropdown (no callers) - rspamd.css: drop all .footable rules and the dead .footable-details / .footable-filtering-search selectors Rename column-options dropdown hooks ft-columns-* -> tab-columns-* (Tabulator; consistent with tab-utils.js). Legacy history path kept. --- diff --git a/interface/ARCHITECTURE.md b/interface/ARCHITECTURE.md index 6f338e316a..96a4920687 100644 --- a/interface/ARCHITECTURE.md +++ b/interface/ARCHITECTURE.md @@ -27,7 +27,7 @@ The Rspamd WebUI is a single-page application (SPA) providing a web interface fo - **D3.js** - Base visualization library - **D3Evolution** - Time-series line charts (throughput graphs) - **D3Pie** - Pie charts (action distribution) -- **FooTable** - Responsive data tables with sorting, filtering, and pagination +- **Tabulator** - Responsive data tables with sorting, filtering, and pagination ### Code Editing - **CodeJar** - Lightweight code editor @@ -64,8 +64,7 @@ interface/ │ │ ├── config.js # Configuration tab (actions, maps) │ │ ├── upload.js # Scan tab (message upload/scanning) │ │ ├── selectors.js # Selectors tab (testing selectors) -│ │ ├── libft.js # FooTable utilities (history table rendering) -│ │ └── footable-fontawesome.js # FooTable Font Awesome integration +│ │ └── libft.js # Tabulator table utilities (history/scan rendering) │ └── lib/ # Third-party libraries (minified) ├── img/ # Images and logos └── README.md # Setup instructions @@ -130,7 +129,7 @@ Renders time-series graphs and pie charts (Throughput tab) using D3Evolution and ### Message History `js/app/history.js` (data fetching), `js/app/libft.js` (table rendering) -Displays processed message history (History tab), handles FooTable initialization, row expansion, symbol details +Displays processed message history (History tab), handles Tabulator initialization, row expansion, symbol details ### Configuration Management `js/app/config.js` @@ -155,12 +154,7 @@ Tests Rspamd selectors against messages (Selectors tab) ### Table Utilities `js/app/libft.js` -Shared utilities for FooTable: data preprocessing, table initialization, pagination, sorting - -### FooTable Icons -`js/app/footable-fontawesome.js` - -Integrates Font Awesome icons with FooTable +Shared Tabulator table utilities: data preprocessing, table initialization, pagination, sorting ## Data Flow @@ -180,9 +174,9 @@ Use function expressions `function() {}` when you need `this` context (event tar Most API communication goes through `common.query(endpoint, options)` which handles multi-server requests, authentication, progress tracking, and error handling. ### Table Management -Tables use FooTable library. Two main patterns: -- **Initial load**: destroy old table → process data → initialize FooTable → bind event handlers -- **Update data**: use FooTable API to update existing table without re-initialization +Tables use Tabulator. Two main patterns: +- **Initial load**: destroy old table → process data → initialize Tabulator → bind event handlers +- **Update data**: use Tabulator API to update existing table without re-initialization ### Module Structure Each tab module returns a `ui` object with public methods (e.g., `ui.getSymbols()`, `ui.draw()`). These methods are called when tabs are activated. @@ -202,7 +196,7 @@ Each tab module returns a `ui` object with public methods (e.g., `ui.getSymbols( **Global state:** - `common.neighbours[]` - Configured servers -- `common.tables{}` - FooTable instances +- `common.tables{}` - Tabulator instances - `timer_id[]` - Active refresh timers - `checked_server` - Currently selected server diff --git a/interface/css/FooTable.FontAwesome.css b/interface/css/FooTable.FontAwesome.css deleted file mode 100644 index aacebfdb6a..0000000000 --- a/interface/css/FooTable.FontAwesome.css +++ /dev/null @@ -1,28 +0,0 @@ -/* Hide the old Glyphicons pseudo-elements */ -.fooicon::before, -.fooicon::after { - content: none !important; - display: none; -} - -/* Critical: allow clicks to pass through SVG to parent span */ -.fooicon svg { - pointer-events: none; -} - -/* Smaller toggle icon and icons in footable header */ -.footable-header .fooicon svg, -.footable-toggle.fooicon svg { - font-size: 12px; -} - -/* Stop span rotation for loader - we animate the SVG instead */ -.fooicon-loader { - animation: none !important; - transform: none !important; -} - -/* Make spinner icon larger to match original size */ -.fooicon-loader.fooicon svg { - font-size: 36px; -} diff --git a/interface/css/footable.standalone.min.css b/interface/css/footable.standalone.min.css deleted file mode 100644 index 0ac5adf5e8..0000000000 --- a/interface/css/footable.standalone.min.css +++ /dev/null @@ -1 +0,0 @@ -.footable .btn,.footable .caret{display:inline-block;vertical-align:middle}.footable-details.table,.footable-details.table *,.footable.table,.footable.table *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.footable-details.table th,.footable.table th{text-align:left}.footable-details.table,.footable.table{width:100%;max-width:100%;margin-bottom:20px}.footable-details.table>caption+thead>tr:first-child>td,.footable-details.table>caption+thead>tr:first-child>th,.footable-details.table>colgroup+thead>tr:first-child>td,.footable-details.table>colgroup+thead>tr:first-child>th,.footable-details.table>thead:first-child>tr:first-child>td,.footable-details.table>thead:first-child>tr:first-child>th,.footable.table>caption+thead>tr:first-child>td,.footable.table>caption+thead>tr:first-child>th,.footable.table>colgroup+thead>tr:first-child>td,.footable.table>colgroup+thead>tr:first-child>th,.footable.table>thead:first-child>tr:first-child>td,.footable.table>thead:first-child>tr:first-child>th{border-top:0}.footable-details.table>tbody>tr>td,.footable-details.table>tbody>tr>th,.footable-details.table>tfoot>tr>td,.footable-details.table>tfoot>tr>th,.footable-details.table>thead>tr>td,.footable-details.table>thead>tr>th,.footable.table>tbody>tr>td,.footable.table>tbody>tr>th,.footable.table>tfoot>tr>td,.footable.table>tfoot>tr>th,.footable.table>thead>tr>td,.footable.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.footable-details.table>thead>tr>td,.footable-details.table>thead>tr>th,.footable.table>thead>tr>td,.footable.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.footable-details.table-condensed>tbody>tr>td,.footable-details.table-condensed>tbody>tr>th,.footable-details.table-condensed>tfoot>tr>td,.footable-details.table-condensed>tfoot>tr>th,.footable-details.table-condensed>thead>tr>td,.footable-details.table-condensed>thead>tr>th,.footable.table-condensed>tbody>tr>td,.footable.table-condensed>tbody>tr>th,.footable.table-condensed>tfoot>tr>td,.footable.table-condensed>tfoot>tr>th,.footable.table-condensed>thead>tr>td,.footable.table-condensed>thead>tr>th{padding:5px}.footable-details.table-bordered,.footable-details.table-bordered>tbody>tr>td,.footable-details.table-bordered>tbody>tr>th,.footable-details.table-bordered>tfoot>tr>td,.footable-details.table-bordered>tfoot>tr>th,.footable-details.table-bordered>thead>tr>td,.footable-details.table-bordered>thead>tr>th,.footable.table-bordered,.footable.table-bordered>tbody>tr>td,.footable.table-bordered>tbody>tr>th,.footable.table-bordered>tfoot>tr>td,.footable.table-bordered>tfoot>tr>th,.footable.table-bordered>thead>tr>td,.footable.table-bordered>thead>tr>th{border:1px solid #ddd}.footable-details.table-bordered>thead>tr>td,.footable-details.table-bordered>thead>tr>th,.footable.table-bordered>thead>tr>td,.footable.table-bordered>thead>tr>th{border-bottom-width:2px}.footable-details.table-striped>tbody>tr:nth-child(odd),.footable.table-striped>tbody>tr:nth-child(odd){background-color:#f9f9f9}.footable-details.table-hover>tbody>tr:hover,.footable.table-hover>tbody>tr:hover{background-color:#f5f5f5}.footable .btn{padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-appearance:button;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px;overflow:visible;text-transform:none}.footable .btn.focus,.footable .btn:focus,.footable .btn:hover{color:#333;text-decoration:none}.footable .btn-default{color:#333;background-color:#fff;border-color:#ccc}.footable .btn-default.active,.footable .btn-default.focus,.footable .btn-default:active,.footable .btn-default:focus,.footable .btn-default:hover,.footable .open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.footable .btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.footable .btn-primary.active,.footable .btn-primary.focus,.footable .btn-primary:active,.footable .btn-primary:focus,.footable .btn-primary:hover,.footable .open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.footable .btn-group,.footable .btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.footable .btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.footable .btn-group>.btn:first-child{margin-left:0}.footable .btn-group-vertical>.btn,.footable .btn-group>.btn{position:relative;float:left}.footable .btn-group-xs>.btn,.footable .btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.footable .btn-group-sm>.btn,.footable .btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.footable .btn-group-lg>.btn,.footable .btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.footable .caret{width:0;height:0;margin-left:2px;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.footable .btn .caret{margin-left:0}.form-group{margin-bottom:15px}.footable .form-control{display:block;width:100%;height:34px;padding:6px 12px;margin:0;font-family:inherit;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.footable .input-group{position:relative;display:table;border-collapse:separate}.footable .input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.footable .input-group-btn{position:relative;font-size:0}.footable .input-group-addon,.footable .input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.footable .input-group .form-control,.footable .input-group-addon,.footable .input-group-btn{display:table-cell}.footable .input-group-btn:last-child>.btn,.footable .input-group-btn:last-child>.btn-group,.footable .input-group-btn>.btn+.btn{margin-left:-1px}.footable .input-group-btn>.btn{position:relative}.footable .input-group-btn>.btn:active,.footable .input-group-btn>.btn:focus,.footable .input-group-btn>.btn:hover{z-index:2}.footable .input-group .form-control:first-child,.footable .input-group-addon:first-child,.footable .input-group-btn:first-child>.btn,.footable .input-group-btn:first-child>.btn-group>.btn,.footable .input-group-btn:first-child>.dropdown-toggle,.footable .input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.footable .input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.footable .input-group .form-control:last-child,.footable .input-group-addon:last-child,.footable .input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.footable .input-group-btn:first-child>.btn:not(:first-child),.footable .input-group-btn:last-child>.btn,.footable .input-group-btn:last-child>.btn-group>.btn,.footable .input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.footable .checkbox,.footable .radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.footable .checkbox label,.footable .radio label{max-width:100%;min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.footable .checkbox input[type=checkbox],.footable .checkbox-inline input[type=checkbox],.footable .radio input[type=radio],.footable .radio-inline input[type=radio]{position:absolute;margin:4px 0 0 -20px;line-height:normal}.footable .dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.footable .open>.dropdown-menu{display:block}.footable .dropdown-menu-right{right:0;left:auto}.footable .dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.footable .dropdown-menu>li>a:focus,.footable .dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.footable .pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.footable .pagination>li{display:inline}.footable .pagination>li:first-child>a,.footable .pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.footable .pagination>li>a,.footable .pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.footable .pagination>li>a:focus,.footable .pagination>li>a:hover,.footable .pagination>li>span:focus,.footable .pagination>li>span:hover{color:#23527c;background-color:#eee;border-color:#ddd}.footable .pagination>.active>a,.footable .pagination>.active>a:focus,.footable .pagination>.active>a:hover,.footable .pagination>.active>span,.footable .pagination>.active>span:focus,.footable .pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.footable .pagination>.disabled>a,.footable .pagination>.disabled>a:focus,.footable .pagination>.disabled>a:hover,.footable .pagination>.disabled>span,.footable .pagination>.disabled>span:focus,.footable .pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.footable .label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.footable .label-default{background-color:#777}.footable-loader.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.footable .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}table.footable-details,table.footable>thead>tr.footable-filtering>th div.form-group{margin-bottom:0}@media (min-width:768px){.footable .form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.footable .form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.footable .form-inline .input-group{display:inline-table;vertical-align:middle}.footable .form-inline .input-group .form-control,.footable .form-inline .input-group .input-group-addon,.footable .form-inline .input-group .input-group-btn{width:auto}.footable .form-inline .input-group>.form-control{width:100%}}table.footable,table.footable-details{position:relative;width:100%;border-spacing:0;border-collapse:collapse}table.footable-hide-fouc{display:none}table>tbody>tr>td>span.footable-toggle{margin-right:8px;opacity:.3}table>tbody>tr>td>span.footable-toggle.last-column{margin-left:8px;float:right}table.table-condensed>tbody>tr>td>span.footable-toggle{margin-right:5px}table.footable-details>tbody>tr>th:nth-child(1){min-width:40px;width:120px}table.footable-details>tbody>tr>td:nth-child(2){word-break:break-all}table.footable-details>tbody>tr:first-child>td,table.footable-details>tbody>tr:first-child>th,table.footable-details>tfoot>tr:first-child>td,table.footable-details>tfoot>tr:first-child>th,table.footable-details>thead>tr:first-child>td,table.footable-details>thead>tr:first-child>th{border-top-width:0}table.footable-details.table-bordered>tbody>tr:first-child>td,table.footable-details.table-bordered>tbody>tr:first-child>th,table.footable-details.table-bordered>tfoot>tr:first-child>td,table.footable-details.table-bordered>tfoot>tr:first-child>th,table.footable-details.table-bordered>thead>tr:first-child>td,table.footable-details.table-bordered>thead>tr:first-child>th{border-top-width:1px}div.footable-loader{vertical-align:middle;text-align:center;height:300px;position:relative}div.footable-loader>span.fooicon{display:inline-block;opacity:.3;font-size:30px;line-height:32px;width:32px;height:32px;margin-top:-16px;margin-left:-16px;position:absolute;top:50%;left:50%;-webkit-animation:fooicon-spin-r 2s infinite linear;animation:fooicon-spin-r 2s infinite linear}table.footable>tbody>tr.footable-empty>td{vertical-align:middle;text-align:center;font-size:30px}table.footable>tbody>tr>td,table.footable>tbody>tr>th{display:none}table.footable>tbody>tr.footable-detail-row>td,table.footable>tbody>tr.footable-detail-row>th,table.footable>tbody>tr.footable-empty>td,table.footable>tbody>tr.footable-empty>th{display:table-cell}@-webkit-keyframes fooicon-spin-r{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fooicon-spin-r{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fooicon{display:inline-block;font-size:inherit;font-family:FontAwesome!important;font-style:normal;font-weight:400;line-height:1;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translate(0,0)}.fooicon:after,.fooicon:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fooicon-loader:before{content:"\f01e"}.fooicon-plus:before{content:"\f067"}.fooicon-minus:before{content:"\f068"}.fooicon-search:before{content:"\f002"}.fooicon-remove:before{content:"\f00d"}.fooicon-sort:before{content:"\f0dc"}.fooicon-sort-asc:before{content:"\f160"}.fooicon-sort-desc:before{content:"\f161"}.fooicon-pencil:before{content:"\f040"}.fooicon-trash:before{content:"\f1f8"}.fooicon-eye-close:before{content:"\f070"}.fooicon-flash:before{content:"\f0e7"}.fooicon-cog:before{content:"\f013"}.fooicon-stats:before{content:"\f080"}table.footable>thead>tr.footable-filtering>th{border-bottom-width:1px;font-weight:400}.footable-filtering-external.footable-filtering-right,table.footable.footable-filtering-right>thead>tr.footable-filtering>th,table.footable>thead>tr.footable-filtering>th{text-align:right}.footable-filtering-external.footable-filtering-left,table.footable.footable-filtering-left>thead>tr.footable-filtering>th{text-align:left}.footable-filtering-external.footable-filtering-center,.footable-paging-external.footable-paging-center,table.footable-paging-center>tfoot>tr.footable-paging>td,table.footable.footable-filtering-center>thead>tr.footable-filtering>th,table.footable>tfoot>tr.footable-paging>td{text-align:center}table.footable>thead>tr.footable-filtering>th div.form-group+div.form-group{margin-top:5px}table.footable>thead>tr.footable-filtering>th div.input-group{width:100%}.footable-filtering-external ul.dropdown-menu>li>a.checkbox,table.footable>thead>tr.footable-filtering>th ul.dropdown-menu>li>a.checkbox{margin:0;display:block;position:relative}.footable-filtering-external ul.dropdown-menu>li>a.checkbox>label,table.footable>thead>tr.footable-filtering>th ul.dropdown-menu>li>a.checkbox>label{display:block;padding-left:20px}.footable-filtering-external ul.dropdown-menu>li>a.checkbox input[type=checkbox],table.footable>thead>tr.footable-filtering>th ul.dropdown-menu>li>a.checkbox input[type=checkbox]{position:absolute;margin-left:-20px}@media (min-width:768px){table.footable>thead>tr.footable-filtering>th div.input-group{width:auto}table.footable>thead>tr.footable-filtering>th div.form-group{margin-left:2px;margin-right:2px}table.footable>thead>tr.footable-filtering>th div.form-group+div.form-group{margin-top:0}}table.footable>tbody>tr>td.footable-sortable,table.footable>tbody>tr>th.footable-sortable,table.footable>tfoot>tr>td.footable-sortable,table.footable>tfoot>tr>th.footable-sortable,table.footable>thead>tr>td.footable-sortable,table.footable>thead>tr>th.footable-sortable{position:relative;padding-right:30px;cursor:pointer}td.footable-sortable>span.fooicon,th.footable-sortable>span.fooicon{position:absolute;right:6px;top:50%;margin-top:-7px;opacity:0;transition:opacity .3s ease-in}td.footable-sortable.footable-asc>span.fooicon,td.footable-sortable.footable-desc>span.fooicon,td.footable-sortable:hover>span.fooicon,th.footable-sortable.footable-asc>span.fooicon,th.footable-sortable.footable-desc>span.fooicon,th.footable-sortable:hover>span.fooicon{opacity:1}table.footable-sorting-disabled td.footable-sortable.footable-asc>span.fooicon,table.footable-sorting-disabled td.footable-sortable.footable-desc>span.fooicon,table.footable-sorting-disabled td.footable-sortable:hover>span.fooicon,table.footable-sorting-disabled th.footable-sortable.footable-asc>span.fooicon,table.footable-sorting-disabled th.footable-sortable.footable-desc>span.fooicon,table.footable-sorting-disabled th.footable-sortable:hover>span.fooicon{opacity:0;visibility:hidden}.footable-paging-external ul.pagination,table.footable>tfoot>tr.footable-paging>td>ul.pagination{margin:10px 0 0}.footable-paging-external span.label,table.footable>tfoot>tr.footable-paging>td>span.label{display:inline-block;margin:0 0 10px;padding:4px 10px}.footable-paging-external.footable-paging-left,table.footable-paging-left>tfoot>tr.footable-paging>td{text-align:left}.footable-paging-external.footable-paging-right,table.footable-editing-right td.footable-editing,table.footable-editing-right tr.footable-editing,table.footable-paging-right>tfoot>tr.footable-paging>td{text-align:right}ul.pagination>li.footable-page{display:none}ul.pagination>li.footable-page.visible{display:inline}td.footable-editing{width:90px;max-width:90px}table.footable-editing-no-delete td.footable-editing,table.footable-editing-no-edit td.footable-editing,table.footable-editing-no-view td.footable-editing{width:70px;max-width:70px}table.footable-editing-no-delete.footable-editing-no-view td.footable-editing,table.footable-editing-no-edit.footable-editing-no-delete td.footable-editing,table.footable-editing-no-edit.footable-editing-no-view td.footable-editing{width:50px;max-width:50px}table.footable-editing-no-edit.footable-editing-no-delete.footable-editing-no-view td.footable-editing,table.footable-editing-no-edit.footable-editing-no-delete.footable-editing-no-view th.footable-editing{width:0;max-width:0;display:none!important}table.footable-editing-left td.footable-editing,table.footable-editing-left tr.footable-editing{text-align:left}table.footable-editing button.footable-add,table.footable-editing button.footable-hide,table.footable-editing-show button.footable-show,table.footable-editing.footable-editing-always-show button.footable-hide,table.footable-editing.footable-editing-always-show button.footable-show,table.footable-editing.footable-editing-always-show.footable-editing-no-add tr.footable-editing{display:none}table.footable-editing.footable-editing-always-show button.footable-add,table.footable-editing.footable-editing-show button.footable-add,table.footable-editing.footable-editing-show button.footable-hide{display:inline-block} \ No newline at end of file diff --git a/interface/css/rspamd.css b/interface/css/rspamd.css index 137279f4e5..e6986b57f8 100644 --- a/interface/css/rspamd.css +++ b/interface/css/rspamd.css @@ -108,12 +108,6 @@ td.warning { } } -/* Tweak FooTable for Bootstrap 5 */ -.footable .btn, -.footable .form-control { - border-radius: 0.375rem; -} - /* bootstrap 4 additionals */ .btn-group-xs > .btn, .btn-xs { @@ -149,80 +143,6 @@ textarea { resize: vertical; } -/* Tweak FooTable for Bootstrap 4 */ -.footable .dropdown-toggle::after { - content: none; -} -.footable .btn-outline-secondary { - border-color: rgb(108 117 125); -} -.footable .btn-group > .btn:not(:first-child), -.footable .btn-group > .btn-group:not(:first-child) > .btn { - border-top-left-radius: 0; - border-bottom-left-radius: 0; -} -.footable .input-sm { - height: 30px; -} - -.footable-header .fooicon { - font-size: 12px; -} -.footable .pagination > li:last-child > a { - border-top-right-radius:4px; - border-bottom-right-radius:4px -} - -/* FooTable dark mode */ -[data-theme="dark"] .footable .pagination .footable-page-link, -[data-theme="dark"] .footable .form-control { - color: #aaaaaa; - background-color: var(--bs-body-bg); - border-color: var(--bs-border-color) -} -[data-theme="dark"] .footable .btn-primary { - color: #ffffff; - background-color: #0d6efd; - border-color: #0d6efd; -} -[data-theme="dark"] .footable .btn-primary:hover { - background-color: #0b5ed7; - border-color: #0a58ca; -} -[data-theme="dark"] .footable .btn-default { - color: #ffffff; - background-color: #6c757d; - border-color: #6c757d; -} -[data-theme="dark"] .footable .btn-default:hover, -[data-theme="dark"] .footable .open > .dropdown-toggle.btn-default { - background-color: #5c636a; - border-color: #565e64; -} - -[data-theme="dark"] .footable .dropdown-menu { - background-color: var(--bs-body-bg); - border-color: var(--bs-dropdown-border-color); -} -[data-theme="dark"] .footable .dropdown-menu > li > a { - color: #aaaaaa; -} -[data-theme="dark"] .footable .dropdown-menu > li > a:hover { - background-color: var(--bs-dropdown-link-hover-bg); -} - -[data-theme="dark"] .footable .pagination > li a:hover { - background-color: var(--bs-nav-link-disabled-color); - border-color: var(--bs-border-color); -} -[data-theme="dark"] .footable .pagination .footable-page-link:hover { - color: var(--bs-nav-link-hover-color); -} -[data-theme="dark"] .footable .pagination .footable-page.active .footable-page-link { - background-color: var(--rspamd-nav-active-bg); - color: var(--rspamd-text-primary); -} - /* * Tabulator theme. * The bundled bootstrap5 theme hardcodes light colors (#fff, #dee2e6, ...), @@ -335,7 +255,7 @@ textarea { white-space: normal; overflow-wrap: break-word; } -/* Horizontal separators between rows; no vertical dividers (like FooTable). +/* Horizontal separators between rows; no vertical dividers. Only between adjacent rows, so no double line at header/footer edges. */ .tabulator-row + .tabulator-row { border-top: 1px solid var(--bs-border-color); @@ -627,7 +547,7 @@ input.action-scores { .status-table td:last-child { border-right: none; } -/* stylelint-disable no-descending-specificity -- tabulator selectors are grouped before the legacy .status-table/.footable rules below; harmless until those are removed */ +/* stylelint-disable no-descending-specificity -- tabulator selectors are grouped before the .status-table rules below */ .status-table thead tr { border-top: none; } @@ -637,15 +557,6 @@ input.action-scores { } /* stylelint-enable no-descending-specificity */ -.footable-header, -.footable tr:not(.footable-detail-row) > td { - font-size: 11px; -} -.footable-dropdown-btn-group { - padding: 0 20px; - margin: 7px 0; -} - .status-table tr:last-child td:last-child { border-radius: 0 0 calc(var(--bs-border-radius) + 1px); } @@ -719,28 +630,6 @@ input.action-scores { } /* history table */ -.footable-details.table { - margin-bottom: 0; -} -#historyTable_scan > tbody > tr > td, -#historyTable_scan > thead > tr > th, -#historyTable_history > tbody > tr > td, -#historyTable_history > thead > tr > th { - padding: 4px; -} -#historyTable_scan > thead > tr > th, -#historyTable_history > thead > tr > th { - padding-right: 20px; -} -@media (min-width: 576px) and (max-width: 1199px) { - .history-col-time { - /* Avoid taking multiple lines in every row when one of rows has long ID */ - white-space: nowrap; - } -} -.footable-filtering-search .dropdown-menu .sym-order-toggle { - display: none; -} .fuzzy-hash-actions .btn-xs { padding: 1px 0.3rem; font-size: 0.75rem; diff --git a/interface/index.html b/interface/index.html index 34f7b7e4af..51508a2db9 100644 --- a/interface/index.html +++ b/interface/index.html @@ -15,8 +15,6 @@ - - @@ -599,10 +597,10 @@ - - + @@ -724,10 +722,10 @@ - - +