Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add admin manage article feature #382

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from

Conversation

mistydqwq
Copy link
Collaborator

[Feature] Add Admin Panel Article Management

Background

This PR adds a new Article Management feature to the admin panel, allowing administrators to search for articles in the database by URL and modify their fields.

Changes Introduced

Frontend Changes

  • Added a new article/management/ folder under recnet/src/app/admin/.
    • Created article/management/page.tsx for the main page.
    • Created article/management/ArticleManagementForm.tsx for the article editing form.
  • Updated AdminPanelNav to include the new Article Management section.
  • Modified src/serve/routers/article.ts:
    • Modified the getArticleByLink logic for fetching articles based on URL and using digital library or not .

Backend Changes

  • Added a new API: adminUpdateArticle to update article fields in the database.
  • Modified getArticleByLink API:
    • Introduced a new request parameter:
      boolean useDigitalLibrary
    • Purpose: Determines whether to fetch articles using the digitalLibrary service.
    • Default Value: true (ensuring no impact on existing behavior).
    • If set to false: The API retrieves articles directly from the database without using digitalLibrary.
  • Updated related backend components:
    • DTOs
    • Repository layer
    • Service layer
    • libs/recnet-api-model

How to Test

  1. Navigate to the Admin Panel.
  2. Go to the newly added Article Management section.
  3. Enter a URL to search for an article in the database.
  4. Modify the necessary fields and submit the changes.
  5. Verify that:
    • The article updates correctly in the database.
    • The new useDigitalLibrary parameter works as expected (retrieves articles correctly when set to false).

Copy link

vercel bot commented Feb 4, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
recnet ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 4, 2025 8:33pm
recnet-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 4, 2025 8:33pm

@swh00tw
Copy link
Collaborator

swh00tw commented Feb 4, 2025

Good to see your 1st PR. I will review it. By the way, can you make sure the Github action successfully passed? It seems like you have linting issue. You can configure your IDE so that you can apply linter on saving the files.

By the way, when you run git commit -m "...", the commit hook should automatically lint the staging files for you. How did you do the git commit?

@swh00tw
Copy link
Collaborator

swh00tw commented Feb 4, 2025

For quick fix, you can do

nx lint <PROJECT_NAME> --fix

for recnet, recnet-api, and recnet-api-model.

And push commit.

@joannechen1223
Copy link
Collaborator

@mistydqwq Please remove the unused code and comments to keep the code tidy and ready for review. Thank you!

@swh00tw
Copy link
Collaborator

swh00tw commented Feb 4, 2025

I haven't started code review yet, just run on my machine. The UI looks great!!
There are some small nitpicks

  1. For the "month" field, although we store 0-indexed number in DB, it's better to display 1-indexed number in UI (you can apply the offset behind the scene) for the sake of UX. (If you can use the same Dropdown component in NewArticleForm.tsx that would be even better)
Screenshot 2025-02-04 at 5 12 55 PM Screenshot 2025-02-04 at 5 16 15 PM
  1. After I click "Save changes", the form disappears. Is it intended behavior? I felt like the disappearing behavior is weird and leaving the form there should be better. @joannechen1223 any thoughts?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a small bug for all the string fields in the form. For example, if the article's doi field is current null in database. When I type something in form's doi field and then delete them, and then click "Save changes", the doi field in DB for this article will be changed to "" (empty string).

To fix this, you can check out how I handle this kind of edge case in onboard/page.tsx. You can essentially use setValueAs field to fix this. For example:

<TextField.Root
    className="w-full"
    size="3"
    placeholder="(Optional)"
    {...register("url", {
      setValueAs: (value) => {
        if (value === "") {
          // when the input is empty string, set to null to avoid url validation
          return null;
        }
        return value;
      },
    })}
  >

public async getArticleByLink(
link: string
link: string,
fetchFromDigitalLibrary: boolean = true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fetchFromDigitalLibrary: boolean = true
useDigitalLibraryFallback: boolean = true

I think the naming can be better. It's confusing to name like this since if you set fetchFromDigitalLibrary to true, it will first fetch from our DB and if not found, it will fetch from Digital Library. Therefore, I think naming fetchFromDigitalLibrary is not accurate.

Just provide one of my random idea, we can name it useDigitalLibraryFallback. @joannechen1223 any thought?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer not to use this parameter and create another method instead, just like what you commented out in getDbArticleByLink as the logic of the digital library here is relatively complicated. Adding another API will be more straightforward if you are not going to reuse the digital library related logic.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually like what I commented out, at first I implemented a separated API to get article directly from the database, but our professor suggests me to combine the getDbArticleByLink with the original getArticleByLink because these two function are pretty similar and he doesn't want the API to explode at the beginning. Also make sense. So I changed the getArticleByLink function to the current version. May need to discuss.

Copy link
Collaborator

@swh00tw swh00tw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GJ overall. And your PR content is great. I can understand what has changed, what's the feature, and how to test it.
Just need to take care of some details.
Btw, you can also add other teammates as reviewers!

Copy link
Collaborator

@joannechen1223 joannechen1223 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your hard work! It was a great initiative. I left some comments related to the recnet-api design and development, summarized to two major perspectives here from my point of view.

  1. For getting article by link, if the requirement is NOT to integrate the digital library and only query from DB, I suggest having a separate API and method to handle it. (Feel free to change to the original method name if you have a better naming idea.)
  2. For updating article API, I suggest updating by article ID instead of the link. Some edge cases were provided in the comments.

If you have any questions, please let me know.

public async getArticleByLink(
link: string
link: string,
fetchFromDigitalLibrary: boolean = true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer not to use this parameter and create another method instead, just like what you commented out in getDbArticleByLink as the logic of the digital library here is relatively complicated. Adding another API will be more straightforward if you are not going to reuse the digital library related logic.

libs/recnet-api-model/src/lib/api/article.ts Show resolved Hide resolved
@mistydqwq
Copy link
Collaborator Author

@swh00tw @joannechen1223 Thanks a lot for your review! I've already started to work on your comments, and fixed some problems locally. I will resolve the remaining problems these days. Btw I left some comments in the useDigitalLibrary or create a new api part, which might need to be discussed.

@mistydqwq
Copy link
Collaborator Author

I haven't started code review yet, just run on my machine. The UI looks great!! There are some small nitpicks

  1. For the "month" field, although we store 0-indexed number in DB, it's better to display 1-indexed number in UI (you can apply the offset behind the scene) for the sake of UX. (If you can use the same Dropdown component in NewArticleForm.tsx that would be even better)

Screenshot 2025-02-04 at 5 12 55 PM Screenshot 2025-02-04 at 5 16 15 PM
2. After I click "Save changes", the form disappears. Is it intended behavior? I felt like the disappearing behavior is weird and leaving the form there should be better. @joannechen1223 any thoughts?

Good idea, I've changed the month field to dropdown list. And for the second question, I actually intended to do it. Because this feature I think is mainly used to modify the article's entry. At first I just think if we changed the article's link, and the form doesn't disappear, the form's link will not be the same as the link in the search box, which could also be a little bit weird. But If you think it's better to keep the form after saving the changes, I can do it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants