diff --git a/frontend/css/green-coding.css b/frontend/css/green-coding.css index cd85f2b8b..e876db518 100644 --- a/frontend/css/green-coding.css +++ b/frontend/css/green-coding.css @@ -340,6 +340,12 @@ a, margin-top: 5px; } +span.hidden-phase-name { + display: none; +} + + + /* Since we have a without href we need to force pointer */ a { cursor: pointer; diff --git a/frontend/js/stats.js b/frontend/js/stats.js index d270dbf4b..5380cf6fa 100644 --- a/frontend/js/stats.js +++ b/frontend/js/stats.js @@ -72,6 +72,16 @@ class CO2Tangible extends HTMLElement { customElements.define('co2-tangible', CO2Tangible); +const showHiddenPhaseTab = (el) => { + if (el.currentTarget.classList.contains('hidden-phase-tab')) { + el.currentTarget.querySelector('.hidden-phase-name').style.display = 'block' + } else { + document.querySelectorAll('.hidden-phase-name').forEach(matched_el => { + matched_el.style.display = 'none' + }) + } +} + const fetchAndFillRunData = async (url_params) => { let run = null; @@ -94,8 +104,20 @@ const fetchAndFillRunData = async (url_params) => { document.querySelector("#logs").insertAdjacentHTML('beforeend', `
${run_data?.[item]}
`) } else if(item == 'measurement_config') { fillRunTab('#measurement-config', run_data[item]); // recurse - } else if(item == 'phases' || item == 'id') { + } else if(item == 'id') { // skip + } else if(item == 'phases') { + Object.keys(run_data[item]).forEach(key => { + if (run_data[item][key]?.hidden == true) { + const tab = document.querySelector(`.item.runtime-step[data-tab="${run_data[item][key].name}"]`) + tab.innerHTML = ` ${tab.innerText}` + tab.classList.add("hidden-phase-tab") + } + }); + document.querySelectorAll('#runtime-sub-phases .item').forEach(el => { + el.addEventListener('click', showHiddenPhaseTab) + }) + } else if(item == 'commit_hash') { if (run_data?.[item] == null) continue; // some old runs did not save it let commit_link = buildCommitLink(run_data); @@ -466,13 +488,14 @@ $(document).ready( (e) => { return; } - fetchAndFillRunData(url_params); + fetchAndFillNetworkIntercepts(url_params); fetchAndFillOptimizationsData(url_params); (async () => { // since we need to wait for fetchAndFillPhaseStatsData we wrap in async so later calls cann already proceed const phase_stats = await fetchAndFillPhaseStatsData(url_params); renderBadges(url_params, phase_stats?.data?.data['[RUNTIME]']); + fetchAndFillRunData(url_params); // bc it will hide phases. TODO: Refactor this to have the data in the phase_stats_object. Is a bigger refactor though! })(); diff --git a/runner.py b/runner.py index 1911b40ca..706832bc5 100755 --- a/runner.py +++ b/runner.py @@ -1161,7 +1161,7 @@ def check_total_runtime_exceeded(self): if self._measurement_total_duration and (time.time() - self.__start_measurement_seconds) > self._measurement_total_duration: raise TimeoutError(f"Timeout of {self._measurement_total_duration} s was exceeded. This can be configured in the user authentication for 'total_duration'.") - def start_phase(self, phase, transition = True): + def start_phase(self, phase, *, hidden=False, transition=True): config = GlobalConfig().config print(TerminalColors.HEADER, f"\nStarting phase {phase}.", TerminalColors.ENDC) @@ -1176,7 +1176,7 @@ def start_phase(self, phase, transition = True): phase_time = int(time.time_ns() / 1_000) self.__notes_helper.add_note({'note': f"Starting phase {phase}", 'detail_name': '[NOTES]', 'timestamp': phase_time}) - self.__phases[phase] = {'start': phase_time, 'name': phase} + self.__phases[phase] = {'start': phase_time, 'name': phase, 'hidden': hidden} def end_phase(self, phase): @@ -1214,7 +1214,7 @@ def run_flows(self): print(TerminalColors.HEADER, '\nRunning flow: ', flow['name'], TerminalColors.ENDC) try: - self.start_phase(flow['name'], transition=False) + self.start_phase(flow['name'], hidden=flow.get('hidden', False), transition=False) for cmd_obj in flow['commands']: self.check_total_runtime_exceeded()