mirror of
https://github.com/ZwareBear/awx.git
synced 2026-05-13 05:58:36 -05:00
Merge pull request #9897 from AlexSCorey/9891-Plural
Properly tags Plural-able strings for translation, and removes unnecessary i18n SUMMARY This resolves #9891. It also begings the process of remove i18n._(t string) in places in favor of this syntax ISSUE TYPE Bugfix Pull Request COMPONENT NAME UI AWX VERSION ADDITIONAL INFORMATION Reviewed-by: Keith Grant <keithjgrant@gmail.com> Reviewed-by: Kersom <None> Reviewed-by: Alex Corey <Alex.swansboro@gmail.com> Reviewed-by: Tiago Góes <tiago.goes2009@gmail.com>
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t, plural } from '@lingui/macro';
|
||||
import { t, Plural } from '@lingui/macro';
|
||||
|
||||
import { Card } from '@patternfly/react-core';
|
||||
import AlertModal from '../AlertModal';
|
||||
@@ -20,7 +19,7 @@ import JobListCancelButton from './JobListCancelButton';
|
||||
import useWsJobs from './useWsJobs';
|
||||
import { UnifiedJobsAPI } from '../../api';
|
||||
|
||||
function JobList({ i18n, defaultParams, showTypeColumn = false }) {
|
||||
function JobList({ defaultParams, showTypeColumn = false }) {
|
||||
const qsConfig = getQSConfig(
|
||||
'job',
|
||||
{
|
||||
@@ -162,67 +161,65 @@ function JobList({ i18n, defaultParams, showTypeColumn = false }) {
|
||||
hasContentLoading={isLoading || isDeleteLoading || isCancelLoading}
|
||||
items={jobs}
|
||||
itemCount={count}
|
||||
pluralizedItemName={i18n._(t`Jobs`)}
|
||||
pluralizedItemName={t`Jobs`}
|
||||
qsConfig={qsConfig}
|
||||
toolbarSearchColumns={[
|
||||
{
|
||||
name: i18n._(t`Name`),
|
||||
name: t`Name`,
|
||||
key: 'name__icontains',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
name: i18n._(t`ID`),
|
||||
name: t`ID`,
|
||||
key: 'id',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Label Name`),
|
||||
name: t`Label Name`,
|
||||
key: 'labels__name__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Job Type`),
|
||||
name: t`Job Type`,
|
||||
key: `or__type`,
|
||||
options: [
|
||||
[`project_update`, i18n._(t`Source Control Update`)],
|
||||
[`inventory_update`, i18n._(t`Inventory Sync`)],
|
||||
[`job`, i18n._(t`Playbook Run`)],
|
||||
[`ad_hoc_command`, i18n._(t`Command`)],
|
||||
[`system_job`, i18n._(t`Management Job`)],
|
||||
[`workflow_job`, i18n._(t`Workflow Job`)],
|
||||
[`project_update`, t`Source Control Update`],
|
||||
[`inventory_update`, t`Inventory Sync`],
|
||||
[`job`, t`Playbook Run`],
|
||||
[`ad_hoc_command`, t`Command`],
|
||||
[`system_job`, t`Management Job`],
|
||||
[`workflow_job`, t`Workflow Job`],
|
||||
],
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Launched By (Username)`),
|
||||
name: t`Launched By (Username)`,
|
||||
key: 'created_by__username__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Status`),
|
||||
name: t`Status`,
|
||||
key: 'status',
|
||||
options: [
|
||||
[`new`, i18n._(t`New`)],
|
||||
[`pending`, i18n._(t`Pending`)],
|
||||
[`waiting`, i18n._(t`Waiting`)],
|
||||
[`running`, i18n._(t`Running`)],
|
||||
[`successful`, i18n._(t`Successful`)],
|
||||
[`failed`, i18n._(t`Failed`)],
|
||||
[`error`, i18n._(t`Error`)],
|
||||
[`canceled`, i18n._(t`Canceled`)],
|
||||
[`new`, t`New`],
|
||||
[`pending`, t`Pending`],
|
||||
[`waiting`, t`Waiting`],
|
||||
[`running`, t`Running`],
|
||||
[`successful`, t`Successful`],
|
||||
[`failed`, t`Failed`],
|
||||
[`error`, t`Error`],
|
||||
[`canceled`, t`Canceled`],
|
||||
],
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Limit`),
|
||||
name: t`Limit`,
|
||||
key: 'job__limit',
|
||||
},
|
||||
]}
|
||||
headerRow={
|
||||
<HeaderRow qsConfig={qsConfig} isExpandable>
|
||||
<HeaderCell sortKey="name">{i18n._(t`Name`)}</HeaderCell>
|
||||
<HeaderCell sortKey="status">{i18n._(t`Status`)}</HeaderCell>
|
||||
{showTypeColumn && <HeaderCell>{i18n._(t`Type`)}</HeaderCell>}
|
||||
<HeaderCell sortKey="started">{i18n._(t`Start Time`)}</HeaderCell>
|
||||
<HeaderCell sortKey="finished">
|
||||
{i18n._(t`Finish Time`)}
|
||||
</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Actions`)}</HeaderCell>
|
||||
<HeaderCell sortKey="name">{t`Name`}</HeaderCell>
|
||||
<HeaderCell sortKey="status">{t`Status`}</HeaderCell>
|
||||
{showTypeColumn && <HeaderCell>{t`Type`}</HeaderCell>}
|
||||
<HeaderCell sortKey="started">{t`Start Time`}</HeaderCell>
|
||||
<HeaderCell sortKey="finished">{t`Finish Time`}</HeaderCell>
|
||||
<HeaderCell>{t`Actions`}</HeaderCell>
|
||||
</HeaderRow>
|
||||
}
|
||||
toolbarSearchableKeys={searchableKeys}
|
||||
@@ -239,17 +236,18 @@ function JobList({ i18n, defaultParams, showTypeColumn = false }) {
|
||||
key="delete"
|
||||
onDelete={handleJobDelete}
|
||||
itemsToDelete={selected}
|
||||
pluralizedItemName={i18n._(t`Jobs`)}
|
||||
pluralizedItemName={t`Jobs`}
|
||||
cannotDelete={item =>
|
||||
isJobRunning(item.status) ||
|
||||
!item.summary_fields.user_capabilities.delete
|
||||
}
|
||||
errorMessage={plural(cannotDeleteItems.length, {
|
||||
one:
|
||||
'The selected job cannot be deleted due to insufficient permission or a running job status',
|
||||
other:
|
||||
'The selected jobs cannot be deleted due to insufficient permissions or a running job status',
|
||||
})}
|
||||
errorMessage={
|
||||
<Plural
|
||||
value={cannotDeleteItems.length}
|
||||
one="The selected job cannot be deleted due to insufficient permission or a running job status"
|
||||
other="The selected jobs cannot be deleted due to insufficient permissions or a running job status"
|
||||
/>
|
||||
}
|
||||
/>,
|
||||
<JobListCancelButton
|
||||
key="cancel"
|
||||
@@ -275,10 +273,10 @@ function JobList({ i18n, defaultParams, showTypeColumn = false }) {
|
||||
<AlertModal
|
||||
isOpen
|
||||
variant="error"
|
||||
title={i18n._(t`Error!`)}
|
||||
title={t`Error!`}
|
||||
onClose={clearDeletionError}
|
||||
>
|
||||
{i18n._(t`Failed to delete one or more jobs.`)}
|
||||
{t`Failed to delete one or more jobs.`}
|
||||
<ErrorDetail error={deletionError} />
|
||||
</AlertModal>
|
||||
)}
|
||||
@@ -286,10 +284,10 @@ function JobList({ i18n, defaultParams, showTypeColumn = false }) {
|
||||
<AlertModal
|
||||
isOpen
|
||||
variant="error"
|
||||
title={i18n._(t`Error!`)}
|
||||
title={t`Error!`}
|
||||
onClose={dismissCancelError}
|
||||
>
|
||||
{i18n._(t`Failed to cancel one or more jobs.`)}
|
||||
{t`Failed to cancel one or more jobs.`}
|
||||
<ErrorDetail error={cancelError} />
|
||||
</AlertModal>
|
||||
)}
|
||||
@@ -297,4 +295,4 @@ function JobList({ i18n, defaultParams, showTypeColumn = false }) {
|
||||
);
|
||||
}
|
||||
|
||||
export default withI18n()(JobList);
|
||||
export default JobList;
|
||||
|
||||
@@ -320,10 +320,8 @@ describe('<JobList />', () => {
|
||||
|
||||
wrapper.update();
|
||||
|
||||
const deleteButton = wrapper.find('ToolbarDeleteButton');
|
||||
expect(deleteButton.find('Tooltip').prop('content').props.children).toEqual(
|
||||
'The selected jobs cannot be deleted due to insufficient permissions or a running job status: job 1, job 2'
|
||||
);
|
||||
const deleteButton = wrapper.find('ToolbarDeleteButton').find('Button');
|
||||
expect(deleteButton.prop('isDisabled')).toBe(true);
|
||||
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
@@ -17,7 +17,6 @@ import {
|
||||
DropdownItem,
|
||||
Tooltip,
|
||||
} from '@patternfly/react-core';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import AlertModal from '../AlertModal';
|
||||
import { KebabifiedContext } from '../../contexts/Kebabified';
|
||||
@@ -95,7 +94,6 @@ function ToolbarDeleteButton({
|
||||
deleteDetailsRequests,
|
||||
warningMessage,
|
||||
deleteMessage,
|
||||
i18n,
|
||||
cannotDelete,
|
||||
}) {
|
||||
const { isKebabified, onKebabModalChange } = useContext(KebabifiedContext);
|
||||
@@ -145,21 +143,24 @@ function ToolbarDeleteButton({
|
||||
if (itemsToDelete.some(cannotDelete)) {
|
||||
return (
|
||||
<div>
|
||||
{errorMessage
|
||||
? `${errorMessage}: ${itemsUnableToDelete}`
|
||||
: i18n._(
|
||||
t`You do not have permission to delete ${pluralizedItemName}: ${itemsUnableToDelete}`
|
||||
)}
|
||||
{errorMessage ? (
|
||||
<>
|
||||
<span>{errorMessage}</span>
|
||||
<span>{`: ${itemsUnableToDelete}`}</span>
|
||||
</>
|
||||
) : (
|
||||
t`You do not have permission to delete ${pluralizedItemName}: ${itemsUnableToDelete}`
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if (itemsToDelete.length) {
|
||||
return i18n._(t`Delete`);
|
||||
return t`Delete`;
|
||||
}
|
||||
return i18n._(t`Select a row to delete`);
|
||||
return t`Select a row to delete`;
|
||||
};
|
||||
|
||||
const modalTitle = i18n._(t`Delete ${pluralizedItemName}?`);
|
||||
const modalTitle = t`Delete ${pluralizedItemName}?`;
|
||||
|
||||
const isDisabled =
|
||||
itemsToDelete.length === 0 || itemsToDelete.some(cannotDelete);
|
||||
@@ -201,7 +202,7 @@ function ToolbarDeleteButton({
|
||||
return (
|
||||
<AlertModal
|
||||
isOpen={deleteMessageError}
|
||||
title={i18n._(t`Error!`)}
|
||||
title={t`Error!`}
|
||||
onClose={() => {
|
||||
toggleModal(false);
|
||||
setDeleteMessageError();
|
||||
@@ -230,7 +231,7 @@ function ToolbarDeleteButton({
|
||||
toggleModal(true);
|
||||
}}
|
||||
>
|
||||
{i18n._(t`Delete`)}
|
||||
{t`Delete`}
|
||||
</DropdownItem>
|
||||
</Tooltip>
|
||||
) : (
|
||||
@@ -240,11 +241,11 @@ function ToolbarDeleteButton({
|
||||
variant="secondary"
|
||||
isLoading={isLoading}
|
||||
spinnerAriaValueText={isLoading ? 'Loading' : undefined}
|
||||
aria-label={i18n._(t`Delete`)}
|
||||
aria-label={t`Delete`}
|
||||
onClick={() => toggleModal(true)}
|
||||
isDisabled={isDisabled}
|
||||
>
|
||||
{i18n._(t`Delete`)}
|
||||
{t`Delete`}
|
||||
</Button>
|
||||
</div>
|
||||
</Tooltip>
|
||||
@@ -261,25 +262,25 @@ function ToolbarDeleteButton({
|
||||
ouiaId="delete-modal-confirm"
|
||||
key="delete"
|
||||
variant="danger"
|
||||
aria-label={i18n._(t`confirm delete`)}
|
||||
aria-label={t`confirm delete`}
|
||||
isDisabled={Boolean(
|
||||
deleteDetails && itemsToDelete[0]?.type === 'credential_type'
|
||||
)}
|
||||
onClick={handleDelete}
|
||||
>
|
||||
{i18n._(t`Delete`)}
|
||||
{t`Delete`}
|
||||
</Button>,
|
||||
<Button
|
||||
key="cancel"
|
||||
variant="link"
|
||||
aria-label={i18n._(t`cancel delete`)}
|
||||
aria-label={t`cancel delete`}
|
||||
onClick={() => toggleModal(false)}
|
||||
>
|
||||
{i18n._(t`Cancel`)}
|
||||
{t`Cancel`}
|
||||
</Button>,
|
||||
]}
|
||||
>
|
||||
<div>{i18n._(t`This action will delete the following:`)}</div>
|
||||
<div>{t`This action will delete the following:`}</div>
|
||||
{itemsToDelete.map(item => (
|
||||
<span key={item.id}>
|
||||
<strong>{item.name || item.username || item.image}</strong>
|
||||
@@ -303,16 +304,14 @@ ToolbarDeleteButton.propTypes = {
|
||||
onDelete: func.isRequired,
|
||||
itemsToDelete: arrayOf(ItemToDelete).isRequired,
|
||||
pluralizedItemName: string,
|
||||
errorMessage: string,
|
||||
warningMessage: node,
|
||||
cannotDelete: func,
|
||||
};
|
||||
|
||||
ToolbarDeleteButton.defaultProps = {
|
||||
pluralizedItemName: 'Items',
|
||||
errorMessage: '',
|
||||
warningMessage: null,
|
||||
cannotDelete: item => !item.summary_fields.user_capabilities.delete,
|
||||
};
|
||||
|
||||
export default withI18n()(ToolbarDeleteButton);
|
||||
export default ToolbarDeleteButton;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
|
||||
import {
|
||||
mountWithContexts,
|
||||
waitForElement,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, { Fragment, useEffect, useState, useCallback } from 'react';
|
||||
import { useLocation, Link } from 'react-router-dom';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import { t, Plural } from '@lingui/macro';
|
||||
import { Card, DropdownItem } from '@patternfly/react-core';
|
||||
import {
|
||||
JobTemplatesAPI,
|
||||
@@ -20,7 +19,7 @@ import AddDropDownButton from '../AddDropDownButton';
|
||||
import TemplateListItem from './TemplateListItem';
|
||||
import { relatedResourceDeleteRequests } from '../../util/getRelatedResourceDeleteDetails';
|
||||
|
||||
function TemplateList({ defaultParams, i18n }) {
|
||||
function TemplateList({ defaultParams }) {
|
||||
// The type value in const qsConfig below does not have a space between job_template and
|
||||
// workflow_job_template so the params sent to the API match what the api expects.
|
||||
const qsConfig = getQSConfig(
|
||||
@@ -138,8 +137,8 @@ function TemplateList({ defaultParams, i18n }) {
|
||||
const canAddWFJT =
|
||||
wfjtActions && Object.prototype.hasOwnProperty.call(wfjtActions, 'POST');
|
||||
|
||||
const addTemplate = i18n._(t`Add job template`);
|
||||
const addWFTemplate = i18n._(t`Add workflow template`);
|
||||
const addTemplate = t`Add job template`;
|
||||
const addWFTemplate = t`Add workflow template`;
|
||||
const addDropDownButton = [];
|
||||
if (canAddJT) {
|
||||
addDropDownButton.push(
|
||||
@@ -181,37 +180,37 @@ function TemplateList({ defaultParams, i18n }) {
|
||||
hasContentLoading={isLoading || isDeleteLoading}
|
||||
items={templates}
|
||||
itemCount={count}
|
||||
pluralizedItemName={i18n._(t`Templates`)}
|
||||
pluralizedItemName={t`Templates`}
|
||||
qsConfig={qsConfig}
|
||||
onRowClick={handleSelect}
|
||||
toolbarSearchColumns={[
|
||||
{
|
||||
name: i18n._(t`Name`),
|
||||
name: t`Name`,
|
||||
key: 'name__icontains',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Description`),
|
||||
name: t`Description`,
|
||||
key: 'description__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Type`),
|
||||
name: t`Type`,
|
||||
key: 'or__type',
|
||||
options: [
|
||||
[`job_template`, i18n._(t`Job Template`)],
|
||||
[`workflow_job_template`, i18n._(t`Workflow Template`)],
|
||||
[`job_template`, t`Job Template`],
|
||||
[`workflow_job_template`, t`Workflow Template`],
|
||||
],
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Playbook name`),
|
||||
name: t`Playbook name`,
|
||||
key: 'job_template__playbook__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Created By (Username)`),
|
||||
name: t`Created By (Username)`,
|
||||
key: 'created_by__username__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Modified By (Username)`),
|
||||
name: t`Modified By (Username)`,
|
||||
key: 'modified_by__username__icontains',
|
||||
},
|
||||
]}
|
||||
@@ -219,12 +218,10 @@ function TemplateList({ defaultParams, i18n }) {
|
||||
toolbarRelatedSearchableKeys={relatedSearchableKeys}
|
||||
headerRow={
|
||||
<HeaderRow qsConfig={qsConfig} isExpandable>
|
||||
<HeaderCell sortKey="name">{i18n._(t`Name`)}</HeaderCell>
|
||||
<HeaderCell sortKey="type">{i18n._(t`Type`)}</HeaderCell>
|
||||
<HeaderCell sortKey="last_job_run">
|
||||
{i18n._(t`Last Ran`)}
|
||||
</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Actions`)}</HeaderCell>
|
||||
<HeaderCell sortKey="name">{t`Name`}</HeaderCell>
|
||||
<HeaderCell sortKey="type">{t`Type`}</HeaderCell>
|
||||
<HeaderCell sortKey="last_job_run">{t`Last Ran`}</HeaderCell>
|
||||
<HeaderCell>{t`Actions`}</HeaderCell>
|
||||
</HeaderRow>
|
||||
}
|
||||
renderToolbar={props => (
|
||||
@@ -240,12 +237,15 @@ function TemplateList({ defaultParams, i18n }) {
|
||||
key="delete"
|
||||
onDelete={handleTemplateDelete}
|
||||
itemsToDelete={selected}
|
||||
pluralizedItemName={i18n._(t`Templates`)}
|
||||
pluralizedItemName={t`Templates`}
|
||||
deleteDetailsRequests={deleteDetailsRequests}
|
||||
deleteMessage={i18n._(
|
||||
'{numItemsToDelete, plural, one {This template is currently being used by some workflow nodes. Are you sure you want to delete it?} other {Deleting these templates could impact some workflow nodes that rely on them. Are you sure you want to delete anyway?}}',
|
||||
{ numItemsToDelete: selected.length }
|
||||
)}
|
||||
deleteMessage={
|
||||
<Plural
|
||||
value={selected.length}
|
||||
one="This template is currently being used by some workflow nodes. Are you sure you want to delete it?"
|
||||
other="Deleting these templates could impact some workflow nodes that rely on them. Are you sure you want to delete anyway?"
|
||||
/>
|
||||
}
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
@@ -266,17 +266,17 @@ function TemplateList({ defaultParams, i18n }) {
|
||||
/>
|
||||
</Card>
|
||||
<AlertModal
|
||||
aria-label={i18n._(t`Deletion Error`)}
|
||||
aria-label={t`Deletion Error`}
|
||||
isOpen={deletionError}
|
||||
variant="error"
|
||||
title={i18n._(t`Error!`)}
|
||||
title={t`Error!`}
|
||||
onClose={clearDeletionError}
|
||||
>
|
||||
{i18n._(t`Failed to delete one or more templates.`)}
|
||||
{t`Failed to delete one or more templates.`}
|
||||
<ErrorDetail error={deletionError} />
|
||||
</AlertModal>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default withI18n()(TemplateList);
|
||||
export default TemplateList;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+1119
-702
File diff suppressed because it is too large
Load Diff
+1145
-711
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+1121
-700
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,6 @@
|
||||
import React, { useEffect, useCallback } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import { t, Plural } from '@lingui/macro';
|
||||
import { Card, PageSection } from '@patternfly/react-core';
|
||||
import { CredentialsAPI } from '../../../api';
|
||||
import useSelected from '../../../util/useSelected';
|
||||
@@ -27,7 +26,7 @@ const QS_CONFIG = getQSConfig('credential', {
|
||||
order_by: 'name',
|
||||
});
|
||||
|
||||
function CredentialList({ i18n }) {
|
||||
function CredentialList() {
|
||||
const location = useLocation();
|
||||
const {
|
||||
result: {
|
||||
@@ -121,28 +120,28 @@ function CredentialList({ i18n }) {
|
||||
toolbarRelatedSearchableKeys={relatedSearchableKeys}
|
||||
toolbarSearchColumns={[
|
||||
{
|
||||
name: i18n._(t`Name`),
|
||||
name: t`Name`,
|
||||
key: 'name__icontains',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Description`),
|
||||
name: t`Description`,
|
||||
key: 'description__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Created By (Username)`),
|
||||
name: t`Created By (Username)`,
|
||||
key: 'created_by__username__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Modified By (Username)`),
|
||||
name: t`Modified By (Username)`,
|
||||
key: 'modified_by__username__icontains',
|
||||
},
|
||||
]}
|
||||
headerRow={
|
||||
<HeaderRow qsConfig={QS_CONFIG}>
|
||||
<HeaderCell sortKey="name">{i18n._(t`Name`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Type`)}</HeaderCell>
|
||||
<HeaderCell alignRight>{i18n._(t`Actions`)}</HeaderCell>
|
||||
<HeaderCell sortKey="name">{t`Name`}</HeaderCell>
|
||||
<HeaderCell>{t`Type`}</HeaderCell>
|
||||
<HeaderCell alignRight>{t`Actions`}</HeaderCell>
|
||||
</HeaderRow>
|
||||
}
|
||||
renderRow={(item, index) => (
|
||||
@@ -173,12 +172,15 @@ function CredentialList({ i18n }) {
|
||||
key="delete"
|
||||
onDelete={handleDelete}
|
||||
itemsToDelete={selected}
|
||||
pluralizedItemName={i18n._(t`Credentials`)}
|
||||
pluralizedItemName={t`Credentials`}
|
||||
deleteDetailsRequests={deleteDetailsRequests}
|
||||
deleteMessage={i18n._(
|
||||
'{numItemsToDelete, plural, one {This credential is currently being used by other resources. Are you sure you want to delete it?} other {Deleting these credentials could impact other resources that rely on them. Are you sure you want to delete anyway?}}',
|
||||
{ numItemsToDelete: selected.length }
|
||||
)}
|
||||
deleteMessage={
|
||||
<Plural
|
||||
value={selected.length}
|
||||
one="This credential is currently being used by other resources. Are you sure you want to delete it?"
|
||||
other="Deleting these credentials could impact other resources that rely on them. Are you sure you want to delete anyway?"
|
||||
/>
|
||||
}
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
@@ -186,17 +188,17 @@ function CredentialList({ i18n }) {
|
||||
/>
|
||||
</Card>
|
||||
<AlertModal
|
||||
aria-label={i18n._(t`Deletion Error`)}
|
||||
aria-label={t`Deletion Error`}
|
||||
isOpen={deletionError}
|
||||
variant="error"
|
||||
title={i18n._(t`Error!`)}
|
||||
title={t`Error!`}
|
||||
onClose={clearDeletionError}
|
||||
>
|
||||
{i18n._(t`Failed to delete one or more credentials.`)}
|
||||
{t`Failed to delete one or more credentials.`}
|
||||
<ErrorDetail error={deletionError} />
|
||||
</AlertModal>
|
||||
</PageSection>
|
||||
);
|
||||
}
|
||||
|
||||
export default withI18n()(CredentialList);
|
||||
export default CredentialList;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useCallback } from 'react';
|
||||
import { useLocation, useRouteMatch } from 'react-router-dom';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
|
||||
import { t, Plural } from '@lingui/macro';
|
||||
import { Card, PageSection } from '@patternfly/react-core';
|
||||
|
||||
import { CredentialTypesAPI } from '../../../api';
|
||||
@@ -28,7 +28,7 @@ const QS_CONFIG = getQSConfig('credential-type', {
|
||||
managed_by_tower: false,
|
||||
});
|
||||
|
||||
function CredentialTypeList({ i18n }) {
|
||||
function CredentialTypeList() {
|
||||
const location = useLocation();
|
||||
const match = useRouteMatch();
|
||||
|
||||
@@ -119,25 +119,25 @@ function CredentialTypeList({ i18n }) {
|
||||
hasContentLoading={isLoading || deleteLoading}
|
||||
items={credentialTypes}
|
||||
itemCount={credentialTypesCount}
|
||||
pluralizedItemName={i18n._(t`Credential Types`)}
|
||||
pluralizedItemName={t`Credential Types`}
|
||||
qsConfig={QS_CONFIG}
|
||||
onRowClick={handleSelect}
|
||||
toolbarSearchColumns={[
|
||||
{
|
||||
name: i18n._(t`Name`),
|
||||
name: t`Name`,
|
||||
key: 'name__icontains',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Description`),
|
||||
name: t`Description`,
|
||||
key: 'description__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Created By (Username)`),
|
||||
name: t`Created By (Username)`,
|
||||
key: 'created_by__username__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Modified By (Username)`),
|
||||
name: t`Modified By (Username)`,
|
||||
key: 'modified_by__username__icontains',
|
||||
},
|
||||
]}
|
||||
@@ -165,20 +165,23 @@ function CredentialTypeList({ i18n }) {
|
||||
key="delete"
|
||||
onDelete={handleDelete}
|
||||
itemsToDelete={selected}
|
||||
pluralizedItemName={i18n._(t`Credential Types`)}
|
||||
pluralizedItemName={t`Credential Types`}
|
||||
deleteDetailsRequests={deleteDetailsRequests}
|
||||
deleteMessage={i18n._(
|
||||
'{numItemsToDelete, plural, one {This credential type is currently being used by some credentials and cannot be deleted.} other {Credential types that are being used by credentials cannot be deleted. Are you sure you want to delete anyway?}}',
|
||||
{ numItemsToDelete: selected.length }
|
||||
)}
|
||||
deleteMessage={
|
||||
<Plural
|
||||
value={selected.length}
|
||||
one="This credential type is currently being used by some credentials and cannot be deleted."
|
||||
other="Credential types that are being used by credentials cannot be deleted. Are you sure you want to delete anyway?"
|
||||
/>
|
||||
}
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
headerRow={
|
||||
<HeaderRow qsConfig={QS_CONFIG}>
|
||||
<HeaderCell sortKey="name">{i18n._(t`Name`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Actions`)}</HeaderCell>
|
||||
<HeaderCell sortKey="name">{t`Name`}</HeaderCell>
|
||||
<HeaderCell>{t`Actions`}</HeaderCell>
|
||||
</HeaderRow>
|
||||
}
|
||||
renderRow={(credentialType, index) => (
|
||||
@@ -201,17 +204,17 @@ function CredentialTypeList({ i18n }) {
|
||||
</Card>
|
||||
</PageSection>
|
||||
<AlertModal
|
||||
aria-label={i18n._(t`Deletion error`)}
|
||||
aria-label={t`Deletion error`}
|
||||
isOpen={deletionError}
|
||||
onClose={clearDeletionError}
|
||||
title={i18n._(t`Error`)}
|
||||
title={t`Error`}
|
||||
variant="error"
|
||||
>
|
||||
{i18n._(t`Failed to delete one or more credential types.`)}
|
||||
{t`Failed to delete one or more credential types.`}
|
||||
<ErrorDetail error={deletionError} />
|
||||
</AlertModal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default withI18n()(CredentialTypeList);
|
||||
export default CredentialTypeList;
|
||||
|
||||
+25
-23
@@ -1,7 +1,6 @@
|
||||
import React, { useEffect, useCallback } from 'react';
|
||||
import { useLocation, useRouteMatch } from 'react-router-dom';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import { t, Plural } from '@lingui/macro';
|
||||
import { Card, PageSection } from '@patternfly/react-core';
|
||||
|
||||
import { ExecutionEnvironmentsAPI } from '../../../api';
|
||||
@@ -28,7 +27,7 @@ const QS_CONFIG = getQSConfig('execution_environments', {
|
||||
order_by: 'name',
|
||||
});
|
||||
|
||||
function ExecutionEnvironmentList({ i18n }) {
|
||||
function ExecutionEnvironmentList() {
|
||||
const location = useLocation();
|
||||
const match = useRouteMatch();
|
||||
|
||||
@@ -118,46 +117,46 @@ function ExecutionEnvironmentList({ i18n }) {
|
||||
hasContentLoading={isLoading || deleteLoading}
|
||||
items={executionEnvironments}
|
||||
itemCount={executionEnvironmentsCount}
|
||||
pluralizedItemName={i18n._(t`Execution Environments`)}
|
||||
pluralizedItemName={t`Execution Environments`}
|
||||
qsConfig={QS_CONFIG}
|
||||
onRowClick={handleSelect}
|
||||
toolbarSearchableKeys={searchableKeys}
|
||||
toolbarRelatedSearchableKeys={relatedSearchableKeys}
|
||||
toolbarSearchColumns={[
|
||||
{
|
||||
name: i18n._(t`Name`),
|
||||
name: t`Name`,
|
||||
key: 'name__icontains',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Image`),
|
||||
name: t`Image`,
|
||||
key: 'image__icontains',
|
||||
},
|
||||
]}
|
||||
toolbarSortColumns={[
|
||||
{
|
||||
name: i18n._(t`Image`),
|
||||
name: t`Image`,
|
||||
key: 'image',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Created`),
|
||||
name: t`Created`,
|
||||
key: 'created',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Organization`),
|
||||
name: t`Organization`,
|
||||
key: 'organization',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Description`),
|
||||
name: t`Description`,
|
||||
key: 'description',
|
||||
},
|
||||
]}
|
||||
headerRow={
|
||||
<HeaderRow qsConfig={QS_CONFIG}>
|
||||
<HeaderCell sortKey="name">{i18n._(t`Name`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Image`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Organization`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Actions`)}</HeaderCell>
|
||||
<HeaderCell sortKey="name">{t`Name`}</HeaderCell>
|
||||
<HeaderCell>{t`Image`}</HeaderCell>
|
||||
<HeaderCell>{t`Organization`}</HeaderCell>
|
||||
<HeaderCell>{t`Actions`}</HeaderCell>
|
||||
</HeaderRow>
|
||||
}
|
||||
renderToolbar={props => (
|
||||
@@ -182,12 +181,15 @@ function ExecutionEnvironmentList({ i18n }) {
|
||||
key="delete"
|
||||
onDelete={handleDelete}
|
||||
itemsToDelete={selected}
|
||||
pluralizedItemName={i18n._(t`Execution Environments`)}
|
||||
pluralizedItemName={t`Execution Environments`}
|
||||
deleteDetailsRequests={deleteDetailsRequests}
|
||||
deleteMessage={i18n._(
|
||||
'{numItemsToDelete, plural, one {This execution environment is currently being used by other resources. Are you sure you want to delete it?} other {Deleting these execution environemnts could impact other resources that rely on them. Are you sure you want to delete anyway?}}',
|
||||
{ numItemsToDelete: selected.length }
|
||||
)}
|
||||
deleteMessage={
|
||||
<Plural
|
||||
value={selected.length}
|
||||
one="This execution environment is currently being used by other resources. Are you sure you want to delete it?"
|
||||
other="These execution environments could be in use by other resources that rely on them. Are you sure you want to delete them anyway?"
|
||||
/>
|
||||
}
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
@@ -214,17 +216,17 @@ function ExecutionEnvironmentList({ i18n }) {
|
||||
</Card>
|
||||
</PageSection>
|
||||
<AlertModal
|
||||
aria-label={i18n._(t`Deletion error`)}
|
||||
aria-label={t`Deletion error`}
|
||||
isOpen={deletionError}
|
||||
onClose={clearDeletionError}
|
||||
title={i18n._(t`Error`)}
|
||||
title={t`Error`}
|
||||
variant="error"
|
||||
>
|
||||
{i18n._(t`Failed to delete one or more execution environments`)}
|
||||
{t`Failed to delete one or more execution environments`}
|
||||
<ErrorDetail error={deletionError} />
|
||||
</AlertModal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default withI18n()(ExecutionEnvironmentList);
|
||||
export default ExecutionEnvironmentList;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useCallback } from 'react';
|
||||
import { useLocation, useRouteMatch, Link } from 'react-router-dom';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
|
||||
import { t, Plural } from '@lingui/macro';
|
||||
import { Card, PageSection, DropdownItem } from '@patternfly/react-core';
|
||||
|
||||
import { InstanceGroupsAPI } from '../../../api';
|
||||
@@ -43,7 +43,7 @@ function modifyInstanceGroups(items = []) {
|
||||
});
|
||||
}
|
||||
|
||||
function InstanceGroupList({ i18n }) {
|
||||
function InstanceGroupList() {
|
||||
const location = useLocation();
|
||||
const match = useRouteMatch();
|
||||
|
||||
@@ -127,7 +127,7 @@ function InstanceGroupList({ i18n }) {
|
||||
return !item.summary_fields.user_capabilities.delete;
|
||||
}
|
||||
|
||||
const pluralizedItemName = i18n._(t`Instance Groups`);
|
||||
const pluralizedItemName = t`Instance Groups`;
|
||||
|
||||
let errorMessageDelete = '';
|
||||
|
||||
@@ -140,9 +140,7 @@ function InstanceGroupList({ i18n }) {
|
||||
|
||||
if (itemsUnableToDelete) {
|
||||
if (modifiedSelected.some(cannotDelete)) {
|
||||
errorMessageDelete = i18n._(
|
||||
t`You do not have permission to delete ${pluralizedItemName}: ${itemsUnableToDelete}. `
|
||||
);
|
||||
errorMessageDelete = t`You do not have permission to delete ${pluralizedItemName}: ${itemsUnableToDelete}. `;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,12 +148,12 @@ function InstanceGroupList({ i18n }) {
|
||||
errorMessageDelete = errorMessageDelete.concat('\n');
|
||||
}
|
||||
errorMessageDelete = errorMessageDelete.concat(
|
||||
i18n._(t`The tower instance group cannot be deleted.`)
|
||||
t`The tower instance group cannot be deleted.`
|
||||
);
|
||||
}
|
||||
|
||||
const addContainerGroup = i18n._(t`Add container group`);
|
||||
const addInstanceGroup = i18n._(t`Add instance group`);
|
||||
const addContainerGroup = t`Add container group`;
|
||||
const addInstanceGroup = t`Add instance group`;
|
||||
|
||||
const addButton = (
|
||||
<AddDropDownButton
|
||||
@@ -218,26 +216,29 @@ function InstanceGroupList({ i18n }) {
|
||||
key="delete"
|
||||
onDelete={handleDelete}
|
||||
itemsToDelete={modifiedSelected}
|
||||
pluralizedItemName={i18n._(t`Instance Groups`)}
|
||||
pluralizedItemName={t`Instance Groups`}
|
||||
errorMessage={errorMessageDelete}
|
||||
deleteDetailsRequests={deleteDetailsRequests}
|
||||
deleteMessage={i18n._(
|
||||
'{numItemsToDelete, plural, one {This instance group is currently being by other resources. Are you sure you want to delete it?} other {Deleting these instance groups could impact other resources that rely on them. Are you sure you want to delete anyway?}}',
|
||||
{ numItemsToDelete: selected.length }
|
||||
)}
|
||||
deleteMessage={
|
||||
<Plural
|
||||
value={selected.length}
|
||||
one="This instance group is currently being by other resources. Are you sure you want to delete it?"
|
||||
other="Deleting these instance groups could impact other resources that rely on them. Are you sure you want to delete anyway?"
|
||||
/>
|
||||
}
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
headerRow={
|
||||
<HeaderRow qsConfig={QS_CONFIG}>
|
||||
<HeaderCell sortKey="name">{i18n._(t`Name`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Type`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Running Jobs`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Total Jobs`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Instances`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Capacity`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Actions`)}</HeaderCell>
|
||||
<HeaderCell sortKey="name">{t`Name`}</HeaderCell>
|
||||
<HeaderCell>{t`Type`}</HeaderCell>
|
||||
<HeaderCell>{t`Running Jobs`}</HeaderCell>
|
||||
<HeaderCell>{t`Total Jobs`}</HeaderCell>
|
||||
<HeaderCell>{t`Instances`}</HeaderCell>
|
||||
<HeaderCell>{t`Capacity`}</HeaderCell>
|
||||
<HeaderCell>{t`Actions`}</HeaderCell>
|
||||
</HeaderRow>
|
||||
}
|
||||
renderRow={(instanceGroup, index) => (
|
||||
@@ -256,17 +257,17 @@ function InstanceGroupList({ i18n }) {
|
||||
</Card>
|
||||
</PageSection>
|
||||
<AlertModal
|
||||
aria-label={i18n._(t`Deletion error`)}
|
||||
aria-label={t`Deletion error`}
|
||||
isOpen={deletionError}
|
||||
onClose={clearDeletionError}
|
||||
title={i18n._(t`Error`)}
|
||||
title={t`Error`}
|
||||
variant="error"
|
||||
>
|
||||
{i18n._(t`Failed to delete one or more instance groups.`)}
|
||||
{t`Failed to delete one or more instance groups.`}
|
||||
<ErrorDetail error={deletionError} />
|
||||
</AlertModal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default withI18n()(InstanceGroupList);
|
||||
export default InstanceGroupList;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, { useState, useCallback, useEffect } from 'react';
|
||||
import { useLocation, useRouteMatch, Link } from 'react-router-dom';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t, plural } from '@lingui/macro';
|
||||
import { t, Plural } from '@lingui/macro';
|
||||
import { Card, PageSection, DropdownItem } from '@patternfly/react-core';
|
||||
import { InventoriesAPI } from '../../../api';
|
||||
import useRequest, { useDeleteItems } from '../../../util/useRequest';
|
||||
@@ -25,7 +24,7 @@ const QS_CONFIG = getQSConfig('inventory', {
|
||||
order_by: 'name',
|
||||
});
|
||||
|
||||
function InventoryList({ i18n }) {
|
||||
function InventoryList() {
|
||||
const location = useLocation();
|
||||
const match = useRouteMatch();
|
||||
const [selected, setSelected] = useState([]);
|
||||
@@ -132,8 +131,8 @@ function InventoryList({ i18n }) {
|
||||
selected[0]
|
||||
);
|
||||
|
||||
const addInventory = i18n._(t`Add inventory`);
|
||||
const addSmartInventory = i18n._(t`Add smart inventory`);
|
||||
const addInventory = t`Add inventory`;
|
||||
const addSmartInventory = t`Add smart inventory`;
|
||||
const addButton = (
|
||||
<AddDropDownButton
|
||||
key="add"
|
||||
@@ -166,30 +165,30 @@ function InventoryList({ i18n }) {
|
||||
hasContentLoading={hasContentLoading}
|
||||
items={inventories}
|
||||
itemCount={itemCount}
|
||||
pluralizedItemName={i18n._(t`Inventories`)}
|
||||
pluralizedItemName={t`Inventories`}
|
||||
qsConfig={QS_CONFIG}
|
||||
toolbarSearchColumns={[
|
||||
{
|
||||
name: i18n._(t`Name`),
|
||||
name: t`Name`,
|
||||
key: 'name__icontains',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Description`),
|
||||
name: t`Description`,
|
||||
key: 'description__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Created By (Username)`),
|
||||
name: t`Created By (Username)`,
|
||||
key: 'created_by__username__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Modified By (Username)`),
|
||||
name: t`Modified By (Username)`,
|
||||
key: 'modified_by__username__icontains',
|
||||
},
|
||||
]}
|
||||
toolbarSortColumns={[
|
||||
{
|
||||
name: i18n._(t`Name`),
|
||||
name: t`Name`,
|
||||
key: 'name',
|
||||
},
|
||||
]}
|
||||
@@ -197,11 +196,11 @@ function InventoryList({ i18n }) {
|
||||
toolbarRelatedSearchableKeys={relatedSearchableKeys}
|
||||
headerRow={
|
||||
<HeaderRow qsConfig={QS_CONFIG}>
|
||||
<HeaderCell sortKey="name">{i18n._(t`Name`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Status`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Type`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Organization`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Actions`)}</HeaderCell>
|
||||
<HeaderCell sortKey="name">{t`Name`}</HeaderCell>
|
||||
<HeaderCell>{t`Status`}</HeaderCell>
|
||||
<HeaderCell>{t`Type`}</HeaderCell>
|
||||
<HeaderCell>{t`Organization`}</HeaderCell>
|
||||
<HeaderCell>{t`Actions`}</HeaderCell>
|
||||
</HeaderRow>
|
||||
}
|
||||
renderToolbar={props => (
|
||||
@@ -217,14 +216,22 @@ function InventoryList({ i18n }) {
|
||||
key="delete"
|
||||
onDelete={handleInventoryDelete}
|
||||
itemsToDelete={selected}
|
||||
pluralizedItemName={i18n._(t`Inventories`)}
|
||||
pluralizedItemName={t`Inventories`}
|
||||
deleteDetailsRequests={deleteDetailsRequests}
|
||||
warningMessage={plural(selected.length, {
|
||||
one:
|
||||
'The inventory will be in a pending status until the final delete is processed.',
|
||||
other:
|
||||
'The inventories will be in a pending status until the final delete is processed.',
|
||||
})}
|
||||
deleteMessage={
|
||||
<Plural
|
||||
value={selected.length}
|
||||
one="This invetory is currently being used by some temeplates. Are you sure you want to delete it?"
|
||||
other="Deleting these inventories could impact some templates that rely on them. Are you sure you want to delete anyway?"
|
||||
/>
|
||||
}
|
||||
warningMessage={
|
||||
<Plural
|
||||
value={selected.length}
|
||||
one="The inventory will be in a pending status until the final delete is processed."
|
||||
other="The inventories will be in a pending status until the final delete is processed."
|
||||
/>
|
||||
}
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
@@ -251,15 +258,15 @@ function InventoryList({ i18n }) {
|
||||
<AlertModal
|
||||
isOpen={deletionError}
|
||||
variant="error"
|
||||
aria-label={i18n._(t`Deletion Error`)}
|
||||
title={i18n._(t`Error!`)}
|
||||
aria-label={t`Deletion Error`}
|
||||
title={t`Error!`}
|
||||
onClose={clearDeletionError}
|
||||
>
|
||||
{i18n._(t`Failed to delete one or more inventories.`)}
|
||||
{t`Failed to delete one or more inventories.`}
|
||||
<ErrorDetail error={deletionError} />
|
||||
</AlertModal>
|
||||
</PageSection>
|
||||
);
|
||||
}
|
||||
|
||||
export default withI18n()(InventoryList);
|
||||
export default InventoryList;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import { useParams, useLocation } from 'react-router-dom';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import { t, Plural } from '@lingui/macro';
|
||||
import { Button, Tooltip } from '@patternfly/react-core';
|
||||
|
||||
import useRequest, {
|
||||
@@ -29,7 +28,7 @@ const QS_CONFIG = getQSConfig('inventory', {
|
||||
order_by: 'name',
|
||||
});
|
||||
|
||||
function InventorySourceList({ i18n }) {
|
||||
function InventorySourceList() {
|
||||
const { inventoryType, id } = useParams();
|
||||
const { search } = useLocation();
|
||||
|
||||
@@ -159,7 +158,7 @@ function InventorySourceList({ i18n }) {
|
||||
}
|
||||
items={sources}
|
||||
itemCount={sourceCount}
|
||||
pluralizedItemName={i18n._(t`Inventory Sources`)}
|
||||
pluralizedItemName={t`Inventory Sources`}
|
||||
qsConfig={QS_CONFIG}
|
||||
renderToolbar={props => (
|
||||
<DatalistToolbar
|
||||
@@ -178,27 +177,30 @@ function InventorySourceList({ i18n }) {
|
||||
key="delete"
|
||||
onDelete={handleDelete}
|
||||
itemsToDelete={selected}
|
||||
pluralizedItemName={i18n._(t`Inventory Sources`)}
|
||||
pluralizedItemName={t`Inventory Sources`}
|
||||
deleteDetailsRequests={deleteDetailsRequests}
|
||||
deleteMessage={i18n._(
|
||||
'{numItemsToDelete, plural, one {This inventory source is currently being used by other resources that rely on it. Are you sure you want to delete it?} other {Deleting these inventory sources could impact other resources that rely on them. Are you sure you want to delete anyway?}}',
|
||||
{ numItemsToDelete: selected.length }
|
||||
)}
|
||||
deleteMessage={
|
||||
<Plural
|
||||
value={selected.length}
|
||||
one="This inventory source is currently being used by other resources that rely on it. Are you sure you want to delete it?"
|
||||
other="Deleting these inventory sources could impact other resources that rely on them. Are you sure you want to delete anyway"
|
||||
/>
|
||||
}
|
||||
/>,
|
||||
...(canSyncSources
|
||||
? [
|
||||
<Tooltip
|
||||
key="update"
|
||||
content={i18n._(t`Sync all sources`)}
|
||||
content={t`Sync all sources`}
|
||||
position="top"
|
||||
>
|
||||
<Button
|
||||
ouiaId="sync-all-button"
|
||||
onClick={syncAll}
|
||||
aria-label={i18n._(t`Sync all`)}
|
||||
aria-label={t`Sync all`}
|
||||
variant="secondary"
|
||||
>
|
||||
{i18n._(t`Sync all`)}
|
||||
{t`Sync all`}
|
||||
</Button>
|
||||
</Tooltip>,
|
||||
]
|
||||
@@ -227,30 +229,30 @@ function InventorySourceList({ i18n }) {
|
||||
/>
|
||||
{syncError && (
|
||||
<AlertModal
|
||||
aria-label={i18n._(t`Sync error`)}
|
||||
aria-label={t`Sync error`}
|
||||
isOpen={syncError}
|
||||
variant="error"
|
||||
title={i18n._(t`Error!`)}
|
||||
title={t`Error!`}
|
||||
onClose={dismissError}
|
||||
>
|
||||
{i18n._(t`Failed to sync some or all inventory sources.`)}
|
||||
{t`Failed to sync some or all inventory sources.`}
|
||||
<ErrorDetail error={syncError} />
|
||||
</AlertModal>
|
||||
)}
|
||||
|
||||
{(deletionError || deleteRelatedResourcesError) && (
|
||||
<AlertModal
|
||||
aria-label={i18n._(t`Delete error`)}
|
||||
aria-label={t`Delete error`}
|
||||
isOpen={deletionError || deleteRelatedResourcesError}
|
||||
variant="error"
|
||||
title={i18n._(t`Error!`)}
|
||||
title={t`Error!`}
|
||||
onClose={clearDeletionError}
|
||||
>
|
||||
{i18n._(t`Failed to delete one or more inventory sources.`)}
|
||||
{t`Failed to delete one or more inventory sources.`}
|
||||
<ErrorDetail error={deletionError || deleteRelatedResourcesError} />
|
||||
</AlertModal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
export default withI18n()(InventorySourceList);
|
||||
export default InventorySourceList;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import { useLocation, useRouteMatch } from 'react-router-dom';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import { t, Plural } from '@lingui/macro';
|
||||
import { Card, PageSection } from '@patternfly/react-core';
|
||||
|
||||
import { OrganizationsAPI } from '../../../api';
|
||||
@@ -27,7 +26,7 @@ const QS_CONFIG = getQSConfig('organization', {
|
||||
order_by: 'name',
|
||||
});
|
||||
|
||||
function OrganizationsList({ i18n }) {
|
||||
function OrganizationsList() {
|
||||
const location = useLocation();
|
||||
const match = useRouteMatch();
|
||||
|
||||
@@ -130,24 +129,24 @@ function OrganizationsList({ i18n }) {
|
||||
hasContentLoading={hasContentLoading}
|
||||
items={organizations}
|
||||
itemCount={organizationCount}
|
||||
pluralizedItemName={i18n._(t`Organizations`)}
|
||||
pluralizedItemName={t`Organizations`}
|
||||
qsConfig={QS_CONFIG}
|
||||
toolbarSearchColumns={[
|
||||
{
|
||||
name: i18n._(t`Name`),
|
||||
name: t`Name`,
|
||||
key: 'name__icontains',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Description`),
|
||||
name: t`Description`,
|
||||
key: 'description__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Created By (Username)`),
|
||||
name: t`Created By (Username)`,
|
||||
key: 'created_by__username__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Modified By (Username)`),
|
||||
name: t`Modified By (Username)`,
|
||||
key: 'modified_by__username__icontains',
|
||||
},
|
||||
]}
|
||||
@@ -155,10 +154,10 @@ function OrganizationsList({ i18n }) {
|
||||
toolbarRelatedSearchableKeys={relatedSearchableKeys}
|
||||
headerRow={
|
||||
<HeaderRow qsConfig={QS_CONFIG}>
|
||||
<HeaderCell sortKey="name">{i18n._(t`Name`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Members`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Teams`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Actions`)}</HeaderCell>
|
||||
<HeaderCell sortKey="name">{t`Name`}</HeaderCell>
|
||||
<HeaderCell>{t`Members`}</HeaderCell>
|
||||
<HeaderCell>{t`Teams`}</HeaderCell>
|
||||
<HeaderCell>{t`Actions`}</HeaderCell>
|
||||
</HeaderRow>
|
||||
}
|
||||
renderToolbar={props => (
|
||||
@@ -176,12 +175,15 @@ function OrganizationsList({ i18n }) {
|
||||
key="delete"
|
||||
onDelete={handleOrgDelete}
|
||||
itemsToDelete={selected}
|
||||
pluralizedItemName={i18n._(t`Organizations`)}
|
||||
pluralizedItemName={t`Organizations`}
|
||||
deleteDetailsRequests={deleteDetailsRequests}
|
||||
deleteMessage={i18n._(
|
||||
'{numItemsToDelete, plural, one {This organization is currently being by other resources. Are you sure you want to delete it?} other {Deleting these organizations could impact other resources that rely on them. Are you sure you want to delete anyway?}}',
|
||||
{ numItemsToDelete: selected.length }
|
||||
)}
|
||||
deleteMessage={
|
||||
<Plural
|
||||
value={selected.length}
|
||||
one="This organization is currently being by other resources. Are you sure you want to delete it?"
|
||||
other="Deleting these organizations could impact other resources that rely on them. Are you sure you want to delete anyway?"
|
||||
/>
|
||||
}
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
@@ -205,10 +207,10 @@ function OrganizationsList({ i18n }) {
|
||||
<AlertModal
|
||||
isOpen={deletionError}
|
||||
variant="error"
|
||||
title={i18n._(t`Error!`)}
|
||||
title={t`Error!`}
|
||||
onClose={clearDeletionError}
|
||||
>
|
||||
{i18n._(t`Failed to delete one or more organizations.`)}
|
||||
{t`Failed to delete one or more organizations.`}
|
||||
<ErrorDetail error={deletionError} />
|
||||
</AlertModal>
|
||||
</>
|
||||
@@ -216,4 +218,4 @@ function OrganizationsList({ i18n }) {
|
||||
}
|
||||
|
||||
export { OrganizationsList as _OrganizationsList };
|
||||
export default withI18n()(OrganizationsList);
|
||||
export default OrganizationsList;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, { Fragment, useState, useEffect, useCallback } from 'react';
|
||||
import { useLocation, useRouteMatch } from 'react-router-dom';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import { t, Plural } from '@lingui/macro';
|
||||
import { Card, PageSection } from '@patternfly/react-core';
|
||||
|
||||
import { ProjectsAPI } from '../../../api';
|
||||
@@ -29,7 +28,7 @@ const QS_CONFIG = getQSConfig('project', {
|
||||
order_by: 'name',
|
||||
});
|
||||
|
||||
function ProjectList({ i18n }) {
|
||||
function ProjectList() {
|
||||
const location = useLocation();
|
||||
const match = useRouteMatch();
|
||||
const [selected, setSelected] = useState([]);
|
||||
@@ -130,52 +129,52 @@ function ProjectList({ i18n }) {
|
||||
hasContentLoading={hasContentLoading}
|
||||
items={projects}
|
||||
itemCount={itemCount}
|
||||
pluralizedItemName={i18n._(t`Projects`)}
|
||||
pluralizedItemName={t`Projects`}
|
||||
qsConfig={QS_CONFIG}
|
||||
onRowClick={handleSelect}
|
||||
toolbarSearchColumns={[
|
||||
{
|
||||
name: i18n._(t`Name`),
|
||||
name: t`Name`,
|
||||
key: 'name__icontains',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Description`),
|
||||
name: t`Description`,
|
||||
key: 'description__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Type`),
|
||||
name: t`Type`,
|
||||
key: 'or__scm_type',
|
||||
options: [
|
||||
[``, i18n._(t`Manual`)],
|
||||
[`git`, i18n._(t`Git`)],
|
||||
[`svn`, i18n._(t`Subversion`)],
|
||||
[`archive`, i18n._(t`Remote Archive`)],
|
||||
[`insights`, i18n._(t`Red Hat Insights`)],
|
||||
[``, t`Manual`],
|
||||
[`git`, t`Git`],
|
||||
[`svn`, t`Subversion`],
|
||||
[`archive`, t`Remote Archive`],
|
||||
[`insights`, t`Red Hat Insights`],
|
||||
],
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Source Control URL`),
|
||||
name: t`Source Control URL`,
|
||||
key: 'scm_url__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Modified By (Username)`),
|
||||
name: t`Modified By (Username)`,
|
||||
key: 'modified_by__username__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Created By (Username)`),
|
||||
name: t`Created By (Username)`,
|
||||
key: 'created_by__username__icontains',
|
||||
},
|
||||
]}
|
||||
toolbarSearchableKeys={searchableKeys}
|
||||
toolbarRelatedSearchableKeys={relatedSearchableKeys}
|
||||
headerRow={
|
||||
<HeaderRow qsConfig={QS_CONFIG} isExpandable>
|
||||
<HeaderCell sortKey="name">{i18n._(t`Name`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Status`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Type`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Revision`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Actions`)}</HeaderCell>
|
||||
<HeaderRow qsConfig={QS_CONFIG}>
|
||||
<HeaderCell sortKey="name">{t`Name`}</HeaderCell>
|
||||
<HeaderCell>{t`Status`}</HeaderCell>
|
||||
<HeaderCell>{t`Type`}</HeaderCell>
|
||||
<HeaderCell>{t`Revision`}</HeaderCell>
|
||||
<HeaderCell>{t`Actions`}</HeaderCell>
|
||||
</HeaderRow>
|
||||
}
|
||||
renderToolbar={props => (
|
||||
@@ -198,12 +197,15 @@ function ProjectList({ i18n }) {
|
||||
key="delete"
|
||||
onDelete={handleProjectDelete}
|
||||
itemsToDelete={selected}
|
||||
pluralizedItemName={i18n._(t`Projects`)}
|
||||
pluralizedItemName={t`Projects`}
|
||||
deleteDetailsRequests={deleteDetailsRequests}
|
||||
deleteMessage={i18n._(
|
||||
'{numItemsToDelete, plural, one {This project is currently being used by other resources. Are you sure you want to delete it?} other {Deleting these projects could impact other resources that rely on them. Are you sure you want to delete anyway?}}',
|
||||
{ numItemsToDelete: selected.length }
|
||||
)}
|
||||
deleteMessage={
|
||||
<Plural
|
||||
value={selected.length}
|
||||
one="This project is currently being used by other resources. Are you sure you want to delete it?"
|
||||
other="Deleting these projects could impact other resources that rely on them. Are you sure you want to delete anyway?"
|
||||
/>
|
||||
}
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
@@ -230,15 +232,15 @@ function ProjectList({ i18n }) {
|
||||
<AlertModal
|
||||
isOpen={deletionError}
|
||||
variant="error"
|
||||
aria-label={i18n._(t`Deletion Error`)}
|
||||
title={i18n._(t`Error!`)}
|
||||
aria-label={t`Deletion Error`}
|
||||
title={t`Error!`}
|
||||
onClose={clearDeletionError}
|
||||
>
|
||||
{i18n._(t`Failed to delete one or more projects.`)}
|
||||
{t`Failed to delete one or more projects.`}
|
||||
<ErrorDetail error={deletionError} />
|
||||
</AlertModal>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default withI18n()(ProjectList);
|
||||
export default ProjectList;
|
||||
|
||||
+23
-20
@@ -1,7 +1,6 @@
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import { useLocation, useRouteMatch } from 'react-router-dom';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import { t, Plural } from '@lingui/macro';
|
||||
import { Card, PageSection } from '@patternfly/react-core';
|
||||
import { WorkflowApprovalsAPI } from '../../../api';
|
||||
import PaginatedTable, {
|
||||
@@ -29,7 +28,7 @@ const QS_CONFIG = getQSConfig('workflow_approvals', {
|
||||
order_by: '-started',
|
||||
});
|
||||
|
||||
function WorkflowApprovalsList({ i18n }) {
|
||||
function WorkflowApprovalsList() {
|
||||
const location = useLocation();
|
||||
const match = useRouteMatch();
|
||||
|
||||
@@ -167,17 +166,17 @@ function WorkflowApprovalsList({ i18n }) {
|
||||
}
|
||||
items={workflowApprovals}
|
||||
itemCount={count}
|
||||
pluralizedItemName={i18n._(t`Workflow Approvals`)}
|
||||
pluralizedItemName={t`Workflow Approvals`}
|
||||
qsConfig={QS_CONFIG}
|
||||
onRowClick={handleSelect}
|
||||
toolbarSearchColumns={[
|
||||
{
|
||||
name: i18n._(t`Name`),
|
||||
name: t`Name`,
|
||||
key: 'name__icontains',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Description`),
|
||||
name: t`Description`,
|
||||
key: 'description__icontains',
|
||||
},
|
||||
]}
|
||||
@@ -207,24 +206,28 @@ function WorkflowApprovalsList({ i18n }) {
|
||||
key="delete"
|
||||
onDelete={handleDelete}
|
||||
itemsToDelete={selected}
|
||||
pluralizedItemName={i18n._(t`Workflow Approvals`)}
|
||||
pluralizedItemName={t`Workflow Approvals`}
|
||||
cannotDelete={item =>
|
||||
item.status === 'pending' ||
|
||||
!item.summary_fields.user_capabilities.delete
|
||||
}
|
||||
errorMessage={i18n._(
|
||||
t`These approvals cannot be deleted due to insufficient permissions or a pending job status`
|
||||
)}
|
||||
errorMessage={
|
||||
<Plural
|
||||
value={selected.length}
|
||||
one="This approval cannot be deleted due to insufficient permissions or a pending job status"
|
||||
other="These approvals cannot be deleted due to insufficient permissions or a pending job status"
|
||||
/>
|
||||
}
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
headerRow={
|
||||
<HeaderRow qsConfig={QS_CONFIG}>
|
||||
<HeaderCell sortKey="name">{i18n._(t`Name`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Job`)}</HeaderCell>
|
||||
<HeaderCell sortKey="started">{i18n._(t`Started`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Status`)}</HeaderCell>
|
||||
<HeaderCell sortKey="name">{t`Name`}</HeaderCell>
|
||||
<HeaderCell>{t`Job`}</HeaderCell>
|
||||
<HeaderCell sortKey="started">{t`Started`}</HeaderCell>
|
||||
<HeaderCell>{t`Status`}</HeaderCell>
|
||||
</HeaderRow>
|
||||
}
|
||||
renderRow={(workflowApproval, index) => (
|
||||
@@ -247,10 +250,10 @@ function WorkflowApprovalsList({ i18n }) {
|
||||
<AlertModal
|
||||
isOpen={deletionError}
|
||||
variant="error"
|
||||
title={i18n._(t`Error!`)}
|
||||
title={t`Error!`}
|
||||
onClose={clearDeletionError}
|
||||
>
|
||||
{i18n._(t`Failed to delete one or more workflow approval.`)}
|
||||
{t`Failed to delete one or more workflow approval.`}
|
||||
<ErrorDetail error={deletionError} />
|
||||
</AlertModal>
|
||||
)}
|
||||
@@ -258,12 +261,12 @@ function WorkflowApprovalsList({ i18n }) {
|
||||
<AlertModal
|
||||
isOpen={actionError}
|
||||
variant="error"
|
||||
title={i18n._(t`Error!`)}
|
||||
title={t`Error!`}
|
||||
onClose={dismissActionError}
|
||||
>
|
||||
{approveApprovalError
|
||||
? i18n._(t`Failed to approve one or more workflow approval.`)
|
||||
: i18n._(t`Failed to deny one or more workflow approval.`)}
|
||||
? t`Failed to approve one or more workflow approval.`
|
||||
: t`Failed to deny one or more workflow approval.`}
|
||||
<ErrorDetail error={actionError} />
|
||||
</AlertModal>
|
||||
)}
|
||||
@@ -271,4 +274,4 @@ function WorkflowApprovalsList({ i18n }) {
|
||||
);
|
||||
}
|
||||
|
||||
export default withI18n()(WorkflowApprovalsList);
|
||||
export default WorkflowApprovalsList;
|
||||
|
||||
Reference in New Issue
Block a user