From b60385a6677251f2d9d3ce5c2778edc1fff38bc8 Mon Sep 17 00:00:00 2001 From: KamilKranczuk Date: Wed, 9 Aug 2023 12:42:59 +0200 Subject: [PATCH 01/11] Redesign Content Usage row. Separate ContentTypeUsages table components --- .../ContentTypeUsageTable.tsx | 94 +++++++ .../ContentTypeUsageTableRow.tsx | 46 ++++ .../Tables/PageUrlCell/PageUrlCell.tsx | 19 ++ .../PageUrlCell/PageUrlLink/PageUrlLink.tsx | 12 + .../Frontend/Views/ContentTypeUsageView.scss | 18 +- .../Frontend/Views/ContentTypeUsageView.tsx | 257 ++---------------- .../Frontend/types.ts | 1 + 7 files changed, 212 insertions(+), 235 deletions(-) create mode 100644 src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx create mode 100644 src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx create mode 100644 src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlCell.tsx create mode 100644 src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlLink/PageUrlLink.tsx diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx new file mode 100644 index 0000000..eadd05f --- /dev/null +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx @@ -0,0 +1,94 @@ +import { Table } from "optimizely-oui"; +import React, { useCallback } from "react"; +import { translations } from "../../../translations"; +import { ContentUsageDto } from "../../../dtos"; +import { TableColumn } from "../../../types"; +import ContentTypeUsageTableRow from "./ContentTypeUsageTableRow/ContentTypeUsageTableRow"; +import { navigateTo } from "../../../routes"; + +enum ContentTypeUsageTableColumn { + ID = "id", + Name = "name", + LanguageBranch = "languageBranch", + PageUrl = "pageUrl", + Actions = "actions", +} + +interface ContentTypeUsagesTableProps { + tableColumns: TableColumn[]; + rows: ContentUsageDto[]; + onSortChange: (column: TableColumn) => void; + sortDirection: string; +} + +const ContentTypeUsagesTable = ({ + tableColumns, + rows, + onSortChange, + sortDirection, +}: ContentTypeUsagesTableProps) => { + const onTableRowClick = useCallback( + (url?: string | null, alwaysTriggerClick = false) => + (event: React.PointerEvent) => { + if (!url) return; + + const target = event.target as HTMLTableCellElement | undefined; + + if ((target && target.tagName === "TD") || alwaysTriggerClick) { + navigateTo(url); + } + }, + [navigateTo] + ); + + return ( + + + + {tableColumns + .filter((column) => column.visible) + .map((column) => ( + <> + onSortChange(column), + order: sortDirection, + }} + key={column.id} + > + {column.name} + + + ))} + + + + + {rows.length > 0 ? ( + rows.map( + (row) => ( + + ) + ) + ) : ( + + {translations.noResults} + + )} + +
+ ); +}; + +export default ContentTypeUsagesTable; +export { ContentTypeUsageTableColumn }; diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx new file mode 100644 index 0000000..4ac8c96 --- /dev/null +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx @@ -0,0 +1,46 @@ +import { Table } from "optimizely-oui"; +import { useTranslations } from "../../../../Contexts/TranslationsProvider"; +import { ContentUsageDto } from "../../../../dtos"; +import { TableColumn } from "../../../../types"; +import PageUrlCell from "../../PageUrlCell/PageUrlCell"; +import React from "react"; +import { ContentTypeUsageTableColumn } from "../ContentTypeUsageTable"; + +interface ContentTypeUsageTableRowProps extends ContentUsageDto { + tableColumns: TableColumn[]; + onRowClick?: (event: React.PointerEvent) => void; + } + +const ContentTypeUsageTableRow = ({ + tableColumns, + onRowClick, + ...row + }: ContentTypeUsageTableRowProps) => { + const { + views: { + contentUsagesView: { + table: { actions }, + }, + }, + } = useTranslations(); + + return ( + + { tableColumns + .filter((column) => column.visible) + .map((column) => + + { column.id.toString() === ContentTypeUsageTableColumn.PageUrl && + row.pageUrls.length > 0 ? ( + + ) : ( + row[column.id] + )} + + )} + + ); + }; + +export default ContentTypeUsageTableRow; + \ No newline at end of file diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlCell.tsx b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlCell.tsx new file mode 100644 index 0000000..9e5be2f --- /dev/null +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlCell.tsx @@ -0,0 +1,19 @@ +import { Disclose } from "optimizely-oui"; +import React from "react"; +import PageUrlLink from "./PageUrlLink/PageUrlLink"; + +const PageUrlCell = ({pageUrls}:{pageUrls: string[]}) => { + const isManyUrls = pageUrls.length > 1; + + return isManyUrls ? ( + + {pageUrls.map((pageUrl, index) => ( + + ))} + + ) : ( + + ); + } + + export default PageUrlCell; \ No newline at end of file diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlLink/PageUrlLink.tsx b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlLink/PageUrlLink.tsx new file mode 100644 index 0000000..accff57 --- /dev/null +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlLink/PageUrlLink.tsx @@ -0,0 +1,12 @@ +import { Link } from "optimizely-oui"; +import React from "react"; + +const PageUrlLink = ({ pageUrl }: { pageUrl: string }) => { + return ( + +
{pageUrl}
+ + ); + }; + +export default PageUrlLink; \ No newline at end of file diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss b/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss index 5272c3d..1a4c1ca 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss @@ -1,4 +1,20 @@ .forte-optimizely-content-usage-spinner__center { display: flex; justify-content: center; -} \ No newline at end of file +} + +.forte-optimizely-content-usage-page-url { + padding: 0 8px; + width: 100%; + &:hover { + background-color: var(--grey-50); + } +} + +.oui-disclose.is-active{ + .oui-disclose__content { + & > .forte-optimizely-content-usage-page-url:last-child { + padding-bottom: 0; + } + } +} diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.tsx b/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.tsx index d4a6556..dc1dfd8 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.tsx +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.tsx @@ -9,6 +9,7 @@ import { Breadcrumb } from "@episerver/ui-framework"; import { TableColumn } from "../types"; import { ButtonIcon, + Disclose, DiscloseTable, Dropdown, Grid, @@ -35,22 +36,7 @@ import Filters from "../Components/Filters/Filters"; import { useScroll } from "../Lib/hooks/useScroll"; import "./ContentTypeUsageView.scss"; - -enum ContentTypeUsageTableColumn { - ID = "id", - Name = "name", - LanguageBranch = "languageBranch", - PageUrl = "pageUrl", - Actions = "actions", -} - -interface ContentTypeUsageTableRowProps extends ContentUsageDto { - tableColumns: TableColumn[]; - onRowClick?: (event: React.PointerEvent) => void; - onEditButtonClick?: (event: React.PointerEvent) => void; - onViewWebsiteClick?: () => void; - hasDiscloseTableRows?: boolean; -} +import ContentTypeUsagesTable, { ContentTypeUsageTableColumn } from "../Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable"; type ContentTypeUsageViewResponse = | APIResponse @@ -61,125 +47,6 @@ type ContentTypeUsageViewInitialResponse = [ APIResponse ]; -const ContentTypeUsageDiscloseTableRow = ({ - tableColumns, - onRowClick, - ...row -}: ContentTypeUsageTableRowProps) => { - const { - views: { - contentUsagesView: { - table: { actions }, - }, - }, - } = useTranslations(); - - return ( - column.visible) - .map((column) => ( - - {column.id.toString() === ContentTypeUsageTableColumn.PageUrl - ? null - : row[column.id]} - - )), - , - ]} - isFullWidth - key={row.id} - > -
-
- - - - URL - - - - {row.pageUrls.length > 0 && - row.pageUrls.map((pageUrl, index) => ( - - - {pageUrl} - - - ))} - -
-
-
-
- ); -}; - -const ContentTypeUsageTableRow = ({ - tableColumns, - onRowClick, - onEditButtonClick, - onViewWebsiteClick, - hasDiscloseTableRows, - ...row -}: ContentTypeUsageTableRowProps) => { - const { - views: { - contentUsagesView: { - table: { actions }, - }, - }, - } = useTranslations(); - - return ( - - {hasDiscloseTableRows && } - {tableColumns - .filter((column) => column.visible) - .map((column) => ( - - {column.id.toString() === ContentTypeUsageTableColumn.PageUrl && - row.pageUrls.length > 0 && - row.pageUrls[0] ? ( - - {row.pageUrls[0]} - - ) : ( - row[column.id] - )} - - ))} - - - } - > - - {row.pageUrls[0] && ( - - - - - - )} - - - - - - - - - - ); -}; const ContentTypeUsageView = () => { const [dataLoaded, setDataLoaded] = useState(false); @@ -208,6 +75,7 @@ const ContentTypeUsageView = () => { visible: true, filter: true, sorting: true, + columnSpanWidth: 1, }, { id: ContentTypeUsageTableColumn.Name, @@ -215,6 +83,7 @@ const ContentTypeUsageView = () => { visible: true, filter: true, sorting: true, + columnSpanWidth: 4, }, { id: ContentTypeUsageTableColumn.LanguageBranch, @@ -222,12 +91,14 @@ const ContentTypeUsageView = () => { visible: true, filter: true, sorting: true, + columnSpanWidth: 2, }, { id: ContentTypeUsageTableColumn.PageUrl, name: columns.pageUrl, visible: true, sorting: false, + columnSpanWidth: 5, }, ] as TableColumn[]; @@ -278,34 +149,6 @@ const ContentTypeUsageView = () => { [translations, contentTypeDisplayName] ); - const onTableRowClick = useCallback( - (url?: string | null, alwaysTriggerClick = false) => - (event: React.PointerEvent) => { - if (!url) return; - - const target = event.target as HTMLTableCellElement | undefined; - - if ((target && target.tagName === "TD") || alwaysTriggerClick) { - navigateTo(url); - } - }, - [navigateTo] - ); - - const onViewWebsiteClick = useCallback( - (url?: string | null) => () => { - if (!url) return; - - navigateTo(url); - }, - [navigateTo] - ); - - const hasDiscloseTableRows = useMemo( - () => rows.some((row) => row.pageUrls.length > 1), - [rows] - ); - const response = useLoaderData() as ContentTypeUsageViewResponse; const setDataFromInitialResponse = useCallback( @@ -343,6 +186,11 @@ const ContentTypeUsageView = () => { } }, [response]); + const handleSortChange = useCallback((column: TableColumn) => { + setDataLoaded(false); + onSortChange(column); + }, [setDataLoaded, onSortChange]); + return ( { /> - - {dataLoaded ? ( -
- - - - {hasDiscloseTableRows && ( - - )} - {tableColumns - .filter((column) => column.visible) - .map((column) => ( - { - setDataLoaded(false); - onSortChange(column); - }, - order: sortDirection.toLowerCase(), - }} - key={column.id} - > - {column.name} - - ))} - - - - - - {rows.length > 0 ? ( - rows.map((row) => - row.pageUrls.length > 1 ? ( - - ) : ( - - ) - ) - ) : ( - - {translations.noResults} - - )} - - -
+ + {dataLoaded ? ( +
+ +
) : (
)} -
+
{totalPages > 1 && dataLoaded && ( - - + + )} diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/types.ts b/src/Forte.Optimizely.ContentUsage/Frontend/types.ts index 0b477e0..1e86e83 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/types.ts +++ b/src/Forte.Optimizely.ContentUsage/Frontend/types.ts @@ -9,6 +9,7 @@ export interface TableColumn { visible?: boolean; filter?: boolean; sorting?: boolean; + columnSpanWidth?: number; } export interface ContentTypeBase { From d4b590fea98ddeca3f2b0485955d83fb2aef0d6b Mon Sep 17 00:00:00 2001 From: KamilKranczuk Date: Wed, 9 Aug 2023 13:29:09 +0200 Subject: [PATCH 02/11] Navigate to new tab when content usage row clicked --- .../Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx | 2 +- src/Forte.Optimizely.ContentUsage/Frontend/routes.ts | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx index eadd05f..43ce103 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx @@ -35,7 +35,7 @@ const ContentTypeUsagesTable = ({ const target = event.target as HTMLTableCellElement | undefined; if ((target && target.tagName === "TD") || alwaysTriggerClick) { - navigateTo(url); + navigateTo(url, true); } }, [navigateTo] diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/routes.ts b/src/Forte.Optimizely.ContentUsage/Frontend/routes.ts index d910a90..ecc6963 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/routes.ts +++ b/src/Forte.Optimizely.ContentUsage/Frontend/routes.ts @@ -19,8 +19,12 @@ export const removeTrailingSlash = (url: string) => url.replace(/\/$/, ""); export const getRoutePath = (route: string) => removeTrailingSlash(getBaseUrl()) + baseViewPath + "#" + route; -export const navigateTo = (url: string | URL) => { +export const navigateTo = (url: string | URL, newWindow = false) => { if (typeof window !== "undefined") { + if (newWindow) { + window.open(url, "_blank"); + return; + } window.location.assign(url); } }; From ce6d03e42d670269ec564121afca4ff87357b393 Mon Sep 17 00:00:00 2001 From: KamilKranczuk Date: Wed, 16 Aug 2023 14:42:24 +0200 Subject: [PATCH 03/11] Add PageUrlCellProps interface --- .../Frontend/Components/Tables/PageUrlCell/PageUrlCell.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlCell.tsx b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlCell.tsx index 9e5be2f..1c959f1 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlCell.tsx +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlCell.tsx @@ -2,7 +2,11 @@ import { Disclose } from "optimizely-oui"; import React from "react"; import PageUrlLink from "./PageUrlLink/PageUrlLink"; -const PageUrlCell = ({pageUrls}:{pageUrls: string[]}) => { +interface PageUrlCellProps { + pageUrls: string[]; +} + +const PageUrlCell = ({pageUrls}: PageUrlCellProps) => { const isManyUrls = pageUrls.length > 1; return isManyUrls ? ( From 6e77ea486f376fd9825bd7a4b0c83ac8d6cebf0b Mon Sep 17 00:00:00 2001 From: KamilKranczuk Date: Wed, 16 Aug 2023 14:54:18 +0200 Subject: [PATCH 04/11] Fix many usages row height --- .../Frontend/Views/ContentTypeUsageView.scss | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss b/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss index 1a4c1ca..4c57456 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss @@ -11,10 +11,8 @@ } } -.oui-disclose.is-active{ - .oui-disclose__content { - & > .forte-optimizely-content-usage-page-url:last-child { - padding-bottom: 0; - } +.oui-disclose { + & .soft-half { + padding: 0 4px !important; } } From bd8f4746617635decf4185fa271279cbab2c065c Mon Sep 17 00:00:00 2001 From: KamilKranczuk Date: Wed, 16 Aug 2023 14:55:34 +0200 Subject: [PATCH 05/11] Put each props in separated line --- .../Frontend/Views/ContentTypeUsageView.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.tsx b/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.tsx index dc1dfd8..356c78c 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.tsx +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.tsx @@ -220,7 +220,10 @@ const ContentTypeUsageView = () => { {dataLoaded ? (
- +
) : (
From 86cd3c2401b6479b8752573c79a60d662327aaf1 Mon Sep 17 00:00:00 2001 From: KamilKranczuk Date: Fri, 18 Aug 2023 09:12:01 +0200 Subject: [PATCH 06/11] Add useHoverTrackingHandlers hook --- .../Lib/hooks/useHoverTrackingHandlers.ts | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/Forte.Optimizely.ContentUsage/Frontend/Lib/hooks/useHoverTrackingHandlers.ts diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Lib/hooks/useHoverTrackingHandlers.ts b/src/Forte.Optimizely.ContentUsage/Frontend/Lib/hooks/useHoverTrackingHandlers.ts new file mode 100644 index 0000000..ce31c27 --- /dev/null +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Lib/hooks/useHoverTrackingHandlers.ts @@ -0,0 +1,24 @@ +import { useState, useMemo } from "react"; + +export type HoverTrackingHook = [ + isHovered: boolean, + handlers: HoverHandlers +] + +export interface HoverHandlers { + enter: () => void; + out: () => void; +} + +export function useHoverTrackingHandlers(): HoverTrackingHook { + const [isHovered, setIsHovered] = useState(false); + + const urlHoveredHandlers = useMemo(() => { + return { + enter: () => setIsHovered(true), + out: () => setIsHovered(false), + }; + }, []); + + return [isHovered, urlHoveredHandlers]; +} From e508db682ae2736b2c5cd67ecaea6e5c91a7cf41 Mon Sep 17 00:00:00 2001 From: KamilKranczuk Date: Fri, 18 Aug 2023 09:55:38 +0200 Subject: [PATCH 07/11] Add action label (view/edit text on hover) --- .../ContentTypeUsageTable.tsx | 1 + .../ContentTypeUsageTableRow.tsx | 13 +++++++--- .../Tables/PageUrlCell/PageUrlCell.tsx | 8 +++--- .../PageUrlCell/PageUrlLink/PageUrlLink.tsx | 25 +++++++++++++------ .../Frontend/Views/ContentTypeUsageView.scss | 13 ++++++++++ 5 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx index 43ce103..b43221c 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx @@ -65,6 +65,7 @@ const ContentTypeUsagesTable = ({ ))} + diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx index 4ac8c96..9f007fd 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx @@ -5,11 +5,12 @@ import { TableColumn } from "../../../../types"; import PageUrlCell from "../../PageUrlCell/PageUrlCell"; import React from "react"; import { ContentTypeUsageTableColumn } from "../ContentTypeUsageTable"; +import { useHoverTrackingHandlers } from "../../../../Lib/hooks/useHoverTrackingHandlers"; interface ContentTypeUsageTableRowProps extends ContentUsageDto { tableColumns: TableColumn[]; onRowClick?: (event: React.PointerEvent) => void; - } +} const ContentTypeUsageTableRow = ({ tableColumns, @@ -23,21 +24,25 @@ const ContentTypeUsageTableRow = ({ }, }, } = useTranslations(); - + + const [isUrlHovered, urlHoveredHandlers] = useHoverTrackingHandlers(); + const actionLabel = isUrlHovered ? "Edit": "View"; + return ( - + { tableColumns .filter((column) => column.visible) .map((column) => { column.id.toString() === ContentTypeUsageTableColumn.PageUrl && row.pageUrls.length > 0 ? ( - + ) : ( row[column.id] )} )} + {actionLabel + " >"} ); }; diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlCell.tsx b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlCell.tsx index 1c959f1..1a273f1 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlCell.tsx +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlCell.tsx @@ -1,22 +1,24 @@ import { Disclose } from "optimizely-oui"; import React from "react"; import PageUrlLink from "./PageUrlLink/PageUrlLink"; +import { HoverHandlers } from "../../../Lib/hooks/useHoverTrackingHandlers"; interface PageUrlCellProps { pageUrls: string[]; + urlHoveredHandlers: HoverHandlers; } -const PageUrlCell = ({pageUrls}: PageUrlCellProps) => { +const PageUrlCell = ({pageUrls, urlHoveredHandlers}: PageUrlCellProps) => { const isManyUrls = pageUrls.length > 1; return isManyUrls ? ( {pageUrls.map((pageUrl, index) => ( - + ))} ) : ( - + ); } diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlLink/PageUrlLink.tsx b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlLink/PageUrlLink.tsx index accff57..9e7ed03 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlLink/PageUrlLink.tsx +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/PageUrlCell/PageUrlLink/PageUrlLink.tsx @@ -1,12 +1,23 @@ import { Link } from "optimizely-oui"; import React from "react"; +import { HoverHandlers } from "../../../../Lib/hooks/useHoverTrackingHandlers"; -const PageUrlLink = ({ pageUrl }: { pageUrl: string }) => { - return ( - -
{pageUrl}
- - ); - }; +interface PageUrlLinkProps { + pageUrl: string; + urlHoveredHandlers: HoverHandlers; +} + +const PageUrlLink = ({ pageUrl, urlHoveredHandlers }: PageUrlLinkProps) => { + return ( + +
+ {pageUrl} +
+ + ); +}; export default PageUrlLink; \ No newline at end of file diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss b/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss index 4c57456..dbc59ad 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss @@ -3,6 +3,19 @@ justify-content: center; } +.forte-optimizely-content-usage-action-label { + display: block; + text-align: center; + opacity: 0; + transition: opacity 150ms ease-in-out; +} + +.forte-optimizely-content-usage-table-row:hover { + & .forte-optimizely-content-usage-action-label { + opacity: 1; + } +} + .forte-optimizely-content-usage-page-url { padding: 0 8px; width: 100%; From 27e3b4d2cc58829c5c915ac747e28f133c6de4db Mon Sep 17 00:00:00 2001 From: KamilKranczuk Date: Fri, 18 Aug 2023 09:58:22 +0200 Subject: [PATCH 08/11] Add muted color on content type usage view helper labels --- .../Frontend/Styles/_variables.scss | 4 ++++ .../Frontend/Views/ContentTypeUsageView.scss | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Styles/_variables.scss b/src/Forte.Optimizely.ContentUsage/Frontend/Styles/_variables.scss index 2722068..2f65887 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Styles/_variables.scss +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Styles/_variables.scss @@ -1 +1,5 @@ @import 'variables/breakpoints'; + +:root { + --muted-color: #707070 +} \ No newline at end of file diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss b/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss index dbc59ad..91e938c 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss @@ -5,6 +5,7 @@ .forte-optimizely-content-usage-action-label { display: block; + color: var(--muted-color); text-align: center; opacity: 0; transition: opacity 150ms ease-in-out; @@ -26,6 +27,7 @@ .oui-disclose { & .soft-half { + color: var(--muted-color); padding: 0 4px !important; } } From e3654ce97796313bed76d69c9196b8572ba656db Mon Sep 17 00:00:00 2001 From: KamilKranczuk Date: Fri, 18 Aug 2023 10:09:02 +0200 Subject: [PATCH 09/11] Correct "many usages" arrow position --- .../Frontend/Views/ContentTypeUsageView.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss b/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss index 91e938c..ffa7629 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Views/ContentTypeUsageView.scss @@ -30,4 +30,10 @@ color: var(--muted-color); padding: 0 4px !important; } + + &:not(.is-active){ + & .oui-disclose__symbol { + top: 0; + } + } } From 8bdd895965bc92e778ca56c86ec7aea14ee904f4 Mon Sep 17 00:00:00 2001 From: KamilKranczuk Date: Fri, 18 Aug 2023 10:10:24 +0200 Subject: [PATCH 10/11] Invert action label text --- .../ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx index 9f007fd..7b9896f 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx @@ -26,7 +26,7 @@ const ContentTypeUsageTableRow = ({ } = useTranslations(); const [isUrlHovered, urlHoveredHandlers] = useHoverTrackingHandlers(); - const actionLabel = isUrlHovered ? "Edit": "View"; + const actionLabel = isUrlHovered ? "View" : "Edit"; return ( From ab0107a4904807cd4d6c09924037ac734185dacb Mon Sep 17 00:00:00 2001 From: KamilKranczuk Date: Fri, 18 Aug 2023 11:27:21 +0200 Subject: [PATCH 11/11] Apply changes --- .../Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx | 2 -- .../ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx index b43221c..a4121fa 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTable.tsx @@ -51,7 +51,6 @@ const ContentTypeUsagesTable = ({ {tableColumns .filter((column) => column.visible) .map((column) => ( - <> {column.name} - ))} diff --git a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx index 7b9896f..b0341c6 100644 --- a/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx +++ b/src/Forte.Optimizely.ContentUsage/Frontend/Components/Tables/ContentTypeUsagesTable/ContentTypeUsageTableRow/ContentTypeUsageTableRow.tsx @@ -26,14 +26,14 @@ const ContentTypeUsageTableRow = ({ } = useTranslations(); const [isUrlHovered, urlHoveredHandlers] = useHoverTrackingHandlers(); - const actionLabel = isUrlHovered ? "View" : "Edit"; + const actionLabel = isUrlHovered ? actions.view : actions.edit; return ( - + { tableColumns .filter((column) => column.visible) .map((column) => - + { column.id.toString() === ContentTypeUsageTableColumn.PageUrl && row.pageUrls.length > 0 ? (