GitFOSS
feat(pipelines): add PipelineArtefactsView, PipelineDetailsView, PipelineStagesView, PipelineStageDetailsView
+ 414
- 6
@@ -1,5 +1,5 @@
 {
-  "_generatedAtUnix": 1778632838233,
+  "_generatedAtUnix": 1778671812667,
   "_hashAlgorithm": "sha1",
   "_version": 2,
   "assets": {

...
@@ -88,7 +88,7 @@
       "pathSourceMap": "./public/.islands/RepositoryPullRequestCreateForm.bundle.js.map"
     },
     "RepositoryTreeView": {
-      "hash": "0a66e97cc87e2e449fff4e938a4eb3a0e4d7589b",
+      "hash": "9249dae22bce3c13300917403c7a1da6035a130e",
       "pathSource": "./app/islands/RepositoryTreeView.tsx",
       "pathBundle": "./public/.islands/RepositoryTreeView.bundle.js",
       "pathSourceMap": "./public/.islands/RepositoryTreeView.bundle.js.map"

...
@@ -162,7 +162,7 @@
       "pathSource": "./app/views/repositoryPullRequests/RepositoryPullRequestDetailsView.tsx"
     },
     "RepositoryPullRequestsView": {
-      "hash": "d9764b3bbb660c5a2c9f09606970d4264e218ffc",
+      "hash": "c5d1055d3691fcdb65c23d03f5a712abcadff82a",
       "pathSource": "./app/views/repositoryPullRequests/RepositoryPullRequestsView.tsx"
     },
     "SettingsKeyAddView": {

...
@@ -178,7 +178,7 @@
       "pathSource": "./app/views/settings/SettingsKeysListView.tsx"
     },
     "SettingsView": {
-      "hash": "f532da9748b4ab68da3942ec6702e7d9d2989211",
+      "hash": "de9e5be8a62bb2b03a5372b5001c6c551e940ccf",
       "pathSource": "./app/views/settings/SettingsView.tsx"
     },
     "UserDashboardView": {

app/components/DrawerPrimary.tsx
@@ -10,7 +10,7 @@ import {
   type CommonViewProps,
   type WithThemeSchemeProp,
 } from "../types";
-import { useMediaQuery } from "../utils/hooks/useMediaQuery";
+// import { useMediaQuery } from "../utils/hooks/useMediaQuery";
 import { buildRouteLink } from "../utils/shared";
 import { AppRoute } from "../routes.defs";
 // app components

app/components/DrawerSettings.tsx
@@ -11,7 +11,7 @@ import {
   type WithThemeSchemeProp,
 } from "../types";
 import { buildRouteLink } from "../utils/shared";
-import { useMediaQuery } from "../utils/hooks/useMediaQuery";
+// import { useMediaQuery } from "../utils/hooks/useMediaQuery";
 import { AppRoute } from "../routes.defs";
 import { KeyIcon } from "./icons/KeyIcon";
 import { SupportIcon } from "./icons/SupportIcon";

app/controllers/index.ts
@@ -8,3 +8,11 @@ export { SSHAuthController } from "./ssh-auth";
 export { SyntaxHighlightController } from "./syntaxHighlight";
 export { ThemeController } from "./theme";
 export { UserController } from "./user";
+export { getPipelinesView } from "./pipelines/getPipelinesView";
+export { default as getPipelineArtefactsView } from "./pipelines/getPipelineArtefactsView";
+export { default as getPipelineDetailsView } from "./pipelines/getPipelineDetailsView";
+export { default as getPipelineStageDetailsView } from "./pipelines/getPipelineStageDetailsView";
+export { default as getPipelineStagesView } from "./pipelines/getPipelineStagesView";
+export { default as getPipelinesDetailsView } from "./repository/pipelines/getPipelinesView";
+export { default as postPipelineTriggerAction } from "./pipelines/postPipelineTriggerAction";
+export { default as getPipelineArtefactsView } from "./pipelines/getPipelineArtefactsView";

new file
app/controllers/pipelines/getPipelineArtefactsView.ts
@@ -0,0 +1,28 @@
+// 1st-party
+import type { ReqHandler } from "@ethicdevs/react-monolith";
+// app
+import { AppRoute, AppRouteParams } from "../../routes.defs";
+import { makePipelineService } from "../../services/pipelines";
+import PipelineArtefactsView, {
+  PipelineArtefactsViewProps,
+} from "../../views/pipelines/PipelineArtefactsView";
+
+const getPipelineArtefactsView: ReqHandler<
+  AppRouteParams,
+  AppRoute.REPOSITORY_PIPELINE_ARTEFACTS
+> = async (request, reply) => {
+  const { orgSlug, repoSlug, pipelineId } = request.params;
+  const pipelineService = makePipelineService({ request, runner: {} });
+  const artefacts = await pipelineService.getPipelineArtefacts(pipelineId);
+  const pipeline = await pipelineService.getPipeline(pipelineId);
+
+  const reqHandler = reply.makeRequestHandler(request, reply);
+  return reqHandler<PipelineArtefactsViewProps>(PipelineArtefactsView.name, {
+    artefacts,
+    pipeline,
+    orgSlug,
+    repoSlug,
+  });
+};
+
+export default getPipelineArtefactsView;

new file
app/controllers/pipelines/getPipelineDetailsView.ts
@@ -0,0 +1,27 @@
+// 1st-party
+import type { ReqHandler } from "@ethicdevs/react-monolith";
+// app
+import { AppRoute, AppRouteParams } from "../../routes.defs";
+import { makePipelineService } from "../../services/pipelines";
+import PipelineDetailsView, {
+  PipelineDetailsViewProps,
+} from "../../views/pipelines/PipelineDetailsView";
+
+const getPipelineDetailsView: ReqHandler<
+  AppRouteParams,
+  AppRoute.REPOSITORY_PIPELINE_DETAILS
+> = async (request, reply) => {
+  const { orgSlug, repoSlug, pipelineId } = request.params;
+
+  const pipelineService = makePipelineService({ request, runner: {} });
+  const pipeline = await pipelineService.getPipeline(pipelineId);
+
+  const reqHandler = reply.makeRequestHandler(request, reply);
+  return reqHandler<PipelineDetailsViewProps>(PipelineDetailsView.name, {
+    pipeline,
+    orgSlug,
+    repoSlug,
+  });
+};
+
+export default getPipelineDetailsView;

new file
app/controllers/pipelines/getPipelineStageDetailsView.ts
@@ -0,0 +1,38 @@
+// 1st-party
+import type { ReqHandler } from "@ethicdevs/react-monolith";
+// app
+import { AppRoute, AppRouteParams } from "../../routes.defs";
+import { makePipelineService } from "../../services/pipelines";
+import PipelineStageDetailsView, {
+  PipelineStageDetailsViewProps,
+} from "../../views/pipelines/PipelineStageDetailsView";
+
+const getPipelineStageDetailsView: ReqHandler<
+  AppRouteParams,
+  AppRoute.REPOSITORY_PIPELINE_STAGE_DETAILS
+> = async (request, reply) => {
+  const { orgSlug, repoSlug, pipelineId, stageId } = request.params;
+
+  const pipelineService = makePipelineService({ request, runner: {} });
+  const pipeline = await pipelineService.getPipeline(pipelineId);
+  const stages = await pipelineService.getPipelineStages(pipelineId);
+  const stage = stages.find((s) => String(s.id) === String(stageId)) ?? null;
+  const logs =
+    stage != null
+      ? await pipelineService.getPipelineStageLogs(pipelineId, String(stageId))
+      : [];
+
+  const reqHandler = reply.makeRequestHandler(request, reply);
+  return reqHandler<PipelineStageDetailsViewProps>(
+    PipelineStageDetailsView.name,
+    {
+      pipeline,
+      stage,
+      logs,
+      orgSlug,
+      repoSlug,
+    },
+  );
+};
+
+export default getPipelineStageDetailsView;

new file
app/controllers/pipelines/getPipelineStagesView.ts
@@ -0,0 +1,29 @@
+// 1st-party
+import type { ReqHandler } from "@ethicdevs/react-monolith";
+// app
+import { AppRoute, AppRouteParams } from "../../routes.defs";
+import { makePipelineService } from "../../services/pipelines";
+import PipelineStagesView, {
+  PipelineStagesViewProps,
+} from "../../views/pipelines/PipelineStagesView";
+
+const getPipelineStagesView: ReqHandler<
+  AppRouteParams,
+  AppRoute.REPOSITORY_PIPELINE_STAGES
+> = async (request, reply) => {
+  const { orgSlug, repoSlug, pipelineId } = request.params;
+
+  const pipelineService = makePipelineService({ request, runner: {} });
+  const pipeline = await pipelineService.getPipeline(pipelineId);
+  const stages = await pipelineService.getPipelineStages(pipelineId);
+
+  const reqHandler = reply.makeRequestHandler(request, reply);
+  return reqHandler<PipelineStagesViewProps>(PipelineStagesView.name, {
+    pipeline,
+    stages,
+    orgSlug,
+    repoSlug,
+  });
+};
+
+export default getPipelineStagesView;

new file
app/controllers/pipelines/getPipelinesView.ts
@@ -0,0 +1,27 @@
+// 1st-party
+import type { ReqHandler } from "@ethicdevs/react-monolith";
+// app
+import { AppRoute, AppRouteParams } from "../../routes.defs";
+import { makePipelineService } from "../../services/pipelines";
+import PipelinesView, {
+  PipelinesViewProps,
+} from "../../views/pipelines/PipelinesView";
+
+const getPipelinesView: ReqHandler<
+  AppRouteParams,
+  AppRoute.REPOSITORY_PIPELINES_LIST
+> = async (request, reply) => {
+  const { orgSlug, repoSlug } = request.params;
+
+  const pipelineService = makePipelineService({ request, runner: {} });
+  const pipelines = await pipelineService.listByRepo(orgSlug, repoSlug);
+
+  const reqHandler = reply.makeRequestHandler(request, reply);
+  return reqHandler<PipelinesViewProps>(PipelinesView.name, {
+    pipelines,
+    orgSlug,
+    repoSlug,
+  });
+};
+
+export default getPipelinesView;

new file
app/controllers/pipelines/index.ts
@@ -0,0 +1,15 @@
+import { default as getPipelinesView } from "./getPipelinesView";
+import { default as getPipelineArtefactsView } from "./getPipelineArtefactsView";
+import { default as getPipelineDetailsView } from "./getPipelineDetailsView";
+import { default as getPipelineStageDetailsView } from "./getPipelineStageDetailsView";
+import { default as getPipelineStagesView } from "./getPipelineStagesView";
+import { default as postPipelineTriggerAction } from "./postPipelineTriggerAction";
+
+export const PipelinesController = {
+  getPipelinesView,
+  getPipelineArtefactsView,
+  getPipelineDetailsView,
+  getPipelineStageDetailsView,
+  getPipelineStagesView,
+  postPipelineTriggerAction,
+};

new file
app/controllers/pipelines/postPipelineTriggerAction.ts
@@ -0,0 +1,31 @@
+// 1st-party
+import type { ReqHandler } from "@ethicdevs/react-monolith";
+// app
+import { AppRoute, AppRouteParams } from "../../routes.defs";
+import { makePipelineService } from "../../services/pipelines";
+import PipelineDetailsView, {
+  PipelineDetailsViewProps,
+} from "../../views/pipelines/PipelineDetailsView";
+
+const postPipelineTriggerAction: ReqHandler<
+  AppRouteParams,
+  AppRoute.REPOSITORY_PIPELINE_TRIGGER_ACTION
+> = async (request, reply) => {
+  const { orgSlug, repoSlug, pipelineId } = request.params;
+
+  const pipelineService = makePipelineService({ request, runner: {} });
+  const updatedPipeline = await pipelineService.triggerRunner(
+    orgSlug,
+    repoSlug,
+    pipelineId,
+  );
+
+  const reqHandler = reply.makeRequestHandler(request, reply);
+  return reqHandler<PipelineDetailsViewProps>(PipelineDetailsView.name, {
+    pipeline: updatedPipeline,
+    orgSlug,
+    repoSlug,
+  });
+};
+
+export default postPipelineTriggerAction;

new file
app/views/pipelines/PipelineArtefactsView.tsx
@@ -0,0 +1,46 @@
+// 1st-party
+import type { ReactView } from "@ethicdevs/react-monolith";
+// 3rd-party
+import React from "react";
+// generated via script[prisma:generate]
+import type { Artefact, Pipeline } from "@prisma/client";
+// app
+import type { CommonProps } from "../../types";
+// import { AppRoute } from "../../routes.defs";
+
+export interface PipelineArtefactsViewProps extends CommonProps {
+  artefacts: Artefact[];
+  pipeline: Pipeline;
+  orgSlug: string;
+  repoSlug: string;
+}
+
+const PipelineArtefactsView: ReactView<PipelineArtefactsViewProps> = ({
+  // commonProps,
+  artefacts,
+  pipeline,
+  // orgSlug,
+  // repoSlug,
+}) => {
+  return (
+    <div>
+      <h2>Artefacts for pipeline {pipeline.name ?? pipeline.id}</h2>
+      {artefacts.length === 0 ? (
+        <p>No artefacts found.</p>
+      ) : (
+        <ul>
+          {artefacts.map((artefact) => (
+            <li key={artefact.id}>
+              <span>{artefact.name ?? `Artefact ${artefact.id}`}</span>
+              {" - "}
+              <span>size: {artefact.size ?? ""}</span>
+            </li>
+          ))}
+        </ul>
+      )}
+    </div>
+  );
+};
+
+PipelineArtefactsView.displayName = "PipelineArtefactsView";
+export default PipelineArtefactsView;

new file
app/views/pipelines/PipelineDetailsView.tsx
@@ -0,0 +1,35 @@
+// 1st-party
+import type { ReactView } from "@ethicdevs/react-monolith";
+// 3rd-party
+import React from "react";
+// generated via script[prisma:generate]
+import type { Pipeline } from "@prisma/client";
+// app
+import type { CommonProps } from "../../types";
+import { Layout } from "../../components/Layout";
+import { PageWrapper } from "../../components/PageWrapper";
+
+export interface PipelineDetailsViewProps extends CommonProps {
+  pipeline: Pipeline;
+  orgSlug: string;
+  repoSlug: string;
+}
+
+const PipelineDetailsView: ReactView<PipelineDetailsViewProps> = ({
+  commonProps,
+  pipeline,
+  orgSlug,
+  repoSlug,
+}) => {
+  return (
+    <Layout {...commonProps} orgSlug={orgSlug} repoSlug={repoSlug}>
+      <PageWrapper>
+        <h2>Pipeline: {pipeline.name ?? pipeline.id}</h2>
+        <p>Status: {pipeline.status ?? "unknown"}</p>
+      </PageWrapper>
+    </Layout>
+  );
+};
+
+PipelineDetailsView.displayName = "PipelineDetailsView";
+export default PipelineDetailsView;

new file
app/views/pipelines/PipelineStageDetailsView.tsx
@@ -0,0 +1,39 @@
+// 1st-party
+import type { ReactView } from "@ethicdevs/react-monolith";
+// 3rd-party
+import React from "react";
+// generated via script[prisma:generate]
+import type { Pipeline, Stage } from "@prisma/client";
+// app
+import type { CommonProps } from "../../types";
+import { Layout } from "../../components/Layout";
+import { PageWrapper } from "../../components/PageWrapper";
+
+export interface PipelineStageDetailsViewProps extends CommonProps {
+  pipeline: Pipeline;
+  stage: Stage | null;
+  logs: Stage["logs"][];
+  orgSlug: string;
+  repoSlug: string;
+}
+
+const PipelineStageDetailsView: ReactView<PipelineStageDetailsViewProps> = ({
+  commonProps,
+  // pipeline,
+  stage,
+  logs,
+  orgSlug,
+  repoSlug,
+}) => {
+  return (
+    <Layout {...commonProps} orgSlug={orgSlug} repoSlug={repoSlug}>
+      <PageWrapper>
+        <h2>Stage: {stage?.name ?? stage?.id ?? "Unknown"}</h2>
+        <div>Logs: {logs?.length ?? 0}</div>
+      </PageWrapper>
+    </Layout>
+  );
+};
+
+PipelineStageDetailsView.displayName = "PipelineStageDetailsView";
+export default PipelineStageDetailsView;

new file
app/views/pipelines/PipelineStagesView.tsx
@@ -0,0 +1,43 @@
+// 1st-party
+import type { ReactView } from "@ethicdevs/react-monolith";
+// 3rd-party
+import React from "react";
+// generated via script[prisma:generate]
+import type { Pipeline, Stage } from "@prisma/client";
+// app
+import type { CommonProps } from "../../types";
+import { Layout } from "../../components/Layout";
+import { PageWrapper } from "../../components/PageWrapper";
+
+export interface PipelineStagesViewProps extends CommonProps {
+  pipeline: Pipeline;
+  stages: Stage[];
+  orgSlug: string;
+  repoSlug: string;
+}
+
+const PipelineStagesView: ReactView<PipelineStagesViewProps> = ({
+  commonProps,
+  pipeline,
+  stages,
+  orgSlug,
+  repoSlug,
+}) => {
+  return (
+    <Layout {...commonProps} orgSlug={orgSlug} repoSlug={repoSlug}>
+      <PageWrapper>
+        <h2>Stages for pipeline {pipeline.name ?? pipeline.id}</h2>
+        <ul>
+          {stages.map((s) => (
+            <li key={s.id}>
+              {s.name ?? s.id} - status: {s.status ?? "unknown"}
+            </li>
+          ))}
+        </ul>
+      </PageWrapper>
+    </Layout>
+  );
+};
+
+PipelineStagesView.displayName = "PipelineStagesView";
+export default PipelineStagesView;

new file
app/views/pipelines/PipelinesView.tsx
@@ -0,0 +1,42 @@
+// 1st-party
+import type { ReactView } from "@ethicdevs/react-monolith";
+// 3rd-party
+import React from "react";
+// generated via script[prisma:generate]
+import type { Pipeline } from "@prisma/client";
+// app
+import type { CommonProps } from "../../types";
+// import { AppRoute } from "../../routes.defs";
+
+export interface PipelinesViewProps extends CommonProps {
+  pipelines: Pipeline[];
+  orgSlug: string;
+  repoSlug: string;
+}
+
+const PipelinesView: ReactView<PipelinesViewProps> = ({
+  // commonProps,
+  pipelines,
+  orgSlug,
+  repoSlug,
+}) => {
+  return (
+    <div>
+      <h2>
+        Pipelines for {orgSlug}/{repoSlug}
+      </h2>
+      <ul>
+        {pipelines.map((p) => (
+          <li key={p.id}>
+            <span>
+              {p.name ?? `Pipeline ${p.id}`} — status: {p.status ?? "unknown"}
+            </span>
+          </li>
+        ))}
+      </ul>
+    </div>
+  );
+};
+
+PipelinesView.displayName = "PipelinesView";
+export default PipelinesView;