Files
medusa-store/packages/admin-next/dashboard/src/hooks/use-command-history.tsx
Kasper Fabricius Kristensen 44d43e8155 feat(dashboard, medusa, medusa-js, medusa-react, icons): DataGrid, partial Product domain, and ProductVariant hook (#6428)
The PR for the Products section is growing quite large, so I would like to merge this PR that contains a lot of the ground work before moving onto finalizing the rest of the domain.

**Note**
Since the PR contains changes to the core, that the dashboard depends on, the staging env will not work. To preview this PR, you will need to run it locally. 

## `@medusajs/medusa`

**What**
- Adds missing query params to `GET /admin/products/:id/variants`
- `options.values` has been added to the default relations of admin product endpoints.

## `medusa-react`

**What**
- Adds missing hook for `GET /admin/products/:id/variants`

## `@medusajs/dashboard`
- Adds base implementation for `DataGrid` component (formerly `BulkEditor`) (WIP)
- Adds `/products` overview page
- Adds partial `/products/create` page for creating new products (WIP - need to go over design w/ Ludvig before continuing)
- Adds `/products/:id` details page
- Adds `/products/:id/gallery` page for inspecting a products images in fullscreen.
- Adds `/products/:id/edit` page for editing the general information of a product
- Adds `/products/:id/attributes` page for editing the attributes information of a product
- Adds `/products/:id/sales-channels` page for editing which sales channels a product is available in
- Fixes a bug in `DataTable` where a table with two fixed columns would not display correctly

For the review its not important to test the DataGrid, as it is still WIP, and I need to go through some minor changes to the behaviour with Ludvig, as virtualizing it adds some constraints.

## `@medusajs/icons`

**What**
- Pulls latest icons from Figma

## TODO in next PR
- [ ] Fix the typing of POST /admin/products/:id as it is currently not possible to delete any of the nullable fields once they have been added. Be aware of this when reviewing this PR.
- [ ] Wrap up `/products/create` page
- [ ] Add `/products/:id/media` page for managing media associated with the product.
- [ ] Add `/products/id/options` for managing product options (need Ludvig to rethink this as the current API is very limited and we can implement the current design as is.)
- [ ] Add `/products/:id/variants/:id` page for editing a variant. (Possibly concat all of these into one BulkEditor page?)
2024-02-21 11:29:35 +00:00

68 lines
1.4 KiB
TypeScript

import { useCallback, useState } from "react"
/**
* Base interface for a command that can be managed
* by the `useCommandHistory` hook.
*/
export interface Command {
execute: () => void
undo: () => void
redo: () => void
}
/**
* Hook to manage a history of commands that can be undone, redone, and executed.
*/
export const useCommandHistory = (maxHistory = 20) => {
const [past, setPast] = useState<Command[]>([])
const [future, setFuture] = useState<Command[]>([])
const canUndo = past.length > 0
const canRedo = future.length > 0
const undo = useCallback(() => {
if (!canUndo) {
return
}
const previous = past[past.length - 1]
const newPast = past.slice(0, past.length - 1)
previous.undo()
setPast(newPast)
setFuture([previous, ...future.slice(0, maxHistory - 1)])
}, [canUndo, future, past, maxHistory])
const redo = useCallback(() => {
if (!canRedo) {
return
}
const next = future[0]
const newFuture = future.slice(1)
next.redo()
setPast([...past, next].slice(0, maxHistory - 1))
setFuture(newFuture)
}, [canRedo, future, past, maxHistory])
const execute = useCallback(
(command: Command) => {
command.execute()
setPast((past) => [...past, command].slice(0, maxHistory - 1))
setFuture([])
},
[maxHistory]
)
return {
undo,
redo,
execute,
canUndo,
canRedo,
}
}