@checkmate-monitor/queue-frontend 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,13 @@
1
+ # @checkmate-monitor/queue-frontend
2
+
3
+ ## 0.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [eff5b4e]
8
+ - Updated dependencies [ffc28f6]
9
+ - Updated dependencies [b354ab3]
10
+ - @checkmate-monitor/ui@0.1.0
11
+ - @checkmate-monitor/common@0.1.0
12
+ - @checkmate-monitor/frontend-api@0.0.2
13
+ - @checkmate-monitor/queue-common@0.0.2
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@checkmate-monitor/queue-frontend",
3
+ "version": "0.0.2",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "dev": "tsc --watch",
10
+ "typecheck": "tsc --noEmit",
11
+ "lint": "bun run lint:code",
12
+ "lint:code": "eslint . --max-warnings 0"
13
+ },
14
+ "dependencies": {
15
+ "@checkmate-monitor/common": "workspace:*",
16
+ "@checkmate-monitor/frontend-api": "workspace:*",
17
+ "@checkmate-monitor/queue-common": "workspace:*",
18
+ "@checkmate-monitor/ui": "workspace:*",
19
+ "ajv": "^8.17.1",
20
+ "ajv-formats": "^3.0.1",
21
+ "lucide-react": "^0.468.0",
22
+ "prismjs": "^1.29.0",
23
+ "react": "^18.3.1",
24
+ "react-router-dom": "^7.1.1",
25
+ "react-simple-code-editor": "^0.14.1",
26
+ "zod": "^4.0.0"
27
+ },
28
+ "devDependencies": {
29
+ "@types/react": "^18.3.18",
30
+ "typescript": "^5.7.2",
31
+ "@checkmate-monitor/tsconfig": "workspace:*",
32
+ "@checkmate-monitor/scripts": "workspace:*"
33
+ }
34
+ }
package/src/api.ts ADDED
@@ -0,0 +1,15 @@
1
+ import { createApiRef } from "@checkmate-monitor/frontend-api";
2
+ import { QueueApi } from "@checkmate-monitor/queue-common";
3
+ import type { InferClient } from "@checkmate-monitor/common";
4
+
5
+ // Re-export types for convenience
6
+ export type {
7
+ QueuePluginDto,
8
+ QueueConfigurationDto,
9
+ UpdateQueueConfiguration,
10
+ } from "@checkmate-monitor/queue-common";
11
+
12
+ // QueueApiClient type inferred from the client definition
13
+ export type QueueApiClient = InferClient<typeof QueueApi>;
14
+
15
+ export const queueApiRef = createApiRef<QueueApiClient>("queue-api");
@@ -0,0 +1,27 @@
1
+ import React from "react";
2
+ import { Link } from "react-router-dom";
3
+ import { ListOrdered } from "lucide-react";
4
+ import { useApi, permissionApiRef } from "@checkmate-monitor/frontend-api";
5
+ import { DropdownMenuItem } from "@checkmate-monitor/ui";
6
+ import { resolveRoute } from "@checkmate-monitor/common";
7
+ import { queueRoutes } from "@checkmate-monitor/queue-common";
8
+
9
+ export const QueueUserMenuItems = () => {
10
+ const permissionApi = useApi(permissionApiRef);
11
+ const { allowed: canRead, loading } = permissionApi.useResourcePermission(
12
+ "queue",
13
+ "read"
14
+ );
15
+
16
+ if (loading || !canRead) {
17
+ return <React.Fragment />;
18
+ }
19
+
20
+ return (
21
+ <Link to={resolveRoute(queueRoutes.routes.config)}>
22
+ <DropdownMenuItem icon={<ListOrdered className="h-4 w-4" />}>
23
+ Queue Settings
24
+ </DropdownMenuItem>
25
+ </Link>
26
+ );
27
+ };
package/src/index.tsx ADDED
@@ -0,0 +1,44 @@
1
+ import {
2
+ rpcApiRef,
3
+ ApiRef,
4
+ UserMenuItemsSlot,
5
+ } from "@checkmate-monitor/frontend-api";
6
+ import { queueApiRef, type QueueApiClient } from "./api";
7
+ import { createFrontendPlugin } from "@checkmate-monitor/frontend-api";
8
+ import { QueueConfigPage } from "./pages/QueueConfigPage";
9
+ import { QueueUserMenuItems } from "./components/UserMenuItems";
10
+ import {
11
+ queueRoutes,
12
+ QueueApi,
13
+ pluginMetadata,
14
+ permissions,
15
+ } from "@checkmate-monitor/queue-common";
16
+
17
+ export const queuePlugin = createFrontendPlugin({
18
+ metadata: pluginMetadata,
19
+ apis: [
20
+ {
21
+ ref: queueApiRef,
22
+ factory: (deps: { get: <T>(ref: ApiRef<T>) => T }): QueueApiClient => {
23
+ const rpcApi = deps.get(rpcApiRef);
24
+ return rpcApi.forPlugin(QueueApi);
25
+ },
26
+ },
27
+ ],
28
+ routes: [
29
+ {
30
+ route: queueRoutes.routes.config,
31
+ element: <QueueConfigPage />,
32
+ permission: permissions.queueRead,
33
+ },
34
+ ],
35
+ extensions: [
36
+ {
37
+ id: "queue.user-menu.items",
38
+ slot: UserMenuItemsSlot,
39
+ component: QueueUserMenuItems,
40
+ },
41
+ ],
42
+ });
43
+
44
+ export * from "./api";
@@ -0,0 +1,126 @@
1
+ import { useEffect, useState } from "react";
2
+ import {
3
+ useApi,
4
+ wrapInSuspense,
5
+ permissionApiRef,
6
+ } from "@checkmate-monitor/frontend-api";
7
+ import { queueApiRef } from "../api";
8
+ import { QueuePluginDto } from "@checkmate-monitor/queue-common";
9
+ import {
10
+ Button,
11
+ Alert,
12
+ AlertTitle,
13
+ AlertDescription,
14
+ PageLayout,
15
+ PluginConfigForm,
16
+ Card,
17
+ CardContent,
18
+ CardFooter,
19
+ CardHeader,
20
+ CardTitle,
21
+ useToast,
22
+ } from "@checkmate-monitor/ui";
23
+ import { AlertTriangle, Save } from "lucide-react";
24
+
25
+ const QueueConfigPageContent = () => {
26
+ const api = useApi(queueApiRef);
27
+ const permissionApi = useApi(permissionApiRef);
28
+ const toast = useToast();
29
+ const { allowed: canRead, loading: permissionLoading } =
30
+ permissionApi.useResourcePermission("queue", "read");
31
+ const { allowed: canUpdate } = permissionApi.useManagePermission("queue");
32
+
33
+ const [plugins, setPlugins] = useState<QueuePluginDto[]>([]);
34
+ const [selectedPluginId, setSelectedPluginId] = useState<string>("");
35
+ const [config, setConfig] = useState<Record<string, unknown>>({});
36
+ const [isSaving, setIsSaving] = useState(false);
37
+
38
+ useEffect(() => {
39
+ const fetchData = async () => {
40
+ const [pluginsList, configuration] = await Promise.all([
41
+ api.getPlugins(),
42
+ api.getConfiguration(),
43
+ ]);
44
+ setPlugins(pluginsList);
45
+ setSelectedPluginId(configuration.pluginId);
46
+ setConfig(configuration.config);
47
+ };
48
+ fetchData();
49
+ }, [api]);
50
+
51
+ const handleSave = async () => {
52
+ if (!selectedPluginId) return;
53
+ setIsSaving(true);
54
+ try {
55
+ await api.updateConfiguration({
56
+ pluginId: selectedPluginId,
57
+ config,
58
+ });
59
+ toast.success("Configuration saved successfully!");
60
+ } catch (error) {
61
+ const message = error instanceof Error ? error.message : String(error);
62
+ toast.error(`Failed to save configuration: ${message}`);
63
+ } finally {
64
+ setIsSaving(false);
65
+ }
66
+ };
67
+
68
+ const isMemoryQueue = selectedPluginId === "memory";
69
+
70
+ return (
71
+ <PageLayout
72
+ title="Queue Settings"
73
+ subtitle="Configure the queue system for background jobs"
74
+ loading={permissionLoading}
75
+ allowed={canRead}
76
+ maxWidth="3xl"
77
+ >
78
+ <Card>
79
+ <CardHeader>
80
+ <CardTitle>Queue Configuration</CardTitle>
81
+ <p className="text-sm text-muted-foreground">
82
+ Select and configure the queue plugin
83
+ </p>
84
+ </CardHeader>
85
+ <CardContent className="space-y-6">
86
+ {isMemoryQueue && (
87
+ <Alert variant="warning">
88
+ <AlertTriangle className="h-5 w-5" />
89
+ <div>
90
+ <AlertTitle>In-Memory Queue Warning</AlertTitle>
91
+ <AlertDescription>
92
+ The in-memory queue is suitable for development and
93
+ single-instance deployments only. It will not scale across
94
+ multiple instances and jobs will be lost on restart. For
95
+ production environments with multiple instances, consider
96
+ using a persistent queue implementation.
97
+ </AlertDescription>
98
+ </div>
99
+ </Alert>
100
+ )}
101
+
102
+ <PluginConfigForm
103
+ label="Queue Plugin"
104
+ plugins={plugins}
105
+ selectedPluginId={selectedPluginId}
106
+ onPluginChange={(value) => {
107
+ setSelectedPluginId(value);
108
+ setConfig({});
109
+ }}
110
+ config={config}
111
+ onConfigChange={setConfig}
112
+ disabled={!canUpdate}
113
+ />
114
+ </CardContent>
115
+ <CardFooter className="flex justify-end gap-2">
116
+ <Button onClick={handleSave} disabled={!canUpdate || isSaving}>
117
+ <Save className="mr-2 h-4 w-4" />
118
+ {isSaving ? "Saving..." : "Save Configuration"}
119
+ </Button>
120
+ </CardFooter>
121
+ </Card>
122
+ </PageLayout>
123
+ );
124
+ };
125
+
126
+ export const QueueConfigPage = wrapInSuspense(QueueConfigPageContent);
package/tsconfig.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "@checkmate-monitor/tsconfig/frontend.json",
3
+ "include": [
4
+ "src"
5
+ ]
6
+ }