mirror of
https://github.com/lidarr/lidarr.git
synced 2025-07-31 04:00:18 -07:00
[UI Work] Add Artist, Import Artist, Calendar
This commit is contained in:
parent
a747c5f135
commit
77f1d2e64c
109 changed files with 891 additions and 1082 deletions
|
@ -24,25 +24,25 @@ export const SET_APP_VALUE = 'SET_APP_VALUE';
|
|||
export const SET_IS_SIDEBAR_VISIBLE = 'SET_IS_SIDEBAR_VISIBLE';
|
||||
|
||||
//
|
||||
// Add Series
|
||||
// Add Artist
|
||||
|
||||
export const LOOKUP_SERIES = 'LOOKUP_SERIES';
|
||||
export const ADD_SERIES = 'ADD_SERIES';
|
||||
export const SET_ADD_SERIES_VALUE = 'SET_ADD_SERIES_VALUE';
|
||||
export const CLEAR_ADD_SERIES = 'CLEAR_ADD_SERIES';
|
||||
export const SET_ADD_SERIES_DEFAULT = 'SET_ADD_SERIES_DEFAULT';
|
||||
export const LOOKUP_ARTIST = 'LOOKUP_ARTIST';
|
||||
export const ADD_ARTIST = 'ADD_ARTIST';
|
||||
export const SET_ADD_ARTIST_VALUE = 'SET_ADD_ARTIST_VALUE';
|
||||
export const CLEAR_ADD_ARTIST = 'CLEAR_ADD_ARTIST';
|
||||
export const SET_ADD_ARTIST_DEFAULT = 'SET_ADD_ARTIST_DEFAULT';
|
||||
|
||||
//
|
||||
// Import Series
|
||||
// Import Artist
|
||||
|
||||
export const QUEUE_LOOKUP_SERIES = 'QUEUE_LOOKUP_SERIES';
|
||||
export const START_LOOKUP_SERIES = 'START_LOOKUP_SERIES';
|
||||
export const CLEAR_IMPORT_SERIES = 'CLEAR_IMPORT_SERIES';
|
||||
export const SET_IMPORT_SERIES_VALUE = 'SET_IMPORT_SERIES_VALUE';
|
||||
export const IMPORT_SERIES = 'IMPORT_SERIES';
|
||||
export const QUEUE_LOOKUP_ARTIST = 'QUEUE_LOOKUP_ARTIST';
|
||||
export const START_LOOKUP_ARTIST = 'START_LOOKUP_ARTIST';
|
||||
export const CLEAR_IMPORT_ARTIST = 'CLEAR_IMPORT_ARTIST';
|
||||
export const SET_IMPORT_ARTIST_VALUE = 'SET_IMPORT_ARTIST_VALUE';
|
||||
export const IMPORT_ARTIST = 'IMPORT_ARTIST';
|
||||
|
||||
//
|
||||
// Series
|
||||
// Artist
|
||||
|
||||
export const FETCH_ARTIST = 'FETCH_ARTIST';
|
||||
export const SET_ARTIST_VALUE = 'SET_ARTIST_VALUE';
|
||||
|
|
|
@ -7,10 +7,10 @@ import { set, update, updateItem } from './baseActions';
|
|||
|
||||
let currentXHR = null;
|
||||
let xhrCancelled = false;
|
||||
const section = 'addSeries';
|
||||
const section = 'addArtist';
|
||||
|
||||
const addSeriesActionHandlers = {
|
||||
[types.LOOKUP_SERIES]: function(payload) {
|
||||
const addArtistActionHandlers = {
|
||||
[types.LOOKUP_ARTIST]: function(payload) {
|
||||
return function(dispatch, getState) {
|
||||
dispatch(set({ section, isFetching: true }));
|
||||
|
||||
|
@ -55,12 +55,12 @@ const addSeriesActionHandlers = {
|
|||
};
|
||||
},
|
||||
|
||||
[types.ADD_SERIES]: function(payload) {
|
||||
[types.ADD_ARTIST]: function(payload) {
|
||||
return function(dispatch, getState) {
|
||||
dispatch(set({ section, isAdding: true }));
|
||||
|
||||
const foreignArtistId = payload.foreignArtistId;
|
||||
const items = getState().addSeries.items;
|
||||
const items = getState().addArtist.items;
|
||||
const newSeries = getNewSeries(_.cloneDeep(_.find(items, { foreignArtistId })), payload);
|
||||
|
||||
const promise = $.ajax({
|
||||
|
@ -95,4 +95,4 @@ const addSeriesActionHandlers = {
|
|||
}
|
||||
};
|
||||
|
||||
export default addSeriesActionHandlers;
|
||||
export default addArtistActionHandlers;
|
15
frontend/src/Store/Actions/addArtistActions.js
Normal file
15
frontend/src/Store/Actions/addArtistActions.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { createAction } from 'redux-actions';
|
||||
import * as types from './actionTypes';
|
||||
import addArtistActionHandlers from './addArtistActionHandlers';
|
||||
|
||||
export const lookupArtist = addArtistActionHandlers[types.LOOKUP_ARTIST];
|
||||
export const addArtist = addArtistActionHandlers[types.ADD_ARTIST];
|
||||
export const clearAddArtist = createAction(types.CLEAR_ADD_ARTIST);
|
||||
export const setAddArtistDefault = createAction(types.SET_ADD_ARTIST_DEFAULT);
|
||||
|
||||
export const setAddArtistValue = createAction(types.SET_ADD_ARTIST_VALUE, (payload) => {
|
||||
return {
|
||||
section: 'addArtist',
|
||||
...payload
|
||||
};
|
||||
});
|
|
@ -1,15 +0,0 @@
|
|||
import { createAction } from 'redux-actions';
|
||||
import * as types from './actionTypes';
|
||||
import addSeriesActionHandlers from './addSeriesActionHandlers';
|
||||
|
||||
export const lookupSeries = addSeriesActionHandlers[types.LOOKUP_SERIES];
|
||||
export const addSeries = addSeriesActionHandlers[types.ADD_SERIES];
|
||||
export const clearAddSeries = createAction(types.CLEAR_ADD_SERIES);
|
||||
export const setAddSeriesDefault = createAction(types.SET_ADD_SERIES_DEFAULT);
|
||||
|
||||
export const setAddSeriesValue = createAction(types.SET_ADD_SERIES_VALUE, (payload) => {
|
||||
return {
|
||||
section: 'addSeries',
|
||||
...payload
|
||||
};
|
||||
});
|
|
@ -4,14 +4,14 @@ import { batchActions } from 'redux-batched-actions';
|
|||
import getNewSeries from 'Utilities/Series/getNewSeries';
|
||||
import * as types from './actionTypes';
|
||||
import { set, updateItem, removeItem } from './baseActions';
|
||||
import { startLookupSeries } from './importSeriesActions';
|
||||
import { startLookupSeries } from './importArtistActions';
|
||||
import { fetchRootFolders } from './rootFolderActions';
|
||||
|
||||
const section = 'importSeries';
|
||||
const section = 'importArtist';
|
||||
let concurrentLookups = 0;
|
||||
|
||||
const importSeriesActionHandlers = {
|
||||
[types.QUEUE_LOOKUP_SERIES]: function(payload) {
|
||||
const importArtistActionHandlers = {
|
||||
[types.QUEUE_LOOKUP_ARTIST]: function(payload) {
|
||||
return function(dispatch, getState) {
|
||||
const {
|
||||
name,
|
||||
|
@ -19,7 +19,7 @@ const importSeriesActionHandlers = {
|
|||
term
|
||||
} = payload;
|
||||
|
||||
const state = getState().importSeries;
|
||||
const state = getState().importArtist;
|
||||
const item = _.find(state.items, { id: name }) || {
|
||||
id: name,
|
||||
term,
|
||||
|
@ -43,13 +43,13 @@ const importSeriesActionHandlers = {
|
|||
};
|
||||
},
|
||||
|
||||
[types.START_LOOKUP_SERIES]: function(payload) {
|
||||
[types.START_LOOKUP_ARTIST]: function(payload) {
|
||||
return function(dispatch, getState) {
|
||||
if (concurrentLookups >= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const state = getState().importSeries;
|
||||
const state = getState().importArtist;
|
||||
const queued = _.find(state.items, { queued: true });
|
||||
|
||||
if (!queued) {
|
||||
|
@ -65,7 +65,7 @@ const importSeriesActionHandlers = {
|
|||
}));
|
||||
|
||||
const promise = $.ajax({
|
||||
url: '/series/lookup',
|
||||
url: '/artist/lookup',
|
||||
data: {
|
||||
term: queued.term
|
||||
}
|
||||
|
@ -102,12 +102,12 @@ const importSeriesActionHandlers = {
|
|||
};
|
||||
},
|
||||
|
||||
[types.IMPORT_SERIES]: function(payload) {
|
||||
[types.IMPORT_ARTIST]: function(payload) {
|
||||
return function(dispatch, getState) {
|
||||
dispatch(set({ section, isImporting: true }));
|
||||
|
||||
const ids = payload.ids;
|
||||
const items = getState().importSeries.items;
|
||||
const items = getState().importArtist.items;
|
||||
const addedIds = [];
|
||||
|
||||
const allNewSeries = ids.reduce((acc, id) => {
|
||||
|
@ -128,7 +128,7 @@ const importSeriesActionHandlers = {
|
|||
}, []);
|
||||
|
||||
const promise = $.ajax({
|
||||
url: '/series/import',
|
||||
url: '/artist/import',
|
||||
method: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(allNewSeries)
|
||||
|
@ -169,4 +169,4 @@ const importSeriesActionHandlers = {
|
|||
}
|
||||
};
|
||||
|
||||
export default importSeriesActionHandlers;
|
||||
export default importArtistActionHandlers;
|
16
frontend/src/Store/Actions/importArtistActions.js
Normal file
16
frontend/src/Store/Actions/importArtistActions.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { createAction } from 'redux-actions';
|
||||
import * as types from './actionTypes';
|
||||
import importArtistActionHandlers from './importArtistActionHandlers';
|
||||
|
||||
export const queueLookupSeries = importArtistActionHandlers[types.QUEUE_LOOKUP_ARTIST];
|
||||
export const startLookupSeries = importArtistActionHandlers[types.START_LOOKUP_ARTIST];
|
||||
export const importArtist = importArtistActionHandlers[types.IMPORT_ARTIST];
|
||||
export const clearImportArtist = createAction(types.CLEAR_IMPORT_ARTIST);
|
||||
|
||||
export const setImportArtistValue = createAction(types.SET_IMPORT_ARTIST_VALUE, (payload) => {
|
||||
return {
|
||||
|
||||
section: 'importArtist',
|
||||
...payload
|
||||
};
|
||||
});
|
|
@ -1,16 +0,0 @@
|
|||
import { createAction } from 'redux-actions';
|
||||
import * as types from './actionTypes';
|
||||
import importSeriesActionHandlers from './importSeriesActionHandlers';
|
||||
|
||||
export const queueLookupSeries = importSeriesActionHandlers[types.QUEUE_LOOKUP_SERIES];
|
||||
export const startLookupSeries = importSeriesActionHandlers[types.START_LOOKUP_SERIES];
|
||||
export const importSeries = importSeriesActionHandlers[types.IMPORT_SERIES];
|
||||
export const clearImportSeries = createAction(types.CLEAR_IMPORT_SERIES);
|
||||
|
||||
export const setImportSeriesValue = createAction(types.SET_IMPORT_SERIES_VALUE, (payload) => {
|
||||
return {
|
||||
|
||||
section: 'importSeries',
|
||||
...payload
|
||||
};
|
||||
});
|
|
@ -1,6 +1,6 @@
|
|||
import _ from 'lodash';
|
||||
import persistState from 'redux-localstorage';
|
||||
import * as addSeriesReducers from 'Store/Reducers/addSeriesReducers';
|
||||
import * as addArtistReducers from 'Store/Reducers/addArtistReducers';
|
||||
import * as episodeReducers from 'Store/Reducers/episodeReducers';
|
||||
import * as artistIndexReducers from 'Store/Reducers/artistIndexReducers';
|
||||
import * as seriesEditorReducers from 'Store/Reducers/seriesEditorReducers';
|
||||
|
@ -15,7 +15,7 @@ import * as interactiveImportReducers from 'Store/Reducers/interactiveImportRedu
|
|||
import * as queueReducers from 'Store/Reducers/queueReducers';
|
||||
|
||||
const reducers = [
|
||||
addSeriesReducers,
|
||||
addArtistReducers,
|
||||
episodeReducers,
|
||||
artistIndexReducers,
|
||||
seriesEditorReducers,
|
||||
|
|
|
@ -29,21 +29,21 @@ export const defaultState = {
|
|||
};
|
||||
|
||||
export const persistState = [
|
||||
'addSeries.defaults'
|
||||
'addArtist.defaults'
|
||||
];
|
||||
|
||||
const reducerSection = 'addSeries';
|
||||
const reducerSection = 'addArtist';
|
||||
|
||||
const addSeriesReducers = handleActions({
|
||||
const addArtistReducers = handleActions({
|
||||
|
||||
[types.SET]: createSetReducer(reducerSection),
|
||||
[types.UPDATE]: createUpdateReducer(reducerSection),
|
||||
[types.UPDATE_ITEM]: createUpdateItemReducer(reducerSection),
|
||||
[types.REMOVE_ITEM]: createRemoveItemReducer(reducerSection),
|
||||
|
||||
[types.SET_ADD_SERIES_VALUE]: createSetSettingValueReducer(reducerSection),
|
||||
[types.SET_ADD_ARTIST_VALUE]: createSetSettingValueReducer(reducerSection),
|
||||
|
||||
[types.SET_ADD_SERIES_DEFAULT]: function(state, { payload }) {
|
||||
[types.SET_ADD_ARTIST_DEFAULT]: function(state, { payload }) {
|
||||
const newState = getSectionState(state, reducerSection);
|
||||
|
||||
newState.defaults = {
|
||||
|
@ -54,7 +54,7 @@ const addSeriesReducers = handleActions({
|
|||
return updateSectionState(state, reducerSection, newState);
|
||||
},
|
||||
|
||||
[types.CLEAR_ADD_SERIES]: function(state) {
|
||||
[types.CLEAR_ADD_ARTIST]: function(state) {
|
||||
const {
|
||||
defaults,
|
||||
...otherDefaultState
|
||||
|
@ -65,4 +65,4 @@ const addSeriesReducers = handleActions({
|
|||
|
||||
}, defaultState);
|
||||
|
||||
export default addSeriesReducers;
|
||||
export default addArtistReducers;
|
|
@ -15,21 +15,21 @@ export const defaultState = {
|
|||
items: []
|
||||
};
|
||||
|
||||
const reducerSection = 'importSeries';
|
||||
const reducerSection = 'importArtist';
|
||||
|
||||
const importSeriesReducers = handleActions({
|
||||
const importArtistReducers = handleActions({
|
||||
|
||||
[types.SET]: createSetReducer(reducerSection),
|
||||
[types.UPDATE]: createUpdateReducer(reducerSection),
|
||||
[types.UPDATE_ITEM]: createUpdateItemReducer(reducerSection),
|
||||
[types.REMOVE_ITEM]: createRemoveItemReducer(reducerSection),
|
||||
|
||||
[types.CLEAR_IMPORT_SERIES]: function(state) {
|
||||
[types.CLEAR_IMPORT_ARTIST]: function(state) {
|
||||
return Object.assign({}, state, defaultState);
|
||||
},
|
||||
|
||||
[types.SET_IMPORT_SERIES_VALUE]: createUpdateItemReducer(reducerSection)
|
||||
[types.SET_IMPORT_ARTIST_VALUE]: createUpdateItemReducer(reducerSection)
|
||||
|
||||
}, defaultState);
|
||||
|
||||
export default importSeriesReducers;
|
||||
export default importArtistReducers;
|
|
@ -2,8 +2,8 @@ import { combineReducers } from 'redux';
|
|||
import { enableBatching } from 'redux-batched-actions';
|
||||
import { routerReducer } from 'react-router-redux';
|
||||
import app, { defaultState as defaultappState } from './appReducers';
|
||||
import addSeries, { defaultState as defaultAddSeriesState } from './addSeriesReducers';
|
||||
import importSeries, { defaultState as defaultImportSeriesState } from './importSeriesReducers';
|
||||
import addArtist, { defaultState as defaultAddSeriesState } from './addArtistReducers';
|
||||
import importArtist, { defaultState as defaultImportArtistState } from './importArtistReducers';
|
||||
import series, { defaultState as defaultSeriesState } from './seriesReducers';
|
||||
import seriesIndex, { defaultState as defaultSeriesIndexState } from './artistIndexReducers';
|
||||
import seriesEditor, { defaultState as defaultSeriesEditorState } from './seriesEditorReducers';
|
||||
|
@ -30,8 +30,8 @@ import organizePreview, { defaultState as defaultOrganizePreviewState } from './
|
|||
|
||||
export const defaultState = {
|
||||
app: defaultappState,
|
||||
addSeries: defaultAddSeriesState,
|
||||
importSeries: defaultImportSeriesState,
|
||||
addArtist: defaultAddSeriesState,
|
||||
importArtist: defaultImportArtistState,
|
||||
series: defaultSeriesState,
|
||||
seriesIndex: defaultSeriesIndexState,
|
||||
seriesEditor: defaultSeriesEditorState,
|
||||
|
@ -59,8 +59,8 @@ export const defaultState = {
|
|||
|
||||
export default enableBatching(combineReducers({
|
||||
app,
|
||||
addSeries,
|
||||
importSeries,
|
||||
addArtist,
|
||||
importArtist,
|
||||
series,
|
||||
seriesIndex,
|
||||
seriesEditor,
|
||||
|
|
15
frontend/src/Store/Selectors/createExistingArtistSelector.js
Normal file
15
frontend/src/Store/Selectors/createExistingArtistSelector.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
import _ from 'lodash';
|
||||
import { createSelector } from 'reselect';
|
||||
import createAllSeriesSelector from './createAllSeriesSelector';
|
||||
|
||||
function createExistingArtistSelector() {
|
||||
return createSelector(
|
||||
(state, { foreignArtistId }) => foreignArtistId,
|
||||
createAllSeriesSelector(),
|
||||
(foreignArtistId, series) => {
|
||||
return _.some(series, { foreignArtistId });
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default createExistingArtistSelector;
|
|
@ -1,15 +0,0 @@
|
|||
import _ from 'lodash';
|
||||
import { createSelector } from 'reselect';
|
||||
import createAllSeriesSelector from './createAllSeriesSelector';
|
||||
|
||||
function createExistingSeriesSelector() {
|
||||
return createSelector(
|
||||
(state, { tvdbId }) => tvdbId,
|
||||
createAllSeriesSelector(),
|
||||
(tvdbId, series) => {
|
||||
return _.some(series, { tvdbId });
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default createExistingSeriesSelector;
|
|
@ -0,0 +1,28 @@
|
|||
import _ from 'lodash';
|
||||
import { createSelector } from 'reselect';
|
||||
import createAllSeriesSelector from './createAllSeriesSelector';
|
||||
|
||||
function createImportArtistItemSelector() {
|
||||
return createSelector(
|
||||
(state, { id }) => id,
|
||||
(state) => state.addArtist,
|
||||
(state) => state.importArtist,
|
||||
createAllSeriesSelector(),
|
||||
(id, addArtist, importArtist, series) => {
|
||||
const item = _.find(importArtist.items, { id }) || {};
|
||||
const selectedSeries = item && item.selectedSeries;
|
||||
const isExistingArtist = !!selectedSeries && _.some(series, { tvdbId: selectedSeries.tvdbId });
|
||||
|
||||
return {
|
||||
defaultMonitor: addArtist.defaults.monitor,
|
||||
defaultQualityProfileId: addArtist.defaults.qualityProfileId,
|
||||
defaultSeriesType: addArtist.defaults.seriesType,
|
||||
defaultSeasonFolder: addArtist.defaults.seasonFolder,
|
||||
...item,
|
||||
isExistingArtist
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default createImportArtistItemSelector;
|
|
@ -1,28 +0,0 @@
|
|||
import _ from 'lodash';
|
||||
import { createSelector } from 'reselect';
|
||||
import createAllSeriesSelector from './createAllSeriesSelector';
|
||||
|
||||
function createImportSeriesItemSelector() {
|
||||
return createSelector(
|
||||
(state, { id }) => id,
|
||||
(state) => state.addSeries,
|
||||
(state) => state.importSeries,
|
||||
createAllSeriesSelector(),
|
||||
(id, addSeries, importSeries, series) => {
|
||||
const item = _.find(importSeries.items, { id }) || {};
|
||||
const selectedSeries = item && item.selectedSeries;
|
||||
const isExistingSeries = !!selectedSeries && _.some(series, { tvdbId: selectedSeries.tvdbId });
|
||||
|
||||
return {
|
||||
defaultMonitor: addSeries.defaults.monitor,
|
||||
defaultQualityProfileId: addSeries.defaults.qualityProfileId,
|
||||
defaultSeriesType: addSeries.defaults.seriesType,
|
||||
defaultSeasonFolder: addSeries.defaults.seasonFolder,
|
||||
...item,
|
||||
isExistingSeries
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default createImportSeriesItemSelector;
|
Loading…
Add table
Add a link
Reference in a new issue