federation block routing
This commit is contained in:
parent
9fbe8f5cfd
commit
80c05825ab
|
@ -21,62 +21,108 @@
|
|||
const Promise = require("bluebird");
|
||||
const React = require("react");
|
||||
const Redux = require("react-redux");
|
||||
const {Switch, Route, Link, useRoute} = require("wouter");
|
||||
|
||||
const Submit = require("../components/submit");
|
||||
|
||||
const api = require("../lib/api");
|
||||
const adminActions = require("../redux/reducers/instances").actions;
|
||||
|
||||
const {
|
||||
TextInput,
|
||||
TextArea,
|
||||
File
|
||||
} = require("../components/form-fields").formFields(adminActions.setAdminSettingsVal, (state) => state.instances.adminSettings);
|
||||
const base = "/settings/admin/federation";
|
||||
|
||||
// const {
|
||||
// TextInput,
|
||||
// TextArea,
|
||||
// File
|
||||
// } = require("../components/form-fields").formFields(adminActions.setAdminSettingsVal, (state) => state.instances.adminSettings);
|
||||
|
||||
module.exports = function AdminSettings() {
|
||||
const dispatch = Redux.useDispatch();
|
||||
const instance = Redux.useSelector(state => state.instances.adminSettings);
|
||||
|
||||
const [loaded, setLoaded] = React.useState(false);
|
||||
// const instance = Redux.useSelector(state => state.instances.adminSettings);
|
||||
const { blockedInstances } = Redux.useSelector(state => state.admin);
|
||||
|
||||
const [errorMsg, setError] = React.useState("");
|
||||
const [statusMsg, setStatus] = React.useState("");
|
||||
|
||||
React.useEffect(() => {
|
||||
Promise.try(() => {
|
||||
return dispatch(api.admin.fetchDomainBlocks());
|
||||
}).then(() => {
|
||||
setLoaded(true);
|
||||
}).catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
}, []);
|
||||
const [loaded, setLoaded] = React.useState(false);
|
||||
|
||||
function submit() {
|
||||
setStatus("PATCHing");
|
||||
setError("");
|
||||
return Promise.try(() => {
|
||||
return dispatch(api.admin.updateInstance());
|
||||
}).then(() => {
|
||||
setStatus("Saved!");
|
||||
}).catch((e) => {
|
||||
setError(e.message);
|
||||
setStatus("");
|
||||
});
|
||||
}
|
||||
React.useEffect(() => {
|
||||
if (blockedInstances != undefined) {
|
||||
setLoaded(true);
|
||||
} else {
|
||||
return Promise.try(() => {
|
||||
return dispatch(api.admin.fetchDomainBlocks());
|
||||
}).then(() => {
|
||||
setLoaded(true);
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
if (!loaded) {
|
||||
return (
|
||||
<div>
|
||||
<h1>Federation</h1>
|
||||
Loading instance blocks...
|
||||
Loading...
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>Federation</h1>
|
||||
<Switch>
|
||||
<Route path={`${base}/:domain`}>
|
||||
<InstancePage blockedInstances={blockedInstances}/>
|
||||
</Route>
|
||||
<InstanceOverview blockedInstances={blockedInstances} />
|
||||
</Switch>
|
||||
</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");
|
||||
|
||||
module.exports = function NavButton({href, name}) {
|
||||
const [isActive] = useRoute(href);
|
||||
const [isActive] = useRoute(`${href}/:anything?`);
|
||||
return (
|
||||
<Link href={href}>
|
||||
<a className={isActive ? "active" : ""} data-content={name}>
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
const Promise = require("bluebird");
|
||||
|
||||
const instance = require("../../redux/reducers/instances").actions;
|
||||
const admin = require("../../redux/reducers/admin").actions;
|
||||
|
||||
module.exports = function ({ apiCall, getChanges }) {
|
||||
return {
|
||||
|
@ -45,6 +46,8 @@ module.exports = function ({ apiCall, getChanges }) {
|
|||
return function (dispatch, _getState) {
|
||||
return Promise.try(() => {
|
||||
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 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 }) {
|
||||
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
|
||||
return Promise.try(() => {
|
||||
return dispatch(apiCall("GET", "/api/v1/admin/domain_blocks"));
|
||||
}).then(() => {
|
||||
return dispatch(oauth.setAdmin(true));
|
||||
}).then((data) => {
|
||||
return Promise.all([
|
||||
dispatch(oauth.setAdmin(true)),
|
||||
dispatch(admin.setBlockedInstances(data))
|
||||
]);
|
||||
}).catch(AuthenticationError, () => {
|
||||
return dispatch(oauth.setAdmin(false));
|
||||
}).catch((e) => {
|
||||
|
|
|
@ -64,11 +64,11 @@ module.exports = function getViews(struct) {
|
|||
let url = `${base}/${urlSafe(name)}`;
|
||||
|
||||
if (firstRoute == undefined) {
|
||||
firstRoute = `${base}/${urlSafe(name)}`;
|
||||
firstRoute = url;
|
||||
}
|
||||
|
||||
routes.push((
|
||||
<Route path={url} key={url}>
|
||||
panelRouterEl.push((
|
||||
<Route path={`${url}/:page?`} key={url}>
|
||||
<ErrorBoundary FallbackComponent={ErrorFallback} onReset={() => { }}>
|
||||
{/* FIXME: implement onReset */}
|
||||
<ViewComponent />
|
||||
|
@ -87,14 +87,15 @@ module.exports = function getViews(struct) {
|
|||
</Route>
|
||||
);
|
||||
|
||||
let childrenPath = `${base}/:section`;
|
||||
panelRouterEl.push(
|
||||
<Route key={childrenPath} path={childrenPath}>
|
||||
<Switch>
|
||||
{routes}
|
||||
</Switch>
|
||||
</Route>
|
||||
);
|
||||
// let childrenPath = `${base}/:section`;
|
||||
// panelRouterEl.push(...routes);
|
||||
console.log(panelRouterEl);
|
||||
// <Route key={childrenPath} path={childrenPath}>
|
||||
// <Switch id="childrenPath-switch">
|
||||
// {routes}
|
||||
// </Switch>
|
||||
// </Route>
|
||||
// );
|
||||
|
||||
sidebarEl.push(
|
||||
<React.Fragment key={name}>
|
||||
|
|
|
@ -36,6 +36,7 @@ const combinedReducers = combineReducers({
|
|||
instances: require("./reducers/instances").reducer,
|
||||
temporary: require("./reducers/temporary").reducer,
|
||||
user: require("./reducers/user").reducer,
|
||||
admin: require("./reducers/admin").reducer,
|
||||
});
|
||||
|
||||
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