Pull brand name from default.strings.json

This commit is contained in:
mabashian
2021-06-08 13:33:10 -04:00
parent e4f21ec294
commit 9e657059f3
20 changed files with 119 additions and 45 deletions

View File

@@ -37,7 +37,6 @@
name="description"
content="AWX"
/>
<title>AWX</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

View File

@@ -12,7 +12,6 @@ import { ErrorBoundary } from 'react-error-boundary';
import { I18nProvider } from '@lingui/react';
import { i18n } from '@lingui/core';
import { Card, PageSection } from '@patternfly/react-core';
import { ConfigProvider, useAuthorizedPath } from './contexts/Config';
import { SessionProvider, useSession } from './contexts/Session';
import AppContainer from './components/AppContainer';
@@ -20,15 +19,14 @@ import Background from './components/Background';
import ContentError from './components/ContentError';
import NotFound from './screens/NotFound';
import Login from './screens/Login';
import { isAuthenticated } from './util/auth';
import { getLanguageWithoutRegionCode } from './util/language';
import { dynamicActivate, locales } from './i18nLoader';
import Metrics from './screens/Metrics';
import getRouteConfig from './routeConfig';
import SubscriptionEdit from './screens/Setting/Subscription/SubscriptionEdit';
import { SESSION_REDIRECT_URL } from './constants';
import { RootAPI } from './api';
function ErrorFallback({ error }) {
return (
@@ -113,10 +111,22 @@ function App() {
// preferred language, default to one that has strings.
language = 'en';
}
useEffect(() => {
dynamicActivate(language);
}, [language]);
useEffect(() => {
async function fetchBrandName() {
const {
data: { BRAND_NAME },
} = await RootAPI.readAssetVariables();
document.title = BRAND_NAME;
}
fetchBrandName();
}, []);
const redirectURL = window.sessionStorage.getItem(SESSION_REDIRECT_URL);
if (redirectURL) {
window.sessionStorage.removeItem(SESSION_REDIRECT_URL);

View File

@@ -1,12 +1,21 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { mountWithContexts } from '../testUtils/enzymeHelpers';
import { RootAPI } from './api';
import * as SessionContext from './contexts/Session';
import App from './App';
jest.mock('./api');
describe('<App />', () => {
beforeEach(() => {
RootAPI.readAssetVariables.mockResolvedValue({
data: {
BRAND_NAME: 'AWX',
},
});
});
test('renders ok', async () => {
const contextValues = {
setAuthRedirectTo: jest.fn(),

View File

@@ -2,12 +2,12 @@ import React from 'react';
import PropTypes from 'prop-types';
import { t } from '@lingui/macro';
import { AboutModal } from '@patternfly/react-core';
import { BrandName } from '../../variables';
import useBrandName from '../../util/useBrandName';
function About({ version, isOpen, onClose }) {
const brandName = useBrandName();
const createSpeechBubble = () => {
let text = `${BrandName} ${version}`;
let text = `${brandName.current} ${version}`;
let top = '';
let bottom = '';
@@ -31,7 +31,7 @@ function About({ version, isOpen, onClose }) {
<AboutModal
isOpen={isOpen}
onClose={onClose}
productName={`Ansible ${BrandName}`}
productName={`Ansible ${brandName.current}`}
trademark={`${copyright} ${new Date().getFullYear()} ${redHatInc}`}
brandImageSrc="/static/media/logo-header.svg"
brandImageAlt={t`Brand Image`}

View File

@@ -9,6 +9,7 @@ import {
InventoriesAPI,
CredentialsAPI,
ExecutionEnvironmentsAPI,
RootAPI,
} from '../../api';
import AdHocCommands from './AdHocCommands';
@@ -16,6 +17,7 @@ jest.mock('../../api/models/CredentialTypes');
jest.mock('../../api/models/Inventories');
jest.mock('../../api/models/Credentials');
jest.mock('../../api/models/ExecutionEnvironments');
jest.mock('../../api/models/Root');
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
@@ -40,6 +42,11 @@ const adHocItems = [
describe('<AdHocCommands />', () => {
beforeEach(() => {
RootAPI.readAssetVariables.mockResolvedValue({
data: {
BRAND_NAME: 'AWX',
},
});
InventoriesAPI.readAdHocOptions.mockResolvedValue({
data: {
actions: {

View File

@@ -4,13 +4,14 @@ import {
mountWithContexts,
waitForElement,
} from '../../../testUtils/enzymeHelpers';
import { CredentialsAPI, ExecutionEnvironmentsAPI } from '../../api';
import { CredentialsAPI, ExecutionEnvironmentsAPI, RootAPI } from '../../api';
import AdHocCommandsWizard from './AdHocCommandsWizard';
jest.mock('../../api/models/CredentialTypes');
jest.mock('../../api/models/Inventories');
jest.mock('../../api/models/Credentials');
jest.mock('../../api/models/ExecutionEnvironments');
jest.mock('../../api/models/Root');
const verbosityOptions = [
{ value: '0', key: '0', label: '0 (Normal)' },
@@ -32,6 +33,11 @@ describe('<AdHocCommandsWizard/>', () => {
let wrapper;
const onLaunch = jest.fn();
beforeEach(async () => {
RootAPI.readAssetVariables.mockResolvedValue({
data: {
BRAND_NAME: 'AWX',
},
});
await act(async () => {
wrapper = mountWithContexts(
<AdHocCommandsWizard

View File

@@ -6,8 +6,6 @@ import PropTypes from 'prop-types';
import { useField } from 'formik';
import { Form, FormGroup, Switch, Checkbox } from '@patternfly/react-core';
import styled from 'styled-components';
import { BrandName } from '../../variables';
import AnsibleSelect from '../AnsibleSelect';
import FormField from '../FormField';
import { VariablesField } from '../CodeEditor';
@@ -18,17 +16,14 @@ import {
} from '../FormLayout';
import Popover from '../Popover';
import { required } from '../../util/validators';
import useBrandName from '../../util/useBrandName';
const TooltipWrapper = styled.div`
text-align: left;
`;
// Setting BrandName to a variable here is necessary to get the jest tests
// passing. Attempting to use BrandName in the template literal results
// in failing tests.
const brandName = BrandName;
function AdHocDetailsStep({ verbosityOptions, moduleOptions }) {
const brandName = useBrandName();
const [moduleNameField, moduleNameMeta, moduleNameHelpers] = useField({
name: 'module_name',
validate: required(null),
@@ -70,7 +65,7 @@ function AdHocDetailsStep({ verbosityOptions, moduleOptions }) {
}
labelIcon={
<Popover
content={t`These are the modules that ${brandName} supports running commands against.`}
content={t`These are the modules that ${brandName.current} supports running commands against.`}
/>
}
>

View File

@@ -2,9 +2,11 @@ import React from 'react';
import { act } from 'react-dom/test-utils';
import { Formik } from 'formik';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import { RootAPI } from '../../api';
import DetailsStep from './AdHocDetailsStep';
jest.mock('../../api/models/Credentials');
jest.mock('../../api/models/Root');
const verbosityOptions = [
{ key: -1, value: '', label: '', isDisabled: false },
@@ -32,6 +34,14 @@ const initialValues = {
describe('<AdHocDetailsStep />', () => {
let wrapper;
beforeEach(() => {
RootAPI.readAssetVariables.mockResolvedValue({
data: {
BRAND_NAME: 'AWX',
},
});
});
test('should mount properly', async () => {
await act(async () => {
wrapper = mountWithContexts(

View File

@@ -3,9 +3,6 @@ import ReactDOM from 'react-dom';
import './setupCSP';
import '@patternfly/react-core/dist/styles/base.css';
import App from './App';
import { BrandName } from './variables';
document.title = `${BrandName}`;
ReactDOM.render(
<React.StrictMode>

View File

@@ -6,7 +6,7 @@ import {
waitForElement,
} from '../../../../testUtils/enzymeHelpers';
import ProjectEdit from './ProjectEdit';
import { ProjectsAPI, CredentialTypesAPI } from '../../../api';
import { ProjectsAPI, CredentialTypesAPI, RootAPI } from '../../../api';
jest.mock('../../../api');
@@ -83,6 +83,11 @@ describe('<ProjectEdit />', () => {
};
beforeEach(async () => {
RootAPI.readAssetVariables.mockResolvedValue({
data: {
BRAND_NAME: 'AWX',
},
});
await ProjectsAPI.readOptions.mockImplementation(
() => projectOptionsResolve
);

View File

@@ -5,7 +5,7 @@ import {
waitForElement,
} from '../../../../testUtils/enzymeHelpers';
import ProjectForm from './ProjectForm';
import { CredentialTypesAPI, ProjectsAPI } from '../../../api';
import { CredentialTypesAPI, ProjectsAPI, RootAPI } from '../../../api';
jest.mock('../../../api');
@@ -81,6 +81,11 @@ describe('<ProjectForm />', () => {
};
beforeEach(async () => {
RootAPI.readAssetVariables.mockResolvedValue({
data: {
BRAND_NAME: 'AWX',
},
});
await ProjectsAPI.readOptions.mockImplementation(
() => projectOptionsResolve
);

View File

@@ -1,6 +1,5 @@
import 'styled-components/macro';
import React from 'react';
import { t } from '@lingui/macro';
import { useField } from 'formik';
import { FormGroup, Alert } from '@patternfly/react-core';
@@ -8,18 +7,14 @@ import { required } from '../../../../util/validators';
import AnsibleSelect from '../../../../components/AnsibleSelect';
import FormField from '../../../../components/FormField';
import Popover from '../../../../components/Popover';
import { BrandName } from '../../../../variables';
// Setting BrandName to a variable here is necessary to get the jest tests
// passing. Attempting to use BrandName in the template literal results
// in failing tests.
const brandName = BrandName;
import useBrandName from '../../../../util/useBrandName';
const ManualSubForm = ({
localPath,
project_base_dir,
project_local_paths,
}) => {
const brandName = useBrandName();
const localPaths = [...new Set([...project_local_paths, localPath])];
const options = [
{
@@ -54,7 +49,7 @@ const ManualSubForm = ({
Either that directory is empty, or all of the contents are already
assigned to other projects. Create a new directory there and make
sure the playbook files can be read by the "awx" system user,
or have ${brandName} directly retrieve your playbooks from
or have ${brandName.current} directly retrieve your playbooks from
source control using the Source Control Type option above.`}
</Alert>
)}

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { t } from '@lingui/macro';
import {
Card as _Card,
@@ -14,14 +13,9 @@ import {
PageSection,
} from '@patternfly/react-core';
import styled from 'styled-components';
import { BrandName } from '../../variables';
import { useConfig } from '../../contexts/Config';
import ContentLoading from '../../components/ContentLoading/ContentLoading';
// Setting BrandName to a variable here is necessary to get the jest tests
// passing. Attempting to use BrandName in the template literal results
// in failing tests.
const brandName = BrandName;
import useBrandName from '../../util/useBrandName';
const SplitLayout = styled(PageSection)`
column-count: 1;
@@ -50,10 +44,11 @@ const CardDescription = styled.div`
function SettingList() {
const config = useConfig();
const brandName = useBrandName();
const settingRoutes = [
{
header: t`Authentication`,
description: t`Enable simplified login for your ${brandName} applications`,
description: t`Enable simplified login for your ${brandName.current} applications`,
id: 'authentication',
routes: [
{
@@ -88,7 +83,7 @@ function SettingList() {
},
{
header: t`Jobs`,
description: t`Update settings pertaining to Jobs within ${brandName}`,
description: t`Update settings pertaining to Jobs within ${brandName.current}`,
id: 'jobs',
routes: [
{

View File

@@ -5,7 +5,7 @@ import {
mountWithContexts,
waitForElement,
} from '../../../testUtils/enzymeHelpers';
import { SettingsAPI } from '../../api';
import { SettingsAPI, RootAPI } from '../../api';
import mockAllOptions from './shared/data.allSettingOptions.json';
import Settings from './Settings';
@@ -19,6 +19,11 @@ describe('<Settings />', () => {
let wrapper;
beforeEach(() => {
RootAPI.readAssetVariables.mockResolvedValue({
data: {
BRAND_NAME: 'AWX',
},
});
SettingsAPI.readAllOptions.mockResolvedValue({
data: mockAllOptions,
});

View File

@@ -12,6 +12,7 @@ import {
JobTemplatesAPI,
LabelsAPI,
ProjectsAPI,
RootAPI,
} from '../../../api';
jest.mock('../../../api');
@@ -67,6 +68,11 @@ describe('<JobTemplateAdd />', () => {
};
beforeEach(() => {
RootAPI.readAssetVariables.mockResolvedValue({
data: {
BRAND_NAME: 'AWX',
},
});
CredentialsAPI.read.mockResolvedValue({
data: {
results: [],

View File

@@ -14,6 +14,7 @@ import {
InventoriesAPI,
ExecutionEnvironmentsAPI,
InstanceGroupsAPI,
RootAPI,
} from '../../../api';
import JobTemplateEdit from './JobTemplateEdit';
import useDebounce from '../../../util/useDebounce';
@@ -27,6 +28,7 @@ jest.mock('../../../api/models/Projects');
jest.mock('../../../api/models/Inventories');
jest.mock('../../../api/models/ExecutionEnvironments');
jest.mock('../../../api/models/InstanceGroups');
jest.mock('../../../api/models/Root');
const mockJobTemplate = {
allow_callbacks: false,
@@ -203,6 +205,11 @@ const mockExecutionEnvironment = [
describe('<JobTemplateEdit />', () => {
beforeEach(() => {
RootAPI.readAssetVariables.mockResolvedValue({
data: {
BRAND_NAME: 'AWX',
},
});
JobTemplatesAPI.readCredentials.mockResolvedValue({
data: mockRelatedCredentials,
});

View File

@@ -13,11 +13,10 @@ import {
} from '@patternfly/react-core';
import ContentError from '../../../components/ContentError';
import ContentLoading from '../../../components/ContentLoading';
import { BrandName } from '../../../variables';
import AnsibleSelect from '../../../components/AnsibleSelect';
import { TagMultiSelect } from '../../../components/MultiSelect';
import useRequest from '../../../util/useRequest';
import useBrandName from '../../../util/useBrandName';
import FormActionGroup from '../../../components/FormActionGroup';
import FormField, {
CheckboxField,
@@ -67,6 +66,7 @@ function JobTemplateForm({
Boolean(template.webhook_service)
);
const isMounted = useIsMounted();
const brandName = useBrandName();
const [askInventoryOnLaunchField] = useField('ask_inventory_on_launch');
const [jobTypeField, jobTypeMeta, jobTypeHelpers] = useField({
@@ -567,7 +567,7 @@ function JobTemplateForm({
&nbsp;
<Popover
content={t`Enables creation of a provisioning
callback URL. Using the URL a host can contact ${BrandName}
callback URL. Using the URL a host can contact ${brandName.current}
and request a configuration update using this job
template.`}
/>

View File

@@ -15,6 +15,7 @@ import {
CredentialsAPI,
CredentialTypesAPI,
InventoriesAPI,
RootAPI,
} from '../../../api';
jest.mock('../../../api');
@@ -95,6 +96,11 @@ describe('<JobTemplateForm />', () => {
beforeEach(() => {
consoleError = global.console.error;
global.console.error = jest.fn();
RootAPI.readAssetVariables.mockResolvedValue({
data: {
BRAND_NAME: 'AWX',
},
});
LabelsAPI.read.mockReturnValue({
data: mockData.summary_fields.labels,
});

View File

@@ -0,0 +1,19 @@
import { useEffect, useRef } from 'react';
import { RootAPI } from '../api';
export default function useBrandName() {
const brandName = useRef('');
useEffect(() => {
async function fetchBrandName() {
const {
data: { BRAND_NAME },
} = await RootAPI.readAssetVariables();
brandName.current = BRAND_NAME;
}
fetchBrandName();
}, []);
return brandName;
}

View File

@@ -1,2 +0,0 @@
export const BrandName = 'AWX';
export const PendoAPIKey = '';