diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml deleted file mode 100644 index b6742f80..00000000 --- a/.forgejo/workflows/ci.yml +++ /dev/null @@ -1,257 +0,0 @@ ---- -name: Debian Image Builder Frontend CI/CD - -on: - push: - branches: [main, develop] - pull_request: - branches: [main] - workflow_dispatch: - -env: - NODE_VERSION: "18" - DEBIAN_FRONTEND: noninteractive - -jobs: - build-and-test: - name: Build and Test Frontend - runs-on: ubuntu-latest - container: - image: node:18-bullseye - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js environment - run: | - node --version - npm --version - - - name: Install build dependencies - run: | - apt-get update - apt-get install -y \ - build-essential \ - git \ - ca-certificates \ - python3 - - - name: Install Node.js dependencies - run: | - npm ci - npm run build || echo "Build script not found" - - - name: Run tests - run: | - if [ -f package.json ] && npm run test; then - npm test - else - echo "No test script found, skipping tests" - fi - - - name: Run linting - run: | - if [ -f package.json ] && npm run lint; then - npm run lint - else - echo "No lint script found, skipping linting" - fi - - - name: Build production bundle - run: | - if [ -f package.json ] && npm run build; then - npm run build - else - echo "No build script found" - fi - - - name: Upload build artifacts - uses: actions/upload-artifact@v4 - with: - name: frontend-build - path: | - dist/ - build/ - retention-days: 30 - - package: - name: Package Frontend - runs-on: ubuntu-latest - container: - image: node:18-bullseye - needs: build-and-test - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js environment - run: | - node --version - npm --version - - - name: Install build dependencies - run: | - apt-get update - apt-get install -y \ - build-essential \ - devscripts \ - debhelper \ - git \ - ca-certificates \ - python3 - - - name: Install Node.js dependencies - run: npm ci - - - name: Build production bundle - run: | - if [ -f package.json ] && npm run build; then - npm run build - else - echo "No build script found" - fi - - - name: Create debian directory - run: | - mkdir -p debian - cat > debian/control << EOF -Source: debian-image-builder-frontend -Section: web -Priority: optional -Maintainer: Debian Forge Team -Build-Depends: debhelper (>= 13), nodejs, npm, git, ca-certificates -Standards-Version: 4.6.2 - -Package: debian-image-builder-frontend -Architecture: all -Depends: \${misc:Depends}, nodejs, nginx -Description: Debian Image Builder Frontend - Web-based frontend for Debian Image Builder with Cockpit integration. - Provides a user interface for managing image builds, blueprints, - and system configurations through a modern React application. -EOF - - cat > debian/rules << EOF -#!/usr/bin/make -f -%: - dh \$@ - -override_dh_auto_install: - dh_auto_install - mkdir -p debian/debian-image-builder-frontend/usr/share/debian-image-builder-frontend - mkdir -p debian/debian-image-builder-frontend/etc/nginx/sites-available - mkdir -p debian/debian-image-builder-frontend/etc/cockpit - - # Copy built frontend files - if [ -d dist ]; then - cp -r dist/* debian/debian-image-builder-frontend/usr/share/debian-image-builder-frontend/ - elif [ -d build ]; then - cp -r build/* debian/debian-image-builder-frontend/usr/share/debian-image-builder-frontend/ - fi - - # Copy source files for development - cp -r src debian/debian-image-builder-frontend/usr/share/debian-image-builder-frontend/ - cp package.json debian/debian-image-builder-frontend/usr/share/debian-image-builder-frontend/ - - # Create nginx configuration - cat > debian/debian-image-builder-frontend/etc/nginx/sites-available/debian-image-builder-frontend << 'NGINX_EOF' -server { - listen 80; - server_name localhost; - root /usr/share/debian-image-builder-frontend; - index index.html; - - location / { - try_files \$uri \$uri/ /index.html; - } - - location /api/ { - proxy_pass http://localhost:8080/; - proxy_set_header Host \$host; - proxy_set_header X-Real-IP \$remote_addr; - } -} -NGINX_EOF - - # Create cockpit manifest - cat > debian/debian-image-builder-frontend/etc/cockpit/debian-image-builder.manifest << 'COCKPIT_EOF' -{ - "version": 1, - "manifest": { - "name": "debian-image-builder", - "version": "1.0.0", - "title": "Debian Image Builder", - "description": "Build and manage Debian atomic images", - "url": "/usr/share/debian-image-builder-frontend", - "icon": "debian-logo", - "requires": { - "cockpit": ">= 200" - } - } -} -COCKPIT_EOF -EOF - - cat > debian/changelog << EOF -debian-image-builder-frontend (1.0.0-1) unstable; urgency=medium - - * Initial release - * Debian Image Builder Frontend with Cockpit integration - * React-based web interface for image management - - -- Debian Forge Team $(date -R) -EOF - - cat > debian/compat << EOF -13 -EOF - - chmod +x debian/rules - - - name: Build Debian package - run: | - dpkg-buildpackage -us -uc -b - ls -la ../*.deb - - - name: Upload Debian package - uses: actions/upload-artifact@v4 - with: - name: debian-image-builder-frontend-deb - path: ../*.deb - retention-days: 30 - - cockpit-integration: - name: Test Cockpit Integration - runs-on: ubuntu-latest - container: - image: node:18-bullseye - needs: build-and-test - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js environment - run: | - node --version - npm --version - - - name: Install Node.js dependencies - run: npm ci - - - name: Test cockpit integration - run: | - echo "Testing Cockpit integration..." - if [ -d cockpit ]; then - echo "Cockpit directory found:" - ls -la cockpit/ - else - echo "No cockpit directory found" - fi - - if [ -f package.json ]; then - echo "Package.json scripts:" - npm run - fi diff --git a/.forgejo/workflows/ci.yml.disabled b/.forgejo/workflows/ci.yml.disabled deleted file mode 100644 index b6742f80..00000000 --- a/.forgejo/workflows/ci.yml.disabled +++ /dev/null @@ -1,257 +0,0 @@ ---- -name: Debian Image Builder Frontend CI/CD - -on: - push: - branches: [main, develop] - pull_request: - branches: [main] - workflow_dispatch: - -env: - NODE_VERSION: "18" - DEBIAN_FRONTEND: noninteractive - -jobs: - build-and-test: - name: Build and Test Frontend - runs-on: ubuntu-latest - container: - image: node:18-bullseye - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js environment - run: | - node --version - npm --version - - - name: Install build dependencies - run: | - apt-get update - apt-get install -y \ - build-essential \ - git \ - ca-certificates \ - python3 - - - name: Install Node.js dependencies - run: | - npm ci - npm run build || echo "Build script not found" - - - name: Run tests - run: | - if [ -f package.json ] && npm run test; then - npm test - else - echo "No test script found, skipping tests" - fi - - - name: Run linting - run: | - if [ -f package.json ] && npm run lint; then - npm run lint - else - echo "No lint script found, skipping linting" - fi - - - name: Build production bundle - run: | - if [ -f package.json ] && npm run build; then - npm run build - else - echo "No build script found" - fi - - - name: Upload build artifacts - uses: actions/upload-artifact@v4 - with: - name: frontend-build - path: | - dist/ - build/ - retention-days: 30 - - package: - name: Package Frontend - runs-on: ubuntu-latest - container: - image: node:18-bullseye - needs: build-and-test - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js environment - run: | - node --version - npm --version - - - name: Install build dependencies - run: | - apt-get update - apt-get install -y \ - build-essential \ - devscripts \ - debhelper \ - git \ - ca-certificates \ - python3 - - - name: Install Node.js dependencies - run: npm ci - - - name: Build production bundle - run: | - if [ -f package.json ] && npm run build; then - npm run build - else - echo "No build script found" - fi - - - name: Create debian directory - run: | - mkdir -p debian - cat > debian/control << EOF -Source: debian-image-builder-frontend -Section: web -Priority: optional -Maintainer: Debian Forge Team -Build-Depends: debhelper (>= 13), nodejs, npm, git, ca-certificates -Standards-Version: 4.6.2 - -Package: debian-image-builder-frontend -Architecture: all -Depends: \${misc:Depends}, nodejs, nginx -Description: Debian Image Builder Frontend - Web-based frontend for Debian Image Builder with Cockpit integration. - Provides a user interface for managing image builds, blueprints, - and system configurations through a modern React application. -EOF - - cat > debian/rules << EOF -#!/usr/bin/make -f -%: - dh \$@ - -override_dh_auto_install: - dh_auto_install - mkdir -p debian/debian-image-builder-frontend/usr/share/debian-image-builder-frontend - mkdir -p debian/debian-image-builder-frontend/etc/nginx/sites-available - mkdir -p debian/debian-image-builder-frontend/etc/cockpit - - # Copy built frontend files - if [ -d dist ]; then - cp -r dist/* debian/debian-image-builder-frontend/usr/share/debian-image-builder-frontend/ - elif [ -d build ]; then - cp -r build/* debian/debian-image-builder-frontend/usr/share/debian-image-builder-frontend/ - fi - - # Copy source files for development - cp -r src debian/debian-image-builder-frontend/usr/share/debian-image-builder-frontend/ - cp package.json debian/debian-image-builder-frontend/usr/share/debian-image-builder-frontend/ - - # Create nginx configuration - cat > debian/debian-image-builder-frontend/etc/nginx/sites-available/debian-image-builder-frontend << 'NGINX_EOF' -server { - listen 80; - server_name localhost; - root /usr/share/debian-image-builder-frontend; - index index.html; - - location / { - try_files \$uri \$uri/ /index.html; - } - - location /api/ { - proxy_pass http://localhost:8080/; - proxy_set_header Host \$host; - proxy_set_header X-Real-IP \$remote_addr; - } -} -NGINX_EOF - - # Create cockpit manifest - cat > debian/debian-image-builder-frontend/etc/cockpit/debian-image-builder.manifest << 'COCKPIT_EOF' -{ - "version": 1, - "manifest": { - "name": "debian-image-builder", - "version": "1.0.0", - "title": "Debian Image Builder", - "description": "Build and manage Debian atomic images", - "url": "/usr/share/debian-image-builder-frontend", - "icon": "debian-logo", - "requires": { - "cockpit": ">= 200" - } - } -} -COCKPIT_EOF -EOF - - cat > debian/changelog << EOF -debian-image-builder-frontend (1.0.0-1) unstable; urgency=medium - - * Initial release - * Debian Image Builder Frontend with Cockpit integration - * React-based web interface for image management - - -- Debian Forge Team $(date -R) -EOF - - cat > debian/compat << EOF -13 -EOF - - chmod +x debian/rules - - - name: Build Debian package - run: | - dpkg-buildpackage -us -uc -b - ls -la ../*.deb - - - name: Upload Debian package - uses: actions/upload-artifact@v4 - with: - name: debian-image-builder-frontend-deb - path: ../*.deb - retention-days: 30 - - cockpit-integration: - name: Test Cockpit Integration - runs-on: ubuntu-latest - container: - image: node:18-bullseye - needs: build-and-test - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js environment - run: | - node --version - npm --version - - - name: Install Node.js dependencies - run: npm ci - - - name: Test cockpit integration - run: | - echo "Testing Cockpit integration..." - if [ -d cockpit ]; then - echo "Cockpit directory found:" - ls -la cockpit/ - else - echo "No cockpit directory found" - fi - - if [ -f package.json ]; then - echo "Package.json scripts:" - npm run - fi diff --git a/cockpit/cockpit-image-builder.spec b/cockpit/cockpit-image-builder.spec index 2c739e91..85988df4 100644 --- a/cockpit/cockpit-image-builder.spec +++ b/cockpit/cockpit-image-builder.spec @@ -1,5 +1,5 @@ Name: cockpit-image-builder -Version: 76 +Version: 75 Release: 1%{?dist} Summary: Image builder plugin for Cockpit diff --git a/src/Components/Blueprints/BlueprintsSideBar.tsx b/src/Components/Blueprints/BlueprintsSideBar.tsx index 9422f8e3..6c1dd852 100644 --- a/src/Components/Blueprints/BlueprintsSideBar.tsx +++ b/src/Components/Blueprints/BlueprintsSideBar.tsx @@ -1,4 +1,4 @@ -import React, { useCallback } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { Bullseye, @@ -17,6 +17,7 @@ import { import { PlusCircleIcon, SearchIcon } from '@patternfly/react-icons'; import { SVGIconProps } from '@patternfly/react-icons/dist/esm/createIcon'; import useChrome from '@redhat-cloud-services/frontend-components/useChrome'; +import { ChromeUser } from '@redhat-cloud-services/types'; import debounce from 'lodash/debounce'; import { Link } from 'react-router-dom'; @@ -28,7 +29,6 @@ import { PAGINATION_LIMIT, PAGINATION_OFFSET, } from '../../constants'; -import { useGetUser } from '../../Hooks'; import { useGetBlueprintsQuery } from '../../store/backendApi'; import { selectBlueprintSearchInput, @@ -60,8 +60,8 @@ type emptyBlueprintStateProps = { }; const BlueprintsSidebar = () => { + const [userData, setUserData] = useState(undefined); const { analytics, auth } = useChrome(); - const { userData } = useGetUser(auth); const selectedBlueprintId = useAppSelector(selectSelectedBlueprintId); const blueprintSearchInput = useAppSelector(selectBlueprintSearchInput); @@ -73,6 +73,16 @@ const BlueprintsSidebar = () => { offset: blueprintsOffset, }; + useEffect(() => { + (async () => { + const data = await auth.getUser(); + setUserData(data); + })(); + // This useEffect hook should run *only* on mount and therefore has an empty + // dependency array. eslint's exhaustive-deps rule does not support this use. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + if (blueprintSearchInput) { searchParams.search = blueprintSearchInput; } diff --git a/src/Components/Blueprints/BuildImagesButton.tsx b/src/Components/Blueprints/BuildImagesButton.tsx index 431b765b..6304d98a 100644 --- a/src/Components/Blueprints/BuildImagesButton.tsx +++ b/src/Components/Blueprints/BuildImagesButton.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { Button, @@ -16,13 +16,11 @@ import { } from '@patternfly/react-core'; import { MenuToggleElement } from '@patternfly/react-core/dist/esm/components/MenuToggle/MenuToggle'; import useChrome from '@redhat-cloud-services/frontend-components/useChrome'; +import { ChromeUser } from '@redhat-cloud-services/types'; import { skipToken } from '@reduxjs/toolkit/query'; import { AMPLITUDE_MODULE_NAME, targetOptions } from '../../constants'; -import { - useComposeBPWithNotification as useComposeBlueprintMutation, - useGetUser, -} from '../../Hooks'; +import { useComposeBPWithNotification as useComposeBlueprintMutation } from '../../Hooks'; import { useGetBlueprintQuery } from '../../store/backendApi'; import { selectSelectedBlueprintId } from '../../store/BlueprintSlice'; import { useAppSelector } from '../../store/hooks'; @@ -39,7 +37,18 @@ export const BuildImagesButton = ({ children }: BuildImagesButtonPropTypes) => { const { trigger: buildBlueprint, isLoading: imageBuildLoading } = useComposeBlueprintMutation(); const { analytics, auth } = useChrome(); - const { userData } = useGetUser(auth); + + const [userData, setUserData] = useState(undefined); + + useEffect(() => { + (async () => { + const data = await auth.getUser(); + setUserData(data); + })(); + // This useEffect hook should run *only* on mount and therefore has an empty + // dependency array. eslint's exhaustive-deps rule does not support this use. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const onBuildHandler = async () => { if (selectedBlueprintId) { diff --git a/src/Components/Blueprints/DeleteBlueprintModal.tsx b/src/Components/Blueprints/DeleteBlueprintModal.tsx index 230deeed..afd209d5 100644 --- a/src/Components/Blueprints/DeleteBlueprintModal.tsx +++ b/src/Components/Blueprints/DeleteBlueprintModal.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { Button, @@ -9,16 +9,14 @@ import { ModalVariant, } from '@patternfly/react-core'; import useChrome from '@redhat-cloud-services/frontend-components/useChrome'; +import { ChromeUser } from '@redhat-cloud-services/types'; import { AMPLITUDE_MODULE_NAME, PAGINATION_LIMIT, PAGINATION_OFFSET, } from '../../constants'; -import { - useDeleteBPWithNotification as useDeleteBlueprintMutation, - useGetUser, -} from '../../Hooks'; +import { useDeleteBPWithNotification as useDeleteBlueprintMutation } from '../../Hooks'; import { backendApi, useGetBlueprintsQuery } from '../../store/backendApi'; import { selectBlueprintSearchInput, @@ -44,7 +42,17 @@ export const DeleteBlueprintModal: React.FunctionComponent< const blueprintsLimit = useAppSelector(selectLimit) || PAGINATION_LIMIT; const dispatch = useAppDispatch(); const { analytics, auth } = useChrome(); - const { userData } = useGetUser(auth); + const [userData, setUserData] = useState(undefined); + + useEffect(() => { + (async () => { + const data = await auth.getUser(); + setUserData(data); + })(); + // This useEffect hook should run *only* on mount and therefore has an empty + // dependency array. eslint's exhaustive-deps rule does not support this use. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const searchParams: GetBlueprintsApiArg = { limit: blueprintsLimit, diff --git a/src/Components/CreateImageWizard/steps/Registration/index.tsx b/src/Components/CreateImageWizard/steps/Registration/index.tsx index 081fd54e..bd96d505 100644 --- a/src/Components/CreateImageWizard/steps/Registration/index.tsx +++ b/src/Components/CreateImageWizard/steps/Registration/index.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { ClipboardCopy, @@ -16,7 +16,6 @@ import ActivationKeysList from './components/ActivationKeysList'; import Registration from './components/Registration'; import SatelliteRegistration from './components/SatelliteRegistration'; -import { useGetUser } from '../../../../Hooks'; import { useAppSelector } from '../../../../store/hooks'; import { selectActivationKey, @@ -25,7 +24,18 @@ import { const RegistrationStep = () => { const { auth } = useChrome(); - const { orgId } = useGetUser(auth); + const [orgId, setOrgId] = useState(undefined); + + useEffect(() => { + (async () => { + const userData = await auth.getUser(); + const id = userData?.identity?.internal?.org_id; + setOrgId(id); + })(); + // This useEffect hook should run *only* on mount and therefore has an empty + // dependency array. eslint's exhaustive-deps rule does not support this use. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const activationKey = useAppSelector(selectActivationKey); const registrationType = useAppSelector(selectRegistrationType); diff --git a/src/Components/CreateImageWizard/steps/Review/Footer/CreateDropdown.tsx b/src/Components/CreateImageWizard/steps/Review/Footer/CreateDropdown.tsx index ba26cfda..f05d4668 100644 --- a/src/Components/CreateImageWizard/steps/Review/Footer/CreateDropdown.tsx +++ b/src/Components/CreateImageWizard/steps/Review/Footer/CreateDropdown.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { Button, @@ -14,12 +14,12 @@ import { Spinner, } from '@patternfly/react-core'; import useChrome from '@redhat-cloud-services/frontend-components/useChrome'; +import { ChromeUser } from '@redhat-cloud-services/types'; import { AMPLITUDE_MODULE_NAME } from '../../../../../constants'; import { useComposeBPWithNotification as useComposeBlueprintMutation, useCreateBPWithNotification as useCreateBlueprintMutation, - useGetUser, } from '../../../../../Hooks'; import { setBlueprintId } from '../../../../../store/BlueprintSlice'; import { CockpitCreateBlueprintRequest } from '../../../../../store/cockpit/types'; @@ -44,8 +44,19 @@ export const CreateSaveAndBuildBtn = ({ setIsOpen, isDisabled, }: CreateDropdownProps) => { + const [userData, setUserData] = useState(undefined); + const { analytics, auth, isBeta } = useChrome(); - const { userData } = useGetUser(auth); + + useEffect(() => { + (async () => { + const data = await auth.getUser(); + setUserData(data); + })(); + // This useEffect hook should run *only* on mount and therefore has an empty + // dependency array. eslint's exhaustive-deps rule does not support this use. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const packages = useAppSelector(selectPackages); @@ -102,7 +113,17 @@ export const CreateSaveButton = ({ isDisabled, }: CreateDropdownProps) => { const { analytics, auth, isBeta } = useChrome(); - const { userData } = useGetUser(auth); + const [userData, setUserData] = useState(undefined); + + useEffect(() => { + (async () => { + const data = await auth.getUser(); + setUserData(data); + })(); + // This useEffect hook should run *only* on mount and therefore has an empty + // dependency array. eslint's exhaustive-deps rule does not support this use. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const packages = useAppSelector(selectPackages); diff --git a/src/Components/CreateImageWizard/steps/Review/Footer/EditDropdown.tsx b/src/Components/CreateImageWizard/steps/Review/Footer/EditDropdown.tsx index 6cc19cc3..cc025a9f 100644 --- a/src/Components/CreateImageWizard/steps/Review/Footer/EditDropdown.tsx +++ b/src/Components/CreateImageWizard/steps/Review/Footer/EditDropdown.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { DropdownItem, @@ -9,11 +9,11 @@ import { Spinner, } from '@patternfly/react-core'; import useChrome from '@redhat-cloud-services/frontend-components/useChrome'; +import { ChromeUser } from '@redhat-cloud-services/types'; import { AMPLITUDE_MODULE_NAME } from '../../../../../constants'; import { useComposeBPWithNotification as useComposeBlueprintMutation, - useGetUser, useUpdateBPWithNotification as useUpdateBlueprintMutation, } from '../../../../../Hooks'; import { CockpitCreateBlueprintRequest } from '../../../../../store/cockpit/types'; @@ -37,8 +37,19 @@ export const EditSaveAndBuildBtn = ({ blueprintId, isDisabled, }: EditDropdownProps) => { + const [userData, setUserData] = useState(undefined); + const { analytics, auth, isBeta } = useChrome(); - const { userData } = useGetUser(auth); + + useEffect(() => { + (async () => { + const data = await auth.getUser(); + setUserData(data); + })(); + // This useEffect hook should run *only* on mount and therefore has an empty + // dependency array. eslint's exhaustive-deps rule does not support this use. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const { trigger: buildBlueprint } = useComposeBlueprintMutation(); const packages = useAppSelector(selectPackages); @@ -94,8 +105,19 @@ export const EditSaveButton = ({ blueprintId, isDisabled, }: EditDropdownProps) => { + const [userData, setUserData] = useState(undefined); + const { analytics, auth, isBeta } = useChrome(); - const { userData } = useGetUser(auth); + + useEffect(() => { + (async () => { + const data = await auth.getUser(); + setUserData(data); + })(); + // This useEffect hook should run *only* on mount and therefore has an empty + // dependency array. eslint's exhaustive-deps rule does not support this use. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const packages = useAppSelector(selectPackages); diff --git a/src/Components/CreateImageWizard/steps/Review/Footer/Footer.tsx b/src/Components/CreateImageWizard/steps/Review/Footer/Footer.tsx index f6a35745..c12d590f 100644 --- a/src/Components/CreateImageWizard/steps/Review/Footer/Footer.tsx +++ b/src/Components/CreateImageWizard/steps/Review/Footer/Footer.tsx @@ -18,7 +18,6 @@ import { EditSaveAndBuildBtn, EditSaveButton } from './EditDropdown'; import { useCreateBPWithNotification as useCreateBlueprintMutation, - useGetUser, useUpdateBPWithNotification as useUpdateBlueprintMutation, } from '../../../../../Hooks'; import { resolveRelPath } from '../../../../../Utilities/path'; @@ -34,7 +33,6 @@ const ReviewWizardFooter = () => { const { isSuccess: isUpdateSuccess, reset: resetUpdate } = useUpdateBlueprintMutation({ fixedCacheKey: 'updateBlueprintKey' }); const { auth } = useChrome(); - const { orgId } = useGetUser(auth); const { composeId } = useParams(); const [isOpen, setIsOpen] = useState(false); const store = useStore(); @@ -54,12 +52,14 @@ const ReviewWizardFooter = () => { const getBlueprintPayload = async () => { if (!process.env.IS_ON_PREMISE) { + const userData = await auth.getUser(); + const orgId = userData?.identity?.internal?.org_id; const requestBody = orgId && mapRequestFromState(store, orgId); return requestBody; } - // NOTE: This is fine for on prem because we save the org id - // to state through a form field in the registration step + // NOTE: This should be fine on-prem, we should + // be able to ignore the `org-id` return mapRequestFromState(store, ''); }; diff --git a/src/Components/ImagesTable/ImageDetails.tsx b/src/Components/ImagesTable/ImageDetails.tsx index 21b8a0db..809b0394 100644 --- a/src/Components/ImagesTable/ImageDetails.tsx +++ b/src/Components/ImagesTable/ImageDetails.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { Alert, @@ -13,11 +13,11 @@ import { } from '@patternfly/react-core'; import { ExternalLinkAltIcon } from '@patternfly/react-icons'; import useChrome from '@redhat-cloud-services/frontend-components/useChrome'; +import { ChromeUser } from '@redhat-cloud-services/types'; import ClonesTable from './ClonesTable'; import { AMPLITUDE_MODULE_NAME } from '../../constants'; -import { useGetUser } from '../../Hooks'; import { useGetComposeStatusQuery } from '../../store/backendApi'; import { extractProvisioningList } from '../../store/helpers'; import { @@ -134,9 +134,19 @@ type AwsDetailsPropTypes = { export const AwsDetails = ({ compose }: AwsDetailsPropTypes) => { const options = compose.request.image_requests[0].upload_request.options; + const [userData, setUserData] = useState(undefined); const { analytics, auth } = useChrome(); - const { userData } = useGetUser(auth); + + useEffect(() => { + (async () => { + const data = await auth.getUser(); + setUserData(data); + })(); + // This useEffect hook should run *only* on mount and therefore has an empty + // dependency array. eslint's exhaustive-deps rule does not support this use. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); if (!isAwsUploadRequestOptions(options)) { throw TypeError( diff --git a/src/Components/ImagesTable/ImagesTable.tsx b/src/Components/ImagesTable/ImagesTable.tsx index 69af395c..8c9118a1 100644 --- a/src/Components/ImagesTable/ImagesTable.tsx +++ b/src/Components/ImagesTable/ImagesTable.tsx @@ -25,6 +25,7 @@ import { Tr, } from '@patternfly/react-table'; import useChrome from '@redhat-cloud-services/frontend-components/useChrome'; +import { ChromeUser } from '@redhat-cloud-services/types'; import { useFlag } from '@unleash/proxy-client-react'; import { useDispatch } from 'react-redux'; import { NavigateFunction, useNavigate } from 'react-router-dom'; @@ -58,7 +59,6 @@ import { SEARCH_INPUT, STATUS_POLLING_INTERVAL, } from '../../constants'; -import { useGetUser } from '../../Hooks'; import { useGetBlueprintComposesQuery, useGetBlueprintsQuery, @@ -94,6 +94,7 @@ import { OciLaunchModal } from '../Launch/OciLaunchModal'; const ImagesTable = () => { const [page, setPage] = useState(1); const [perPage, setPerPage] = useState(10); + const [userData, setUserData] = useState(undefined); const selectedBlueprintId = useAppSelector(selectSelectedBlueprintId); const blueprintSearchInput = @@ -106,7 +107,16 @@ const ImagesTable = () => { const blueprintsLimit = useAppSelector(selectLimit) || PAGINATION_LIMIT; const { analytics, auth } = useChrome(); - const { userData } = useGetUser(auth); + + useEffect(() => { + (async () => { + const data = await auth.getUser(); + setUserData(data); + })(); + // This useEffect hook should run *only* on mount and therefore has an empty + // dependency array. eslint's exhaustive-deps rule does not support this use. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const searchParamsGetBlueprints: GetBlueprintsApiArg = { limit: blueprintsLimit, @@ -471,8 +481,18 @@ type AwsRowPropTypes = { const AwsRow = ({ compose, composeStatus, rowIndex }: AwsRowPropTypes) => { const navigate = useNavigate(); + const [userData, setUserData] = useState(undefined); const { analytics, auth } = useChrome(); - const { userData } = useGetUser(auth); + + useEffect(() => { + (async () => { + const data = await auth.getUser(); + setUserData(data); + })(); + // This useEffect hook should run *only* on mount and therefore has an empty + // dependency array. eslint's exhaustive-deps rule does not support this use. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const target = ; const status = ; @@ -547,8 +567,18 @@ const Row = ({ details, instance, }: RowPropTypes) => { + const [userData, setUserData] = useState(undefined); const { analytics, auth } = useChrome(); - const { userData } = useGetUser(auth); + + useEffect(() => { + (async () => { + const data = await auth.getUser(); + setUserData(data); + })(); + // This useEffect hook should run *only* on mount and therefore has an empty + // dependency array. eslint's exhaustive-deps rule does not support this use. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const [isExpanded, setIsExpanded] = useState(false); const handleToggle = () => setIsExpanded(!isExpanded); diff --git a/src/Components/ImagesTable/Instance.tsx b/src/Components/ImagesTable/Instance.tsx index 254f0b05..4af6f5e9 100644 --- a/src/Components/ImagesTable/Instance.tsx +++ b/src/Components/ImagesTable/Instance.tsx @@ -1,4 +1,4 @@ -import React, { Suspense, useState } from 'react'; +import React, { Suspense, useEffect, useState } from 'react'; import path from 'path'; @@ -20,6 +20,7 @@ import { } from '@patternfly/react-core/dist/esm/components/List/List'; import { ExternalLinkAltIcon } from '@patternfly/react-icons'; import useChrome from '@redhat-cloud-services/frontend-components/useChrome'; +import { ChromeUser } from '@redhat-cloud-services/types'; import { useLoadModule, useScalprum } from '@scalprum/react-core'; import cockpit from 'cockpit'; import { useNavigate } from 'react-router-dom'; @@ -30,7 +31,6 @@ import { MODAL_ANCHOR, SEARCH_INPUT, } from '../../constants'; -import { useGetUser } from '../../Hooks'; import { useGetBlueprintsQuery, useGetComposeStatusQuery, @@ -101,9 +101,19 @@ const ProvisioningLink = ({ composeStatus, }: ProvisioningLinkPropTypes) => { const launchEofFlag = useFlag('image-builder.launcheof'); + const [userData, setUserData] = useState(undefined); const { analytics, auth } = useChrome(); - const { userData } = useGetUser(auth); + + useEffect(() => { + (async () => { + const data = await auth.getUser(); + setUserData(data); + })(); + // This useEffect hook should run *only* on mount and therefore has an empty + // dependency array. eslint's exhaustive-deps rule does not support this use. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const [isModalOpen, setIsModalOpen] = useState(false); const [exposedScalprumModule, error] = useLoadModule( diff --git a/src/Components/ImagesTable/Status.tsx b/src/Components/ImagesTable/Status.tsx index fbe08ceb..b3c4ca8a 100644 --- a/src/Components/ImagesTable/Status.tsx +++ b/src/Components/ImagesTable/Status.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import './ImageBuildStatus.scss'; import { @@ -24,13 +24,13 @@ import { PendingIcon, } from '@patternfly/react-icons'; import useChrome from '@redhat-cloud-services/frontend-components/useChrome'; +import { ChromeUser } from '@redhat-cloud-services/types'; import { AMPLITUDE_MODULE_NAME, AWS_S3_EXPIRATION_TIME_IN_HOURS, OCI_STORAGE_EXPIRATION_TIME_IN_DAYS, } from '../../constants'; -import { useGetUser } from '../../Hooks'; import { useGetComposeStatusQuery } from '../../store/backendApi'; import { CockpitComposesResponseItem } from '../../store/cockpit/types'; import { @@ -122,8 +122,18 @@ export const CloudStatus = ({ compose }: CloudStatusPropTypes) => { const { data, isSuccess } = useGetComposeStatusQuery({ composeId: compose.id, }); + const [userData, setUserData] = useState(undefined); const { analytics, auth } = useChrome(); - const { userData } = useGetUser(auth); + + useEffect(() => { + (async () => { + const data = await auth.getUser(); + setUserData(data); + })(); + // This useEffect hook should run *only* on mount and therefore has an empty + // dependency array. eslint's exhaustive-deps rule does not support this use. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); if (!isSuccess) { return ; diff --git a/src/Components/ShareImageModal/RegionsSelect.tsx b/src/Components/ShareImageModal/RegionsSelect.tsx index abd20390..13ca0dcc 100644 --- a/src/Components/ShareImageModal/RegionsSelect.tsx +++ b/src/Components/ShareImageModal/RegionsSelect.tsx @@ -156,7 +156,7 @@ const RegionsSelect = ({ composeId, handleClose }: RegionsSelectPropTypes) => { diff --git a/src/Hooks/index.tsx b/src/Hooks/index.tsx index cb2f6aef..df6abc94 100644 --- a/src/Hooks/index.tsx +++ b/src/Hooks/index.tsx @@ -4,4 +4,3 @@ export { useDeleteBPWithNotification } from './MutationNotifications/useDeleteBP export { useFixupBPWithNotification } from './MutationNotifications/useFixupBPWithNotification'; export { useComposeBPWithNotification } from './MutationNotifications/useComposeBPWithNotification'; export { useCloneComposeWithNotification } from './MutationNotifications/useCloneComposeWithNotification'; -export { useGetUser } from './useGetUser'; diff --git a/src/Hooks/useGetUser.tsx b/src/Hooks/useGetUser.tsx deleted file mode 100644 index 445bdf22..00000000 --- a/src/Hooks/useGetUser.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { useEffect, useState } from 'react'; - -import { ChromeUser } from '@redhat-cloud-services/types'; - -export const useGetUser = (auth: { getUser(): Promise }) => { - const [userData, setUserData] = useState(undefined); - const [orgId, setOrgId] = useState(undefined); - - useEffect(() => { - (async () => { - if (!process.env.IS_ON_PREMISE) { - const data = await auth.getUser(); - const id = data?.identity.internal?.org_id; - setUserData(data); - setOrgId(id); - } - })(); - // This useEffect hook should run *only* on mount and therefore has an empty - // dependency array. eslint's exhaustive-deps rule does not support this use. - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - return { userData, orgId }; -};