Skip to content

Commit

Permalink
feat: implement Elektro module with initial components, actions, and …
Browse files Browse the repository at this point in the history
…GraphQL client setup
  • Loading branch information
jhnnsrs committed Feb 26, 2025
1 parent b9e89d2 commit 77f330d
Show file tree
Hide file tree
Showing 24 changed files with 3,647 additions and 5 deletions.
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,9 @@ Before the new version of Orkestrator can be merged into the main repository, th
- [ ] Basic UI Testing
- [ ] User Stories (e.g. documentation for specific user stories)
- [ ] Documentation, Documentation, Documentation
- [ ] Move to React Query (suggested)
- [ ] Move to React TanStack Router (suggested)
- [x] Lazy Load Modules (only if corresponding service in Deployment)
- [ ] Hosted Deployment (e.g. on Vercel)
- [ ] Hosted Deployment (e.g. on Goethe Cluster)
- [x] CI/CD Pipeline


## Service Specific Next Features
Expand All @@ -73,7 +72,7 @@ Before the new version of Orkestrator can be merged into the main repository, th

- [x] Move to Mikro Next
- [X] Establish "Views" as central concept
- [ ] Deprecated OMERO metadata support
- [X] Deprecated OMERO metadata support

### Fluss

Expand All @@ -92,7 +91,7 @@ Before the new version of Orkestrator can be merged into the main repository, th

- [x] Establish Kabinet
- [X] Create App Store like Feature
- [ ] Create App Store UI
- [X] Create App Store UI

### Omero-Ark

Expand All @@ -108,5 +107,9 @@ Before the new version of Orkestrator can be merged into the main repository, th
- [ ] Build Kluster UI
- [ ] Elaborate on Dask-Cluster integration
- [ ] Provide support for other cluster

### Elektro

- [ ] Implement basic trace visualization


2 changes: 2 additions & 0 deletions src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { PrivateNavigationBar } from "./components/navigation/PrivateNavigationB
import KraphModule from "@/kraph/KraphModule";
import BlokModule from "@/blok/BlokModule";
import AlpakaModule from "@/alpaka/AlpakaModule";
import ElektroModule from "@/elektro/ElektroModule";
// Entrypoint of the application.
// We provide two main routers, one for the public routes, and one for the private routes.
export const protect = (component: React.ReactNode) => {
Expand Down Expand Up @@ -51,6 +52,7 @@ function App() {
{/* This is the callback route for the herre provider, and needs to be publicalyl available. (Represents Oauth2 Callback)*/}
<Route index element={<Hero />} />
<Route path="mikro/*" element={protect(<MikroNextModule />)} />
<Route path="elektro/*" element={protect(<ElektroModule />)} />
<Route
path="rekuest/*"
element={protect(<RekuestNextModule />)}
Expand Down
4 changes: 4 additions & 0 deletions src/app/AppProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Button } from "@/components/ui/button";
import { Toaster } from "@/components/ui/sonner";
import { ShadnWigets } from "@/components/widgets/ShadnWigets";
import { baseName, Router, WELL_KNOWN_ENDPOINTS } from "@/constants";
import { ElektroWard } from "@/elektro/ElektroWard";
import { KabinetWard } from "@/kabinet/KabinetWard";
import { KraphWard } from "@/kraph/KraphWard";
import { WellKnownDiscovery } from "@/lib/fakts";
Expand Down Expand Up @@ -124,6 +125,9 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
<Guard.Alpaka fallback={<></>}>
<AlpakaWard key="alpaka" />
</Guard.Alpaka>
<Guard.Elektro fallback={<></>}>
<ElektroWard key="elektro" />
</Guard.Elektro>
<Guard.Mikro fallback={<></>}>
<MikroNextWard key="mikro" />
</Guard.Mikro>
Expand Down
3 changes: 3 additions & 0 deletions src/app/components/navigation/PrivateNavigationBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { TbBugOff } from "react-icons/tb";
import { ModeToggle } from "../ModeToggle";
import { Icons } from "@/components/icons";
import { BiSolidWidget } from "react-icons/bi";
import { BsLightning } from "react-icons/bs";

export type INavigationBarProps = {
children?: React.ReactNode;
Expand Down Expand Up @@ -64,6 +65,8 @@ export const matchIcon = (key: string) => {
return (
<ChatBubbleIcon className="w-8 h-8 mx-auto text-foreground p-[0.5]" />
);
case "elektro":
return <BsLightning className="w-8 h-8 mx-auto text-foreground" />;
default:
return <HomeIcon className="w-8 h-8 mx-auto text-foreground" />;
}
Expand Down
27 changes: 27 additions & 0 deletions src/arkitekt/Arkitekt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { App, ServiceMap } from "./types";
import { createLivekitClient } from "@/lib/livekit/client";
import { createKraphClient } from "@/lib/kraph/client";
import { createAlpakaClient } from "@/lib/alpaka/client";
import { createElektroClient } from "@/lib/elektro/client";

export const electronRedirect = async (
url: string,
Expand Down Expand Up @@ -151,6 +152,21 @@ export const serviceMap: ServiceBuilderMap = {
};
},
},
elektro: {
key: "elektro",
service: "live.arkitekt.elektro",
optional: true,
builder: (manifest, fakts: any, token) => {
return {
client: createElektroClient({
wsEndpointUrl: fakts.alpaka.ws_endpoint_url,
endpointUrl: fakts.alpaka.endpoint_url,
possibleTypes: alpakaResult.possibleTypes,
retrieveToken: () => token,
}),
};
},
},
livekit: {
key: "livekit",
service: "io.livekit.livekit",
Expand Down Expand Up @@ -195,6 +211,7 @@ export const Guard = {
Livekit: buildGuard("livekit"),
Kraph: buildGuard("kraph"),
Alpaka: buildGuard("alpaka"),
Elektro: buildGuard("elektro"),
};

export const useMikro = (): ApolloClient<NormalizedCache> => {
Expand Down Expand Up @@ -277,6 +294,16 @@ export const useAlpaka = (): ApolloClient<NormalizedCache> => {
return clients.alpaka?.client;
};

export const useElektro = (): ApolloClient<NormalizedCache> => {
const { clients } = useArkitekt();

if (!clients.elektro?.client) {
throw new Error("Elektro client not available");
}

return clients.elektro?.client;
};

export const useLivekit = (): LivekitClient => {
const { clients } = useArkitekt();

Expand Down
23 changes: 23 additions & 0 deletions src/elektro/ElektroModule.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Guard } from "@/arkitekt/Arkitekt";
import { ModuleLayout } from "@/components/layout/ModuleLayout";
import React from "react";
import { Route, Routes } from "react-router";
import HomePage from "./pages/HomePage";
import RoomPage from "./pages/RoomPage";
import StandardPane from "./panes/StandardPane";
interface Props {}

export const ElektroModule: React.FC<Props> = (props) => {
return (
<Guard.Elektro fallback={<>Loading</>}>
<ModuleLayout pane={<StandardPane />}>
<Routes>
<Route path="rooms/:id" element={<RoomPage />} />
<Route path="*" element={<HomePage />} />
</Routes>
</ModuleLayout>
</Guard.Elektro>
);
};

export default ElektroModule;
35 changes: 35 additions & 0 deletions src/elektro/ElektroWard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useAlpaka } from "@/arkitekt/Arkitekt";
import { useWidgetRegistry } from "@/rekuest/widgets/WidgetsContext";
import { gql } from "@apollo/client";
import { useEffect } from "react";

export const ElektroWard: React.FC<{
fallback?: React.ReactNode;
key: string;
}> = ({ key, fallback }) => {
const client = useAlpaka();
const { registry } = useWidgetRegistry();

useEffect(() => {
if (client) {
const runFunc = (options: { query: string; variables: any }) => {
let document = gql(options.query);
return client
.query({
query: document,
variables: options.variables,
})
.then((result: any) => {
console.log(result.data);
return result.data.options;
});
};

registry?.registerWard(key, {
search: runFunc,
});
}
}, [client, registry]);

return <>{fallback}</>;
};
40 changes: 40 additions & 0 deletions src/elektro/SystemMessage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Button } from "@/components/ui/button";
import {
useAcknowledgeMessageMutation,
useMyActiveMessagesQuery,
} from "./api/graphql";

export const SystemMessageDisplay = (props: {}) => {
const { data, error } = useMyActiveMessagesQuery();
const [ack] = useAcknowledgeMessageMutation({
refetchQueries: ["MyActiveMessages"],
});

console.log("yyst", data, error);
return (
<>
{(data?.myActiveMessages?.length || 0) > 0 && (
<div className="absolute top-0 right-0 h-screen w-screen ">
{data?.myActiveMessages.map((message) => (
<div
key={message.id}
className="p-2 rounded shadow-md bg-black opacity-99 p-2 text-white absolute w-full h-full z-100"
>
<div className="top-[50%] left-[50%] translate-x-[-50%] translate-y-[50%] text-white w-100 ">
<div className="font-bold">{message.title}</div>
<div>{message.message}</div>
<Button
onClick={() =>
ack({ variables: { id: message.id, ack: true } })
}
>
Acknowledge
</Button>
</div>
</div>
))}
</div>
)}
</>
);
};
21 changes: 21 additions & 0 deletions src/elektro/api/fragments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

export interface PossibleTypesResultData {
possibleTypes: {
[key: string]: string[]
}
}
const result: PossibleTypesResultData = {
"possibleTypes": {
"Descendant": [
"LeafDescendant",
"MentionDescendant",
"ParagraphDescendant"
],
"SocialAccount": [
"GenericAccount",
"OrcidAccount"
]
}
};
export default result;

Loading

0 comments on commit 77f330d

Please sign in to comment.