Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CONSOLE-2371: [i18n] Externalize olm operand related strings #7500

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions frontend/packages/operator-lifecycle-manager/locales/en/olm.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,20 @@
"This will remove Operator <1>{{name}}</1> from <4>{{namespace}}</4>. Removing the Operator will not remove any of its custom resource definitions or managed resources. If your Operator has deployed applications on the cluster or configured off-cluster resources, these will continue to run and need to be cleaned up manually.": "This will remove Operator <1>{{name}}</1> from <4>{{namespace}}</4>. Removing the Operator will not remove any of its custom resource definitions or managed resources. If your Operator has deployed applications on the cluster or configured off-cluster resources, these will continue to run and need to be cleaned up manually.",
"Message from Operator developer": "Message from Operator developer",
"Uninstall": "Uninstall",
"Limits": "Limits",
"Requests": "Requests",
"Select {{item}}": "Select {{item}}",
"Add {{item}}": "Add {{item}}",
"Advanced configuration": "Advanced configuration",
"Note: Some fields may not be represented in this form. Please select \"YAML View\" for full control of object creation.": "Note: Some fields may not be represented in this form. Please select \"YAML View\" for full control of object creation.",
"Fix above errors": "Fix above errors",
"No operands found": "No operands found",
"Operands are declarative components used to define the behavior of the application.": "Operands are declarative components used to define the behavior of the application.",
"No provided APIs defined": "No provided APIs defined",
"This application was not properly installed or configured.": "This application was not properly installed or configured.",
"Create new": "Create new",
"The server doesn't have a resource type {{kind}}. Try refreshing the page if it was recently added.": "The server doesn't have a resource type {{kind}}. Try refreshing the page if it was recently added.",
"{{kind}} overview": "{{kind}} overview",
"The Operator Lifecycle Manager will not watch this Namespace because it is not configured with an OperatorGroup.": "The Operator Lifecycle Manager will not watch this Namespace because it is not configured with an OperatorGroup.",
"Create one here.": "Create one here.",
"Select OperatorGroup": "Select OperatorGroup",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {
import { OperandFormProps } from './operand-form';
import { ProvidedAPI } from '../../types';
import { usePostFormSubmitAction } from '@console/shared';
import { useTranslation } from 'react-i18next';

/*
* Matches a path that contains an array index. Use Sting.match against an OperandField 'path'
Expand Down Expand Up @@ -520,6 +521,7 @@ export const DEPRECATED_CreateOperandForm: React.FC<OperandFormProps> = ({
next,
}) => {
const postFormCallback = usePostFormSubmitAction<K8sResourceKind>();
const { t } = useTranslation();
const immutableFormData = Immutable.fromJS(formData);
const handleFormDataUpdate = (path: string, value: any): void => {
const { regexMatch, index, pathBeforeIndex, pathAfterIndex } = parseArrayPath(path);
Expand Down Expand Up @@ -779,7 +781,7 @@ export const DEPRECATED_CreateOperandForm: React.FC<OperandFormProps> = ({
const storageRequestsPath = 'requests.ephemeral-storage';
return (
<dl style={{ marginLeft: '15px' }}>
<dt>Limits</dt>
<dt>{t('olm~Limits')}</dt>
<dd>
<ResourceRequirements
cpu={currentValue.getIn?.(_.toPath(cpuLimitsPath))}
Expand All @@ -793,7 +795,7 @@ export const DEPRECATED_CreateOperandForm: React.FC<OperandFormProps> = ({
path={`${id}.limits`}
/>
</dd>
<dt>Requests</dt>
<dt>{t('olm~Requests')}</dt>
<dd>
<ResourceRequirements
cpu={currentValue.getIn?.(_.toPath(cpuRequestsPath))}
Expand Down Expand Up @@ -846,7 +848,7 @@ export const DEPRECATED_CreateOperandForm: React.FC<OperandFormProps> = ({
},
]}
desc={displayName}
placeholder={`Select ${kindForReference(groupVersionKind)}`}
placeholder={t('olm~Select {{item}}', { item: kindForReference(groupVersionKind) })}
onChange={(value) => handleFormDataUpdate(path, value)}
selectedKey={currentValue ? `${currentValue}-${k8sModel?.kind}` : null}
/>
Expand All @@ -871,8 +873,8 @@ export const DEPRECATED_CreateOperandForm: React.FC<OperandFormProps> = ({
id={id}
isChecked={(_.isNil(currentValue) ? false : currentValue) as boolean}
onChange={(value) => handleFormDataUpdate(path, value)}
label="True"
labelOff="False"
label={t('public~True')}
labelOff={t('public~False')}
/>
);
}
Expand Down Expand Up @@ -967,7 +969,7 @@ export const DEPRECATED_CreateOperandForm: React.FC<OperandFormProps> = ({
<div>
<Dropdown
id={id}
title={`Select ${displayName}`}
title={t('olm~Select {{item}}', { item: displayName })}
selectedKey={currentValue}
items={capabilities
.filter((c) => c.startsWith(SpecCapability.select))
Expand Down Expand Up @@ -1066,7 +1068,7 @@ export const DEPRECATED_CreateOperandForm: React.FC<OperandFormProps> = ({
variant="link"
>
<MinusCircleIcon className="co-icon-space-r" />
Remove {singularGroupDisplayName}
{t('olm~Remove {{item}}', { item: singularGroupDisplayName })}
</Button>
</div>
)}
Expand All @@ -1083,7 +1085,7 @@ export const DEPRECATED_CreateOperandForm: React.FC<OperandFormProps> = ({
<div className="row">
<Button type="button" onClick={() => addArrayFieldGroup(fieldLists)} variant="link">
<PlusCircleIcon className="co-icon-space-r" />
Add {singularGroupDisplayName}
{t('olm~Add {{item}}', { item: singularGroupDisplayName })}
</Button>
</div>
</FieldGroup>
Expand Down Expand Up @@ -1128,8 +1130,8 @@ export const DEPRECATED_CreateOperandForm: React.FC<OperandFormProps> = ({
advancedFields.length > 0 && (
<div>
<ExpandCollapse
textExpanded="Advanced Configuration"
textCollapsed="Advanced Configuration"
textExpanded={t('olm~Advanced configuration')}
textCollapsed={t('olm~Advanced configuration')}
>
{_.map(advancedFields, (field) => (
<OperandFormInputGroup
Expand Down Expand Up @@ -1164,9 +1166,9 @@ export const DEPRECATED_CreateOperandForm: React.FC<OperandFormProps> = ({
isInline
className="co-alert co-break-word"
variant="info"
title={
'Note: Some fields may not be represented in this form. Please select "YAML View" for full control of object creation.'
}
title={t(
'olm~Note: Some fields may not be represented in this form. Please select "YAML View" for full control of object creation.',
)}
/>
<form className="co-dynamic-form" onSubmit={submit}>
<Accordion asDefinitionList={false} className="co-dynamic-form__accordion">
Expand All @@ -1176,7 +1178,7 @@ export const DEPRECATED_CreateOperandForm: React.FC<OperandFormProps> = ({
className="form-group"
>
<label className="form-label co-required" htmlFor="DEPRECATED_root_metadata_name">
Name
{t('public~Name')}
</label>
<input
className="pf-c-form-control"
Expand All @@ -1193,7 +1195,7 @@ export const DEPRECATED_CreateOperandForm: React.FC<OperandFormProps> = ({
className="form-group"
>
<label className="form-label" htmlFor="tags-input">
Labels
{t('public~Labels')}
</label>
<SelectorInput
onChange={(value) =>
Expand All @@ -1217,16 +1219,16 @@ export const DEPRECATED_CreateOperandForm: React.FC<OperandFormProps> = ({
variant="danger"
title="Error"
>
{error || 'Fix above errors'}
{error || t('olm~Fix above errors')}
</Alert>
)}
<div style={{ paddingBottom: '30px' }}>
<ActionGroup className="pf-c-form">
<Button onClick={submit} type="submit" variant="primary">
Create
{t('public~Create')}
</Button>
<Button onClick={history.goBack} variant="secondary">
Cancel
{t('public~Cancel')}
</Button>
</ActionGroup>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ import { EditorType } from '@console/shared/src/components/synced-editor/editor-

import Spy = jasmine.Spy;

jest.mock('react-i18next', () => {
const reactI18next = require.requireActual('react-i18next');
return {
...reactI18next,
useTranslation: () => ({ t: (key) => key }),
};
});

xdescribe('[https://issues.redhat.com/browse/CONSOLE-2137] CreateOperand', () => {
let wrapper: ShallowWrapper<CreateOperandProps>;

Expand Down Expand Up @@ -186,7 +194,9 @@ xdescribe('[https://issues.redhat.com/browse/CONSOLE-2136] CreateOperandForm', (
const error = { message: 'Failed to create' } as k8s.Status;
/* eslint-disable-next-line prefer-promise-reject-errors */
spyAndExpect(spyOn(k8s, 'k8sCreate'))(Promise.reject({ json: error }))
.then(() => new Promise((resolve) => setTimeout(() => resolve(), 10)))
.then(
() => new Promise<void>((resolve) => setTimeout(() => resolve(), 10)),
)
.then(() => {
expect(
wrapper
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
import { DEPRECATED_CreateOperandForm } from './DEPRECATED_operand-form';

import './create-operand.scss';
import { useTranslation } from 'react-i18next';

export const CreateOperand: React.FC<CreateOperandProps> = ({
clusterServiceVersion,
Expand All @@ -54,6 +55,7 @@ export const CreateOperand: React.FC<CreateOperandProps> = ({
match,
model,
}) => {
const { t } = useTranslation();
const { data: csv } = clusterServiceVersion;
const { data: crd } = customResourceDefinition;
const [activePerspective] = useActivePerspective();
Expand Down Expand Up @@ -121,14 +123,17 @@ export const CreateOperand: React.FC<CreateOperandProps> = ({
csv.metadata.namespace,
),
},
{ name: `Create ${model.label}`, path: window.location.pathname },
{
name: t('olm~Create {{item}}', { item: model.label }),
path: window.location.pathname,
},
]}
/>
</div>
<PageHeading
badge={getBadgeFromType(model.badge)}
className="olm-create-operand__page-heading"
title={`Create ${model.label}`}
title={t('olm~Create {{item}}', { item: model.label })}
>
<span className="help-block">{helpText}</span>
</PageHeading>
Expand All @@ -155,41 +160,46 @@ const stateToProps = (state: RootState, props: Omit<CreateOperandPageProps, 'mod
model: state.k8s.getIn(['RESOURCES', 'models', props.match.params.plural]) as K8sKind,
});

export const CreateOperandPage = connect(stateToProps)((props: CreateOperandPageProps) => (
<>
<Helmet>
<title>{`Create ${kindForReference(props.match.params.plural)}`}</title>
</Helmet>
{props.model && (
<Firehose
resources={[
{
kind: referenceForModel(ClusterServiceVersionModel),
name: props.match.params.appName,
namespace: props.match.params.ns,
isList: false,
prop: 'clusterServiceVersion',
},
{
kind: CustomResourceDefinitionModel.kind,
isList: false,
name: nameForModel(props.model),
prop: 'customResourceDefinition',
optional: true,
},
]}
>
{/* FIXME(alecmerdler): Hack because `Firehose` injects props without TypeScript knowing about it */}
<CreateOperand
{...(props as any)}
model={props.model}
match={props.match}
initialEditorType={EditorType.Form}
/>
</Firehose>
)}
</>
));
export const CreateOperandPage = connect(stateToProps)((props: CreateOperandPageProps) => {
const { t } = useTranslation();
return (
<>
<Helmet>
<title>
{t('olm~Create {{item}}', { item: kindForReference(props.match.params.plural) })}
</title>
</Helmet>
{props.model && (
<Firehose
resources={[
{
kind: referenceForModel(ClusterServiceVersionModel),
name: props.match.params.appName,
namespace: props.match.params.ns,
isList: false,
prop: 'clusterServiceVersion',
},
{
kind: CustomResourceDefinitionModel.kind,
isList: false,
name: nameForModel(props.model),
prop: 'customResourceDefinition',
optional: true,
},
]}
>
{/* FIXME(alecmerdler): Hack because `Firehose` injects props without TypeScript knowing about it */}
<CreateOperand
{...(props as any)}
model={props.model}
match={props.match}
initialEditorType={EditorType.Form}
/>
</Firehose>
)}
</>
);
});

export type CreateOperandProps = {
clusterServiceVersion: FirehoseResult<ClusterServiceVersionKind>;
Expand Down