Penta 2 hete
szülő
commit
b026e92225

+ 5 - 1
charts/openshift-console-plugin/templates/consoleplugin.yaml

@@ -6,7 +6,7 @@ metadata:
     {{- include "openshift-console-plugin.labels" . | nindent 4 }}
 spec:
   displayName: {{ default (printf "%s Plugin" (include "openshift-console-plugin.name" .)) .Values.plugin.description }}
-  i18n: 
+  i18n:
     loadType: Preload
   backend:
     type: Service
@@ -15,3 +15,7 @@ spec:
       namespace: {{ .Release.Namespace }}
       port: {{ .Values.plugin.port }}
       basePath: {{ .Values.plugin.basePath }}
+{{ with .Values.plugin.proxies }}
+  proxy:
+{{ toYaml . | nindent 4 }}
+{{ end }}

+ 9 - 0
charts/openshift-console-plugin/values.yaml

@@ -1,5 +1,14 @@
 ---
 plugin:
+  proxies:
+    - alias: mpd-status
+      authorization: None
+      endpoint:
+        type: Service
+        service:
+          name: mpd-radio-dashboard
+          namespace: ampache
+          port: 9443
   name: ""
   description: ""
   image: ""

+ 6 - 0
src/components/DashboardPage.tsx

@@ -20,6 +20,8 @@ import {
 import type { FC } from 'react';
 import { useState } from 'react';
 
+import NowPlayingCard from './NowPlayingCard';
+
 const TUNED_NAMESPACE = 'openshift-cluster-node-tuning-operator';
 const TUNED_NAME = 'custom-tuned-profile';
 
@@ -178,6 +180,10 @@ const DashboardPage: FC = () => {
           </CardBody>
         </Card>
       </PageSection>
+
+      <PageSection>
+        <NowPlayingCard />
+      </PageSection>
     </>
   );
 };

+ 140 - 0
src/components/NowPlayingCard.tsx

@@ -0,0 +1,140 @@
+import { consoleFetchJSON } from '@openshift-console/dynamic-plugin-sdk';
+
+import {
+  Alert,
+  Card,
+  CardBody,
+  CardTitle,
+  Spinner,
+} from '@patternfly/react-core';
+
+import type { FC } from 'react';
+import { useEffect, useState } from 'react';
+
+interface Song {
+  display: string;
+  artist: string | null;
+  title: string | null;
+  file: string | null;
+}
+
+interface MPDStatus {
+  available: boolean;
+  current: Song | null;
+  previous: Song[];
+  error: string | null;
+  updatedAt: string | null;
+}
+
+const STATUS_URL =
+  '/api/proxy/plugin/homelab-dashboard/mpd-status/api/status';
+
+const NowPlayingCard: FC = () => {
+  const [status, setStatus] = useState<MPDStatus>();
+  const [fetchError, setFetchError] = useState(false);
+
+  useEffect(() => {
+    let stopped = false;
+    let timer: number | undefined;
+
+    const poll = async () => {
+      try {
+        const result = (await consoleFetchJSON(
+          STATUS_URL,
+          'GET',
+          {},
+          1000,
+        )) as MPDStatus;
+
+        if (!stopped) {
+          setStatus(result);
+          setFetchError(false);
+        }
+      } catch {
+        if (!stopped) {
+          setFetchError(true);
+        }
+      } finally {
+        if (!stopped) {
+          timer = window.setTimeout(poll, 1000);
+        }
+      }
+    };
+
+    void poll();
+
+    return () => {
+      stopped = true;
+
+      if (timer !== undefined) {
+        window.clearTimeout(timer);
+      }
+    };
+  }, []);
+
+  return (
+    <Card>
+      <CardTitle>MPD Radio</CardTitle>
+
+      <CardBody>
+        {!status && !fetchError ? (
+          <Spinner size="md" />
+        ) : fetchError ? (
+          <Alert
+            isInline
+            variant="danger"
+            title="MPD status unavailable"
+          >
+            The MPD status service did not respond within one second.
+          </Alert>
+        ) : (
+          <>
+            {!status?.available && (
+              <Alert
+                isInline
+                variant="warning"
+                title="MPD unavailable"
+              >
+                {status?.error ?? 'Unable to contact MPD.'}
+              </Alert>
+            )}
+
+            {status?.available ? (
+              <p>
+                Current song:{' '}
+                <strong>
+                  {status.current?.display ?? 'Nothing playing'}
+                </strong>
+              </p>
+            ) : status?.current ? (
+              <p>
+                Last known song:{' '}
+                <strong>{status.current.display}</strong>
+              </p>
+            ) : null}
+
+            {status?.previous && status.previous.length > 0 && (
+              <>
+                <br />
+
+                <p>
+                  <strong>Previous:</strong>
+                </p>
+
+                <ul>
+                  {status.previous.map((song, index) => (
+                    <li key={`${song.display}-${index}`}>
+                      {song.display}
+                    </li>
+                  ))}
+                </ul>
+              </>
+            )}
+          </>
+        )}
+      </CardBody>
+    </Card>
+  );
+};
+
+export default NowPlayingCard;