mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Refactor and transform "Application update", "Preferences" and "Application menu" into Features (#6437)
* Move some code for application update to feature directory The rest of the code could not be moved yet because of work-in-progress refactorings for OCP compliance. Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Introduce helper to get a global override for a function-injectable Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Extract global override-files from bloated getDiForUnitTesting Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Move some more code for application update to feature directory Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Introduce competition for top bar items to achieve OCP-compliance Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Extract top menu item for opening context menu using the new competition Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Extract top menu item for navigating to home as OCP Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Extract top menu item for navigating to back as OCP Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Extract top menu item for navigating to forward as OCP Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Extract top menu item for application update as OCP Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Format code to make ongoing refactoring a bit easier Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Add missing unit tests for top bar extendability using extension API This makes ongoing refactoring easier. Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Replace implementation for old top-bar items for losing competition Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Extract top menu item for window controls as OCP Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Introduce reusable component for spacing between other components Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce helper component to render list of React elements Features: - Placeholder for empty list - Separators between items - No boilerplate for "key" prop in React Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix double-clicking and dragging of window from top bar Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Update snapshots Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix stuff broken in rebase Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Update snapshots after rebase Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make fake time have a default value for "now" Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Migrate some application menu items to injectables Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Consolidate separators of application menu in single file Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Remove duplication from separators in application menu Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Extract some operation system actions from application menu as injectables Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Extract menu item for quitting application as injectable Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Introduce way to type narrow a string property Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make the di's for unit testing able to auto-register also named exports Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make global override less strict to simplify setup of many unit tests There's a better solution for this in the horizon, as this overridden thing is better faked than stubbed. Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Simplify a test Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Introduce way to create hierarchical composites from a flat array Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Implement hierarchy of application menu items using "many-root" composite Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Migrate more application menu items to injectables Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Simplify hierarchy of application menu items using "single-root" composite Also solve composed typing of application menu by using Discriminated Unions of TypeScript, see: https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Update snapshot Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Simplify creation of composite Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make composite able to have custom handler for missing parent ids This will be useful next for application menu items, where a missing parent id cannot be fatal. Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Defend against self-referencing composites Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Reintroduce non-fatal handling of orphan application menu items Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make faked, yet weak, typing a bit stronger Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Simplify getting of composite paths Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make registrator for application menu items support all known scenarios Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Add logging for unrecognizable application menu item types Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Rename id of menu item to keep it discoverable by existing extensions Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Consolidate code to check for updates closer to feature Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Introduce reusable horizontal line Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce competition for preferences as a Feature Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce competition for terminal preference tab Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce competition for editor preference tab Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce competition for proxy preference tab Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce competition for telemetry preference tab Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce competition for application preference tab Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Move code related to helm chart preferences under related Feature in preparation for competition Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce competition for kubernetes preference tab Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Switch to using competition for application preferences Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Switch to using competition for editor preferences Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Switch to using competition for kubernetes preferences Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Switch to using competition for proxy preferences Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Add missing observer to make sure component updates Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Switch to using competition for telemetry preferences Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Switch to using competition for terminal preferences Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Tweak UI for preferences Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove dead code Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Tweak more UI of preferences Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Revert "Introduce reusable horizontal line" This reverts commit 4d8c147fe0f1a14bd884f73cf345e7d3a28b954a. Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove dead code Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce utility to find exactly one item from array Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce competition for preferences navigation Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Move code under a Feature Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove usage of old code Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove dead code Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Add extensions tab group to preferences Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce way to find out if composite has a descendant This will serve eg. hiding of empty preference tab groups. Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make tab groups and tabs in preferences not render when there is no content Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Remove code made redundant with hiding of preference tabs without content Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Tweak UI for preference navigation tab groups Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Introduce test helper to abstract discovery of HTML elements Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Kill dead code Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Consolidate discovery of HTML elements in some tests Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Update snapshots Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Adapt application builder to changes in preference navigation Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Adapt test setup to changes in preference navigation Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove uninteresting technical tests that are covered by behavioural ones Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Consolidate discovery of HTML elements in a test Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove test ID made redundant by consolidating discovery of HTML elements Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove duplication from preference pages Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix import Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make queries in element discovery return matching attribute values for easier testing Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make element discovery able to do nested discovery Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make element discovery able to discover without value for attribute Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Implement registrator for preference items Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Update snapshots Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make styling less brittle by not relying on static HTML-element structures with CSS-rules Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Add todo Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Remove "group" from preference types, as it is exact replica of "item" Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Update snapshots Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Replace usages of react-component factory with actual components for simplicity Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Start considering application preferences as default tab Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Consolidate naming Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make sense in horizontal lines Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Clean public interface of a normalize composite Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Consolidate name of function Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Consolidate directory structure of composite Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Move utility functions to common Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Rename a preference item type to better communicate intent in UI Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Move shared UI component to more common place Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Consolidate sizing of horizontal line to t-shirts Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Move application update related preferences under application update feature Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make winner of competition to use original route for preferences Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make HTML element discovery require less parameters Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Extract "composable-responsibilities" for Discriminable, Labelable, Orderable, and Showable Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Update snapshot Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Remove dead code Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Move code under a feature Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Consolidate navigating to preferences Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Move code under a feature Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Relocate code under a sub-feature Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Add TODO Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove dead code Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix merge conflicts Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Update snapshots after rebase Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix import path after rebase Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Remove duplication from exhaustiveness checks for discriminating unions Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Add TODO Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Update link to a more recent article Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Simplify static Showability of a PreferenceItem Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Move general function to general directory Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Extract responsibility of "separability" Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make separator in Map-component know left and right item Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Remove additional separators when separated items are not shown for having no content Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Update snapshots Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Fix lint error Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Adapt integration test to recent changes Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Adapt more integration tests to recent changes Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> * Make composite not care about in formatting of ids Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Adapt application builder and tests to array-like paths over string-like paths Array-like paths do not have weakness for special characters as part of id, such as ".". Also note: the error messaging for clicking of application menu in application builder is a bit worse now I think, but the simplification of the test code is worth it in this case IMHO. Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make composite not care about formatting of ids Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Adapt application builder and tests to array-like paths over string-like paths Array-like paths do not have weakness for special characters as part of id, such as ".". Also note: the error messaging for clicking of application menu in application builder is a bit worse now I think, but the simplification of the test code is worth it in this case IMHO. Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Consolidate output of get-composite-path to match find-composite's input Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make global overrides for functions log args of the call for devability Also make the thrown error suggest how to fix the problem. Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make attempts to log error throw in unit tests Errors cannot be allowed to happen without a unit test explicitly causing it. Errors cannot be allowed to happen without author of unit test knowing it. Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make composite not know about how children are transformed Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Remove some duplication from tests of composite Also make the thrown error suggest how to fix the problem. Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make composite unit test an unrealistic test scenario about undefined ids Also make the thrown error suggest how to fix the problem. Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Kill dead code Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Simplify unit tests for composite Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Consolidate tests to now point-free composite Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Simplify "Showable" Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make non-shown application menu items not break composite structure This was made apparent by adding related unit tests for all known environments. Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Simplify usages of Orderable and Showable Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Extract being maybe Showable as explicit composable responsibility Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make more showables maybe showable Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Consolidate logic for application menu for Windows to be based on composite Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Start using named export for composite Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Rename type for accuracy Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Remove unnecessary type and value Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make composable responsibilities readonly to nudge towards immutability Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Remove a bit of duplication to create TS-constants Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Make a comment and test name make more sense Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Simplify fallthrough in a switch/case Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Replace inline styles with proper CSS Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Switch to correct type to indicate "object which might not contain a property" Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Simplify overriding of platform in a unit test Also make typing of platforms more strict, and remove some magic strings. Also add a TODO for further OCP-ification. Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Consolidate some "maybe-types" and arguments using them Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> * Update snapshots Co-authored-by: Janne Savolainen <janne.savolainen@live.fi> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> Signed-off-by: Iku-turso <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi> Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
1 parent
38feab813c
commit
37eb236948
418 files changed
+39647
-27024
No files matched your search
+8
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import toggleMaximizeWindowInjectable from "./toggle-maximize-window.injectable";
|
||||
import { getGlobalOverrideForFunction } from "../../../../../common/test-utils/get-global-override-for-function";
|
||||
|
||||
export default getGlobalOverrideForFunction(toggleMaximizeWindowInjectable);
|
||||
+2
-2
@@ -3,8 +3,8 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { WindowAction } from "../../../../common/ipc/window";
|
||||
import { requestWindowAction } from "../../../ipc";
|
||||
import { WindowAction } from "../../../../../common/ipc/window";
|
||||
import { requestWindowAction } from "../../../../ipc";
|
||||
|
||||
const toggleMaximizeWindowInjectable = getInjectable({
|
||||
id: "toggle-maximize-window",
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import isLinuxInjectable from "../../../../../../common/vars/is-linux.injectable";
|
||||
import isWindowsInjectable from "../../../../../../common/vars/is-windows.injectable";
|
||||
import { computed } from "mobx";
|
||||
import { ContextMenu } from "./context-menu";
|
||||
import { topBarItemOnLeftSideInjectionToken } from "../top-bar-item-injection-token";
|
||||
|
||||
const contextMenuTopBarItemInjectable = getInjectable({
|
||||
id: "context-menu-top-bar-item",
|
||||
|
||||
instantiate: (di) => {
|
||||
const isWindows = di.inject(isWindowsInjectable);
|
||||
const isLinux = di.inject(isLinuxInjectable);
|
||||
|
||||
return {
|
||||
id: "context-menu",
|
||||
isShown: computed(() => isWindows || isLinux),
|
||||
orderNumber: 10,
|
||||
Component: ContextMenu,
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: topBarItemOnLeftSideInjectionToken,
|
||||
});
|
||||
|
||||
export default contextMenuTopBarItemInjectable;
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import React from "react";
|
||||
import styles from "../../top-bar.module.scss";
|
||||
import openAppContextMenuInjectable from "./open-app-context-menu/open-app-context-menu.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
openAppContextMenu: () => void;
|
||||
}
|
||||
|
||||
const NonInjectedContextMenu = ({ openAppContextMenu }: Dependencies) => (
|
||||
<div className={styles.winMenu}>
|
||||
<div onClick={openAppContextMenu} data-testid="window-menu">
|
||||
<svg
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
shapeRendering="crispEdges"
|
||||
>
|
||||
<path fill="currentColor" d="M0,8.5h12v1H0V8.5z" />
|
||||
<path fill="currentColor" d="M0,5.5h12v1H0V5.5z" />
|
||||
<path fill="currentColor" d="M0,2.5h12v1H0V2.5z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const ContextMenu = withInjectables<Dependencies>(
|
||||
NonInjectedContextMenu,
|
||||
|
||||
{
|
||||
getProps: (di) => ({
|
||||
openAppContextMenu: di.inject(openAppContextMenuInjectable),
|
||||
}),
|
||||
},
|
||||
);
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import openAppContextMenuInjectable from "./open-app-context-menu.injectable";
|
||||
import { getGlobalOverrideForFunction } from "../../../../../../../common/test-utils/get-global-override-for-function";
|
||||
|
||||
export default getGlobalOverrideForFunction(openAppContextMenuInjectable);
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { emitOpenAppMenuAsContextMenu } from "../../../ipc";
|
||||
import { emitOpenAppMenuAsContextMenu } from "../../../../../../ipc";
|
||||
|
||||
const openAppContextMenuInjectable = getInjectable({
|
||||
id: "open-app-context-menu",
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import goBackInjectable from "./go-back.injectable";
|
||||
import { getGlobalOverrideForFunction } from "../../../../../../../common/test-utils/get-global-override-for-function";
|
||||
|
||||
export default getGlobalOverrideForFunction(goBackInjectable);
|
||||
+2
-2
@@ -3,8 +3,8 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { WindowAction } from "../../../../common/ipc/window";
|
||||
import { requestWindowAction } from "../../../ipc";
|
||||
import { WindowAction } from "../../../../../../../common/ipc/window";
|
||||
import { requestWindowAction } from "../../../../../../ipc";
|
||||
|
||||
const goBackInjectable = getInjectable({
|
||||
id: "go-back",
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import { topBarItemOnLeftSideInjectionToken } from "../top-bar-item-injection-token";
|
||||
import { NavigationToBack } from "./navigation-to-back";
|
||||
|
||||
const navigationToBackTopBarItemInjectable = getInjectable({
|
||||
id: "navigation-to-back-top-bar-item",
|
||||
|
||||
instantiate: () => ({
|
||||
id: "navigation-to-back",
|
||||
isShown: computed(() => true),
|
||||
orderNumber: 30,
|
||||
Component: NavigationToBack,
|
||||
}),
|
||||
|
||||
injectionToken: topBarItemOnLeftSideInjectionToken,
|
||||
});
|
||||
|
||||
export default navigationToBackTopBarItemInjectable;
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import React from "react";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import { Icon } from "../../../../icon";
|
||||
import topBarPrevEnabledInjectable from "./prev-enabled.injectable";
|
||||
import goBackInjectable from "./go-back/go-back.injectable";
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
interface Dependencies {
|
||||
prevEnabled: IComputedValue<boolean>;
|
||||
goBack: () => void;
|
||||
}
|
||||
|
||||
const NonInjectedNavigationToBack = observer(({
|
||||
prevEnabled,
|
||||
goBack,
|
||||
}: Dependencies) => (
|
||||
<Icon
|
||||
data-testid="history-back"
|
||||
material="arrow_back"
|
||||
onClick={goBack}
|
||||
disabled={!prevEnabled.get()}
|
||||
/>
|
||||
));
|
||||
|
||||
export const NavigationToBack = withInjectables<Dependencies>(
|
||||
NonInjectedNavigationToBack,
|
||||
|
||||
{
|
||||
getProps: (di) => ({
|
||||
prevEnabled: di.inject(topBarPrevEnabledInjectable),
|
||||
goBack: di.inject(goBackInjectable),
|
||||
}),
|
||||
},
|
||||
);
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import topBarStateInjectable from "./state.injectable";
|
||||
import topBarStateInjectable from "../../state.injectable";
|
||||
|
||||
const topBarPrevEnabledInjectable = getInjectable({
|
||||
id: "top-bar-prev-enabled",
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import goForwardInjectable from "./go-forward.injectable";
|
||||
import { getGlobalOverrideForFunction } from "../../../../../../../common/test-utils/get-global-override-for-function";
|
||||
|
||||
export default getGlobalOverrideForFunction(goForwardInjectable);
|
||||
+2
-2
@@ -3,8 +3,8 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { WindowAction } from "../../../../common/ipc/window";
|
||||
import { requestWindowAction } from "../../../ipc";
|
||||
import { WindowAction } from "../../../../../../../common/ipc/window";
|
||||
import { requestWindowAction } from "../../../../../../ipc";
|
||||
|
||||
const goForwardInjectable = getInjectable({
|
||||
id: "go-forward",
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import { NavigationToForward } from "./navigation-to-forward";
|
||||
import { topBarItemOnLeftSideInjectionToken } from "../top-bar-item-injection-token";
|
||||
|
||||
const navigationToForwardTopBarItemInjectable = getInjectable({
|
||||
id: "navigation-to-forward-top-bar-item",
|
||||
|
||||
instantiate: () => ({
|
||||
id: "navigation-to-forward",
|
||||
isShown: computed(() => true),
|
||||
orderNumber: 40,
|
||||
Component: NavigationToForward,
|
||||
}),
|
||||
|
||||
injectionToken: topBarItemOnLeftSideInjectionToken,
|
||||
});
|
||||
|
||||
export default navigationToForwardTopBarItemInjectable;
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import React from "react";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import { Icon } from "../../../../icon";
|
||||
import topBarNextEnabledInjectable from "./next-enabled.injectable";
|
||||
import goForwardInjectable from "./go-forward/go-forward.injectable";
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
interface Dependencies {
|
||||
nextEnabled: IComputedValue<boolean>;
|
||||
goForward: () => void;
|
||||
}
|
||||
|
||||
const NonInjectedNavigationToForward = observer(({
|
||||
nextEnabled,
|
||||
goForward,
|
||||
}: Dependencies) => (
|
||||
<Icon
|
||||
data-testid="history-forward"
|
||||
material="arrow_forward"
|
||||
onClick={goForward}
|
||||
disabled={!nextEnabled.get()}
|
||||
/>
|
||||
));
|
||||
|
||||
export const NavigationToForward = withInjectables<Dependencies>(
|
||||
NonInjectedNavigationToForward,
|
||||
|
||||
{
|
||||
getProps: (di) => ({
|
||||
nextEnabled: di.inject(topBarNextEnabledInjectable),
|
||||
goForward: di.inject(goForwardInjectable),
|
||||
}),
|
||||
},
|
||||
);
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import topBarStateInjectable from "./state.injectable";
|
||||
import topBarStateInjectable from "../../state.injectable";
|
||||
|
||||
const topBarNextEnabledInjectable = getInjectable({
|
||||
id: "top-bar-next-enabled",
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import { NavigationToHome } from "./navigation-to-home";
|
||||
import { topBarItemOnLeftSideInjectionToken } from "../top-bar-item-injection-token";
|
||||
|
||||
const navigationToHomeTopBarItemInjectable = getInjectable({
|
||||
id: "navigation-to-home-top-bar-item",
|
||||
|
||||
instantiate: () => ({
|
||||
id: "navigation-to-home",
|
||||
isShown: computed(() => true),
|
||||
orderNumber: 20,
|
||||
Component: NavigationToHome,
|
||||
}),
|
||||
|
||||
injectionToken: topBarItemOnLeftSideInjectionToken,
|
||||
});
|
||||
|
||||
export default navigationToHomeTopBarItemInjectable;
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import React from "react";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import { Icon } from "../../../../icon";
|
||||
import routeIsActiveInjectable from "../../../../../routes/route-is-active.injectable";
|
||||
import { observer } from "mobx-react";
|
||||
import welcomeRouteInjectable from "../../../../../../common/front-end-routing/routes/welcome/welcome-route.injectable";
|
||||
import navigateToWelcomeInjectable from "../../../../../../common/front-end-routing/routes/welcome/navigate-to-welcome.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
disabled: IComputedValue<boolean>;
|
||||
goHome: () => void;
|
||||
}
|
||||
|
||||
const NonInjectedNavigationToHome = observer(({
|
||||
disabled,
|
||||
goHome,
|
||||
}: Dependencies) => (
|
||||
<Icon
|
||||
data-testid="home-button"
|
||||
material="home"
|
||||
onClick={goHome}
|
||||
disabled={disabled.get()}
|
||||
/>
|
||||
));
|
||||
|
||||
export const NavigationToHome = withInjectables<Dependencies>(
|
||||
NonInjectedNavigationToHome,
|
||||
|
||||
{
|
||||
getProps: (di) => ({
|
||||
disabled: di.inject(
|
||||
routeIsActiveInjectable,
|
||||
di.inject(welcomeRouteInjectable),
|
||||
),
|
||||
|
||||
goHome: di.inject(navigateToWelcomeInjectable),
|
||||
}),
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type React from "react";
|
||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||
import type { IComputedValue } from "mobx";
|
||||
|
||||
export interface TopBarItem {
|
||||
id: string;
|
||||
isShown: IComputedValue<boolean>;
|
||||
orderNumber: number;
|
||||
Component: React.ComponentType;
|
||||
}
|
||||
|
||||
export const topBarItemOnRightSideInjectionToken = getInjectionToken<TopBarItem>({
|
||||
id: "top-bar-item-on-right-side-injection-token",
|
||||
});
|
||||
|
||||
export const topBarItemOnLeftSideInjectionToken = getInjectionToken<TopBarItem>({
|
||||
id: "top-bar-item-on-left-side-injection-token",
|
||||
});
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { pipeline } from "@ogre-tools/fp";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
|
||||
import { filter, sortBy } from "lodash/fp";
|
||||
import { computed } from "mobx";
|
||||
import { topBarItemOnLeftSideInjectionToken } from "./top-bar-item-injection-token";
|
||||
|
||||
const topBarItemsOnLeftSideInjectable = getInjectable({
|
||||
id: "top-bar-items-on-left-side",
|
||||
|
||||
instantiate: (di) => {
|
||||
const computedInjectMany = di.inject(computedInjectManyInjectable);
|
||||
|
||||
const items = computedInjectMany(topBarItemOnLeftSideInjectionToken);
|
||||
|
||||
return computed(() =>
|
||||
pipeline(
|
||||
items.get(),
|
||||
filter((item) => item.isShown.get()),
|
||||
sortBy(item => item.orderNumber),
|
||||
),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export default topBarItemsOnLeftSideInjectable;
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { pipeline } from "@ogre-tools/fp";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
|
||||
import { filter, sortBy } from "lodash/fp";
|
||||
import { computed } from "mobx";
|
||||
import { topBarItemOnRightSideInjectionToken } from "./top-bar-item-injection-token";
|
||||
|
||||
const topBarItemsOnRightSideInjectable = getInjectable({
|
||||
id: "top-bar-items-on-right-side",
|
||||
|
||||
instantiate: (di) => {
|
||||
const computedInjectMany = di.inject(computedInjectManyInjectable);
|
||||
|
||||
const items = computedInjectMany(topBarItemOnRightSideInjectionToken);
|
||||
|
||||
return computed(() =>
|
||||
pipeline(
|
||||
items.get(),
|
||||
filter((item) => item.isShown.get()),
|
||||
sortBy(item => item.orderNumber),
|
||||
),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export default topBarItemsOnRightSideInjectable;
|
||||
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import rendererExtensionsInjectable from "../../../../../extensions/renderer-extensions.injectable";
|
||||
|
||||
const topBarItemsInjectable = getInjectable({
|
||||
id: "top-bar-items",
|
||||
|
||||
instantiate: (di) => {
|
||||
const extensions = di.inject(rendererExtensionsInjectable);
|
||||
|
||||
return computed(() =>
|
||||
extensions.get().flatMap((extension) => extension.topBarItems),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export default topBarItemsInjectable;
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import closeWindowInjectable from "./close-window.injectable";
|
||||
import { getGlobalOverrideForFunction } from "../../../../../../../common/test-utils/get-global-override-for-function";
|
||||
|
||||
export default getGlobalOverrideForFunction(closeWindowInjectable);
|
||||
+2
-2
@@ -3,8 +3,8 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { WindowAction } from "../../../../common/ipc/window";
|
||||
import { requestWindowAction } from "../../../ipc";
|
||||
import { WindowAction } from "../../../../../../../common/ipc/window";
|
||||
import { requestWindowAction } from "../../../../../../ipc";
|
||||
|
||||
const closeWindowInjectable = getInjectable({
|
||||
id: "close-window",
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import maximizeWindowInjectable from "./maximize-window.injectable";
|
||||
import { getGlobalOverrideForFunction } from "../../../../../../../common/test-utils/get-global-override-for-function";
|
||||
|
||||
export default getGlobalOverrideForFunction(maximizeWindowInjectable);
|
||||
+2
-2
@@ -3,8 +3,8 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { WindowAction } from "../../../../common/ipc/window";
|
||||
import { requestWindowAction } from "../../../ipc";
|
||||
import { WindowAction } from "../../../../../../../common/ipc/window";
|
||||
import { requestWindowAction } from "../../../../../../ipc";
|
||||
|
||||
const maximizeWindowInjectable = getInjectable({
|
||||
id: "maximize-window",
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import { topBarItemOnRightSideInjectionToken } from "../top-bar-item-injection-token";
|
||||
import { WindowControls } from "./window-controls";
|
||||
import isWindowsInjectable from "../../../../../../common/vars/is-windows.injectable";
|
||||
import isLinuxInjectable from "../../../../../../common/vars/is-linux.injectable";
|
||||
|
||||
const windowControlsTopBarItemInjectable = getInjectable({
|
||||
id: "window-controls-top-bar-item",
|
||||
|
||||
instantiate: (di) => {
|
||||
const isWindows = di.inject(isWindowsInjectable);
|
||||
const isLinux = di.inject(isLinuxInjectable);
|
||||
|
||||
return ({
|
||||
id: "window-controls",
|
||||
orderNumber: 900,
|
||||
isShown: computed(() => (isWindows || isLinux)),
|
||||
Component: WindowControls,
|
||||
});
|
||||
},
|
||||
|
||||
injectionToken: topBarItemOnRightSideInjectionToken,
|
||||
});
|
||||
|
||||
export default windowControlsTopBarItemInjectable;
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import React from "react";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import { cssNames } from "../../../../../utils";
|
||||
import styles from "../../top-bar.module.scss";
|
||||
import isLinuxInjectable from "../../../../../../common/vars/is-linux.injectable";
|
||||
import toggleMaximizeWindowInjectable from "../../toggle-maximize-window/toggle-maximize-window.injectable";
|
||||
import closeWindowInjectable from "./close-window/close-window.injectable";
|
||||
import maximizeWindowInjectable from "./maximize-window/maximize-window.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
isLinux: boolean;
|
||||
toggleMaximizeWindow: () => void;
|
||||
closeWindow: () => void;
|
||||
minimizeWindow: () => void;
|
||||
}
|
||||
|
||||
const NonInjectedWindowControls = ({
|
||||
isLinux,
|
||||
toggleMaximizeWindow,
|
||||
closeWindow,
|
||||
minimizeWindow,
|
||||
}: Dependencies) => (
|
||||
<div
|
||||
className={cssNames(styles.windowButtons, {
|
||||
[styles.linuxButtons]: isLinux,
|
||||
})}
|
||||
>
|
||||
<div
|
||||
className={styles.minimize}
|
||||
data-testid="window-minimize"
|
||||
onClick={minimizeWindow}
|
||||
>
|
||||
<svg shapeRendering="crispEdges" viewBox="0 0 12 12">
|
||||
<rect
|
||||
fill="currentColor"
|
||||
width="10"
|
||||
height="1"
|
||||
x="1"
|
||||
y="9" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={styles.maximize}
|
||||
data-testid="window-maximize"
|
||||
onClick={toggleMaximizeWindow}
|
||||
>
|
||||
<svg shapeRendering="crispEdges" viewBox="0 0 12 12">
|
||||
<rect
|
||||
width="9"
|
||||
height="9"
|
||||
x="1.5"
|
||||
y="1.5"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={styles.close}
|
||||
data-testid="window-close"
|
||||
onClick={closeWindow}
|
||||
>
|
||||
<svg shapeRendering="crispEdges" viewBox="0 0 12 12">
|
||||
<polygon
|
||||
fill="currentColor"
|
||||
points="11 1.576 6.583 6 11 10.424 10.424 11 6 6.583 1.576 11 1 10.424 5.417 6 1 1.576 1.576 1 6 5.417 10.424 1"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const WindowControls = withInjectables<Dependencies>(
|
||||
NonInjectedWindowControls,
|
||||
|
||||
{
|
||||
getProps: (di) => ({
|
||||
isLinux: di.inject(isLinuxInjectable),
|
||||
toggleMaximizeWindow: di.inject(toggleMaximizeWindowInjectable),
|
||||
closeWindow: di.inject(closeWindowInjectable),
|
||||
minimizeWindow: di.inject(maximizeWindowInjectable),
|
||||
}),
|
||||
},
|
||||
);
|
||||
@@ -4,13 +4,10 @@
|
||||
*/
|
||||
|
||||
.topBar {
|
||||
display: flex;
|
||||
background-color: var(--layoutBackground);
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
grid-area: topbar;
|
||||
height: var(--main-layout-header);
|
||||
justify-content: space-between;
|
||||
|
||||
/* Use topbar as draggable region */
|
||||
user-select: none;
|
||||
@@ -18,26 +15,20 @@
|
||||
}
|
||||
|
||||
.topBar .items {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
padding-left: calc(var(--padding) * 2);
|
||||
padding-right: calc(var(--padding) * 2);
|
||||
}
|
||||
|
||||
.preventedDragging {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
&:first-of-type {
|
||||
padding-left: calc(var(--padding) * 2);
|
||||
|
||||
& > *:not(:empty) {
|
||||
margin-right: calc(var(--padding) * 1.5);
|
||||
}
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
padding-right: calc(var(--padding) * 2);
|
||||
|
||||
& > *:not(:empty) {
|
||||
margin-left: calc(var(--padding) * 1.5);
|
||||
}
|
||||
}
|
||||
.separator {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
:global(.is-mac) .topBar {
|
||||
|
||||
@@ -11,17 +11,16 @@ import { getDiForUnitTesting } from "../../../getDiForUnitTesting";
|
||||
import type { DiContainer } from "@ogre-tools/injectable";
|
||||
import type { DiRender } from "../../test-utils/renderFor";
|
||||
import { renderFor } from "../../test-utils/renderFor";
|
||||
import topBarItemsInjectable from "./top-bar-items/top-bar-items.injectable";
|
||||
import { computed, observable } from "mobx";
|
||||
import rendererExtensionsInjectable from "../../../../extensions/renderer-extensions.injectable";
|
||||
import closeWindowInjectable from "./close-window.injectable";
|
||||
import goBackInjectable from "./go-back.injectable";
|
||||
import goForwardInjectable from "./go-forward.injectable";
|
||||
import maximizeWindowInjectable from "./maximize-window.injectable";
|
||||
import openAppContextMenuInjectable from "./open-app-context-menu.injectable";
|
||||
import toggleMaximizeWindowInjectable from "./toggle-maximize-window.injectable";
|
||||
import closeWindowInjectable from "./top-bar-items/window-controls/close-window/close-window.injectable";
|
||||
import goBackInjectable from "./top-bar-items/navigation-to-back/go-back/go-back.injectable";
|
||||
import maximizeWindowInjectable from "./top-bar-items/window-controls/maximize-window/maximize-window.injectable";
|
||||
import openAppContextMenuInjectable from "./top-bar-items/context-menu/open-app-context-menu/open-app-context-menu.injectable";
|
||||
import toggleMaximizeWindowInjectable from "./toggle-maximize-window/toggle-maximize-window.injectable";
|
||||
import topBarStateInjectable from "./state.injectable";
|
||||
import platformInjectable from "../../../../common/vars/platform.injectable";
|
||||
import goForwardInjectable from "./top-bar-items/navigation-to-forward/go-forward/go-forward.injectable";
|
||||
|
||||
describe("<TopBar/>", () => {
|
||||
let di: DiContainer;
|
||||
@@ -54,6 +53,7 @@ describe("<TopBar/>", () => {
|
||||
nextEnabled: true,
|
||||
}));
|
||||
});
|
||||
|
||||
it("renders w/o errors", () => {
|
||||
const { container } = render(<TopBar/>);
|
||||
|
||||
@@ -95,23 +95,6 @@ describe("<TopBar/>", () => {
|
||||
expect(goForward).toBeCalled();
|
||||
});
|
||||
|
||||
it("renders items", async () => {
|
||||
const testId = "testId";
|
||||
const text = "an item";
|
||||
|
||||
di.override(topBarItemsInjectable, () => computed(() => [
|
||||
{
|
||||
components: {
|
||||
Item: () => <span data-testid={testId}>{text}</span>,
|
||||
},
|
||||
},
|
||||
]));
|
||||
|
||||
const { findByTestId } = render(<TopBar/>);
|
||||
|
||||
expect(await findByTestId(testId)).toHaveTextContent(text);
|
||||
});
|
||||
|
||||
describe("on macos", () => {
|
||||
beforeEach(() => {
|
||||
di.override(platformInjectable, () => "darwin");
|
||||
|
||||
@@ -4,199 +4,76 @@
|
||||
*/
|
||||
|
||||
import styles from "./top-bar.module.scss";
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import { Icon } from "../../icon";
|
||||
import { cssNames } from "../../../utils";
|
||||
import topBarItemsInjectable from "./top-bar-items/top-bar-items.injectable";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import type { TopBarRegistration } from "./top-bar-registration";
|
||||
import isLinuxInjectable from "../../../../common/vars/is-linux.injectable";
|
||||
import isWindowsInjectable from "../../../../common/vars/is-windows.injectable";
|
||||
import routeIsActiveInjectable from "../../../routes/route-is-active.injectable";
|
||||
import { UpdateButton } from "../../update-button";
|
||||
import topBarPrevEnabledInjectable from "./prev-enabled.injectable";
|
||||
import topBarNextEnabledInjectable from "./next-enabled.injectable";
|
||||
import openAppContextMenuInjectable from "./open-app-context-menu.injectable";
|
||||
import goBackInjectable from "./go-back.injectable";
|
||||
import goForwardInjectable from "./go-forward.injectable";
|
||||
import closeWindowInjectable from "./close-window.injectable";
|
||||
import maximizeWindowInjectable from "./maximize-window.injectable";
|
||||
import toggleMaximizeWindowInjectable from "./toggle-maximize-window.injectable";
|
||||
import toggleMaximizeWindowInjectable from "./toggle-maximize-window/toggle-maximize-window.injectable";
|
||||
import watchHistoryStateInjectable from "../../../remote-helpers/watch-history-state.injectable";
|
||||
import welcomeRouteInjectable from "../../../../common/front-end-routing/routes/welcome/welcome-route.injectable";
|
||||
import navigateToWelcomeInjectable from "../../../../common/front-end-routing/routes/welcome/navigate-to-welcome.injectable";
|
||||
import topBarItemsOnRightSideInjectable from "./top-bar-items/top-bar-items-on-right-side.injectable";
|
||||
import type { TopBarItem } from "./top-bar-items/top-bar-item-injection-token";
|
||||
import { Map } from "../../map/map";
|
||||
import Gutter from "../../gutter/gutter";
|
||||
import topBarItemsOnLeftSideInjectable from "./top-bar-items/top-bar-items-on-left-side.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
navigateToWelcomePage: () => void;
|
||||
welcomeRouteIsActive: IComputedValue<boolean>;
|
||||
items: IComputedValue<TopBarRegistration[]>;
|
||||
isWindows: boolean;
|
||||
isLinux: boolean;
|
||||
prevEnabled: IComputedValue<Boolean>;
|
||||
nextEnabled: IComputedValue<Boolean>;
|
||||
openAppContextMenu: () => void;
|
||||
goBack: () => void;
|
||||
goForward: () => void;
|
||||
minimizeWindow: () => void;
|
||||
itemsOnLeft: IComputedValue<TopBarItem[]>;
|
||||
itemsOnRight: IComputedValue<TopBarItem[]>;
|
||||
toggleMaximizeWindow: () => void;
|
||||
closeWindow: () => void;
|
||||
watchHistoryState: () => () => void;
|
||||
}
|
||||
|
||||
const NonInjectedTopBar = observer(({
|
||||
items,
|
||||
navigateToWelcomePage,
|
||||
welcomeRouteIsActive,
|
||||
isWindows,
|
||||
isLinux,
|
||||
prevEnabled,
|
||||
nextEnabled,
|
||||
openAppContextMenu,
|
||||
goBack,
|
||||
goForward,
|
||||
closeWindow,
|
||||
minimizeWindow,
|
||||
toggleMaximizeWindow,
|
||||
watchHistoryState,
|
||||
}: Dependencies) => {
|
||||
const elem = useRef<HTMLDivElement | null>(null);
|
||||
const NonInjectedTopBar = observer(
|
||||
({
|
||||
itemsOnLeft,
|
||||
itemsOnRight,
|
||||
toggleMaximizeWindow,
|
||||
watchHistoryState,
|
||||
}: Dependencies) => {
|
||||
useEffect(() => watchHistoryState(), []);
|
||||
|
||||
const goHome = () => {
|
||||
navigateToWelcomePage();
|
||||
};
|
||||
return (
|
||||
<div className={styles.topBar} onDoubleClick={toggleMaximizeWindow}>
|
||||
<div className={styles.items}>
|
||||
<Map
|
||||
items={itemsOnLeft.get()}
|
||||
getSeparator={() => <Gutter size="sm" />}
|
||||
>
|
||||
{toItemWhichWorksWithWindowDraggingAndDoubleClicking}
|
||||
</Map>
|
||||
|
||||
const windowSizeToggle = (evt: React.MouseEvent) => {
|
||||
if (elem.current === evt.target) {
|
||||
toggleMaximizeWindow();
|
||||
}
|
||||
};
|
||||
<div className={styles.separator} />
|
||||
|
||||
useEffect(() => watchHistoryState(), []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={styles.topBar}
|
||||
onDoubleClick={windowSizeToggle}
|
||||
ref={elem}
|
||||
>
|
||||
<div className={styles.items}>
|
||||
{(isWindows || isLinux) && (
|
||||
<div className={styles.winMenu}>
|
||||
<div onClick={openAppContextMenu} data-testid="window-menu">
|
||||
<svg
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
shapeRendering="crispEdges"
|
||||
>
|
||||
<path fill="currentColor" d="M0,8.5h12v1H0V8.5z" />
|
||||
<path fill="currentColor" d="M0,5.5h12v1H0V5.5z" />
|
||||
<path fill="currentColor" d="M0,2.5h12v1H0V2.5z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<Icon
|
||||
data-testid="home-button"
|
||||
material="home"
|
||||
onClick={goHome}
|
||||
disabled={welcomeRouteIsActive.get()}
|
||||
/>
|
||||
<Icon
|
||||
data-testid="history-back"
|
||||
material="arrow_back"
|
||||
onClick={goBack}
|
||||
disabled={!prevEnabled.get()}
|
||||
/>
|
||||
<Icon
|
||||
data-testid="history-forward"
|
||||
material="arrow_forward"
|
||||
onClick={goForward}
|
||||
disabled={!nextEnabled.get()}
|
||||
/>
|
||||
<UpdateButton />
|
||||
<Map
|
||||
items={itemsOnRight.get()}
|
||||
getSeparator={() => <Gutter size="sm" />}
|
||||
>
|
||||
{toItemWhichWorksWithWindowDraggingAndDoubleClicking}
|
||||
</Map>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.items}>
|
||||
{renderRegisteredItems(items.get())}
|
||||
{(isWindows || isLinux) && (
|
||||
<div className={cssNames(styles.windowButtons, { [styles.linuxButtons]: isLinux })}>
|
||||
<div
|
||||
className={styles.minimize}
|
||||
data-testid="window-minimize"
|
||||
onClick={minimizeWindow}
|
||||
>
|
||||
<svg shapeRendering="crispEdges" viewBox="0 0 12 12">
|
||||
<rect
|
||||
fill="currentColor"
|
||||
width="10"
|
||||
height="1"
|
||||
x="1"
|
||||
y="9"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
className={styles.maximize}
|
||||
data-testid="window-maximize"
|
||||
onClick={toggleMaximizeWindow}
|
||||
>
|
||||
<svg shapeRendering="crispEdges" viewBox="0 0 12 12">
|
||||
<rect
|
||||
width="9"
|
||||
height="9"
|
||||
x="1.5"
|
||||
y="1.5"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
className={styles.close}
|
||||
data-testid="window-close"
|
||||
onClick={closeWindow}
|
||||
>
|
||||
<svg shapeRendering="crispEdges" viewBox="0 0 12 12">
|
||||
<polygon fill="currentColor" points="11 1.576 6.583 6 11 10.424 10.424 11 6 6.583 1.576 11 1 10.424 5.417 6 1 1.576 1.576 1 6 5.417 10.424 1" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
const renderRegisteredItems = (items: TopBarRegistration[]) => (
|
||||
items.map((registration, index) => {
|
||||
if (!registration?.components?.Item) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <registration.components.Item key={index} />;
|
||||
})
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export const TopBar = withInjectables<Dependencies>(NonInjectedTopBar, {
|
||||
getProps: (di) => ({
|
||||
navigateToWelcomePage: di.inject(navigateToWelcomeInjectable),
|
||||
items: di.inject(topBarItemsInjectable),
|
||||
isLinux: di.inject(isLinuxInjectable),
|
||||
isWindows: di.inject(isWindowsInjectable),
|
||||
prevEnabled: di.inject(topBarPrevEnabledInjectable),
|
||||
nextEnabled: di.inject(topBarNextEnabledInjectable),
|
||||
welcomeRouteIsActive: di.inject(
|
||||
routeIsActiveInjectable,
|
||||
di.inject(welcomeRouteInjectable),
|
||||
),
|
||||
openAppContextMenu: di.inject(openAppContextMenuInjectable),
|
||||
goBack: di.inject(goBackInjectable),
|
||||
goForward: di.inject(goForwardInjectable),
|
||||
closeWindow: di.inject(closeWindowInjectable),
|
||||
minimizeWindow: di.inject(maximizeWindowInjectable),
|
||||
itemsOnLeft: di.inject(topBarItemsOnLeftSideInjectable),
|
||||
itemsOnRight: di.inject(topBarItemsOnRightSideInjectable),
|
||||
toggleMaximizeWindow: di.inject(toggleMaximizeWindowInjectable),
|
||||
watchHistoryState: di.inject(watchHistoryStateInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
const toItemWhichWorksWithWindowDraggingAndDoubleClicking = (
|
||||
item: TopBarItem,
|
||||
) => (
|
||||
<div
|
||||
className={styles.preventedDragging}
|
||||
onDoubleClick={(event) => {
|
||||
return event.stopPropagation();
|
||||
}}
|
||||
>
|
||||
<item.Component />
|
||||
</div>
|
||||
);
|
||||
Reference in new issue
Block a user