diff --git a/frontend/resourceadm/components/ResourceAdmHeader/ResourceAdmHeader.tsx b/frontend/resourceadm/components/ResourceAdmHeader/ResourceAdmHeader.tsx
index ff7c2ae54e6..ef2a6fee178 100644
--- a/frontend/resourceadm/components/ResourceAdmHeader/ResourceAdmHeader.tsx
+++ b/frontend/resourceadm/components/ResourceAdmHeader/ResourceAdmHeader.tsx
@@ -1,4 +1,5 @@
import React from 'react';
+import classes from './ResourceAdmHeader.module.css';
import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import {
@@ -15,6 +16,7 @@ import { useLogoutMutation } from 'app-shared/hooks/mutations/useLogoutMutation'
import type { User } from 'app-shared/types/Repository';
import { useUrlParams } from '../../hooks/useUrlParams';
import { getAppName } from '../../utils/stringUtils';
+import { GiteaHeader } from 'app-shared/components/GiteaHeader';
interface ResourceAdmHeaderProps {
organizations: Organization[];
@@ -34,6 +36,9 @@ export const ResourceAdmHeader = ({ organizations, user }: ResourceAdmHeaderProp
+
+
+
);
};
diff --git a/frontend/resourceadm/pages/PageLayout/PageLayout.module.css b/frontend/resourceadm/components/ResourceAdmHeader/ResourceaAdmHeader.module.css
similarity index 100%
rename from frontend/resourceadm/pages/PageLayout/PageLayout.module.css
rename to frontend/resourceadm/components/ResourceAdmHeader/ResourceaAdmHeader.module.css
diff --git a/frontend/resourceadm/context/HeaderContext/HeaderContext.tsx b/frontend/resourceadm/context/HeaderContext/HeaderContext.tsx
new file mode 100644
index 00000000000..b919d6f9912
--- /dev/null
+++ b/frontend/resourceadm/context/HeaderContext/HeaderContext.tsx
@@ -0,0 +1,19 @@
+import React from 'react';
+import { type Organization } from 'app-shared/types/Organization';
+import { type User } from 'app-shared/types/Repository';
+
+export enum SelectedContextType {
+ All = 'all',
+ Self = 'self',
+ None = 'none',
+}
+
+export type HeaderContextType = {
+ selectableOrgs?: Organization[];
+ user: User;
+};
+
+export const HeaderContext = React.createContext({
+ selectableOrgs: undefined,
+ user: undefined,
+});
diff --git a/frontend/resourceadm/context/HeaderContext/index.ts b/frontend/resourceadm/context/HeaderContext/index.ts
new file mode 100644
index 00000000000..ec5587f9307
--- /dev/null
+++ b/frontend/resourceadm/context/HeaderContext/index.ts
@@ -0,0 +1 @@
+export { HeaderContext, type HeaderContextType, SelectedContextType } from './HeaderContext';
diff --git a/frontend/resourceadm/pages/PageLayout/PageLayout.tsx b/frontend/resourceadm/pages/PageLayout/PageLayout.tsx
index 76600ed2b19..9ce62c6d9a4 100644
--- a/frontend/resourceadm/pages/PageLayout/PageLayout.tsx
+++ b/frontend/resourceadm/pages/PageLayout/PageLayout.tsx
@@ -1,10 +1,8 @@
import React, { useEffect, useRef } from 'react';
-import classes from './PageLayout.module.css';
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
import { userHasAccessToOrganization } from '../../utils/userUtils';
import { useOrganizationsQuery } from '../../hooks/queries';
import { useRepoStatusQuery, useUserQuery } from 'app-shared/hooks/queries';
-import { GiteaHeader } from 'app-shared/components/GiteaHeader';
import { useUrlParams } from '../../hooks/useUrlParams';
import postMessages from 'app-shared/utils/postMessages';
import { MergeConflictModal } from '../../components/MergeConflictModal';
@@ -63,7 +61,6 @@ export const PageLayout = (): React.JSX.Element => {
<>
{organizations && user && }
-
>
);
diff --git a/frontend/resourceadm/utils/userUtils/userUtils.test.ts b/frontend/resourceadm/utils/userUtils/userUtils.test.ts
index 081c8e62100..da463685fd7 100644
--- a/frontend/resourceadm/utils/userUtils/userUtils.test.ts
+++ b/frontend/resourceadm/utils/userUtils/userUtils.test.ts
@@ -1,60 +1,106 @@
-import { SelectedContextType } from 'app-shared/navigation/main-header/Header';
-import { userHasAccessToOrganization } from './index';
+import { SelectedContextType } from 'resourceadm/context/HeaderContext';
+import { getOrgNameByUsername, userHasAccessToOrganization } from './userUtils';
+import { type Organization } from 'app-shared/types/Organization';
-describe('userHasAccessToOrganization', () => {
- it('should return true when context is self', () => {
- const result = userHasAccessToOrganization({
- org: SelectedContextType.Self,
- orgs: [],
+const mockOrg1: Organization = {
+ avatar_url: '',
+ id: 12,
+ username: 'ttd',
+ full_name: 'Test',
+};
+const mockOrg2: Organization = {
+ avatar_url: '',
+ id: 23,
+ username: 'unit-test-2',
+ full_name: 'unit-test-2',
+};
+const mockOrganizations: Organization[] = [mockOrg1, mockOrg2];
+
+describe('userUtils', () => {
+ describe('userHasAccessToOrganization', () => {
+ it('should return true when context is self', () => {
+ const result = userHasAccessToOrganization({
+ org: SelectedContextType.Self,
+ orgs: [],
+ });
+
+ expect(result).toBe(true);
});
- expect(result).toBe(true);
- });
+ it('should return true when context is all', () => {
+ const result = userHasAccessToOrganization({
+ org: SelectedContextType.All,
+ orgs: [],
+ });
- it('should return true when context is all', () => {
- const result = userHasAccessToOrganization({
- org: SelectedContextType.All,
- orgs: [],
+ expect(result).toBe(true);
});
- expect(result).toBe(true);
- });
+ it('should return true when context id is present in orgs list', () => {
+ const result = userHasAccessToOrganization({
+ org: 'username1',
+ orgs: [
+ {
+ avatar_url: 'avatar_url',
+ description: '',
+ full_name: 'full_name',
+ id: 1,
+ location: '',
+ username: 'username1',
+ website: '',
+ },
+ ],
+ });
- it('should return true when context id is present in orgs list', () => {
- const result = userHasAccessToOrganization({
- org: 'username1',
- orgs: [
- {
- avatar_url: 'avatar_url',
- description: '',
- full_name: 'full_name',
- id: 1,
- location: '',
- username: 'username1',
- website: '',
- },
- ],
- });
-
- expect(result).toBe(true);
+ expect(result).toBe(true);
+ });
+
+ it('should return false when context id is not present in orgs list', () => {
+ const result = userHasAccessToOrganization({
+ org: 'username2',
+ orgs: [
+ {
+ avatar_url: 'avatar_url',
+ description: '',
+ full_name: 'full_name',
+ id: 1,
+ location: '',
+ username: 'username',
+ website: '',
+ },
+ ],
+ });
+
+ expect(result).toBe(false);
+ });
});
- it('should return false when context id is not present in orgs list', () => {
- const result = userHasAccessToOrganization({
- org: 'username2',
- orgs: [
- {
- avatar_url: 'avatar_url',
- description: '',
- full_name: 'full_name',
- id: 1,
- location: '',
- username: 'username',
- website: '',
- },
- ],
- });
-
- expect(result).toBe(false);
+ describe('getOrgNameByUsername', () => {
+ it('should return the full name of the organization when a matching username is found', () => {
+ const result = getOrgNameByUsername(mockOrg1.username, mockOrganizations);
+ expect(result).toBe(mockOrg1.full_name);
+ });
+
+ it('should return the username if full name is not available', () => {
+ const mockOrg3: Organization = {
+ username: 'org3',
+ full_name: '',
+ id: 12,
+ avatar_url: '',
+ };
+ const orgsWithoutFullName: Organization[] = [mockOrg3];
+ const result = getOrgNameByUsername(mockOrg3.username, orgsWithoutFullName);
+ expect(result).toBe(mockOrg3.username);
+ });
+
+ it('should return undefined if the organization is not found', () => {
+ const result = getOrgNameByUsername('nonexistent-org', mockOrganizations);
+ expect(result).toBeUndefined();
+ });
+
+ it('should return undefined if orgs array is undefined', () => {
+ const result = getOrgNameByUsername(mockOrg1.username, undefined);
+ expect(result).toBeUndefined();
+ });
});
});
diff --git a/frontend/resourceadm/utils/userUtils/userUtils.ts b/frontend/resourceadm/utils/userUtils/userUtils.ts
index 9373106c2b9..3ca2ede3737 100644
--- a/frontend/resourceadm/utils/userUtils/userUtils.ts
+++ b/frontend/resourceadm/utils/userUtils/userUtils.ts
@@ -1,4 +1,4 @@
-import { SelectedContextType } from 'app-shared/navigation/main-header/Header';
+import { SelectedContextType } from 'resourceadm/context/HeaderContext';
import type { Organization } from 'app-shared/types/Organization';
export const userHasAccessToOrganization = ({