initial structure for components rewrite

This commit is contained in:
Rodrigo Antinarelli authored and James A. Petts committed 2020-05-15 13:18:30 +02:00
1 parent 944afe4a3e
commit c391c007ff
284 files changed
+68087 -17215

No files matched your search

@@ -1,119 +0,0 @@
/* NOTE: the order of these styles DO matter */
/* Will edit everything selected including everything between a range of dates */
.CalendarDay__selected_span {
background: var(--datePicker-picker-background);
color: var(--datePicker-picker-text);
border-color: #e4e7e7;
}
/* Will edit selected date or the endpoints of a range of dates */
.CalendarDay__selected {
background: var(--datePicker-picker-background);
color: var(--datePicker-picker-text);
border-color: #e4e7e7;
}
/* Will edit when hovered over. _span style also has this property */
.CalendarDay__selected:hover,
.CalendarDay__default:hover {
background: var(--datePicker-picker-background);
color: var(--datePicker-picker-text);
border-color: #e4e7e7;
}
/* Will edit when the second date (end date) in a range of dates
is not yet selected. Edits the dates between your mouse and said date */
.CalendarDay__hovered_span:hover,
.CalendarDay__hovered_span {
background: var(--datePicker-picker-background);
color: var(--datePicker-picker-text);
border-color: #e4e7e7;
}
/* EXTERIOR INPUT STYLE */
/* Container - placement */
.DateRangePicker {
height: 40px;
margin: 0 5px 20px 5px;
cursor: pointer;
border: none;
width: 100%;
}
/* Container - visual */
.DateRangePickerInput {
width: calc(100% - 10px); /* Just use padding? */
background-color: var(--datePicker-input-background);
border-color: var(--datePicker-input-background);
color: var(--datePicker-picker-text-input);
height: 40px;
}
.DateRangePickerInput.DateRangePickerInput__withBorder {
border-radius: 4px;
background-color: var(--datePicker-input-background);
}
/* Input Container */
.DateInput {
width: 97px;
height: 38px;
border-radius: 4px;
background-color: var(--datePicker-input-background);
}
/* Actual Input Element */
.DateInput > .DateInput_input {
border-color: transparent;
background-color: transparent;
color: var(--datePicker-picker-text-input);
height: 38px;
font-size: 10pt;
padding: 0;
}
/* PRESETS */
.PresetDateRangePicker_panel {
display: flex;
justify-content: space-between;
}
.PresetDateRangePicker_button {
margin: 0;
padding: 4px 8px;
color: #00a699;
background: var(--datePicker-picker-text-input);
}
.PresetDateRangePicker_button:hover {
background: #00a699;
color: var(--datePicker-picker-text-input);
}
.CalendarDay__blocked_out_of_range:hover {
background: #fff;
cursor: not-allowed;
color: var(--datePicker-picker-text-disabled);
}
.DateRangePicker_select {
background-color: white;
color: var(--datePicker-picker-text);
border: 1px solid #e4e7e7;
border-radius: 4px;
display: inline-block;
padding: 3px 20px 3px 10px;
font-size: 14px;
cursor: pointer;
appearance: none;
background-image: linear-gradient(45deg, transparent 50%, gray 50%),
linear-gradient(135deg, gray 50%, transparent 50%);
background-position: calc(100% - 11px) 11px, calc(100% - 6px) calc(11px);
background-size: 5px 5px, 5px 5px;
background-repeat: no-repeat;
}
.DateRangePicker_select:hover {
border-color: #c4c4c4;
}
@@ -1,140 +0,0 @@
// If you want to continue using CSS stylesheets and classes...
// https://github.com/airbnb/react-dates#initialize
import 'react-dates/initialize';
import 'react-dates/lib/css/_datepicker.css';
import './CustomDateRangePicker.css';
import React from 'react';
import PropTypes from 'prop-types';
import { DateRangePicker } from 'react-dates';
import moment from 'moment';
import i18n from '@ohif/i18n';
import { useTranslation } from 'react-i18next';
function CustomDateRangePicker(props) {
moment.locale(i18n.language); // using i18n in the date picker
const { t } = useTranslation('DatePicker');
const {
onDatesChange,
startDate,
endDate,
presets,
...dateRangePickerProps
} = props;
const renderDatePresets = () => {
const { presets } = props;
return (
<div className="PresetDateRangePicker_panel">
{presets.map(({ text, start, end }) => {
const isSelected = startDate === start && endDate === end;
return (
<button
key={text}
type="button"
className={`PresetDateRangePicker_button ${
isSelected ? 'PresetDateRangePicker_button__selected' : ''
}`}
onClick={() =>
onDatesChange({
startDate: start,
endDate: end,
preset: true,
})
}
>
{text}
</button>
);
})}
</div>
);
};
const renderMonthElement = ({ month, onMonthSelect, onYearSelect }) => {
const containerStyle = {
margin: '0 5px',
};
const renderYearsOptions = () => {
const yearsRange = 20;
const options = [];
for (let i = 0; i < yearsRange; i++) {
const year = moment().year() - i;
options.push(<option value={year}>{year}</option>);
}
return options;
};
renderMonthElement.propTypes = {
onMonthSelect: PropTypes.func,
onYearSelect: PropTypes.func,
};
return (
<div style={{ display: 'flex', justifyContent: 'center' }}>
<div style={containerStyle}>
<select
className="DateRangePicker_select"
value={month.month()}
onChange={e => onMonthSelect(month, e.target.value)}
>
{moment.months().map((label, value) => (
<option key={value} value={value}>
{label}
</option>
))}
</select>
</div>
<div style={containerStyle}>
{}
<select
className="DateRangePicker_select"
value={month.year()}
onChange={e => onYearSelect(month, e.target.value)}
>
{renderYearsOptions()}
</select>
</div>
</div>
);
};
return (
<DateRangePicker
{...dateRangePickerProps}
startDate={startDate}
endDate={endDate}
renderCalendarInfo={renderDatePresets}
onDatesChange={onDatesChange}
renderMonthElement={renderMonthElement}
startDatePlaceholderText={t('Start Date')}
endDatePlaceholderText={t('End Date')}
phrases={{
closeDatePicker: t('Common:Close'),
clearDates: t('Clear dates'),
}}
/>
);
}
CustomDateRangePicker.propTypes = {
presets: PropTypes.arrayOf(
PropTypes.shape({
text: PropTypes.string,
start: PropTypes.required,
end: PropTypes.required,
})
),
onDatesChange: PropTypes.func.isRequired,
startDate: PropTypes.instanceOf(Date),
endDate: PropTypes.instanceOf(Date),
month: PropTypes.instanceOf(Date),
};
export default CustomDateRangePicker;
@@ -1,38 +0,0 @@
import React, { PureComponent } from 'react';
import { Icon } from './../../elements/Icon';
import PropTypes from 'prop-types';
class PageToolbar extends PureComponent {
static propTypes = {
onImport: PropTypes.func,
};
onImport = event => {
if (this.props.onImport) {
this.props.onImport(event);
}
};
getImportTool() {
if (this.props.onImport) {
return (
<div className="addNewStudy btn-file">
<label
htmlFor="btnImport"
style={{ width: '18px' }}
onClick={this.onImport}
>
<Icon name="plus" />
</label>
</div>
);
}
}
render() {
return <div className="studylistToolbar">{this.getImportTool()}</div>;
}
}
export { PageToolbar };
@@ -1,63 +0,0 @@
.pagination-area
display: flex;
color: var(--text-secondary-color);
font-size: 13px
font-weight: normal !important
label
font-weight: normal
select
margin: 5px
background-color: var(--primary-background-color)
color: white
.rows-dropdown
width: 25%;
padding-right: 15px;
padding-left: 15px;
.pagination-buttons
width: 75%;
padding-right: 15px;
padding-left: 15px;
.form-group
margin-bottom: 15px;
.rows-per-page label.wrapperLabel
display: inline-table !important
margin: 0 4px
select
margin: 0px 4px 0px 4px
width: 42px
.page-buttons
margin: 0
text-align: right
font-weight: normal
ul.pagination-control
margin: 0
li
display: table-cell
padding: 5px 2px
button
padding: 4px 8px
background-color: var(--primary-background-color)
border-color: var(--ui-gray)
color: var(--ui-gray-darkest)
color: white
text-decoration: none
&:hover:enabled
color: var(--active-color)
.active
button
background-color: var(--ui-gray)
border-color: #ddd
color: white
@@ -1,18 +0,0 @@
import React from 'react';
import { Icon } from './../../elements/Icon';
// TODO: useTranslation
import { withTranslation } from '../../contextProviders';
function StudyListLoadingText({ t: translate }) {
return (
<div className="loading-text">
{translate('Loading')}... <Icon name="circle-notch" animation="pulse" />
</div>
);
}
const connectedComponent = withTranslation('StudyListLoadingText')(
StudyListLoadingText
);
export { connectedComponent as StudyListLoadingText };
@@ -1,150 +0,0 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import { isInclusivelyBeforeDay } from 'react-dates';
import CustomDateRangePicker from './CustomDateRangePicker.js';
import { Icon } from './../../elements/Icon';
import { useTranslation } from 'react-i18next';
const getDateEntry = (datePicked, rangeDatePicked) => {
return rangeDatePicked || datePicked || null;
};
const getDateEntryFromRange = (today, numOfDays, edge = 'start') => {
if (typeof numOfDays !== 'number') {
return;
}
if (edge === 'end') {
return today;
} else {
today.subtract(numOfDays, 'days');
}
};
function TableSearchFilter(props) {
const {
meta,
values,
onSort,
onValueChange,
sortFieldName,
sortDirection,
// TODO: Rename
studyListDateFilterNumDays,
} = props;
const { studyDateTo, studyDateFrom } = values || {};
const [focusedInput, setFocusedInput] = useState(null);
const { t, ready: translationsAreReady } = useTranslation('Common');
const sortIcons = ['sort', 'sort-up', 'sort-down'];
const sortIconForSortField =
sortDirection === 'asc' ? sortIcons[1] : sortIcons[2];
const today = moment();
const lastWeek = moment().subtract(7, 'day');
const lastMonth = moment().subtract(1, 'month');
const defaultStartDate = getDateEntryFromRange(
today,
studyListDateFilterNumDays,
'start'
);
const defaultEndDate = getDateEntryFromRange(
today,
studyListDateFilterNumDays,
'end'
);
const studyDatePresets = [
{
text: t('Today'),
start: today,
end: today,
},
{
text: t('Last 7 days'),
start: lastWeek,
end: today,
},
{
text: t('Last 30 days'),
start: lastMonth,
end: today,
},
];
return translationsAreReady
? meta.map((field, i) => {
const { displayText, fieldName, inputType } = field;
const isSortField = sortFieldName === fieldName;
const sortIcon = isSortField ? sortIconForSortField : sortIcons[0];
return (
<th key={`${fieldName}-${i}`}>
<label
htmlFor={`filter-${fieldName}`}
onClick={() => onSort(fieldName)}
>
{`${displayText}`}
<Icon name={sortIcon} style={{ fontSize: '12px' }} />
</label>
{inputType === 'text' && (
<input
type="text"
id={`filter-${fieldName}`}
className="form-control studylist-search"
value={values[fieldName]}
onChange={e => onValueChange(fieldName, e.target.value)}
/>
)}
{inputType === 'date-range' && (
// https://github.com/airbnb/react-dates
<CustomDateRangePicker
// Required
startDate={getDateEntry(studyDateFrom, defaultStartDate)}
startDateId="start-date"
endDate={getDateEntry(studyDateTo, defaultEndDate)}
endDateId="end-date"
// TODO: We need a dynamic way to determine which fields values to update
onDatesChange={({ startDate, endDate, preset = false }) => {
onValueChange('studyDateFrom', startDate);
onValueChange('studyDateTo', endDate);
}}
focusedInput={focusedInput}
onFocusChange={updatedVal => setFocusedInput(updatedVal)}
// Optional
numberOfMonths={1} // For med and small screens? 2 for large?
showClearDates={true}
anchorDirection="left"
presets={studyDatePresets}
hideKeyboardShortcutsPanel={true}
isOutsideRange={day => !isInclusivelyBeforeDay(day, moment())}
/>
)}
</th>
);
})
: null;
}
TableSearchFilter.propTypes = {
meta: PropTypes.arrayOf(
PropTypes.shape({
displayText: PropTypes.string.isRequired,
fieldName: PropTypes.string.isRequired,
inputType: PropTypes.oneOf(['text', 'date-range']).isRequired,
size: PropTypes.number.isRequired,
})
).isRequired,
values: PropTypes.object.isRequired,
onSort: PropTypes.func.isRequired,
sortFieldName: PropTypes.string,
sortDirection: PropTypes.oneOf([null, 'asc', 'desc']),
};
TableSearchFilter.defaultProps = {};
export { TableSearchFilter };
export default TableSearchFilter;
@@ -1,4 +0,0 @@
export { StudyList } from './StudyList.js';
export { TableSearchFilter } from './TableSearchFilter.js';
export { TablePagination } from './TablePagination.js';
export { PageToolbar } from './PageToolbar.js';