chore: reconcile mobile layer after stack rebase
This commit is contained in:
1 parent
4a4b04d471
commit
eb918b805a
55 files changed
+1558
-598
No files matched your search
@@ -1831,47 +1831,6 @@ describe("saveLayouts should save layout changes", () => {
|
||||
expect(basePosition).toMatchObject({ xOffset: 0, yOffset: 1, width: 4, height: 1, sectionId });
|
||||
expect(customPosition).toMatchObject({ xOffset: 0, yOffset: 1, width: 4, height: 1, sectionId });
|
||||
});
|
||||
test("should project a new custom layout from the resized Base layout", async () => {
|
||||
const db = createDb();
|
||||
const caller = boardRouter.createCaller({ db, deviceType: undefined, session: defaultSession });
|
||||
const { boardId, layoutId, sectionId, itemId } = await createFullBoardAsync(db, "default");
|
||||
const mobileLayoutId = await addMobileLayoutAsync(db, boardId);
|
||||
const secondItemId = createId();
|
||||
|
||||
await db.update(itemLayouts).set({ width: 4, xOffset: 0 }).where(eq(itemLayouts.itemId, itemId));
|
||||
await db.insert(items).values({
|
||||
id: secondItemId,
|
||||
kind: "clock",
|
||||
boardId,
|
||||
options: SuperJSON.stringify({ is24HourFormat: true }),
|
||||
});
|
||||
await db.insert(itemLayouts).values({
|
||||
itemId: secondItemId,
|
||||
layoutId,
|
||||
sectionId,
|
||||
width: 4,
|
||||
height: 1,
|
||||
xOffset: 6,
|
||||
yOffset: 0,
|
||||
});
|
||||
|
||||
const resizedBase = { ...createExistingLayout(layoutId), columnCount: 6 };
|
||||
const savedLayouts = await caller.saveLayouts({
|
||||
id: boardId,
|
||||
layouts: [createMobileLayout(mobileLayoutId), createNewLayout(8), resizedBase],
|
||||
});
|
||||
const customLayoutId = expectToBeDefined(savedLayouts.find((layout) => layout.role === "custom")).id;
|
||||
|
||||
const basePosition = await db.query.itemLayouts.findFirst({
|
||||
where: and(eq(itemLayouts.itemId, secondItemId), eq(itemLayouts.layoutId, layoutId)),
|
||||
});
|
||||
const customPosition = await db.query.itemLayouts.findFirst({
|
||||
where: and(eq(itemLayouts.itemId, secondItemId), eq(itemLayouts.layoutId, customLayoutId)),
|
||||
});
|
||||
|
||||
expect(basePosition).toMatchObject({ xOffset: 0, yOffset: 1, width: 4, height: 1, sectionId });
|
||||
expect(customPosition).toMatchObject({ xOffset: 0, yOffset: 1, width: 4, height: 1, sectionId });
|
||||
});
|
||||
test("should remove layout when not present in input", async () => {
|
||||
// Arrange
|
||||
const db = createDb();
|
||||
|
||||
@@ -1,17 +1,47 @@
|
||||
import { z } from "zod/v4";
|
||||
|
||||
import type { IntegrationKindByCategory } from "@homarr/definitions";
|
||||
import { getIntegrationKindsByCategory } from "@homarr/definitions";
|
||||
import type { DownloadClientJobsAndStatus } from "@homarr/integrations";
|
||||
import { createIntegrationAsync, downloadClientItemSchema } from "@homarr/integrations";
|
||||
import { downloadClientRequestHandler } from "@homarr/request-handler/downloads";
|
||||
|
||||
import type { IntegrationAction } from "../../middlewares/integration";
|
||||
import { createManyIntegrationMiddleware } from "../../middlewares/integration";
|
||||
import { settleIntegrationQueries } from "../../settle-integrations";
|
||||
import { PUBLIC_INTEGRATION_ERROR, settleIntegrationQueries } from "../../settle-integrations";
|
||||
import { createTRPCRouter, protectedProcedure, publicProcedure } from "../../trpc";
|
||||
|
||||
const createDownloadClientIntegrationMiddleware = (action: IntegrationAction) =>
|
||||
createManyIntegrationMiddleware(action, ...getIntegrationKindsByCategory("downloadClient"));
|
||||
|
||||
interface DownloadClientQueryResultBase {
|
||||
integrationId: string;
|
||||
integrationName: string;
|
||||
}
|
||||
|
||||
type DownloadClientQueryResult = DownloadClientQueryResultBase &
|
||||
(
|
||||
| {
|
||||
integration: {
|
||||
id: string;
|
||||
name: string;
|
||||
kind: IntegrationKindByCategory<"downloadClient">;
|
||||
updatedAt: Date;
|
||||
};
|
||||
data: DownloadClientJobsAndStatus;
|
||||
error?: never;
|
||||
}
|
||||
| {
|
||||
integration: {
|
||||
id: string;
|
||||
name: string;
|
||||
kind: IntegrationKindByCategory<"downloadClient">;
|
||||
};
|
||||
data: null;
|
||||
error: string;
|
||||
}
|
||||
);
|
||||
|
||||
export const downloadsRouter = createTRPCRouter({
|
||||
getJobsAndStatuses: publicProcedure
|
||||
.meta({
|
||||
@@ -24,14 +54,29 @@ export const downloadsRouter = createTRPCRouter({
|
||||
.concat(createDownloadClientIntegrationMiddleware("query"))
|
||||
.input(z.object({ limitPerIntegration: z.number().default(50) }))
|
||||
.query(async ({ ctx, input }) => {
|
||||
return await settleIntegrationQueries(ctx.integrations, async (integration) => {
|
||||
const innerHandler = downloadClientRequestHandler.handler(integration, { limit: input.limitPerIntegration });
|
||||
const { data, timestamp } = await innerHandler.getDataAsync();
|
||||
return {
|
||||
integration: { id: integration.id, name: integration.name, kind: integration.kind, updatedAt: timestamp },
|
||||
data,
|
||||
};
|
||||
});
|
||||
return await settleIntegrationQueries<(typeof ctx.integrations)[number], DownloadClientQueryResult>(
|
||||
ctx.integrations,
|
||||
async (integration) => {
|
||||
const innerHandler = downloadClientRequestHandler.handler(integration, { limit: input.limitPerIntegration });
|
||||
const { data, timestamp } = await innerHandler.getDataAsync();
|
||||
return {
|
||||
integrationId: integration.id,
|
||||
integrationName: integration.name,
|
||||
integration: { id: integration.id, name: integration.name, kind: integration.kind, updatedAt: timestamp },
|
||||
data,
|
||||
};
|
||||
},
|
||||
{
|
||||
fallback: (integration) => ({
|
||||
integrationId: integration.id,
|
||||
integrationName: integration.name,
|
||||
integration: { id: integration.id, name: integration.name, kind: integration.kind },
|
||||
data: null,
|
||||
error: PUBLIC_INTEGRATION_ERROR,
|
||||
}),
|
||||
throwOnAllFailures: true,
|
||||
},
|
||||
);
|
||||
}),
|
||||
pause: protectedProcedure
|
||||
.meta({
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { createIntegrationAsync } from "@homarr/integrations";
|
||||
import type { SystemHealthMonitoring } from "@homarr/integrations";
|
||||
import { SynologyIntegration } from "@homarr/integrations";
|
||||
import { clusterInfoRequestHandler, systemInfoRequestHandler } from "@homarr/request-handler/health-monitoring";
|
||||
|
||||
import { createManyIntegrationMiddleware, createOneIntegrationMiddleware } from "../../middlewares/integration";
|
||||
import { settleIntegrationQueries } from "../../settle-integrations";
|
||||
import { PUBLIC_INTEGRATION_ERROR, settleIntegrationQueries } from "../../settle-integrations";
|
||||
import { createTRPCRouter, publicProcedure } from "../../trpc";
|
||||
|
||||
const healthMonitoringIntegrationKinds = [
|
||||
@@ -16,6 +17,14 @@ const healthMonitoringIntegrationKinds = [
|
||||
"mock",
|
||||
] as const;
|
||||
|
||||
interface SystemHealthQueryResult {
|
||||
integrationId: string;
|
||||
integrationName: string;
|
||||
healthInfo: SystemHealthMonitoring | null;
|
||||
updatedAt?: Date;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export const healthMonitoringRouter = createTRPCRouter({
|
||||
getSystemHealthStatus: publicProcedure
|
||||
.meta({
|
||||
@@ -27,15 +36,27 @@ export const healthMonitoringRouter = createTRPCRouter({
|
||||
})
|
||||
.concat(createManyIntegrationMiddleware("query", ...healthMonitoringIntegrationKinds))
|
||||
.query(async ({ ctx }) => {
|
||||
return await settleIntegrationQueries(ctx.integrations, async (integration) => {
|
||||
const { data, timestamp } = await systemInfoRequestHandler.handler(integration, {}).getDataAsync();
|
||||
return {
|
||||
integrationId: integration.id,
|
||||
integrationName: integration.name,
|
||||
healthInfo: data,
|
||||
updatedAt: timestamp,
|
||||
};
|
||||
});
|
||||
return await settleIntegrationQueries<(typeof ctx.integrations)[number], SystemHealthQueryResult>(
|
||||
ctx.integrations,
|
||||
async (integration) => {
|
||||
const { data, timestamp } = await systemInfoRequestHandler.handler(integration, {}).getDataAsync();
|
||||
return {
|
||||
integrationId: integration.id,
|
||||
integrationName: integration.name,
|
||||
healthInfo: data,
|
||||
updatedAt: timestamp,
|
||||
};
|
||||
},
|
||||
{
|
||||
fallback: (integration) => ({
|
||||
integrationId: integration.id,
|
||||
integrationName: integration.name,
|
||||
healthInfo: null,
|
||||
error: PUBLIC_INTEGRATION_ERROR,
|
||||
}),
|
||||
throwOnAllFailures: true,
|
||||
},
|
||||
);
|
||||
}),
|
||||
listStorageVolumes: publicProcedure
|
||||
.meta({
|
||||
|
||||
@@ -2,32 +2,21 @@ import { getIntegrationKindsByCategory } from "@homarr/definitions";
|
||||
import { mediaReleaseRequestHandler } from "@homarr/request-handler/media-release";
|
||||
|
||||
import { createManyIntegrationMiddleware } from "../../middlewares/integration";
|
||||
import { settleIntegrationQueries } from "../../settle-integrations";
|
||||
import { createTRPCRouter, publicProcedure } from "../../trpc";
|
||||
import { getMediaReleaseResponse } from "./media-release-result";
|
||||
|
||||
export const mediaReleaseRouter = createTRPCRouter({
|
||||
getMediaReleases: publicProcedure
|
||||
.concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("mediaRelease")))
|
||||
.query(async ({ ctx }) => {
|
||||
const results = await settleIntegrationQueries(ctx.integrations, async (integration) => {
|
||||
return await getMediaReleaseResponse(ctx.integrations, async (integration) => {
|
||||
const innerHandler = mediaReleaseRequestHandler.handler(integration, {});
|
||||
const { data, timestamp } = await innerHandler.getDataAsync();
|
||||
|
||||
return {
|
||||
integration: {
|
||||
id: integration.id,
|
||||
name: integration.name,
|
||||
kind: integration.kind,
|
||||
updatedAt: timestamp,
|
||||
},
|
||||
releases: data,
|
||||
updatedAt: timestamp,
|
||||
};
|
||||
});
|
||||
return results.flatMap((result) =>
|
||||
result.releases.map((release) => ({
|
||||
...release,
|
||||
integration: result.integration,
|
||||
})),
|
||||
);
|
||||
}),
|
||||
});
|
||||
@@ -1,24 +1,39 @@
|
||||
import { uptimeKumaRequestHandler } from "@homarr/request-handler/uptime-kuma";
|
||||
|
||||
import { createManyIntegrationMiddleware } from "../../middlewares/integration";
|
||||
import { settleIntegrationQueries } from "../../settle-integrations";
|
||||
import { settleIntegrationQueries, toPublicIntegrationError } from "../../settle-integrations";
|
||||
import { createTRPCRouter, publicProcedure } from "../../trpc";
|
||||
|
||||
export const uptimeKumaRouter = createTRPCRouter({
|
||||
getDashboard: publicProcedure
|
||||
.concat(createManyIntegrationMiddleware("query", "uptimeKuma"))
|
||||
.query(async ({ ctx }) => {
|
||||
return await settleIntegrationQueries(ctx.integrations, async (integration) => {
|
||||
const innerHandler = uptimeKumaRequestHandler.handler(integration, {});
|
||||
const { data, timestamp } = await innerHandler.getDataAsync();
|
||||
return await settleIntegrationQueries(
|
||||
ctx.integrations,
|
||||
async (integration) => {
|
||||
const innerHandler = uptimeKumaRequestHandler.handler(integration, {});
|
||||
const { data, timestamp } = await innerHandler.getDataAsync();
|
||||
|
||||
return {
|
||||
integrationId: integration.id,
|
||||
integrationName: integration.name,
|
||||
integrationUrl: integration.url,
|
||||
dashboard: data,
|
||||
updatedAt: timestamp,
|
||||
};
|
||||
});
|
||||
return {
|
||||
integrationId: integration.id,
|
||||
integrationName: integration.name,
|
||||
integrationUrl: integration.url,
|
||||
dashboard: data as typeof data | null,
|
||||
updatedAt: timestamp,
|
||||
error: undefined as string | undefined,
|
||||
};
|
||||
},
|
||||
{
|
||||
fallback: (integration, error) => ({
|
||||
integrationId: integration.id,
|
||||
integrationName: integration.name,
|
||||
integrationUrl: integration.url,
|
||||
dashboard: null,
|
||||
updatedAt: new Date(0),
|
||||
error: toPublicIntegrationError(error),
|
||||
}),
|
||||
throwOnAllFailures: true,
|
||||
},
|
||||
);
|
||||
}),
|
||||
});
|
||||
Reference in new issue
Block a user