Using a clean wordpress install, woocommerce and storefront theme, I came up with this code.
It sorts regular products and variable products only. Only sorts in admin panel. Sorts by weight from hgih to low (you can see the commented section, you can uncomment the relevant option to you).
The code goes into functions.php
add_filter('woocommerce_order_get_items', 'bt_sort_woo_order_by_weight', 10, 3);
function bt_sort_woo_order_by_weight ($items, $_this, $types) {
if (!is_admin()) return $items;
if (isset($types[0]) && $types[0] !== 'line_item') return $items;
$items_sorted_by_weight = [];
foreach ($items as $item_id => $item) {
// get variation or product id, starting with variation
$id = !empty($item->get_variation_id()) ? $item->get_variation_id() : $item->get_product_id();
// get product
$product = wc_get_product($id);
// in case the product/variation no longer exist OR product is not variable or simple
if (empty($product) || !in_array($product->get_type(), ['variation', 'simple'])) {
$items_sorted_by_weight[] = [
'weight' => 0,
'item' => $item
];
continue;
}
$items_sorted_by_weight[] = [
'weight' => floatval($product->get_weight()),
'item' => $item
];
}
// sort by weight
usort($items_sorted_by_weight, function($a, $b) {
//return $a['weight'] <=> $b['weight']; // low to high
return $b['weight'] <=> $a['weight']; // high to low
});
// set each sorted element to contain only the item, nothing else
foreach ($items_sorted_by_weight as &$item) {
$item = $item['item'];
}
// in case nothing worked set the sorted variable to contain default items
if (empty($items_sorted_by_weight)) $items_sorted_by_weight = $items;
return $items_sorted_by_weight;
}