From 15cd6907dc0c68dc5bc353a88f4456183498382f Mon Sep 17 00:00:00 2001 From: hillaliy Date: Tue, 21 Jan 2025 17:03:02 +0200 Subject: [PATCH 1/4] feat: add bookmarks options (apps) --- packages/translation/src/lang/en.json | 9 ++ packages/widgets/src/bookmarks/component.tsx | 133 +++++++++++++------ packages/widgets/src/bookmarks/index.tsx | 3 + 3 files changed, 104 insertions(+), 41 deletions(-) diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index 04f487041..242a5d8d5 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -1067,6 +1067,15 @@ } } }, + "showIcon": { + "label": "Show icons" + }, + "showUrl": { + "label": "Show URLs" + }, + "openInNewTab": { + "label": "Open in new tab" + }, "items": { "label": "Bookmarks", "add": "Add bookmark" diff --git a/packages/widgets/src/bookmarks/component.tsx b/packages/widgets/src/bookmarks/component.tsx index b4383fb42..ec4de5319 100644 --- a/packages/widgets/src/bookmarks/component.tsx +++ b/packages/widgets/src/bookmarks/component.tsx @@ -42,8 +42,25 @@ export default function BookmarksWidget({ options, width, height, itemId }: Widg {options.title} - {options.layout === "grid" && } - {options.layout !== "grid" && } + {options.layout === "grid" && ( + + )} + {options.layout !== "grid" && ( + + )} ); } @@ -51,9 +68,12 @@ export default function BookmarksWidget({ options, width, height, itemId }: Widg interface FlexLayoutProps { data: RouterOutputs["app"]["byIds"]; direction: "row" | "column"; + showIcon: boolean; + showUrl: boolean; + openInNewTab: boolean; } -const FlexLayout = ({ data, direction }: FlexLayoutProps) => { +const FlexLayout = ({ data, direction, showIcon, showUrl, openInNewTab }: FlexLayoutProps) => { return ( {data.map((app, index) => ( @@ -66,7 +86,7 @@ const FlexLayout = ({ data, direction }: FlexLayoutProps) => { { display="flex" p={0} > - {direction === "row" ? : } + {direction === "row" ? ( + + ) : ( + + )} @@ -94,9 +118,12 @@ interface GridLayoutProps { data: RouterOutputs["app"]["byIds"]; width: number; height: number; + showIcon: boolean; + showUrl: boolean; + openInNewTab: boolean; } -const GridLayout = ({ data, width, height }: GridLayoutProps) => { +const GridLayout = ({ data, width, height, showIcon, showUrl, openInNewTab }: GridLayoutProps) => { // Calculates the perfect number of columns for the grid layout based on the width and height in pixels and the number of items const columns = Math.ceil(Math.sqrt(data.length * (width / height))); @@ -113,13 +140,13 @@ const GridLayout = ({ data, width, height }: GridLayoutProps) => { - + ))} @@ -127,55 +154,79 @@ const GridLayout = ({ data, width, height }: GridLayoutProps) => { ); }; -const VerticalItem = ({ app }: { app: RouterOutputs["app"]["byIds"][number] }) => { +const VerticalItem = ({ + app, + showIcon, + showUrl, +}: { + app: RouterOutputs["app"]["byIds"][number]; + showIcon: boolean; + showUrl: boolean; +}) => { return ( {app.name} - {app.name} - - {app.href ? new URL(app.href).hostname : undefined} - + {showIcon && ( + {app.name} + )} + {showUrl && ( + + {app.href ? new URL(app.href).hostname : undefined} + + )} ); }; -const HorizontalItem = ({ app }: { app: RouterOutputs["app"]["byIds"][number] }) => { +const HorizontalItem = ({ + app, + showIcon, + showUrl, +}: { + app: RouterOutputs["app"]["byIds"][number]; + showIcon: boolean; + showUrl: boolean; +}) => { return ( - {app.name} + {showIcon && ( + {app.name} + )} {app.name} - - {app.href ? new URL(app.href).hostname : undefined} - + {showUrl && ( + + {app.href ? new URL(app.href).hostname : undefined} + + )} ); diff --git a/packages/widgets/src/bookmarks/index.tsx b/packages/widgets/src/bookmarks/index.tsx index dccd16e3d..4be9df9ad 100644 --- a/packages/widgets/src/bookmarks/index.tsx +++ b/packages/widgets/src/bookmarks/index.tsx @@ -19,6 +19,9 @@ export const { definition, componentLoader } = createWidgetDefinition("bookmarks })), defaultValue: "column", }), + showIcon: factory.switch({ defaultValue: true }), + showUrl: factory.switch({ defaultValue: true }), + openInNewTab: factory.switch({ defaultValue: true }), items: factory.sortableItemList({ ItemComponent: ({ item, handle: Handle, removeItem, rootAttributes }) => { return ( From 29dc13b203612ca9b19dcf5c08e27900016cb932 Mon Sep 17 00:00:00 2001 From: hillaliy Date: Tue, 21 Jan 2025 17:09:54 +0200 Subject: [PATCH 2/4] fix: deep source error --- packages/widgets/src/bookmarks/component.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/widgets/src/bookmarks/component.tsx b/packages/widgets/src/bookmarks/component.tsx index ec4de5319..fe0a00ea9 100644 --- a/packages/widgets/src/bookmarks/component.tsx +++ b/packages/widgets/src/bookmarks/component.tsx @@ -1,6 +1,6 @@ "use client"; -import { Anchor, Box, Card, Divider, Flex, Group, Stack, Text, Title, UnstyledButton } from "@mantine/core"; +import { Anchor, Box, Card, Divider, Flex, Group, Image, Stack, Text, Title, UnstyledButton } from "@mantine/core"; import type { RouterOutputs } from "@homarr/api"; import { clientApi } from "@homarr/api/client"; @@ -169,7 +169,7 @@ const VerticalItem = ({ {app.name} {showIcon && ( - {showIcon && ( - Date: Tue, 21 Jan 2025 17:40:31 +0200 Subject: [PATCH 3/4] fix: typecheck (old options) --- packages/old-import/src/widgets/options.ts | 5 +- packages/translation/src/lang/en.json | 12 ++-- packages/widgets/src/bookmarks/component.tsx | 62 ++++++++++---------- packages/widgets/src/bookmarks/index.tsx | 6 +- 4 files changed, 44 insertions(+), 41 deletions(-) diff --git a/packages/old-import/src/widgets/options.ts b/packages/old-import/src/widgets/options.ts index 6c9b44d7c..e9082565f 100644 --- a/packages/old-import/src/widgets/options.ts +++ b/packages/old-import/src/widgets/options.ts @@ -2,8 +2,8 @@ import { objectEntries } from "@homarr/common"; import { logger } from "@homarr/log"; import type { WidgetComponentProps } from "../../../widgets/src/definition"; -import { mapKind } from "./definitions"; import type { InversedWidgetMapping, OldmarrWidgetDefinitions, WidgetMapping } from "./definitions"; +import { mapKind } from "./definitions"; // This type enforces, that for all widget mappings there is a corresponding option mapping, // each option of newmarr can be mapped from the value of the oldmarr options @@ -38,6 +38,9 @@ const optionMapping: OptionMapping = { return mappedLayouts[oldOptions.layout]; }, + hideIcon: (oldOptions) => oldOptions.items.some((item) => item.hideIcon), + hideHostname: (oldOptions) => oldOptions.items.some((item) => item.hideHostname), + openNewTab: (oldOptions) => oldOptions.items.some((item) => item.openNewTab), }, calendar: { releaseType: (oldOptions) => [oldOptions.radarrReleaseType], diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index 242a5d8d5..eeb350476 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -1067,14 +1067,14 @@ } } }, - "showIcon": { - "label": "Show icons" + "hideIcon": { + "label": "Hide icons" }, - "showUrl": { - "label": "Show URLs" + "hideHostname": { + "label": "Hide hostname" }, - "openInNewTab": { - "label": "Open in new tab" + "openNewTab": { + "label": "Open new tab" }, "items": { "label": "Bookmarks", diff --git a/packages/widgets/src/bookmarks/component.tsx b/packages/widgets/src/bookmarks/component.tsx index fe0a00ea9..721965f21 100644 --- a/packages/widgets/src/bookmarks/component.tsx +++ b/packages/widgets/src/bookmarks/component.tsx @@ -47,18 +47,18 @@ export default function BookmarksWidget({ options, width, height, itemId }: Widg data={data} width={width} height={height} - showIcon={options.showIcon} - showUrl={options.showUrl} - openInNewTab={options.openInNewTab} + hideIcon={options.hideIcon} + hideHostname={options.hideHostname} + openNewTab={options.openNewTab} /> )} {options.layout !== "grid" && ( )} @@ -68,12 +68,12 @@ export default function BookmarksWidget({ options, width, height, itemId }: Widg interface FlexLayoutProps { data: RouterOutputs["app"]["byIds"]; direction: "row" | "column"; - showIcon: boolean; - showUrl: boolean; - openInNewTab: boolean; + hideIcon: boolean; + hideHostname: boolean; + openNewTab: boolean; } -const FlexLayout = ({ data, direction, showIcon, showUrl, openInNewTab }: FlexLayoutProps) => { +const FlexLayout = ({ data, direction, hideIcon, hideHostname, openNewTab }: FlexLayoutProps) => { return ( {data.map((app, index) => ( @@ -86,7 +86,7 @@ const FlexLayout = ({ data, direction, showIcon, showUrl, openInNewTab }: FlexLa {direction === "row" ? ( - + ) : ( - + )} @@ -118,12 +118,12 @@ interface GridLayoutProps { data: RouterOutputs["app"]["byIds"]; width: number; height: number; - showIcon: boolean; - showUrl: boolean; - openInNewTab: boolean; + hideIcon: boolean; + hideHostname: boolean; + openNewTab: boolean; } -const GridLayout = ({ data, width, height, showIcon, showUrl, openInNewTab }: GridLayoutProps) => { +const GridLayout = ({ data, width, height, hideIcon, hideHostname, openNewTab }: GridLayoutProps) => { // Calculates the perfect number of columns for the grid layout based on the width and height in pixels and the number of items const columns = Math.ceil(Math.sqrt(data.length * (width / height))); @@ -140,13 +140,13 @@ const GridLayout = ({ data, width, height, showIcon, showUrl, openInNewTab }: Gr - + ))} @@ -156,19 +156,19 @@ const GridLayout = ({ data, width, height, showIcon, showUrl, openInNewTab }: Gr const VerticalItem = ({ app, - showIcon, - showUrl, + hideIcon, + hideHostname, }: { app: RouterOutputs["app"]["byIds"][number]; - showIcon: boolean; - showUrl: boolean; + hideIcon: boolean; + hideHostname: boolean; }) => { return ( {app.name} - {showIcon && ( + {!hideIcon && ( {app.name} )} - {showUrl && ( + {!hideHostname && ( {app.href ? new URL(app.href).hostname : undefined} @@ -193,16 +193,16 @@ const VerticalItem = ({ const HorizontalItem = ({ app, - showIcon, - showUrl, + hideIcon, + hideHostname, }: { app: RouterOutputs["app"]["byIds"][number]; - showIcon: boolean; - showUrl: boolean; + hideIcon: boolean; + hideHostname: boolean; }) => { return ( - {showIcon && ( + {!hideIcon && ( - {showUrl && ( + {!hideHostname && ( {app.href ? new URL(app.href).hostname : undefined} diff --git a/packages/widgets/src/bookmarks/index.tsx b/packages/widgets/src/bookmarks/index.tsx index 4be9df9ad..959a8601d 100644 --- a/packages/widgets/src/bookmarks/index.tsx +++ b/packages/widgets/src/bookmarks/index.tsx @@ -19,9 +19,9 @@ export const { definition, componentLoader } = createWidgetDefinition("bookmarks })), defaultValue: "column", }), - showIcon: factory.switch({ defaultValue: true }), - showUrl: factory.switch({ defaultValue: true }), - openInNewTab: factory.switch({ defaultValue: true }), + hideIcon: factory.switch({ defaultValue: false }), + hideHostname: factory.switch({ defaultValue: false }), + openNewTab: factory.switch({ defaultValue: true }), items: factory.sortableItemList({ ItemComponent: ({ item, handle: Handle, removeItem, rootAttributes }) => { return ( From 70c836d3f38c076400509d9f8f47a84c3127adcb Mon Sep 17 00:00:00 2001 From: hillaliy Date: Thu, 23 Jan 2025 06:39:24 +0200 Subject: [PATCH 4/4] fix: translation --- packages/translation/src/lang/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index eeb350476..86596a08e 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -1071,10 +1071,10 @@ "label": "Hide icons" }, "hideHostname": { - "label": "Hide hostname" + "label": "Hide hostnames" }, "openNewTab": { - "label": "Open new tab" + "label": "Open in new tab" }, "items": { "label": "Bookmarks",