From db090782ca53958b6bba1ac23d91d1c60af9621e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr>
Date: Thu, 14 Mar 2024 21:33:12 +0100
Subject: [PATCH] [ivette] labview API

---
 ivette/src/ivette/display.tsx    | 61 +++++++++++++++++++++++++++-----
 ivette/src/ivette/laboratory.tsx | 14 ++++----
 2 files changed, 59 insertions(+), 16 deletions(-)

diff --git a/ivette/src/ivette/display.tsx b/ivette/src/ivette/display.tsx
index e5b3cb3744e..dd6567a9876 100644
--- a/ivette/src/ivette/display.tsx
+++ b/ivette/src/ivette/display.tsx
@@ -20,9 +20,9 @@
 /*                                                                          */
 /* ************************************************************************ */
 
-/* --------------------------------------------------------------------------*/
-/* --- Display Interaction                                                ---*/
-/* --------------------------------------------------------------------------*/
+/* -------------------------------------------------------------------------- */
+/* --- Display Interaction                                                --- */
+/* -------------------------------------------------------------------------- */
 
 /**
    @packageDocumentation
@@ -30,7 +30,7 @@
  */
 
 import React from 'react';
-import { VIEW, COMPONENT } from 'ivette';
+import { VIEW, COMPONENT, LayoutPosition } from 'ivette';
 import * as State from './state';
 import * as Laboratory from './laboratory';
 
@@ -44,7 +44,7 @@ export interface ItemProps {
  */
 export function ViemItem(props: ItemProps): JSX.Element | null {
   const { id, selected=false } = props;
-  const view = State.useElement(VIEW,id);
+  const view = State.useElement(VIEW, id);
   const state = Laboratory.useState();
   if (!view) return null;
   const status = Laboratory.getViewStatus(state, id);
@@ -62,7 +62,7 @@ export function ViemItem(props: ItemProps): JSX.Element | null {
  */
 export function ComponentItem(props: ItemProps): JSX.Element | null {
   const { id, selected=false } = props;
-  const comp = State.useElement(COMPONENT,id);
+  const comp = State.useElement(COMPONENT, id);
   const state = Laboratory.useState();
   if (!comp) return null;
   const status = Laboratory.getComponentStatus(state, id);
@@ -75,11 +75,54 @@ export function ComponentItem(props: ItemProps): JSX.Element | null {
   );
 }
 
+export interface GroupItemsProps {
+  id: string;
+  selected?: string;
+}
+
 /**
    A bundle of sidebar items for controlling an Ivette group of components.
  */
-export function GroupSection(props: ItemProps): JSX.Element | null {
-  return <>{props.id}</>;
+export function GroupItems(props: GroupItemsProps): JSX.Element | null {
+  const items =
+    State.useElements(COMPONENT)
+         .filter(Laboratory.inGroup(props))
+         .map(({ id }) => (
+           <ComponentItem
+             key={id}
+             id={id}
+             selected={id === props.selected} />
+         ));
+  return <>{items}</>;
+}
+
+/** Switch display to specified view. */
+export function switchToView(id: string): void {
+  const view = VIEW.getElement(id);
+  if (view) Laboratory.applyView(view);
+}
+
+/** Show component. */
+export function showComponent(id: string, at?: LayoutPosition): void
+{
+  const comp = COMPONENT.getElement(id);
+  if (comp) Laboratory.applyComponent(comp, at);
+}
+
+/** Dock component. */
+export function dockComponent(id: string, at?: LayoutPosition): void
+{
+  const comp = COMPONENT.getElement(id);
+  if (comp) Laboratory.dockComponent(comp, at);
+}
+
+/** Component Status Hook. */
+export function useComponentStatus(
+  id: string | undefined
+): Laboratory.ComponentStatus
+{
+  const state = Laboratory.useState();
+  return Laboratory.getComponentStatus(state, id ?? '');
 }
 
-/* --------------------------------------------------------------------------*/
+/* -------------------------------------------------------------------------- */
diff --git a/ivette/src/ivette/laboratory.tsx b/ivette/src/ivette/laboratory.tsx
index 9515e8c2561..a4674a420e3 100644
--- a/ivette/src/ivette/laboratory.tsx
+++ b/ivette/src/ivette/laboratory.tsx
@@ -475,7 +475,7 @@ function restoreDefault(key: tabKey): void {
   }
 }
 
-function applyView(view: Ivette.ViewLayoutProps): void {
+export function applyView(view: Ivette.ViewLayoutProps): void {
   const state = LAB.getValue();
   const viewId = view.id;
   if (state.tabs.has(viewId))
@@ -521,7 +521,7 @@ function applyFavorite(
   }
 }
 
-function applyComponent(
+export function applyComponent(
   comp: Ivette.ComponentProps,
   at?: LayoutPosition
 ): void {
@@ -533,7 +533,7 @@ function applyComponent(
   LAB.setValue({ ...state, panels, stack });
 }
 
-function dockComponent(
+export function dockComponent(
   comp: Ivette.ComponentProps,
   at?: Ivette.LayoutPosition
 ): void
@@ -660,7 +660,7 @@ export function getComponentStatus(
 ): ComponentStatus
 {
   const layout = state.stack[0] ?? defaultLayout;
-  const position= getLayoutPosition(layout, compId);
+  const position = getLayoutPosition(layout, compId);
   const active = state.panels.has(compId);
   const docked = state.docked.has(compId);
   return { position, active, docked };
@@ -1054,9 +1054,9 @@ export function ComponentItem(props: ComponentItemProps): JSX.Element {
 
 interface ID { id: string }
 
-const inGroup = (group: ID) => (elt: ID) => elt.id.startsWith(group.id+'.');
-const groupOf = (elt: ID) => (group: ID) => elt.id.startsWith(group.id+'.');
-const inNoGroup = (groups: ID[]) => (elt: ID) => !groups.some(groupOf(elt));
+export const inGroup = (g: ID) => (e: ID) => e.id.startsWith(g.id+'.');
+export const groupOf = (e: ID) => (g: ID) => e.id.startsWith(g.id+'.');
+export const inNoGroup = (gs: ID[]) => (e: ID) => !gs.some(groupOf(e));
 
 interface GroupSectionProps extends Ivette.ItemProps {
   filter: (comp: ID) => boolean;
-- 
GitLab