UI enhancements

This commit is contained in:
2026-07-19 16:57:58 +02:00
parent a69daa1294
commit be21c0afea
10 changed files with 66282 additions and 366 deletions

2
.codex/config.toml Normal file
View File

@@ -0,0 +1,2 @@
approval_policy = "never"
sandbox_mode = "danger-full-access"

BIN
dist/tradon_wbg.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

3346
dist/tryton-sao.css vendored

File diff suppressed because it is too large Load Diff

2191
dist/tryton-sao.js vendored

File diff suppressed because it is too large Load Diff

16612
dist/tryton-sao_v1.2.css vendored Normal file

File diff suppressed because it is too large Load Diff

38715
dist/tryton-sao_v1.2.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -29,8 +29,8 @@ this repository contains the full copyright notices and license terms. -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community@31.3.4/styles/ag-grid.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community@31.3.4/styles/ag-grid.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community@31.3.4/styles/ag-theme-alpine.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community@31.3.4/styles/ag-theme-alpine.css">
<script type="text/javascript" src="dist/tryton-sao.js"></script> <script type="text/javascript" src="dist/tryton-sao_v1.2.js"></script>
<link rel="stylesheet" type="text/css" href="dist/tryton-sao.css" media="screen"/> <link rel="stylesheet" type="text/css" href="dist/tryton-sao_v1.2.css" media="screen"/>
<script type="text/javascript" src="custom.js"></script> <script type="text/javascript" src="custom.js"></script>
<link rel="stylesheet" type="text/css" href="custom.css" media="screen"/> <link rel="stylesheet" type="text/css" href="custom.css" media="screen"/>
<script type="text/javascript"> <script type="text/javascript">
@@ -45,6 +45,16 @@ this repository contains the full copyright notices and license terms. -->
document.documentElement.setAttribute( document.documentElement.setAttribute(
'data-theme-mode', 'light'); 'data-theme-mode', 'light');
} }
try {
var storedDensity = window.localStorage &&
localStorage.getItem('sao_density_mode');
document.documentElement.setAttribute(
'data-density',
storedDensity || 'compact');
} catch (error) {
document.documentElement.setAttribute(
'data-density', 'compact');
}
}()); }());
</script> </script>
</head> </head>
@@ -113,6 +123,9 @@ this repository contains the full copyright notices and license terms. -->
</div> </div>
</nav> </nav>
<div id="main" class="container-fluid" style="padding: 0px;"> <div id="main" class="container-fluid" style="padding: 0px;">
<div id="tradon-full-menu" class="tradon-full-menu" aria-hidden="true">
<div class="tradon-full-menu-grid"></div>
</div>
<div class="row row-offcanvas row-offcanvas-left active" <div class="row row-offcanvas row-offcanvas-left active"
style="height: calc(100vh - 50px - 1px - 20px); margin: 0px;"> style="height: calc(100vh - 50px - 1px - 20px); margin: 0px;">
<div class="col-xs-12 col-sm-4 col-lg-3 sidebar-offcanvas" id="menu" role="navigation" <div class="col-xs-12 col-sm-4 col-lg-3 sidebar-offcanvas" id="menu" role="navigation"
@@ -149,8 +162,8 @@ this repository contains the full copyright notices and license terms. -->
if (logo.length) { if (logo.length) {
logo.attr( logo.attr(
'src', 'src',
isDark ? 'dist/tradon-dark.png' : 'dist/tradon_wbg.png');
'dist/tradon.png'); logo.attr('title', 'v1.2');
} }
} }
@@ -170,7 +183,268 @@ this repository contains the full copyright notices and license terms. -->
}, delay); }, delay);
}); });
} }
jQuery('[data-toggle="offcanvas"]').click(function() { // Keep the full-screen menu code in place, but disable its
// loading and logo entry point while the layout is refined.
var enableFullMenu = false;
function setFullMenuVisible(visible) {
var main = jQuery('#main');
if (visible && !jQuery('#tradon-full-menu')
.find('.tradon-full-menu-card').length) {
visible = false;
}
jQuery('#tradon-full-menu').attr(
'aria-hidden', visible ? 'false' : 'true');
main.toggleClass('tradon-full-menu-active', visible);
if (visible) {
jQuery('.row-offcanvas').removeClass('active');
}
notifyLayoutResize();
}
function normalizeMenuValue(value) {
if (value === null || value === undefined) {
return '';
}
if (Array.isArray(value)) {
return value.length > 1 ? value[1] : value[0];
}
if (typeof value == 'object') {
return value.rec_name || value.name || '';
}
return value;
}
function menuField(record, name) {
if (name == 'rec_name' && record._values &&
record._values.rec_name) {
return record._values.rec_name;
}
try {
if (record.model && record.model.fields[name]) {
return normalizeMenuValue(
record.field_get_client(name));
}
} catch (error) {
}
return null;
}
function menuLabel(record) {
return menuField(record, 'name') ||
menuField(record, 'rec_name') ||
(record.id ? String(record.id) : '');
}
function prepareMenuRecord(record) {
var waits = [];
['name', 'icon'].forEach(function(name) {
if (record.model && record.model.fields[name] &&
!record.is_loaded(name)) {
waits.push(record.load(name, true, false));
}
});
if (!record._values || !record._values.rec_name) {
waits.push(record.rec_name().then(
function(name) {
record._values.rec_name = name;
},
function() {
}));
}
return jQuery.when.apply(jQuery, waits);
}
function activateMenuRecord(record) {
if (Sao.main_menu_screen) {
Sao.main_menu_screen.current_record = record;
setFullMenuVisible(false);
Sao.main_menu_row_activate();
}
}
function loadMenuChildren(record, childrenField) {
if (!childrenField) {
return jQuery.when([]);
}
var load = record.is_loaded &&
record.is_loaded(childrenField) ?
jQuery.when() :
record.load(childrenField, true, false);
return load.then(function() {
return record.field_get_client(childrenField) || [];
});
}
function buildMenuNode(record, childrenField, depth) {
return prepareMenuRecord(record).then(function() {
var node = {
label: menuLabel(record),
icon: menuField(record, 'icon'),
record: record,
children: []
};
if (depth > 4) {
return node;
}
return loadMenuChildren(record, childrenField)
.then(function(children) {
var waits = [];
children.forEach(function(child) {
waits.push(buildMenuNode(
child, childrenField, depth + 1));
});
return jQuery.when.apply(jQuery, waits)
.then(function() {
node.children = Array.prototype.slice
.call(arguments);
return node;
});
});
});
}
function appendMenuLink(container, node, level) {
var link = jQuery('<button/>', {
'type': 'button',
'class': 'tradon-full-menu-link level-' + level,
'title': node.label,
'text': node.label
}).click(function() {
activateMenuRecord(node.record);
});
container.append(link);
}
function appendMenuBranch(container, node, level) {
appendMenuLink(container, node, level);
if (level >= 3) {
return;
}
node.children.slice(0, 4).forEach(function(child) {
appendMenuBranch(container, child, level + 1);
});
}
function renderMenuCard(grid, node, index) {
if (!node || !node.label) {
return;
}
var card = jQuery('<section/>', {
'class': 'tradon-full-menu-card'
}).appendTo(grid);
var header = jQuery('<button/>', {
'type': 'button',
'class': 'tradon-full-menu-card-title',
'title': node.label
}).click(function() {
activateMenuRecord(node.record);
}).appendTo(card);
if (node.icon) {
Sao.common.ICONFACTORY.get_icon_url(node.icon)
.then(function(url) {
jQuery('<img/>', {
'class': 'tradon-full-menu-icon',
'src': url,
'alt': ''
}).prependTo(header);
});
}
jQuery('<span/>', {'text': node.label}).appendTo(header);
var content = jQuery('<div/>', {
'class': 'tradon-full-menu-card-content'
}).appendTo(card);
var children = node.children || [];
if (children.length > 5) {
var tabs = jQuery('<div/>', {
'class': 'tradon-full-menu-tabs'
}).appendTo(content);
children.slice(0, 4).forEach(function(child, tabIndex) {
var tab = jQuery('<button/>', {
'type': 'button',
'class': 'tradon-full-menu-tab' +
(tabIndex ? '' : ' active'),
'text': child.label,
'title': child.label
}).appendTo(tabs);
tab.click(function() {
tabs.children().removeClass('active');
tab.addClass('active');
links.empty();
appendMenuBranch(links, child, 1);
});
});
var links = jQuery('<div/>', {
'class': 'tradon-full-menu-links'
}).appendTo(content);
appendMenuBranch(links, children[0], 1);
} else {
var plainLinks = jQuery('<div/>', {
'class': 'tradon-full-menu-links'
}).appendTo(content);
children.forEach(function(child) {
appendMenuBranch(plainLinks, child, 1);
});
}
}
function rebuildFullMenu() {
var screen = Sao.main_menu_screen;
var view = screen && screen.current_view;
var grid = jQuery('#tradon-full-menu .tradon-full-menu-grid');
var records = [];
if (view && view.rows && view.rows.length) {
records = view.rows.map(function(row) {
return row.record;
});
} else if (screen && screen.group && screen.group.length) {
records = screen.group.slice(0);
}
if (!view || !records.length) {
return jQuery.when(false);
}
grid.empty();
var waits = records.map(function(record) {
return buildMenuNode(record, view.children_field, 0);
});
return jQuery.when.apply(jQuery, waits).then(function() {
var nodes = Array.prototype.slice.call(arguments);
grid.empty();
nodes.forEach(function(node, index) {
renderMenuCard(grid, node, index);
});
return Boolean(grid.children().length);
});
}
function showFullMenuWhenReady(attempt) {
if (!enableFullMenu) {
setFullMenuVisible(false);
return;
}
attempt = attempt || 0;
rebuildFullMenu().then(
function(ready) {
if (ready) {
setFullMenuVisible(true);
} else if (attempt < 8) {
window.setTimeout(function() {
showFullMenuWhenReady(attempt + 1);
}, 120);
} else {
setFullMenuVisible(false);
}
},
function() {
setFullMenuVisible(false);
});
}
jQuery(document).on('tradon:main-menu-ready', function() {
if (!enableFullMenu) {
setFullMenuVisible(false);
return;
}
showFullMenuWhenReady(0);
});
jQuery('[data-toggle="offcanvas"]').click(function(event) {
if (enableFullMenu &&
jQuery(event.target).closest('#title-logo').length) {
if (jQuery('#main').hasClass(
'tradon-full-menu-active')) {
setFullMenuVisible(false);
} else {
showFullMenuWhenReady(0);
}
return false;
}
setFullMenuVisible(false);
jQuery('.row-offcanvas').toggleClass('active'); jQuery('.row-offcanvas').toggleClass('active');
notifyLayoutResize(); notifyLayoutResize();
}); });

BIN
tradon_wbg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff