perf(assets): bundle global dialog js+css into single hashed bundles
The 3 selection-dialog JS files and 3 CSS files were each separate raw app_include entries — 6 lines in the desk `Link: rel=preload` header (the edge proxy has a ~4 KB header buffer; overflow returns 502) and, being hashless /assets paths, subject to nginx's 1-year cache (stale-JS dance). - selections.bundle.js imports the 3 dialog libs (window.* interop preserved; verified globals + cross-refs survive minification). - selections.bundle.css merges the 3 stylesheets. - app_include js/css: 3+3 → 1+1, now hashed → automatic cache-busting. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
348b29056b
commit
3ea777ac9d
|
|
@ -25,15 +25,14 @@ app_license = "unlicense"
|
|||
# ------------------
|
||||
|
||||
# include js, css files in header of desk.html
|
||||
# Single hashed bundles (was 3 raw entries each). Fewer desk `Link: rel=preload`
|
||||
# entries (edge proxy has a ~4 KB header buffer → 502 on overflow) and automatic
|
||||
# cache-busting on every `bench build`.
|
||||
app_include_css = [
|
||||
"/assets/selections/css/selection_dialog.css",
|
||||
"/assets/selections/css/account_selection_dialog.css",
|
||||
"/assets/selections/css/document_selection_dialog.css",
|
||||
"selections.bundle.css",
|
||||
]
|
||||
app_include_js = [
|
||||
"/assets/selections/js/document_selection_dialog.js",
|
||||
"/assets/selections/js/account_selection_dialog.js",
|
||||
"/assets/selections/js/selection_dialog.js",
|
||||
"selections.bundle.js",
|
||||
]
|
||||
|
||||
# include js, css files in header of web template
|
||||
|
|
|
|||
|
|
@ -1,258 +0,0 @@
|
|||
/**
|
||||
* Стили для формы подбора счетов (Account)
|
||||
*/
|
||||
|
||||
/* Fullscreen modal */
|
||||
.account-selection-dialog-wrapper .modal-dialog {
|
||||
max-width: 100vw !important;
|
||||
width: 100vw !important;
|
||||
height: 100vh !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.account-selection-dialog-wrapper .modal-content {
|
||||
height: 100vh !important;
|
||||
border-radius: 0 !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.account-selection-dialog-wrapper .modal-body {
|
||||
padding: 15px !important;
|
||||
overflow: clip !important;
|
||||
flex: 1 !important;
|
||||
}
|
||||
|
||||
.account-selection-dialog-wrapper .frappe-control {
|
||||
width: 100% !important;
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
.account-selection-dialog-wrapper .form-group {
|
||||
width: 100% !important;
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
/* 2-колоночный layout */
|
||||
.account-selection-content {
|
||||
display: flex;
|
||||
gap: 0;
|
||||
height: calc(100vh - 130px);
|
||||
min-height: 500px;
|
||||
}
|
||||
|
||||
/* ── Левая колонка: Дерево ──────────────────────────────────────────── */
|
||||
.account-selection-filters {
|
||||
flex: 0 0 380px;
|
||||
padding-right: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Заголовок дерева с кнопками */
|
||||
.account-tree-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.account-tree-header label {
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.account-tree-actions {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.account-tree-actions .btn {
|
||||
padding: 3px 7px;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* Контейнер дерева — scroll по Y, hidden по X предотвращает сдвиги */
|
||||
.account-group-tree {
|
||||
flex: 1;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 5px;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* ── Узлы дерева ────────────────────────────────────────────────────── */
|
||||
.acct-tree-node {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 4px 8px;
|
||||
cursor: pointer;
|
||||
border-radius: var(--border-radius);
|
||||
transition: background-color 0.15s;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.acct-tree-node:hover {
|
||||
background-color: var(--bg-light-gray);
|
||||
}
|
||||
|
||||
.acct-tree-node.active {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.acct-tree-node.active .acct-tree-link {
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
/* Chevron toggle */
|
||||
.acct-tree-toggle {
|
||||
flex-shrink: 0;
|
||||
width: 16px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.acct-tree-toggle:hover {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.acct-tree-node.active .acct-tree-toggle {
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Placeholder для узлов без детей — сохраняет выравнивание */
|
||||
.acct-tree-toggle-placeholder {
|
||||
flex-shrink: 0;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
/* Ссылка (label) */
|
||||
.acct-tree-link {
|
||||
text-decoration: none;
|
||||
color: var(--text-color);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 16px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.acct-tree-link i {
|
||||
margin-right: 5px;
|
||||
width: 14px;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* ── Правая колонка ─────────────────────────────────────────────────── */
|
||||
.account-selection-items-column {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* Поиск сверху */
|
||||
.account-search-bar {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 8px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.account-search-bar .frappe-control,
|
||||
.account-search-bar .form-group {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Иконка поиска — вставляется в .control-input через JS */
|
||||
.account-search-icon {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: var(--text-muted);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* Таблица счетов — фиксированная ширина колонок предотвращает сдвиги */
|
||||
.account-table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.account-table tbody tr {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.account-table tbody tr:hover {
|
||||
background-color: var(--bg-light-gray);
|
||||
}
|
||||
|
||||
.account-table td {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.btn-select-account {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Awesomplete для фильтров */
|
||||
.account-filter-bar .awesomplete > ul {
|
||||
z-index: 1060;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.account-filter-bar #account-custom-filters-list:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ── Скроллбары ─────────────────────────────────────────────────────── */
|
||||
.account-items-grid::-webkit-scrollbar,
|
||||
.account-group-tree::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
.account-items-grid::-webkit-scrollbar-track,
|
||||
.account-group-tree::-webkit-scrollbar-track {
|
||||
background: var(--bg-light-gray);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.account-items-grid::-webkit-scrollbar-thumb,
|
||||
.account-group-tree::-webkit-scrollbar-thumb {
|
||||
background: var(--text-muted);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.account-items-grid::-webkit-scrollbar-thumb:hover,
|
||||
.account-group-tree::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-color);
|
||||
}
|
||||
|
||||
/* ── Responsive ─────────────────────────────────────────────────────── */
|
||||
@media (max-width: 1200px) {
|
||||
.account-selection-content {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.account-selection-filters {
|
||||
flex: 0 0 auto;
|
||||
border: none;
|
||||
padding: 0;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
padding-bottom: 15px;
|
||||
margin-bottom: 15px;
|
||||
max-height: 250px;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,386 +0,0 @@
|
|||
/**
|
||||
* Стили для формы подбора документов (Landed Cost Voucher).
|
||||
* Повторяют структуру account_selection_dialog.css.
|
||||
*/
|
||||
|
||||
/* Fullscreen modal */
|
||||
.document-selection-dialog-wrapper .modal-dialog {
|
||||
max-width: 100vw !important;
|
||||
width: 100vw !important;
|
||||
height: 100vh !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.document-selection-dialog-wrapper .modal-content {
|
||||
height: 100vh !important;
|
||||
border-radius: 0 !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.document-selection-dialog-wrapper .modal-body {
|
||||
padding: 15px !important;
|
||||
overflow: clip !important;
|
||||
flex: 1 !important;
|
||||
}
|
||||
|
||||
.document-selection-dialog-wrapper .frappe-control {
|
||||
width: 100% !important;
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
.document-selection-dialog-wrapper .form-group {
|
||||
width: 100% !important;
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
/* 2-колоночный layout */
|
||||
.document-selection-content {
|
||||
display: flex;
|
||||
gap: 0;
|
||||
height: calc(100vh - 130px);
|
||||
min-height: 500px;
|
||||
}
|
||||
|
||||
/* ── Левая колонка: Дерево ──────────────────────────────────────────── */
|
||||
.document-selection-filters {
|
||||
flex: 0 0 320px;
|
||||
padding-right: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.document-tree-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.document-tree-header label {
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.document-tree-actions {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.document-tree-actions .btn {
|
||||
padding: 3px 7px;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.document-group-tree {
|
||||
flex: 1;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 5px;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* ── Узлы дерева ────────────────────────────────────────────────────── */
|
||||
.doc-tree-node {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 4px 8px;
|
||||
cursor: pointer;
|
||||
border-radius: var(--border-radius);
|
||||
transition: background-color 0.15s;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.doc-tree-node:hover {
|
||||
background-color: var(--bg-light-gray);
|
||||
}
|
||||
|
||||
.doc-tree-node.active {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.doc-tree-node.active .doc-tree-link {
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.doc-tree-toggle {
|
||||
flex-shrink: 0;
|
||||
width: 16px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.doc-tree-toggle:hover {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.doc-tree-node.active .doc-tree-toggle {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.doc-tree-toggle-placeholder {
|
||||
flex-shrink: 0;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.doc-tree-link {
|
||||
text-decoration: none;
|
||||
color: var(--text-color);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 15px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.doc-tree-link i {
|
||||
margin-right: 5px;
|
||||
width: 14px;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* ── Правая колонка ─────────────────────────────────────────────────── */
|
||||
.document-selection-items-column {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* Поиск сверху */
|
||||
.document-search-bar {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 8px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.document-search-bar .frappe-control,
|
||||
.document-search-bar .form-group {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.document-search-icon {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: var(--text-muted);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* Панель фильтров */
|
||||
.document-filter-bar {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 8px;
|
||||
padding: 0 4px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.document-filter-bar #document-custom-filters-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.document-filter-bar #document-custom-filters-list:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.document-filter-bar .custom-filter-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.document-filter-bar .cf-field-wrap {
|
||||
flex: 0 0 220px;
|
||||
}
|
||||
|
||||
.document-filter-bar .cf-operator-wrap {
|
||||
flex: 0 0 130px;
|
||||
}
|
||||
|
||||
.document-filter-bar .cf-value-wrap {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.document-filter-bar .cf-remove {
|
||||
flex: 0 0 auto;
|
||||
line-height: 1;
|
||||
padding: 3px 7px;
|
||||
}
|
||||
|
||||
.document-filter-bar .frappe-control,
|
||||
.document-filter-bar .form-group {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.document-filter-bar .awesomplete > ul {
|
||||
z-index: 1060;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.document-filter-bar .btn-add-custom-filter {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
/* Контейнер таблицы */
|
||||
.document-items-grid {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--border-radius);
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.document-table {
|
||||
margin-bottom: 0;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.document-table thead th {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background-color: var(--fg-color);
|
||||
z-index: 2;
|
||||
white-space: nowrap;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.document-table tbody tr {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.document-table tbody tr:hover,
|
||||
.document-table tbody tr.selection-row-focused {
|
||||
background-color: var(--bg-light-gray);
|
||||
}
|
||||
|
||||
.document-table td {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.document-table .sortable-header {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.document-table .sortable-header.sort-active {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.document-table .item-open-link {
|
||||
margin-left: 6px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.document-table .item-open-link:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.btn-select-document {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Пагинация */
|
||||
.document-selection-items-column .selection-pagination {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
padding: 6px 0 0;
|
||||
}
|
||||
|
||||
.document-selection-items-column .pagination-info {
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* Ручка resize */
|
||||
.document-selection-dialog-wrapper .resize-handle {
|
||||
flex: 0 0 6px;
|
||||
cursor: col-resize;
|
||||
background: transparent;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.document-selection-dialog-wrapper .resize-handle::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 2px;
|
||||
background: var(--border-color);
|
||||
border-radius: 1px;
|
||||
transition: background-color 0.15s;
|
||||
}
|
||||
|
||||
.document-selection-dialog-wrapper .resize-handle:hover::before {
|
||||
background: var(--primary-color);
|
||||
}
|
||||
|
||||
body.selection-resizing {
|
||||
cursor: col-resize !important;
|
||||
user-select: none !important;
|
||||
}
|
||||
|
||||
/* Скроллбары */
|
||||
.document-items-grid::-webkit-scrollbar,
|
||||
.document-group-tree::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
.document-items-grid::-webkit-scrollbar-track,
|
||||
.document-group-tree::-webkit-scrollbar-track {
|
||||
background: var(--bg-light-gray);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.document-items-grid::-webkit-scrollbar-thumb,
|
||||
.document-group-tree::-webkit-scrollbar-thumb {
|
||||
background: var(--text-muted);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.document-items-grid::-webkit-scrollbar-thumb:hover,
|
||||
.document-group-tree::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-color);
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 1200px) {
|
||||
.document-selection-content {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.document-selection-filters {
|
||||
flex: 0 0 auto;
|
||||
border: none;
|
||||
padding: 0;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
padding-bottom: 15px;
|
||||
margin-bottom: 15px;
|
||||
max-height: 250px;
|
||||
}
|
||||
|
||||
.document-selection-dialog-wrapper .resize-handle {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,9 @@
|
|||
/* Bundled selection-dialog styles (was 3 raw app_include_css entries).
|
||||
One hashed bundle -> smaller desk preload header + auto cache-busting.
|
||||
Source merged from selection_dialog.css + account_selection_dialog.css +
|
||||
document_selection_dialog.css. */
|
||||
|
||||
/* ===== selection_dialog.css ===== */
|
||||
/**
|
||||
* Стили для формы подбора товаров
|
||||
*/
|
||||
|
|
@ -861,3 +867,651 @@ body.selection-resizing * {
|
|||
.selection-no-rate .cart-total,
|
||||
.selection-no-rate .cart-item-price,
|
||||
.selection-no-rate .line-through { display: none !important; }
|
||||
|
||||
/* ===== account_selection_dialog.css ===== */
|
||||
/**
|
||||
* Стили для формы подбора счетов (Account)
|
||||
*/
|
||||
|
||||
/* Fullscreen modal */
|
||||
.account-selection-dialog-wrapper .modal-dialog {
|
||||
max-width: 100vw !important;
|
||||
width: 100vw !important;
|
||||
height: 100vh !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.account-selection-dialog-wrapper .modal-content {
|
||||
height: 100vh !important;
|
||||
border-radius: 0 !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.account-selection-dialog-wrapper .modal-body {
|
||||
padding: 15px !important;
|
||||
overflow: clip !important;
|
||||
flex: 1 !important;
|
||||
}
|
||||
|
||||
.account-selection-dialog-wrapper .frappe-control {
|
||||
width: 100% !important;
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
.account-selection-dialog-wrapper .form-group {
|
||||
width: 100% !important;
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
/* 2-колоночный layout */
|
||||
.account-selection-content {
|
||||
display: flex;
|
||||
gap: 0;
|
||||
height: calc(100vh - 130px);
|
||||
min-height: 500px;
|
||||
}
|
||||
|
||||
/* ── Левая колонка: Дерево ──────────────────────────────────────────── */
|
||||
.account-selection-filters {
|
||||
flex: 0 0 380px;
|
||||
padding-right: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Заголовок дерева с кнопками */
|
||||
.account-tree-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.account-tree-header label {
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.account-tree-actions {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.account-tree-actions .btn {
|
||||
padding: 3px 7px;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* Контейнер дерева — scroll по Y, hidden по X предотвращает сдвиги */
|
||||
.account-group-tree {
|
||||
flex: 1;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 5px;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* ── Узлы дерева ────────────────────────────────────────────────────── */
|
||||
.acct-tree-node {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 4px 8px;
|
||||
cursor: pointer;
|
||||
border-radius: var(--border-radius);
|
||||
transition: background-color 0.15s;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.acct-tree-node:hover {
|
||||
background-color: var(--bg-light-gray);
|
||||
}
|
||||
|
||||
.acct-tree-node.active {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.acct-tree-node.active .acct-tree-link {
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
/* Chevron toggle */
|
||||
.acct-tree-toggle {
|
||||
flex-shrink: 0;
|
||||
width: 16px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.acct-tree-toggle:hover {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.acct-tree-node.active .acct-tree-toggle {
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Placeholder для узлов без детей — сохраняет выравнивание */
|
||||
.acct-tree-toggle-placeholder {
|
||||
flex-shrink: 0;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
/* Ссылка (label) */
|
||||
.acct-tree-link {
|
||||
text-decoration: none;
|
||||
color: var(--text-color);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 16px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.acct-tree-link i {
|
||||
margin-right: 5px;
|
||||
width: 14px;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* ── Правая колонка ─────────────────────────────────────────────────── */
|
||||
.account-selection-items-column {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* Поиск сверху */
|
||||
.account-search-bar {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 8px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.account-search-bar .frappe-control,
|
||||
.account-search-bar .form-group {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Иконка поиска — вставляется в .control-input через JS */
|
||||
.account-search-icon {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: var(--text-muted);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* Таблица счетов — фиксированная ширина колонок предотвращает сдвиги */
|
||||
.account-table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.account-table tbody tr {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.account-table tbody tr:hover {
|
||||
background-color: var(--bg-light-gray);
|
||||
}
|
||||
|
||||
.account-table td {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.btn-select-account {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Awesomplete для фильтров */
|
||||
.account-filter-bar .awesomplete > ul {
|
||||
z-index: 1060;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.account-filter-bar #account-custom-filters-list:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ── Скроллбары ─────────────────────────────────────────────────────── */
|
||||
.account-items-grid::-webkit-scrollbar,
|
||||
.account-group-tree::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
.account-items-grid::-webkit-scrollbar-track,
|
||||
.account-group-tree::-webkit-scrollbar-track {
|
||||
background: var(--bg-light-gray);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.account-items-grid::-webkit-scrollbar-thumb,
|
||||
.account-group-tree::-webkit-scrollbar-thumb {
|
||||
background: var(--text-muted);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.account-items-grid::-webkit-scrollbar-thumb:hover,
|
||||
.account-group-tree::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-color);
|
||||
}
|
||||
|
||||
/* ── Responsive ─────────────────────────────────────────────────────── */
|
||||
@media (max-width: 1200px) {
|
||||
.account-selection-content {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.account-selection-filters {
|
||||
flex: 0 0 auto;
|
||||
border: none;
|
||||
padding: 0;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
padding-bottom: 15px;
|
||||
margin-bottom: 15px;
|
||||
max-height: 250px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== document_selection_dialog.css ===== */
|
||||
/**
|
||||
* Стили для формы подбора документов (Landed Cost Voucher).
|
||||
* Повторяют структуру account_selection_dialog.css.
|
||||
*/
|
||||
|
||||
/* Fullscreen modal */
|
||||
.document-selection-dialog-wrapper .modal-dialog {
|
||||
max-width: 100vw !important;
|
||||
width: 100vw !important;
|
||||
height: 100vh !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.document-selection-dialog-wrapper .modal-content {
|
||||
height: 100vh !important;
|
||||
border-radius: 0 !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.document-selection-dialog-wrapper .modal-body {
|
||||
padding: 15px !important;
|
||||
overflow: clip !important;
|
||||
flex: 1 !important;
|
||||
}
|
||||
|
||||
.document-selection-dialog-wrapper .frappe-control {
|
||||
width: 100% !important;
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
.document-selection-dialog-wrapper .form-group {
|
||||
width: 100% !important;
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
/* 2-колоночный layout */
|
||||
.document-selection-content {
|
||||
display: flex;
|
||||
gap: 0;
|
||||
height: calc(100vh - 130px);
|
||||
min-height: 500px;
|
||||
}
|
||||
|
||||
/* ── Левая колонка: Дерево ──────────────────────────────────────────── */
|
||||
.document-selection-filters {
|
||||
flex: 0 0 320px;
|
||||
padding-right: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.document-tree-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.document-tree-header label {
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.document-tree-actions {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.document-tree-actions .btn {
|
||||
padding: 3px 7px;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.document-group-tree {
|
||||
flex: 1;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 5px;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* ── Узлы дерева ────────────────────────────────────────────────────── */
|
||||
.doc-tree-node {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 4px 8px;
|
||||
cursor: pointer;
|
||||
border-radius: var(--border-radius);
|
||||
transition: background-color 0.15s;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.doc-tree-node:hover {
|
||||
background-color: var(--bg-light-gray);
|
||||
}
|
||||
|
||||
.doc-tree-node.active {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.doc-tree-node.active .doc-tree-link {
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.doc-tree-toggle {
|
||||
flex-shrink: 0;
|
||||
width: 16px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.doc-tree-toggle:hover {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.doc-tree-node.active .doc-tree-toggle {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.doc-tree-toggle-placeholder {
|
||||
flex-shrink: 0;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.doc-tree-link {
|
||||
text-decoration: none;
|
||||
color: var(--text-color);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 15px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.doc-tree-link i {
|
||||
margin-right: 5px;
|
||||
width: 14px;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* ── Правая колонка ─────────────────────────────────────────────────── */
|
||||
.document-selection-items-column {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* Поиск сверху */
|
||||
.document-search-bar {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 8px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.document-search-bar .frappe-control,
|
||||
.document-search-bar .form-group {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.document-search-icon {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: var(--text-muted);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* Панель фильтров */
|
||||
.document-filter-bar {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 8px;
|
||||
padding: 0 4px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.document-filter-bar #document-custom-filters-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.document-filter-bar #document-custom-filters-list:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.document-filter-bar .custom-filter-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.document-filter-bar .cf-field-wrap {
|
||||
flex: 0 0 220px;
|
||||
}
|
||||
|
||||
.document-filter-bar .cf-operator-wrap {
|
||||
flex: 0 0 130px;
|
||||
}
|
||||
|
||||
.document-filter-bar .cf-value-wrap {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.document-filter-bar .cf-remove {
|
||||
flex: 0 0 auto;
|
||||
line-height: 1;
|
||||
padding: 3px 7px;
|
||||
}
|
||||
|
||||
.document-filter-bar .frappe-control,
|
||||
.document-filter-bar .form-group {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.document-filter-bar .awesomplete > ul {
|
||||
z-index: 1060;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.document-filter-bar .btn-add-custom-filter {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
/* Контейнер таблицы */
|
||||
.document-items-grid {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--border-radius);
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.document-table {
|
||||
margin-bottom: 0;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.document-table thead th {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background-color: var(--fg-color);
|
||||
z-index: 2;
|
||||
white-space: nowrap;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.document-table tbody tr {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.document-table tbody tr:hover,
|
||||
.document-table tbody tr.selection-row-focused {
|
||||
background-color: var(--bg-light-gray);
|
||||
}
|
||||
|
||||
.document-table td {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.document-table .sortable-header {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.document-table .sortable-header.sort-active {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.document-table .item-open-link {
|
||||
margin-left: 6px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.document-table .item-open-link:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.btn-select-document {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Пагинация */
|
||||
.document-selection-items-column .selection-pagination {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
padding: 6px 0 0;
|
||||
}
|
||||
|
||||
.document-selection-items-column .pagination-info {
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* Ручка resize */
|
||||
.document-selection-dialog-wrapper .resize-handle {
|
||||
flex: 0 0 6px;
|
||||
cursor: col-resize;
|
||||
background: transparent;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.document-selection-dialog-wrapper .resize-handle::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 2px;
|
||||
background: var(--border-color);
|
||||
border-radius: 1px;
|
||||
transition: background-color 0.15s;
|
||||
}
|
||||
|
||||
.document-selection-dialog-wrapper .resize-handle:hover::before {
|
||||
background: var(--primary-color);
|
||||
}
|
||||
|
||||
body.selection-resizing {
|
||||
cursor: col-resize !important;
|
||||
user-select: none !important;
|
||||
}
|
||||
|
||||
/* Скроллбары */
|
||||
.document-items-grid::-webkit-scrollbar,
|
||||
.document-group-tree::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
.document-items-grid::-webkit-scrollbar-track,
|
||||
.document-group-tree::-webkit-scrollbar-track {
|
||||
background: var(--bg-light-gray);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.document-items-grid::-webkit-scrollbar-thumb,
|
||||
.document-group-tree::-webkit-scrollbar-thumb {
|
||||
background: var(--text-muted);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.document-items-grid::-webkit-scrollbar-thumb:hover,
|
||||
.document-group-tree::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-color);
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 1200px) {
|
||||
.document-selection-content {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.document-selection-filters {
|
||||
flex: 0 0 auto;
|
||||
border: none;
|
||||
padding: 0;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
padding-bottom: 15px;
|
||||
margin-bottom: 15px;
|
||||
max-height: 250px;
|
||||
}
|
||||
|
||||
.document-selection-dialog-wrapper .resize-handle {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// Bundled global selection-dialog libraries.
|
||||
//
|
||||
// These three were previously three separate raw entries in app_include_js,
|
||||
// each adding a line to the desk `Link: rel=preload` header (the edge proxy has
|
||||
// a ~4 KB header buffer; overflowing it returns 502). Combining them into one
|
||||
// hashed bundle keeps a single preload entry AND gives automatic cache-busting
|
||||
// on every `bench build` (no more stale-JS / hard-refresh dance).
|
||||
//
|
||||
// They communicate via window.* globals (window.AccountSelectionDialog etc.) and
|
||||
// selection_dialog.js overrides LinkSelector, calling the other two lazily at
|
||||
// click time — so import the two providers first, the override last.
|
||||
import "./account_selection_dialog.js";
|
||||
import "./document_selection_dialog.js";
|
||||
import "./selection_dialog.js";
|
||||
Loading…
Reference in New Issue