federation block routing
This commit is contained in:
parent
9fbe8f5cfd
commit
80c05825ab
|
@ -21,62 +21,108 @@
|
||||||
const Promise = require("bluebird");
|
const Promise = require("bluebird");
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const Redux = require("react-redux");
|
const Redux = require("react-redux");
|
||||||
|
const {Switch, Route, Link, useRoute} = require("wouter");
|
||||||
|
|
||||||
const Submit = require("../components/submit");
|
const Submit = require("../components/submit");
|
||||||
|
|
||||||
const api = require("../lib/api");
|
const api = require("../lib/api");
|
||||||
const adminActions = require("../redux/reducers/instances").actions;
|
const adminActions = require("../redux/reducers/instances").actions;
|
||||||
|
|
||||||
const {
|
const base = "/settings/admin/federation";
|
||||||
TextInput,
|
|
||||||
TextArea,
|
// const {
|
||||||
File
|
// TextInput,
|
||||||
} = require("../components/form-fields").formFields(adminActions.setAdminSettingsVal, (state) => state.instances.adminSettings);
|
// TextArea,
|
||||||
|
// File
|
||||||
|
// } = require("../components/form-fields").formFields(adminActions.setAdminSettingsVal, (state) => state.instances.adminSettings);
|
||||||
|
|
||||||
module.exports = function AdminSettings() {
|
module.exports = function AdminSettings() {
|
||||||
const dispatch = Redux.useDispatch();
|
const dispatch = Redux.useDispatch();
|
||||||
const instance = Redux.useSelector(state => state.instances.adminSettings);
|
// const instance = Redux.useSelector(state => state.instances.adminSettings);
|
||||||
|
const { blockedInstances } = Redux.useSelector(state => state.admin);
|
||||||
const [loaded, setLoaded] = React.useState(false);
|
|
||||||
|
|
||||||
const [errorMsg, setError] = React.useState("");
|
const [errorMsg, setError] = React.useState("");
|
||||||
const [statusMsg, setStatus] = React.useState("");
|
const [statusMsg, setStatus] = React.useState("");
|
||||||
|
|
||||||
React.useEffect(() => {
|
const [loaded, setLoaded] = React.useState(false);
|
||||||
Promise.try(() => {
|
|
||||||
return dispatch(api.admin.fetchDomainBlocks());
|
|
||||||
}).then(() => {
|
|
||||||
setLoaded(true);
|
|
||||||
}).catch((e) => {
|
|
||||||
console.log(e);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
function submit() {
|
React.useEffect(() => {
|
||||||
setStatus("PATCHing");
|
if (blockedInstances != undefined) {
|
||||||
setError("");
|
setLoaded(true);
|
||||||
return Promise.try(() => {
|
} else {
|
||||||
return dispatch(api.admin.updateInstance());
|
return Promise.try(() => {
|
||||||
}).then(() => {
|
return dispatch(api.admin.fetchDomainBlocks());
|
||||||
setStatus("Saved!");
|
}).then(() => {
|
||||||
}).catch((e) => {
|
setLoaded(true);
|
||||||
setError(e.message);
|
});
|
||||||
setStatus("");
|
}
|
||||||
});
|
}, []);
|
||||||
}
|
|
||||||
|
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h1>Federation</h1>
|
<h1>Federation</h1>
|
||||||
Loading instance blocks...
|
Loading...
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h1>Federation</h1>
|
<Switch>
|
||||||
|
<Route path={`${base}/:domain`}>
|
||||||
|
<InstancePage blockedInstances={blockedInstances}/>
|
||||||
|
</Route>
|
||||||
|
<InstanceOverview blockedInstances={blockedInstances} />
|
||||||
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function InstanceOverview({blockedInstances}) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Federation</h1>
|
||||||
|
{blockedInstances.map((entry) => {
|
||||||
|
return (
|
||||||
|
<Link key={entry.domain} to={`${base}/${entry.domain}`}>
|
||||||
|
<a>{entry.domain}</a>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function BackButton() {
|
||||||
|
return (
|
||||||
|
<Link to={base}>
|
||||||
|
<a className="button">< back</a>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function InstancePage({blockedInstances}) {
|
||||||
|
let [_match, {domain}] = useRoute(`${base}/:domain`);
|
||||||
|
let [status, setStatus] = React.useState("");
|
||||||
|
let [entry, setEntry] = React.useState(() => {
|
||||||
|
let entry = blockedInstances.find((a) => a.domain == domain);
|
||||||
|
|
||||||
|
if (entry == undefined) {
|
||||||
|
setStatus(`No block entry found for ${domain}, but you can create one below:`);
|
||||||
|
return {
|
||||||
|
private_comment: ""
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{status}
|
||||||
|
<h1><BackButton/> Federation settings for: {domain}</h1>
|
||||||
|
<div>{entry.private_comment}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ const React = require("react");
|
||||||
const { Link, useRoute } = require("wouter");
|
const { Link, useRoute } = require("wouter");
|
||||||
|
|
||||||
module.exports = function NavButton({href, name}) {
|
module.exports = function NavButton({href, name}) {
|
||||||
const [isActive] = useRoute(href);
|
const [isActive] = useRoute(`${href}/:anything?`);
|
||||||
return (
|
return (
|
||||||
<Link href={href}>
|
<Link href={href}>
|
||||||
<a className={isActive ? "active" : ""} data-content={name}>
|
<a className={isActive ? "active" : ""} data-content={name}>
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
const Promise = require("bluebird");
|
const Promise = require("bluebird");
|
||||||
|
|
||||||
const instance = require("../../redux/reducers/instances").actions;
|
const instance = require("../../redux/reducers/instances").actions;
|
||||||
|
const admin = require("../../redux/reducers/admin").actions;
|
||||||
|
|
||||||
module.exports = function ({ apiCall, getChanges }) {
|
module.exports = function ({ apiCall, getChanges }) {
|
||||||
return {
|
return {
|
||||||
|
@ -45,6 +46,8 @@ module.exports = function ({ apiCall, getChanges }) {
|
||||||
return function (dispatch, _getState) {
|
return function (dispatch, _getState) {
|
||||||
return Promise.try(() => {
|
return Promise.try(() => {
|
||||||
return dispatch(apiCall("GET", "/api/v1/admin/domain_blocks"));
|
return dispatch(apiCall("GET", "/api/v1/admin/domain_blocks"));
|
||||||
|
}).then((data) => {
|
||||||
|
return dispatch(admin.setBlockedInstances(data));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ const { OAUTHError, AuthenticationError } = require("../errors");
|
||||||
|
|
||||||
const oauth = require("../../redux/reducers/oauth").actions;
|
const oauth = require("../../redux/reducers/oauth").actions;
|
||||||
const temporary = require("../../redux/reducers/temporary").actions;
|
const temporary = require("../../redux/reducers/temporary").actions;
|
||||||
const user = require("../../redux/reducers/user").actions;
|
const admin = require("../../redux/reducers/admin").actions;
|
||||||
|
|
||||||
module.exports = function oauthAPI({ apiCall, getCurrentUrl }) {
|
module.exports = function oauthAPI({ apiCall, getCurrentUrl }) {
|
||||||
return {
|
return {
|
||||||
|
@ -103,8 +103,11 @@ module.exports = function oauthAPI({ apiCall, getCurrentUrl }) {
|
||||||
// no role info, try fetching an admin-only route and see if we get an error
|
// no role info, try fetching an admin-only route and see if we get an error
|
||||||
return Promise.try(() => {
|
return Promise.try(() => {
|
||||||
return dispatch(apiCall("GET", "/api/v1/admin/domain_blocks"));
|
return dispatch(apiCall("GET", "/api/v1/admin/domain_blocks"));
|
||||||
}).then(() => {
|
}).then((data) => {
|
||||||
return dispatch(oauth.setAdmin(true));
|
return Promise.all([
|
||||||
|
dispatch(oauth.setAdmin(true)),
|
||||||
|
dispatch(admin.setBlockedInstances(data))
|
||||||
|
]);
|
||||||
}).catch(AuthenticationError, () => {
|
}).catch(AuthenticationError, () => {
|
||||||
return dispatch(oauth.setAdmin(false));
|
return dispatch(oauth.setAdmin(false));
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
|
|
|
@ -64,11 +64,11 @@ module.exports = function getViews(struct) {
|
||||||
let url = `${base}/${urlSafe(name)}`;
|
let url = `${base}/${urlSafe(name)}`;
|
||||||
|
|
||||||
if (firstRoute == undefined) {
|
if (firstRoute == undefined) {
|
||||||
firstRoute = `${base}/${urlSafe(name)}`;
|
firstRoute = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
routes.push((
|
panelRouterEl.push((
|
||||||
<Route path={url} key={url}>
|
<Route path={`${url}/:page?`} key={url}>
|
||||||
<ErrorBoundary FallbackComponent={ErrorFallback} onReset={() => { }}>
|
<ErrorBoundary FallbackComponent={ErrorFallback} onReset={() => { }}>
|
||||||
{/* FIXME: implement onReset */}
|
{/* FIXME: implement onReset */}
|
||||||
<ViewComponent />
|
<ViewComponent />
|
||||||
|
@ -87,14 +87,15 @@ module.exports = function getViews(struct) {
|
||||||
</Route>
|
</Route>
|
||||||
);
|
);
|
||||||
|
|
||||||
let childrenPath = `${base}/:section`;
|
// let childrenPath = `${base}/:section`;
|
||||||
panelRouterEl.push(
|
// panelRouterEl.push(...routes);
|
||||||
<Route key={childrenPath} path={childrenPath}>
|
console.log(panelRouterEl);
|
||||||
<Switch>
|
// <Route key={childrenPath} path={childrenPath}>
|
||||||
{routes}
|
// <Switch id="childrenPath-switch">
|
||||||
</Switch>
|
// {routes}
|
||||||
</Route>
|
// </Switch>
|
||||||
);
|
// </Route>
|
||||||
|
// );
|
||||||
|
|
||||||
sidebarEl.push(
|
sidebarEl.push(
|
||||||
<React.Fragment key={name}>
|
<React.Fragment key={name}>
|
||||||
|
|
|
@ -36,6 +36,7 @@ const combinedReducers = combineReducers({
|
||||||
instances: require("./reducers/instances").reducer,
|
instances: require("./reducers/instances").reducer,
|
||||||
temporary: require("./reducers/temporary").reducer,
|
temporary: require("./reducers/temporary").reducer,
|
||||||
user: require("./reducers/user").reducer,
|
user: require("./reducers/user").reducer,
|
||||||
|
admin: require("./reducers/admin").reducer,
|
||||||
});
|
});
|
||||||
|
|
||||||
const persistedReducer = persistReducer(persistConfig, combinedReducers);
|
const persistedReducer = persistReducer(persistConfig, combinedReducers);
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
GoToSocial
|
||||||
|
Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const {createSlice} = require("@reduxjs/toolkit");
|
||||||
|
// const d = require("dotty");
|
||||||
|
|
||||||
|
function sortBlocks(blocks) {
|
||||||
|
return blocks.sort((a, b) => { // alphabetical sort
|
||||||
|
return a.domain.localeCompare(b.domain);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// function deduplicateBlocks(blocks) {
|
||||||
|
// let a = new Map();
|
||||||
|
// blocks.forEach((block) => {
|
||||||
|
// a.set(block.id, block);
|
||||||
|
// });
|
||||||
|
// return Array.from(a.values());
|
||||||
|
// }
|
||||||
|
|
||||||
|
module.exports = createSlice({
|
||||||
|
name: "admin",
|
||||||
|
initialState: {
|
||||||
|
blockedInstances: undefined,
|
||||||
|
blockedInstancesMap: {}
|
||||||
|
},
|
||||||
|
reducers: {
|
||||||
|
setBlockedInstances: (state, {payload}) => {
|
||||||
|
state.blockedInstances = sortBlocks(payload);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
Loading…
Reference in New Issue