Skip to content

Commit

Permalink
dashboard: add list records widget
Browse files Browse the repository at this point in the history
  • Loading branch information
jrcastro2 committed Sep 6, 2022
1 parent 8aefcdc commit 7c6b618
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import { APIRoutes } from "./routes";
import { http } from "./config";

const getResource = async (
apiEndpoint,
pid,
) => {
const getResource = async (apiEndpoint, pid) => {
return await http.get(APIRoutes.get(apiEndpoint, pid));
};

const deleteResource = async (
resource,
apiEndpoint,
idKeyPath = "pid"
) => {
return await http.delete(APIRoutes.detailsView(apiEndpoint, resource, idKeyPath));
const searchResource = async (apiEndpoint, query, sort, page, size) => {
return await http.get(APIRoutes.search(apiEndpoint, query, sort, page, size));
};

const editResource = async(apiEndpoint, pid, payload) => {
return await http.put(APIRoutes.get(apiEndpoint,pid), payload);
const deleteResource = async (resource, apiEndpoint, idKeyPath = "pid") => {
return await http.delete(
APIRoutes.detailsView(apiEndpoint, resource, idKeyPath)
);
};

const editResource = async (apiEndpoint, pid, payload) => {
return await http.put(APIRoutes.get(apiEndpoint, pid), payload);
};

const createResource = () => {};
Expand All @@ -30,5 +27,5 @@ export const InvenioAdministrationActionsApi = {
deleteResource: deleteResource,
editResource: editResource,
getResource: getResource,
searchResource: searchResource,
};

Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ const apiConfig = {
withCredentials: true,
xsrfCookieName: "csrftoken",
xsrfHeaderName: "X-CSRFToken",
baseURL: "/",
headers: {
"Accept": "application/json",
Accept: "application/json",
"Content-Type": "application/json",
},
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import _get from "lodash/get";

const APIRoutesGenerators = {
detailsView: (routePrefix, resource, idKeyPath="pid") => {
detailsView: (routePrefix, resource, idKeyPath = "pid") => {
return `${routePrefix}/${_get(resource, idKeyPath)}`;
},
get: (routePrefix, pid) => {
return `${routePrefix}/${pid}`;
},
}
search: (routePrefix, query, sort, page, size) => {
return `${routePrefix}?q=${query}&sort=${sort}&page=${page}&size=${size}`;
},
};

export const APIRoutes = {
...APIRoutesGenerators
}
...APIRoutesGenerators,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import React from "react";
import ReactDOM from "react-dom";
import PropTypes from "prop-types";
import { InvenioAdministrationActionsApi } from "../api/actions";
import { Table, Container, Loader, Header, Message } from "semantic-ui-react";
import _get from "lodash/get";
import _isEmpty from "lodash/isEmpty";
import _upperFirst from "lodash/upperFirst";

export default class TableListView extends React.Component {
constructor() {
super();
this.state = {
hits: [],
isLoading: false,
sortedFields: {},
};
}
fetchValues = async () => {
const { apiEndpoint, query, sort, page, size } = this.props;
return await InvenioAdministrationActionsApi.searchResource(
apiEndpoint,
query,
sort,
page,
size
);
};

sortFields = (fields) =>
Object.entries(fields).sort((a, b) => a[1].order > b[1].order);

async componentDidMount() {
this.setState({ isLoading: true });
const { fields } = this.props;

const response = await this.fetchValues();
const sortedFields = this.sortFields(fields);
this.setState({
hits: response.data.hits.hits,
isLoading: false,
sortedFields: sortedFields,
});
}

displayNoHits = () => {
return <Message>No results found</Message>;
};

displayTable = () => {
const { hits, sortedFields } = this.state;

return (
<>
<Table>
<Table.Header>
<Table.Row>
{sortedFields.map(([property, { text, order }]) => {
return (
<Table.HeaderCell data-testid={`header-${property}`}>
{text}
</Table.HeaderCell>
);
})}
</Table.Row>
</Table.Header>

<Table.Body>
{hits.map((hit) => {
return (
<Table.Row>
{sortedFields.map(([property, { text, order }]) => {
return <Table.Cell>{_get(hit, property)}</Table.Cell>;
})}
</Table.Row>
);
})}
</Table.Body>
</Table>
</>
);
};

render() {
const { isLoading, hits } = this.state;
const { header } = this.props;

return (
<Container>
<Header>{header}</Header>
{isLoading ? (
<Loader active />
) : !_isEmpty(hits) ? (
this.displayTable()
) : (
this.displayNoHits()
)}
</Container>
);
}
}

TableListView.propTypes = {
apiEndpoint: PropTypes.string.isRequired,
fields: PropTypes.object.isRequired,
header: PropTypes.string.isRequired,
query: PropTypes.string,
sort: PropTypes.string,
page: PropTypes.number,
size: PropTypes.number,
};

TableListView.defaultProps = {
query: "",
sort: "newest",
page: 1,
size: 5,
};

export function createTableListView(rootElement, props) {
return ReactDOM.render(<TableListView {...props} />, rootElement);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { createTableListView } from "./TableListView";

export { createTableListView };

const featuredCommunitiesDomContainer = document.getElementById(
"featured-communities-table-view-widget"
);
const communityDomContainer = document.getElementById(
"community-table-view-widget"
);
const oaipmhDomContainer = document.getElementById("oaipmh-table-view-widget");

const communityProps = {
header: "New communities",
apiEndpoint: "api/communities",
fields: {
"metadata.title": { text: "Title", order: 1 },
"metadata.type.title.en": { text: "Type", order: 2 },
"access.visibility": { text: "Restriction", order: 3 },
},
};

const featuredCommunitiesProps = {
header: "Featured communities",
apiEndpoint: "/api/communities/featured",
fields: {
"metadata.title": { text: "Title", order: 1 },
},
};

const oaipmhProps = {
header: "OAI-PMH Sets",
apiEndpoint: "api/oaipmh/sets",
fields: {
name: { text: "Name", order: 1 },
spec: { text: "Spec", order: 2 },
description: { text: "Description", order: 2 },
},
sort: "created",
};

createTableListView(featuredCommunitiesDomContainer, featuredCommunitiesProps);
createTableListView(communityDomContainer, communityProps);
createTableListView(oaipmhDomContainer, oaipmhProps);
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@

{% block admin_page_content %}

Put content here
<div class="ui grid">
<div class="eight wide column" id="featured-communities-table-view-widget"> </div>
<div class="eight wide column" id="community-table-view-widget"> </div>
<div class="eight wide column" id="oaipmh-table-view-widget"> TEST</div>
<div class="eight wide column" id="stats-widget-TODO"></div>
</div>

{% endblock admin_page_content %}

{% block javascript %}
{{ super() }}
{{ webpack['invenio-administration-dashboard.js'] }}
{% endblock %}
2 changes: 2 additions & 0 deletions invenio_administration/webpack.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
entry={
"invenio-administration-search":
"./js/invenio_administration/search/search.js",
"invenio-administration-dashboard":
"./js/invenio_administration/dashboard/index.js",
"base-admin-theme":
"./js/invenio_administration/theme.js"
},
Expand Down

0 comments on commit 7c6b618

Please sign in to comment.