Refactor Indexer index to use react-window

(cherry picked from commit d022679b7dcbce3cec98e6a1fd0879e3c0d92523)
pull/1480/head
Mark McDowall 1 year ago committed by Qstick
parent c2599ef2e7
commit c0383ad5f5

@ -4,7 +4,7 @@ import { Redirect, Route } from 'react-router-dom';
import NotFound from 'Components/NotFound';
import Switch from 'Components/Router/Switch';
import HistoryConnector from 'History/HistoryConnector';
import IndexerIndexConnector from 'Indexer/Index/IndexerIndexConnector';
import IndexerIndex from 'Indexer/Index/IndexerIndex';
import StatsConnector from 'Indexer/Stats/StatsConnector';
import SearchIndexConnector from 'Search/SearchIndexConnector';
import ApplicationSettingsConnector from 'Settings/Applications/ApplicationSettingsConnector';
@ -38,7 +38,7 @@ function AppRoutes(props) {
<Route
exact={true}
path="/"
component={IndexerIndexConnector}
component={IndexerIndex}
/>
{

@ -0,0 +1,9 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'changes': string;
'maintenance': string;
'version': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'automatic': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,5 @@
interface ModelBase {
id: number;
}
export default ModelBase;

@ -0,0 +1,163 @@
import { cloneDeep } from 'lodash';
import React, { useEffect } from 'react';
import areAllSelected from 'Utilities/Table/areAllSelected';
import selectAll from 'Utilities/Table/selectAll';
import toggleSelected from 'Utilities/Table/toggleSelected';
import ModelBase from './ModelBase';
export enum SelectActionType {
Reset,
SelectAll,
UnselectAll,
ToggleSelected,
RemoveItem,
UpdateItems,
}
type SelectedState = Record<number, boolean>;
interface SelectState {
selectedState: SelectedState;
lastToggled: number | null;
allSelected: boolean;
allUnselected: boolean;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
items: any[];
}
type SelectAction =
| { type: SelectActionType.Reset }
| { type: SelectActionType.SelectAll }
| { type: SelectActionType.UnselectAll }
| {
type: SelectActionType.ToggleSelected;
id: number;
isSelected: boolean;
shiftKey: boolean;
}
| {
type: SelectActionType.RemoveItem;
id: number;
}
| {
type: SelectActionType.UpdateItems;
items: ModelBase[];
};
type Dispatch = (action: SelectAction) => void;
const initialState = {
selectedState: {},
lastToggled: null,
allSelected: false,
allUnselected: true,
items: [],
};
interface SelectProviderOptions<T extends ModelBase> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
children: any;
items: Array<T>;
}
function getSelectedState(items: ModelBase[], existingState: SelectedState) {
return items.reduce((acc: SelectedState, item) => {
const id = item.id;
acc[id] = existingState[id] ?? false;
return acc;
}, {});
}
// TODO: Can this be reused?
const SelectContext = React.createContext<[SelectState, Dispatch] | undefined>(
cloneDeep(undefined)
);
function selectReducer(state: SelectState, action: SelectAction): SelectState {
const { items, selectedState } = state;
switch (action.type) {
case SelectActionType.Reset: {
return cloneDeep(initialState);
}
case SelectActionType.SelectAll: {
return {
items,
...selectAll(selectedState, true),
};
}
case SelectActionType.UnselectAll: {
return {
items,
...selectAll(selectedState, false),
};
}
case SelectActionType.ToggleSelected: {
const result = {
items,
...toggleSelected(
state,
items,
action.id,
action.isSelected,
action.shiftKey
),
};
return result;
}
case SelectActionType.UpdateItems: {
const nextSelectedState = getSelectedState(action.items, selectedState);
return {
...state,
...areAllSelected(nextSelectedState),
selectedState: nextSelectedState,
items: action.items,
};
}
default: {
throw new Error(`Unhandled action type: ${action.type}`);
}
}
}
export function SelectProvider<T extends ModelBase>(
props: SelectProviderOptions<T>
) {
const { items } = props;
const selectedState = getSelectedState(items, {});
const [state, dispatch] = React.useReducer(selectReducer, {
selectedState,
lastToggled: null,
allSelected: false,
allUnselected: true,
items,
});
const value: [SelectState, Dispatch] = [state, dispatch];
useEffect(() => {
dispatch({ type: SelectActionType.UpdateItems, items });
}, [items]);
return (
<SelectContext.Provider value={value}>
{props.children}
</SelectContext.Provider>
);
}
export function useSelect() {
const context = React.useContext(SelectContext);
if (context === undefined) {
throw new Error('useSelect must be used within a SelectProvider');
}
return context;
}

@ -0,0 +1,11 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'alert': string;
'danger': string;
'info': string;
'success': string;
'warning': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -4,7 +4,9 @@ import React from 'react';
import { kinds } from 'Helpers/Props';
import styles from './Alert.css';
function Alert({ className, kind, children, ...otherProps }) {
function Alert(props) {
const { className, kind, children, ...otherProps } = props;
return (
<div
className={classNames(
@ -19,8 +21,8 @@ function Alert({ className, kind, children, ...otherProps }) {
}
Alert.propTypes = {
className: PropTypes.string.isRequired,
kind: PropTypes.oneOf(kinds.all).isRequired,
className: PropTypes.string,
kind: PropTypes.oneOf(kinds.all),
children: PropTypes.node.isRequired
};

@ -0,0 +1,9 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'card': string;
'overlay': string;
'underlay': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'descriptionList': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'description': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'title': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'dragLayer': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -25,6 +25,10 @@
white-space: pre-wrap;
}
.version {
margin-top: 20px;
}
@media only screen and (max-width: $breakpointMedium) {
.image {
height: 250px;

@ -0,0 +1,12 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'container': string;
'details': string;
'image': string;
'imageContainer': string;
'message': string;
'version': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -1,60 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import styles from './ErrorBoundaryError.css';
function ErrorBoundaryError(props) {
const {
className,
messageClassName,
detailsClassName,
message,
error,
info
} = props;
return (
<div className={className}>
<div className={messageClassName}>
{message}
</div>
<div className={styles.imageContainer}>
<img
className={styles.image}
src={`${window.Prowlarr.urlBase}/Content/Images/error.png`}
/>
</div>
<details className={detailsClassName}>
{
error &&
<div>
{error.toString()}
</div>
}
<div className={styles.info}>
{info.componentStack}
</div>
</details>
</div>
);
}
ErrorBoundaryError.propTypes = {
className: PropTypes.string.isRequired,
messageClassName: PropTypes.string.isRequired,
detailsClassName: PropTypes.string.isRequired,
message: PropTypes.string.isRequired,
error: PropTypes.object.isRequired,
info: PropTypes.object.isRequired
};
ErrorBoundaryError.defaultProps = {
className: styles.container,
messageClassName: styles.message,
detailsClassName: styles.details,
message: 'There was an error loading this content'
};
export default ErrorBoundaryError;

@ -0,0 +1,74 @@
import React, { useEffect, useState } from 'react';
import StackTrace from 'stacktrace-js';
import styles from './ErrorBoundaryError.css';
interface ErrorBoundaryErrorProps {
className: string;
messageClassName: string;
detailsClassName: string;
message: string;
error: Error;
info: {
componentStack: string;
};
}
function ErrorBoundaryError(props: ErrorBoundaryErrorProps) {
const {
className = styles.container,
messageClassName = styles.message,
detailsClassName = styles.details,
message = 'There was an error loading this content',
error,
info,
} = props;
const [detailedError, setDetailedError] = useState(null);
useEffect(() => {
if (error) {
StackTrace.fromError(error).then((de) => {
setDetailedError(de);
});
} else {
setDetailedError(null);
}
}, [error, setDetailedError]);
return (
<div className={className}>
<div className={messageClassName}>{message}</div>
<div className={styles.imageContainer}>
<img
className={styles.image}
src={`${window.Prowlarr.urlBase}/Content/Images/error.png`}
/>
</div>
<details className={detailsClassName}>
{error ? <div>{error.message}</div> : null}
{detailedError ? (
detailedError.map((d, index) => {
return (
<div key={index}>
{` at ${d.functionName} (${d.fileName}:${d.lineNumber}:${d.columnNumber})`}
</div>
);
})
) : (
<div>{info.componentStack}</div>
)}
{
<div className={styles.version}>
Version: {window.Prowlarr.version}
</div>
}
</details>
</div>
);
}
export default ErrorBoundaryError;

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'fieldSet': string;
'legend': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'modal': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,12 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'faqLink': string;
'loading': string;
'mappedDrivesWarning': string;
'modalBody': string;
'pathInput': string;
'scroller': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'type': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,9 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'container': string;
'numberInput': string;
'selectInput': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,10 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'label': string;
'labelContainer': string;
'labelInputContainer': string;
'rows': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,10 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'actionsContainer': string;
'filterRow': string;
'inputContainer': string;
'valueInputContainer': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,10 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'isLastTag': string;
'label': string;
'or': string;
'tag': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,9 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'actions': string;
'customFilter': string;
'label': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'addButtonContainer': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,15 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'hasError': string;
'hasWarning': string;
'input': string;
'inputContainer': string;
'suggestion': string;
'suggestionHighlighted': string;
'suggestionsContainer': string;
'suggestionsContainerOpen': string;
'suggestionsList': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,12 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'captchaInputWrapper': string;
'hasButton': string;
'hasError': string;
'hasWarning': string;
'input': string;
'recaptchaWrapper': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,18 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'checkbox': string;
'container': string;
'dangerIsChecked': string;
'helpText': string;
'input': string;
'isDisabled': string;
'isIndeterminate': string;
'isNotChecked': string;
'label': string;
'primaryIsChecked': string;
'successIsChecked': string;
'warningIsChecked': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'deviceInputWrapper': string;
'input': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,22 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'dropdownArrowContainer': string;
'dropdownArrowContainerDisabled': string;
'dropdownArrowContainerEditable': string;
'editableContainer': string;
'enhancedSelect': string;
'hasError': string;
'hasWarning': string;
'isDisabled': string;
'loading': string;
'mobileCloseButton': string;
'mobileCloseButtonContainer': string;
'options': string;
'optionsContainer': string;
'optionsModal': string;
'optionsModalBody': string;
'optionsModalScroller': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -12,9 +12,9 @@ import ModalBody from 'Components/Modal/ModalBody';
import Portal from 'Components/Portal';
import Scroller from 'Components/Scroller/Scroller';
import { icons, scrollDirections, sizes } from 'Helpers/Props';
import { isMobile as isMobileUtil } from 'Utilities/browser';
import * as keyCodes from 'Utilities/Constants/keyCodes';
import getUniqueElememtId from 'Utilities/getUniqueElementId';
import { isMobile as isMobileUtil } from 'Utilities/mobile';
import HintedSelectInputOption from './HintedSelectInputOption';
import HintedSelectInputSelectedValue from './HintedSelectInputSelectedValue';
import TextInput from './TextInput';
@ -113,10 +113,12 @@ class EnhancedSelectInput extends Component {
this._scheduleUpdate();
}
if (!Array.isArray(this.props.value) && prevProps.value !== this.props.value) {
this.setState({
selectedIndex: getSelectedIndex(this.props)
});
if (!Array.isArray(this.props.value)) {
if (prevProps.value !== this.props.value || prevProps.values !== this.props.values) {
this.setState({
selectedIndex: getSelectedIndex(this.props)
});
}
}
}
@ -332,6 +334,11 @@ class EnhancedSelectInput extends Component {
const isMultiSelect = Array.isArray(value);
const selectedOption = getSelectedOption(selectedIndex, values);
let selectedValue = value;
if (!values.length) {
selectedValue = isMultiSelect ? [] : '';
}
return (
<div>
@ -372,15 +379,17 @@ class EnhancedSelectInput extends Component {
onPress={this.onPress}
>
{
isFetching &&
isFetching ?
<LoadingIndicator
className={styles.loading}
size={20}
/>
/> :
null
}
{
!isFetching &&
isFetching ?
null :
<Icon
name={icons.CARET_DOWN}
/>
@ -400,7 +409,7 @@ class EnhancedSelectInput extends Component {
onPress={this.onPress}
>
<SelectedValueComponent
value={value}
value={selectedValue}
values={values}
{...selectedValueOptions}
{...selectedOption}
@ -418,15 +427,17 @@ class EnhancedSelectInput extends Component {
>
{
isFetching &&
isFetching ?
<LoadingIndicator
className={styles.loading}
size={20}
/>
/> :
null
}
{
!isFetching &&
isFetching ?
null :
<Icon
name={icons.CARET_DOWN}
/>
@ -505,7 +516,7 @@ class EnhancedSelectInput extends Component {
</Manager>
{
isMobile &&
isMobile ?
<Modal
className={styles.optionsModal}
size={sizes.EXTRA_SMALL}
@ -555,7 +566,8 @@ class EnhancedSelectInput extends Component {
}
</Scroller>
</ModalBody>
</Modal>
</Modal> :
null
}
</div>
);

@ -0,0 +1,14 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'iconContainer': string;
'isDisabled': string;
'isHidden': string;
'isMobile': string;
'isSelected': string;
'option': string;
'optionCheck': string;
'optionCheckInput': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'isDisabled': string;
'selectedValue': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'validationFailures': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,11 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'extraSmall': string;
'group': string;
'large': string;
'medium': string;
'small': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'button': string;
'middleButton': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,14 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'helpLink': string;
'inputContainer': string;
'inputGroup': string;
'inputGroupContainer': string;
'inputUnit': string;
'inputUnitNumber': string;
'pendingChangesContainer': string;
'pendingChangesIcon': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -1,7 +1,7 @@
import PropTypes from 'prop-types';
import React from 'react';
import Link from 'Components/Link/Link';
import { inputTypes } from 'Helpers/Props';
import { inputTypes, kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import AppProfileSelectInputConnector from './AppProfileSelectInputConnector';
import AutoCompleteInput from './AutoCompleteInput';
@ -253,16 +253,24 @@ FormInputGroup.propTypes = {
className: PropTypes.string.isRequired,
containerClassName: PropTypes.string.isRequired,
inputClassName: PropTypes.string,
name: PropTypes.string.isRequired,
value: PropTypes.any,
values: PropTypes.arrayOf(PropTypes.any),
type: PropTypes.string.isRequired,
kind: PropTypes.oneOf(kinds.all),
unit: PropTypes.string,
buttons: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]),
helpText: PropTypes.string,
helpTexts: PropTypes.arrayOf(PropTypes.string),
helpTextWarning: PropTypes.string,
helpLink: PropTypes.string,
includeNoChange: PropTypes.bool,
includeNoChangeDisabled: PropTypes.bool,
selectedValueOptions: PropTypes.object,
pending: PropTypes.bool,
errors: PropTypes.arrayOf(PropTypes.object),
warnings: PropTypes.arrayOf(PropTypes.object)
warnings: PropTypes.arrayOf(PropTypes.object),
onChange: PropTypes.func.isRequired
};
FormInputGroup.defaultProps = {

@ -0,0 +1,12 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'details': string;
'helpText': string;
'isCheckInput': string;
'isError': string;
'isWarning': string;
'link': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,11 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'hasError': string;
'isAdvanced': string;
'label': string;
'large': string;
'small': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -4,16 +4,18 @@ import React from 'react';
import { sizes } from 'Helpers/Props';
import styles from './FormLabel.css';
function FormLabel({
children,
className,
errorClassName,
size,
name,
hasError,
isAdvanced,
...otherProps
}) {
function FormLabel(props) {
const {
children,
className,
errorClassName,
size,
name,
hasError,
isAdvanced,
...otherProps
} = props;
return (
<label
{...otherProps}
@ -31,13 +33,13 @@ function FormLabel({
}
FormLabel.propTypes = {
children: PropTypes.node.isRequired,
children: PropTypes.oneOfType([PropTypes.node, PropTypes.string]).isRequired,
className: PropTypes.string,
errorClassName: PropTypes.string,
size: PropTypes.oneOf(sizes.all),
name: PropTypes.string,
hasError: PropTypes.bool,
isAdvanced: PropTypes.bool.isRequired
isAdvanced: PropTypes.bool
};
FormLabel.defaultProps = {

@ -0,0 +1,9 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'hintText': string;
'isMobile': string;
'optionText': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,9 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'hintText': string;
'selectedValue': string;
'valueText': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,10 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'hasError': string;
'hasWarning': string;
'inputContainer': string;
'isFocused': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,11 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'buttonWrapper': string;
'inputWrapper': string;
'itemContainer': string;
'keyInput': string;
'valueInput': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'input': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,10 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'fileBrowserButton': string;
'hasFileBrowser': string;
'inputWrapper': string;
'pathMatch': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,10 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'hasError': string;
'hasWarning': string;
'isDisabled': string;
'select': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,9 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'input': string;
'internalInput': string;
'isFocused': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'inputContainer': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'tag': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,10 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'hasError': string;
'hasWarning': string;
'input': string;
'readOnly': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,11 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'hasButton': string;
'hasError': string;
'hasWarning': string;
'input': string;
'readOnly': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,13 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'danger': string;
'default': string;
'disabled': string;
'info': string;
'purple': string;
'success': string;
'warning': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,19 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'danger': string;
'default': string;
'disabled': string;
'info': string;
'inverse': string;
'label': string;
'large': string;
'medium': string;
'outline': string;
'primary': string;
'small': string;
'success': string;
'warning': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -31,6 +31,7 @@ function Label(props) {
Label.propTypes = {
className: PropTypes.string.isRequired,
title: PropTypes.string,
kind: PropTypes.oneOf(kinds.all).isRequired,
size: PropTypes.oneOf(sizes.all).isRequired,
outline: PropTypes.bool.isRequired,

@ -0,0 +1,18 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'button': string;
'center': string;
'danger': string;
'default': string;
'large': string;
'left': string;
'medium': string;
'primary': string;
'right': string;
'small': string;
'success': string;
'warning': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,10 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'button': string;
'clipboardIconContainer': string;
'showStateIcon': string;
'stateIconContainer': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'button': string;
'isDisabled': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -38,11 +38,13 @@ function IconButton(props) {
}
IconButton.propTypes = {
...Link.propTypes,
className: PropTypes.string.isRequired,
iconClassName: PropTypes.string,
kind: PropTypes.string,
name: PropTypes.object.isRequired,
size: PropTypes.number,
title: PropTypes.string,
isSpinning: PropTypes.bool,
isDisabled: PropTypes.bool
};

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'link': string;
'to': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,11 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'button': string;
'isSpinning': string;
'label': string;
'spinner': string;
'spinnerContainer': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -42,6 +42,7 @@ function SpinnerButton(props) {
}
SpinnerButton.propTypes = {
...Button.Props,
className: PropTypes.string.isRequired,
isSpinning: PropTypes.bool.isRequired,
isDisabled: PropTypes.bool,

@ -0,0 +1,10 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'icon': string;
'iconContainer': string;
'label': string;
'showIcon': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -23,6 +23,8 @@ function SpinnerIconButton(props) {
}
SpinnerIconButton.propTypes = {
...IconButton.propTypes,
className: PropTypes.string,
name: PropTypes.object.isRequired,
spinningName: PropTypes.object.isRequired,
isDisabled: PropTypes.bool.isRequired,

@ -0,0 +1,9 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'loading': string;
'ripple': string;
'rippleContainer': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'loadingMessage': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'filterMenu': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'menu': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'isDisabled': string;
'menuButton': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'menuContent': string;
'scroller': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'isDisabled': string;
'menuItem': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'separator': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,9 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'isNotSelected': string;
'isSelected': string;
'item': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
import React from 'react';
import Menu from 'Components/Menu/Menu';
import ToolbarMenuButton from 'Components/Menu/ToolbarMenuButton';
import { icons } from 'Helpers/Props';
import { align, icons } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
function SortMenu(props) {
@ -31,7 +31,8 @@ function SortMenu(props) {
SortMenu.propTypes = {
className: PropTypes.string,
children: PropTypes.node.isRequired,
isDisabled: PropTypes.bool.isRequired
isDisabled: PropTypes.bool.isRequired,
alignMenu: PropTypes.oneOf([align.LEFT, align.RIGHT])
};
SortMenu.defaultProps = {

@ -0,0 +1,10 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'indicatorContainer': string;
'label': string;
'labelContainer': string;
'menuButton': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
import React from 'react';
import Menu from 'Components/Menu/Menu';
import ToolbarMenuButton from 'Components/Menu/ToolbarMenuButton';
import { icons } from 'Helpers/Props';
import { align, icons } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
function ViewMenu(props) {
@ -28,7 +28,8 @@ function ViewMenu(props) {
ViewMenu.propTypes = {
children: PropTypes.node.isRequired,
isDisabled: PropTypes.bool.isRequired
isDisabled: PropTypes.bool.isRequired,
alignMenu: PropTypes.oneOf([align.LEFT, align.RIGHT])
};
ViewMenu.defaultProps = {

@ -0,0 +1,15 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'extraLarge': string;
'large': string;
'medium': string;
'modal': string;
'modalBackdrop': string;
'modalContainer': string;
'modalOpen': string;
'modalOpenIOS': string;
'small': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -6,9 +6,9 @@ import ReactDOM from 'react-dom';
import FocusLock from 'react-focus-lock';
import ErrorBoundary from 'Components/Error/ErrorBoundary';
import { sizes } from 'Helpers/Props';
import { isIOS } from 'Utilities/browser';
import * as keyCodes from 'Utilities/Constants/keyCodes';
import getUniqueElememtId from 'Utilities/getUniqueElementId';
import { isIOS } from 'Utilities/mobile';
import { setScrollLock } from 'Utilities/scrollLock';
import ModalError from './ModalError';
import styles from './Modal.css';

@ -0,0 +1,9 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'innerModalBody': string;
'modalBody': string;
'modalScroller': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'closeButton': string;
'modalContent': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'details': string;
'message': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'modalFooter': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'modalHeader': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,9 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'container': string;
'image': string;
'message': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'page': string;
'version': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,18 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'addNewMovieSuggestion': string;
'container': string;
'containerOpen': string;
'highlighted': string;
'input': string;
'list': string;
'listItem': string;
'loading': string;
'movieContainer': string;
'ripple': string;
'sectionTitle': string;
'wrapper': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,12 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'alternateTitle': string;
'poster': string;
'result': string;
'tagContainer': string;
'title': string;
'titles': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'key': string;
'shortcut': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,16 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'actionMenu': string;
'appTitle': string;
'donate': string;
'header': string;
'logo': string;
'logoContainer': string;
'logoFull': string;
'right': string;
'sidebarToggleContainer': string;
'translate': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'itemIcon': string;
'menuButton': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'logoFull': string;
'page': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'main': string;
'page': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'content': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,8 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'contentBody': string;
'innerContentBody': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -1,74 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import OverlayScroller from 'Components/Scroller/OverlayScroller';
import Scroller from 'Components/Scroller/Scroller';
import { scrollDirections } from 'Helpers/Props';
import { isMobile as isMobileUtil } from 'Utilities/mobile';
import { isLocked } from 'Utilities/scrollLock';
import styles from './PageContentBody.css';
class PageContentBody extends Component {
//
// Lifecycle
constructor(props, context) {
super(props, context);
this._isMobile = isMobileUtil();
}
//
// Listeners
onScroll = (props) => {
const { onScroll } = this.props;
if (this.props.onScroll && !isLocked()) {
onScroll(props);
}
};
//
// Render
render() {
const {
className,
innerClassName,
children,
dispatch,
...otherProps
} = this.props;
const ScrollerComponent = this._isMobile ? Scroller : OverlayScroller;
return (
<ScrollerComponent
className={className}
scrollDirection={scrollDirections.VERTICAL}
{...otherProps}
onScroll={this.onScroll}
>
<div className={innerClassName}>
{children}
</div>
</ScrollerComponent>
);
}
}
PageContentBody.propTypes = {
className: PropTypes.string,
innerClassName: PropTypes.string,
children: PropTypes.node.isRequired,
onScroll: PropTypes.func,
dispatch: PropTypes.func
};
PageContentBody.defaultProps = {
className: styles.contentBody,
innerClassName: styles.innerContentBody
};
export default PageContentBody;

@ -0,0 +1,51 @@
import React, { forwardRef, ReactNode, useCallback } from 'react';
import Scroller from 'Components/Scroller/Scroller';
import ScrollDirection from 'Helpers/Props/ScrollDirection';
import { isLocked } from 'Utilities/scrollLock';
import styles from './PageContentBody.css';
interface PageContentBodyProps {
className: string;
innerClassName: string;
children: ReactNode;
initialScrollTop?: number;
onScroll?: (payload) => void;
}
const PageContentBody = forwardRef(
(
props: PageContentBodyProps,
ref: React.MutableRefObject<HTMLDivElement>
) => {
const {
className = styles.contentBody,
innerClassName = styles.innerContentBody,
children,
onScroll,
...otherProps
} = props;
const onScrollWrapper = useCallback(
(payload) => {
if (onScroll && !isLocked()) {
onScroll(payload);
}
},
[onScroll]
);
return (
<Scroller
ref={ref}
{...otherProps}
className={className}
scrollDirection={ScrollDirection.Vertical}
onScroll={onScrollWrapper}
>
<div className={innerClassName}>{children}</div>
</Scroller>
);
}
);
export default PageContentBody;

@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'content': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -8,18 +8,10 @@
@media only screen and (max-width: $breakpointSmall) {
.contentFooter {
display: block;
div {
margin-top: 10px;
&:first-child {
margin-top: 0;
}
}
}
}
@media only screen and (max-width: $breakpointLarge) {
@media only screen and (max-width: $breakpointExtraLarge) {
.contentFooter {
flex-wrap: wrap;
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save