mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-10-05 22:05:50 +01:00
Patch: Various feature additions (#625)
- Add admin config for self-settings options visibility. Remove delivery preferences or notifications from the view. - Add option to use Booklore's Bookdrop API destination instead of a specific library - Add download path options for all torrent clients
This commit is contained in:
@@ -9,7 +9,12 @@ import {
|
||||
import { SelectField } from './fields';
|
||||
import { FieldWrapper } from './shared';
|
||||
import { UserAccountCardContent, UserEditActions, UserIdentityHeader } from './users/UserCard';
|
||||
import { UserOverridesSections } from './users/UserOverridesSections';
|
||||
import {
|
||||
DEFAULT_SELF_USER_OVERRIDE_SECTIONS,
|
||||
normalizeUserOverrideSections,
|
||||
UserOverridesSections,
|
||||
type UserOverrideSectionId,
|
||||
} from './users';
|
||||
import { PerUserSettings } from './users/types';
|
||||
import { useUserOverridesState } from './users/useUserOverridesState';
|
||||
import { getStoredThemePreference, setThemePreference, THEME_FIELD } from '../../utils/themePreference';
|
||||
@@ -52,6 +57,9 @@ export const SelfSettingsModal = ({ isOpen, onClose, onShowToast }: SelfSettings
|
||||
const [originalUser, setOriginalUser] = useState<AdminUser | null>(null);
|
||||
const [deliveryPreferences, setDeliveryPreferences] = useState<DeliveryPreferencesResponse | null>(null);
|
||||
const [notificationPreferences, setNotificationPreferences] = useState<DeliveryPreferencesResponse | null>(null);
|
||||
const [visibleSections, setVisibleSections] = useState<UserOverrideSectionId[]>(
|
||||
DEFAULT_SELF_USER_OVERRIDE_SECTIONS
|
||||
);
|
||||
|
||||
const [editPassword, setEditPassword] = useState('');
|
||||
const [editPasswordConfirm, setEditPasswordConfirm] = useState('');
|
||||
@@ -81,6 +89,9 @@ export const SelfSettingsModal = ({ isOpen, onClose, onShowToast }: SelfSettings
|
||||
setOriginalUser(context.user);
|
||||
setDeliveryPreferences(context.deliveryPreferences || null);
|
||||
setNotificationPreferences(context.notificationPreferences || null);
|
||||
setVisibleSections(
|
||||
normalizeUserOverrideSections(context.visibleUserSettingsSections, 'self')
|
||||
);
|
||||
applyUserOverridesContext({
|
||||
settings: (context.user.settings || {}) as PerUserSettings,
|
||||
userOverridableKeys: context.userOverridableKeys || [],
|
||||
@@ -309,6 +320,7 @@ export const SelfSettingsModal = ({ isOpen, onClose, onShowToast }: SelfSettings
|
||||
children: (
|
||||
<UserOverridesSections
|
||||
scope="self"
|
||||
sections={visibleSections}
|
||||
deliveryPreferences={deliveryPreferences}
|
||||
notificationPreferences={notificationPreferences}
|
||||
isUserOverridable={isUserOverridable}
|
||||
|
||||
@@ -41,6 +41,7 @@ const USER_OVERRIDE_SECTION_DEFINITIONS: UserOverrideSectionDefinition[] = [
|
||||
|
||||
const USER_OVERRIDE_SECTION_ORDER: UserOverrideSectionId[] =
|
||||
USER_OVERRIDE_SECTION_DEFINITIONS.map((section) => section.id);
|
||||
const USER_OVERRIDE_SECTION_ID_SET = new Set<UserOverrideSectionId>(USER_OVERRIDE_SECTION_ORDER);
|
||||
|
||||
const USER_OVERRIDE_SECTION_META: Record<UserOverrideSectionId, UserOverrideSectionDefinition> = {
|
||||
delivery: { id: 'delivery', adminOnly: false },
|
||||
@@ -48,6 +49,53 @@ const USER_OVERRIDE_SECTION_META: Record<UserOverrideSectionId, UserOverrideSect
|
||||
requestPolicy: { id: 'requestPolicy', adminOnly: true },
|
||||
};
|
||||
|
||||
export const DEFAULT_SELF_USER_OVERRIDE_SECTIONS: UserOverrideSectionId[] =
|
||||
USER_OVERRIDE_SECTION_ORDER.filter((sectionId) => !USER_OVERRIDE_SECTION_META[sectionId].adminOnly);
|
||||
|
||||
const isUserOverrideSectionId = (value: string): value is UserOverrideSectionId => (
|
||||
USER_OVERRIDE_SECTION_ID_SET.has(value as UserOverrideSectionId)
|
||||
);
|
||||
|
||||
export const normalizeUserOverrideSections = (
|
||||
sections: Iterable<unknown> | null | undefined,
|
||||
scope: UserOverrideScope,
|
||||
): UserOverrideSectionId[] => {
|
||||
const fallbackSections = scope === 'self'
|
||||
? DEFAULT_SELF_USER_OVERRIDE_SECTIONS
|
||||
: USER_OVERRIDE_SECTION_ORDER;
|
||||
|
||||
if (!sections) {
|
||||
return fallbackSections;
|
||||
}
|
||||
|
||||
const requestedValues = Array.from(sections);
|
||||
if (requestedValues.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const requestedIds = new Set<UserOverrideSectionId>();
|
||||
requestedValues.forEach((value) => {
|
||||
const normalizedValue = String(value ?? '').trim();
|
||||
if (isUserOverrideSectionId(normalizedValue)) {
|
||||
requestedIds.add(normalizedValue);
|
||||
}
|
||||
});
|
||||
|
||||
if (requestedIds.size === 0) {
|
||||
return fallbackSections;
|
||||
}
|
||||
|
||||
return USER_OVERRIDE_SECTION_ORDER.filter((sectionId) => {
|
||||
if (!requestedIds.has(sectionId)) {
|
||||
return false;
|
||||
}
|
||||
if (scope === 'self' && USER_OVERRIDE_SECTION_META[sectionId].adminOnly) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
export const UserOverridesSections = ({
|
||||
scope,
|
||||
sections,
|
||||
@@ -60,13 +108,7 @@ export const UserOverridesSections = ({
|
||||
globalUsersSettingsValues,
|
||||
onTestNotificationRoutes,
|
||||
}: UserOverridesSectionsProps) => {
|
||||
const requestedSections = sections ?? USER_OVERRIDE_SECTION_ORDER;
|
||||
const activeSections = requestedSections.filter((sectionId) => {
|
||||
if (scope === 'self' && USER_OVERRIDE_SECTION_META[sectionId].adminOnly) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
const activeSections = normalizeUserOverrideSections(sections, scope);
|
||||
|
||||
const sectionNodes: UserOverrideSectionNode[] = [];
|
||||
|
||||
|
||||
@@ -11,7 +11,11 @@ export { UserListView } from './UserListView';
|
||||
export { RequestPolicyGrid } from './RequestPolicyGrid';
|
||||
export { UserNotificationOverridesSection } from './UserNotificationOverridesSection';
|
||||
export { UserOverridesSection } from './UserOverridesSection';
|
||||
export { UserOverridesSections } from './UserOverridesSections';
|
||||
export {
|
||||
UserOverridesSections,
|
||||
DEFAULT_SELF_USER_OVERRIDE_SECTIONS,
|
||||
normalizeUserOverrideSections,
|
||||
} from './UserOverridesSections';
|
||||
export { UserOverridesView } from './UserOverridesView';
|
||||
export { useUserForm } from './useUserForm';
|
||||
export { useUserMutations } from './useUserMutations';
|
||||
@@ -27,4 +31,5 @@ export {
|
||||
export type {
|
||||
RequestPolicyContentType,
|
||||
} from './requestPolicyGridUtils';
|
||||
export type { UserOverrideSectionId } from './UserOverridesSections';
|
||||
export type { RequestPolicyMode } from '../../../types';
|
||||
|
||||
@@ -600,6 +600,7 @@ export interface SelfUserEditContext {
|
||||
deliveryPreferences: DeliveryPreferencesResponse | null;
|
||||
notificationPreferences: DeliveryPreferencesResponse | null;
|
||||
userOverridableKeys: string[];
|
||||
visibleUserSettingsSections?: string[];
|
||||
}
|
||||
|
||||
export const getAdminUsers = async (): Promise<AdminUser[]> => {
|
||||
|
||||
Reference in New Issue
Block a user