diff --git a/app/components/EntityListDownload/OptionListHeader.js b/app/components/EntityListDownload/OptionListHeader.js
index aabd9e750..9337425a0 100644
--- a/app/components/EntityListDownload/OptionListHeader.js
+++ b/app/components/EntityListDownload/OptionListHeader.js
@@ -9,7 +9,7 @@ import PropTypes from 'prop-types';
import { Box, Text } from 'grommet';
import styled from 'styled-components';
-import IndeterminateCheckbox, { STATES } from 'components/forms/IndeterminateCheckbox';
+import IndeterminateCheckbox, { STATES } from 'components/formik/IndeterminateCheckbox';
const Checkbox = styled(IndeterminateCheckbox)`
vertical-align: middle;
`;
diff --git a/app/components/EntityListMain/EntityListGroups/EntityListHeader/ColumnSelect/index.js b/app/components/EntityListMain/EntityListGroups/EntityListHeader/ColumnSelect/index.js
index bfd55ba31..e10178fb7 100644
--- a/app/components/EntityListMain/EntityListGroups/EntityListHeader/ColumnSelect/index.js
+++ b/app/components/EntityListMain/EntityListGroups/EntityListHeader/ColumnSelect/index.js
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import styled from 'styled-components';
import { FormattedMessage, injectIntl } from 'react-intl';
-import IndeterminateCheckbox from 'components/forms/IndeterminateCheckbox';
+import IndeterminateCheckbox from 'components/formik/IndeterminateCheckbox';
import SelectReset from 'components/SelectReset';
import ButtonFlatIconOnly from 'components/buttons/ButtonFlatIconOnly';
import Icon from 'components/Icon';
diff --git a/app/components/EntityListMain/EntityListGroups/EntityListHeader/index.js b/app/components/EntityListMain/EntityListGroups/EntityListHeader/index.js
index 5fcc4ebb6..548638ee4 100644
--- a/app/components/EntityListMain/EntityListGroups/EntityListHeader/index.js
+++ b/app/components/EntityListMain/EntityListGroups/EntityListHeader/index.js
@@ -8,7 +8,7 @@ import { palette } from 'styled-theme';
import { getSortOption } from 'utils/sort';
import appMessage from 'utils/app-message';
-import { STATES as CHECKBOX_STATES } from 'components/forms/IndeterminateCheckbox';
+import { STATES as CHECKBOX_STATES } from 'components/formik/IndeterminateCheckbox';
import { SORT_ORDER_OPTIONS } from 'containers/App/constants';
import { COLUMN_WIDTHS } from 'themes/config';
diff --git a/app/components/EntityListSidebar/editOptionsFactory.js b/app/components/EntityListSidebar/editOptionsFactory.js
index 3951c57c3..8b40312c4 100644
--- a/app/components/EntityListSidebar/editOptionsFactory.js
+++ b/app/components/EntityListSidebar/editOptionsFactory.js
@@ -1,5 +1,5 @@
import { find, forEach } from 'lodash/collection';
-import { STATES as CHECKBOX } from 'components/forms/IndeterminateCheckbox';
+import { STATES as CHECKBOX } from 'components/formik/IndeterminateCheckbox';
import { startsWith } from 'utils/string';
import {
@@ -10,7 +10,7 @@ import {
getEntityParentId,
} from 'utils/entities';
import { qe } from 'utils/quasi-equals';
-import { makeTagFilterGroups } from 'utils/forms';
+import { makeTagFilterGroups } from 'utils/formik';
export const checkedState = (count, length) => {
if (count === length) {
diff --git a/app/components/EntityListSidebar/filterOptionsFactory.js b/app/components/EntityListSidebar/filterOptionsFactory.js
index e4e1d56c9..f01104306 100644
--- a/app/components/EntityListSidebar/filterOptionsFactory.js
+++ b/app/components/EntityListSidebar/filterOptionsFactory.js
@@ -16,7 +16,7 @@ import {
getEntityParentId,
} from 'utils/entities';
import { qe } from 'utils/quasi-equals';
-import { makeTagFilterGroups } from 'utils/forms';
+import { makeTagFilterGroups } from 'utils/formik';
import {
optionChecked,
diff --git a/app/components/formik/DateControl/index.js b/app/components/formik/DateControl/index.js
index b54c52b94..44f1f7832 100644
--- a/app/components/formik/DateControl/index.js
+++ b/app/components/formik/DateControl/index.js
@@ -4,7 +4,7 @@ import { toLower } from 'lodash/string';
// eslint-disable-next-line import/no-unresolved
import { isValid, format, parse, startOfToday, getYear, getMonth } from 'date-fns';
-import validateDateFormat from 'components/forms/validators/validate-date-format';
+import validateDateFormat from 'components/formik/validators/validate-date-format';
import { DayPicker } from 'react-day-picker';
import { useField, useFormikContext } from "formik";
diff --git a/app/components/formik/RadioControl/index.js b/app/components/formik/RadioControl/index.js
index 624c981dd..d78a4cd34 100644
--- a/app/components/formik/RadioControl/index.js
+++ b/app/components/formik/RadioControl/index.js
@@ -1,9 +1,11 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Field } from 'react-redux-form/immutable';
+
import styled from 'styled-components';
import { palette } from 'styled-theme';
+const StyledWrapper = styled.span``;
+
const Option = styled.div`
padding: 0.25em 0;
`;
@@ -21,20 +23,23 @@ const Label = styled.label`
const LabelInner = styled.span`
padding-left: 5px;
`;
-
+const Input = styled.input`
+`;
export class RadioControl extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
render() {
- const { model, options, hints } = this.props;
+ const { options, hints, onChange, name, value } = this.props;
return (
-
+
{
options && options.map((option, i) => (
+
);
}
}
RadioControl.propTypes = {
- model: PropTypes.string.isRequired,
options: PropTypes.array.isRequired,
hints: PropTypes.object,
+ onChange: PropTypes.func,
+ name: PropTypes.string,
+ value: PropTypes.string,
};
-export default RadioControl;
+export default RadioControl;
\ No newline at end of file
diff --git a/app/components/forms/AuthForm/index.js b/app/components/forms/AuthForm/index.js
deleted file mode 100644
index 0ec4952ab..000000000
--- a/app/components/forms/AuthForm/index.js
+++ /dev/null
@@ -1,124 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { FormattedMessage } from 'react-intl';
-import { Form, Errors } from 'react-redux-form/immutable';
-import styled from 'styled-components';
-
-import { omit } from 'lodash/object';
-import { startCase } from 'lodash/string';
-
-import appMessages from 'containers/App/messages';
-
-import ButtonCancel from 'components/buttons/ButtonCancel';
-import ButtonSubmit from 'components/buttons/ButtonSubmit';
-import Clear from 'components/styled/Clear';
-import Main from 'components/EntityView/Main';
-import ViewPanel from 'components/EntityView/ViewPanel';
-import FieldGroupWrapper from 'components/fields/FieldGroupWrapper';
-import Field from 'components/fields/Field';
-
-import ErrorWrapper from '../ErrorWrapper';
-import FormWrapper from '../FormWrapper';
-import FormBody from '../FormBody';
-import FormFooter from '../FormFooter';
-import FormFooterButtons from '../FormFooterButtons';
-import Label from '../Label';
-import Required from '../Required';
-import ControlInput from '../ControlInput';
-
-// These props will be omitted before being passed to the Control component
-const nonControlProps = ['hint', 'label', 'component', 'controlType', 'children', 'errorMessages'];
-
-const StyledForm = styled(Form)`
- display: table;
- width: 100%;
-`;
-
-class AuthForm extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
- renderField = (field) => {
- const { id, model, ...props } = omit(field, nonControlProps);
- return (
-
- );
- }
-
- renderBody = (fields) => (
-
-
-
-
- {fields.map((field, i) => (
-
- { field.label !== false
- && (
-
- )
- }
- {this.renderField(field)}
- {
- field.errorMessages
- && (
-
-
-
- )
- }
-
- ))}
-
-
-
-
- );
-
- render() {
- const {
- fields, model, handleSubmit, handleCancel, labels,
- } = this.props;
- return (
-
-
- { fields && this.renderBody(fields) }
-
-
-
-
-
-
- {labels.submit}
-
-
-
-
-
-
- );
- }
-}
-
-AuthForm.propTypes = {
- handleSubmit: PropTypes.func.isRequired,
- handleCancel: PropTypes.func.isRequired,
- labels: PropTypes.object,
- model: PropTypes.string,
- fields: PropTypes.array,
- sending: PropTypes.bool,
-};
-AuthForm.defaultProps = {
- sending: false,
-};
-export default AuthForm;
diff --git a/app/components/forms/ControlCheckbox.js b/app/components/forms/ControlCheckbox.js
deleted file mode 100644
index 8d5f92c06..000000000
--- a/app/components/forms/ControlCheckbox.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import { Control } from 'react-redux-form/immutable';
-import styled from 'styled-components';
-
-const ControlCheckbox = styled(Control.checkbox)`
- margin-right: 5px;
-`;
-
-export default ControlCheckbox;
diff --git a/app/components/forms/ControlInput.js b/app/components/forms/ControlInput.js
deleted file mode 100644
index c8a8587c3..000000000
--- a/app/components/forms/ControlInput.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Control } from 'react-redux-form/immutable';
-import styled from 'styled-components';
-import { palette } from 'styled-theme';
-
-const ControlInput = styled(Control.input)`
- background-color: ${palette('background', 0)};
- width: 100%;
- border: 1px solid ${palette('light', 1)};
- padding: 0.7em;
- border-radius: 0.5em;
-`;
-
-export default ControlInput;
diff --git a/app/components/forms/ControlLink.js b/app/components/forms/ControlLink.js
deleted file mode 100644
index 9a3018ee2..000000000
--- a/app/components/forms/ControlLink.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import styled from 'styled-components';
-import A from 'components/styled/A';
-
-const ControlMain = styled(A)``;
-
-export default class ControlLink extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
- static propTypes = {
- text: PropTypes.string,
- path: PropTypes.string,
- onClick: PropTypes.func.isRequired,
- }
-
- render() {
- return (
- {
- if (evt !== undefined && evt.preventDefault) evt.preventDefault();
- this.props.onClick();
- }}
- >
- {this.props.text}
-
- );
- }
-}
diff --git a/app/components/forms/ControlSelect.js b/app/components/forms/ControlSelect.js
deleted file mode 100644
index 463fcd7ff..000000000
--- a/app/components/forms/ControlSelect.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Control } from 'react-redux-form/immutable';
-import styled from 'styled-components';
-
-const ControlSelect = styled(Control.select)`
- background:#ffffff;
- border:1px solid #E0E1E2;
- color:#000;
- padding:5px;
-`;
-
-export default ControlSelect;
diff --git a/app/components/forms/ControlShort.js b/app/components/forms/ControlShort.js
deleted file mode 100644
index fa191a747..000000000
--- a/app/components/forms/ControlShort.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import styled from 'styled-components';
-import ControlInput from './ControlInput';
-
-const ControlShort = styled(ControlInput)`
- max-width: 120px;
-`;
-export default ControlShort;
diff --git a/app/components/forms/ControlTextArea.js b/app/components/forms/ControlTextArea.js
deleted file mode 100644
index 2129873fe..000000000
--- a/app/components/forms/ControlTextArea.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Control } from 'react-redux-form/immutable';
-import styled from 'styled-components';
-import { palette } from 'styled-theme';
-
-const ControlTextArea = styled(Control.textarea)`
- background-color: ${palette('background', 0)};
- width: 100%;
- border: 1px solid ${palette('light', 1)};
- padding: 0.7em;
- border-radius: 0.5em;
- min-height: 6em;
- color: ${palette('text', 0)};
-`;
-
-export default ControlTextArea;
diff --git a/app/components/forms/ControlTextAreaLarge.js b/app/components/forms/ControlTextAreaLarge.js
deleted file mode 100644
index 881895710..000000000
--- a/app/components/forms/ControlTextAreaLarge.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import styled from 'styled-components';
-import ControlTextArea from './ControlTextArea';
-
-const ControlTextAreaLarge = styled(ControlTextArea)`
- min-height:14em;
-`;
-
-export default ControlTextAreaLarge;
diff --git a/app/components/forms/ControlTitle.js b/app/components/forms/ControlTitle.js
deleted file mode 100644
index 0f93d5710..000000000
--- a/app/components/forms/ControlTitle.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import styled from 'styled-components';
-import ControlInput from './ControlInput';
-
-const ControlTitle = styled(ControlInput)`
- font-size: 1.3em;
- @media print {
- font-size: ${(props) => props.theme.sizes.print.large};
- }
-`;
-
-export default ControlTitle;
diff --git a/app/components/forms/ControlTitleText.js b/app/components/forms/ControlTitleText.js
deleted file mode 100644
index fe8941d0b..000000000
--- a/app/components/forms/ControlTitleText.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import styled from 'styled-components';
-import ControlTextArea from './ControlTextArea';
-
-const ControlTitleText = styled(ControlTextArea)`
- min-height: 5em;
-`;
-
-export default ControlTitleText;
diff --git a/app/components/forms/DateControl/DatePicker.js b/app/components/forms/DateControl/DatePicker.js
deleted file mode 100644
index b6848865f..000000000
--- a/app/components/forms/DateControl/DatePicker.js
+++ /dev/null
@@ -1,106 +0,0 @@
-import React, { useRef, useState } from 'react';
-import PropTypes from 'prop-types';
-import { toLower } from 'lodash/string';
-// import { useIntl } from 'react-intl';
-
-import {
- isValid, format, parse, startOfToday, getYear, getMonth,
-} from 'date-fns';
-
-import validateDateFormat from 'components/forms/validators/validate-date-format';
-import { DayPicker } from 'react-day-picker';
-
-import { DATE_FORMAT, DB_DATE_FORMAT } from 'themes/config';
-
-import InputComponent from './InputComponent';
-import DatePickerStyle from './styles';
-
-const DatePicker = ({ value, onChange }) => {
- // const intl = useIntl();
- const inputRef = useRef(null);
- const [showDayPicker, setShowDayPicker] = useState(false);
-
- const handleDateChange = (valueDate) => {
- if (valueDate) {
- const formattedDB = format(valueDate, DB_DATE_FORMAT);
- if (formattedDB) {
- setShowDayPicker(false);
- return onChange(formattedDB);
- }
- }
- return null;
- };
-
- const handleInputChange = ({ target }) => {
- const inputValue = target.value;
- // if it's the right format, store as db format
- if (inputValue !== '' && validateDateFormat(inputValue, DATE_FORMAT)) {
- // parse from input format to db format
- const formattedDB = format(
- parse(inputValue, DATE_FORMAT, new Date()),
- DB_DATE_FORMAT,
- );
- onChange(formattedDB);
- } else {
- // wrong format but store value for input field
- onChange(inputValue);
- }
- };
-
- const formattedDay = value
- && validateDateFormat(value, DB_DATE_FORMAT)
- ? format(parse(value, DB_DATE_FORMAT, new Date()), DATE_FORMAT)
- : value;
-
- const selected = validateDateFormat(value, DB_DATE_FORMAT) ? parse(value, DB_DATE_FORMAT, new Date()) : null;
-
- const handleInputFocus = () => {
- setShowDayPicker(true);
- };
-
- const handleInputBlur = (event) => {
- // on click outside, close day picker
- if (!event.currentTarget.contains(event.relatedTarget)) {
- setShowDayPicker(false);
- }
- };
- const getDefaultMonth = (selectedDate) => {
- const defaultDate = isValid(selectedDate) ? selectedDate : startOfToday();
- const year = getYear(defaultDate);
- const month = getMonth(defaultDate);
- return new Date(year, month);
- };
-
- return (
-
-
- {showDayPicker && (
-
- )}
-
-
- );
-};
-
-DatePicker.propTypes = {
- value: PropTypes.string,
- onChange: PropTypes.func.isRequired,
-};
-
-export default DatePicker;
diff --git a/app/components/forms/DateControl/InputComponent.js b/app/components/forms/DateControl/InputComponent.js
deleted file mode 100644
index 722b2338b..000000000
--- a/app/components/forms/DateControl/InputComponent.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import React from 'react';
-
-import styled from 'styled-components';
-import { palette } from 'styled-theme';
-
-const StyledInput = styled.input`
- background-color: ${palette('background', 0)};
- width: 100%;
- border: 1px solid ${palette('light', 1)};
- padding: 0.7em;
- border-radius: 0.5em;
-`;
-
-class InputComponent extends React.Component {
- focus = () => {
- this.input.focus();
- }
-
- render() {
- return (
- { this.input = node; }}
- {...this.props}
- />
- );
- }
-}
-
-export default InputComponent;
diff --git a/app/components/forms/DateControl/index.js b/app/components/forms/DateControl/index.js
deleted file mode 100644
index 5adeceae0..000000000
--- a/app/components/forms/DateControl/index.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import { Control } from 'react-redux-form/immutable';
-
-import DatePicker from './DatePicker';
-
-export class DateControl extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
- render() {
- const { model, ...props } = this.props;
- return (
- cprops.onChange,
- error: ({ fieldValue }) => !fieldValue.valid,
- }}
- {...props}
- />
- );
- }
-}
-
-DateControl.propTypes = {
- model: PropTypes.string.isRequired,
-};
-
-export default DateControl;
diff --git a/app/components/forms/DateControl/styles.js b/app/components/forms/DateControl/styles.js
deleted file mode 100644
index 944c8fbb0..000000000
--- a/app/components/forms/DateControl/styles.js
+++ /dev/null
@@ -1,100 +0,0 @@
-/* Day Picker styles */
-import { createGlobalStyle } from 'styled-components';
-import { palette } from 'styled-theme';
-
-/* eslint no-unused-expressions: 0 */
-/* stylelint-disable */
-const DatePickerStyle = createGlobalStyle`
- .rdp {
- position: absolute;
- }
-
- .rdp-months {
- display: flex;
- position: relative;
- z-index: 1;
- background: white;
- }
- .rdp-month {
- padding: 1rem;
- }
-
- .rdp-nav_button {
- position: absolute;
- width: 1.5rem;
- height: 1.5rem;
- background-repeat: no-repeat;
- background-position: center;
- background-size: contain;
- cursor: pointer;
- }
-
- .rdp-nav_button_previous {
- left: 1rem;
- background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjI2cHgiIGhlaWdodD0iNTBweCIgdmlld0JveD0iMCAwIDI2IDUwIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbG5zOnNrZXRjaD0iaHR0cDovL3d3dy5ib2hlbWlhbmNvZGluZy5jb20vc2tldGNoL25zIj4KICAgIDwhLS0gR2VuZXJhdG9yOiBTa2V0Y2ggMy4zLjIgKDEyMDQzKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5wcmV2PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc2tldGNoOnR5cGU9Ik1TUGFnZSI+CiAgICAgICAgPGcgaWQ9InByZXYiIHNrZXRjaDp0eXBlPSJNU0xheWVyR3JvdXAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEzLjM5MzE5MywgMjUuMDAwMDAwKSBzY2FsZSgtMSwgMSkgdHJhbnNsYXRlKC0xMy4zOTMxOTMsIC0yNS4wMDAwMDApIHRyYW5zbGF0ZSgwLjg5MzE5MywgMC4wMDAwMDApIiBmaWxsPSIjNTY1QTVDIj4KICAgICAgICAgICAgPHBhdGggZD0iTTAsNDkuMTIzNzMzMSBMMCw0NS4zNjc0MzQ1IEwyMC4xMzE4NDU5LDI0LjcyMzA2MTIgTDAsNC4yMzEzODMxNCBMMCwwLjQ3NTA4NDQ1OSBMMjUsMjQuNzIzMDYxMiBMMCw0OS4xMjM3MzMxIEwwLDQ5LjEyMzczMzEgWiIgaWQ9InJpZ2h0IiBza2V0Y2g6dHlwZT0iTVNTaGFwZUdyb3VwIj48L3BhdGg+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4K");
- }
-
- .rdp-nav_button_next {
- right: 1rem;
- background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjI2cHgiIGhlaWdodD0iNTBweCIgdmlld0JveD0iMCAwIDI2IDUwIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbG5zOnNrZXRjaD0iaHR0cDovL3d3dy5ib2hlbWlhbmNvZGluZy5jb20vc2tldGNoL25zIj4KICAgIDwhLS0gR2VuZXJhdG9yOiBTa2V0Y2ggMy4zLjIgKDEyMDQzKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5uZXh0PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc2tldGNoOnR5cGU9Ik1TUGFnZSI+CiAgICAgICAgPGcgaWQ9Im5leHQiIHNrZXRjaDp0eXBlPSJNU0xheWVyR3JvdXAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuOTUxNDUxLCAwLjAwMDAwMCkiIGZpbGw9IiM1NjVBNUMiPgogICAgICAgICAgICA8cGF0aCBkPSJNMCw0OS4xMjM3MzMxIEwwLDQ1LjM2NzQzNDUgTDIwLjEzMTg0NTksMjQuNzIzMDYxMiBMMCw0LjIzMTM4MzE0IEwwLDAuNDc1MDg0NDU5IEwyNSwyNC43MjMwNjEyIEwwLDQ5LjEyMzczMzEgTDAsNDkuMTIzNzMzMSBaIiBpZD0icmlnaHQiIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPgo=");
- }
-
- .rdp-nav_button_interactionDisabled {
- display: none;
- }
-
- .rdp-caption {
- height: 1.5rem;
- text-align: center;
- }
- .rdp-caption_label {
- display: inline;
- }
-
- .rdp-day_today {
- color: ${palette('secondary', 0)};
- font-weight: bold;
- }
- .rdp-day_selected {
- background: ${palette('primary', 0)};
- color: white !important;
- font-weight: normal !important;
- }
-
- .rdp-nav_icon {
- display: none;
- }
-
- .rdp-nav {
- padding: 0.5rem;
- display: inline;
- }
-
- .rdp-head_cell {
- padding: .5rem;
- font-size: .875em;
- text-align: center;
- color: #8b9898;
- }
-
- .rdp-cell {
- text-align: center;
- cursor: pointer;
- vertical-align: middle;
- white-space: nowrap;
- }
-
- .rdp-day {
- padding: .5rem;
- @media (min-width: 769px) {
- padding: .5rem;
- }
- }
-
- .rdp-day_outside {
- opacity: 0.4;
- }
-
-`;
-
-export default DatePickerStyle;
diff --git a/app/components/forms/ErrorWrapper.js b/app/components/forms/ErrorWrapper.js
deleted file mode 100644
index d2c9cd198..000000000
--- a/app/components/forms/ErrorWrapper.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import styled from 'styled-components';
-import { palette } from 'styled-theme';
-
-const ErrorWrapper = styled.div`
- color: ${palette('error', 0)};
- font-size: ${(props) => props.theme.sizes.text.small};
- @media print {
- font-size: ${(props) => props.theme.sizes.print.small};
- }
-`;
-export default ErrorWrapper;
diff --git a/app/components/forms/FormBody.js b/app/components/forms/FormBody.js
deleted file mode 100644
index cc8142de7..000000000
--- a/app/components/forms/FormBody.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import styled from 'styled-components';
-
-const FormBody = styled.div`
- display: table-row-group;
-`;
-export default FormBody;
diff --git a/app/components/forms/FormFieldWrap.js b/app/components/forms/FormFieldWrap.js
deleted file mode 100644
index 070c9b6d3..000000000
--- a/app/components/forms/FormFieldWrap.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import styled from 'styled-components';
-
-const FormFieldWrap = styled.div`
- display: ${({ nested, inline }) => (nested || inline) ? 'inline-block' : 'block'};
- vertical-align: top;
-`;
-
-export default FormFieldWrap;
diff --git a/app/components/forms/FormFooter.js b/app/components/forms/FormFooter.js
deleted file mode 100644
index cc9ea696d..000000000
--- a/app/components/forms/FormFooter.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import styled from 'styled-components';
-import { palette } from 'styled-theme';
-
-const FormFooter = styled.div`
- border-top: 1px solid ${palette('light', 2)};
- position: relative;
- display: table-caption;
- caption-side: bottom;
-`;
-
-export default FormFooter;
diff --git a/app/components/forms/FormFooterButtons.js b/app/components/forms/FormFooterButtons.js
deleted file mode 100644
index 5ef562e8d..000000000
--- a/app/components/forms/FormFooterButtons.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import styled from 'styled-components';
-
-const FormFooterButtons = styled.div`
- text-align: ${(props) => props.left ? 'left' : 'right'};
- float: ${(props) => props.left ? 'left' : 'right'};
-`;
-
-export default FormFooterButtons;
diff --git a/app/components/forms/FormHeader.js b/app/components/forms/FormHeader.js
deleted file mode 100644
index 31dd6533b..000000000
--- a/app/components/forms/FormHeader.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import styled from 'styled-components';
-
-const FormHeader = styled.div`
- min-height:100px;
- border-bottom:1px solid;
-`;
-export default FormHeader;
diff --git a/app/components/forms/FormWrapper.js b/app/components/forms/FormWrapper.js
deleted file mode 100644
index b8492bf81..000000000
--- a/app/components/forms/FormWrapper.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import styled from 'styled-components';
-import { palette } from 'styled-theme';
-
-const FormWrapper = styled.div`
- box-shadow: ${(props) => props.withoutShadow ? 'none' : '0px 0px 15px 0px rgba(0,0,0,0.2)'};
- background-color: ${(props) => props.white ? palette('background', 0) : palette('background', 1)};
- margin-bottom: ${(props) => props.hasMarginBottom ? 200 : 0}px;
- @media print {
- box-shadow: none;
- background-color: transparent;
- }
-`;
-export default FormWrapper;
diff --git a/app/components/forms/ImportEntitiesForm/index.js b/app/components/forms/ImportEntitiesForm/index.js
deleted file mode 100644
index 361ff56e4..000000000
--- a/app/components/forms/ImportEntitiesForm/index.js
+++ /dev/null
@@ -1,321 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { FormattedMessage, injectIntl } from 'react-intl';
-import { Form } from 'react-redux-form/immutable';
-
-import CsvDownloader from 'react-csv-downloader';
-import styled from 'styled-components';
-import { palette } from 'styled-theme';
-
-import { omit } from 'lodash/object';
-import { map } from 'lodash/collection';
-
-import asArray from 'utils/as-array';
-
-import A from 'components/styled/A';
-import Field from 'components/fields/Field';
-
-import ViewPanel from 'components/EntityView/ViewPanel';
-import Main from 'components/EntityView/Main';
-
-import Messages from 'components/Messages';
-import Loading from 'components/Loading';
-
-import DocumentWrap from 'components/fields/DocumentWrap';
-import FieldGroupWrapper from 'components/fields/FieldGroupWrapper';
-
-import ButtonCancel from 'components/buttons/ButtonCancel';
-import ButtonSubmit from 'components/buttons/ButtonSubmit';
-import Clear from 'components/styled/Clear';
-
-import ImportFileSelectControl from '../ImportFileSelectControl';
-import FormWrapper from '../FormWrapper';
-import FormBody from '../FormBody';
-import FormFieldWrap from '../FormFieldWrap';
-import FormFooter from '../FormFooter';
-import FormFooterButtons from '../FormFooterButtons';
-
-import messages from './messages';
-
-const StyledForm = styled(Form)`
- display: table;
- width: 100%;
-`;
-
-const Importing = styled.div``;
-
-const ImportingText = styled.div`
- font-weight: bold;
- font-size: 1em;
- color: ${palette('text', 1)};
- margin-bottom: 0.25em;
- margin-top: -0.5em;
- overflow: hidden;
- @media print {
- font-size: ${(props) => props.theme.sizes.print.default};
- }
-`;
-
-const DocumentWrapEdit = styled(DocumentWrap)`
- background-color: ${palette('background', 0)};
- position: relative;
- padding: 1em 0.75em;
-`;
-
-const FormTitle = styled.h2`
- padding-top: 0;
- margin-top: 0;
-`;
-
-const Intro = styled.div`
- margin-bottom: 10px;
- @media (min-width: ${(props) => props.theme.breakpoints.small}) {
- margin-bottom: 16px;
- font-size: 1.2em;
- }
- @media print {
- font-size: ${(props) => props.theme.sizes.print.large};
- }
-`;
-const Hint = styled.div`
- @media (min-width: ${(props) => props.theme.breakpoints.small}) {
- margin-bottom: 16px;
- font-size: 1.2em;
- }
- @media print {
- font-size: ${(props) => props.theme.sizes.print.large};
- }
-`;
-const CsvDownload = styled.span`
- display: inline-block;
-`;
-const NoteLink = styled(A)`
- color: #BA5D03;
- &:hover {
- color: #BA5D03;
- text-decoration: underline;
- }
-`;
-const RowErrors = styled.div`
- margin-top: 2em;
-`;
-
-const HintList = styled.ul`
- margin: 10px 0;
-`;
-
-const HintTitle = styled.h6`
- margin: 0;
- font-weight: normal;
-`;
-const ErrorHint = styled.div``;
-const ErrorHintTitle = styled.h5``;
-const ErrorHintText = styled.p``;
-
-// These props will be omitted before being passed to the Control component
-const nonControlProps = ['label', 'component', 'controlType', 'children', 'errorMessages'];
-
-export class ImportEntitiesForm extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
- getControlProps = (field) => omit(field, nonControlProps);
-
- render() {
- const {
- model,
- handleSubmit,
- handleCancel,
- handleReset,
- fieldModel,
- template,
- formData,
- progress,
- errors,
- success,
- intl,
- } = this.props;
- const field = {
- id: 'file',
- model: `.${fieldModel}`,
- placeholder: 'filename',
- };
-
- const { id, ...props } = this.getControlProps(field);
-
- return (
-
- data.get('import') !== null && handleSubmit(data)}>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- evt.preventDefault()}>
-
-
-
-
-
-
-
-
-
-
-
-
- { (progress === null)
- && (
-
- )
- }
- { progress !== null
- && (
-
- { progress < 100
- && (
-
-
-
-
- { formData && `"${formData.get('import').file.name}"`}
-
-
-
-
- )
- }
- { progress >= 100
- && (
-
- {(errors.size > 0 && success.size === 0)
- && (
-
- )
- }
- {(errors.size > 0 && success.size > 0)
- && (
-
- )
- }
- {(errors.size === 0)
- && (
-
- )
- }
-
- )
- }
- {(errors.size > 0)
- && (
-
-
- error && error.data && error.data.saveRef)
- .reduce((memo, error) => error.error.messages
- ? memo.concat(map(error.error.messages, (message) => error.data.saveRef
- ? [`${error.data.saveRef}:`, message]
- : message))
- : memo,
- [])
- }
- />
-
- )
- }
- {(errors.size > 0 && progress >= 100)
- && (
-
-
-
-
-
-
-
-
- )
- }
-
- )
- }
-
-
-
-
-
-
- { progress >= 100
- && (
-
-
-
-
-
-
-
-
-
-
-
- )
- }
-
-
- );
- }
-}
-
-ImportEntitiesForm.propTypes = {
- handleSubmit: PropTypes.func.isRequired,
- handleReset: PropTypes.func.isRequired,
- handleCancel: PropTypes.func.isRequired,
- model: PropTypes.string,
- fieldModel: PropTypes.string,
- formData: PropTypes.object,
- progress: PropTypes.number,
- errors: PropTypes.object,
- success: PropTypes.object,
- template: PropTypes.object,
- intl: PropTypes.object.isRequired,
-};
-
-export default injectIntl(ImportEntitiesForm);
diff --git a/app/components/forms/ImportEntitiesForm/messages.js b/app/components/forms/ImportEntitiesForm/messages.js
deleted file mode 100644
index 84defb39b..000000000
--- a/app/components/forms/ImportEntitiesForm/messages.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Form Messages
- *
- */
-import { defineMessages } from 'react-intl';
-
-export default defineMessages({
- title: {
- id: 'app.components.ImportEntitiesForm.title',
- defaultMessage: 'Batch import',
- },
- introduction: {
- id: 'app.components.ImportEntitiesForm.introduction',
- defaultMessage: 'Import multiple items from a CSV file.',
- },
- hintTitle: {
- id: 'app.components.ImportEntitiesForm.hintLabel',
- defaultMessage: 'Please note:',
- },
- templateHint: {
- id: 'app.components.ImportEntitiesForm.templateHint',
- defaultMessage: 'For the available fields and field types please ',
- },
- templateHintDownloadLink: {
- id: 'app.components.ImportEntitiesForm.templateHintDownloadLink',
- defaultMessage: 'download the CSV template',
- },
- formatHint: {
- id: 'app.components.ImportEntitiesForm.formatHint',
- defaultMessage: 'When saving from Excel (Office 2016 or later), chose file type "CSV UTF-8 (Comma delimited)". For instructions for previous versions of Excel (Office 2013 and earlier) please refer to the ',
- },
- formatHintLink: {
- id: 'app.components.ImportEntitiesForm.formatHintLink',
- defaultMessage: 'user-manual.impactoss.org/managers/import.html',
- },
- formatHintLinkAnchor: {
- id: 'app.components.ImportEntitiesForm.formatHintLinkAnchor',
- defaultMessage: 'user manual',
- },
- someErrors: {
- id: 'app.components.ImportEntitiesForm.someErrors',
- defaultMessage: 'We are sorry, only {successNo} of {rowNo} row(s) could be imported.',
- },
- allErrors: {
- id: 'app.components.ImportEntitiesForm.allErrors',
- defaultMessage: 'We are sorry, none of the rows could be imported.',
- },
- success: {
- id: 'app.components.ImportEntitiesForm.success',
- defaultMessage: 'All {rowNo} row(s) successfully imported.',
- },
- importAgain: {
- id: 'app.components.ImportEntitiesForm.importAgain',
- defaultMessage: 'Import another file',
- },
- done: {
- id: 'app.components.ImportEntitiesForm.done',
- defaultMessage: 'Back to list',
- },
- importing: {
- id: 'app.components.ImportEntitiesForm.importing',
- defaultMessage: 'Importing: ',
- },
- rowErrorHint: {
- id: 'app.components.ImportEntitiesForm.rowErrorHint',
- defaultMessage: 'Import of the following rows failed:',
- },
- errorHintTitle: {
- id: 'app.components.ImportEntitiesForm.errorHintTitle',
- defaultMessage: 'Important',
- },
- errorHintText: {
- id: 'app.components.ImportEntitiesForm.errorHintText',
- defaultMessage: 'When using the import feature to add the failed rows, please make sure to first remove the successful rows from your csv file - failure to do so will lead to duplicate entries. Alternatively you can add each failed row individually by manually entering each entry.',
- },
-});
diff --git a/app/components/forms/ImportFileSelectControl/SelectFile.js b/app/components/forms/ImportFileSelectControl/SelectFile.js
deleted file mode 100644
index e935599f0..000000000
--- a/app/components/forms/ImportFileSelectControl/SelectFile.js
+++ /dev/null
@@ -1,179 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { FormattedMessage, injectIntl } from 'react-intl';
-import styled from 'styled-components';
-import { palette } from 'styled-theme';
-import FileReaderInput from 'react-file-reader-input';
-import Papa from 'papaparse';
-
-import Icon from 'components/Icon';
-import ButtonSubmit from 'components/buttons/ButtonSubmit';
-import ButtonFlatIconOnly from 'components/buttons/ButtonFlatIconOnly';
-import ButtonDefaultWithIcon from 'components/buttons/ButtonDefaultWithIcon';
-
-import DocumentWrap from 'components/fields/DocumentWrap';
-import Messages from 'components/Messages';
-
-import messages from './messages';
-
-
-const Styled = styled.div`
- padding-top: 1em;
- display: block;
-`;
-
-const DocumentWrapEdit = styled(DocumentWrap)`
- background-color: ${palette('background', 0)};
- position: relative;
- padding: 0;
- border: 1px solid ${palette('light', 1)};
- font-weight: 500;
- max-width: 100%;
- padding-right: 35px;
- display: inline-block;
- vertical-align: top;
-`;
-
-const FileName = styled.div`
- padding: 1em 0.75em;
- overflow: hidden;
- line-height: normal;
-`;
-
-const Remove = styled(ButtonFlatIconOnly)`
- display: block;
- position:absolute;
- right: 0;
- top: 0;
- bottom: 0;
- padding: 0 0.75em;
- color: ${palette('buttonFlat', 1)};
- &:hover {
- color: ${palette('buttonFlatHover', 1)};
- }
- @media (min-width: ${(props) => props.theme.breakpoints.small}) {
- padding: 0 0.75em;
- }
-`;
-
-const ImportButton = styled(ButtonSubmit)`
- white-space: nowrap;
- display: inline-block;
- vertical-align: top;
- border-top: 1px solid;
- border-bottom: 1px solid;
- border-color: ${palette('buttonDefault', 1)};
-`;
-
-class SelectFile extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
- constructor() {
- super();
- this.state = {
- errors: [],
- };
- }
-
- UNSAFE_componentWillMount() {
- this.setState({ errors: [] });
- }
-
- onDismissErrors = (evt) => {
- if (evt !== undefined && evt.preventDefault) evt.preventDefault();
- this.setState({ errors: [] });
- };
-
- handleChange = (e, results) => {
- // todo: limit to 1 file?
- results.forEach((result) => {
- const [evt, file] = result;
- try {
- const parsed = Papa.parse(evt.target.result, { header: true, skipEmptyLines: true, delimiter: ',' });
- if (parsed && parsed.errors && parsed.errors.length > 0) {
- this.setState(
- (prevState) => ({
- errors: prevState.errors.concat(parsed.errors),
- })
- );
- } else {
- this.props.onChange({
- rows: parsed.data,
- meta: parsed.meta,
- file,
- });
- }
- } catch (err) {
- this.setState(
- (prevState) => ({
- errors: prevState.errors.concat([{ error: 0 }]),
- })
- );
- }
- });
- };
-
- handleRemove = (evt) => {
- if (evt !== undefined && evt.preventDefault) evt.preventDefault();
- this.props.onChange(null);
- };
-
- render() {
- // console.log(this.props.value)
- const { intl } = this.props;
- return (
-
- { (this.state.errors.length > 0)
- && (
- `Code: "${err.code}", Message: "${err.message}"`))}
- onDismiss={this.onDismissErrors}
- />
- )
- }
- { this.props.value && (this.state.errors.length === 0)
- && (
-
-
-
- {this.props.value.file.name}
-
-
-
-
-
-
- { this.props.value.rows.length === 1
- &&
- }
- { this.props.value.rows.length !== 1
- &&
- }
-
-
- )
- }
- { !this.props.value && (this.state.errors.length === 0)
- && (
-
-
-
- )
- }
-
- );
- }
-}
-
-SelectFile.propTypes = {
- onChange: PropTypes.func,
- value: PropTypes.object,
- as: PropTypes.string,
- accept: PropTypes.string,
- intl: PropTypes.object.isRequired,
-};
-
-export default injectIntl(SelectFile);
diff --git a/app/components/forms/ImportFileSelectControl/index.js b/app/components/forms/ImportFileSelectControl/index.js
deleted file mode 100644
index 0f5160627..000000000
--- a/app/components/forms/ImportFileSelectControl/index.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { Control } from 'react-redux-form/immutable';
-import SelectFile from './SelectFile';
-
-const ImportFileSelectControl = (props) => {
- const { model, ...otherProps } = props;
- return (
-
- );
-};
-
-ImportFileSelectControl.propTypes = {
- model: PropTypes.string.isRequired,
-};
-
-export default ImportFileSelectControl;
diff --git a/app/components/forms/ImportFileSelectControl/messages.js b/app/components/forms/ImportFileSelectControl/messages.js
deleted file mode 100644
index 322e2aeb1..000000000
--- a/app/components/forms/ImportFileSelectControl/messages.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * ImportFileSelectControl Messages
- *
- */
-import { defineMessages } from 'react-intl';
-
-export default defineMessages({
- import: {
- single: {
- id: 'app.components.ImportFileSelectControl.import.single',
- defaultMessage: 'Import {total} row',
- },
- plural: {
- id: 'app.components.ImportFileSelectControl.import.plural',
- defaultMessage: 'Import {total} rows',
- },
- },
- selectFile: {
- id: 'app.components.ImportFileSelectControl.selectFile',
- defaultMessage: 'Select File',
- },
- fileSelectError: {
- id: 'app.components.ImportFileSelectControl.fileSelectError',
- defaultMessage: 'Error parsing file. Please make sure to use the correct format only.',
- },
-});
diff --git a/app/components/forms/IndeterminateCheckbox/index.js b/app/components/forms/IndeterminateCheckbox/index.js
deleted file mode 100644
index fb532eb18..000000000
--- a/app/components/forms/IndeterminateCheckbox/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import styled from 'styled-components';
-import { palette } from 'styled-theme';
-
-export const STATES = {
- INDETERMINATE: null,
- CHECKED: true,
- UNCHECKED: false,
-};
-
-const Input = styled.input`
-accent-color: ${palette('checkbox', 0)};
-&:focus-visible {
- outline: 1px solid ${palette('primary', 0)};
-}
-`;
-export default class IndeterminateCheckbox extends React.Component {
- static propTypes = {
- checked: PropTypes.oneOf(Object.values(STATES)),
- onChange: PropTypes.func.isRequired,
- };
-
- render() {
- const { onChange, checked, ...props } = this.props;
- /* eslint-disable no-param-reassign */
- return (
- { if (ref) ref.indeterminate = checked === STATES.INDETERMINATE; }}
- checked={!!checked}
- onChange={(evt) => onChange(evt.target.checked)}
- {...props}
- />
- );
- /* eslint-enable no-param-reassign */
- }
-}
diff --git a/app/components/forms/Label.js b/app/components/forms/Label.js
deleted file mode 100644
index 3aca0b646..000000000
--- a/app/components/forms/Label.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import styled from 'styled-components';
-import { palette } from 'styled-theme';
-
-const Label = styled.label`
- color: ${palette('text', 1)};
- font-weight: 500;
- font-size: ${(props) => props.theme.sizes.text.small};
- position: relative;
- display: ${(props) => props.inline ? 'inline-block' : 'block'};
- @media print {
- font-size: ${(props) => props.theme.sizes.print.small};
- }
-`;
-
-export default Label;
diff --git a/app/components/forms/MarkdownControl/TextareaMarkdownWrapper.js b/app/components/forms/MarkdownControl/TextareaMarkdownWrapper.js
deleted file mode 100644
index 44f12eaae..000000000
--- a/app/components/forms/MarkdownControl/TextareaMarkdownWrapper.js
+++ /dev/null
@@ -1,311 +0,0 @@
-import React, {
- useRef, useState, useEffect,
-} from 'react';
-import PropTypes from 'prop-types';
-import { FormattedMessage, useIntl } from 'react-intl';
-import { palette } from 'styled-theme';
-import styled, { withTheme } from 'styled-components';
-import { Box, Text, Button } from 'grommet';
-
-import {
- Bold,
- Italic,
- Link as LinkIcon,
- List,
-} from 'grommet-icons';
-
-import TextareaMarkdown from 'textarea-markdown-editor';
-import MarkdownField from 'components/fields/MarkdownField';
-import InfoOverlay from 'components/InfoOverlay';
-import A from 'components/styled/A';
-import messages from './messages';
-
-const MIN_TEXTAREA_HEIGHT = 320;
-
-const MarkdownHint = styled.div`
- text-align: right;
- color: ${palette('text', 1)};
- font-size: 0.85em;
- @media print {
- font-size: ${(props) => props.theme.sizes.print.smaller};
- }
-`;
-
-const StyledTextareaMarkdown = styled(
- React.forwardRef((p, ref) => )
-)`
- background-color: ${palette('background', 0)};
- width: 100%;
- border: 1px solid ${palette('light', 1)};
- padding: 0.7em;
- border-radius: 0.5em;
- color: ${palette('text', 0)};
- min-height: ${MIN_TEXTAREA_HEIGHT}px;
- resize: "none";
-`;
-const Preview = styled((p) => )`
- background-color: ${palette('background', 0)};
- width: 100%;
- border: 1px solid ${palette('light', 1)};
- padding: 0.7em;
- color: ${palette('text', 0)};
- min-height: ${MIN_TEXTAREA_HEIGHT}px;
-`;
-
-const MDButton = styled((p) => (
-
-))`
- min-width: 30px;
- min-height: 30px;
- text-align: center;
- padding: 4px 7px;
- &:hover {
- background-color: ${({ disabled }) => disabled ? 'transparent' : palette('light', 2)};
- }
-`;
-const ViewButton = styled((p) => (
-
-))`
- background: none;
- opacity: ${({ active }) => active ? 1 : 0.6};
- border-bottom: 3px solid;
- border-bottom-color: ${(
- { active, theme }
- ) => active ? theme.global.colors.aHover : 'transparent'
-};
- &:hover {
- opacity: 0.8;
- border-bottom-color: ${palette('light', 2)};
- }
-`;
-const MDButtonText = styled((p) => (
-
-))`
- position: relative;
- top: -1px;
-`;
-
-function TextareaMarkdownWrapper(props) {
- const { value, theme } = props;
- const intl = useIntl();
- const textareaRef = useRef(null);
- const [view, setView] = useState('write');
- // const [hasFocus, setHasFocus] = useState(false);
- useEffect(() => {
- if (textareaRef.current) {
- textareaRef.current.style.height = 'inherit';
- textareaRef.current.style.height = `${Math.max(textareaRef.current.scrollHeight + 20, MIN_TEXTAREA_HEIGHT)
- }px`;
- }
- // has textarea focus?
- // setHasFocus(document.activeElement === textareaRef.current);
- });
- const mdDisabled = view !== 'write';
- return (
-
-
-
- setView('write')}
- active={view === 'write'}
- >
-
-
- setView('preview')}
- active={view === 'preview'}
- >
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- bold,
- italic: _italic_,
- }
- }
- />
-
-
-
-
-
-
-
-
-
-
-
-
- ,
- }}
- />
-
-
-
- )}
- />
-
-
-
- {
- if (!mdDisabled && textareaRef.current) {
- textareaRef.current.trigger('h2');
- }
- }}
- >
- H2
-
- {
- if (!mdDisabled && textareaRef.current) {
- textareaRef.current.trigger('h3');
- }
- }}
- >
- H3
-
- {
- if (!mdDisabled && textareaRef.current) {
- textareaRef.current.trigger('bold');
- }
- }}
- icon={}
- />
- {
- if (!mdDisabled && textareaRef.current) {
- textareaRef.current.trigger('italic');
- }
- }}
- icon={}
- />
- {
- if (!mdDisabled && textareaRef.current) {
- textareaRef.current.trigger('link');
- }
- }}
- icon={}
- />
- {
- if (!mdDisabled && textareaRef.current) {
- textareaRef.current.trigger('unordered-list');
- }
- }}
- icon={
}
- />
- {
- if (!mdDisabled && textareaRef.current) {
- textareaRef.current.trigger('ordered-list');
- }
- }}
- >
- 123
-
-
-
-
- {view === 'preview' && (
-
-
-
- )}
- {view === 'write' && (
-
-
-
-
-
-
-
-
- )}
-
- );
-}
-
-TextareaMarkdownWrapper.propTypes = {
- value: PropTypes.string,
- onChange: PropTypes.func,
- theme: PropTypes.object,
-};
-
-export default withTheme(TextareaMarkdownWrapper);
diff --git a/app/components/forms/MarkdownControl/index.js b/app/components/forms/MarkdownControl/index.js
deleted file mode 100644
index ee9b7b9fc..000000000
--- a/app/components/forms/MarkdownControl/index.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { Control } from 'react-redux-form/immutable';
-
-import TextareaMarkdownWrapper from './TextareaMarkdownWrapper';
-
-export function MarkdownControl({ model, ...props }) {
- return (
- viewValue,
- }}
- {...props}
- />
- );
-}
-
-MarkdownControl.propTypes = {
- model: PropTypes.string.isRequired,
-};
-
-export default MarkdownControl;
diff --git a/app/components/forms/MarkdownControl/messages.js b/app/components/forms/MarkdownControl/messages.js
deleted file mode 100644
index fe508f22f..000000000
--- a/app/components/forms/MarkdownControl/messages.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * MarkdownControl Messages
- *
- */
-import { defineMessages } from 'react-intl';
-
-export default defineMessages({
- anchor: {
- id: 'app.components.MarkdownControl.anchor',
- defaultMessage: 'Learn more about markdown format options here',
- },
- url: {
- id: 'app.components.MarkdownControl.url',
- defaultMessage: 'http://commonmark.org/help/',
- },
- hint: {
- id: 'app.components.MarkdownControl.hint',
- defaultMessage: ' ## Subheader, **bold**, _italic_',
- },
- writeLabel: {
- id: 'app.components.MarkdownControl.writeLabel',
- defaultMessage: 'Write',
- },
- previewLabel: {
- id: 'app.components.MarkdownControl.previewLabel',
- defaultMessage: 'Preview',
- },
- formatTextLabel: {
- id: 'app.components.MarkdownControl.formatTextLabel',
- defaultMessage: 'Format Text',
- },
- infoOverlayTitle: {
- id: 'app.components.MarkdownControl.infoOverlayTitle',
- defaultMessage: 'Format text using markdown',
- },
- infoOverlayFirstSection: {
- id: 'app.components.MarkdownControl.infoOverlayFirstSection',
- defaultMessage: 'This text field supports basic formatting using markdown, incuding section headings, {strong}, {italic}, links, and more.',
- },
- infoOverlaySecondSection: {
- id: 'app.components.MarkdownControl.infoOverlaySecondSection',
- defaultMessage: 'You can either directly type markdown code or use one of the format buttons above the text area to insert it, by either',
- },
- infoOverlayThirdSection: {
- id: 'app.components.MarkdownControl.infoOverlayThirdSection',
- defaultMessage: 'first clicking one of the buttons and then replace the generated placeholder text, or',
- },
- infoOverlayFourthSection: {
- id: 'app.components.MarkdownControl.infoOverlayFourthSection',
- defaultMessage: ' select some existing text and then apply a format using one the buttons.',
- },
- infoOverlayFifthSection: {
- id: 'app.components.MarkdownControl.infoOverlayFifthSection',
- defaultMessage: 'You can learn more about {link}.',
- },
- infoOverlaySixthSection: {
- id: 'app.components.MarkdownControl.infoOverlaySixthSection',
- defaultMessage: 'markdown and additional formatting options here',
- },
- buttonTitleHeading2: {
- id: 'app.components.MarkdownControl.buttonTitleHeading2',
- defaultMessage: '## Heading',
- },
- buttonTitleHeading3: {
- id: 'app.components.MarkdownControl.buttons.titles.heading3',
- defaultMessage: '### Secondary heading',
- },
- buttonTitleBold: {
- id: 'app.components.MarkdownControl.buttonTitleBold',
- defaultMessage: 'Bold: **bold**',
- },
- buttonTitleItalic: {
- id: 'app.components.MarkdownControl.buttonTitleItalic',
- defaultMessage: 'Italic: _italic_',
- },
- buttonTitleLink: {
- id: 'app.components.MarkdownControl.buttonTitleLink',
- defaultMessage: 'Link: (text)[url]',
- },
- buttonTitleUnorderedList: {
- id: 'app.components.MarkdownControl.buttonTitleUnorderedList',
- defaultMessage: 'Unordered list: -',
- },
- buttonTitleOrderedList: {
- id: 'app.components.MarkdownControl.buttonTitleOrderedList',
- defaultMessage: 'Ordered list: 1.',
- },
-});
diff --git a/app/components/forms/MarkdownField.js b/app/components/forms/MarkdownField.js
deleted file mode 100644
index 417abf982..000000000
--- a/app/components/forms/MarkdownField.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/* eslint-disable react/no-children-prop */
-import React from 'react';
-import PropTypes from 'prop-types';
-import styled from 'styled-components';
-import ReactMarkdown from 'react-markdown';
-import rehypeExternalLinks from 'rehype-external-links';
-
-import { FormattedMessage } from 'react-intl';
-
-import FieldWrap from 'components/fields/FieldWrap';
-import Label from 'components/fields/Label';
-// import appMessages from 'containers/App/messages';
-const Markdown = styled(ReactMarkdown)`
- font-size: ${(props) => props.theme.text.mediumTall.size};
- line-height: ${(props) => props.theme.text.mediumTall.height};
- @media (min-width: ${(props) => props.theme.breakpoints.medium}) {
- font-size: ${(props) => props.theme.text.largeTall.size};
- line-height: ${(props) => props.theme.text.largeTall.height};
- }
- @media print {
- font-size: ${(props) => props.theme.sizes.print.markdown};
- }
-`;
-
-const RenderLink = ({ href, children }) => {
- if (!href.startsWith('http')) {
- return href;
- }
- return {children};
-};
-
-RenderLink.propTypes = {
- href: PropTypes.string,
- children: PropTypes.node,
-};
-
-// TODO also render HTML if not markdown
-function MarkdownField({ field }) {
- return (
-
- {field.label
- && (
-
- )
- }
-
-
- );
-}
-
-MarkdownField.propTypes = {
- field: PropTypes.object.isRequired,
-};
-
-export default MarkdownField;
diff --git a/app/components/forms/MultiSelectControl/Header.js b/app/components/forms/MultiSelectControl/Header.js
deleted file mode 100644
index a264d288a..000000000
--- a/app/components/forms/MultiSelectControl/Header.js
+++ /dev/null
@@ -1,51 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import styled from 'styled-components';
-import { palette } from 'styled-theme';
-
-import ButtonFactory from '../../buttons/ButtonFactory';
-
-const Styled = styled.div`
- display: table;
- width: 100%;
- color: ${palette('multiSelectHeader', 0)};
- background-color: ${palette('multiSelectHeader', 1)};
- box-shadow: 0px 0px 8px 0px rgba(0,0,0,0.2);
- z-index: 1;
- height: 80px;
- padding: 16px;
- padding-left: 0.75em;
- @media (min-width: ${(props) => props.theme.breakpoints.small}) {
- height: 80px;
- padding-left: 1em;
- }
-`;
-
-const Title = styled.div`
- font-size: 0.85em;
- display: table-cell;
- width: 99%;
- vertical-align: middle;
- @media print {
- font-size: ${(props) => props.theme.sizes.print.smaller};
- }
-`;
-
-const Header = (props) => (
-
-
- {props.title}
-
- {props.onCancel
- && (
-
- )
- }
-
-);
-
-Header.propTypes = {
- onCancel: PropTypes.func,
- title: PropTypes.string,
-};
-export default Header;
diff --git a/app/components/forms/MultiSelectControl/MultiSelect.js b/app/components/forms/MultiSelectControl/MultiSelect.js
deleted file mode 100644
index 724f10bd3..000000000
--- a/app/components/forms/MultiSelectControl/MultiSelect.js
+++ /dev/null
@@ -1,480 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { without } from 'lodash/array';
-import { filter, find } from 'lodash/collection';
-import { Map, List, fromJS } from 'immutable';
-import styled from 'styled-components';
-import { palette } from 'styled-theme';
-import { FormattedMessage } from 'react-intl';
-
-import ButtonFactory from 'components/buttons/ButtonFactory';
-import TagSearch from 'components/TagSearch';
-
-import IndeterminateCheckbox, { STATES as CHECKBOX_STATES } from 'components/forms/IndeterminateCheckbox';
-
-import {
- sortOptions,
- filterOptionsByTags,
- filterOptionsByKeywords,
-} from './utils';
-
-import TagFilters from './TagFilters';
-import OptionList from './OptionList';
-import Header from './Header';
-
-import messages from './messages';
-
-const ButtonGroup = styled.div`
- float: ${(props) => props.left ? 'left' : 'right'}
-`;
-// const ControlWrapper = styled.div``;
-
-const ChangeHint = styled.div`
- position: absolute;
- left: 0;
- right: 0;
- bottom: ${(props) => props.hasFooter ? '30px' : '0px'};
- color: ${palette('text', 1)};
- background-color: ${palette('background', 1)};
- padding: 0.5em 1em;
- box-shadow: 0px 0px 8px 0px rgba(0,0,0,0.2);
- text-align: right;
- @media (min-width: ${(props) => props.theme.breakpoints.small}) {
- bottom: ${(props) => props.hasFooter ? '50px' : '0px'};
- }
-`;
-
-const ChangeHintHighlighted = styled.span`
- color: ${palette('buttonDefault', 1)};
-`;
-
-const ControlMain = styled.div`
- position: absolute;
- top: 80px;
- bottom: ${(props) => props.hasFooter ? '50px' : '0px'};
- left: 0;
- right: 0;
- overflow-y: auto;
- padding:0;
- padding-bottom: ${(props) => props.hasChangeNote ? '50px' : '0px'};
- border-top: 1px solid ${palette('primary', 4)};
- @media (min-width: ${(props) => props.theme.breakpoints.small}) {
- top: 80px;
- }
-`;
-const ControlFooter = styled.div`
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- background-color: ${palette('background', 1)};
- box-shadow: 0px 0px 8px 0px rgba(0,0,0,0.2);
- @media (min-width: ${(props) => props.theme.breakpoints.small}) {
- height: 50px;
- }
-`;
-
-const Search = styled.div`
- padding: 0.75em;
- background-color: ${palette('background', 1)};
- @media (min-width: ${(props) => props.theme.breakpoints.small}) {
- padding: 0.75em 1em;
- }
-`;
-
-const SelectAll = styled.div`
- padding: 0.5em 1em 0.5em 0;
- background-color: ${palette('background', 1)};
- display: table;
- width: 100%;
- line-height: 1.1;
-`;
-
-const LabelWrap = styled.div`
- display: table-cell;
- padding-left: 0.5em;
- padding-right: 1em;
- font-size: 0.8em;
- vertical-align: middle;
- @media print {
- font-size: ${(props) => props.theme.sizes.print.smaller};
- }
-`;
-const CheckboxWrap = styled.div`
- text-align: center;
- display: table-cell;
- width: 10px;
- vertical-align: middle;
- padding-left: 0.75em;
- @media (min-width: ${(props) => props.theme.breakpoints.small}) {
- padding-right: 0.5em;
- padding-left: 1em;
- }
-
-`;
-const Checkbox = styled(IndeterminateCheckbox)`
- vertical-align: middle;
-`;
-const Label = styled.label``;
-
-
-class MultiSelect extends React.Component {
- constructor() {
- super();
- this.state = {
- query: null,
- optionsInitial: null,
- panelId: null,
- queryTags: [],
- };
-
- this.setWrapperRef = this.setWrapperRef.bind(this);
- this.handleClickOutside = this.handleClickOutside.bind(this);
- }
-
- UNSAFE_componentWillMount() {
- // remember initial options
- this.setState({
- optionsInitial: this.props.options,
- panelId: this.props.panelId,
- });
- document.addEventListener('mousedown', this.handleClickOutside);
- }
-
- UNSAFE_componentWillReceiveProps(nextProps) {
- if (nextProps.panelId && (nextProps.panelId !== this.state.panelId)) {
- this.setState({
- optionsInitial: nextProps.options,
- panelId: nextProps.panelId,
- query: null,
- queryTags: [],
- });
- }
- }
-
- componentWillUnmount() {
- document.removeEventListener('mousedown', this.handleClickOutside);
- }
-
- onSearch = (value) => {
- this.setState({
- query: value,
- });
- };
-
- onResetFilters = () => {
- this.setState({
- query: null,
- queryTags: [],
- });
- };
-
- onTagSelected = (active, tagOption) => {
- this.setState(
- (prevState) => ({
- queryTags: active
- ? prevState.queryTags.concat([tagOption.get('value')])
- : without(prevState.queryTags, tagOption.get('value')),
- })
- );
- };
-
- setWrapperRef(node) {
- this.wrapperRef = node;
- }
-
- getNextValues = (checked, option) => {
- const { multiple, required, values } = this.props;
- // do not update if required and change would result in empty list
- if (!checked && required) {
- const otherCheckedValues = values.find((v) => v.get('checked')
- && v.get('value') !== option.get('value')
- && (option.get('query') ? v.get('query') === option.get('query') : true));
- if (!otherCheckedValues) {
- return values;
- }
- }
-
- // uncheck all others if single mode (!multiple)
- let nextValues = values;
- const existingValueIndex = values.findIndex((v) => v.get('value') === option.get('value')
- && (option.get('query') ? v.get('query') === option.get('query') : true));
- if (!multiple && checked) {
- // uncheck all other options
- nextValues = nextValues.map((value, index) => existingValueIndex !== index ? value.set('checked', false).set('hasChanged', true) : value);
- }
- // set new value
- const newValue = option.set('checked', checked).set('hasChanged', true);
- // set current value, add if not present
- return existingValueIndex > -1 ? nextValues.set(existingValueIndex, newValue) : nextValues.push(newValue);
- };
-
- getAllSelectedValues = (checked, options) => {
- const { values } = this.props;
- // TODO consider how to deal with required variant
- // uncheck all others if single mode (!multiple)
- let nextValues = values;
- options.forEach((option) => {
- const existingValueIndex = values.findIndex((v) => v.get('value') === option.get('value')
- && (option.get('query') ? v.get('query') === option.get('query') : true));
- const newValue = option.set('checked', checked).set('hasChanged', true);
- // set new value
- // set current value, add if not present
- nextValues = existingValueIndex > -1
- ? nextValues.set(existingValueIndex, newValue)
- : nextValues.push(newValue);
- });
- return nextValues;
- };
-
- getSelectedState = (selectedTotal, allSelected) => {
- if (selectedTotal === 0) {
- return CHECKBOX_STATES.UNCHECKED;
- }
- if (selectedTotal > 0 && allSelected) {
- return CHECKBOX_STATES.CHECKED;
- }
- return CHECKBOX_STATES.INDETERMINATE;
- };
-
- // props, state
- // map options
- prepareOptions = ({ options, values, threeState }, { optionsInitial }) => options.map((option) => {
- const value = values.find((v) => option.get('value') === v.get('value'));// && option.get('query') === v.get('query'));
- const isNew = !optionsInitial.includes(option);
- const isIndeterminateInitial = threeState && this.isOptionIndeterminate(option);
- const isCheckedIntitial = option.get('checked');
- const optionUpdated = option.withMutations((o) => o.set('isNew', isNew)
- .set('initialChecked', isCheckedIntitial)
- .set('isIndeterminate', isIndeterminateInitial));
- return value
- ? optionUpdated.withMutations((o) => o.set('checked', value.get('checked'))
- .set('changedToChecked', value.get('checked') && !isCheckedIntitial)
- .set('changedToUnchecked', !value.get('checked') && !this.isOptionIndeterminate(value) && (isCheckedIntitial || isIndeterminateInitial)))
- : optionUpdated;
- });
-
- filterOptions = (options, { search, advanced }, { query, queryTags }) => { // filter options
- let checkboxOptions = options;
- if (search && query) {
- checkboxOptions = filterOptionsByKeywords(checkboxOptions, query);
- }
- if (advanced && queryTags) {
- checkboxOptions = filterOptionsByTags(checkboxOptions, queryTags);
- }
- // sort options
- return sortOptions(checkboxOptions);
- };
-
- currentTagFilterGroups = (tagFilterGroups, options) => {
- // get all actually connected categories from connections
- const optionTagIds = options
- .map((option) => option.get('tags'))
- .flatten()
- .toSet()
- .toList();
-
- // filter multiselect options
- return optionTagIds.size > 0
- && !(optionTagIds.size === 1 && !optionTagIds.first())
- ? tagFilterGroups.map((group) => ({
- title: group.title,
- palette: group.palette,
- options: filter(group.options, (groupOption) => optionTagIds.includes(parseInt(groupOption.value, 10))),
- }))
- : [];
- };
-
- currentFilters = (queryTags, filterGroups) => queryTags.map((tagValue) => filterGroups.reduce((memo, group) => {
- const option = find(group.options, (groupOption) => groupOption.value === tagValue);
- return option
- ? ({
- label: option.filterLabel,
- type: group.palette[0],
- id: group.palette[1],
- onClick: (evt) => {
- if (evt && evt.preventDefault) evt.preventDefault();
- this.onTagSelected(false, fromJS(option));
- },
- })
- : memo;
- }, null));
-
- isOptionIndeterminate = (option) => option.get('checked') === CHECKBOX_STATES.INDETERMINATE;
-
- handleClickOutside(event) {
- if (this.props.closeOnClickOutside && this.wrapperRef && !this.wrapperRef.contains(event.target)) {
- this.props.onCancel();
- }
- }
-
- renderButton = (action, i, hasChanges) => (
- action.onClick()),
- submit: action.submit,
- disabled: action.submit && !hasChanges,
- }}
- />
- );
-
-
- // TODO intl
- render() {
- let options = this.prepareOptions(this.props, this.state);
-
- const optionsChangedToChecked = options.filter((option) => option.get('changedToChecked'));
- const optionsChangedToUnchecked = options.filter((option) => option.get('changedToUnchecked'));
- const hasChanges = optionsChangedToChecked.size > 0 || optionsChangedToUnchecked.size > 0;
- const showChangeHint = this.props.advanced && hasChanges;
-
- options = this.filterOptions(options, this.props, this.state);
- const filteredOptionsSelected = options.filter((option) => option.get('checked') || this.isOptionIndeterminate(option));
- return (
-
-
-
- {this.props.search
- && (
-
-
-
- )
- }
- {this.props.advanced && this.props.tagFilterGroups
- && (
-
- )
- }
- {this.props.selectAll
- && (
-
-
- this.props.onChange(this.getAllSelectedValues(checkedState, options))
- }
- />
-
-
-
-
-
- )
- }
- {
- this.props.onChange(this.getNextValues(checkedState, option));
- }}
- />
-
- {showChangeHint
- && (
-
-
- {optionsChangedToChecked.size > 0
- && (
-
-
- .
-
- )
- }
- {optionsChangedToUnchecked.size > 0
- && (
-
-
- .
-
- )
- }
-
- )
- }
- {this.props.buttons
- && (
-
-
- {
- this.props.buttons.map((action, i) => action && action.position !== 'left' && this.renderButton(action, i, hasChanges))
- }
-
-
- {
- this.props.buttons.map((action, i) => (
- action && action.position === 'left' && this.renderButton(action, i, hasChanges)
- ))
- }
-
-
- )
- }
-
- );
- }
-}
-
-
-MultiSelect.propTypes = {
- options: PropTypes.instanceOf(List),
- values: PropTypes.instanceOf(List),
- groups: PropTypes.instanceOf(Map),
- onChange: PropTypes.func.isRequired,
- onCancel: PropTypes.func,
- multiple: PropTypes.bool,
- required: PropTypes.bool,
- title: PropTypes.string,
- buttons: PropTypes.array,
- search: PropTypes.bool,
- advanced: PropTypes.bool,
- selectAll: PropTypes.bool,
- closeOnClickOutside: PropTypes.bool,
- threeState: PropTypes.bool,
- panelId: PropTypes.string,
- tagFilterGroups: PropTypes.array,
- searchAttributes: PropTypes.array,
- placeholderMessageId: PropTypes.string,
-};
-
-MultiSelect.defaultProps = {
- values: new List(),
- threeState: false,
- multiple: true,
- required: false,
- search: true,
- advanced: false,
- closeOnClickOutside: true,
-};
-
-export default MultiSelect;
diff --git a/app/components/forms/MultiSelectControl/Option.js b/app/components/forms/MultiSelectControl/Option.js
deleted file mode 100644
index 45f1c691c..000000000
--- a/app/components/forms/MultiSelectControl/Option.js
+++ /dev/null
@@ -1,107 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import styled from 'styled-components';
-import { palette } from 'styled-theme';
-import { FormattedMessage, injectIntl } from 'react-intl';
-
-import { lowerCase } from 'utils/string';
-import appMessage from 'utils/app-message';
-
-import ItemStatus from 'components/ItemStatus';
-
-import messages from './messages';
-
-const Label = styled.div`
- font-weight: ${(props) => props.bold ? 500 : 'normal'};
- position: relative;
-`;
-const New = styled.span`
- color: ${palette('primary', 4)};
- background-color: ${palette('primary', 0)};
- padding: 1px 5px;
- font-size: 0.8em;
- margin-left: 0.5em;
- border-radius: 4px;
- @media print {
- font-size: ${(props) => props.theme.sizes.print.smaller};
- }
-`;
-const Id = styled.span`
- color: ${palette('text', 1)};
- font-size: 0.9em;
- @media print {
- font-size: ${(props) => props.theme.sizes.print.small};
- }
-`;
-const Sublabel = styled.div`
- color: ${palette('text', 1)};
- font-size: 0.8em;
- opacity: 0.6;
- padding-top: 4px;
- @media print {
- font-size: ${(props) => props.theme.sizes.print.small};
- }
-`;
-const IdSpacer = styled.span`
- padding-left: 0.25em;
- padding-right: 0.25em;
- color: ${palette('text', 1)};
-`;
-//