Add sync actions to CRUDActions
This commit is contained in:
parent
71f7687ab9
commit
0b1cd203c3
@ -7,6 +7,7 @@ import {withRouter} from 'react-router'
|
|||||||
|
|
||||||
interface ILinkProps
|
interface ILinkProps
|
||||||
extends IWithRouterProps<Record<string, string>> {
|
extends IWithRouterProps<Record<string, string>> {
|
||||||
|
readonly className?: string
|
||||||
readonly to: string
|
readonly to: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15,6 +16,7 @@ class ContextLink extends React.PureComponent<ILinkProps> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
|
className,
|
||||||
history,
|
history,
|
||||||
location,
|
location,
|
||||||
match,
|
match,
|
||||||
@ -25,7 +27,7 @@ class ContextLink extends React.PureComponent<ILinkProps> {
|
|||||||
const href = this.urlFormatter.format(to, match.params)
|
const href = this.urlFormatter.format(to, match.params)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RouterLink to={href}>
|
<RouterLink className={className} to={href}>
|
||||||
{children}
|
{children}
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import {createCRUDActions} from './CRUDActions'
|
import {createCRUDActions} from './CRUDActions'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {AnyAction} from 'redux'
|
import {AnyAction} from 'redux'
|
||||||
import {CRUDReducer, TCRUDMethod} from './'
|
import {CRUDReducer, TCRUDMethod, TCRUDAsyncMethod} from './'
|
||||||
import {HTTPClientMock, TestUtils, getError} from '../test-utils'
|
import {HTTPClientMock, TestUtils, getError} from '../test-utils'
|
||||||
import {TMethod} from '@rondo/common'
|
import {TMethod} from '@rondo/common'
|
||||||
import {IPendingAction} from '../actions'
|
import {IPendingAction} from '../actions'
|
||||||
@ -62,7 +62,7 @@ describe('CRUD', () => {
|
|||||||
'/one/:oneId/two',
|
'/one/:oneId/two',
|
||||||
'TEST',
|
'TEST',
|
||||||
)
|
)
|
||||||
const crudReducer = new CRUDReducer<ITwo, 'TEST'>('TEST')
|
const crudReducer = new CRUDReducer<ITwo, 'TEST'>('TEST', {name: ''})
|
||||||
const Crud = crudReducer.reduce
|
const Crud = crudReducer.reduce
|
||||||
|
|
||||||
const test = new TestUtils()
|
const test = new TestUtils()
|
||||||
@ -100,7 +100,7 @@ describe('CRUD', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function dispatch(
|
function dispatch(
|
||||||
method: TCRUDMethod,
|
method: TCRUDAsyncMethod,
|
||||||
action: IPendingAction<unknown, string>,
|
action: IPendingAction<unknown, string>,
|
||||||
) {
|
) {
|
||||||
store.dispatch(action)
|
store.dispatch(action)
|
||||||
@ -109,13 +109,13 @@ describe('CRUD', () => {
|
|||||||
return action
|
return action
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUrl(method: TCRUDMethod) {
|
function getUrl(method: TCRUDAsyncMethod) {
|
||||||
return method === 'save' || method === 'findMany'
|
return method === 'save' || method === 'findMany'
|
||||||
? '/one/1/two'
|
? '/one/1/two'
|
||||||
: '/one/1/two/2'
|
: '/one/1/two/2'
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHTTPMethod(method: TCRUDMethod): TMethod {
|
function getHTTPMethod(method: TCRUDAsyncMethod): TMethod {
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case 'save':
|
case 'save':
|
||||||
return 'post'
|
return 'post'
|
||||||
@ -131,7 +131,7 @@ describe('CRUD', () => {
|
|||||||
|
|
||||||
describe('Promise rejections', () => {
|
describe('Promise rejections', () => {
|
||||||
const testCases: Array<{
|
const testCases: Array<{
|
||||||
method: TCRUDMethod
|
method: TCRUDAsyncMethod
|
||||||
params: any
|
params: any
|
||||||
}> = [{
|
}> = [{
|
||||||
method: 'findOne',
|
method: 'findOne',
|
||||||
@ -203,7 +203,7 @@ describe('CRUD', () => {
|
|||||||
const entity = {id: 100, name: 'test'}
|
const entity = {id: 100, name: 'test'}
|
||||||
|
|
||||||
const testCases: Array<{
|
const testCases: Array<{
|
||||||
method: TCRUDMethod
|
method: TCRUDAsyncMethod,
|
||||||
params: any
|
params: any
|
||||||
body?: any
|
body?: any
|
||||||
response: any
|
response: any
|
||||||
@ -307,4 +307,68 @@ describe('CRUD', () => {
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('synchronous methods', () => {
|
||||||
|
|
||||||
|
describe('create', () => {
|
||||||
|
it('resets form.create state', () => {
|
||||||
|
store.dispatch(actions.create())
|
||||||
|
expect(store.getState().Crud.form.create).toEqual({
|
||||||
|
item: {
|
||||||
|
name: '',
|
||||||
|
},
|
||||||
|
errors: {},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('change', () => {
|
||||||
|
it('sets value', () => {
|
||||||
|
store.dispatch(actions.change({key: 'name', value: 'test'}))
|
||||||
|
expect(store.getState().Crud.form.create).toEqual({
|
||||||
|
item: {
|
||||||
|
name: 'test',
|
||||||
|
},
|
||||||
|
errors: {},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('edit', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
http.mockAdd({
|
||||||
|
method: 'post',
|
||||||
|
data: {name: 'test'},
|
||||||
|
url: '/one/1/two',
|
||||||
|
}, {id: 100, name: 'test'})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
http.mockClear()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sets item as edited', async () => {
|
||||||
|
await store.dispatch(actions.save({
|
||||||
|
params: {oneId: 1},
|
||||||
|
body: {name: 'test'},
|
||||||
|
})).payload
|
||||||
|
store.dispatch(actions.edit({id: 100}))
|
||||||
|
expect(store.getState().Crud.form.byId[100]).toEqual({
|
||||||
|
item: {
|
||||||
|
id: 100,
|
||||||
|
name: 'test',
|
||||||
|
},
|
||||||
|
errors: {},
|
||||||
|
})
|
||||||
|
store.dispatch(actions.change({id: 100, key: 'name', value: 'grrr'}))
|
||||||
|
expect(store.getState().Crud.form.byId[100]).toEqual({
|
||||||
|
item: {
|
||||||
|
id: 100,
|
||||||
|
name: 'grrr',
|
||||||
|
},
|
||||||
|
errors: {},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
import {TCRUDAction} from './TCRUDAction'
|
|
||||||
import {TCRUDMethod} from './TCRUDMethod'
|
|
||||||
import {IHTTPClient, ITypedRequestParams} from '../http'
|
import {IHTTPClient, ITypedRequestParams} from '../http'
|
||||||
import {IRoutes, TFilter, TOnlyDefined} from '@rondo/common'
|
import {IRoutes, TFilter, TOnlyDefined} from '@rondo/common'
|
||||||
|
import {TCRUDAction} from './TCRUDAction'
|
||||||
|
import {TCRUDChangeAction} from './TCRUDAction'
|
||||||
|
import {TCRUDCreateAction} from './TCRUDAction'
|
||||||
|
import {TCRUDEditAction} from './TCRUDAction'
|
||||||
|
import {TCRUDMethod} from './TCRUDMethod'
|
||||||
|
|
||||||
type TAction<T, ActionType extends string, Method extends TCRUDMethod> =
|
type TAction<T, ActionType extends string, Method extends TCRUDMethod> =
|
||||||
TFilter<TCRUDAction<T, ActionType>, {method: Method, status: 'pending'}>
|
TFilter<TCRUDAction<T, ActionType>, {method: Method, status: 'pending'}>
|
||||||
@ -144,6 +147,38 @@ export class FindManyActionCreator<
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class FormActionCreator<T, ActionType extends string> {
|
||||||
|
constructor(readonly actionType: ActionType) {}
|
||||||
|
|
||||||
|
create = (): TCRUDCreateAction<ActionType> => {
|
||||||
|
return {
|
||||||
|
payload: undefined,
|
||||||
|
type: this.actionType,
|
||||||
|
method: 'create',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
edit = (params: {id: number}): TCRUDEditAction<ActionType> => {
|
||||||
|
return {
|
||||||
|
payload: {id: params.id},
|
||||||
|
type: this.actionType,
|
||||||
|
method: 'edit',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
change = (params: {
|
||||||
|
id?: number,
|
||||||
|
key: keyof T,
|
||||||
|
value: string
|
||||||
|
}): TCRUDChangeAction<T, ActionType> => {
|
||||||
|
return {
|
||||||
|
payload: params,
|
||||||
|
type: this.actionType,
|
||||||
|
method: 'change',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function createCRUDActions<
|
export function createCRUDActions<
|
||||||
T extends IRoutes,
|
T extends IRoutes,
|
||||||
EntityRoute extends keyof T & string,
|
EntityRoute extends keyof T & string,
|
||||||
@ -161,5 +196,17 @@ export function createCRUDActions<
|
|||||||
const {findOne} = new FindOneActionCreator(http, entityRoute, actionType)
|
const {findOne} = new FindOneActionCreator(http, entityRoute, actionType)
|
||||||
const {findMany} = new FindManyActionCreator(http, listRoute, actionType)
|
const {findMany} = new FindManyActionCreator(http, listRoute, actionType)
|
||||||
|
|
||||||
return {save, update, remove, findOne, findMany}
|
const {create, edit, change} = new FormActionCreator
|
||||||
|
<T[ListRoute]['post']['body'], ActionType>(actionType)
|
||||||
|
|
||||||
|
return {
|
||||||
|
save,
|
||||||
|
update,
|
||||||
|
remove,
|
||||||
|
findOne,
|
||||||
|
findMany,
|
||||||
|
create,
|
||||||
|
edit,
|
||||||
|
change,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
101
packages/client/src/crud/CRUDForm.tsx
Normal file
101
packages/client/src/crud/CRUDForm.tsx
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import {Control, Field, Label, Icon, Input} from 'bloomer'
|
||||||
|
|
||||||
|
export type TCRUDFieldType = 'text' | 'password' | 'number' | 'email' | 'tel'
|
||||||
|
|
||||||
|
export interface ICRUDFieldProps<T> {
|
||||||
|
onChange<K extends keyof T>(key: K, value: string): void
|
||||||
|
Icon?: React.ComponentType
|
||||||
|
error?: string
|
||||||
|
label: string
|
||||||
|
placeholder?: string
|
||||||
|
name: keyof T & string
|
||||||
|
type: TCRUDFieldType
|
||||||
|
value: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ICRUDFormProps<T> {
|
||||||
|
errors: Partial<Record<keyof T & string, string>>
|
||||||
|
item: T
|
||||||
|
error: string
|
||||||
|
submitText: string
|
||||||
|
fields: Array<{
|
||||||
|
Icon?: React.ComponentType
|
||||||
|
label: string
|
||||||
|
placeholder?: string
|
||||||
|
name: keyof T & string
|
||||||
|
type: TCRUDFieldType
|
||||||
|
}>
|
||||||
|
|
||||||
|
onSubmit: (t: T) => void
|
||||||
|
onChange<K extends keyof T>(key: K, value: string): void
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CRUDField<T> extends React.PureComponent<ICRUDFieldProps<T>> {
|
||||||
|
handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const {onChange} = this.props
|
||||||
|
const {value} = e.target
|
||||||
|
onChange(this.props.name, value)
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
const {label, name, value, placeholder} = this.props
|
||||||
|
return (
|
||||||
|
<Field>
|
||||||
|
<Label>{label}</Label>
|
||||||
|
<Control hasIcons={!!this.props.Icon}>
|
||||||
|
<Input
|
||||||
|
name={name}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
placeholder={placeholder}
|
||||||
|
value={value}
|
||||||
|
/>
|
||||||
|
{!!this.props.Icon && (
|
||||||
|
<Icon isSize='small' isAlign='left'>
|
||||||
|
<this.props.Icon />
|
||||||
|
</Icon>
|
||||||
|
)}
|
||||||
|
</Control>
|
||||||
|
</Field>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CRUDForm<T> extends React.PureComponent<ICRUDFormProps<T>> {
|
||||||
|
handleSubmit = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault()
|
||||||
|
const {onSubmit, item} = this.props
|
||||||
|
onSubmit(item)
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
const {fields, item} = this.props
|
||||||
|
return (
|
||||||
|
<form onSubmit={this.handleSubmit}>
|
||||||
|
<p className='error'>{this.props.error}</p>
|
||||||
|
{fields.map(field => {
|
||||||
|
const error = this.props.errors[field.name]
|
||||||
|
const value = item[field.name]
|
||||||
|
return (
|
||||||
|
<CRUDField<T>
|
||||||
|
key={field.name}
|
||||||
|
name={field.name}
|
||||||
|
label={field.label}
|
||||||
|
onChange={this.props.onChange}
|
||||||
|
error={error}
|
||||||
|
Icon={field.Icon}
|
||||||
|
value={String(value)}
|
||||||
|
type={field.type}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
<div className='center'>
|
||||||
|
<input
|
||||||
|
className='button is-primary'
|
||||||
|
name='submit'
|
||||||
|
type='submit'
|
||||||
|
value={this.props.submitText}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {Button, Panel, PanelHeading, PanelBlock} from 'bloomer'
|
import {Button, Panel, PanelHeading, PanelBlock} from 'bloomer'
|
||||||
import {FaPlus, FaEdit, FaTimes} from 'react-icons/fa'
|
import {FaPlus, FaEdit, FaTimes} from 'react-icons/fa'
|
||||||
import {Link} from 'react-router-dom'
|
import {Link} from '../components'
|
||||||
|
|
||||||
export interface ICRUDListProps<T> {
|
export interface ICRUDListProps<T> {
|
||||||
nameKey: keyof T
|
nameKey: keyof T
|
||||||
|
|||||||
@ -15,7 +15,19 @@ export interface ICRUDMethodStatus {
|
|||||||
export interface ICRUDState<T extends ICRUDEntity> {
|
export interface ICRUDState<T extends ICRUDEntity> {
|
||||||
readonly ids: ReadonlyArray<number>
|
readonly ids: ReadonlyArray<number>
|
||||||
readonly byId: Record<number, T>
|
readonly byId: Record<number, T>
|
||||||
status: ICRUDStatus
|
readonly status: ICRUDStatus
|
||||||
|
readonly form: ICRUDForm<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICRUDForm<T extends ICRUDEntity> {
|
||||||
|
readonly create: {
|
||||||
|
readonly item: Pick<T, Exclude<keyof T, 'id'>>,
|
||||||
|
readonly errors: Partial<Record<keyof T, string>>
|
||||||
|
}
|
||||||
|
readonly byId: Record<number, {
|
||||||
|
readonly item: T,
|
||||||
|
readonly errors: Partial<Record<keyof T, string>>
|
||||||
|
}>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICRUDStatus {
|
export interface ICRUDStatus {
|
||||||
@ -32,12 +44,22 @@ export class CRUDReducer<
|
|||||||
> {
|
> {
|
||||||
readonly defaultState: ICRUDState<T>
|
readonly defaultState: ICRUDState<T>
|
||||||
|
|
||||||
constructor(readonly actionName: ActionType) {
|
constructor(
|
||||||
|
readonly actionName: ActionType,
|
||||||
|
readonly newItem: Pick<T, Exclude<keyof T, 'id'>>,
|
||||||
|
) {
|
||||||
|
|
||||||
const defaultMethodStatus = this.getDefaultMethodStatus()
|
const defaultMethodStatus = this.getDefaultMethodStatus()
|
||||||
this.defaultState = {
|
this.defaultState = {
|
||||||
ids: [],
|
ids: [],
|
||||||
byId: {},
|
byId: {},
|
||||||
|
form: {
|
||||||
|
byId: {},
|
||||||
|
create: {
|
||||||
|
item: newItem,
|
||||||
|
errors: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
status: {
|
status: {
|
||||||
save: defaultMethodStatus,
|
save: defaultMethodStatus,
|
||||||
@ -161,7 +183,77 @@ export class CRUDReducer<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reduce = (
|
handleCreate = (state: ICRUDState<T>): ICRUDState<T> => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
form: {
|
||||||
|
...state.form,
|
||||||
|
create: {
|
||||||
|
item: this.newItem,
|
||||||
|
errors: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleEdit = (state: ICRUDState<T>, id: number): ICRUDState<T> => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
form: {
|
||||||
|
...state.form,
|
||||||
|
byId: {
|
||||||
|
...state.form.byId,
|
||||||
|
[id]: {
|
||||||
|
item: state.byId[id],
|
||||||
|
errors: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleChange = (state: ICRUDState<T>, payload: {
|
||||||
|
id?: number,
|
||||||
|
key: keyof T,
|
||||||
|
value: string,
|
||||||
|
}): ICRUDState<T> => {
|
||||||
|
const {id, key, value} = payload
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
form: {
|
||||||
|
...state.form,
|
||||||
|
create: {
|
||||||
|
...state.form.create,
|
||||||
|
item: {
|
||||||
|
...state.form.create.item,
|
||||||
|
[key]: value,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
form: {
|
||||||
|
...state.form,
|
||||||
|
byId: {
|
||||||
|
...state.form.byId,
|
||||||
|
[id]: {
|
||||||
|
...state.form.byId[id],
|
||||||
|
item: {
|
||||||
|
...state.form.byId[id].item,
|
||||||
|
[key]: value,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce = (
|
||||||
state: ICRUDState<T> | undefined,
|
state: ICRUDState<T> | undefined,
|
||||||
action: TCRUDAction<T, ActionType>,
|
action: TCRUDAction<T, ActionType>,
|
||||||
): ICRUDState<T> => {
|
): ICRUDState<T> => {
|
||||||
@ -172,6 +264,19 @@ export class CRUDReducer<
|
|||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!('status' in action)) {
|
||||||
|
switch (action.method) {
|
||||||
|
case 'change':
|
||||||
|
return this.handleChange(state, action.payload)
|
||||||
|
case 'edit':
|
||||||
|
return this.handleEdit(state, action.payload.id)
|
||||||
|
case 'create':
|
||||||
|
return this.handleCreate(state)
|
||||||
|
default:
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (action.status) {
|
switch (action.status) {
|
||||||
case 'pending':
|
case 'pending':
|
||||||
return this.handleLoading(state, action.method)
|
return this.handleLoading(state, action.method)
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import {TAsyncAction} from '../actions'
|
import {IAction, TAsyncAction} from '../actions'
|
||||||
import {TCRUDMethod} from './TCRUDMethod'
|
import {TCRUDMethod} from './TCRUDMethod'
|
||||||
|
|
||||||
|
// Async actions
|
||||||
|
|
||||||
export type TCRUDSaveAction<T, ActionType extends string> =
|
export type TCRUDSaveAction<T, ActionType extends string> =
|
||||||
TAsyncAction<T, ActionType> & {method: Extract<TCRUDMethod, 'save'>}
|
TAsyncAction<T, ActionType> & {method: Extract<TCRUDMethod, 'save'>}
|
||||||
|
|
||||||
@ -16,9 +18,24 @@ export type TCRUDFindOneAction<T, ActionType extends string> =
|
|||||||
export type TCRUDFindManyAction<T, ActionType extends string> =
|
export type TCRUDFindManyAction<T, ActionType extends string> =
|
||||||
TAsyncAction<T[], ActionType> & {method: Extract<TCRUDMethod, 'findMany'>}
|
TAsyncAction<T[], ActionType> & {method: Extract<TCRUDMethod, 'findMany'>}
|
||||||
|
|
||||||
|
// Synchronous actions
|
||||||
|
|
||||||
|
export type TCRUDCreateAction<ActionType extends string> =
|
||||||
|
IAction<undefined, ActionType> & {method: Extract<TCRUDMethod, 'create'>}
|
||||||
|
|
||||||
|
export type TCRUDEditAction<ActionType extends string> =
|
||||||
|
IAction<{id: number}, ActionType> & {method: Extract<TCRUDMethod, 'edit'>}
|
||||||
|
|
||||||
|
export type TCRUDChangeAction<T, ActionType extends string> =
|
||||||
|
IAction<{id?: number, key: keyof T, value: string}, ActionType>
|
||||||
|
& {method: Extract<TCRUDMethod, 'change'>}
|
||||||
|
|
||||||
export type TCRUDAction<T, ActionType extends string> =
|
export type TCRUDAction<T, ActionType extends string> =
|
||||||
TCRUDSaveAction<T, ActionType>
|
TCRUDSaveAction<T, ActionType>
|
||||||
| TCRUDUpdateAction<T, ActionType>
|
| TCRUDUpdateAction<T, ActionType>
|
||||||
| TCRUDRemoveAction<T, ActionType>
|
| TCRUDRemoveAction<T, ActionType>
|
||||||
| TCRUDFindOneAction<T, ActionType>
|
| TCRUDFindOneAction<T, ActionType>
|
||||||
| TCRUDFindManyAction<T, ActionType>
|
| TCRUDFindManyAction<T, ActionType>
|
||||||
|
| TCRUDCreateAction<ActionType>
|
||||||
|
| TCRUDEditAction<ActionType>
|
||||||
|
| TCRUDChangeAction<T, ActionType>
|
||||||
|
|||||||
@ -1 +1,15 @@
|
|||||||
export type TCRUDMethod = 'save' | 'update' | 'findOne' | 'findMany' | 'remove'
|
export type TCRUDAsyncMethod =
|
||||||
|
'save'
|
||||||
|
| 'update'
|
||||||
|
| 'findOne'
|
||||||
|
| 'findMany'
|
||||||
|
| 'remove'
|
||||||
|
|
||||||
|
export type TCRUDSyncMethod =
|
||||||
|
| 'create'
|
||||||
|
| 'edit'
|
||||||
|
| 'change'
|
||||||
|
|
||||||
|
export type TCRUDMethod =
|
||||||
|
TCRUDAsyncMethod
|
||||||
|
| TCRUDSyncMethod
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user