Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions client/src/Conductor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import OrganizationsManager from './components/controlpanel/OrganizationsManager
import PeerReviewPage from './components/peerreview/PeerReviewPage';
import PeerReviewRubricManage from './components/controlpanel/PeerReviewRubricManage';
import PeerReviewRubrics from './components/controlpanel/PeerReviewRubrics';
const PeopleManager = lazy(() => import('./screens/conductor/controlpanel/PeopleManager'));
const AuthorsManager = lazy(() => import('./screens/conductor/controlpanel/AuthorsManager'));
import ProjectAccessibility from './components/projects/ProjectAccessibility';
import ProjectPeerReview from './components/projects/ProjectPeerReview';
const MyProjects = lazy(() => import('./screens/conductor/Projects'));
Expand Down Expand Up @@ -143,7 +143,7 @@ const Conductor = () => {
<PrivateRoute exact path='/controlpanel/adoptionreports' component={AdoptionReports} />
<PrivateRoute exact path='/controlpanel/analyticsrequests' component={AnalyticsRequests} />
<PrivateRoute exact path='/controlpanel/assettagsmanager' component={AssetTagsManager} />
<PrivateRoute exact path='/controlpanel/peoplemanager' component={PeopleManager} />
<PrivateRoute exact path='/controlpanel/authorsmanager' component={AuthorsManager} />
<PrivateRoute exact path='/controlpanel/booksmanager' component={BooksManager} />
<PrivateRoute exact path='/controlpanel/booksmanager/mastercatalog' component={MasterCatalogPlainView} />
<PrivateRoute exact path='/controlpanel/indexmanager' component={IndexManager} />
Expand Down
52 changes: 18 additions & 34 deletions client/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ import {
CentralIdentityAppLicense,
StoreDigitalDeliveryOption,
StoreOrder,
GetStoreOrdersResponse,
StoreOrderWithStripeSession,
OrderCharge,
OrderSession,
Expand All @@ -79,7 +78,7 @@ import {
CustomFilter,
MiniRepoSearchParams,
} from "./types/Search";
import { CloudflareCaptionData, SortDirection } from "./types/Misc";
import { CloudflareCaptionData, ConductorInfiniteScrollResponse, SortDirection } from "./types/Misc";
import {
TrafficAnalyticsAggregatedMetricsByPageDataPoint,
TrafficAnalyticsBaseRequestParams,
Expand Down Expand Up @@ -284,11 +283,10 @@ class API {
return res;
}

public cloudflareStreamUploadURL: string = `${
import.meta.env.MODE === "development"
public cloudflareStreamUploadURL: string = `${import.meta.env.MODE === "development"
? import.meta.env.VITE_DEV_BASE_URL
: ""
}/api/v1/cloudflare/stream-url`;
}/api/v1/cloudflare/stream-url`;

async getPermanentLink(projectID: string, fileID: string) {
const res = await axios.get<
Expand All @@ -303,25 +301,20 @@ class API {
async getAuthors({
page,
limit,
sort,
query,
sort,
}: {
page?: number;
limit?: number;
sort?: string;
query?: string;
sort?: string;
}) {
const res = await axios.get<
{
authors: Author[];
totalCount: number;
} & ConductorBaseResponse
>("/authors", {
const res = await axios.get<ConductorInfiniteScrollResponse<Author>>("/authors", {
params: {
page,
limit,
sort,
query,
sort,
},
});
return res;
Expand Down Expand Up @@ -360,15 +353,6 @@ class API {
return res;
}

async bulkCreateAuthors(authors: Omit<Author, "_id">[]) {
const res = await axios.post<
{
authors: Author[];
} & ConductorBaseResponse
>("/authors/bulk", { authors });
return res;
}

async updateAuthor(id: string, data: Author) {
const res = await axios.patch<
{
Expand Down Expand Up @@ -648,7 +632,7 @@ class API {
lulu_status?: string;
query?: string;
}) {
const res = await axios.get<GetStoreOrdersResponse & ConductorBaseResponse>(
const res = await axios.get<ConductorInfiniteScrollResponse<StoreOrderWithStripeSession>>(
"/store/admin/orders",
{
params,
Expand Down Expand Up @@ -1418,18 +1402,18 @@ class API {
async updateUserPinnedProjects(
data:
| {
action: "add-project" | "move-project";
folder: string;
projectID: string;
}
action: "add-project" | "move-project";
folder: string;
projectID: string;
}
| {
action: "remove-project";
projectID: string;
}
action: "remove-project";
projectID: string;
}
| {
action: "add-folder" | "remove-folder";
folder: string;
}
action: "add-folder" | "remove-folder";
folder: string;
}
) {
const res = await axios.patch<ConductorBaseResponse>(
"/user/projects/pinned",
Expand Down
88 changes: 10 additions & 78 deletions client/src/components/FilesManager/AuthorsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@ import {
useMemo,
useState,
} from "react";
import { Button, Dropdown, Form, Icon } from "semantic-ui-react";
import { Author } from "../../types";
import { Dropdown, Form } from "semantic-ui-react";
import useGlobalError from "../error/ErrorHooks";
import useDebounce from "../../hooks/useDebounce";
import api from "../../api";
import { ProjectFileAuthor } from "../../types/Project";
import ManualEntryModal from "../util/ManualEntryModal";
import { useModals } from "../../context/ModalContext";

interface AuthorsFormProps {
mode: "project-default" | "file";
Expand Down Expand Up @@ -40,7 +37,6 @@ const AuthorsForm = forwardRef(

const { handleGlobalError } = useGlobalError();
const { debounce } = useDebounce();
const { openModal, closeAllModals } = useModals();

const [authorOptions, setAuthorOptions] = useState<ProjectFileAuthor[]>([]);
const [secondaryAuthorOptions, setSecondaryAuthorOptions] = useState<
Expand Down Expand Up @@ -111,12 +107,12 @@ const AuthorsForm = forwardRef(
if (res.data.err) {
throw new Error(res.data.errMsg);
}
if (!res.data.authors || !Array.isArray(res.data.authors)) {
if (!res.data.items || !Array.isArray(res.data.items)) {
throw new Error("Failed to load author options");
}

const opts = [
...res.data.authors,
...res.data.items,
...(selectedPrimary ? [selectedPrimary] : []),
...(selectedCorresponding ? [selectedCorresponding] : []),
...(selectedSecondary ?? []),
Expand All @@ -143,11 +139,11 @@ const AuthorsForm = forwardRef(
if (res.data.err) {
throw new Error(res.data.errMsg);
}
if (!res.data.authors || !Array.isArray(res.data.authors)) {
if (!res.data.items || !Array.isArray(res.data.items)) {
throw new Error("Failed to load author options");
}

const opts = [...res.data.authors, ...(selectedSecondary ?? [])];
const opts = [...res.data.items, ...(selectedSecondary ?? [])];

const unique = opts.filter(
(a, i, self) => self.findIndex((b) => b._id === a._id) === i
Expand All @@ -168,12 +164,12 @@ const AuthorsForm = forwardRef(
if (res.data.err) {
throw new Error(res.data.errMsg);
}
if (!res.data.authors || !Array.isArray(res.data.authors)) {
if (!res.data.items || !Array.isArray(res.data.items)) {
throw new Error("Failed to load author options");
}

const opts = [
...res.data.authors,
...res.data.items,
...(selectedCorresponding ? [selectedCorresponding] : []),
];

Expand All @@ -200,74 +196,13 @@ const AuthorsForm = forwardRef(
200
);

const handleAddAuthor = (newAuthor: Author, ctx: string) => {
if (!["primary", "secondary", "corresponding"].includes(ctx)) return;

const withID = {
...newAuthor,
_id: crypto.randomUUID(),
}

// Set the manually added author as the primary or secondary author
// based on where the manual entry was triggered
if (ctx === "primary") {
setSelectedPrimary(withID);
setAuthorOptions([...authorOptions, withID]);
}

if (ctx === "corresponding") {
setSelectedCorresponding(withID);
setCorrespondingAuthorOptions([...correspondingAuthorOptions, withID]);
}

if (ctx === "secondary") {
setSecondaryAuthorOptions([...secondaryAuthorOptions, withID]);
if (currentAuthors) {
setSelectedSecondary([...currentAuthors, withID]);
} else {
setSelectedSecondary([withID]);
}
}
};

const ManualEntryButton = ({
from,
}: {
from: "primary" | "secondary" | "corresponding";
}) => (
<div className="flex justify-end">
<Button
onClick={() => {
openModal(
<ManualEntryModal
show={true}
onClose={() => closeAllModals()}
onSaved={(author, ctx) => {
handleAddAuthor(author, ctx);
closeAllModals();
}}
ctx={from}
/>
)
}}
basic
size="mini"
color="blue"
className="!-mt-1"
>
<Icon name="plus" />
Manual Entry
</Button>
</div>
);

const primaryAuthorOpts = useMemo(() => {
const opts = authorOptions
.filter((a) => !selectedSecondary?.find((ca) => ca._id === a._id))
.map((a) => ({
key: crypto.randomUUID(),
value: a._id ?? "",
text: `${a.firstName} ${a.lastName}`,
text: a.name ?? "Unknown",
}));

opts.unshift({
Expand All @@ -285,7 +220,7 @@ const AuthorsForm = forwardRef(
.map((a) => ({
key: crypto.randomUUID(),
value: a._id ?? "",
text: `${a.firstName} ${a.lastName}`,
text: a.name ?? "Unknown",
}));

opts.unshift({
Expand All @@ -301,7 +236,7 @@ const AuthorsForm = forwardRef(
const opts = correspondingAuthorOptions.map((a) => ({
key: crypto.randomUUID(),
value: a._id ?? "",
text: `${a.firstName} ${a.lastName}`,
text: a.name ?? "Unknown",
}));

opts.unshift({
Expand Down Expand Up @@ -343,7 +278,6 @@ const AuthorsForm = forwardRef(
loading={loadingAuthors}
/>
</Form.Field>
<ManualEntryButton from="primary" />
</div>
<div className="mt-4">
<label
Expand Down Expand Up @@ -378,7 +312,6 @@ const AuthorsForm = forwardRef(
loading={loadingCorrespondingAuthors}
/>
</Form.Field>
<ManualEntryButton from="corresponding" />
</div>
<div>
<Form.Field className="flex flex-col">
Expand Down Expand Up @@ -417,7 +350,6 @@ const AuthorsForm = forwardRef(
loading={loadingSecondaryAuthors}
/>
</Form.Field>
<ManualEntryButton from="secondary" />
</div>
</>
);
Expand Down
36 changes: 18 additions & 18 deletions client/src/components/FilesManager/FilesUploader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,24 +130,24 @@ const FilesUploader: React.FC<FilesUploaderProps> = ({
formData.append("parentID", uploadPath);

// If uploader exists in authors collection, add them as an author to the file
if (mode === "add" && user) {
const authorsRes = await api.getAuthors({ query: user.email });
if (authorsRes.data.err) {
console.error(authorsRes.data.errMsg);
}
if (!authorsRes.data.authors) {
console.error("An error occurred while getting authors");
}

if (authorsRes.data.authors) {
const foundAuthor = authorsRes.data.authors.find(
(author) => author.email === user.email
);
if (foundAuthor && foundAuthor._id) {
formData.append("authors", [foundAuthor._id].toString());
}
}
}
// if (mode === "add" && user) {
// const authorsRes = await api.getAuthors({ query: user.email });
// if (authorsRes.data.err) {
// console.error(authorsRes.data.errMsg);
// }
// if (!authorsRes.data.authors) {
// console.error("An error occurred while getting authors");
// }

// if (authorsRes.data.authors) {
// const foundAuthor = authorsRes.data.authors.find(
// (author) => author.email === user.email
// );
// if (foundAuthor && foundAuthor._id) {
// formData.append("authors", [foundAuthor._id].toString());
// }
// }
// }

if (mode === "replace") {
formData.append("overwriteName", overwriteName.toString()); // Only used for replace mode
Expand Down
14 changes: 7 additions & 7 deletions client/src/components/commons/CommonsCatalog/AuthorsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const AuthorsTable: React.FC<AuthorsTableProps> = ({
<Header sub>Name</Header>
</Table.HeaderCell>
<Table.HeaderCell scope="col">
<Header sub>Primary Institution</Header>
<Header sub>Institution/Program</Header>
</Table.HeaderCell>
<Table.HeaderCell scope="col">
<Header sub>URL</Header>
Expand All @@ -35,21 +35,21 @@ const AuthorsTable: React.FC<AuthorsTableProps> = ({
<Table.Cell>
<a href={`/authors/${item._id}`} className="cursor-pointer">
{truncateString(
`${item.firstName ?? ""} ${item.lastName ?? ""}`,
`${item.name}`,
50
)}
</a>
</Table.Cell>
<Table.Cell>
<p>
{item.primaryInstitution &&
truncateString(item.primaryInstitution, 50)}
{
truncateString(item.companyName || item.programName || "", 50)}
</p>
</Table.Cell>
<Table.Cell>
{item.url && (
<a href={item.url} target="_blank" rel="noreferrer">
{item.url}
{item.nameURL && (
<a href={item.nameURL} target="_blank" rel="noreferrer">
{truncateString(item.nameURL, 50)}
</a>
)}
</Table.Cell>
Expand Down
Loading
Loading