Compare commits
4 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
080513ad6d | ||
|
|
7391652e17 | ||
|
|
9a17373234 | ||
|
|
d7f844b8b6 |
17 changed files with 584 additions and 185 deletions
257
.forgejo/workflows/ci.yml
Normal file
257
.forgejo/workflows/ci.yml
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
---
|
||||
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 <team@debian-forge.org>
|
||||
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 <team@debian-forge.org> $(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
|
||||
257
.forgejo/workflows/ci.yml.disabled
Normal file
257
.forgejo/workflows/ci.yml.disabled
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
---
|
||||
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 <team@debian-forge.org>
|
||||
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 <team@debian-forge.org> $(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
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
Name: cockpit-image-builder
|
||||
Version: 75
|
||||
Version: 76
|
||||
Release: 1%{?dist}
|
||||
Summary: Image builder plugin for Cockpit
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import {
|
||||
Bullseye,
|
||||
|
|
@ -17,7 +17,6 @@ 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';
|
||||
|
||||
|
|
@ -29,6 +28,7 @@ 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<ChromeUser | void>(undefined);
|
||||
const { analytics, auth } = useChrome();
|
||||
const { userData } = useGetUser(auth);
|
||||
|
||||
const selectedBlueprintId = useAppSelector(selectSelectedBlueprintId);
|
||||
const blueprintSearchInput = useAppSelector(selectBlueprintSearchInput);
|
||||
|
|
@ -73,16 +73,6 @@ 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import {
|
||||
Button,
|
||||
|
|
@ -16,11 +16,13 @@ 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 } from '../../Hooks';
|
||||
import {
|
||||
useComposeBPWithNotification as useComposeBlueprintMutation,
|
||||
useGetUser,
|
||||
} from '../../Hooks';
|
||||
import { useGetBlueprintQuery } from '../../store/backendApi';
|
||||
import { selectSelectedBlueprintId } from '../../store/BlueprintSlice';
|
||||
import { useAppSelector } from '../../store/hooks';
|
||||
|
|
@ -37,18 +39,7 @@ export const BuildImagesButton = ({ children }: BuildImagesButtonPropTypes) => {
|
|||
const { trigger: buildBlueprint, isLoading: imageBuildLoading } =
|
||||
useComposeBlueprintMutation();
|
||||
const { analytics, auth } = useChrome();
|
||||
|
||||
const [userData, setUserData] = useState<ChromeUser | void>(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 { userData } = useGetUser(auth);
|
||||
|
||||
const onBuildHandler = async () => {
|
||||
if (selectedBlueprintId) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
Button,
|
||||
|
|
@ -9,14 +9,16 @@ 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 } from '../../Hooks';
|
||||
import {
|
||||
useDeleteBPWithNotification as useDeleteBlueprintMutation,
|
||||
useGetUser,
|
||||
} from '../../Hooks';
|
||||
import { backendApi, useGetBlueprintsQuery } from '../../store/backendApi';
|
||||
import {
|
||||
selectBlueprintSearchInput,
|
||||
|
|
@ -42,17 +44,7 @@ export const DeleteBlueprintModal: React.FunctionComponent<
|
|||
const blueprintsLimit = useAppSelector(selectLimit) || PAGINATION_LIMIT;
|
||||
const dispatch = useAppDispatch();
|
||||
const { analytics, auth } = useChrome();
|
||||
const [userData, setUserData] = useState<ChromeUser | void>(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 { userData } = useGetUser(auth);
|
||||
|
||||
const searchParams: GetBlueprintsApiArg = {
|
||||
limit: blueprintsLimit,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
ClipboardCopy,
|
||||
|
|
@ -16,6 +16,7 @@ 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,
|
||||
|
|
@ -24,18 +25,7 @@ import {
|
|||
|
||||
const RegistrationStep = () => {
|
||||
const { auth } = useChrome();
|
||||
const [orgId, setOrgId] = useState<string | undefined>(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 { orgId } = useGetUser(auth);
|
||||
|
||||
const activationKey = useAppSelector(selectActivationKey);
|
||||
const registrationType = useAppSelector(selectRegistrationType);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import React, { 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,19 +44,8 @@ export const CreateSaveAndBuildBtn = ({
|
|||
setIsOpen,
|
||||
isDisabled,
|
||||
}: CreateDropdownProps) => {
|
||||
const [userData, setUserData] = useState<ChromeUser | void>(undefined);
|
||||
|
||||
const { analytics, auth, isBeta } = useChrome();
|
||||
|
||||
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 { userData } = useGetUser(auth);
|
||||
|
||||
const packages = useAppSelector(selectPackages);
|
||||
|
||||
|
|
@ -113,17 +102,7 @@ export const CreateSaveButton = ({
|
|||
isDisabled,
|
||||
}: CreateDropdownProps) => {
|
||||
const { analytics, auth, isBeta } = useChrome();
|
||||
const [userData, setUserData] = useState<ChromeUser | void>(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 { userData } = useGetUser(auth);
|
||||
|
||||
const packages = useAppSelector(selectPackages);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import React 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,19 +37,8 @@ export const EditSaveAndBuildBtn = ({
|
|||
blueprintId,
|
||||
isDisabled,
|
||||
}: EditDropdownProps) => {
|
||||
const [userData, setUserData] = useState<ChromeUser | void>(undefined);
|
||||
|
||||
const { analytics, auth, isBeta } = useChrome();
|
||||
|
||||
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 { userData } = useGetUser(auth);
|
||||
|
||||
const { trigger: buildBlueprint } = useComposeBlueprintMutation();
|
||||
const packages = useAppSelector(selectPackages);
|
||||
|
|
@ -105,19 +94,8 @@ export const EditSaveButton = ({
|
|||
blueprintId,
|
||||
isDisabled,
|
||||
}: EditDropdownProps) => {
|
||||
const [userData, setUserData] = useState<ChromeUser | void>(undefined);
|
||||
|
||||
const { analytics, auth, isBeta } = useChrome();
|
||||
|
||||
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 { userData } = useGetUser(auth);
|
||||
|
||||
const packages = useAppSelector(selectPackages);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import { EditSaveAndBuildBtn, EditSaveButton } from './EditDropdown';
|
|||
|
||||
import {
|
||||
useCreateBPWithNotification as useCreateBlueprintMutation,
|
||||
useGetUser,
|
||||
useUpdateBPWithNotification as useUpdateBlueprintMutation,
|
||||
} from '../../../../../Hooks';
|
||||
import { resolveRelPath } from '../../../../../Utilities/path';
|
||||
|
|
@ -33,6 +34,7 @@ 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();
|
||||
|
|
@ -52,14 +54,12 @@ 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 should be fine on-prem, we should
|
||||
// be able to ignore the `org-id`
|
||||
// NOTE: This is fine for on prem because we save the org id
|
||||
// to state through a form field in the registration step
|
||||
return mapRequestFromState(store, '');
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import React 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,19 +134,9 @@ type AwsDetailsPropTypes = {
|
|||
|
||||
export const AwsDetails = ({ compose }: AwsDetailsPropTypes) => {
|
||||
const options = compose.request.image_requests[0].upload_request.options;
|
||||
const [userData, setUserData] = useState<ChromeUser | void>(undefined);
|
||||
|
||||
const { analytics, auth } = useChrome();
|
||||
|
||||
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 { userData } = useGetUser(auth);
|
||||
|
||||
if (!isAwsUploadRequestOptions(options)) {
|
||||
throw TypeError(
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ 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';
|
||||
|
|
@ -59,6 +58,7 @@ import {
|
|||
SEARCH_INPUT,
|
||||
STATUS_POLLING_INTERVAL,
|
||||
} from '../../constants';
|
||||
import { useGetUser } from '../../Hooks';
|
||||
import {
|
||||
useGetBlueprintComposesQuery,
|
||||
useGetBlueprintsQuery,
|
||||
|
|
@ -94,7 +94,6 @@ import { OciLaunchModal } from '../Launch/OciLaunchModal';
|
|||
const ImagesTable = () => {
|
||||
const [page, setPage] = useState(1);
|
||||
const [perPage, setPerPage] = useState(10);
|
||||
const [userData, setUserData] = useState<ChromeUser | void>(undefined);
|
||||
|
||||
const selectedBlueprintId = useAppSelector(selectSelectedBlueprintId);
|
||||
const blueprintSearchInput =
|
||||
|
|
@ -107,16 +106,7 @@ const ImagesTable = () => {
|
|||
const blueprintsLimit = useAppSelector(selectLimit) || PAGINATION_LIMIT;
|
||||
|
||||
const { analytics, auth } = useChrome();
|
||||
|
||||
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 { userData } = useGetUser(auth);
|
||||
|
||||
const searchParamsGetBlueprints: GetBlueprintsApiArg = {
|
||||
limit: blueprintsLimit,
|
||||
|
|
@ -481,18 +471,8 @@ type AwsRowPropTypes = {
|
|||
|
||||
const AwsRow = ({ compose, composeStatus, rowIndex }: AwsRowPropTypes) => {
|
||||
const navigate = useNavigate();
|
||||
const [userData, setUserData] = useState<ChromeUser | void>(undefined);
|
||||
const { analytics, auth } = useChrome();
|
||||
|
||||
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 { userData } = useGetUser(auth);
|
||||
|
||||
const target = <AwsTarget compose={compose} />;
|
||||
const status = <CloudStatus compose={compose} />;
|
||||
|
|
@ -567,18 +547,8 @@ const Row = ({
|
|||
details,
|
||||
instance,
|
||||
}: RowPropTypes) => {
|
||||
const [userData, setUserData] = useState<ChromeUser | void>(undefined);
|
||||
const { analytics, auth } = useChrome();
|
||||
|
||||
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 { userData } = useGetUser(auth);
|
||||
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
const handleToggle = () => setIsExpanded(!isExpanded);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { Suspense, useEffect, useState } from 'react';
|
||||
import React, { Suspense, useState } from 'react';
|
||||
|
||||
import path from 'path';
|
||||
|
||||
|
|
@ -20,7 +20,6 @@ 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';
|
||||
|
|
@ -31,6 +30,7 @@ import {
|
|||
MODAL_ANCHOR,
|
||||
SEARCH_INPUT,
|
||||
} from '../../constants';
|
||||
import { useGetUser } from '../../Hooks';
|
||||
import {
|
||||
useGetBlueprintsQuery,
|
||||
useGetComposeStatusQuery,
|
||||
|
|
@ -101,19 +101,9 @@ const ProvisioningLink = ({
|
|||
composeStatus,
|
||||
}: ProvisioningLinkPropTypes) => {
|
||||
const launchEofFlag = useFlag('image-builder.launcheof');
|
||||
const [userData, setUserData] = useState<ChromeUser | void>(undefined);
|
||||
|
||||
const { analytics, auth } = useChrome();
|
||||
|
||||
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 { userData } = useGetUser(auth);
|
||||
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [exposedScalprumModule, error] = useLoadModule(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import React 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,18 +122,8 @@ export const CloudStatus = ({ compose }: CloudStatusPropTypes) => {
|
|||
const { data, isSuccess } = useGetComposeStatusQuery({
|
||||
composeId: compose.id,
|
||||
});
|
||||
const [userData, setUserData] = useState<ChromeUser | void>(undefined);
|
||||
const { analytics, auth } = useChrome();
|
||||
|
||||
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 { userData } = useGetUser(auth);
|
||||
|
||||
if (!isSuccess) {
|
||||
return <Skeleton />;
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ const RegionsSelect = ({ composeId, handleClose }: RegionsSelectPropTypes) => {
|
|||
<MenuToggle
|
||||
variant='typeahead'
|
||||
onClick={handleToggle}
|
||||
innerRef={toggleRef}
|
||||
ref={toggleRef}
|
||||
isExpanded={isOpen}
|
||||
>
|
||||
<TextInputGroup isPlain>
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@ export { useDeleteBPWithNotification } from './MutationNotifications/useDeleteBP
|
|||
export { useFixupBPWithNotification } from './MutationNotifications/useFixupBPWithNotification';
|
||||
export { useComposeBPWithNotification } from './MutationNotifications/useComposeBPWithNotification';
|
||||
export { useCloneComposeWithNotification } from './MutationNotifications/useCloneComposeWithNotification';
|
||||
export { useGetUser } from './useGetUser';
|
||||
|
|
|
|||
24
src/Hooks/useGetUser.tsx
Normal file
24
src/Hooks/useGetUser.tsx
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { ChromeUser } from '@redhat-cloud-services/types';
|
||||
|
||||
export const useGetUser = (auth: { getUser(): Promise<void | ChromeUser> }) => {
|
||||
const [userData, setUserData] = useState<ChromeUser | void>(undefined);
|
||||
const [orgId, setOrgId] = useState<string | undefined>(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 };
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue