diff --git a/frontend/js/actions/admins.js b/frontend/js/actions/admins.js
index 050ca88..c9c713a 100644
--- a/frontend/js/actions/admins.js
+++ b/frontend/js/actions/admins.js
@@ -14,6 +14,13 @@ export function getStats() {
)
}
+export function getAdminModules() {
+ return request(
+ "ADMIN_GET_MODULES",
+ configureAxios().get("/admins/modules")
+ )
+}
+
export function updateUser(data) {
return request(
"ADMIN_UPDATE_USER",
diff --git a/frontend/js/actions/users.js b/frontend/js/actions/users.js
index d8d6844..b55b986 100644
--- a/frontend/js/actions/users.js
+++ b/frontend/js/actions/users.js
@@ -67,3 +67,10 @@ export function deleteUserToken(token) {
]
)
}
+
+export function getUserModules() {
+ return request(
+ "GET_USER_MODULES",
+ configureAxios().get("/users/modules/status")
+ )
+}
diff --git a/frontend/js/components/admins/panel.js b/frontend/js/components/admins/panel.js
index 5f5e5f0..74e2ce5 100644
--- a/frontend/js/components/admins/panel.js
+++ b/frontend/js/components/admins/panel.js
@@ -3,6 +3,7 @@ import { connect } from "react-redux"
import { bindActionCreators } from "redux"
import { updateUser } from "../../actions/admins"
+import Modules from "../modules/modules"
import UserList from "./users"
import Stats from "./stats"
@@ -10,6 +11,7 @@ function mapStateToProps(state) {
return {
users : state.adminStore.get("users"),
stats : state.adminStore.get("stats"),
+ modules : state.adminStore.get("modules"),
};
}
const mapDispatchToProps = (dipatch) =>
@@ -25,6 +27,9 @@ function AdminPanel(props) {
users={props.users}
updateUser={props.updateUser}
/>
+
);
}
diff --git a/frontend/js/components/modules/modules.js b/frontend/js/components/modules/modules.js
new file mode 100644
index 0000000..59a162e
--- /dev/null
+++ b/frontend/js/components/modules/modules.js
@@ -0,0 +1,115 @@
+import React from "react"
+
+import { OverlayTrigger, Tooltip } from "react-bootstrap"
+
+export default function Modules(props) {
+ return (
+
+
Modules
+ {props.modules && props.modules.keySeq().map(function(value, key) {
+ return (
+
+ );
+ })}
+
+ );
+}
+
+function capitalize(string) {
+ return string.charAt(0).toUpperCase() + string.slice(1);
+}
+
+function ModulesByVideoType(props) {
+ return (
+
+
+
+
+ {capitalize(props.videoType)} {/* Movie or Show */}
+
+
+
+ {props.data.keySeq().map(function(value, key) {
+ return (
+
+ );
+ })}
+
+
+
+ );
+}
+
+function ModuleByType(props) {
+ return (
+
+
{props.type} {/* Detailer / Explorer / ... */}
+
+
+ {props.data.map(function(value, key) {
+ return (
+
+ );
+ })}
+
+
+
+ );
+}
+
+function Module(props) {
+ var iconClass, prettyStatus, labelClass
+
+ switch(props.data.get("status")) {
+ case "ok":
+ iconClass = "fa fa-check-circle"
+ labelClass = "label label-success"
+ prettyStatus = "OK"
+ break;
+ case "fail":
+ iconClass = "fa fa-times-circle"
+ labelClass = "label label-danger"
+ prettyStatus = "Fail"
+ break;
+ case "not_implemented":
+ iconClass = "fa fa-question-circle"
+ labelClass = "label label-default"
+ prettyStatus = "Not implemented"
+ break;
+ default:
+ iconClass = "fa fa-question-circle"
+ labelClass = "label label-warning"
+ prettyStatus = "Unknown"
+ }
+
+ const tooltip = (
+
+ Status: {prettyStatus}
+ Error: {props.data.get("error")}
+
+ );
+ return (
+
+ {props.data.get("name")} |
+
+
+
+ {prettyStatus}
+
+
+ |
+
+ );
+}
diff --git a/frontend/js/components/navbar.js b/frontend/js/components/navbar.js
index 008a82b..7c279b4 100644
--- a/frontend/js/components/navbar.js
+++ b/frontend/js/components/navbar.js
@@ -161,7 +161,7 @@ function UserDropdown(props) {
}
{props.isActivated &&
-
+
}
{props.isActivated &&
diff --git a/frontend/js/components/users/edit.js b/frontend/js/components/users/edit.js
index 758d231..6c53e9e 100644
--- a/frontend/js/components/users/edit.js
+++ b/frontend/js/components/users/edit.js
@@ -3,16 +3,32 @@ import { connect } from "react-redux"
import { bindActionCreators } from "redux"
import { updateUser } from "../../actions/users"
+import Modules from "../modules/modules"
function mapStateToProps(state) {
return {
polochonToken: state.userStore.get("polochonToken"),
polochonUrl: state.userStore.get("polochonUrl"),
+ modules : state.userStore.get("modules"),
};
}
+
const mapDispatchToProps = (dispatch) =>
bindActionCreators({ updateUser }, dispatch)
+function UserProfile(props) {
+ return (
+
+
+
+
+ )
+}
+
class UserEdit extends React.PureComponent {
constructor(props) {
super(props);
@@ -100,4 +116,4 @@ class UserEdit extends React.PureComponent {
);
}
}
-export default connect(mapStateToProps, mapDispatchToProps)(UserEdit);
+export default connect(mapStateToProps, mapDispatchToProps)(UserProfile);
diff --git a/frontend/js/reducers/admins.js b/frontend/js/reducers/admins.js
index a309c46..cea31ea 100644
--- a/frontend/js/reducers/admins.js
+++ b/frontend/js/reducers/admins.js
@@ -3,11 +3,13 @@ import { Map, List, fromJS } from "immutable"
const defaultState = Map({
"users": List(),
"stats": Map({}),
+ "modules": Map({}),
});
const handlers = {
"ADMIN_LIST_USERS_FULFILLED": (state, action) => state.set("users", fromJS(action.payload.response.data)),
"ADMIN_GET_STATS_FULFILLED": (state, action) => state.set("stats", fromJS(action.payload.response.data)),
+ "ADMIN_GET_MODULES_FULFILLED": (state, action) => state.set("modules", fromJS(action.payload.response.data)),
}
export default (state = defaultState, action) =>
diff --git a/frontend/js/reducers/users.js b/frontend/js/reducers/users.js
index 9195f13..20da605 100644
--- a/frontend/js/reducers/users.js
+++ b/frontend/js/reducers/users.js
@@ -32,6 +32,9 @@ const handlers = {
"GET_USER_TOKENS_FULFILLED": (state, action) => state.set(
"tokens", fromJS(action.payload.response.data)
),
+ "GET_USER_MODULES_FULFILLED": (state, action) => state.set(
+ "modules", fromJS(action.payload.response.data)
+ ),
}
function logoutUser() {
diff --git a/frontend/js/routes.js b/frontend/js/routes.js
index 86596db..0dfc909 100644
--- a/frontend/js/routes.js
+++ b/frontend/js/routes.js
@@ -2,7 +2,7 @@ import MovieList from "./components/movies/list"
import ShowList from "./components/shows/list"
import ShowDetails from "./components/shows/details"
import UserLoginForm from "./components/users/login"
-import UserEdit from "./components/users/edit"
+import UserProfile from "./components/users/edit"
import UserTokens from "./components/users/tokens"
import UserActivation from "./components/users/activation"
import UserSignUp from "./components/users/signup"
@@ -11,10 +11,10 @@ import TorrentSearch from "./components/torrents/search"
import AdminPanel from "./components/admins/panel"
import { fetchTorrents, searchTorrents } from "./actions/torrents"
-import { userLogout, getUserInfos, getUserTokens } from "./actions/users"
+import { userLogout, getUserInfos, getUserTokens, getUserModules } from "./actions/users"
import { fetchMovies, getMovieExploreOptions } from "./actions/movies"
import { fetchShows, fetchShowDetails, getShowExploreOptions } from "./actions/shows"
-import { getUsers, getStats } from "./actions/admins"
+import { getUsers, getStats, getAdminModules } from "./actions/admins"
import store from "./store"
@@ -112,10 +112,11 @@ export default function getRoutes(App) {
},
{
path: "/users/edit",
- component: UserEdit,
+ component: UserProfile,
onEnter: function(nextState, replace, next) {
loginCheck(nextState, replace, next, function() {
store.dispatch(getUserInfos());
+ store.dispatch(getUserModules());
});
},
},
@@ -282,6 +283,7 @@ export default function getRoutes(App) {
adminCheck(nextState, replace, next, function() {
store.dispatch(getUsers());
store.dispatch(getStats());
+ store.dispatch(getAdminModules());
});
},
},