diff --git a/daiquiri/core/assets/js/api/BaseApi.js b/daiquiri/core/assets/js/api/BaseApi.js index b8b61021..65a05ccd 100644 --- a/daiquiri/core/assets/js/api/BaseApi.js +++ b/daiquiri/core/assets/js/api/BaseApi.js @@ -15,7 +15,7 @@ function ValidationError(errors) { this.errors = errors } -class BaseApi { +export default class BaseApi { static get(url) { return fetch(baseUrl + url).catch(error => { @@ -29,6 +29,18 @@ class BaseApi { }) } + static getText(url) { + return fetch(baseUrl + url).catch(error => { + throw new ApiError(error.message) + }).then(response => { + if (response.ok) { + return response.text() + } else { + throw new ApiError(response.statusText, response.status) + } + }) + } + static post(url, data) { return fetch(baseUrl + url, { method: 'POST', @@ -120,5 +132,3 @@ class BaseApi { } } - -export default BaseApi diff --git a/daiquiri/core/assets/js/api/CoreApi.js b/daiquiri/core/assets/js/api/CoreApi.js new file mode 100644 index 00000000..485a8f43 --- /dev/null +++ b/daiquiri/core/assets/js/api/CoreApi.js @@ -0,0 +1,20 @@ +import BaseApi from './BaseApi' + +import { encodeParams } from 'daiquiri/core/assets/js/utils/api' + +export default class CoreApi extends BaseApi { + + static fetchDataLinks(dataLinkId) { + const params = { + 'ID': dataLinkId, + 'RESPONSEFORMAT': 'application/json' + } + + return this.get(`/datalink/links?${encodeParams(params)}`).then(response => response.links) + } + + static fetchNote(url) { + return this.getText(url) + } + +} diff --git a/daiquiri/core/assets/js/components/table/Table.js b/daiquiri/core/assets/js/components/table/Table.js index 5fbe0b27..128d0f7f 100644 --- a/daiquiri/core/assets/js/components/table/Table.js +++ b/daiquiri/core/assets/js/components/table/Table.js @@ -1,14 +1,95 @@ -import React from 'react' +import React, { useState, useEffect } from 'react' import PropTypes from 'prop-types' import { isEmpty } from 'lodash' +import { useModal } from 'daiquiri/core/assets/js/hooks/modal' + +import { getFileUrl, isDataLinkColumn, isImageColumn, isNoteColumn, isModalColumn } from '../../utils/table.js' + import TableFooter from './TableFooter' import TableHeader from './TableHeader' +import TableModal from './TableModal' import TablePane from './TablePane' const Table = ({ columns, rows, pageSizes, params, setParams }) => { const show = !(isEmpty(columns) || isEmpty(rows)) - const pageCount = rows.count / params.page_size + const pageCount = Math.ceil(rows.count / params.page_size) + + const [modalRef, showModal, hideModal] = useModal() + const [modalValues, setModalValues] = useState({}) + const [active, setActive] = useState({}) + + useEffect(() => { + if (modalRef.current && modalRef.current.classList.contains('show') && modalValues.page == params.page) { + // update the modal if (a) it is shown and (b) if we are not currently changing pages + updateModal(active) + } + }, [active]) + + useEffect(() => { + if (modalRef.current && modalRef.current.classList.contains('show')) { + // always update the modal if the rows change + updateModal(active) + } + }, [rows]) + + const updateModal = ({ rowIndex, columnIndex }) => { + const column = columns[columnIndex] + const value = rows.results[rowIndex][columnIndex] + + if (isModalColumn(column)) { + setModalValues({ + title: value, + dataLinkId: isDataLinkColumn(column) ? value : null, + noteUrl: isNoteColumn(column) ? getFileUrl(column, value) : null, + imageSrc: isImageColumn(column) ? getFileUrl(column, value) : null, + page: params.page, + up: (rowIndex > 0 || params.page > 1), + down: (rowIndex < params.page_size - 1 || params.page < pageCount), + right: columns.filter((c, i) => i > columnIndex).some(isModalColumn), + left: columns.filter((c, i) => i < columnIndex).some(isModalColumn), + }) + } + } + + const handleClick = (rowIndex, columnIndex) => { + setActive({ rowIndex, columnIndex }) + + console.log(isModalColumn(columns[columnIndex])) + + if (isModalColumn(columns[columnIndex])) { + updateModal({ rowIndex, columnIndex }) + showModal() + } + } + + const handleNavigation = (direction) => { + if (direction == 'up') { + if (active.rowIndex > 0) { + setActive({ ...active, rowIndex: active.rowIndex - 1 }) + } else if (params.page > 1) { + setActive({ ...active, rowIndex: params.page_size - 1 }) + setParams({ ...params, page: params.page - 1 }) + } + } else if (direction == 'down') { + if (active.rowIndex < params.page_size - 1) { + setActive({ ...active, rowIndex: active.rowIndex + 1 }) + } else if (params.page < pageCount) { + setActive({ ...active, rowIndex: 0 }) + setParams({ ...params, page: params.page + 1 }) + } + } else if (direction == 'right') { + const columnIndex = columns.findIndex((c, i) => isModalColumn(c) && i > active.columnIndex) + if (columnIndex > 0) { + setActive({ ...active, columnIndex}) + } + } else if (direction == 'left') { + const columnIndex = columns.findIndex((c, i) => isModalColumn(c) && i < active.columnIndex) + if (columnIndex > 0) { + setActive({ ...active, columnIndex}) + } + } + } return show && (
{note}+ } + { + modalValues.imageSrc && ( + + ) + } +