diff --git a/invenio_administration/assets/semantic-ui/js/invenio_administration/api/actions.js b/invenio_administration/assets/semantic-ui/js/invenio_administration/api/actions.js index 1c140ae..6517f30 100644 --- a/invenio_administration/assets/semantic-ui/js/invenio_administration/api/actions.js +++ b/invenio_administration/assets/semantic-ui/js/invenio_administration/api/actions.js @@ -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 = () => {}; @@ -30,5 +27,5 @@ export const InvenioAdministrationActionsApi = { deleteResource: deleteResource, editResource: editResource, getResource: getResource, + searchResource: searchResource, }; - diff --git a/invenio_administration/assets/semantic-ui/js/invenio_administration/api/config.js b/invenio_administration/assets/semantic-ui/js/invenio_administration/api/config.js index 5130261..98cffc4 100644 --- a/invenio_administration/assets/semantic-ui/js/invenio_administration/api/config.js +++ b/invenio_administration/assets/semantic-ui/js/invenio_administration/api/config.js @@ -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", }, }; diff --git a/invenio_administration/assets/semantic-ui/js/invenio_administration/api/routes.js b/invenio_administration/assets/semantic-ui/js/invenio_administration/api/routes.js index ee803ee..55896ac 100644 --- a/invenio_administration/assets/semantic-ui/js/invenio_administration/api/routes.js +++ b/invenio_administration/assets/semantic-ui/js/invenio_administration/api/routes.js @@ -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, +}; diff --git a/invenio_administration/assets/semantic-ui/js/invenio_administration/dashboard/TableListView.js b/invenio_administration/assets/semantic-ui/js/invenio_administration/dashboard/TableListView.js new file mode 100644 index 0000000..d614474 --- /dev/null +++ b/invenio_administration/assets/semantic-ui/js/invenio_administration/dashboard/TableListView.js @@ -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 No results found; + }; + + displayTable = () => { + const { hits, sortedFields } = this.state; + + return ( + <> + + + + {sortedFields.map(([property, { text, order }]) => { + return ( + + {text} + + ); + })} + + + + + {hits.map((hit) => { + return ( + + {sortedFields.map(([property, { text, order }]) => { + return {_get(hit, property)}; + })} + + ); + })} + +
+ + ); + }; + + render() { + const { isLoading, hits } = this.state; + const { header } = this.props; + + return ( + +
{header}
+ {isLoading ? ( + + ) : !_isEmpty(hits) ? ( + this.displayTable() + ) : ( + this.displayNoHits() + )} +
+ ); + } +} + +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(, rootElement); +} diff --git a/invenio_administration/assets/semantic-ui/js/invenio_administration/dashboard/index.js b/invenio_administration/assets/semantic-ui/js/invenio_administration/dashboard/index.js new file mode 100644 index 0000000..132eb5c --- /dev/null +++ b/invenio_administration/assets/semantic-ui/js/invenio_administration/dashboard/index.js @@ -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); diff --git a/invenio_administration/templates/semantic-ui/invenio_administration/dashboard/dashboard.html b/invenio_administration/templates/semantic-ui/invenio_administration/dashboard/dashboard.html index 1fc8856..efb230b 100644 --- a/invenio_administration/templates/semantic-ui/invenio_administration/dashboard/dashboard.html +++ b/invenio_administration/templates/semantic-ui/invenio_administration/dashboard/dashboard.html @@ -9,6 +9,16 @@ {% block admin_page_content %} -Put content here +
+ +
+
TEST
+
+
{% endblock admin_page_content %} + +{% block javascript %} + {{ super() }} + {{ webpack['invenio-administration-dashboard.js'] }} +{% endblock %} \ No newline at end of file diff --git a/invenio_administration/webpack.py b/invenio_administration/webpack.py index e77a087..0275aa0 100644 --- a/invenio_administration/webpack.py +++ b/invenio_administration/webpack.py @@ -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" },