mirror of
https://github.com/lidarr/lidarr.git
synced 2025-08-19 21:13:28 -07:00
UI Formatting Cleanup
This commit is contained in:
parent
b963f2aa82
commit
52e3d96f4a
110 changed files with 901 additions and 701 deletions
|
@ -142,6 +142,8 @@ class BlacklistRow extends Component {
|
|||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -205,6 +205,8 @@ class HistoryRow extends Component {
|
|||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -268,6 +268,8 @@ class QueueRow extends Component {
|
|||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -161,9 +161,7 @@ class AddNewArtist extends Component {
|
|||
</div>
|
||||
}
|
||||
|
||||
<div>
|
||||
|
||||
</div>
|
||||
<div />
|
||||
</PageContentBodyConnector>
|
||||
</PageContent>
|
||||
);
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
.poster {
|
||||
flex: 0 0 170px;
|
||||
margin-right: 20px;
|
||||
margin-right: 20px;
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@ class ImportArtistFooter extends Component {
|
|||
</SpinnerButton>
|
||||
|
||||
{
|
||||
isLookingUpArtist &&
|
||||
isLookingUpArtist &&
|
||||
<LoadingIndicator
|
||||
className={styles.loading}
|
||||
size={24}
|
||||
|
|
|
@ -66,7 +66,6 @@
|
|||
.searchInput {
|
||||
composes: text from 'Components/Form/TextInput.css';
|
||||
|
||||
/*border-left: 0;*/
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
|
|
@ -116,8 +116,7 @@ class ImportArtistSelectArtist extends Component {
|
|||
isPopulated,
|
||||
error,
|
||||
items,
|
||||
queued,
|
||||
onArtistSelect
|
||||
queued
|
||||
} = this.props;
|
||||
|
||||
const errorMessage = error &&
|
||||
|
|
|
@ -4,7 +4,6 @@ import React, { Component } from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { push } from 'react-router-redux';
|
||||
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
|
||||
import { fetchRootFolders, addRootFolder, deleteRootFolder } from 'Store/Actions/rootFolderActions';
|
||||
import ImportArtistSelectFolder from './ImportArtistSelectFolder';
|
||||
|
||||
|
|
|
@ -62,9 +62,9 @@ AlbumStudioConnector.propTypes = {
|
|||
};
|
||||
|
||||
export default connectSection(
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'series', uiSection: 'albumStudio' }
|
||||
)(AlbumStudioConnector);
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'series', uiSection: 'albumStudio' }
|
||||
)(AlbumStudioConnector);
|
||||
|
|
|
@ -10,6 +10,6 @@
|
|||
.changes {
|
||||
margin-top: 20px;
|
||||
padding-bottom: 5px;
|
||||
font-size: 18px;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
|
|
@ -429,7 +429,7 @@ class ArtistDetails extends Component {
|
|||
foreignArtistId={foreignArtistId}
|
||||
links={links}
|
||||
/>
|
||||
}
|
||||
}
|
||||
kind={kinds.INVERSE}
|
||||
position={tooltipPositions.BOTTOM}
|
||||
/>
|
||||
|
|
|
@ -2,7 +2,6 @@ import PropTypes from 'prop-types';
|
|||
import React from 'react';
|
||||
import { kinds, sizes } from 'Helpers/Props';
|
||||
import Label from 'Components/Label';
|
||||
import styles from './ArtistTags.css';
|
||||
|
||||
function ArtistTags({ tags }) {
|
||||
return (
|
||||
|
|
|
@ -78,9 +78,9 @@ ArtistEditorConnector.propTypes = {
|
|||
};
|
||||
|
||||
export default connectSection(
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'series', uiSection: 'artistEditor' }
|
||||
)(ArtistEditorConnector);
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'series', uiSection: 'artistEditor' }
|
||||
)(ArtistEditorConnector);
|
||||
|
|
|
@ -51,8 +51,7 @@ class TagsModalContent extends Component {
|
|||
const {
|
||||
artistTags,
|
||||
tagList,
|
||||
onModalClose,
|
||||
onApplyTagsPress
|
||||
onModalClose
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
|
@ -107,55 +106,55 @@ class TagsModalContent extends Component {
|
|||
<FormLabel>Result</FormLabel>
|
||||
|
||||
<div className={styles.result}>
|
||||
{
|
||||
artistTags.map((t) => {
|
||||
{
|
||||
artistTags.map((t) => {
|
||||
const tag = _.find(tagList, { id: t });
|
||||
|
||||
if (!tag) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const removeTag = (applyTags === 'remove' && tags.indexOf(t) > -1) ||
|
||||
(applyTags === 'replace' && tags.indexOf(t) === -1);
|
||||
|
||||
return (
|
||||
<Label
|
||||
key={tag.id}
|
||||
title={removeTag ? 'Removing tag' : 'Existing tag'}
|
||||
kind={removeTag ? kinds.INVERSE : kinds.INFO}
|
||||
size={sizes.LARGE}
|
||||
>
|
||||
{tag.label}
|
||||
</Label>
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
(applyTags === 'add' || applyTags === 'replace') &&
|
||||
tags.map((t) => {
|
||||
const tag = _.find(tagList, { id: t });
|
||||
|
||||
if (!tag) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const removeTag = (applyTags === 'remove' && tags.indexOf(t) > -1) ||
|
||||
(applyTags === 'replace' && tags.indexOf(t) === -1);
|
||||
if (artistTags.indexOf(t) > -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Label
|
||||
key={tag.id}
|
||||
title={removeTag ? 'Removing tag' : 'Existing tag'}
|
||||
kind={removeTag ? kinds.INVERSE : kinds.INFO}
|
||||
title={'Adding tag'}
|
||||
kind={kinds.SUCCESS}
|
||||
size={sizes.LARGE}
|
||||
>
|
||||
{tag.label}
|
||||
</Label>
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
(applyTags === 'add' || applyTags === 'replace') &&
|
||||
tags.map((t) => {
|
||||
const tag = _.find(tagList, { id: t });
|
||||
|
||||
if (!tag) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (artistTags.indexOf(t) > -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Label
|
||||
key={tag.id}
|
||||
title={'Adding tag'}
|
||||
kind={kinds.SUCCESS}
|
||||
size={sizes.LARGE}
|
||||
>
|
||||
{tag.label}
|
||||
</Label>
|
||||
);
|
||||
})
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import _ from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
@ -151,6 +150,7 @@ class ArtistIndexConnector extends Component {
|
|||
}
|
||||
|
||||
ArtistIndexConnector.propTypes = {
|
||||
isSmallScreen: PropTypes.bool.isRequired,
|
||||
view: PropTypes.string.isRequired,
|
||||
scrollTop: PropTypes.number.isRequired,
|
||||
fetchArtist: PropTypes.func.isRequired,
|
||||
|
|
|
@ -31,22 +31,22 @@ function ArtistIndexFooter({ series }) {
|
|||
<div className={styles.footer}>
|
||||
<div>
|
||||
<div className={styles.legendItem}>
|
||||
<div className={styles.continuing}></div>
|
||||
<div className={styles.continuing} />
|
||||
<div>Continuing (All tracks downloaded)</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.legendItem}>
|
||||
<div className={styles.ended}></div>
|
||||
<div className={styles.ended} />
|
||||
<div>Ended (All tracks downloaded)</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.legendItem}>
|
||||
<div className={styles.missingMonitored}></div>
|
||||
<div className={styles.missingMonitored} />
|
||||
<div>Missing Tracks (Artist monitored)</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.legendItem}>
|
||||
<div className={styles.missingUnmonitored}></div>
|
||||
<div className={styles.missingUnmonitored} />
|
||||
<div>Missing Tracks (Artist not monitored)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -12,9 +12,6 @@ $hoverScale: 1.05;
|
|||
box-shadow: 0 0 12px $black;
|
||||
transition: all 200ms ease-in;
|
||||
|
||||
// Transforming causes the content to shift slightly
|
||||
// transform: scale($hoverScale);
|
||||
|
||||
.controls {
|
||||
opacity: 0.9;
|
||||
transition: opacity 200ms linear 150ms;
|
||||
|
|
|
@ -72,6 +72,8 @@ function calculateRowHeight(bannerHeight, sortKey, isSmallScreen, bannerOptions)
|
|||
heights.push(19);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// No need to add a height of 0
|
||||
}
|
||||
|
||||
return heights.reduce((acc, height) => acc + height, 0);
|
||||
|
|
|
@ -25,9 +25,9 @@ function createMapStateToProps() {
|
|||
}
|
||||
|
||||
export default connectSection(
|
||||
createMapStateToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ withRef: true },
|
||||
{ section: 'series', uiSection: 'artistIndex' }
|
||||
)(ArtistIndexBanners);
|
||||
createMapStateToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ withRef: true },
|
||||
{ section: 'series', uiSection: 'artistIndex' }
|
||||
)(ArtistIndexBanners);
|
||||
|
|
|
@ -12,9 +12,6 @@ $hoverScale: 1.05;
|
|||
box-shadow: 0 0 12px $black;
|
||||
transition: all 200ms ease-in;
|
||||
|
||||
// Transforming causes the content to shift slightly
|
||||
// transform: scale($hoverScale);
|
||||
|
||||
.controls {
|
||||
opacity: 0.9;
|
||||
transition: opacity 200ms linear 150ms;
|
||||
|
|
|
@ -72,6 +72,8 @@ function calculateRowHeight(posterHeight, sortKey, isSmallScreen, posterOptions)
|
|||
heights.push(19);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// No need to add a height of 0
|
||||
}
|
||||
|
||||
return heights.reduce((acc, height) => acc + height, 0);
|
||||
|
|
|
@ -25,9 +25,9 @@ function createMapStateToProps() {
|
|||
}
|
||||
|
||||
export default connectSection(
|
||||
createMapStateToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ withRef: true },
|
||||
{ section: 'series', uiSection: 'artistIndex' }
|
||||
)(ArtistIndexPosters);
|
||||
createMapStateToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ withRef: true },
|
||||
{ section: 'series', uiSection: 'artistIndex' }
|
||||
)(ArtistIndexPosters);
|
||||
|
|
|
@ -26,9 +26,9 @@ function createMapDispatchToProps(dispatch, props) {
|
|||
}
|
||||
|
||||
export default connectSection(
|
||||
createMapStateToProps,
|
||||
createMapDispatchToProps,
|
||||
undefined,
|
||||
{ withRef: true },
|
||||
{ section: 'series', uiSection: 'artistIndex' }
|
||||
)(ArtistIndexTable);
|
||||
createMapStateToProps,
|
||||
createMapDispatchToProps,
|
||||
undefined,
|
||||
{ withRef: true },
|
||||
{ section: 'series', uiSection: 'artistIndex' }
|
||||
)(ArtistIndexTable);
|
||||
|
|
|
@ -20,7 +20,8 @@ function CalendarDay(props) {
|
|||
<div className={classNames(
|
||||
styles.day,
|
||||
view === calendarViews.DAY && styles.isSingleDay
|
||||
)}>
|
||||
)}
|
||||
>
|
||||
{
|
||||
view === calendarViews.MONTH &&
|
||||
<div className={classNames(
|
||||
|
|
|
@ -134,7 +134,8 @@ class CalendarDays extends Component {
|
|||
<div className={classNames(
|
||||
styles.days,
|
||||
styles[view]
|
||||
)}>
|
||||
)}
|
||||
>
|
||||
{
|
||||
dates.map((date) => {
|
||||
return (
|
||||
|
|
|
@ -36,7 +36,8 @@ class DayOfWeek extends Component {
|
|||
styles.dayOfWeek,
|
||||
view === calendarViews.DAY && styles.isSingleDay,
|
||||
highlightToday && styles.isToday
|
||||
)}>
|
||||
)}
|
||||
>
|
||||
{formatedDate}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint max-params: 0 */
|
||||
import moment from 'moment';
|
||||
|
||||
function getStatusStyle(episodeNumber, downloading, startTime, isMonitored) {
|
||||
|
|
|
@ -103,8 +103,7 @@ class CircularProgressBar extends Component {
|
|||
strokeWidth,
|
||||
strokeDashoffset
|
||||
}}
|
||||
>
|
||||
</circle>
|
||||
/>
|
||||
</svg>
|
||||
|
||||
{
|
||||
|
|
|
@ -366,7 +366,7 @@ class EnhancedSelectInput extends Component {
|
|||
}
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { icons, inputTypes } from 'Helpers/Props';
|
||||
import Icon from 'Components/Icon';
|
||||
import { inputTypes } from 'Helpers/Props';
|
||||
import Link from 'Components/Link/Link';
|
||||
import CaptchaInputConnector from './CaptchaInputConnector';
|
||||
import CheckInput from './CheckInput';
|
||||
|
@ -85,7 +84,7 @@ function FormInputGroup(props) {
|
|||
errors,
|
||||
warnings,
|
||||
...otherProps
|
||||
} = props;
|
||||
} = props;
|
||||
|
||||
const InputComponent = getComponent(type);
|
||||
const checkInput = type === inputTypes.CHECK;
|
||||
|
|
|
@ -23,7 +23,8 @@ function FormInputHelpText(props) {
|
|||
isError && styles.isError,
|
||||
isWarning && styles.isWarning,
|
||||
isCheckInput && styles.isCheckInput
|
||||
)}>
|
||||
)}
|
||||
>
|
||||
{text}
|
||||
|
||||
{
|
||||
|
|
|
@ -98,8 +98,13 @@ RootFolderSelectInput.propTypes = {
|
|||
values: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
isSaving: PropTypes.bool.isRequired,
|
||||
saveError: PropTypes.object,
|
||||
includeNoChange: PropTypes.bool.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onNewRootFolderSelect: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
RootFolderSelectInput.defaultProps = {
|
||||
includeNoChange: false
|
||||
};
|
||||
|
||||
export default RootFolderSelectInput;
|
||||
|
|
|
@ -21,7 +21,8 @@ function RootFolderSelectInputOption(props) {
|
|||
<div className={classNames(
|
||||
styles.optionText,
|
||||
isMobile && styles.isMobile
|
||||
)}>
|
||||
)}
|
||||
>
|
||||
<div>{value}</div>
|
||||
|
||||
{
|
||||
|
|
|
@ -18,8 +18,8 @@ function RootFolderSelectInputSelectedValue(props) {
|
|||
{...otherProps}
|
||||
>
|
||||
<div className={styles.path}>
|
||||
{value
|
||||
}</div>
|
||||
{value}
|
||||
</div>
|
||||
|
||||
{
|
||||
freeSpace != null && includeFreeSpace &&
|
||||
|
|
|
@ -24,8 +24,7 @@ function Icon(props) {
|
|||
style={{
|
||||
fontSize: `${size}px`
|
||||
}}
|
||||
>
|
||||
</i>
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,6 @@ class ClipboardButton extends Component {
|
|||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
|
||||
const {
|
||||
showSuccess,
|
||||
showError
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
cursor: pointer;
|
||||
|
||||
&:global(.isDisabled) {
|
||||
/*color: $disabledColor;*/
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,24 +28,8 @@
|
|||
position: absolute;
|
||||
border: 2px solid #3a3f51;
|
||||
border-radius: 100%;
|
||||
animation-fill-mode: both;
|
||||
animation: rippleContainer 1.25s 0s infinite cubic-bezier(0.21, 0.53, 0.56, 0.8);
|
||||
}
|
||||
|
||||
@-webkit-keyframes rippleContainer {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform: scale(0.1);
|
||||
}
|
||||
|
||||
70% {
|
||||
opacity: 0.7;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
@keyframes rippleContainer {
|
||||
|
|
|
@ -1,35 +1,29 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import Menu from 'Components/Menu/Menu';
|
||||
import ToolbarMenuButton from 'Components/Menu/ToolbarMenuButton';
|
||||
import styles from './FilterMenu.css';
|
||||
|
||||
class FilterMenu extends Component {
|
||||
function FilterMenu(props) {
|
||||
const {
|
||||
className,
|
||||
children,
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
className,
|
||||
children,
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Menu
|
||||
className={className}
|
||||
{...otherProps}
|
||||
>
|
||||
<ToolbarMenuButton
|
||||
iconName={icons.FILTER}
|
||||
text="Filter"
|
||||
/>
|
||||
{children}
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Menu
|
||||
className={className}
|
||||
{...otherProps}
|
||||
>
|
||||
<ToolbarMenuButton
|
||||
iconName={icons.FILTER}
|
||||
text="Filter"
|
||||
/>
|
||||
{children}
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
FilterMenu.propTypes = {
|
||||
|
|
|
@ -1,34 +1,28 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import Menu from 'Components/Menu/Menu';
|
||||
import ToolbarMenuButton from 'Components/Menu/ToolbarMenuButton';
|
||||
|
||||
class SortMenu extends Component {
|
||||
function SortMenu(props) {
|
||||
const {
|
||||
className,
|
||||
children,
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
className,
|
||||
children,
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Menu
|
||||
className={className}
|
||||
{...otherProps}
|
||||
>
|
||||
<ToolbarMenuButton
|
||||
iconName={icons.SORT}
|
||||
text="Sort"
|
||||
/>
|
||||
{children}
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Menu
|
||||
className={className}
|
||||
{...otherProps}
|
||||
>
|
||||
<ToolbarMenuButton
|
||||
iconName={icons.SORT}
|
||||
text="Sort"
|
||||
/>
|
||||
{children}
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
SortMenu.propTypes = {
|
||||
|
|
|
@ -18,7 +18,7 @@ function ViewMenu(props) {
|
|||
iconName={icons.VIEW}
|
||||
text="View"
|
||||
/>
|
||||
{children}
|
||||
{children}
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,8 @@ PageContentBody.propTypes = {
|
|||
className: PropTypes.string,
|
||||
innerClassName: PropTypes.string,
|
||||
isSmallScreen: PropTypes.bool.isRequired,
|
||||
children: PropTypes.node.isRequired
|
||||
children: PropTypes.node.isRequired,
|
||||
dispatch: PropTypes.func
|
||||
};
|
||||
|
||||
PageContentBody.defaultProps = {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.jumpBar {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
align-content: stretch;
|
||||
align-items: stretch;
|
||||
align-self: stretch;
|
||||
justify-content: center;
|
||||
flex: 0 0 30px;
|
||||
|
|
|
@ -43,7 +43,8 @@ function Message(props) {
|
|||
<div className={classNames(
|
||||
styles.message,
|
||||
styles[type]
|
||||
)}>
|
||||
)}
|
||||
>
|
||||
<div className={styles.iconContainer}>
|
||||
<Icon
|
||||
name={getIconName(name)}
|
||||
|
|
|
@ -148,7 +148,8 @@ class PageToolbarSection extends Component {
|
|||
<div className={classNames(
|
||||
styles.section,
|
||||
styles[alignContent]
|
||||
)}>
|
||||
)}
|
||||
>
|
||||
{
|
||||
buttons.map((button) => {
|
||||
return button;
|
||||
|
|
|
@ -8,7 +8,7 @@ class PageToolbarSeparator extends Component {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<div className={styles.separator}></div>
|
||||
<div className={styles.separator} />
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,22 +55,22 @@ function ProgressBar(props) {
|
|||
aria-valuemax="100"
|
||||
style={{ width: progressPercent }}
|
||||
/>
|
||||
{
|
||||
showText &&
|
||||
{
|
||||
showText &&
|
||||
<div
|
||||
className={styles.frontTextContainer}
|
||||
style={{ width: progressPercent }}
|
||||
>
|
||||
<div
|
||||
className={styles.frontTextContainer}
|
||||
style={{ width: progressPercent }}
|
||||
className={styles.frontText}
|
||||
style={{ width: actualWidth }}
|
||||
>
|
||||
<div
|
||||
className={styles.frontText}
|
||||
style={{ width: actualWidth }}
|
||||
>
|
||||
<div>
|
||||
{progressText}
|
||||
</div>
|
||||
<div>
|
||||
{progressText}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
.scroller {
|
||||
/* Placeholder */
|
||||
}
|
||||
|
||||
.thumb {
|
||||
|
|
|
@ -5,7 +5,7 @@ import Link from 'Components/Link/Link';
|
|||
import Icon from 'Components/Icon';
|
||||
import styles from './TableHeaderCell.css';
|
||||
|
||||
class VirtualTableHeaderCell extends Component {
|
||||
class TableHeaderCell extends Component {
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
@ -43,8 +43,8 @@ class VirtualTableHeaderCell extends Component {
|
|||
|
||||
const isSorting = isSortable && sortKey === name;
|
||||
const sortIcon = sortDirection === sortDirections.ASCENDING ?
|
||||
icons.SORT_ASCENDING :
|
||||
icons.SORT_DESCENDING;
|
||||
icons.SORT_ASCENDING :
|
||||
icons.SORT_DESCENDING;
|
||||
|
||||
return (
|
||||
isSortable ?
|
||||
|
@ -72,7 +72,7 @@ class VirtualTableHeaderCell extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
VirtualTableHeaderCell.propTypes = {
|
||||
TableHeaderCell.propTypes = {
|
||||
className: PropTypes.string,
|
||||
name: PropTypes.string.isRequired,
|
||||
label: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
||||
|
@ -86,9 +86,9 @@ VirtualTableHeaderCell.propTypes = {
|
|||
onSortPress: PropTypes.func
|
||||
};
|
||||
|
||||
VirtualTableHeaderCell.defaultProps = {
|
||||
TableHeaderCell.defaultProps = {
|
||||
className: styles.headerCell,
|
||||
isSortable: false
|
||||
};
|
||||
|
||||
export default VirtualTableHeaderCell;
|
||||
export default TableHeaderCell;
|
||||
|
|
|
@ -142,9 +142,9 @@ class VirtualTable extends Component {
|
|||
{...otherProps}
|
||||
/>
|
||||
</Scroller>
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
</WindowScroller>
|
||||
</Measure>
|
||||
);
|
||||
|
|
|
@ -58,8 +58,8 @@ class VirtualTableHeaderCell extends Component {
|
|||
|
||||
const isSorting = isSortable && sortKey === name;
|
||||
const sortIcon = sortDirection === sortDirections.ASCENDING ?
|
||||
icons.SORT_ASCENDING :
|
||||
icons.SORT_DESCENDING;
|
||||
icons.SORT_ASCENDING :
|
||||
icons.SORT_DESCENDING;
|
||||
|
||||
return (
|
||||
isSortable ?
|
||||
|
|
4
frontend/src/Content/Fonts/font-awesome.css
vendored
4
frontend/src/Content/Fonts/font-awesome.css
vendored
|
@ -1,3 +1,5 @@
|
|||
/* stylelint-disable */
|
||||
|
||||
/*!
|
||||
* Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
|
||||
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
|
||||
|
@ -2335,3 +2337,5 @@
|
|||
overflow: visible;
|
||||
clip: auto;
|
||||
}
|
||||
|
||||
/* stylelint-enable */
|
|
@ -82,9 +82,9 @@ InteractiveEpisodeSearchConnector.propTypes = {
|
|||
};
|
||||
|
||||
export default connectSection(
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'releases' }
|
||||
)(InteractiveEpisodeSearchConnector);
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'releases' }
|
||||
)(InteractiveEpisodeSearchConnector);
|
||||
|
|
|
@ -66,15 +66,15 @@ class SelectArtistModalContent extends Component {
|
|||
{
|
||||
items.map((item) => {
|
||||
return item.artistName.toLowerCase().includes(filter) ?
|
||||
(
|
||||
<SelectArtistRow
|
||||
key={item.id}
|
||||
id={item.id}
|
||||
artistName={item.artistName}
|
||||
onArtistSelect={onArtistSelect}
|
||||
/>
|
||||
) :
|
||||
null;
|
||||
(
|
||||
<SelectArtistRow
|
||||
key={item.id}
|
||||
id={item.id}
|
||||
artistName={item.artistName}
|
||||
onArtistSelect={onArtistSelect}
|
||||
/>
|
||||
) :
|
||||
null;
|
||||
})
|
||||
}
|
||||
</Scroller>
|
||||
|
|
|
@ -147,9 +147,9 @@ InteractiveImportModalContentConnector.propTypes = {
|
|||
};
|
||||
|
||||
export default connectSection(
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'interactiveImport' }
|
||||
)(InteractiveImportModalContentConnector);
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'interactiveImport' }
|
||||
)(InteractiveImportModalContentConnector);
|
||||
|
|
|
@ -178,7 +178,7 @@ class InteractiveImportRow extends Component {
|
|||
const artistName = artist ? artist.artistName : '';
|
||||
const albumTitle = album ? album.title : '';
|
||||
const trackNumbers = tracks.map((track) => track.trackNumber)
|
||||
.join(', ');
|
||||
.join(', ');
|
||||
|
||||
const showArtistPlaceholder = isSelected && !artist;
|
||||
const showAlbumNumberPlaceholder = isSelected && !!artist && !album;
|
||||
|
|
|
@ -3,7 +3,7 @@ import styles from './InteractiveImportRowCellPlaceholder.css';
|
|||
|
||||
function InteractiveImportRowCellPlaceholder() {
|
||||
return (
|
||||
<span className={styles.placeholder}></span>
|
||||
<span className={styles.placeholder} />
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ class SelectLanguageModalContentConnector extends Component {
|
|||
onLanguageSelect = ({ value }) => {
|
||||
const languageId = parseInt(value);
|
||||
const language = _.find(this.props.items,
|
||||
(item) => item.language.id === languageId).language;
|
||||
(item) => item.language.id === languageId).language;
|
||||
|
||||
this.props.updateInteractiveImportItem({
|
||||
id: this.props.id,
|
||||
|
|
|
@ -49,7 +49,7 @@ class SelectQualityModalContentConnector extends Component {
|
|||
|
||||
onQualitySelect = ({ qualityId, proper, real }) => {
|
||||
const quality = _.find(this.props.items,
|
||||
(item) => item.quality.id === qualityId).quality;
|
||||
(item) => item.quality.id === qualityId).quality;
|
||||
|
||||
const revision = {
|
||||
version: proper ? 2 : 1,
|
||||
|
|
|
@ -46,7 +46,7 @@ class AddDownloadClientModalContent extends Component {
|
|||
}
|
||||
|
||||
{
|
||||
!isFetching && !error &&
|
||||
isPopulated && !error &&
|
||||
<div>
|
||||
|
||||
<Alert kind={kinds.INFO}>
|
||||
|
|
|
@ -84,9 +84,9 @@ DownloadClientOptionsConnector.propTypes = {
|
|||
};
|
||||
|
||||
export default connectSection(
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
{ withRef: true },
|
||||
{ section: 'downloadClientOptions' }
|
||||
)(DownloadClientOptionsConnector);
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
{ withRef: true },
|
||||
{ section: 'downloadClientOptions' }
|
||||
)(DownloadClientOptionsConnector);
|
||||
|
|
|
@ -109,9 +109,9 @@ GeneralSettingsConnector.propTypes = {
|
|||
};
|
||||
|
||||
export default connectSection(
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'general' }
|
||||
)(GeneralSettingsConnector);
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'general' }
|
||||
)(GeneralSettingsConnector);
|
||||
|
|
|
@ -84,9 +84,9 @@ IndexerOptionsConnector.propTypes = {
|
|||
};
|
||||
|
||||
export default connectSection(
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
{ withRef: true },
|
||||
{ section: 'indexerOptions' }
|
||||
)(IndexerOptionsConnector);
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
{ withRef: true },
|
||||
{ section: 'indexerOptions' }
|
||||
)(IndexerOptionsConnector);
|
||||
|
|
|
@ -83,9 +83,9 @@ MediaManagementConnector.propTypes = {
|
|||
};
|
||||
|
||||
export default connectSection(
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'mediaManagement' }
|
||||
)(MediaManagementConnector);
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'mediaManagement' }
|
||||
)(MediaManagementConnector);
|
||||
|
|
|
@ -94,9 +94,9 @@ NamingConnector.propTypes = {
|
|||
};
|
||||
|
||||
export default connectSection(
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'naming' }
|
||||
)(NamingConnector);
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'naming' }
|
||||
)(NamingConnector);
|
||||
|
|
|
@ -168,21 +168,21 @@ class NamingModal extends Component {
|
|||
<FieldSet legend="File Names">
|
||||
<div className={styles.groups}>
|
||||
{
|
||||
fileNameTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
key={token}
|
||||
name={name}
|
||||
value={value}
|
||||
token={token}
|
||||
example={example}
|
||||
isFullFilename={true}
|
||||
tokenCase={this.state.case}
|
||||
size={sizes.LARGE}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
fileNameTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
key={token}
|
||||
name={name}
|
||||
value={value}
|
||||
token={token}
|
||||
example={example}
|
||||
isFullFilename={true}
|
||||
tokenCase={this.state.case}
|
||||
size={sizes.LARGE}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
@ -192,19 +192,19 @@ class NamingModal extends Component {
|
|||
<FieldSet legend="Artist">
|
||||
<div className={styles.groups}>
|
||||
{
|
||||
artistTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
key={token}
|
||||
name={name}
|
||||
value={value}
|
||||
token={token}
|
||||
example={example}
|
||||
tokenCase={this.state.case}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
artistTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
key={token}
|
||||
name={name}
|
||||
value={value}
|
||||
token={token}
|
||||
example={example}
|
||||
tokenCase={this.state.case}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
@ -215,7 +215,7 @@ class NamingModal extends Component {
|
|||
<div>
|
||||
<FieldSet legend="Album">
|
||||
<div className={styles.groups}>
|
||||
{
|
||||
{
|
||||
albumTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
|
@ -229,14 +229,14 @@ class NamingModal extends Component {
|
|||
/>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</FieldSet>
|
||||
|
||||
<FieldSet legend="Release Date">
|
||||
<div className={styles.groups}>
|
||||
{
|
||||
{
|
||||
releaseDateTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
|
@ -250,8 +250,8 @@ class NamingModal extends Component {
|
|||
/>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</FieldSet>
|
||||
</div>
|
||||
|
@ -263,19 +263,19 @@ class NamingModal extends Component {
|
|||
<FieldSet legend="Track">
|
||||
<div className={styles.groups}>
|
||||
{
|
||||
trackTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
key={token}
|
||||
name={name}
|
||||
value={value}
|
||||
token={token}
|
||||
example={example}
|
||||
tokenCase={this.state.case}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
trackTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
key={token}
|
||||
name={name}
|
||||
value={value}
|
||||
token={token}
|
||||
example={example}
|
||||
tokenCase={this.state.case}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
@ -290,19 +290,19 @@ class NamingModal extends Component {
|
|||
<FieldSet legend="Track Title">
|
||||
<div className={styles.groups}>
|
||||
{
|
||||
trackTitleTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
key={token}
|
||||
name={name}
|
||||
value={value}
|
||||
token={token}
|
||||
example={example}
|
||||
tokenCase={this.state.case}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
trackTitleTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
key={token}
|
||||
name={name}
|
||||
value={value}
|
||||
token={token}
|
||||
example={example}
|
||||
tokenCase={this.state.case}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
@ -311,19 +311,19 @@ class NamingModal extends Component {
|
|||
<FieldSet legend="Quality">
|
||||
<div className={styles.groups}>
|
||||
{
|
||||
qualityTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
key={token}
|
||||
name={name}
|
||||
value={value}
|
||||
token={token}
|
||||
example={example}
|
||||
tokenCase={this.state.case}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
qualityTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
key={token}
|
||||
name={name}
|
||||
value={value}
|
||||
token={token}
|
||||
example={example}
|
||||
tokenCase={this.state.case}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
@ -332,19 +332,19 @@ class NamingModal extends Component {
|
|||
<FieldSet legend="Media Info">
|
||||
<div className={styles.groups}>
|
||||
{
|
||||
mediaInfoTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
key={token}
|
||||
name={name}
|
||||
value={value}
|
||||
token={token}
|
||||
example={example}
|
||||
tokenCase={this.state.case}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
mediaInfoTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
key={token}
|
||||
name={name}
|
||||
value={value}
|
||||
token={token}
|
||||
example={example}
|
||||
tokenCase={this.state.case}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
@ -353,19 +353,19 @@ class NamingModal extends Component {
|
|||
<FieldSet legend="Release Group">
|
||||
<div className={styles.groups}>
|
||||
{
|
||||
releaseGroupTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
key={token}
|
||||
name={name}
|
||||
value={value}
|
||||
token={token}
|
||||
example={example}
|
||||
tokenCase={this.state.case}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
releaseGroupTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
key={token}
|
||||
name={name}
|
||||
value={value}
|
||||
token={token}
|
||||
example={example}
|
||||
tokenCase={this.state.case}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
@ -374,20 +374,20 @@ class NamingModal extends Component {
|
|||
<FieldSet legend="Original">
|
||||
<div className={styles.groups}>
|
||||
{
|
||||
originalTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
key={token}
|
||||
name={name}
|
||||
value={value}
|
||||
token={token}
|
||||
example={example}
|
||||
tokenCase={this.state.case}
|
||||
size={sizes.LARGE}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
originalTokens.map(({ token, example }) => {
|
||||
return (
|
||||
<NamingOption
|
||||
key={token}
|
||||
name={name}
|
||||
value={value}
|
||||
token={token}
|
||||
example={example}
|
||||
tokenCase={this.state.case}
|
||||
size={sizes.LARGE}
|
||||
onInputChange={onInputChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { inputTypes, kinds } from 'Helpers/Props';
|
||||
import { inputTypes } from 'Helpers/Props';
|
||||
import Button from 'Components/Link/Button';
|
||||
import SpinnerErrorButton from 'Components/Link/SpinnerErrorButton';
|
||||
import ModalContent from 'Components/Modal/ModalContent';
|
||||
|
|
|
@ -42,7 +42,7 @@ class AddNotificationModalContent extends Component {
|
|||
}
|
||||
|
||||
{
|
||||
!isFetching && !error &&
|
||||
!isPopulated && !error &&
|
||||
<div>
|
||||
<div className={styles.notifications}>
|
||||
{
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import _ from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { kinds, sizes } from 'Helpers/Props';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import Button from 'Components/Link/Button';
|
||||
import Modal from 'Components/Modal/Modal';
|
||||
import ModalContent from 'Components/Modal/ModalContent';
|
||||
|
@ -11,7 +11,6 @@ import ModalFooter from 'Components/Modal/ModalFooter';
|
|||
function PendingChangesModal(props) {
|
||||
const {
|
||||
isOpen,
|
||||
size,
|
||||
onConfirm,
|
||||
onCancel
|
||||
} = props;
|
||||
|
@ -52,7 +51,6 @@ PendingChangesModal.propTypes = {
|
|||
className: PropTypes.string,
|
||||
isOpen: PropTypes.bool.isRequired,
|
||||
kind: PropTypes.oneOf(kinds.all),
|
||||
size: PropTypes.oneOf(sizes.all),
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
onCancel: PropTypes.func.isRequired
|
||||
};
|
||||
|
|
|
@ -78,7 +78,6 @@ class DelayProfile extends Component {
|
|||
preferredProtocol,
|
||||
usenetDelay,
|
||||
torrentDelay,
|
||||
order,
|
||||
tags,
|
||||
tagList,
|
||||
isDragging,
|
||||
|
@ -158,7 +157,6 @@ DelayProfile.propTypes = {
|
|||
preferredProtocol: PropTypes.string.isRequired,
|
||||
usenetDelay: PropTypes.number.isRequired,
|
||||
torrentDelay: PropTypes.number.isRequired,
|
||||
order: PropTypes.number.isRequired,
|
||||
tags: PropTypes.arrayOf(PropTypes.number).isRequired,
|
||||
tagList: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
isDragging: PropTypes.bool.isRequired,
|
||||
|
|
|
@ -58,7 +58,7 @@ class QualityProfileItem extends Component {
|
|||
name={icons.REORDER}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -74,9 +74,9 @@ UISettingsConnector.propTypes = {
|
|||
};
|
||||
|
||||
export default connectSection(
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'ui' }
|
||||
)(UISettingsConnector);
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'ui' }
|
||||
)(UISettingsConnector);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
if (window.Sonarr.analytics) {
|
||||
var d = document;
|
||||
var g = d.createElement('script');
|
||||
var s = d.getElementsByTagName('script')[0];
|
||||
const d = document;
|
||||
const g = d.createElement('script');
|
||||
const s = d.getElementsByTagName('script')[0];
|
||||
g.type = 'text/javascript';
|
||||
g.async = true;
|
||||
g.defer = true;
|
||||
|
|
4
frontend/src/Shims/jquery.js
vendored
4
frontend/src/Shims/jquery.js
vendored
|
@ -3,6 +3,8 @@ import ajax from 'jQuery/jquery.ajax';
|
|||
|
||||
ajax($);
|
||||
|
||||
const jquery = $;
|
||||
window.$ = $;
|
||||
window.jQuery = $;
|
||||
export default $;
|
||||
|
||||
export default jquery;
|
||||
|
|
|
@ -12,8 +12,8 @@ function createSetServerSideCollectionSortHandler(section, getFromState, fetchHa
|
|||
if (!sortDirection) {
|
||||
if (payload.sortKey === sectionState.sortKey) {
|
||||
sortDirection = sectionState.sortDirection === sortDirections.ASCENDING ?
|
||||
sortDirections.DESCENDING :
|
||||
sortDirections.ASCENDING;
|
||||
sortDirections.DESCENDING :
|
||||
sortDirections.ASCENDING;
|
||||
} else {
|
||||
sortDirection = sectionState.sortDirection;
|
||||
}
|
||||
|
|
|
@ -12,13 +12,15 @@ const section = 'series';
|
|||
const artistActionHandlers = {
|
||||
[types.FETCH_ARTIST]: createFetchHandler(section, '/artist'),
|
||||
|
||||
[types.SAVE_ARTIST]: createSaveProviderHandler(section,
|
||||
'/artist',
|
||||
(state) => state.series),
|
||||
[types.SAVE_ARTIST]: createSaveProviderHandler(
|
||||
section,
|
||||
'/artist',
|
||||
(state) => state.series),
|
||||
|
||||
[types.DELETE_ARTIST]: createRemoveItemHandler(section,
|
||||
'/artist',
|
||||
(state) => state.series),
|
||||
[types.DELETE_ARTIST]: createRemoveItemHandler(
|
||||
section,
|
||||
'/artist',
|
||||
(state) => state.series),
|
||||
|
||||
[types.TOGGLE_ARTIST_MONITORED]: function(payload) {
|
||||
return function(dispatch, getState) {
|
||||
|
|
|
@ -130,12 +130,12 @@ const calendarActionHandlers = {
|
|||
};
|
||||
|
||||
const attrs = isPrePopulated ?
|
||||
{
|
||||
view,
|
||||
...basesAttrs,
|
||||
...dates
|
||||
} :
|
||||
basesAttrs;
|
||||
{
|
||||
view,
|
||||
...basesAttrs,
|
||||
...dates
|
||||
} :
|
||||
basesAttrs;
|
||||
|
||||
dispatch(set(attrs));
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint callback-return: 0 */
|
||||
import _ from 'lodash';
|
||||
import $ from 'jquery';
|
||||
import requestAction from 'Utilities/requestAction';
|
||||
|
|
|
@ -10,9 +10,10 @@ const section = 'rootFolders';
|
|||
const rootFolderActionHandlers = {
|
||||
[types.FETCH_ROOT_FOLDERS]: createFetchHandler('rootFolders', '/rootFolder'),
|
||||
|
||||
[types.DELETE_ROOT_FOLDER]: createRemoveItemHandler('rootFolders',
|
||||
'/rootFolder',
|
||||
(state) => state.rootFolders),
|
||||
[types.DELETE_ROOT_FOLDER]: createRemoveItemHandler(
|
||||
'rootFolders',
|
||||
'/rootFolder',
|
||||
(state) => state.rootFolders),
|
||||
|
||||
[types.ADD_ROOT_FOLDER]: function(payload) {
|
||||
return function(dispatch, getState) {
|
||||
|
|
|
@ -88,34 +88,40 @@ const settingsActionHandlers = {
|
|||
[types.FETCH_QUALITY_PROFILES]: createFetchHandler('qualityProfiles', '/qualityprofile'),
|
||||
[types.FETCH_QUALITY_PROFILE_SCHEMA]: createFetchSchemaHandler('qualityProfiles', '/qualityprofile/schema'),
|
||||
|
||||
[types.SAVE_QUALITY_PROFILE]: createSaveProviderHandler('qualityProfiles',
|
||||
'/qualityprofile',
|
||||
(state) => state.settings.qualityProfiles),
|
||||
[types.SAVE_QUALITY_PROFILE]: createSaveProviderHandler(
|
||||
'qualityProfiles',
|
||||
'/qualityprofile',
|
||||
(state) => state.settings.qualityProfiles),
|
||||
|
||||
[types.DELETE_QUALITY_PROFILE]: createRemoveItemHandler('qualityProfiles',
|
||||
'/qualityprofile',
|
||||
(state) => state.settings.qualityProfiles),
|
||||
[types.DELETE_QUALITY_PROFILE]: createRemoveItemHandler(
|
||||
'qualityProfiles',
|
||||
'/qualityprofile',
|
||||
(state) => state.settings.qualityProfiles),
|
||||
|
||||
[types.FETCH_LANGUAGE_PROFILES]: createFetchHandler('languageProfiles', '/languageprofile'),
|
||||
[types.FETCH_LANGUAGE_PROFILE_SCHEMA]: createFetchSchemaHandler('languageProfiles', '/languageprofile/schema'),
|
||||
|
||||
[types.SAVE_LANGUAGE_PROFILE]: createSaveProviderHandler('languageProfiles',
|
||||
'/languageprofile',
|
||||
(state) => state.settings.languageProfiles),
|
||||
[types.SAVE_LANGUAGE_PROFILE]: createSaveProviderHandler(
|
||||
'languageProfiles',
|
||||
'/languageprofile',
|
||||
(state) => state.settings.languageProfiles),
|
||||
|
||||
[types.DELETE_LANGUAGE_PROFILE]: createRemoveItemHandler('languageProfiles',
|
||||
'/languageprofile',
|
||||
(state) => state.settings.languageProfiles),
|
||||
[types.DELETE_LANGUAGE_PROFILE]: createRemoveItemHandler(
|
||||
'languageProfiles',
|
||||
'/languageprofile',
|
||||
(state) => state.settings.languageProfiles),
|
||||
|
||||
[types.FETCH_DELAY_PROFILES]: createFetchHandler('delayProfiles', '/delayprofile'),
|
||||
|
||||
[types.SAVE_DELAY_PROFILE]: createSaveProviderHandler('delayProfiles',
|
||||
'/delayprofile',
|
||||
(state) => state.settings.delayProfiles),
|
||||
[types.SAVE_DELAY_PROFILE]: createSaveProviderHandler(
|
||||
'delayProfiles',
|
||||
'/delayprofile',
|
||||
(state) => state.settings.delayProfiles),
|
||||
|
||||
[types.DELETE_DELAY_PROFILE]: createRemoveItemHandler('delayProfiles',
|
||||
'/delayprofile',
|
||||
(state) => state.settings.delayProfiles),
|
||||
[types.DELETE_DELAY_PROFILE]: createRemoveItemHandler(
|
||||
'delayProfiles',
|
||||
'/delayprofile',
|
||||
(state) => state.settings.delayProfiles),
|
||||
|
||||
[types.FETCH_QUALITY_DEFINITIONS]: createFetchHandler('qualityDefinitions', '/qualitydefinition'),
|
||||
[types.SAVE_QUALITY_DEFINITIONS]: createSaveHandler('qualityDefinitions', '/qualitydefinition', (state) => state.settings.qualitydefinitions),
|
||||
|
@ -157,19 +163,22 @@ const settingsActionHandlers = {
|
|||
[types.FETCH_INDEXERS]: createFetchHandler('indexers', '/indexer'),
|
||||
[types.FETCH_INDEXER_SCHEMA]: createFetchSchemaHandler('indexers', '/indexer/schema'),
|
||||
|
||||
[types.SAVE_INDEXER]: createSaveProviderHandler('indexers',
|
||||
'/indexer',
|
||||
(state) => state.settings.indexers),
|
||||
[types.SAVE_INDEXER]: createSaveProviderHandler(
|
||||
'indexers',
|
||||
'/indexer',
|
||||
(state) => state.settings.indexers),
|
||||
|
||||
[types.CANCEL_SAVE_INDEXER]: createCancelSaveProviderHandler('indexers'),
|
||||
|
||||
[types.DELETE_INDEXER]: createRemoveItemHandler('indexers',
|
||||
'/indexer',
|
||||
(state) => state.settings.indexers),
|
||||
[types.DELETE_INDEXER]: createRemoveItemHandler(
|
||||
'indexers',
|
||||
'/indexer',
|
||||
(state) => state.settings.indexers),
|
||||
|
||||
[types.TEST_INDEXER]: createTestProviderHandler('indexers',
|
||||
'/indexer',
|
||||
(state) => state.settings.indexers),
|
||||
[types.TEST_INDEXER]: createTestProviderHandler(
|
||||
'indexers',
|
||||
'/indexer',
|
||||
(state) => state.settings.indexers),
|
||||
|
||||
[types.CANCEL_TEST_INDEXER]: createCancelTestProviderHandler('indexers'),
|
||||
|
||||
|
@ -178,30 +187,35 @@ const settingsActionHandlers = {
|
|||
|
||||
[types.FETCH_RESTRICTIONS]: createFetchHandler('restrictions', '/restriction'),
|
||||
|
||||
[types.SAVE_RESTRICTION]: createSaveProviderHandler('restrictions',
|
||||
'/restriction',
|
||||
(state) => state.settings.restrictions),
|
||||
[types.SAVE_RESTRICTION]: createSaveProviderHandler(
|
||||
'restrictions',
|
||||
'/restriction',
|
||||
(state) => state.settings.restrictions),
|
||||
|
||||
[types.DELETE_RESTRICTION]: createRemoveItemHandler('restrictions',
|
||||
'/restriction',
|
||||
(state) => state.settings.restrictions),
|
||||
[types.DELETE_RESTRICTION]: createRemoveItemHandler(
|
||||
'restrictions',
|
||||
'/restriction',
|
||||
(state) => state.settings.restrictions),
|
||||
|
||||
[types.FETCH_DOWNLOAD_CLIENTS]: createFetchHandler('downloadClients', '/downloadclient'),
|
||||
[types.FETCH_DOWNLOAD_CLIENT_SCHEMA]: createFetchSchemaHandler('downloadClients', '/downloadclient/schema'),
|
||||
|
||||
[types.SAVE_DOWNLOAD_CLIENT]: createSaveProviderHandler('downloadClients',
|
||||
'/downloadclient',
|
||||
(state) => state.settings.downloadClients),
|
||||
[types.SAVE_DOWNLOAD_CLIENT]: createSaveProviderHandler(
|
||||
'downloadClients',
|
||||
'/downloadclient',
|
||||
(state) => state.settings.downloadClients),
|
||||
|
||||
[types.CANCEL_SAVE_DOWNLOAD_CLIENT]: createCancelSaveProviderHandler('downloadClients'),
|
||||
|
||||
[types.DELETE_DOWNLOAD_CLIENT]: createRemoveItemHandler('downloadClients',
|
||||
'/downloadclient',
|
||||
(state) => state.settings.downloadClients),
|
||||
[types.DELETE_DOWNLOAD_CLIENT]: createRemoveItemHandler(
|
||||
'downloadClients',
|
||||
'/downloadclient',
|
||||
(state) => state.settings.downloadClients),
|
||||
|
||||
[types.TEST_DOWNLOAD_CLIENT]: createTestProviderHandler('downloadClients',
|
||||
'/downloadclient',
|
||||
(state) => state.settings.downloadClients),
|
||||
[types.TEST_DOWNLOAD_CLIENT]: createTestProviderHandler(
|
||||
'downloadClients',
|
||||
'/downloadclient',
|
||||
(state) => state.settings.downloadClients),
|
||||
|
||||
[types.CANCEL_TEST_DOWNLOAD_CLIENT]: createCancelTestProviderHandler('downloadClients'),
|
||||
|
||||
|
@ -210,38 +224,44 @@ const settingsActionHandlers = {
|
|||
|
||||
[types.FETCH_REMOTE_PATH_MAPPINGS]: createFetchHandler('remotePathMappings', '/remotepathmapping'),
|
||||
|
||||
[types.SAVE_REMOTE_PATH_MAPPING]: createSaveProviderHandler('remotePathMappings',
|
||||
'/remotepathmapping',
|
||||
(state) => state.settings.remotePathMappings),
|
||||
[types.SAVE_REMOTE_PATH_MAPPING]: createSaveProviderHandler(
|
||||
'remotePathMappings',
|
||||
'/remotepathmapping',
|
||||
(state) => state.settings.remotePathMappings),
|
||||
|
||||
[types.DELETE_REMOTE_PATH_MAPPING]: createRemoveItemHandler('remotePathMappings',
|
||||
'/remotepathmapping',
|
||||
(state) => state.settings.remotePathMappings),
|
||||
[types.DELETE_REMOTE_PATH_MAPPING]: createRemoveItemHandler(
|
||||
'remotePathMappings',
|
||||
'/remotepathmapping',
|
||||
(state) => state.settings.remotePathMappings),
|
||||
|
||||
[types.FETCH_NOTIFICATIONS]: createFetchHandler('notifications', '/notification'),
|
||||
[types.FETCH_NOTIFICATION_SCHEMA]: createFetchSchemaHandler('notifications', '/notification/schema'),
|
||||
|
||||
[types.SAVE_NOTIFICATION]: createSaveProviderHandler('notifications',
|
||||
'/notification',
|
||||
(state) => state.settings.notifications),
|
||||
[types.SAVE_NOTIFICATION]: createSaveProviderHandler(
|
||||
'notifications',
|
||||
'/notification',
|
||||
(state) => state.settings.notifications),
|
||||
|
||||
[types.CANCEL_SAVE_NOTIFICATION]: createCancelSaveProviderHandler('notifications'),
|
||||
|
||||
[types.DELETE_NOTIFICATION]: createRemoveItemHandler('notifications',
|
||||
'/notification',
|
||||
(state) => state.settings.notifications),
|
||||
[types.DELETE_NOTIFICATION]: createRemoveItemHandler(
|
||||
'notifications',
|
||||
'/notification',
|
||||
(state) => state.settings.notifications),
|
||||
|
||||
[types.TEST_NOTIFICATION]: createTestProviderHandler('notifications',
|
||||
'/notification',
|
||||
(state) => state.settings.notifications),
|
||||
[types.TEST_NOTIFICATION]: createTestProviderHandler(
|
||||
'notifications',
|
||||
'/notification',
|
||||
(state) => state.settings.notifications),
|
||||
|
||||
[types.CANCEL_TEST_NOTIFICATION]: createCancelTestProviderHandler('notifications'),
|
||||
|
||||
[types.FETCH_METADATA]: createFetchHandler('metadata', '/metadata'),
|
||||
|
||||
[types.SAVE_METADATA]: createSaveProviderHandler('metadata',
|
||||
'/metadata',
|
||||
(state) => state.settings.metadata),
|
||||
[types.SAVE_METADATA]: createSaveProviderHandler(
|
||||
'metadata',
|
||||
'/metadata',
|
||||
(state) => state.settings.metadata),
|
||||
|
||||
[types.FETCH_METADATA_PROVIDER]: createFetchHandler('metadataProvider', '/config/metadataProvider'),
|
||||
[types.SAVE_METADATA_PROVIDER]: createSaveHandler('metadataProvider', '/config/metadataProvider', (state) => state.settings.metadataProvider),
|
||||
|
|
|
@ -1,35 +1,15 @@
|
|||
import { applyMiddleware, compose } from 'redux';
|
||||
import Raven from 'raven-js';
|
||||
import createRavenMiddleware from 'raven-for-redux';
|
||||
import thunk from 'redux-thunk';
|
||||
import { routerMiddleware } from 'react-router-redux';
|
||||
import sentryMiddleware from './sentryMiddleware';
|
||||
import persistState from './persistState';
|
||||
|
||||
export default function(history) {
|
||||
const {
|
||||
analytics,
|
||||
branch,
|
||||
version,
|
||||
release,
|
||||
isProduction
|
||||
} = window.Sonarr;
|
||||
|
||||
const dsn = isProduction ? 'https://c3a5b33e08de4e18b7d0505e942dbc95@sentry.io/216290' :
|
||||
'https://c3a5b33e08de4e18b7d0505e942dbc95@sentry.io/216290';
|
||||
|
||||
Raven.config(dsn).install();
|
||||
|
||||
const middlewares = [];
|
||||
const ravenMiddleware = sentryMiddleware();
|
||||
|
||||
if (analytics) {
|
||||
middlewares.push(createRavenMiddleware(Raven, {
|
||||
environment: isProduction ? 'production' : 'development',
|
||||
release,
|
||||
tags: {
|
||||
branch,
|
||||
version
|
||||
}
|
||||
}));
|
||||
if (ravenMiddleware) {
|
||||
middlewares.push(ravenMiddleware);
|
||||
}
|
||||
|
||||
middlewares.push(routerMiddleware(history));
|
||||
|
|
48
frontend/src/Store/Middleware/sentryMiddleware.js
Normal file
48
frontend/src/Store/Middleware/sentryMiddleware.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
import _ from 'lodash';
|
||||
import Raven from 'raven-js';
|
||||
import createRavenMiddleware from 'raven-for-redux';
|
||||
import parseUrl from 'Utilities/String/parseUrl';
|
||||
|
||||
function cleanseUrl(url) {
|
||||
const properties = parseUrl(url);
|
||||
|
||||
return `${properties.pathname}${properties.search}`;
|
||||
}
|
||||
|
||||
function cleanseData(data) {
|
||||
const result = _.cloneDeep(data);
|
||||
|
||||
result.culprit = cleanseUrl(result.culprit);
|
||||
result.request.url = cleanseUrl(result.request.url);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export default function sentryMiddleware() {
|
||||
const {
|
||||
analytics,
|
||||
branch,
|
||||
version,
|
||||
release,
|
||||
isProduction
|
||||
} = window.Sonarr;
|
||||
|
||||
if (!analytics) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dsn = isProduction ? 'https://c3a5b33e08de4e18b7d0505e942dbc95@sentry.io/216290' :
|
||||
'https://c3a5b33e08de4e18b7d0505e942dbc95@sentry.io/216290';
|
||||
|
||||
Raven.config(dsn).install();
|
||||
|
||||
return createRavenMiddleware(Raven, {
|
||||
environment: isProduction ? 'production' : 'development',
|
||||
release,
|
||||
tags: {
|
||||
branch,
|
||||
version
|
||||
},
|
||||
dataCallback: cleanseData
|
||||
});
|
||||
}
|
|
@ -12,8 +12,8 @@ function createSetClientSideCollectionSortReducer(section) {
|
|||
if (!sortDirection) {
|
||||
if (payload.sortKey === newState.sortKey) {
|
||||
sortDirection = newState.sortDirection === sortDirections.ASCENDING ?
|
||||
sortDirections.DESCENDING :
|
||||
sortDirections.ASCENDING;
|
||||
sortDirections.DESCENDING :
|
||||
sortDirections.ASCENDING;
|
||||
} else {
|
||||
sortDirection = newState.sortDirection;
|
||||
}
|
||||
|
|
|
@ -2,28 +2,6 @@ import _ from 'lodash';
|
|||
import getSectionState from 'Utilities/State/getSectionState';
|
||||
import updateSectionState from 'Utilities/State/updateSectionState';
|
||||
|
||||
const whitelistedProperties = [
|
||||
'isFetching',
|
||||
'isPopulated',
|
||||
'error',
|
||||
'isFetchingSchema',
|
||||
'schemaPopulated',
|
||||
'schemaError',
|
||||
'schema',
|
||||
'selectedSchema',
|
||||
'isSaving',
|
||||
'saveError',
|
||||
'isTesting',
|
||||
'isDeleting',
|
||||
'deleteError',
|
||||
'pendingChanges',
|
||||
'filterKey',
|
||||
'filterValue',
|
||||
'page',
|
||||
'sortKey',
|
||||
'sortDirection'
|
||||
];
|
||||
|
||||
const blacklistedProperties = [
|
||||
'section',
|
||||
'id'
|
||||
|
@ -33,7 +11,7 @@ function createSetReducer(section) {
|
|||
return (state, { payload }) => {
|
||||
if (section === payload.section) {
|
||||
const newState = Object.assign(getSectionState(state, section),
|
||||
_.omit(payload, blacklistedProperties));
|
||||
_.omit(payload, blacklistedProperties));
|
||||
|
||||
return updateSectionState(state, section, newState);
|
||||
}
|
||||
|
|
|
@ -9,8 +9,9 @@ const whitelistedProperties = [
|
|||
|
||||
function createSetTableOptionReducer(section) {
|
||||
return (state, { payload }) => {
|
||||
const newState = Object.assign(getSectionState(state, section),
|
||||
_.pick(payload, whitelistedProperties));
|
||||
const newState = Object.assign(
|
||||
getSectionState(state, section),
|
||||
_.pick(payload, whitelistedProperties));
|
||||
|
||||
return updateSectionState(state, section, newState);
|
||||
};
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { handleActions } from 'redux-actions';
|
||||
import updateSectionState from 'Utilities/State/updateSectionState';
|
||||
import { sortDirections } from 'Helpers/Props';
|
||||
import * as types from 'Store/Actions/actionTypes';
|
||||
import createClearReducer from './Creators/createClearReducer';
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
/* stylelint-disable */
|
||||
|
||||
@import '~normalize.css/normalize.css';
|
||||
@import 'scaffolding.css';
|
||||
@import '../Content/Fonts/fonts.css';
|
||||
@import '../Content/Fonts/font-awesome.css';
|
||||
|
||||
/* stylelint-enable */
|
|
@ -1,19 +1,22 @@
|
|||
/* stylelint-disable */
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
*:before,
|
||||
*:after {
|
||||
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
*:focus {
|
||||
outline: none;
|
||||
}
|
||||
/* stylelint-enable */
|
||||
|
||||
html,
|
||||
body {
|
||||
color: #515253;
|
||||
font-family: "Roboto", "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-family: 'Roboto', 'open sans', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
|
|
|
@ -123,6 +123,8 @@ class LogsTableRow extends Component {
|
|||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ class UpdateChanges extends Component {
|
|||
<li key={index}>
|
||||
{change}
|
||||
</li>
|
||||
)
|
||||
);
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
|
@ -42,4 +42,4 @@ UpdateChanges.propTypes = {
|
|||
changes: PropTypes.arrayOf(PropTypes.string)
|
||||
};
|
||||
|
||||
export default UpdateChanges
|
||||
export default UpdateChanges;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint max-params: 0 */
|
||||
import _ from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import moment from 'moment';
|
||||
|
||||
function isTomrrow(date) {
|
||||
function isTomorrow(date) {
|
||||
if (!date) {
|
||||
return false;
|
||||
}
|
||||
|
@ -8,4 +8,4 @@ function isTomrrow(date) {
|
|||
return moment(date).isSame(moment().add(1, 'day'), 'day');
|
||||
}
|
||||
|
||||
export default isTomrrow;
|
||||
export default isTomorrow;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var $ = require('jquery');
|
||||
import $ from 'jquery';
|
||||
|
||||
module.exports = {
|
||||
resolutions: {
|
||||
|
|
34
frontend/src/Utilities/String/parseUrl.js
Normal file
34
frontend/src/Utilities/String/parseUrl.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
import _ from 'lodash';
|
||||
import qs from 'qs';
|
||||
|
||||
// See: https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils
|
||||
const anchor = document.createElement('a');
|
||||
|
||||
export default function parseUrl(url) {
|
||||
anchor.href = url;
|
||||
|
||||
// The `origin`, `password`, and `username` properties are unavailable in
|
||||
// Opera Presto. We synthesize `origin` if it's not present. While `password`
|
||||
// and `username` are ignored intentionally.
|
||||
const properties = _.pick(
|
||||
anchor,
|
||||
'hash',
|
||||
'host',
|
||||
'hostname',
|
||||
'href',
|
||||
'origin',
|
||||
'pathname',
|
||||
'port',
|
||||
'protocol',
|
||||
'search'
|
||||
);
|
||||
|
||||
properties.isAbsolute = (/^[\w:]*\/\//).test(url);
|
||||
|
||||
if (properties.search) {
|
||||
// Remove leading ? from querystring before parsing.
|
||||
properties.params = qs.parse(properties.search.substring(1));
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
export default function aareAllSelected(selectedState) {
|
||||
export default function areAllSelected(selectedState) {
|
||||
let allSelected = true;
|
||||
let allUnselected = true;
|
||||
|
||||
|
|
|
@ -20,8 +20,7 @@ export default function createAjaxRequest() {
|
|||
xhr.aborted = aborted;
|
||||
|
||||
return $.Deferred().reject(xhr, textStatus, errorThrown).promise();
|
||||
})
|
||||
.always(() => {
|
||||
}).always(() => {
|
||||
complete = true;
|
||||
});
|
||||
|
||||
|
|
|
@ -143,6 +143,8 @@ function CutoffUnmetRow(props) {
|
|||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
}
|
||||
</TableRow>
|
||||
|
|
|
@ -129,6 +129,8 @@ function MissingRow(props) {
|
|||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
}
|
||||
</TableRow>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue