forked from Katello/katello
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #29298 - Add new Content View table
This adds a new content view table using patternfly 4 to the page "/labs/content_views"
- Loading branch information
John Mitsch
committed
May 6, 2020
1 parent
e39a522
commit 44f7120
Showing
40 changed files
with
1,091 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
webpack/foremanReact |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,3 +58,4 @@ node_modules | |
npm-debug.log | ||
/foreman/ | ||
package-lock.json | ||
webpack/foremanReact/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { | ||
selectAPIStatus, | ||
selectAPIError, | ||
selectAPIResponse, | ||
} from 'foremanReact/redux/API/APISelectors'; | ||
import CONTENT_VIEWS_KEY from './ContentViewsConstants'; | ||
|
||
export const selectContentViews = state => | ||
selectAPIResponse(state, CONTENT_VIEWS_KEY).results || []; | ||
|
||
export const selectContentViewStatus = state => selectAPIStatus(state, CONTENT_VIEWS_KEY); | ||
|
||
export const selectContentViewError = state => selectAPIError(state, CONTENT_VIEWS_KEY); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { API_OPERATIONS, get } from 'foremanReact/redux/API'; | ||
import api, { orgId } from '../../services/api'; | ||
import CONTENT_VIEWS_KEY from './ContentViewsConstants'; | ||
|
||
|
||
const createContentViewsParams = () => ({ | ||
organization_id: orgId(), | ||
nondefault: true, | ||
}); | ||
|
||
const getContentViews = () => get({ | ||
type: API_OPERATIONS.GET, | ||
key: CONTENT_VIEWS_KEY, | ||
url: api.getApiUrl('/content_views'), | ||
params: createContentViewsParams(), | ||
}); | ||
|
||
export default getContentViews; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
const CONTENT_VIEWS_KEY = 'contentViews'; | ||
|
||
export default CONTENT_VIEWS_KEY; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import React, { useEffect } from 'react'; | ||
import { translate as __ } from 'foremanReact/common/I18n'; | ||
import { useSelector, useDispatch } from 'react-redux'; | ||
import getContentViews from './ContentViewsActions'; | ||
import { selectContentViews, | ||
selectContentViewStatus, | ||
selectContentViewError } from './ContentViewSelectors'; | ||
|
||
import ContentViewsTable from './Table/ContentViewsTable'; | ||
|
||
const ContentViewsPage = () => { | ||
const items = useSelector(selectContentViews); | ||
const status = useSelector(selectContentViewStatus); | ||
const error = useSelector(selectContentViewError); | ||
|
||
const dispatch = useDispatch(); | ||
|
||
useEffect(() => { | ||
dispatch(getContentViews()); | ||
}, []); | ||
|
||
return ( | ||
<React.Fragment> | ||
<h1>{__('Content Views')}</h1> | ||
<ContentViewsTable {...{ items, status, error }} /> | ||
</React.Fragment> | ||
); | ||
}; | ||
|
||
export default ContentViewsPage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import React, { useState, useEffect } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { translate as __ } from 'foremanReact/common/I18n'; | ||
import { STATUS } from 'foremanReact/constants'; | ||
|
||
import TableWrapper from './TableWrapper'; | ||
import tableDataGenerator from './tableDataGenerator'; | ||
import actionResolver from './actionResolver'; | ||
|
||
const ContentViewTable = ({ | ||
items, status, error, | ||
}) => { | ||
const [table, setTable] = useState({ rows: [], columns: [] }); | ||
const [rowMapping, setRowMapping] = useState({}); | ||
const loading = status === STATUS.PENDING; | ||
|
||
useEffect( | ||
() => { | ||
if (!loading && items && items.length > 0) { | ||
const { updatedRowMapping, ...tableData } = tableDataGenerator( | ||
items, | ||
rowMapping, | ||
); | ||
setTable(tableData); | ||
setRowMapping(updatedRowMapping); | ||
} | ||
}, | ||
[items, JSON.stringify(rowMapping)], // use JSON to check obj values eq not reference eq | ||
); | ||
|
||
const cvIdFromRow = (rowIdx) => { | ||
const entry = Object.entries(rowMapping).find(item => item[1].rowIndex === rowIdx); | ||
if (entry) return parseInt(entry[0], 10); | ||
return null; | ||
}; | ||
|
||
const onSelect = (event, isSelected, rowId) => { | ||
let rows; | ||
if (rowId === -1) { | ||
rows = table.rows.map(row => ({ ...row, selected: isSelected })); | ||
} else { | ||
rows = [...table.rows]; | ||
rows[rowId].selected = isSelected; | ||
} | ||
|
||
setTable(prevTable => ({ ...prevTable, rows })); | ||
}; | ||
|
||
const onExpand = (_event, rowIndex, colIndex, isOpen) => { | ||
const { rows } = table; | ||
const contentViewId = cvIdFromRow(rowIndex); | ||
// adjust for the selection checkbox cell being counted in the index | ||
const adjustedColIndex = colIndex - 1; | ||
|
||
if (!isOpen) { | ||
setRowMapping((prev) => { | ||
const updatedMap = { ...prev[contentViewId], expandedColumn: adjustedColIndex }; | ||
return { ...prev, [contentViewId]: updatedMap }; | ||
}); | ||
} else { | ||
// remove the row completely by assigning it to a throwaway variable | ||
// eslint-disable-next-line camelcase, no-unused-vars | ||
const { [contentViewId]: _throwaway, ...newMap } = rowMapping; | ||
setRowMapping(newMap); | ||
} | ||
|
||
setTable(prevTable => ({ ...prevTable, rows })); | ||
}; | ||
|
||
const emptyTitle = __("You currently don't have any Content Views."); | ||
const emptyBody = __('A Content View can be added by using the "New content view" button below.'); | ||
|
||
const { rows, columns } = table; | ||
return ( | ||
<TableWrapper | ||
rows={rows} | ||
cells={columns} | ||
status={status} | ||
emptyTitle={emptyTitle} | ||
emptyBody={emptyBody} | ||
onSelect={onSelect} | ||
canSelectAll={false} | ||
onExpand={onExpand} | ||
actionResolver={actionResolver} | ||
error={error} | ||
/> | ||
); | ||
}; | ||
|
||
ContentViewTable.propTypes = { | ||
items: PropTypes.arrayOf(PropTypes.shape({})), | ||
status: PropTypes.string.isRequired, | ||
error: PropTypes.oneOfType([ | ||
PropTypes.shape({}), | ||
PropTypes.string, | ||
]), | ||
}; | ||
|
||
ContentViewTable.defaultProps = { | ||
error: null, | ||
items: [], | ||
}; | ||
|
||
export default ContentViewTable; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import React from 'react'; | ||
import { | ||
Table, | ||
TableHeader, | ||
TableBody, | ||
} from '@patternfly/react-table'; | ||
import PropTypes from 'prop-types'; | ||
import { STATUS } from 'foremanReact/constants'; | ||
|
||
import EmptyStateMessage from '../components/EmptyStateMessage'; | ||
import Loading from '../components/Loading'; | ||
|
||
const TableWrapper = ({ | ||
status, cells, rows, error, emptyTitle, emptyBody, ...extraTableProps | ||
}) => { | ||
if (status === STATUS.PENDING) return (<Loading />); | ||
// Can we display the error message? | ||
if (status === STATUS.ERROR) return (<EmptyStateMessage error={error} />); | ||
// Can we prevent flash of empty row message while rows are loading with data? | ||
if (status === STATUS.RESOLVED && rows.length === 0) { | ||
return (<EmptyStateMessage title={emptyTitle} body={emptyBody} />); | ||
} | ||
|
||
const tableProps = { cells, rows, ...extraTableProps }; | ||
return ( | ||
<Table | ||
aria-label="Content View Table" | ||
className="katello-pf4-table" | ||
{...tableProps} | ||
> | ||
<TableHeader /> | ||
<TableBody /> | ||
</Table> | ||
); | ||
}; | ||
|
||
TableWrapper.propTypes = { | ||
status: PropTypes.string.isRequired, | ||
cells: PropTypes.arrayOf(PropTypes.oneOfType([ | ||
PropTypes.shape({}), | ||
PropTypes.string])).isRequired, | ||
rows: PropTypes.arrayOf(PropTypes.shape({})).isRequired, | ||
error: PropTypes.oneOfType([ | ||
PropTypes.shape({}), | ||
PropTypes.string, | ||
]), | ||
emptyBody: PropTypes.string.isRequired, | ||
emptyTitle: PropTypes.string.isRequired, | ||
}; | ||
|
||
TableWrapper.defaultProps = { | ||
error: null, | ||
}; | ||
|
||
export default TableWrapper; |
Oops, something went wrong.