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

feat: Taxonomy delete dialog [FC-0036] #684

Merged
merged 1 commit into from
Dec 12, 2023

Conversation

ChrisChV
Copy link
Contributor

@ChrisChV ChrisChV commented Nov 14, 2023

This adds:

  • New submenu 'Delete' on the Taxonomy card meny
  • Delete Dialog with the functionality to delete a Taxonomy
  • Show a Toast after delete the Taxonomy
  • Enable export for System defined Taxonomies.

image
image

Testing instructions

  • Go to the taxonomy list page.
  • Click on the menu of a normal taxonomy, and click on Delete submenu
  • Review the Delete Dialog. Enter "DELETE" on the input.
  • Await unitl the taxonomy is deleted and the toast is shown.
  • Click on a Taxonomy to go to the detail page.
  • Click on Actions and click on Delete submenu
  • Enter "DELETE" on the input.
  • Await unitl the taxonomy is deleted
  • Check the redirection and the toast is shown.

Other Info

TODO

  • The number of tags in the taxonomy that appears in the delete dialog. The code is ready to receive this value. It is necessary to use this version of open edx-learning for it to be displayed. No other code change is necessary.

@openedx-webhooks
Copy link

openedx-webhooks commented Nov 14, 2023

Thanks for the pull request, @ChrisChV! Please note that it may take us up to several weeks or months to complete a review and merge your PR.

Feel free to add as much of the following information to the ticket as you can:

  • supporting documentation
  • Open edX discussion forum threads
  • timeline information ("this must be merged by XX date", and why that is)
  • partner information ("this is a course on edx.org")
  • any other information that can help Product understand the context for the PR

All technical communication about the code itself will be done via the GitHub pull request interface. As a reminder, our process documentation is here.

Please let us know once your PR is ready for our review and all tests are green.

@openedx-webhooks openedx-webhooks added the open-source-contribution PR author is not from Axim or 2U label Nov 14, 2023
@ChrisChV ChrisChV marked this pull request as draft November 14, 2023 23:18
Copy link

codecov bot commented Nov 14, 2023

Codecov Report

Attention: 5 lines in your changes are missing coverage. Please review.

Comparison is base (67cda57) 88.86% compared to head (8690387) 88.93%.
Report is 1 commits behind head on master.

Files Patch % Lines
src/taxonomy/data/apiHooks.jsx 75.00% 2 Missing ⚠️
src/taxonomy/TaxonomyLayout.jsx 80.00% 1 Missing ⚠️
src/taxonomy/TaxonomyListPage.jsx 87.50% 1 Missing ⚠️
...rc/taxonomy/taxonomy-detail/TaxonomyDetailPage.jsx 96.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #684      +/-   ##
==========================================
+ Coverage   88.86%   88.93%   +0.06%     
==========================================
  Files         469      472       +3     
  Lines        7255     7327      +72     
  Branches     1559     1564       +5     
==========================================
+ Hits         6447     6516      +69     
- Misses        781      784       +3     
  Partials       27       27              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ChrisChV ChrisChV changed the title feat: Taxonomy delete dialog feat: Taxonomy delete dialog [FC-0036] Nov 20, 2023
@ChrisChV ChrisChV marked this pull request as ready for review November 20, 2023 20:02
Copy link
Member

@yusuf-musleh yusuf-musleh left a comment

Choose a reason for hiding this comment

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

👍 Great job on this, it works great! I just had a few comments/nits.

  • I tested this: (ran it locally following instructions)
  • I read through the code
  • I checked for accessibility issues
  • Includes documentation
  • I made sure any change in configuration variables is reflected in the corresponding client's configuration-secure repository.

src/taxonomy/messages.js Outdated Show resolved Hide resolved
src/taxonomy/TaxonomyListPage.jsx Outdated Show resolved Hide resolved
src/taxonomy/TaxonomyListPage.jsx Outdated Show resolved Hide resolved
src/taxonomy/TaxonomyListPage.jsx Outdated Show resolved Hide resolved
Comment on lines 33 to 42
export const useDeleteTaxonomy = () => {
/**
* Deletes a taxonomy.
*
* @param {import("./types.mjs").DeleteTaxonomyParams} params - Parameters for deleting the taxonomy.
* @returns {Promise<void>} - A promise that resolves when the taxonomy is deleted.
*/
const deleteTaxonomyWrap = async ({ pk }) => {
await deleteTaxonomy(pk);
};

return useMutation({
mutationFn: deleteTaxonomyWrap,
});
};
Copy link
Member

Choose a reason for hiding this comment

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

Is there a reason why we dont use the deleteTaxonomy api function directly inside the useMutation without wrapping it? Maybe something similar to this (It might need some adjustments, as I haven't tested this, but I had something similar working in my PR)

Suggested change
export const useDeleteTaxonomy = () => {
/**
* Deletes a taxonomy.
*
* @param {import("./types.mjs").DeleteTaxonomyParams} params - Parameters for deleting the taxonomy.
* @returns {Promise<void>} - A promise that resolves when the taxonomy is deleted.
*/
const deleteTaxonomyWrap = async ({ pk }) => {
await deleteTaxonomy(pk);
};
return useMutation({
mutationFn: deleteTaxonomyWrap,
});
};
/**
* Deletes a taxonomy.
*/
export const useDeleteTaxonomy = () => (
useMutation({
mutationFn: ({ pk }) => deleteTaxonomy(pk),
});
);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@yusuf-musleh I did this changes, a little copy of your PR:

/**
 * Builds the mutation to delete a taxonomy.
 * @returns {Object} - An object with the mutation configuration.
 */
export const useDeleteTaxonomy = () => {
  const queryClient = useQueryClient()

  /**
   * @type {import("@tanstack/react-query").MutateFunction<any, any, {pk: number}>}
  */
  return useMutation({
    mutationFn: async ({ pk }) => await deleteTaxonomy(pk),
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ['taxonomyList'] });
    },
  });
};

But I got this error after run npm run types:

src/taxonomy/data/apiHooks.jsx:40:26 - error TS2339: Property 'pk' does not exist on type 'void'.

40     mutationFn: async ({ pk }) => await deleteTaxonomy(pk),

How did you resolve this error in your PR?

Copy link
Member

Choose a reason for hiding this comment

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

@ChrisChV Interesting, I actually have the same issue, but didn't show up in the PR because it is failing earlier on other issues. I tried different things to fix this, but it didnt seem to work. Maybe @bradenmacdonald might have some suggestions?

Copy link
Member

Choose a reason for hiding this comment

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

@ChrisChV I figured it out, you have to put the jsdoc comment right above the mutationFn: line, mine looks like this, (notice how it is inside the useMutation):

/**
 * Builds the mutation to update the tags applied to the content object
 * @param {string} contentId The id of the content object to update tags for
 * @param {number} taxonomyId The id of the taxonomy the tags belong to
 */
export const useContentTaxonomyTagsMutation = (contentId, taxonomyId) => {
  const queryClient = useQueryClient();

  return useMutation({
    /**
     * @type {import("@tanstack/react-query").MutateFunction<
     *   any,
     *   any,
     *   {
     *     tags: string[]
     *   }
     * >}
     */
    mutationFn: ({ tags }) => updateContentTaxonomyTags(contentId, taxonomyId, tags),
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ['contentTaxonomyTags', contentId] });
    },
  });
};

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! It works

src/taxonomy/TaxonomyListPage.jsx Outdated Show resolved Hide resolved
src/taxonomy/taxonomy-card/TaxonomyCardMenu.jsx Outdated Show resolved Hide resolved
src/taxonomy/taxonomy-detail/TaxonomyDetailMenu.jsx Outdated Show resolved Hide resolved
src/taxonomy/TaxonomyListPage.jsx Outdated Show resolved Hide resolved
Comment on lines 44 to 52
useEffect(() => {
const deleted = searchParams.get('deleted');
if (deleted !== null) {
setToastText(intl.formatMessage(messages.taxonomyDeleteToast, { name: deleted }));
setShowToast(true);
searchParams.delete('deleted');
setSearchParams(searchParams);
}
}, []);
Copy link
Contributor

Choose a reason for hiding this comment

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

If I understand correctly, this is temporarily using the search query to store the item to be deleted. I'm not sure why this is needed. Why not just store this in react state?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added a comment on this code. You can delete taxonomies from the Taxonomy details page, so after delete, is redirected to the list page and show the toast. Using the searchParams is the simplest way to show the toast in the redirect that I found.

Copy link
Contributor

Choose a reason for hiding this comment

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

If you use search params, you need to make sure to use the router to reset the search params after the toast is displayed. Otherwise, if users bookmark that URL or refresh the page, they'll see the toast again. (This may sound unlikely but it happens to me all the time in Studio with the similar query param that focuses on the unit name field to let you rename a newly-created unit; it happens to me many times when the unit already exists. Very annoying.)

You could also just use localStorage to indicate that a toast should be shown though? Probably easier. Could also as on #wg-frontend if there is a standard pattern for this in our MFEs. Maybe a helper for these sort of flash messages already exists in openedx/frontend-platform or similar.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@bradenmacdonald Thanks! I used localStorage. I didn't find a standard way, but I still left my question in #wg-frontend

Copy link
Contributor

Choose a reason for hiding this comment

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

When dealing with notifications on other projects, I used this: https://notistack.com/features/basic

If we're not able to import the library, we could use the same concept: a notification provider/context on top of our <App /> (or <TaxonomyLayout> if we don't want affect other parts of the framework).

Copy link
Contributor

Choose a reason for hiding this comment

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

I would prefer to avoid adding dependencies if at all possible; the bundle size is already very large.

Copy link
Contributor

@xitij2000 xitij2000 Nov 30, 2023

Choose a reason for hiding this comment

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

Local storage is good, but I'm wondering why this needs even that. Perhaps I am mistaken about this, but there is not hard refresh when navigating here, so it should be entirely possible to store this in react or redux state right?

I think these PRs are avoiding redux but even with react you can use a shared context. i.e. the root of the page can be wrapped in a which can be a component that provides common context that all components might need. See an example here.

So this context provider can be provided with the current deleted taxonomy state, i.e. what you're doing with localstorage right now.

Here is some sample code:

Context component

export const TaxonomyContext = React.createContext({
  deletedTaxonomy: null,
  setDeletedTaxonomy: null,
})

New root page for all taxonomy pages:

function TaxonomyRoutes(){
   const [deletedTaxonomy,  setDeletedTaxonomy] = useState(null);
  return (
 <TaxonomyContext.Provider value={{deletedTaxonomy,  setDeletedTaxonomy}}>
... taxonomy routes
</TaxonomyContext.Provider>
)
}

Using the context:

 const {deletedTaxonomy} = useContext(TaxonomyContext);

With this approach you can pass around data between components, and it may be useful in the future as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

I also need the same functionality to show a toast after importing a taxonomy.

I suggest we make this more generic, like:

   const [toastMessages,  setToastMessages] = useState([]);

We have the TaxonomyLayout that is a "root" for the taxonomy pages and can be responsible to render toast/alerts.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I like this approach I'm going to try it. Thanks to all!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@xitij2000 Updated here 18a224a. Thanks for the feedback, that change will be help in the future. It's ready for another review round

let enabledMenuItems = menuItems;
if (taxonomy.systemDefined) {
enabledMenuItems = systemDefinedMenuItems;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't we also need to check whether the user is allowed to delete this taxonomy before we show 'Delete' as a menu option?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@pomegranited You are right. It may be best to do this in a follow-up task. Since the menu has been refactored and there will be conflicts. It would be best to do this after the conflicts have been resolved. CC @bradenmacdonald

Copy link
Contributor

@xitij2000 xitij2000 left a comment

Choose a reason for hiding this comment

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

The code generally looks good. I've left a few nits. I haven't been able to test it yet since I don't have it set up on this computer. If it's been tested after the latest changes then it's good to go.

For the tests I don't know if it's a good idea to test the hooks the way they are being tested, i.e. being called as direct functions.

I think it's better to mock the API response calls using axiosMock and then see if the endpoints are being called.

src/taxonomy/TaxonomyLayout.test.jsx Outdated Show resolved Hide resolved

const TaxonomyListPage = () => {
const intl = useIntl();
const [deletedTaxonomyName, setDeletedTaxonomyName] = useState('');
const deleteMutation = useDeleteTaxonomy();
Copy link
Contributor

Choose a reason for hiding this comment

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

I think for someone unfamiliar with useQuery this approach of getting a deleteMutation object and then calling mutate is a bit confusing. I think this logic can be moved into the hook itself. i.e. then you can use it as follows:

const deleteTaxonomy = useDeleteTaxonomyHelper();

const onDeleteTaxonomy = (id name) => {
  ...
  deleteTaxonomy(id);
}

Essentially hide the useQuery API from the component.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this will be solved using the Braden's approach

Comment on lines 29 to 43
/**
* Builds the mutation to delete a taxonomy.
* @returns {Object} - An object with the mutation configuration.
*/
export const useDeleteTaxonomy = () => {
const queryClient = useQueryClient();
return useMutation({
/**
* @type {import("@tanstack/react-query").MutateFunction<
* any,
* any,
* {
* pk: number
* }
* >}
*/
mutationFn: async ({ pk }) => deleteTaxonomy(pk),
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ['taxonomyList'] });
},
});
};

Copy link
Contributor

Choose a reason for hiding this comment

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

I think hiding the specifics of useQuery will make it easier for those dealing with other aspects of this code to understand what's going on.

Suggested change
/**
* Builds the mutation to delete a taxonomy.
* @returns {Object} - An object with the mutation configuration.
*/
export const useDeleteTaxonomy = () => {
const queryClient = useQueryClient();
return useMutation({
/**
* @type {import("@tanstack/react-query").MutateFunction<
* any,
* any,
* {
* pk: number
* }
* >}
*/
mutationFn: async ({ pk }) => deleteTaxonomy(pk),
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ['taxonomyList'] });
},
});
};
/**
* Builds the mutation to delete a taxonomy.
* @returns {(id: string) => void} - An object with the mutation configuration.
*/
export const useDeleteTaxonomy = () => {
const queryClient = useQueryClient();
const { mutate } = useMutation({
mutationFn: async ({ pk }) => deleteTaxonomy(pk),
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ['taxonomyList'] });
},
});
return (id) => mutate({ pk: id});
};

Copy link
Contributor

@bradenmacdonald bradenmacdonald Dec 8, 2023

Choose a reason for hiding this comment

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

Building on that, I would recommend that you return the mutate function directly, so your code can look like this:

export const useDeleteTaxonomy = () => {
  const queryClient = useQueryClient();
  const { mutate } = useMutation({
    /** @type {import("@tanstack/react-query").MutateFunction<any, any, {pk: number}>} */
    mutationFn: async ({ pk }) => deleteTaxonomy(pk),
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ['taxonomyList'] });
    },
  });
  return mutate;
};
  const deleteTaxonomy = useDeleteTaxonomy();
  //...
  const onClickDeleteTaxonomy = React.useCallback(() => {
    deleteTaxonomy({pk: taxonomy.id}, {
      onSuccess: async() => {
        setToastMessage(intl.formatMessage(taxonomyMessages.taxonomyDeleteToast, { name: taxonomy.name }));
        navigate('/taxonomies');
      },
      onError: async() => {
        // TODO: display the error to the user
      },
    });
  }, [setToastMessage, navigate]);

Notice that this way you can directly access onSuccess for that exact mutation, and you don't have to use useEffect. Also notice that if you inspect these variables in your IDE, all the detailed type information is preserved and correct. For example, it knows what parameters the onSuccess handler is given, including that the second parameter has the pk of the object. Not that you need that here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated here

Copy link
Contributor

@bradenmacdonald bradenmacdonald left a comment

Choose a reason for hiding this comment

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

I noticed some typing issues while driving by...

src/taxonomy/taxonomy-detail/TaxonomyDetailPage.jsx Outdated Show resolved Hide resolved
@@ -26,6 +26,29 @@ const useTaxonomyListData = (org) => (
})
);

/**
* Builds the mutation to delete a taxonomy.
* @returns {Object} - An object with the mutation configuration.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* @returns {Object} - An object with the mutation configuration.
* @returns An object with the mutation configuration.

You are actually erasing the useful type information here. Leave out the type and TypeScript will infer it automatically :)

Before:
Screenshot 2023-12-08 at 10 56 42 AM

After:
Screenshot 2023-12-08 at 10 55 04 AM
(assuming you also fixed the @ts-check at the top of TaxonomyDetailPage.tsx)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed here: 87d508c

Comment on lines 29 to 43
/**
* Builds the mutation to delete a taxonomy.
* @returns {Object} - An object with the mutation configuration.
*/
export const useDeleteTaxonomy = () => {
const queryClient = useQueryClient();
return useMutation({
/**
* @type {import("@tanstack/react-query").MutateFunction<
* any,
* any,
* {
* pk: number
* }
* >}
*/
mutationFn: async ({ pk }) => deleteTaxonomy(pk),
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ['taxonomyList'] });
},
});
};

Copy link
Contributor

@bradenmacdonald bradenmacdonald Dec 8, 2023

Choose a reason for hiding this comment

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

Building on that, I would recommend that you return the mutate function directly, so your code can look like this:

export const useDeleteTaxonomy = () => {
  const queryClient = useQueryClient();
  const { mutate } = useMutation({
    /** @type {import("@tanstack/react-query").MutateFunction<any, any, {pk: number}>} */
    mutationFn: async ({ pk }) => deleteTaxonomy(pk),
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ['taxonomyList'] });
    },
  });
  return mutate;
};
  const deleteTaxonomy = useDeleteTaxonomy();
  //...
  const onClickDeleteTaxonomy = React.useCallback(() => {
    deleteTaxonomy({pk: taxonomy.id}, {
      onSuccess: async() => {
        setToastMessage(intl.formatMessage(taxonomyMessages.taxonomyDeleteToast, { name: taxonomy.name }));
        navigate('/taxonomies');
      },
      onError: async() => {
        // TODO: display the error to the user
      },
    });
  }, [setToastMessage, navigate]);

Notice that this way you can directly access onSuccess for that exact mutation, and you don't have to use useEffect. Also notice that if you inspect these variables in your IDE, all the detailed type information is preserved and correct. For example, it knows what parameters the onSuccess handler is given, including that the second parameter has the pk of the object. Not that you need that here.

@@ -31,4 +32,10 @@
* @typedef {Object} UseQueryResult
Copy link
Contributor

Choose a reason for hiding this comment

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

You should not be defining or using UseQueryResult here. Please delete this and replace all occurrences of import("./types.mjs").UseQueryResult with import('@tanstack/react-query').UseQueryResult<T>

Copy link
Contributor

Choose a reason for hiding this comment

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

Or, better yet - see the fixes I made for another PR in open-craft@01c9cd1 . Basically if you put the right type on the method in api.js, then you can leave out the @returns definition in apiHooks.tsx and the type will still be correct.

open-craft@01c9cd1#diff-3aff02024d6cb28f96cce104799ab0f3bfe2e9559fe0cd572b9d745daeb590afL25-R25

open-craft@01c9cd1#diff-b5aca46925ac5f8adac9fbe39002822044019f623908e73f3dba1d5386048dcdL20

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed here: 4bf6f0f

Comment on lines 25 to 36
const handleInputChange = (event) => {
if (event.target.value === deleteLabel) {
setDeleteButtonDisabled(false);
} else {
setDeleteButtonDisabled(true);
}
};

const onClickDelete = () => {
onClose();
onDelete();
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const handleInputChange = (event) => {
if (event.target.value === deleteLabel) {
setDeleteButtonDisabled(false);
} else {
setDeleteButtonDisabled(true);
}
};
const onClickDelete = () => {
onClose();
onDelete();
};
const handleInputChange = React.useCallback((event) => {
setDeleteButtonDisabled(event.target.value !== deleteLabel);
});
const onClickDelete = React.useCallback(() => {
onClose();
onDelete();
}, [onClose, onDelete]);

If you don't wrap these handlers in useCallback, they change and become new functions every time, which will cause child components to re-render needlessly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated here: fd18b0f

@bradenmacdonald
Copy link
Contributor

For the tests I don't know if it's a good idea to test the hooks the way they are being tested, i.e. being called as direct functions. I think it's better to mock the API response calls using axiosMock and then see if the endpoints are being called.

+1 That's my preferred way to write these tests as well. It mocks the thing that's external (the API) while still properly testing all the integrated functionality of the UI - the queries, hooks, and react components.

You can see https://github.com/openedx/frontend-app-course-authoring/blob/195c9e416c99bb8e53fc469d57887acf245a029c/src/taxonomy/tag-list/TagListTable.test.jsx which I wrote in that way.

But if they're working, no need to change as we're getting tight on budget. Maybe just add a comment in the test that we could refactor them that way in the future.

@bradenmacdonald
Copy link
Contributor

@ChrisChV Can you please address those nits, squash this down to one commit, then ping @xitij2000 to merge it for you?

@ChrisChV
Copy link
Contributor Author

@xitij2000 It's ready for merge

feat: Connect with delete API

feat: Show toast after delete

feat: Enable export for system taxonomies

test: Adding tests

feat: Delete submenu on details page

style: Comment added

style: Typos

feat: Improve delete mutation

style: Nits on types

refactor: Taxonomy Card Menu and Taxonomy Details Menu

refactor: Refactor delete function and tests

style: Nit on list page

refactor: Use localStorage to show toast

feat: tagsCount configuration added

chore: Nit on tests

test: Add test to meet coverage

refactor: Refactor Toast with Taxonomy context

refactor: Fix typing nits and refactor delete mutation

style: Nits on typing

style: Nits

nits
@ChrisChV ChrisChV force-pushed the chris/FAL-3533-delete-taxonomy branch from 2e327e2 to 8690387 Compare December 11, 2023 23:45
@xitij2000 xitij2000 merged commit 1eff489 into openedx:master Dec 12, 2023
6 checks passed
@openedx-webhooks
Copy link

@ChrisChV 🎉 Your pull request was merged! Please take a moment to answer a two question survey so we can improve your experience in the future.

@xitij2000 xitij2000 deleted the chris/FAL-3533-delete-taxonomy branch December 12, 2023 12:24
jesperhodge added a commit that referenced this pull request Dec 12, 2023
jesperhodge added a commit that referenced this pull request Dec 12, 2023
Internal issue: https://2u-internal.atlassian.net/servicedesk/customer/portal/9/CR-6328?created=true

Reverted 6 merged PRs due to problems.

scroll was not working on editors
potential problems with editor content loading

------------------------------------------------------


* Revert "fix(deps): update dependency @edx/frontend-lib-content-components to v1.177.4 (#742)"

This reverts commit cc40e9d.

* Revert "feat: add escalation email field for LTI-based proctoring providers (#736)"

This reverts commit 0f483dc.

* Revert "fix: video downloads (#728)"

This reverts commit c5abd21.

* Revert "fix: import api to chunk file (#734)"

This reverts commit 6f7a992.

* Revert "feat: Taxonomy delete dialog (#684)"

This reverts commit 1eff489.

* Revert "fix(deps): update dependency @edx/frontend-lib-content-components to v1.177.1 (#727)"

This reverts commit dcabb77.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
open-source-contribution PR author is not from Axim or 2U
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

[Tagging] Delete a taxonomy
7 participants