Skip to content

Commit 10dbbf5

Browse files
authoredMar 7, 2025··
Merge branch 'master' into libraryAccess
2 parents 68f635d + ba8746a commit 10dbbf5

36 files changed

+2623
-687
lines changed
 

‎client/src/api.ts

+38-9
Original file line numberDiff line numberDiff line change
@@ -348,17 +348,19 @@ class API {
348348
}
349349

350350
async getBookPagesDetails(bookID: string) {
351+
const nonce = Math.random().toString(36).substring(7);
351352
const res = await axios.get<
352353
{
353354
toc: TableOfContentsDetailed;
354355
} & ConductorBaseResponse
355-
>(`/commons/book/${bookID}/pages-details`);
356+
>(`/commons/book/${bookID}/pages-details?nonce=${nonce}`);
356357
return res;
357358
}
358359

359360
async getPageDetails(pageID: string, coverPageID: string) {
361+
const nonce = Math.random().toString(36).substring(7);
360362
const res = await axios.get<PageDetailsResponse & ConductorBaseResponse>(
361-
`/commons/pages/${pageID}?coverPageID=${coverPageID}`
363+
`/commons/pages/${pageID}?coverPageID=${coverPageID}?nonce=${nonce}`,
362364
);
363365
return res;
364366
}
@@ -381,22 +383,38 @@ class API {
381383
return res;
382384
}
383385

386+
async generatePageImagesAltText(
387+
pageID: string,
388+
coverPageID: string,
389+
overwrite: boolean
390+
) {
391+
const res = await axios.post<
392+
{
393+
success: boolean;
394+
modified_count: number;
395+
} & ConductorBaseResponse
396+
>(`/commons/pages/${pageID}/ai-alt-text?coverPageID=${coverPageID}`, {
397+
overwrite,
398+
});
399+
return res;
400+
}
401+
384402
/**
385403
* Generates and applies AI-generated summaries, tags, or both, to all pages in a book
386404
* @param {string} bookID - the cover page of the book to apply the summaries to
387405
*/
388406
async batchGenerateAIMetadata(
389407
bookID: string,
390-
summaries: boolean,
391-
tags: boolean,
392-
alttext: boolean
408+
summaries: { generate: boolean; overwrite: boolean },
409+
tags: { generate: boolean; overwrite: boolean },
410+
alttext: { generate: boolean; overwrite: boolean }
393411
) {
394412
const res = await axios.post<ConductorBaseResponse>(
395413
`/commons/book/${bookID}/ai-metadata-batch`,
396414
{
397-
summaries,
398-
tags,
399-
alttext,
415+
...(summaries.generate ? { summaries } : {}),
416+
...(tags.generate ? { tags } : {}),
417+
...(alttext.generate ? { alttext } : {}),
400418
}
401419
);
402420
return res;
@@ -411,7 +429,7 @@ class API {
411429
bookID: string,
412430
pages: { id: string; summary: string; tags: string[] }[]
413431
) {
414-
const res = await axios.post<ConductorBaseResponse>(
432+
const res = await axios.post<{ msg: string } & ConductorBaseResponse>(
415433
`/commons/book/${bookID}/update-metadata-batch`,
416434
{
417435
pages,
@@ -1165,6 +1183,17 @@ class API {
11651183
);
11661184
return res;
11671185
}
1186+
1187+
// user manager
1188+
async deleteUserRole(orgID: string, uuid: string) {
1189+
const res = await axios.delete<ConductorBaseResponse>(`/user/role/delete`, {
1190+
data: {
1191+
orgID,
1192+
uuid,
1193+
},
1194+
});
1195+
return res;
1196+
}
11681197
}
11691198

11701199
export default new API();

‎client/src/components/controlpanel/UsersManager/ManageUserRolesModal.tsx

+28-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import axios from "axios";
2-
import { Button, Dropdown, List, Loader, Modal } from "semantic-ui-react";
2+
import { Button, Dropdown, List, Loader, Modal, Icon } from "semantic-ui-react";
33
import { Organization } from "../../../types";
44
import React, { useEffect, useState } from "react";
55
import useGlobalError from "../../error/ErrorHooks";
66
import { UserRoleOptions } from "../../../utils/userHelpers";
7+
import api from "../../../api";
78

89
type ManageUserRolesModalProps = {
910
firstName: string;
@@ -107,6 +108,18 @@ const ManageUserRolesModal: React.FC<ManageUserRolesModalProps> = ({
107108
}
108109
}
109110

111+
async function deleteUserRole(orgID: string) {
112+
try {
113+
setLoading(true);
114+
const res = await api.deleteUserRole(orgID, uuid);
115+
await getUserRoles();
116+
} catch (err) {
117+
handleGlobalError(err);
118+
} finally {
119+
setLoading(false);
120+
}
121+
}
122+
110123
return (
111124
<Modal size="large" open={show} onClose={onClose} {...props}>
112125
<Modal.Header>
@@ -119,6 +132,10 @@ const ManageUserRolesModal: React.FC<ManageUserRolesModalProps> = ({
119132
{loading && <Loader />}
120133
<List divided verticalAlign="middle">
121134
{allOrganizations.map((org) => {
135+
const currentRole = userRoles.find(
136+
(r) => r.org?.orgID === org.orgID
137+
)?.roleInternal;
138+
const hasRole = !!currentRole;
122139
return (
123140
<List.Item key={org.orgID}>
124141
<div className="flex-row-div">
@@ -146,11 +163,17 @@ const ManageUserRolesModal: React.FC<ManageUserRolesModalProps> = ({
146163
}
147164
placeholder="No role set"
148165
selection
149-
value={
150-
userRoles.find((r) => r.org?.orgID === org.orgID)
151-
?.roleInternal
152-
}
166+
value={currentRole || ""}
153167
/>
168+
<Button
169+
icon
170+
size="mini"
171+
onClick={() => deleteUserRole(org.orgID)}
172+
style={{ marginLeft: "5px" }}
173+
disabled={!hasRole}
174+
>
175+
<Icon name="x" />
176+
</Button>
154177
</div>
155178
</div>
156179
</List.Item>

‎client/src/components/projects/ProjectView.jsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1648,7 +1648,7 @@ const ProjectView = (props) => {
16481648
</Breakpoint>
16491649
</Button>
16501650
}
1651-
{/* {
1651+
{
16521652
project.libreLibrary && project.libreCoverID && (
16531653
<Button
16541654
as={Link}
@@ -1662,7 +1662,7 @@ const ProjectView = (props) => {
16621662
</Breakpoint>
16631663
</Button>
16641664
)
1665-
} */}
1665+
}
16661666
<Button
16671667
color='olive'
16681668
as={Link}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { Button, Icon, Message } from "semantic-ui-react";
2+
import { ProjectBookBatchUpdateJob } from "../../../types";
3+
4+
interface ActiveJobAlertProps {
5+
job: ProjectBookBatchUpdateJob;
6+
onRefresh: () => void;
7+
loading: boolean;
8+
}
9+
10+
const ActiveJobAlert: React.FC<ActiveJobAlertProps> = ({
11+
job,
12+
onRefresh,
13+
loading,
14+
}) => {
15+
return (
16+
<Message icon info>
17+
<Icon name="info circle" />
18+
<Message.Content>
19+
<div className="flex flex-row justify-between">
20+
<div className="flex flex-col">
21+
<Message.Header>Bulk Update Job In Progress</Message.Header>
22+
<p>
23+
{job.dataSource === "generated"
24+
? "AI-generated metadata is "
25+
: "Metadata updates are "}
26+
currently being applied. This may take some time to complete.
27+
Editing is not available while this job is running.
28+
</p>
29+
</div>
30+
<Button onClick={onRefresh} icon color="blue" loading={loading}>
31+
<Icon name="refresh" />
32+
</Button>
33+
</div>
34+
</Message.Content>
35+
</Message>
36+
);
37+
};
38+
39+
export default ActiveJobAlert;

0 commit comments

Comments
 (0)
Please sign in to comment.