UI for advanced sub permissions
This commit is contained in:
parent
40486f81fd
commit
34e8d0eae3
4 changed files with 175 additions and 11 deletions
28
web/api.py
28
web/api.py
|
|
@ -6,7 +6,7 @@ from flask import Blueprint, jsonify, abort, request
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
from db.constants import TIMELINE_ORDERS_POOL_CREATED, TIMELINE_ORDERS_POOL_DELETED, TIMELINE_ORDERS_POOL_UPDATED
|
from db.constants import TIMELINE_ORDERS_POOL_CREATED, TIMELINE_ORDERS_POOL_DELETED, TIMELINE_ORDERS_POOL_UPDATED
|
||||||
from db.models import database, OrdersPool, Order, OrderAddOn, MastodonServer
|
from db.models import database, OrdersPool, Order, OrderAddOn, MastodonServer
|
||||||
from db.queries import timeline_event_put, timeline_event_recent, user_can_orders_pools_details, user_can_orders_pools_edit, user_can_orders_pools_view, user_get, domsubusers_list, orders_pool_list, orders_pool, mastodon_server_get, mastodon_server_put, user_has_doms, user_mastodon_server_set, user_preferences_set
|
from db.queries import timeline_event_put, timeline_event_recent, user_can_orders_pools_details, user_can_orders_pools_edit, user_can_orders_pools_view, user_doms, user_get, domsubusers_list, orders_pool_list, orders_pool, mastodon_server_get, mastodon_server_put, user_has_doms, user_mastodon_server_set, user_preferences_set
|
||||||
from settings import MASTODON_OAUTH_CLIENT_NAME, MASTODON_OAUTH_REDIRECT_URI, MASTODON_OAUTH_SCOPES, MASTODON_OAUTH_CLIENT_WEBSITE
|
from settings import MASTODON_OAUTH_CLIENT_NAME, MASTODON_OAUTH_REDIRECT_URI, MASTODON_OAUTH_SCOPES, MASTODON_OAUTH_CLIENT_WEBSITE
|
||||||
from util import time_sqlite
|
from util import time_sqlite
|
||||||
|
|
||||||
|
|
@ -164,15 +164,27 @@ def authorized_sub(func):
|
||||||
@authorized_sub
|
@authorized_sub
|
||||||
def sub(username, sub):
|
def sub(username, sub):
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
if user_has_doms(sub) and sub.id == current_user.db_user.id:
|
if (user_has_doms(sub) and sub.id == current_user.db_user.id and
|
||||||
|
('permission_orders_pools_view' in request.json or
|
||||||
|
'permission_orders_pools_details' in request.json or
|
||||||
|
'permission_orders_pools_edit' in request.json)):
|
||||||
abort(403)
|
abort(403)
|
||||||
return
|
return
|
||||||
|
|
||||||
sub.verify_mastodon_favorite = bool(request.json['verify_mastodon_favorite'])
|
if 'verify_mastodon_favorite' in request.json:
|
||||||
sub.verify_mastodon_alt_text = bool(request.json['verify_mastodon_alt_text'])
|
sub.verify_mastodon_favorite = bool(request.json['verify_mastodon_favorite'])
|
||||||
if request.json['verify_delay'] is not None:
|
if 'verify_mastodon_alt_text' in request.json:
|
||||||
|
sub.verify_mastodon_alt_text = bool(request.json['verify_mastodon_alt_text'])
|
||||||
|
if 'verify_delay' in request.json and request.json['verify_delay'] is not None:
|
||||||
sub.verify_delay = int(request.json["verify_delay"])
|
sub.verify_delay = int(request.json["verify_delay"])
|
||||||
|
|
||||||
|
if 'permission_orders_pools_view' in request.json:
|
||||||
|
sub.permission_orders_pools_view = bool(request.json['permission_orders_pools_view'])
|
||||||
|
if 'permission_orders_pools_details' in request.json:
|
||||||
|
sub.permission_orders_pools_details = bool(request.json['permission_orders_pools_details'])
|
||||||
|
if 'permission_orders_pools_edit' in request.json:
|
||||||
|
sub.permission_orders_pools_edit = bool(request.json['permission_orders_pools_edit'])
|
||||||
|
|
||||||
sub.save()
|
sub.save()
|
||||||
|
|
||||||
return ('', 204)
|
return ('', 204)
|
||||||
|
|
@ -183,7 +195,11 @@ def sub(username, sub):
|
||||||
"mastodon_username": sub.mastodon_username,
|
"mastodon_username": sub.mastodon_username,
|
||||||
"verify_mastodon_alt_text": sub.verify_mastodon_alt_text,
|
"verify_mastodon_alt_text": sub.verify_mastodon_alt_text,
|
||||||
"verify_mastodon_favorite": sub.verify_mastodon_favorite,
|
"verify_mastodon_favorite": sub.verify_mastodon_favorite,
|
||||||
"verify_delay": sub.verify_delay
|
"verify_delay": sub.verify_delay,
|
||||||
|
"can_edit_permissions": current_user.db_user in user_doms(sub.id),
|
||||||
|
"permission_orders_pools_view": sub.permission_orders_pools_view,
|
||||||
|
"permission_orders_pools_details": sub.permission_orders_pools_details,
|
||||||
|
"permission_orders_pools_edit": sub.permission_orders_pools_edit
|
||||||
})
|
})
|
||||||
|
|
||||||
@api.route('/orders/')
|
@api.route('/orders/')
|
||||||
|
|
|
||||||
129
web/vite/src/ProfilePermissions.tsx
Normal file
129
web/vite/src/ProfilePermissions.tsx
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
import React from "react";
|
||||||
|
import { Button, Checkbox, Paper, Title } from "@mantine/core";
|
||||||
|
import { useForm } from "@mantine/form";
|
||||||
|
import { notifications } from "@mantine/notifications";
|
||||||
|
import { fetchHeaders } from "./fetch";
|
||||||
|
|
||||||
|
type ProfilePermissionsProps = Pick<
|
||||||
|
UserProfile,
|
||||||
|
| "permission_orders_pools_view"
|
||||||
|
| "permission_orders_pools_details"
|
||||||
|
| "permission_orders_pools_edit"
|
||||||
|
> & { username: string };
|
||||||
|
|
||||||
|
type ProfilePermissionsForm = Pick<
|
||||||
|
UserProfile,
|
||||||
|
| "permission_orders_pools_view"
|
||||||
|
| "permission_orders_pools_details"
|
||||||
|
| "permission_orders_pools_edit"
|
||||||
|
>;
|
||||||
|
|
||||||
|
export const ProfilePermissions: React.FC<ProfilePermissionsProps> = ({
|
||||||
|
username,
|
||||||
|
permission_orders_pools_view,
|
||||||
|
permission_orders_pools_details,
|
||||||
|
permission_orders_pools_edit,
|
||||||
|
}) => {
|
||||||
|
const [loading, setLoading] = React.useState(false);
|
||||||
|
const [detailsDisabled, setDetailsDisabled] = React.useState(
|
||||||
|
!permission_orders_pools_view,
|
||||||
|
);
|
||||||
|
const [editDisabled, setEditDisabled] = React.useState(
|
||||||
|
!permission_orders_pools_details,
|
||||||
|
);
|
||||||
|
const form = useForm<ProfilePermissionsForm>({
|
||||||
|
mode: "uncontrolled",
|
||||||
|
initialValues: {
|
||||||
|
permission_orders_pools_view,
|
||||||
|
permission_orders_pools_details,
|
||||||
|
permission_orders_pools_edit,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
form.watch("permission_orders_pools_view", ({ value }) => {
|
||||||
|
if (!value) {
|
||||||
|
form.setFieldValue("permission_orders_pools_details", false);
|
||||||
|
setDetailsDisabled(true);
|
||||||
|
} else {
|
||||||
|
setDetailsDisabled(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
form.watch("permission_orders_pools_details", ({ value }) => {
|
||||||
|
if (!value) {
|
||||||
|
form.setFieldValue("permission_orders_pools_edit", false);
|
||||||
|
setEditDisabled(true);
|
||||||
|
} else {
|
||||||
|
setEditDisabled(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleSubmit = React.useCallback(
|
||||||
|
form.onSubmit((values) => {
|
||||||
|
setLoading(true);
|
||||||
|
fetch(`/api/subs/${username}`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: fetchHeaders(),
|
||||||
|
body: JSON.stringify(values),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.ok) {
|
||||||
|
notifications.show({
|
||||||
|
title: "Success",
|
||||||
|
message: "Permissions have been saved",
|
||||||
|
color: "green",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
notifications.show({
|
||||||
|
title: "Error",
|
||||||
|
message: "There was a problem saving permissions",
|
||||||
|
color: "red",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Paper>
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<Title order={4} mb="md">
|
||||||
|
Permissions
|
||||||
|
</Title>
|
||||||
|
<Checkbox
|
||||||
|
{...form.getInputProps("permission_orders_pools_view", {
|
||||||
|
type: "checkbox",
|
||||||
|
})}
|
||||||
|
key={form.key("permission_orders_pools_view")}
|
||||||
|
label="Sub can view orders sets"
|
||||||
|
mb="md"
|
||||||
|
/>
|
||||||
|
<Checkbox
|
||||||
|
{...form.getInputProps("permission_orders_pools_details", {
|
||||||
|
type: "checkbox",
|
||||||
|
})}
|
||||||
|
key={form.key("permission_orders_pools_details")}
|
||||||
|
disabled={detailsDisabled}
|
||||||
|
label="Sub can view orders sets details"
|
||||||
|
mb="md"
|
||||||
|
/>
|
||||||
|
<Checkbox
|
||||||
|
{...form.getInputProps("permission_orders_pools_edit", {
|
||||||
|
type: "checkbox",
|
||||||
|
})}
|
||||||
|
key={form.key("permission_orders_pools_edit")}
|
||||||
|
disabled={editDisabled}
|
||||||
|
label="Sub can edit orders sets"
|
||||||
|
mb="md"
|
||||||
|
/>
|
||||||
|
<Button type="submit" loading={loading} mt="md">
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -3,6 +3,7 @@ import { Params, useLoaderData, useParams, Link } from "react-router";
|
||||||
import { OrderSetProps, OrderSets, OrderSetsResponse } from "./OrderSets";
|
import { OrderSetProps, OrderSets, OrderSetsResponse } from "./OrderSets";
|
||||||
import { ProfileVerification } from "./ProfileVerification";
|
import { ProfileVerification } from "./ProfileVerification";
|
||||||
import { Anchor, Title } from "@mantine/core";
|
import { Anchor, Title } from "@mantine/core";
|
||||||
|
import { ProfilePermissions } from "./ProfilePermissions";
|
||||||
|
|
||||||
export const userOrderSetsLoader = async ({
|
export const userOrderSetsLoader = async ({
|
||||||
params: { username },
|
params: { username },
|
||||||
|
|
@ -16,11 +17,11 @@ export const UserOrderSets: React.FC = () => {
|
||||||
|
|
||||||
const [profile, setProfile] = React.useState<UserProfile | null>(null);
|
const [profile, setProfile] = React.useState<UserProfile | null>(null);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
// fetch(`/api/subs/${sub_username}`).then(async (response) => {
|
fetch(`/api/subs/${sub_username}`).then(async (response) => {
|
||||||
// if (response.ok) {
|
if (response.ok) {
|
||||||
// setProfile(await response.json());
|
setProfile(await response.json());
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
}, [sub_username]);
|
}, [sub_username]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -46,6 +47,20 @@ export const UserOrderSets: React.FC = () => {
|
||||||
verify_mastodon_favorite={profile.verify_mastodon_favorite}
|
verify_mastodon_favorite={profile.verify_mastodon_favorite}
|
||||||
verify_delay={profile.verify_delay}
|
verify_delay={profile.verify_delay}
|
||||||
/>
|
/>
|
||||||
|
{profile.can_edit_permissions ? (
|
||||||
|
<ProfilePermissions
|
||||||
|
username={sub_username}
|
||||||
|
permission_orders_pools_view={
|
||||||
|
profile.permission_orders_pools_view
|
||||||
|
}
|
||||||
|
permission_orders_pools_details={
|
||||||
|
profile.permission_orders_pools_details
|
||||||
|
}
|
||||||
|
permission_orders_pools_edit={
|
||||||
|
profile.permission_orders_pools_edit
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
</>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
4
web/vite/src/index.d.ts
vendored
4
web/vite/src/index.d.ts
vendored
|
|
@ -9,6 +9,10 @@ type UserProfile = {
|
||||||
verify_mastodon_alt_text?: boolean;
|
verify_mastodon_alt_text?: boolean;
|
||||||
verify_mastodon_favorite?: boolean;
|
verify_mastodon_favorite?: boolean;
|
||||||
verify_delay?: number;
|
verify_delay?: number;
|
||||||
|
can_edit_permissions?: boolean;
|
||||||
|
permission_orders_pools_view?: boolean;
|
||||||
|
permission_orders_pools_details?: boolean;
|
||||||
|
permission_orders_pools_edit?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrderSetOrderAddOn = {
|
type OrderSetOrderAddOn = {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue