From 30c21cb2e3f2af98d92be48eff78437d734eafee Mon Sep 17 00:00:00 2001
From: Austin Sullivan <ausulliv@redhat.com>
Date: Thu, 28 Sep 2023 09:07:49 -0400
Subject: [PATCH] onboard to automated consumer testing

Signed-off-by: Austin Sullivan <ausulliv@redhat.com>
---
 .github/workflows/ci-actions.yml              |   6 +-
 client/package.json                           |   2 +-
 client/src/app/hooks/table-controls/types.ts  |   2 +-
 .../useLocalTableControlState.ts              | 161 ++++++++++++++++++
 .../src/app/layout/SidebarApp/SidebarApp.tsx  |   2 +-
 client/src/app/pages/controls/tags/tags.tsx   |   2 +-
 .../app/pages/dependencies/dependencies.tsx   |   2 +-
 .../dependencies/dependency-apps-table.tsx    |   2 +-
 .../affected-applications.tsx                 |   2 +-
 .../file-all-incidents-table.tsx              |   2 +-
 .../issue-affected-files-table.tsx            |   2 +-
 client/src/app/pages/issues/issues-table.tsx  |   2 +-
 .../reports/application-selection-context.tsx |   5 +-
 package-lock.json                             |   2 +-
 renovate.json                                 |  27 +++
 15 files changed, 204 insertions(+), 17 deletions(-)
 create mode 100644 client/src/app/hooks/table-controls/useLocalTableControlState.ts
 create mode 100644 renovate.json

diff --git a/.github/workflows/ci-actions.yml b/.github/workflows/ci-actions.yml
index eeed592731..bde516cd17 100644
--- a/.github/workflows/ci-actions.yml
+++ b/.github/workflows/ci-actions.yml
@@ -1,10 +1,6 @@
 name: CI
 
 on:
-  push:
-    branches:
-      - main
-      - "release-*"
   pull_request:
     branches:
       - main
@@ -30,7 +26,7 @@ jobs:
         run: ./scripts/verify_lock.mjs
 
       - name: Install
-        run: npm clean-install --ignore-scripts
+        run: npm install --ignore-scripts
 
       - name: Lint sources
         run: npm run lint
diff --git a/client/package.json b/client/package.json
index 787060b79c..9d1bd7d681 100644
--- a/client/package.json
+++ b/client/package.json
@@ -24,7 +24,7 @@
     "@dnd-kit/sortable": "^7.0.2",
     "@hookform/resolvers": "^2.9.11",
     "@hot-loader/react-dom": "^17.0.2",
-    "@migtools/lib-ui": "^10.0.1",
+    "@pf-consumer-testing/lib-ui": "1.0.1",
     "@patternfly/patternfly": "^5.0.2",
     "@patternfly/react-charts": "^7.1.0",
     "@patternfly/react-code-editor": "^5.1.0",
diff --git a/client/src/app/hooks/table-controls/types.ts b/client/src/app/hooks/table-controls/types.ts
index a96829c6a1..a9afc94150 100644
--- a/client/src/app/hooks/table-controls/types.ts
+++ b/client/src/app/hooks/table-controls/types.ts
@@ -1,5 +1,5 @@
 import { TableProps, TdProps, ThProps, TrProps } from "@patternfly/react-table";
-import { ISelectionStateArgs, useSelectionState } from "@migtools/lib-ui";
+import { ISelectionStateArgs, useSelectionState } from "@pf-consumer-testing/lib-ui";
 import { DisallowCharacters, DiscriminatedArgs } from "@app/utils/type-utils";
 import {
   IFilterStateArgs,
diff --git a/client/src/app/hooks/table-controls/useLocalTableControlState.ts b/client/src/app/hooks/table-controls/useLocalTableControlState.ts
new file mode 100644
index 0000000000..29d904934b
--- /dev/null
+++ b/client/src/app/hooks/table-controls/useLocalTableControlState.ts
@@ -0,0 +1,161 @@
+import { useSelectionState } from "@pf-consumer-testing/lib-ui";
+import {
+  getLocalFilterDerivedState,
+  useFilterState,
+  useFilterUrlParams,
+} from "./filtering";
+import {
+  useSortState,
+  getLocalSortDerivedState,
+  useSortUrlParams,
+} from "./sorting";
+import {
+  getLocalPaginationDerivedState,
+  usePaginationState,
+  usePaginationUrlParams,
+} from "./pagination";
+import { useExpansionState, useExpansionUrlParams } from "./expansion";
+import { useActiveRowState, useActiveRowUrlParams } from "./active-row";
+import {
+  IExtraArgsForURLParamHooks,
+  IUseLocalTableControlStateArgs,
+  IUseTableControlPropsArgs,
+} from "./types";
+
+export const useLocalTableControlState = <
+  TItem,
+  TColumnKey extends string,
+  TSortableColumnKey extends TColumnKey,
+>(
+  args: IUseLocalTableControlStateArgs<TItem, TColumnKey, TSortableColumnKey>
+): IUseTableControlPropsArgs<TItem, TColumnKey, TSortableColumnKey> => {
+  const {
+    items,
+    filterCategories = [],
+    sortableColumns = [],
+    getSortValues,
+    initialSort = null,
+    hasPagination = true,
+    initialItemsPerPage = 10,
+    idProperty,
+    initialSelected,
+    isItemSelectable,
+  } = args;
+
+  const filterState = useFilterState(args);
+  const { filteredItems } = getLocalFilterDerivedState({
+    items,
+    filterCategories,
+    filterState,
+  });
+
+  const selectionState = useSelectionState({
+    items: filteredItems,
+    isEqual: (a, b) => a[idProperty] === b[idProperty],
+    initialSelected,
+    isItemSelectable,
+  });
+
+  const sortState = useSortState({ sortableColumns, initialSort });
+  const { sortedItems } = getLocalSortDerivedState({
+    sortState,
+    items: filteredItems,
+    getSortValues,
+  });
+
+  const paginationState = usePaginationState({
+    initialItemsPerPage,
+  });
+  const { currentPageItems } = getLocalPaginationDerivedState({
+    paginationState,
+    items: sortedItems,
+  });
+
+  const expansionState = useExpansionState<TColumnKey>();
+
+  const activeRowState = useActiveRowState();
+
+  return {
+    ...args,
+    filterState,
+    expansionState,
+    selectionState,
+    sortState,
+    paginationState,
+    activeRowState,
+    totalItemCount: items.length,
+    currentPageItems: hasPagination ? currentPageItems : sortedItems,
+  };
+};
+
+// TODO refactor useUrlParams so it can be used conditionally (e.g. useStateOrUrlParams) so we don't have to duplicate all this.
+//      this would mean all use[Feature]UrlParams hooks could be consolidated into use[Feature]State with a boolean option for whether to use URL params.
+
+export const useLocalTableControlUrlParams = <
+  TItem,
+  TColumnKey extends string,
+  TSortableColumnKey extends TColumnKey,
+  TURLParamKeyPrefix extends string = string,
+>(
+  args: IUseLocalTableControlStateArgs<TItem, TColumnKey, TSortableColumnKey> &
+    IExtraArgsForURLParamHooks<TURLParamKeyPrefix>
+): IUseTableControlPropsArgs<TItem, TColumnKey, TSortableColumnKey> => {
+  const {
+    items,
+    filterCategories = [],
+    sortableColumns = [],
+    getSortValues,
+    initialSort = null,
+    hasPagination = true,
+    initialItemsPerPage = 10,
+    idProperty,
+    initialSelected,
+    isItemSelectable,
+  } = args;
+
+  const filterState = useFilterUrlParams(args);
+  const { filteredItems } = getLocalFilterDerivedState({
+    items,
+    filterCategories,
+    filterState,
+  });
+
+  const selectionState = useSelectionState({
+    items: filteredItems,
+    isEqual: (a, b) => a[idProperty] === b[idProperty],
+    initialSelected,
+    isItemSelectable,
+  });
+
+  const sortState = useSortUrlParams({ ...args, sortableColumns, initialSort });
+  const { sortedItems } = getLocalSortDerivedState({
+    sortState,
+    items: filteredItems,
+    getSortValues,
+  });
+
+  const paginationState = usePaginationUrlParams({
+    ...args,
+    initialItemsPerPage,
+  });
+  const { currentPageItems } = getLocalPaginationDerivedState({
+    paginationState,
+    items: sortedItems,
+  });
+
+  const expansionState = useExpansionUrlParams<TColumnKey>(args);
+
+  const activeRowState = useActiveRowUrlParams(args);
+
+  return {
+    ...args,
+    filterState,
+    expansionState,
+    selectionState,
+    sortState,
+    paginationState,
+    activeRowState,
+    totalItemCount: items.length,
+    currentPageItems: hasPagination ? currentPageItems : sortedItems,
+  };
+};
diff --git a/client/src/app/layout/SidebarApp/SidebarApp.tsx b/client/src/app/layout/SidebarApp/SidebarApp.tsx
index dcabacf316..29a28c269e 100644
--- a/client/src/app/layout/SidebarApp/SidebarApp.tsx
+++ b/client/src/app/layout/SidebarApp/SidebarApp.tsx
@@ -16,7 +16,7 @@ import { LayoutTheme } from "../LayoutUtils";
 import { checkAccess } from "@app/utils/rbac-utils";
 import keycloak from "@app/keycloak";
 
-import { useLocalStorage } from "@migtools/lib-ui";
+import { useLocalStorage } from "@pf-consumer-testing/lib-ui";
 import { LocalStorageKey } from "@app/Constants";
 import { FEATURES_ENABLED } from "@app/FeatureFlags";
 import { SimpleSelectBasic } from "@app/components/SimpleSelectBasic";
diff --git a/client/src/app/pages/controls/tags/tags.tsx b/client/src/app/pages/controls/tags/tags.tsx
index f00bb7b64a..1ff8de5f66 100644
--- a/client/src/app/pages/controls/tags/tags.tsx
+++ b/client/src/app/pages/controls/tags/tags.tsx
@@ -1,7 +1,7 @@
 import React from "react";
 import { AxiosError } from "axios";
 import { useTranslation } from "react-i18next";
-import { useSelectionState } from "@migtools/lib-ui";
+import { useSelectionState } from "@pf-consumer-testing/lib-ui";
 import {
   Button,
   ButtonVariant,
diff --git a/client/src/app/pages/dependencies/dependencies.tsx b/client/src/app/pages/dependencies/dependencies.tsx
index f05e95c595..acae222a2d 100644
--- a/client/src/app/pages/dependencies/dependencies.tsx
+++ b/client/src/app/pages/dependencies/dependencies.tsx
@@ -27,7 +27,7 @@ import {
   TableRowContentWithControls,
 } from "@app/components/TableControls";
 import { useFetchDependencies } from "@app/queries/dependencies";
-import { useSelectionState } from "@migtools/lib-ui";
+import { useSelectionState } from "@pf-consumer-testing/lib-ui";
 import { DependencyAppsDetailDrawer } from "./dependency-apps-detail-drawer";
 import { useSharedAffectedApplicationFilterCategories } from "../issues/helpers";
 import { getParsedLabel } from "@app/utils/rules-utils";
diff --git a/client/src/app/pages/dependencies/dependency-apps-table.tsx b/client/src/app/pages/dependencies/dependency-apps-table.tsx
index 793db71824..b6d2cfb9ed 100644
--- a/client/src/app/pages/dependencies/dependency-apps-table.tsx
+++ b/client/src/app/pages/dependencies/dependency-apps-table.tsx
@@ -9,7 +9,7 @@ import {
 } from "@patternfly/react-core";
 import { Table, Tbody, Td, Th, Thead, Tr } from "@patternfly/react-table";
 import spacing from "@patternfly/react-styles/css/utilities/Spacing/spacing";
-import { useSelectionState } from "@migtools/lib-ui";
+import { useSelectionState } from "@pf-consumer-testing/lib-ui";
 import { AnalysisAppDependency, AnalysisDependency } from "@app/api/models";
 import {
   useTableControlState,
diff --git a/client/src/app/pages/issues/affected-applications/affected-applications.tsx b/client/src/app/pages/issues/affected-applications/affected-applications.tsx
index e26c6f63a4..c656491971 100644
--- a/client/src/app/pages/issues/affected-applications/affected-applications.tsx
+++ b/client/src/app/pages/issues/affected-applications/affected-applications.tsx
@@ -12,7 +12,7 @@ import {
 } from "@patternfly/react-core";
 import { useTranslation } from "react-i18next";
 import { Table, Tbody, Td, Th, Thead, Tr } from "@patternfly/react-table";
-import { useSelectionState } from "@migtools/lib-ui";
+import { useSelectionState } from "@pf-consumer-testing/lib-ui";
 
 import { ConditionalRender } from "@app/components/ConditionalRender";
 import { AppPlaceholder } from "@app/components/AppPlaceholder";
diff --git a/client/src/app/pages/issues/issue-detail-drawer/file-incidents-detail-modal/file-all-incidents-table.tsx b/client/src/app/pages/issues/issue-detail-drawer/file-incidents-detail-modal/file-all-incidents-table.tsx
index 07638c4d30..680bb8275a 100644
--- a/client/src/app/pages/issues/issue-detail-drawer/file-incidents-detail-modal/file-all-incidents-table.tsx
+++ b/client/src/app/pages/issues/issue-detail-drawer/file-incidents-detail-modal/file-all-incidents-table.tsx
@@ -1,6 +1,6 @@
 import * as React from "react";
 import { Table, Thead, Tr, Th, Tbody, Td } from "@patternfly/react-table";
-import { useSelectionState } from "@migtools/lib-ui";
+import { useSelectionState } from "@pf-consumer-testing/lib-ui";
 import { TablePersistenceKeyPrefix } from "@app/Constants";
 import { AnalysisFileReport } from "@app/api/models";
 import { useFetchIncidents } from "@app/queries/issues";
diff --git a/client/src/app/pages/issues/issue-detail-drawer/issue-affected-files-table.tsx b/client/src/app/pages/issues/issue-detail-drawer/issue-affected-files-table.tsx
index 9ae5637c20..0ea1a95173 100644
--- a/client/src/app/pages/issues/issue-detail-drawer/issue-affected-files-table.tsx
+++ b/client/src/app/pages/issues/issue-detail-drawer/issue-affected-files-table.tsx
@@ -8,7 +8,7 @@ import {
 } from "@patternfly/react-core";
 import { Table, Tbody, Td, Th, Thead, Tr } from "@patternfly/react-table";
 import spacing from "@patternfly/react-styles/css/utilities/Spacing/spacing";
-import { useSelectionState } from "@migtools/lib-ui";
+import { useSelectionState } from "@pf-consumer-testing/lib-ui";
 import { AnalysisFileReport, AnalysisIssue } from "@app/api/models";
 import {
   useTableControlState,
diff --git a/client/src/app/pages/issues/issues-table.tsx b/client/src/app/pages/issues/issues-table.tsx
index 401e724eba..cdf926cb4a 100644
--- a/client/src/app/pages/issues/issues-table.tsx
+++ b/client/src/app/pages/issues/issues-table.tsx
@@ -29,7 +29,7 @@ import {
 import spacing from "@patternfly/react-styles/css/utilities/Spacing/spacing";
 import textStyles from "@patternfly/react-styles/css/utilities/Text/text";
 import CubesIcon from "@patternfly/react-icons/dist/esm/icons/cubes-icon";
-import { useSelectionState } from "@migtools/lib-ui";
+import { useSelectionState } from "@pf-consumer-testing/lib-ui";
 
 import { AppPlaceholder } from "@app/components/AppPlaceholder";
 import { OptionWithValue, SimpleSelect } from "@app/components/SimpleSelect";
diff --git a/client/src/app/pages/reports/application-selection-context.tsx b/client/src/app/pages/reports/application-selection-context.tsx
index 525b848b97..a4d275bc99 100644
--- a/client/src/app/pages/reports/application-selection-context.tsx
+++ b/client/src/app/pages/reports/application-selection-context.tsx
@@ -1,5 +1,8 @@
 import React, { useEffect, useState } from "react";
-import { useSelectionState, ISelectionState } from "@migtools/lib-ui";
+import {
+  useSelectionState,
+  ISelectionState,
+} from "@pf-consumer-testing/lib-ui";
 import { Application } from "@app/api/models";
 
 interface IApplicationSelectionContext extends ISelectionState<Application> {
diff --git a/package-lock.json b/package-lock.json
index 6ed9531d8d..13fef4a8ef 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -61,7 +61,7 @@
         "@dnd-kit/sortable": "^7.0.2",
         "@hookform/resolvers": "^2.9.11",
         "@hot-loader/react-dom": "^17.0.2",
-        "@migtools/lib-ui": "^10.0.1",
+        "@migtools/lib-ui": "npm:@pf-consumer-testing/lib-ui@latest",
         "@patternfly/patternfly": "^5.0.2",
         "@patternfly/react-charts": "^7.1.0",
         "@patternfly/react-code-editor": "^5.1.0",
diff --git a/renovate.json b/renovate.json
new file mode 100644
index 0000000000..47fab7964a
--- /dev/null
+++ b/renovate.json
@@ -0,0 +1,27 @@
+{
+  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
+  "extends": ["config:base"],
+  "enabledManagers": ["npm"],
+  "rangeStrategy": "bump",
+  "includeForks": true,
+  "packageRules": [
+    {
+      "packagePatterns": ["*"],
+      "excludePackagePatterns": ["@patternfly/*"],
+      "enabled": false
+    },
+    {
+      "datasources": ["npm"],
+      "packagePatterns": ["@patternfly/*"],
+      "excludePackageNames": ["@patternfly/documentation-framework", "@patternfly/patternfly-a11y"],
+      "groupName": "patternfly",
+      "followTag": "prerelease"
+    },
+    {
+      "datasources": ["npm"],
+      "matchPackageNames": ["@patternfly/documentation-framework", "@patternfly/patternfly-a11y"],
+      "groupName": "patternfly",
+      "followTag": "latest"
+    }
+  ]
+}